From 014fbcda4c662c275532eb0e0e7ef57f46bd7321 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 7 Jun 2021 12:04:24 +0200 Subject: [PATCH] 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 (). --- gas/ChangeLog | 8 ++++++++ gas/config/tc-i386.c | 17 +++-------------- gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/unary.d | 17 +++++++++++++++++ gas/testsuite/gas/i386/unary.s | 11 +++++++++++ 5 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 gas/testsuite/gas/i386/unary.d create mode 100644 gas/testsuite/gas/i386/unary.s diff --git a/gas/ChangeLog b/gas/ChangeLog index b5686eed778..cc6f332d832 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2021-06-07 Jan Beulich + + * 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 * config/tc-i386.c (starts_memory_operand): New. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 063383c8dcd..bbdb5bd4c57 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 001c5f90adb..db52df4152f 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -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" "" diff --git a/gas/testsuite/gas/i386/unary.d b/gas/testsuite/gas/i386/unary.d new file mode 100644 index 00000000000..1a4cfaa8480 --- /dev/null +++ b/gas/testsuite/gas/i386/unary.d @@ -0,0 +1,17 @@ +#objdump: -dr +#name: i386 memory operands w/ unary operators + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[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 diff --git a/gas/testsuite/gas/i386/unary.s b/gas/testsuite/gas/i386/unary.s new file mode 100644 index 00000000000..e72121a86b3 --- /dev/null +++ b/gas/testsuite/gas/i386/unary.s @@ -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 -- 2.30.2