[6/8] x86: allow unary operators to start a memory operand

Message ID 6928c506-1458-9f7a-11d6-046d67ea5da7@suse.com
State New
Headers show
Series
  • x86: some tidying and quoted symbols fixes
Related show

Commit Message

Alan Modra via Binutils June 4, 2021, 1:41 p.m.
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/
2021-06-XX  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.

Patch

--- 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
--- 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" ""
--- /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+ <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
--- /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