x86/gas: support quoted address scale factor in AT&T syntax
authorJan Beulich <jbeulich@suse.com>
Wed, 5 Oct 2022 07:16:24 +0000 (09:16 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 5 Oct 2022 07:16:24 +0000 (09:16 +0200)
An earlier attempt (e68c3d59acd0 ["x86: better respect quotes in
parse_operands()"]) needed undoing (cc0f96357e0b ["x86: permit
parenthesized expressions again as addressing scale factor"]) as far its
effect here went. As indicated back then, the issue is the backwards
scanning of the operand string to find the matching opening parenthesis.
Switch to forward scanning, finding the last outermost unquoted opening
parenthesis (which is the one matching the trailing closing one).

gas/config/tc-i386.c
gas/testsuite/gas/i386/sib-intel.d
gas/testsuite/gas/i386/sib.d
gas/testsuite/gas/i386/sib.s

index 3435cb5699d03e18790bc83467d176b018926707..6d04e8361a98e13287fadf0d243a32b5e640f35a 100644 (file)
@@ -11589,25 +11589,32 @@ i386_att_operand (char *operand_string)
       if (*base_string == ')')
        {
          char *temp_string;
-         unsigned int parens_not_balanced = 1;
+         unsigned int parens_not_balanced = 0;
+         bool in_quotes = false;
 
          /* We've already checked that the number of left & right ()'s are
-            equal, so this loop will not be infinite.  */
-         do
-           {
-             base_string--;
-             if (*base_string == ')')
-               parens_not_balanced++;
-             if (*base_string == '(')
-               parens_not_balanced--;
+            equal, and that there's a matching set of double quotes.  */
+         end_op = base_string;
+         for (temp_string = op_string; temp_string < end_op; temp_string++)
+           {
+             if (*temp_string == '\\' && temp_string[1] == '"')
+               ++temp_string;
+             else if (*temp_string == '"')
+               in_quotes = !in_quotes;
+             else if (!in_quotes)
+               {
+                 if (*temp_string == '(' && !parens_not_balanced++)
+                   base_string = temp_string;
+                 if (*temp_string == ')')
+                   --parens_not_balanced;
+               }
            }
-         while (parens_not_balanced && *base_string != '"');
 
          temp_string = base_string;
 
          /* Skip past '(' and whitespace.  */
-         if (*base_string == '(')
-           ++base_string;
+         gas_assert (*base_string == '(');
+         ++base_string;
          if (is_space_char (*base_string))
            ++base_string;
 
index ccd2ea9643e517c9231114f322361efc9764b8c3..0688a5f3baa30819cd8154b0038d05bc0527bdc1 100644 (file)
@@ -34,6 +34,10 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    8b 04 40                mov    eax,DWORD PTR \[eax\+eax\*2\]
 [      ]*[a-f0-9]+:    8b 04 80                mov    eax,DWORD PTR \[eax\+eax\*4\]
 [      ]*[a-f0-9]+:    8b 04 c0                mov    eax,DWORD PTR \[eax\+eax\*8\]
+[      ]*[a-f0-9]+:    8b 14 08                mov    edx,DWORD PTR \[eax\+ecx\*1\]
+[      ]*[a-f0-9]+:    8b 14 48                mov    edx,DWORD PTR \[eax\+ecx\*2\]
+[      ]*[a-f0-9]+:    8b 14 88                mov    edx,DWORD PTR \[eax\+ecx\*4\]
+[      ]*[a-f0-9]+:    8b 14 c8                mov    edx,DWORD PTR \[eax\+ecx\*8\]
 [      ]*[a-f0-9]+:    8b 04 25 e2 ff ff ff    mov    eax,DWORD PTR \[eiz\*1-0x1e\]
 [      ]*[a-f0-9]+:    8b 04 65 e2 ff ff ff    mov    eax,DWORD PTR \[eiz\*2-0x1e\]
 [      ]*[a-f0-9]+:    8b 04 a5 e2 ff ff ff    mov    eax,DWORD PTR \[eiz\*4-0x1e\]
index 151935c62ec166d44f5d8d5d1e0696c815a54b25..f578d3db276a8a90ee98be47b14371c8669fbe4a 100644 (file)
@@ -33,6 +33,10 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    8b 04 40                mov    \(%eax,%eax,2\),%eax
 [      ]*[a-f0-9]+:    8b 04 80                mov    \(%eax,%eax,4\),%eax
 [      ]*[a-f0-9]+:    8b 04 c0                mov    \(%eax,%eax,8\),%eax
+[      ]*[a-f0-9]+:    8b 14 08                mov    \(%eax,%ecx,1\),%edx
+[      ]*[a-f0-9]+:    8b 14 48                mov    \(%eax,%ecx,2\),%edx
+[      ]*[a-f0-9]+:    8b 14 88                mov    \(%eax,%ecx,4\),%edx
+[      ]*[a-f0-9]+:    8b 14 c8                mov    \(%eax,%ecx,8\),%edx
 [      ]*[a-f0-9]+:    8b 04 25 e2 ff ff ff    mov    -0x1e\(,%eiz,1\),%eax
 [      ]*[a-f0-9]+:    8b 04 65 e2 ff ff ff    mov    -0x1e\(,%eiz,2\),%eax
 [      ]*[a-f0-9]+:    8b 04 a5 e2 ff ff ff    mov    -0x1e\(,%eiz,4\),%eax
index c0e007f3108ebf8b8dc876c3dc4695398fac746b..16afb00b91d7a647e116b20d1f9693f1a03e4f39 100644 (file)
@@ -30,6 +30,14 @@ foo:
        mov     (%eax, %eax, (1 << 1)), %eax
        mov     (%eax, %eax, (1 << 2)), %eax
        mov     (%eax, %eax, (1 << 3)), %eax
+       .equ "scale(1)", 1
+       mov     (%eax, %ecx, "scale(1)"), %edx
+       .equiv "scale[2]", 2
+       mov     (%eax, %ecx, "scale[2]"), %edx
+       .eqv "scale{4}", 4
+       mov     (%eax, %ecx, "scale{4}"), %edx
+       .set "scale<8>", 8
+       mov     (%eax, %ecx, "scale<8>"), %edx
        .intel_syntax noprefix
         mov    eax,DWORD PTR [eiz*1-30]
         mov    eax,DWORD PTR [eiz*2-30]