x86: allow unary operators to start a memory operand

So far only - was permitted, but +, !, and ~ ought to be treated the
same.

Rather than adding them to digit_chars[], which was at least odd to have
held - so far, drop this array and its wrapper macro for being used just
once.

While adjusting this logic, also include [ in the characters which may
start a displacement expression - gas generally treats [] as equivalent
to ().
This commit is contained in:
Jan Beulich 2021-06-07 12:04:24 +02:00
parent 9d299bea8c
commit 014fbcda4c
5 changed files with 40 additions and 14 deletions

View File

@ -1,3 +1,11 @@
2021-06-07 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (digit_chars, is_digit_char): Delete.
(md_begin): Fold digit and lower-case letter handling.
(starts_memory_operand): Permit more characters.
* testsuite/gas/i386/unary.s, testsuite/gas/i386/unary.d: New.
* testsuite/gas/i386/i386.exp: Run new test.
2021-06-07 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (starts_memory_operand): New.

View File

@ -518,7 +518,6 @@ static char mnemonic_chars[256];
static char register_chars[256];
static char operand_chars[256];
static char identifier_chars[256];
static char digit_chars[256];
/* Lexical macros. */
#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
@ -526,7 +525,6 @@ static char digit_chars[256];
#define is_register_char(x) (register_chars[(unsigned char) x])
#define is_space_char(x) ((x) == ' ')
#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
#define is_digit_char(x) (digit_chars[(unsigned char) x])
/* All non-digit non-letter characters that may occur in an operand. */
static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]";
@ -3140,14 +3138,7 @@ md_begin (void)
for (c = 0; c < 256; c++)
{
if (ISDIGIT (c))
{
digit_chars[c] = c;
mnemonic_chars[c] = c;
register_chars[c] = c;
operand_chars[c] = c;
}
else if (ISLOWER (c))
if (ISDIGIT (c) || ISLOWER (c))
{
mnemonic_chars[c] = c;
register_chars[c] = c;
@ -3185,7 +3176,6 @@ md_begin (void)
identifier_chars['?'] = '?';
operand_chars['?'] = '?';
#endif
digit_chars['-'] = '-';
mnemonic_chars['_'] = '_';
mnemonic_chars['-'] = '-';
mnemonic_chars['.'] = '.';
@ -11370,10 +11360,9 @@ maybe_adjust_templates (void)
static INLINE bool starts_memory_operand (char c)
{
return is_digit_char (c)
return ISDIGIT (c)
|| is_identifier_char (c)
|| c == '"'
|| c == '(';
|| strchr ("([\"+-!~", c);
}
/* Parse OPERAND_STRING into the i386_insn structure I. Returns zero

View File

@ -97,6 +97,7 @@ if [gas_32_check] then {
run_list_test "equ-bad"
run_dump_test "divide"
run_dump_test "quoted"
run_dump_test "unary"
run_dump_test "padlock"
run_dump_test "crx"
run_list_test "cr-err" ""

View File

@ -0,0 +1,17 @@
#objdump: -dr
#name: i386 memory operands w/ unary operators
.*: +file format .*
Disassembly of section .text:
0+ <unary>:
[ ]*[a-f0-9]+:[ ]*8b 40 01[ ]+mov 0x1\(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 40 ff[ ]+mov -0x1\(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 00[ ]+mov \(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 40 fe[ ]+mov -0x2\(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 40 01[ ]+mov 0x1\(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 40 ff[ ]+mov -0x1\(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 00[ ]+mov \(%eax\),%eax
[ ]*[a-f0-9]+:[ ]*8b 40 fe[ ]+mov -0x2\(%eax\),%eax
#pass

View File

@ -0,0 +1,11 @@
.text
unary:
mov +1(%eax), %eax
mov -1(%eax), %eax
mov !1(%eax), %eax
mov ~1(%eax), %eax
mov [+1](%eax), %eax
mov [-1](%eax), %eax
mov [!1](%eax), %eax
mov [~1](%eax), %eax