gas/
authorJan Beulich <jbeulich@novell.com>
Thu, 17 Mar 2005 12:05:24 +0000 (12:05 +0000)
committerJan Beulich <jbeulich@novell.com>
Thu, 17 Mar 2005 12:05:24 +0000 (12:05 +0000)
2005-03-17  Jan Beulich  <jbeulich@novell.com>

* config/tc-i386.c (i386_scale): Beautify error message.
(Intel syntax comments): Update.
(struct intel_parser_s): Add fields in_offset, in_bracket, and
next_operand.
(intel_e04_1, intel_e05_1, intel_e05_1, intel_e09_1, intel_e10_1):
Remove declarations.
(intel_bracket_expr): Declare.
(i386_intel_operand): Initialize new intel_parser fields. Wrap most
of the function body in a loop allowing to split an operand into two.
Replace calls to malloc and checks of it returning non-NULL with
calls to xmalloc/xstrdup.
(intel_expr): SHORT no longer handled here. Add comment indicating
comparison ops need implementation.
(intel_e04, intel_e04_1): Combine, replace recursion with loop.
Check right operand of - does not specify a register when parsing
the address of a memory reference.
(intel_e05, intel_e05_1): Combine, replace recursion with loop.
Check operands do not specify a register when parsing the address of
a memory reference.
(intel_e06, intel_e06_1): Likewise.
(intel_e09, intel_e09_1): Combine, replace recursion with loop. Also
handle SHORT as well as unary + and -. Don't accept : except for
segment overrides or in direct far jump/call insns.
(intel_brack_expr): New.
(intel_e10, intel_e10_1): Combine, replace recursion with loop. Use
intel_brack_expr.
(intel_e11): Replace chain of if/else-if by switch, alloing fall-
through in certain cases. Use intel_brack_expr. Add new diagnostics.
Allow symbolic constants as register scale value.
(intel_get_token): Replace call to malloc and check of return value
with call to xmalloc. Change handling for FLAT to match MASM's.
(intel_putback_token): Don't try to back up/free current token if
that is T_NIL.

gas/testsuite/
2005-03-17  Jan Beulich  <jbeulich@novell.com>

* gas/i386/intel.d: Add stderr directive.
* gas/i386/intel.e: New.
* gas/i386/intel16.d: Add stderr directive. Adjust for changed
source.
* gas/i386/intel16.e: New.
* gas/i386/intel16.s: Add instances of addressing forms with base
and index specified in reverse order.
* gas/i386/intelbad.l: Adjust for changed source.
* gas/i386/intelbad.s: Add more operand forms to check.
* gas/i386/intelok.d: Remove -r from objdump options. Add stderr
directive. Adjust for changed source.
* gas/i386/intelok.e: New.
* gas/i386/intelok.s: Define MASM constants byte, word, etc. Add
more operand forms to check.
* gas/i386/x86_64.d: Add stderr directive.
* gas/i386/x86_64.e: New.
* gas/i386/x86_64.s: Adjust for parser changes.

16 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/intel.d
gas/testsuite/gas/i386/intel.e [new file with mode: 0644]
gas/testsuite/gas/i386/intel16.d
gas/testsuite/gas/i386/intel16.e [new file with mode: 0644]
gas/testsuite/gas/i386/intel16.s
gas/testsuite/gas/i386/intelbad.l
gas/testsuite/gas/i386/intelbad.s
gas/testsuite/gas/i386/intelok.d
gas/testsuite/gas/i386/intelok.e [new file with mode: 0644]
gas/testsuite/gas/i386/intelok.s
gas/testsuite/gas/i386/x86_64.d
gas/testsuite/gas/i386/x86_64.e [new file with mode: 0644]
gas/testsuite/gas/i386/x86_64.s

index db3af83..1610ac5 100644 (file)
@@ -1,3 +1,39 @@
+2005-03-17  Jan Beulich  <jbeulich@novell.com>
+
+       * config/tc-i386.c (i386_scale): Beautify error message.
+       (Intel syntax comments): Update.
+       (struct intel_parser_s): Add fields in_offset, in_bracket, and
+       next_operand.
+       (intel_e04_1, intel_e05_1, intel_e05_1, intel_e09_1, intel_e10_1):
+       Remove declarations.
+       (intel_bracket_expr): Declare.
+       (i386_intel_operand): Initialize new intel_parser fields. Wrap most
+       of the function body in a loop allowing to split an operand into two.
+       Replace calls to malloc and checks of it returning non-NULL with
+       calls to xmalloc/xstrdup.
+       (intel_expr): SHORT no longer handled here. Add comment indicating
+       comparison ops need implementation.
+       (intel_e04, intel_e04_1): Combine, replace recursion with loop.
+       Check right operand of - does not specify a register when parsing
+       the address of a memory reference.
+       (intel_e05, intel_e05_1): Combine, replace recursion with loop.
+       Check operands do not specify a register when parsing the address of
+       a memory reference.
+       (intel_e06, intel_e06_1): Likewise.
+       (intel_e09, intel_e09_1): Combine, replace recursion with loop. Also
+       handle SHORT as well as unary + and -. Don't accept : except for
+       segment overrides or in direct far jump/call insns.
+       (intel_brack_expr): New.
+       (intel_e10, intel_e10_1): Combine, replace recursion with loop. Use
+       intel_brack_expr.
+       (intel_e11): Replace chain of if/else-if by switch, alloing fall-
+       through in certain cases. Use intel_brack_expr. Add new diagnostics.
+       Allow symbolic constants as register scale value.
+       (intel_get_token): Replace call to malloc and check of return value
+       with call to xmalloc. Change handling for FLAT to match MASM's.
+       (intel_putback_token): Don't try to back up/free current token if
+       that is T_NIL.
+
 2005-03-16  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * configure.tgt: Set emulation for arm-*-eabi*.
index bdcb55e..220e99c 100644 (file)
@@ -3965,10 +3965,16 @@ i386_scale (scale)
       i.log2_scale_factor = 3;
       break;
     default:
-      as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
-             scale);
-      input_line_pointer = save;
-      return NULL;
+      {
+       char sep = *input_line_pointer;
+
+       *input_line_pointer = '\0';
+       as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
+               scale);
+       *input_line_pointer = sep;
+       input_line_pointer = save;
+       return NULL;
+      }
     }
   if (i.log2_scale_factor != 0 && i.index_reg == 0)
     {
@@ -5514,6 +5520,9 @@ tc_gen_reloc (section, fixp)
                        | e09
 
     e09                        OFFSET e10
+                       | SHORT e10
+                       | + e10
+                       | - e10
                        | ~ e10
                        | NOT e10
                        | e09 PTR e10
@@ -5531,7 +5540,7 @@ tc_gen_reloc (section, fixp)
                        | $
                        | register
 
- => expr               SHORT e04
+ => expr               expr cmpOp e04
                        | e04
 
     gpRegister         AX | EAX | BX | EBX | CX | ECX | DX | EDX
@@ -5562,8 +5571,10 @@ tc_gen_reloc (section, fixp)
     done by calling parse_register) and eliminate immediate left recursion
     to implement a recursive-descent parser.
 
-    expr       SHORT e04
-               | e04
+    expr       e04 expr'
+
+    expr'      cmpOp e04 expr'
+               | Empty
 
     e04                e05 e04'
 
@@ -5581,8 +5592,11 @@ tc_gen_reloc (section, fixp)
                | Empty
 
     e09                OFFSET e10 e09'
-               | ~ e10
-               | NOT e10
+               | SHORT e10'
+               | + e10'
+               | - e10'
+               | ~ e10'
+               | NOT e10'
                | e10 e09'
 
     e09'       PTR e10 e09'
@@ -5618,8 +5632,11 @@ struct intel_parser_s
     int got_a_float;           /* Whether the operand is a float.  */
     int op_modifier;           /* Operand modifier.  */
     int is_mem;                        /* 1 if operand is memory reference.  */
+    int in_offset;                     /* >=1 if parsing operand of offset.  */
+    int in_bracket;                    /* >=1 if parsing operand in brackets.  */
     const reg_entry *reg;      /* Last register reference found.  */
     char *disp;                        /* Displacement string being built.  */
+    char *next_operand;                /* Resume point when splitting operands.  */
   };
 
 static struct intel_parser_s intel_parser;
@@ -5660,15 +5677,11 @@ static void intel_get_token     PARAMS ((void));
 static void intel_putback_token        PARAMS ((void));
 static int intel_expr          PARAMS ((void));
 static int intel_e04           PARAMS ((void));
-static int intel_e04_1         PARAMS ((void));
 static int intel_e05           PARAMS ((void));
-static int intel_e05_1         PARAMS ((void));
 static int intel_e06           PARAMS ((void));
-static int intel_e06_1         PARAMS ((void));
 static int intel_e09           PARAMS ((void));
-static int intel_e09_1         PARAMS ((void));
+static int intel_bracket_expr  PARAMS ((void));
 static int intel_e10           PARAMS ((void));
-static int intel_e10_1         PARAMS ((void));
 static int intel_e11           PARAMS ((void));
 
 static int
@@ -5679,31 +5692,33 @@ i386_intel_operand (operand_string, got_a_float)
   int ret;
   char *p;
 
-  /* Initialize token holders.  */
-  cur_token.code = prev_token.code = T_NIL;
-  cur_token.reg = prev_token.reg = NULL;
-  cur_token.str = prev_token.str = NULL;
-
-  /* Initialize parser structure.  */
-  p = intel_parser.op_string = (char *) malloc (strlen (operand_string) + 1);
-  if (p == NULL)
-    abort ();
-  strcpy (intel_parser.op_string, operand_string);
-  intel_parser.got_a_float = got_a_float;
-  intel_parser.op_modifier = -1;
-  intel_parser.is_mem = 0;
-  intel_parser.reg = NULL;
-  intel_parser.disp = (char *) malloc (strlen (operand_string) + 1);
-  if (intel_parser.disp == NULL)
-    abort ();
-  intel_parser.disp[0] = '\0';
-
-  /* Read the first token and start the parser.  */
-  intel_get_token ();
-  ret = intel_expr ();
-
-  if (ret)
+  p = intel_parser.op_string = xstrdup (operand_string);
+  intel_parser.disp = (char *) xmalloc (strlen (operand_string) + 1);
+
+  for (;;)
     {
+      /* Initialize token holders.  */
+      cur_token.code = prev_token.code = T_NIL;
+      cur_token.reg = prev_token.reg = NULL;
+      cur_token.str = prev_token.str = NULL;
+
+      /* Initialize parser structure.  */
+      intel_parser.got_a_float = got_a_float;
+      intel_parser.op_modifier = 0;
+      intel_parser.is_mem = 0;
+      intel_parser.in_offset = 0;
+      intel_parser.in_bracket = 0;
+      intel_parser.reg = NULL;
+      intel_parser.disp[0] = '\0';
+      intel_parser.next_operand = NULL;
+
+      /* Read the first token and start the parser.  */
+      intel_get_token ();
+      ret = intel_expr ();
+
+      if (!ret)
+       break;
+
       if (cur_token.code != T_NIL)
        {
          as_bad (_("invalid operand for '%s' ('%s' unexpected)"),
@@ -5727,18 +5742,46 @@ i386_intel_operand (operand_string, got_a_float)
              char *s = intel_parser.disp;
              i.mem_operands++;
 
+             if (!quiet_warnings && intel_parser.is_mem < 0)
+               /* See the comments in intel_bracket_expr.  */
+               as_warn (_("Treating `%s' as memory reference"), operand_string);
+
              /* Add the displacement expression.  */
              if (*s != '\0')
                ret = i386_displacement (s, s + strlen (s));
              if (ret)
-               ret = i386_index_check (operand_string);
+               {
+                 /* Swap base and index in 16-bit memory operands like
+                    [si+bx]. Since i386_index_check is also used in AT&T
+                    mode we have to do that here.  */
+                 if (i.base_reg
+                     && i.index_reg
+                     && (i.base_reg->reg_type & Reg16)
+                     && (i.index_reg->reg_type & Reg16)
+                     && i.base_reg->reg_num >= 6
+                     && i.index_reg->reg_num < 6)
+                   {
+                     const reg_entry *base = i.index_reg;
+
+                     i.index_reg = i.base_reg;
+                     i.base_reg = base;
+                   }
+                 ret = i386_index_check (operand_string);
+               }
            }
        }
 
       /* Constant and OFFSET expressions are handled by i386_immediate.  */
-      else if (intel_parser.op_modifier == T_OFFSET
+      else if ((intel_parser.op_modifier & (1 << T_OFFSET))
               || intel_parser.reg == NULL)
        ret = i386_immediate (intel_parser.disp);
+
+      if (intel_parser.next_operand && this_operand >= MAX_OPERANDS - 1)
+        ret = 0;
+      if (!ret || !intel_parser.next_operand)
+       break;
+      intel_parser.op_string = intel_parser.next_operand;
+      this_operand = i.operands++;
     }
 
   free (p);
@@ -5747,54 +5790,46 @@ i386_intel_operand (operand_string, got_a_float)
   return ret;
 }
 
-/* expr        SHORT e04
-       | e04  */
+#define NUM_ADDRESS_REGS (!!i.base_reg + !!i.index_reg)
+
+/* expr        e04 expr'
+
+   expr'  cmpOp e04 expr'
+       | Empty  */
 static int
 intel_expr ()
 {
-  /* expr  SHORT e04  */
-  if (cur_token.code == T_SHORT)
-    {
-      intel_parser.op_modifier = T_SHORT;
-      intel_match_token (T_SHORT);
-
-      return (intel_e04 ());
-    }
-
-  /* expr  e04  */
-  else
-    return intel_e04 ();
+  /* XXX Implement the comparison operators.  */
+  return intel_e04 ();
 }
 
-/* e04 e06 e04'
+/* e04 e05 e04'
 
-   e04'        addOp e06 e04'
+   e04'        addOp e05 e04'
        | Empty  */
 static int
 intel_e04 ()
 {
-  return (intel_e05 () && intel_e04_1 ());
-}
+  int nregs = -1;
 
-static int
-intel_e04_1 ()
-{
-  /* e04'  addOp e05 e04'  */
-  if (cur_token.code == '+' || cur_token.code == '-')
+  for (;;)
     {
-      char str[2];
+      if (!intel_e05())
+       return 0;
 
-      str[0] = cur_token.code;
-      str[1] = 0;
-      strcat (intel_parser.disp, str);
-      intel_match_token (cur_token.code);
+      if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
+       i.base_reg = i386_regtab + REGNAM_AL; /* al is invalid as base */
 
-      return (intel_e05 () && intel_e04_1 ());
-    }
+      if (cur_token.code == '+')
+       nregs = -1;
+      else if (cur_token.code == '-')
+       nregs = NUM_ADDRESS_REGS;
+      else
+       return 1;
 
-  /* e04'  Empty  */
-  else
-    return 1;
+      strcat (intel_parser.disp, cur_token.str);
+      intel_match_token (cur_token.code);
+    }
 }
 
 /* e05 e06 e05'
@@ -5804,28 +5839,32 @@ intel_e04_1 ()
 static int
 intel_e05 ()
 {
-  return (intel_e06 () && intel_e05_1 ());
-}
+  int nregs = ~NUM_ADDRESS_REGS;
 
-static int
-intel_e05_1 ()
-{
-  /* e05'  binOp e06 e05'  */
-  if (cur_token.code == '&' || cur_token.code == '|' || cur_token.code == '^')
+  for (;;)
     {
-      char str[2];
+      if (!intel_e06())
+       return 0;
+
+      if (cur_token.code == '&' || cur_token.code == '|' || cur_token.code == '^')
+       {
+         char str[2];
+
+         str[0] = cur_token.code;
+         str[1] = 0;
+         strcat (intel_parser.disp, str);
+       }
+      else
+       break;
 
-      str[0] = cur_token.code;
-      str[1] = 0;
-      strcat (intel_parser.disp, str);
       intel_match_token (cur_token.code);
 
-      return (intel_e06 () && intel_e05_1 ());
+      if (nregs < 0)
+       nregs = ~nregs;
     }
-
-  /* e05'  Empty  */
-  else
-    return 1;
+  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
+    i.base_reg = i386_regtab + REGNAM_AL + 1; /* cl is invalid as base */
+  return 1;
 }
 
 /* e06 e09 e06'
@@ -5835,49 +5874,44 @@ intel_e05_1 ()
 static int
 intel_e06 ()
 {
-  return (intel_e09 () && intel_e06_1 ());
-}
+  int nregs = ~NUM_ADDRESS_REGS;
 
-static int
-intel_e06_1 ()
-{
-  /* e06'  mulOp e09 e06'  */
-  if (cur_token.code == '*' || cur_token.code == '/' || cur_token.code == '%')
+  for (;;)
     {
-      char str[2];
+      if (!intel_e09())
+       return 0;
 
-      str[0] = cur_token.code;
-      str[1] = 0;
-      strcat (intel_parser.disp, str);
-      intel_match_token (cur_token.code);
+      if (cur_token.code == '*' || cur_token.code == '/' || cur_token.code == '%')
+       {
+         char str[2];
 
-      return (intel_e09 () && intel_e06_1 ());
-    }
-  else if (cur_token.code == T_SHL)
-    {
-      strcat (intel_parser.disp, "<<");
-      intel_match_token (cur_token.code);
+         str[0] = cur_token.code;
+         str[1] = 0;
+         strcat (intel_parser.disp, str);
+       }
+      else if (cur_token.code == T_SHL)
+       strcat (intel_parser.disp, "<<");
+      else if (cur_token.code == T_SHR)
+       strcat (intel_parser.disp, ">>");
+      else
+       break;
 
-      return (intel_e09 () && intel_e06_1 ());
-    }
-  else if (cur_token.code == T_SHR)
-    {
-      strcat (intel_parser.disp, ">>");
-      intel_match_token (cur_token.code);
+     intel_match_token (cur_token.code);
 
-      return (intel_e09 () && intel_e06_1 ());
+      if (nregs < 0)
+       nregs = ~nregs;
     }
-
-  /* e06'  Empty  */
-  else
-    return 1;
+  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
+    i.base_reg = i386_regtab + REGNAM_AL + 2; /* dl is invalid as base */
+  return 1;
 }
 
-/* e09 OFFSET e10 e09'
-       | e10 e09'
-
-   e09 ~ e10 e09'
-       | NOT e10 e09'
+/* e09 OFFSET e09
+       | SHORT e09
+       | + e09
+       | - e09
+       | ~ e09
+       | NOT e09
        | e10 e09'
 
    e09'        PTR e10 e09'
@@ -5886,146 +5920,277 @@ intel_e06_1 ()
 static int
 intel_e09 ()
 {
-  /* e09  OFFSET e10 e09'  */
-  if (cur_token.code == T_OFFSET)
+  int nregs = ~NUM_ADDRESS_REGS;
+  int in_offset = 0;
+
+  for (;;)
     {
-      intel_parser.is_mem = 0;
-      intel_parser.op_modifier = T_OFFSET;
-      intel_match_token (T_OFFSET);
+      /* Don't consume constants here.  */
+      if (cur_token.code == '+' || cur_token.code == '-')
+       {
+         /* Need to look one token ahead - if the next token
+            is a constant, the current token is its sign.  */
+         int next_code;
+
+         intel_match_token (cur_token.code);
+         next_code = cur_token.code;
+         intel_putback_token ();
+         if (next_code == T_CONST)
+           break;
+       }
+
+      /* e09  OFFSET e09  */
+      if (cur_token.code == T_OFFSET)
+       {
+         if (!in_offset++)
+           ++intel_parser.in_offset;
+       }
+
+      /* e09  SHORT e09  */
+      else if (cur_token.code == T_SHORT)
+       intel_parser.op_modifier |= 1 << T_SHORT;
+
+      /* e09  + e09  */
+      else if (cur_token.code == '+')
+       strcat (intel_parser.disp, "+");
+
+      /* e09  - e09
+             | ~ e09
+             | NOT e09  */
+      else if (cur_token.code == '-' || cur_token.code == '~')
+       {
+         char str[2];
 
-      return (intel_e10 () && intel_e09_1 ());
+         if (nregs < 0)
+           nregs = ~nregs;
+         str[0] = cur_token.code;
+         str[1] = 0;
+         strcat (intel_parser.disp, str);
+       }
+
+      /* e09  e10 e09'  */
+      else
+       break;
+
+      intel_match_token (cur_token.code);
     }
 
-  /* e09  NOT e10 e09'  */
-  else if (cur_token.code == '~')
+  for (;;)
     {
-      char str[2];
+      if (!intel_e10 ())
+       return 0;
 
-      str[0] = cur_token.code;
-      str[1] = 0;
-      strcat (intel_parser.disp, str);
-      intel_match_token (cur_token.code);
+      /* e09'  PTR e10 e09' */
+      if (cur_token.code == T_PTR)
+       {
+         char suffix;
 
-      return (intel_e10 () && intel_e09_1 ());
-    }
+         if (prev_token.code == T_BYTE)
+           suffix = BYTE_MNEM_SUFFIX;
 
-  /* e09  e10 e09'  */
-  else
-    return (intel_e10 () && intel_e09_1 ());
-}
+         else if (prev_token.code == T_WORD)
+           {
+             if (current_templates->start->name[0] == 'l'
+                 && current_templates->start->name[2] == 's'
+                 && current_templates->start->name[3] == 0)
+               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
+             else if (intel_parser.got_a_float == 2)   /* "fi..." */
+               suffix = SHORT_MNEM_SUFFIX;
+             else
+               suffix = WORD_MNEM_SUFFIX;
+           }
 
-static int
-intel_e09_1 ()
-{
-  /* e09'  PTR e10 e09' */
-  if (cur_token.code == T_PTR)
-    {
-      char suffix;
+         else if (prev_token.code == T_DWORD)
+           {
+             if (current_templates->start->name[0] == 'l'
+                 && current_templates->start->name[2] == 's'
+                 && current_templates->start->name[3] == 0)
+               suffix = WORD_MNEM_SUFFIX;
+             else if (flag_code == CODE_16BIT
+                      && (current_templates->start->opcode_modifier
+                          & (Jump|JumpDword|JumpInterSegment)))
+               suffix = LONG_DOUBLE_MNEM_SUFFIX;
+             else if (intel_parser.got_a_float == 1)   /* "f..." */
+               suffix = SHORT_MNEM_SUFFIX;
+             else
+               suffix = LONG_MNEM_SUFFIX;
+           }
 
-      if (prev_token.code == T_BYTE)
-       suffix = BYTE_MNEM_SUFFIX;
+         else if (prev_token.code == T_FWORD)
+           {
+             if (current_templates->start->name[0] == 'l'
+                 && current_templates->start->name[2] == 's'
+                 && current_templates->start->name[3] == 0)
+               suffix = LONG_MNEM_SUFFIX;
+             else if (!intel_parser.got_a_float)
+               {
+                 if (flag_code == CODE_16BIT)
+                   add_prefix (DATA_PREFIX_OPCODE);
+                 suffix = LONG_DOUBLE_MNEM_SUFFIX;
+               }
+             else
+               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
+           }
 
-      else if (prev_token.code == T_WORD)
-       {
-         if (current_templates->start->name[0] == 'l'
-             && current_templates->start->name[2] == 's'
-             && current_templates->start->name[3] == 0)
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-         else if (intel_parser.got_a_float == 2)       /* "fi..." */
-           suffix = SHORT_MNEM_SUFFIX;
-         else
-           suffix = WORD_MNEM_SUFFIX;
-       }
+         else if (prev_token.code == T_QWORD)
+           {
+             if (intel_parser.got_a_float == 1)        /* "f..." */
+               suffix = LONG_MNEM_SUFFIX;
+             else
+               suffix = QWORD_MNEM_SUFFIX;
+           }
 
-      else if (prev_token.code == T_DWORD)
-       {
-         if (current_templates->start->name[0] == 'l'
-             && current_templates->start->name[2] == 's'
-             && current_templates->start->name[3] == 0)
-           suffix = WORD_MNEM_SUFFIX;
-         else if (flag_code == CODE_16BIT
-                  && (current_templates->start->opcode_modifier
-                      & (Jump|JumpDword|JumpInterSegment)))
-           suffix = LONG_DOUBLE_MNEM_SUFFIX;
-         else if (intel_parser.got_a_float == 1)       /* "f..." */
-           suffix = SHORT_MNEM_SUFFIX;
-         else
-           suffix = LONG_MNEM_SUFFIX;
-       }
+         else if (prev_token.code == T_TBYTE)
+           {
+             if (intel_parser.got_a_float == 1)
+               suffix = LONG_DOUBLE_MNEM_SUFFIX;
+             else
+               suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
+           }
 
-      else if (prev_token.code == T_FWORD)
-       {
-         if (current_templates->start->name[0] == 'l'
-             && current_templates->start->name[2] == 's'
-             && current_templates->start->name[3] == 0)
-           suffix = LONG_MNEM_SUFFIX;
-         else if (!intel_parser.got_a_float)
+         else if (prev_token.code == T_XMMWORD)
            {
-             if (flag_code == CODE_16BIT)
-               add_prefix (DATA_PREFIX_OPCODE);
-             suffix = LONG_DOUBLE_MNEM_SUFFIX;
+             /* XXX ignored for now, but accepted since gcc uses it */
+             suffix = 0;
            }
-         else
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-       }
 
-      else if (prev_token.code == T_QWORD)
-       {
-         if (intel_parser.got_a_float == 1)    /* "f..." */
-           suffix = LONG_MNEM_SUFFIX;
          else
-           suffix = QWORD_MNEM_SUFFIX;
-       }
+           {
+             as_bad (_("Unknown operand modifier `%s'"), prev_token.str);
+             return 0;
+           }
+
+         if (current_templates->start->base_opcode == 0x8d /* lea */)
+           ;
+         else if (!i.suffix)
+           i.suffix = suffix;
+         else if (i.suffix != suffix)
+           {
+             as_bad (_("Conflicting operand modifiers"));
+             return 0;
+           }
 
-      else if (prev_token.code == T_TBYTE)
-       {
-         if (intel_parser.got_a_float == 1)
-           suffix = LONG_DOUBLE_MNEM_SUFFIX;
-         else
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
        }
 
-      else if (prev_token.code == T_XMMWORD)
+      /* e09'  : e10 e09'  */
+      else if (cur_token.code == ':')
        {
-         /* XXX ignored for now, but accepted since gcc uses it */
-         suffix = 0;
+         if (prev_token.code != T_REG)
+           {
+             /* While {call,jmp} SSSS:OOOO is MASM syntax only when SSSS is a
+                segment/group identifier (which we don't have), using comma
+                as the operand separator there is even less consistent, since
+                there all branches only have a single operand.  */
+             if (this_operand != 0
+                 || intel_parser.in_offset
+                 || intel_parser.in_bracket
+                 || (!(current_templates->start->opcode_modifier
+                       & (Jump|JumpDword|JumpInterSegment))
+                     && !(current_templates->start->operand_types[0]
+                          & JumpAbsolute)))
+               return intel_match_token (T_NIL);
+             /* Remember the start of the 2nd operand and terminate 1st
+                operand here.
+                XXX This isn't right, yet (when SSSS:OOOO is right operand of
+                another expression), but it gets at least the simplest case
+                (a plain number or symbol on the left side) right.  */
+             intel_parser.next_operand = intel_parser.op_string;
+             *--intel_parser.op_string = '\0';
+             return intel_match_token (':');
+           }
        }
 
+      /* e09'  Empty  */
       else
-       {
-         as_bad (_("Unknown operand modifier `%s'"), prev_token.str);
-         return 0;
-       }
+       break;
 
-      if (current_templates->start->base_opcode == 0x8d /* lea */)
-       ;
-      else if (!i.suffix)
-       i.suffix = suffix;
-      else if (i.suffix != suffix)
+      intel_match_token (cur_token.code);
+
+    }
+
+  if (in_offset)
+    {
+      --intel_parser.in_offset;
+      if (nregs < 0)
+       nregs = ~nregs;
+      if (NUM_ADDRESS_REGS > nregs)
        {
-         as_bad (_("Conflicting operand modifiers"));
+         as_bad (_("Invalid operand to `OFFSET'"));
          return 0;
        }
+      intel_parser.op_modifier |= 1 << T_OFFSET;
+    }
 
-      intel_match_token (T_PTR);
+  if (nregs >= 0 && NUM_ADDRESS_REGS > nregs)
+    i.base_reg = i386_regtab + REGNAM_AL + 3; /* bl is invalid as base */
+  return 1;
+}
 
-      return (intel_e10 () && intel_e09_1 ());
+static int
+intel_bracket_expr ()
+{
+  int was_offset = intel_parser.op_modifier & (1 << T_OFFSET);
+  const char *start = intel_parser.op_string;
+  int len;
+
+  if (i.op[this_operand].regs)
+    return intel_match_token (T_NIL);
+
+  intel_match_token ('[');
+
+  /* Mark as a memory operand only if it's not already known to be an
+     offset expression.  If it's an offset expression, we need to keep
+     the brace in.  */
+  if (!intel_parser.in_offset)
+    {
+      ++intel_parser.in_bracket;
+      /* Unfortunately gas always diverged from MASM in a respect that can't
+        be easily fixed without risking to break code sequences likely to be
+        encountered (the testsuite even check for this): MASM doesn't consider
+        an expression inside brackets unconditionally as a memory reference.
+        When that is e.g. a constant, an offset expression, or the sum of the
+        two, this is still taken as a constant load. gas, however, always
+        treated these as memory references. As a compromise, we'll try to make
+        offset expressions inside brackets work the MASM way (since that's
+        less likely to be found in real world code), but make constants alone
+        continue to work the traditional gas way. In either case, issue a
+        warning.  */
+      intel_parser.op_modifier &= ~was_offset;
     }
+  else
+      strcat (intel_parser.disp, "[");
+
+  /* Add a '+' to the displacement string if necessary.  */
+  if (*intel_parser.disp != '\0'
+      && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
+    strcat (intel_parser.disp, "+");
 
-  /* e09  : e10 e09'  */
-  else if (cur_token.code == ':')
+  if (intel_expr ()
+      && (len = intel_parser.op_string - start - 1,
+         intel_match_token (']')))
     {
-      /* Mark as a memory operand only if it's not already known to be an
-        offset expression.  */
-      if (intel_parser.op_modifier != T_OFFSET)
-       intel_parser.is_mem = 1;
+      /* Preserve brackets when the operand is an offset expression.  */
+      if (intel_parser.in_offset)
+       strcat (intel_parser.disp, "]");
+      else
+       {
+         --intel_parser.in_bracket;
+         if (i.base_reg || i.index_reg)
+           intel_parser.is_mem = 1;
+         if (!intel_parser.is_mem)
+           {
+             if (!(intel_parser.op_modifier & (1 << T_OFFSET)))
+               /* Defer the warning until all of the operand was parsed.  */
+               intel_parser.is_mem = -1;
+             else if (!quiet_warnings)
+               as_warn (_("`[%.*s]' taken to mean just `%.*s'"), len, start, len, start);
+           }
+       }
+      intel_parser.op_modifier |= was_offset;
 
-      return (intel_match_token (':') && intel_e10 () && intel_e09_1 ());
+      return 1;
     }
-
-  /* e09'  Empty  */
-  else
-    return 1;
+  return 0;
 }
 
 /* e10 e11 e10'
@@ -6035,45 +6200,16 @@ intel_e09_1 ()
 static int
 intel_e10 ()
 {
-  return (intel_e11 () && intel_e10_1 ());
-}
+  if (!intel_e11 ())
+    return 0;
 
-static int
-intel_e10_1 ()
-{
-  /* e10'  [ expr ]  e10'  */
-  if (cur_token.code == '[')
+  while (cur_token.code == '[')
     {
-      intel_match_token ('[');
-
-      /* Mark as a memory operand only if it's not already known to be an
-        offset expression.  If it's an offset expression, we need to keep
-        the brace in.  */
-      if (intel_parser.op_modifier != T_OFFSET)
-       intel_parser.is_mem = 1;
-      else
-       strcat (intel_parser.disp, "[");
-
-      /* Add a '+' to the displacement string if necessary.  */
-      if (*intel_parser.disp != '\0'
-         && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
-       strcat (intel_parser.disp, "+");
-
-      if (intel_expr () && intel_match_token (']'))
-       {
-         /* Preserve brackets when the operand is an offset expression.  */
-         if (intel_parser.op_modifier == T_OFFSET)
-           strcat (intel_parser.disp, "]");
-
-         return intel_e10_1 ();
-       }
-      else
+      if (!intel_bracket_expr ())
        return 0;
     }
 
-  /* e10'  Empty  */
-  else
-    return 1;
+  return 1;
 }
 
 /* e11 ( expr )
@@ -6094,9 +6230,10 @@ intel_e10_1 ()
 static int
 intel_e11 ()
 {
-  /* e11  ( expr ) */
-  if (cur_token.code == '(')
+  switch (cur_token.code)
     {
+    /* e11  ( expr ) */
+    case '(':
       intel_match_token ('(');
       strcat (intel_parser.disp, "(");
 
@@ -6105,318 +6242,299 @@ intel_e11 ()
          strcat (intel_parser.disp, ")");
          return 1;
        }
-      else
-       return 0;
-    }
-
-  /* e11  [ expr ] */
-  else if (cur_token.code == '[')
-    {
-      intel_match_token ('[');
-
-      /* Mark as a memory operand only if it's not already known to be an
-        offset expression.  If it's an offset expression, we need to keep
-        the brace in.  */
-      if (intel_parser.op_modifier != T_OFFSET)
-       intel_parser.is_mem = 1;
-      else
-       strcat (intel_parser.disp, "[");
+      return 0;
 
-      /* Operands for jump/call inside brackets denote absolute addresses.  */
+    /* e11  [ expr ] */
+    case '[':
+      /* Operands for jump/call inside brackets denote absolute addresses.
+        XXX This shouldn't be needed anymore (or if it should rather live
+        in intel_bracket_expr).  */
       if (current_templates->start->opcode_modifier
          & (Jump|JumpDword|JumpByte|JumpInterSegment))
        i.types[this_operand] |= JumpAbsolute;
 
-      /* Add a '+' to the displacement string if necessary.  */
-      if (*intel_parser.disp != '\0'
-         && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
-       strcat (intel_parser.disp, "+");
-
-      if (intel_expr () && intel_match_token (']'))
-       {
-         /* Preserve brackets when the operand is an offset expression.  */
-         if (intel_parser.op_modifier == T_OFFSET)
-           strcat (intel_parser.disp, "]");
-
-         return 1;
-       }
-      else
-       return 0;
-    }
-
-  /* e11  BYTE
-         | WORD
-         | DWORD
-         | FWORD
-         | QWORD
-         | TBYTE
-         | OWORD
-         | XMMWORD  */
-  else if (cur_token.code == T_BYTE
-          || cur_token.code == T_WORD
-          || cur_token.code == T_DWORD
-          || cur_token.code == T_FWORD
-          || cur_token.code == T_QWORD
-          || cur_token.code == T_TBYTE
-          || cur_token.code == T_XMMWORD)
-    {
-      intel_match_token (cur_token.code);
+      return intel_bracket_expr ();
 
-      if (cur_token.code != T_PTR)
-       {
-         /* It must have been an identifier; add it to the displacement string.  */
-         strcat (intel_parser.disp, prev_token.str);
-
-         /* The identifier represents a memory reference only if it's not
-            preceded by an offset modifier and if it's not an equate.  */
-         if (intel_parser.op_modifier != T_OFFSET)
-           {
-             symbolS *symbolP;
-
-             symbolP = symbol_find(prev_token.str);
-             if (!symbolP || S_GET_SEGMENT(symbolP) != absolute_section)
-               intel_parser.is_mem = 1;
-           }
-       }
-
-      return 1;
-    }
-
-  /* e11  $
-         | .  */
-  else if (cur_token.code == '.')
-    {
+    /* e11  $
+           | .  */
+    case '.':
       strcat (intel_parser.disp, cur_token.str);
       intel_match_token (cur_token.code);
 
       /* Mark as a memory operand only if it's not already known to be an
         offset expression.  */
-      if (intel_parser.op_modifier != T_OFFSET)
+      if (!intel_parser.in_offset)
        intel_parser.is_mem = 1;
 
       return 1;
-    }
 
-  /* e11  register  */
-  else if (cur_token.code == T_REG)
-    {
-      const reg_entry *reg = intel_parser.reg = cur_token.reg;
+    /* e11  register  */
+    case T_REG:
+      {
+       const reg_entry *reg = intel_parser.reg = cur_token.reg;
 
-      intel_match_token (T_REG);
+       intel_match_token (T_REG);
 
-      /* Check for segment change.  */
-      if (cur_token.code == ':')
-       {
-         if (reg->reg_type & (SReg2 | SReg3))
-           {
-             switch (reg->reg_num)
-               {
-               case 0:
-                 i.seg[i.mem_operands] = &es;
-                 break;
-               case 1:
-                 i.seg[i.mem_operands] = &cs;
-                 break;
-               case 2:
-                 i.seg[i.mem_operands] = &ss;
-                 break;
-               case 3:
-                 i.seg[i.mem_operands] = &ds;
-                 break;
-               case 4:
-                 i.seg[i.mem_operands] = &fs;
-                 break;
-               case 5:
-                 i.seg[i.mem_operands] = &gs;
-                 break;
-               }
-           }
-         else
-           {
-             as_bad (_("`%s' is not a valid segment register"), reg->reg_name);
-             return 0;
-           }
-       }
+       /* Check for segment change.  */
+       if (cur_token.code == ':')
+         {
+           if (!(reg->reg_type & (SReg2 | SReg3)))
+             {
+               as_bad (_("`%s' is not a valid segment register"), reg->reg_name);
+               return 0;
+             }
+           else if (i.seg[i.mem_operands])
+             as_warn (_("Extra segment override ignored"));
+           else
+             {
+               if (!intel_parser.in_offset)
+                 intel_parser.is_mem = 1;
+               switch (reg->reg_num)
+                 {
+                 case 0:
+                   i.seg[i.mem_operands] = &es;
+                   break;
+                 case 1:
+                   i.seg[i.mem_operands] = &cs;
+                   break;
+                 case 2:
+                   i.seg[i.mem_operands] = &ss;
+                   break;
+                 case 3:
+                   i.seg[i.mem_operands] = &ds;
+                   break;
+                 case 4:
+                   i.seg[i.mem_operands] = &fs;
+                   break;
+                 case 5:
+                   i.seg[i.mem_operands] = &gs;
+                   break;
+                 }
+             }
+         }
 
-      /* Not a segment register. Check for register scaling.  */
-      else if (cur_token.code == '*')
-       {
-         if (!intel_parser.is_mem)
-           {
-             as_bad (_("Register scaling only allowed in memory operands."));
-             return 0;
-           }
+       /* Not a segment register. Check for register scaling.  */
+       else if (cur_token.code == '*')
+         {
+           if (!intel_parser.in_bracket)
+             {
+               as_bad (_("Register scaling only allowed in memory operands"));
+               return 0;
+             }
 
-         /* What follows must be a valid scale.  */
-         if (intel_match_token ('*')
-             && strchr ("01248", *cur_token.str))
-           {
-             i.index_reg = reg;
-             i.types[this_operand] |= BaseIndex;
+           if (reg->reg_type & Reg16) /* Disallow things like [si*1]. */
+             reg = i386_regtab + REGNAM_AX + 4; /* sp is invalid as index */
+           else if (i.index_reg)
+             reg = i386_regtab + REGNAM_EAX + 4; /* esp is invalid as index */
 
-             /* Set the scale after setting the register (otherwise,
-                i386_scale will complain)  */
-             i386_scale (cur_token.str);
-             intel_match_token (T_CONST);
-           }
-         else
-           {
-             as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
-                     cur_token.str);
-             return 0;
-           }
-       }
+           /* What follows must be a valid scale.  */
+           intel_match_token ('*');
+           i.index_reg = reg;
+           i.types[this_operand] |= BaseIndex;
 
-      /* No scaling. If this is a memory operand, the register is either a
-        base register (first occurrence) or an index register (second
-        occurrence).  */
-      else if (intel_parser.is_mem && !(reg->reg_type & (SReg2 | SReg3)))
-       {
-         if (i.base_reg && i.index_reg)
-           {
-             as_bad (_("Too many register references in memory operand."));
+           /* Set the scale after setting the register (otherwise,
+              i386_scale will complain)  */
+           if (cur_token.code == '+' || cur_token.code == '-')
+             {
+               char *str, sign = cur_token.code;
+               intel_match_token (cur_token.code);
+               if (cur_token.code != T_CONST)
+                 {
+                   as_bad (_("Syntax error: Expecting a constant, got `%s'"),
+                           cur_token.str);
+                   return 0;
+                 }
+               str = (char *) xmalloc (strlen (cur_token.str) + 2);
+               strcpy (str + 1, cur_token.str);
+               *str = sign;
+               if (!i386_scale (str))
+                 return 0;
+               free (str);
+             }
+           else if (!i386_scale (cur_token.str))
              return 0;
-           }
+           intel_match_token (cur_token.code);
+         }
 
-         if (i.base_reg == NULL)
-           i.base_reg = reg;
-         else
-           i.index_reg = reg;
+       /* No scaling. If this is a memory operand, the register is either a
+          base register (first occurrence) or an index register (second
+          occurrence).  */
+       else if (intel_parser.in_bracket && !(reg->reg_type & (SReg2 | SReg3)))
+         {
 
-         i.types[this_operand] |= BaseIndex;
-       }
+           if (!i.base_reg)
+             i.base_reg = reg;
+           else if (!i.index_reg)
+             i.index_reg = reg;
+           else
+             {
+               as_bad (_("Too many register references in memory operand"));
+               return 0;
+             }
 
-      /* Offset modifier. Add the register to the displacement string to be
-        parsed as an immediate expression after we're done.  */
-      else if (intel_parser.op_modifier == T_OFFSET)
-       strcat (intel_parser.disp, reg->reg_name);
+           i.types[this_operand] |= BaseIndex;
+         }
 
-      /* It's neither base nor index nor offset.  */
-      else
-       {
-         i.types[this_operand] |= reg->reg_type & ~BaseIndex;
-         i.op[this_operand].regs = reg;
-         i.reg_operands++;
-       }
+       /* Offset modifier. Add the register to the displacement string to be
+          parsed as an immediate expression after we're done.  */
+       else if (intel_parser.in_offset)
+         {
+           as_warn (_("Using register names in OFFSET expressions is deprecated"));
+           strcat (intel_parser.disp, reg->reg_name);
+         }
 
-      /* Since registers are not part of the displacement string (except
-        when we're parsing offset operands), we may need to remove any
-        preceding '+' from the displacement string.  */
-      if (*intel_parser.disp != '\0'
-         && intel_parser.op_modifier != T_OFFSET)
-       {
-         char *s = intel_parser.disp;
-         s += strlen (s) - 1;
-         if (*s == '+')
-           *s = '\0';
-       }
+       /* It's neither base nor index nor offset.  */
+       else if (!intel_parser.is_mem)
+         {
+           i.types[this_operand] |= reg->reg_type & ~BaseIndex;
+           i.op[this_operand].regs = reg;
+           i.reg_operands++;
+         }
+       else
+         {
+           as_bad (_("Invalid use of register"));
+           return 0;
+         }
 
-      return 1;
-    }
+       /* Since registers are not part of the displacement string (except
+          when we're parsing offset operands), we may need to remove any
+          preceding '+' from the displacement string.  */
+       if (*intel_parser.disp != '\0'
+           && !intel_parser.in_offset)
+         {
+           char *s = intel_parser.disp;
+           s += strlen (s) - 1;
+           if (*s == '+')
+             *s = '\0';
+         }
 
-  /* e11  id  */
-  else if (cur_token.code == T_ID)
-    {
-      /* Add the identifier to the displacement string.  */
-      strcat (intel_parser.disp, cur_token.str);
+       return 1;
+      }
+
+    /* e11  BYTE
+           | WORD
+           | DWORD
+           | FWORD
+           | QWORD
+           | TBYTE
+           | OWORD
+           | XMMWORD  */
+    case T_BYTE:
+    case T_WORD:
+    case T_DWORD:
+    case T_FWORD:
+    case T_QWORD:
+    case T_TBYTE:
+    case T_XMMWORD:
+      intel_match_token (cur_token.code);
 
-      /* The identifier represents a memory reference only if it's not
-        preceded by an offset modifier and if it's not an equate.  */
-      if (intel_parser.op_modifier != T_OFFSET)
+      if (cur_token.code == T_PTR)
+       return 1;
+
+      /* It must have been an identifier.  */
+      intel_putback_token ();
+      cur_token.code = T_ID;
+      /* FALLTHRU */
+
+    /* e11  id
+           | constant  */
+    case T_ID:
+      if (!intel_parser.in_offset && intel_parser.is_mem <= 0)
        {
          symbolS *symbolP;
 
+         /* The identifier represents a memory reference only if it's not
+            preceded by an offset modifier and if it's not an equate.  */
          symbolP = symbol_find(cur_token.str);
          if (!symbolP || S_GET_SEGMENT(symbolP) != absolute_section)
            intel_parser.is_mem = 1;
        }
+       /* FALLTHRU */
 
-      intel_match_token (T_ID);
-      return 1;
-    }
-
-  /* e11  constant  */
-  else if (cur_token.code == T_CONST
-          || cur_token.code == '-'
-          || cur_token.code == '+')
-    {
-      char *save_str;
+    case T_CONST:
+    case '-':
+    case '+':
+      {
+       char *save_str, sign = 0;
 
-      /* Allow constants that start with `+' or `-'.  */
-      if (cur_token.code == '-' || cur_token.code == '+')
-       {
-         strcat (intel_parser.disp, cur_token.str);
-         intel_match_token (cur_token.code);
-         if (cur_token.code != T_CONST)
-           {
-             as_bad (_("Syntax error. Expecting a constant. Got `%s'."),
-                     cur_token.str);
-             return 0;
-           }
-       }
+       /* Allow constants that start with `+' or `-'.  */
+       if (cur_token.code == '-' || cur_token.code == '+')
+         {
+           sign = cur_token.code;
+           intel_match_token (cur_token.code);
+           if (cur_token.code != T_CONST)
+             {
+               as_bad (_("Syntax error: Expecting a constant, got `%s'"),
+                       cur_token.str);
+               return 0;
+             }
+         }
 
-      save_str = (char *) malloc (strlen (cur_token.str) + 1);
-      if (save_str == NULL)
-       abort ();
-      strcpy (save_str, cur_token.str);
+       save_str = (char *) xmalloc (strlen (cur_token.str) + 2);
+       strcpy (save_str + !!sign, cur_token.str);
+       if (sign)
+         *save_str = sign;
 
-      /* Get the next token to check for register scaling.  */
-      intel_match_token (cur_token.code);
+       /* Get the next token to check for register scaling.  */
+       intel_match_token (cur_token.code);
 
-      /* Check if this constant is a scaling factor for an index register.  */
-      if (cur_token.code == '*')
-       {
-         if (intel_match_token ('*') && cur_token.code == T_REG)
-           {
-             if (!intel_parser.is_mem)
-               {
-                 as_bad (_("Register scaling only allowed in memory operands."));
+       /* Check if this constant is a scaling factor for an index register.  */
+       if (cur_token.code == '*')
+         {
+           if (intel_match_token ('*') && cur_token.code == T_REG)
+             {
+               const reg_entry *reg = cur_token.reg;
+
+               if (!intel_parser.in_bracket)
+                 {
+                   as_bad (_("Register scaling only allowed in memory operands"));
+                   return 0;
+                 }
+
+               if (reg->reg_type & Reg16) /* Disallow things like [1*si]. */
+                 reg = i386_regtab + REGNAM_AX + 4; /* sp is invalid as index */
+               else if (i.index_reg)
+                 reg = i386_regtab + REGNAM_EAX + 4; /* esp is invalid as index */
+
+               /* The constant is followed by `* reg', so it must be
+                  a valid scale.  */
+               i.index_reg = reg;
+               i.types[this_operand] |= BaseIndex;
+
+               /* Set the scale after setting the register (otherwise,
+                  i386_scale will complain)  */
+               if (!i386_scale (save_str))
                  return 0;
-               }
-
-             /* The constant is followed by `* reg', so it must be
-                a valid scale.  */
-             if (strchr ("01248", *save_str))
-               {
-                 i.index_reg = cur_token.reg;
-                 i.types[this_operand] |= BaseIndex;
-
-                 /* Set the scale after setting the register (otherwise,
-                    i386_scale will complain)  */
-                 i386_scale (save_str);
-                 intel_match_token (T_REG);
-
-                 /* Since registers are not part of the displacement
-                    string, we may need to remove any preceding '+' from
-                    the displacement string.  */
-                 if (*intel_parser.disp != '\0')
-                   {
-                     char *s = intel_parser.disp;
-                     s += strlen (s) - 1;
-                     if (*s == '+')
-                       *s = '\0';
-                   }
-
-                 free (save_str);
-
-                 return 1;
-               }
-             else
-               return 0;
-           }
+               intel_match_token (T_REG);
+
+               /* Since registers are not part of the displacement
+                  string, we may need to remove any preceding '+' from
+                  the displacement string.  */
+               if (*intel_parser.disp != '\0')
+                 {
+                   char *s = intel_parser.disp;
+                   s += strlen (s) - 1;
+                   if (*s == '+')
+                     *s = '\0';
+                 }
+
+               free (save_str);
+
+               return 1;
+             }
 
-         /* The constant was not used for register scaling. Since we have
-            already consumed the token following `*' we now need to put it
-            back in the stream.  */
-         else
+           /* The constant was not used for register scaling. Since we have
+              already consumed the token following `*' we now need to put it
+              back in the stream.  */
            intel_putback_token ();
-       }
+         }
 
-      /* Add the constant to the displacement string.  */
-      strcat (intel_parser.disp, save_str);
-      free (save_str);
+       /* Add the constant to the displacement string.  */
+       strcat (intel_parser.disp, save_str);
+       free (save_str);
 
-      return 1;
+       return 1;
+      }
     }
 
   as_bad (_("Unrecognized token '%s'"), cur_token.str);
@@ -6473,9 +6591,7 @@ intel_get_token ()
 
   /* The new token cannot be larger than the remainder of the operand
      string.  */
-  new_token.str = (char *) malloc (strlen (intel_parser.op_string) + 1);
-  if (new_token.str == NULL)
-    abort ();
+  new_token.str = (char *) xmalloc (strlen (intel_parser.op_string) + 1);
   new_token.str[0] = '\0';
 
   if (strchr ("0123456789", *intel_parser.op_string))
@@ -6595,7 +6711,13 @@ intel_get_token ()
 
          /* ??? This is not mentioned in the MASM grammar.  */
          else if (strcasecmp (new_token.str, "FLAT") == 0)
-           new_token.code = T_OFFSET;
+           {
+             new_token.code = T_OFFSET;
+             if (*q == ':')
+               strcat (new_token.str, ":");
+             else
+               as_bad (_("`:' expected"));
+           }
 
          else
            new_token.code = T_ID;
@@ -6630,8 +6752,11 @@ intel_get_token ()
 static void
 intel_putback_token ()
 {
-  intel_parser.op_string -= strlen (cur_token.str);
-  free (cur_token.str);
+  if (cur_token.code != T_NIL)
+    {
+      intel_parser.op_string -= strlen (cur_token.str);
+      free (cur_token.str);
+    }
   cur_token = prev_token;
 
   /* Forget prev_token.  */
index 86af7eb..630745a 100644 (file)
@@ -1,3 +1,23 @@
+2005-03-17  Jan Beulich  <jbeulich@novell.com>
+
+       * gas/i386/intel.d: Add stderr directive. 
+       * gas/i386/intel.e: New.
+       * gas/i386/intel16.d: Add stderr directive. Adjust for changed
+       source.
+       * gas/i386/intel16.e: New.
+       * gas/i386/intel16.s: Add instances of addressing forms with base
+       and index specified in reverse order.
+       * gas/i386/intelbad.l: Adjust for changed source.
+       * gas/i386/intelbad.s: Add more operand forms to check.
+       * gas/i386/intelok.d: Remove -r from objdump options. Add stderr
+       directive. Adjust for changed source.
+       * gas/i386/intelok.e: New.
+       * gas/i386/intelok.s: Define MASM constants byte, word, etc. Add
+       more operand forms to check.
+       * gas/i386/x86_64.d: Add stderr directive.
+       * gas/i386/x86_64.e: New.
+       * gas/i386/x86_64.s: Adjust for parser changes.
+
 2005-03-15  Zack Weinberg  <zack@codesourcery.com>
 
        * gas/arm/archv6t2.d, gas/arm/archv6t2.s: New dump test.
index 24f4536..3fb9270 100644 (file)
@@ -1,6 +1,7 @@
 #as: -J
 #objdump: -dw
 #name: i386 intel
+#stderr: intel.e
 
 .*: +file format .*
 
diff --git a/gas/testsuite/gas/i386/intel.e b/gas/testsuite/gas/i386/intel.e
new file mode 100644 (file)
index 0000000..b56da1a
--- /dev/null
@@ -0,0 +1,8 @@
+.*: Assembler messages:
+.*:154: Warning: Treating .\[0x90909090\]. as memory reference
+.*:155: Warning: Treating .\[0x90909090\]. as memory reference
+.*:156: Warning: Treating .\[0x90909090\]. as memory reference
+.*:157: Warning: Treating .\[0x90909090\]. as memory reference
+.*:492: Warning: Treating .\[0x90909090\]. as memory reference
+.*:493: Warning: Treating .\[0x90909090\]. as memory reference
+.*:580: Warning: Using register names in OFFSET expressions is deprecated
index 79e57d8..495fe14 100644 (file)
@@ -1,5 +1,6 @@
 #objdump: -dw -mi8086
 #name: i386 intel16
+#stderr: intel16.e
 
 .*: +file format .*
 
@@ -12,4 +13,12 @@ Disassembly of section .text:
   11:  66 0f b7 06 00 00 [     ]*movzwl 0,%eax
   17:  66 0f b6 06 00 00 [     ]*movzbl 0,%eax
   1d:  0f b6 06 00 00 [        ]*movzbw 0,%ax
-#pass
+  22:  8d 00 [         ]*lea    \(%bx,%si\),%ax
+  24:  8d 02 [         ]*lea    \(%bp,%si\),%ax
+  26:  8d 01 [         ]*lea    \(%bx,%di\),%ax
+  28:  8d 03 [         ]*lea    \(%bp,%di\),%ax
+  2a:  8d 00 [         ]*lea    \(%bx,%si\),%ax
+  2c:  8d 02 [         ]*lea    \(%bp,%si\),%ax
+  2e:  8d 01 [         ]*lea    \(%bx,%di\),%ax
+  30:  8d 03 [         ]*lea    \(%bp,%di\),%ax
+       ...
diff --git a/gas/testsuite/gas/i386/intel16.e b/gas/testsuite/gas/i386/intel16.e
new file mode 100644 (file)
index 0000000..62da8a7
--- /dev/null
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:5: Warning: Treating .word ptr \[0\]. as memory reference
+.*:6: Warning: Treating .byte ptr \[0\]. as memory reference
+.*:7: Warning: Treating .byte ptr \[0\]. as memory reference
+.*:8: Warning: Treating .word ptr \[0\]. as memory reference
+.*:9: Warning: Treating .byte ptr \[0\]. as memory reference
+.*:10: Warning: Treating .byte ptr \[0\]. as memory reference
index bf78ad8..e27b017 100644 (file)
@@ -8,4 +8,14 @@
  movzx eax,word ptr [0]
  movzx eax,byte ptr [0]
  movzx ax,byte ptr [0]
+
+ lea   ax, [si+bx]
+ lea   ax, [si+bp]
+ lea   ax, [di+bx]
+ lea   ax, [di+bp]
+ lea   ax, [si][bx]
+ lea   ax, [si][bp]
+ lea   ax, [di][bx]
+ lea   ax, [di][bp]
+
  .p2align 4,0
index 45c21d2..5eaa5d1 100644 (file)
 .*:89: Error: .*
 .*:90: Error: .*
 .*:91: Error: .*
+.*:94: Error: .*
+.*:95: Error: .*
+.*:96: Error: .*
+.*:97: Error: .*
+.*:98: Error: .*
+.*:99: Error: .*
+.*:100: Error: .*
+.*:101: Error: .*
+.*:102: Error: .*
+.*:103: Error: .*
+.*:104: Error: .*
+.*:105: Error: .*
+.*:106: Error: .*
+.*:107: Error: .*
+.*:108: Error: .*
+.*:109: Error: .*
+.*:110: Error: .*
+.*:111: Error: .*
+.*:112: Error: .*
+.*:113: Error: .*
+.*:114: Error: .*
+.*:115: Error: .*
+.*:116: Error: .*
+.*:117: Error: .*
+.*:118: Error: .*
+.*:119: Error: .*
+.*:120: Error: .*
+.*:121: Error: .*
+.*:122: Error: .*
+.*:123: Error: .*
+.*:124: Error: .*
+.*:125: Error: .*
+.*:126: Error: .*
+.*:127: Error: .*
+.*:128: Error: .*
+#...
+.*:129: Error: .*
+#...
+.*:130: Error: .*
+.*:131: Error: .*
+.*:132: Error: .*
+.*:133: Error: .*
+.*:135: Warning: .*
+.*:136: Warning: .*
+.*:137: Warning: .*
+.*:138: Warning: .*
+.*:139: Warning: .*
+.*:141: Error: .*
+.*:142: Warning: .*
+.*:142: Error: .*
index c4b03f3..2a9daad 100644 (file)
@@ -89,3 +89,54 @@ start:
        push    1 1
        push    1 +
        push    1 * * 1
+
+       # memory references
+       mov     eax, [ecx*3]
+       mov     eax, [3*ecx]
+       mov     eax, [-1*ecx + 1]
+       mov     eax, [esp + esp]
+       mov     eax, [eax - 1*ecx + 1]
+       mov     eax, [(eax-1) * (eax-1)]
+       mov     eax, [eax-1 xor eax-1]
+       mov     eax, [(eax-1) xor (eax-1)]
+       mov     eax, [not eax + 1]
+       mov     eax, [ecx*2 + edx*4]
+       mov     eax, [2*ecx + 4*edx]
+       mov     eax, [eax]1[ecx]                # ugly diag
+       mov     eax, [eax][ecx]1                # ugly diag
+       mov     eax, eax[ecx]                   # ugly diag
+       mov     eax, es[ecx]
+       mov     eax, cr0[ecx]
+       mov     eax, [eax]ecx
+       mov     eax, [eax]+ecx
+       mov     eax, [eax]+ecx*2
+       mov     eax, [eax]+2*ecx
+       mov     eax, [[eax]ecx]
+       mov     eax, eax:[ecx]
+       lea     eax, [bx+si*1]
+       lea     eax, [bp+si*2]
+       lea     eax, [bx+di*4]
+       lea     eax, [bp+di*8]
+       lea     eax, [bx+1*si]
+       lea     eax, [bp+2*si]
+       lea     eax, [bx+4*di]
+       lea     eax, [bp+8*di]
+       mov     eax, [ah]
+       mov     eax, [ax]
+       mov     eax, [eax+bx]
+       mov     eax, offset [1*eax]
+       mov     eax, offset 1*eax
+       mov     eax, offset x[eax]              # ugly diag
+       mov     eax, offset [x][eax]            # ugly diag
+       mov     eax, flat x
+       mov     eax, flat [x]
+       mov     eax, es:eax
+
+       mov     eax, offset [eax]
+       mov     eax, offset eax
+       mov     eax, offset offset eax
+       mov     eax, es:ss:[eax]
+       mov     eax, es:[eax]+ss:[eax]
+
+       mov     eax, 3:5
+       call    3:[5]
index f596eb6..e8a80a7 100644 (file)
@@ -1,6 +1,7 @@
 #as: -J
-#objdump: -drwMintel
+#objdump: -dwMintel
 #name: i386 intel-ok
+#stderr: intelok.e
 
 .*: +file format .*
 
@@ -93,20 +94,39 @@ Disassembly of section .text:
 [      ]*[0-9a-f]+:    d7[     ]+xlat(b|[      ]+(BYTE PTR )?(ds:)?\[ebx\])
 [      ]*[0-9a-f]+:    d7[     ]+xlat(b|[      ]+(BYTE PTR )?(ds:)?\[ebx\])
 [      ]*[0-9a-f]+:    d7[     ]+xlat(b|[      ]+(BYTE PTR )?(ds:)?\[ebx\])
-[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\][     ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+byte
-[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\][     ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+byte
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
 [      ]*[0-9a-f]+:    8b 40 04[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+4\]
 [      ]*[0-9a-f]+:    8b 40 04[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+4\]
-[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\][     ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+fword
-[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\][     ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+fword
-[      ]*[0-9a-f]+:    8b 80 04 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\+4\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+qword
-[      ]*[0-9a-f]+:    8b 80 04 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\+4\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+qword
-[      ]*[0-9a-f]+:    8b 80 08 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\+8\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+tbyte
-[      ]*[0-9a-f]+:    8b 80 08 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\+8\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+tbyte
-#[     ]*[0-9a-f]+:    8b 04 85 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+word
-#[     ]*[0-9a-f]+:    8b 04 85 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\][  ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+word
-#[     ]*[0-9a-f]+:    8b 04 85 04 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\+4\][       ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+xmmword
-#[     ]*[0-9a-f]+:    8b 04 85 04 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\+4\][       ]+[0-9a-f]+:[   ]+(R_386_|dir)?32[      ]+xmmword
+[      ]*[0-9a-f]+:    8b 40 06[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+6\]
+[      ]*[0-9a-f]+:    8b 40 06[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+6\]
+[      ]*[0-9a-f]+:    8b 40 0c[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+12\]
+[      ]*[0-9a-f]+:    8b 40 0c[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+12\]
+[      ]*[0-9a-f]+:    8b 40 12[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+18\]
+[      ]*[0-9a-f]+:    8b 40 12[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+18\]
+[      ]*[0-9a-f]+:    8b 04 85 02 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\+2\]
+[      ]*[0-9a-f]+:    8b 04 85 02 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*4\+2\]
+[      ]*[0-9a-f]+:    8b 04 45 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*2\]
+[      ]*[0-9a-f]+:    8b 04 45 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[eax\*2\]
+[      ]*[0-9a-f]+:    8b 04 8d 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[ecx\*4\]
+[      ]*[0-9a-f]+:    8b 04 8d 00 00 00 00[   ]+mov[  ]+eax,(DWORD PTR )?\[ecx\*4\]
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 fb[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\-5\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 0f[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+15\]
+[      ]*[0-9a-f]+:    8b 40 10[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+16\]
+[      ]*[0-9a-f]+:    8b 40 10[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+16\]
+[      ]*[0-9a-f]+:    8b 44 08 10[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+16\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 44 08 01[    ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\+1\]
+[      ]*[0-9a-f]+:    8b 00[  ]+mov[  ]+eax,(DWORD PTR )?\[eax\]
+[      ]*[0-9a-f]+:    8b 04 08[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\]
+[      ]*[0-9a-f]+:    8b 04 08[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+ecx\]
+[      ]*[0-9a-f]+:    26 8b 00[       ]+mov[  ]+eax,es:(DWORD PTR )?\[eax\]
 [      ]*[0-9a-f]+:    6a 01[  ]+push[         ]+0x1
 [      ]*[0-9a-f]+:    6a ff[  ]+push[         ]+0xffffffff
 [      ]*[0-9a-f]+:    6a fe[  ]+push[         ]+0xfffffffe
@@ -120,4 +140,35 @@ Disassembly of section .text:
 [      ]*[0-9a-f]+:    6a 02[  ]+push[         ]+0x2
 [      ]*[0-9a-f]+:    6a 03[  ]+push[         ]+0x3
 [      ]*[0-9a-f]+:    6a 0d[  ]+push[         ]+0xd
+[      ]*[0-9a-f]+:    6a 04[  ]+push[         ]+0x4
+[      ]*[0-9a-f]+:    6a fc[  ]+push[         ]+0xfffffffc
+[      ]*[0-9a-f]+:    6a fb[  ]+push[         ]+0xfffffffb
+[      ]*[0-9a-f]+:    6a fb[  ]+push[         ]+0xfffffffb
+[      ]*[0-9a-f]+:    6a 03[  ]+push[         ]+0x3
+[      ]*[0-9a-f]+:    6a 04[  ]+push[         ]+0x4
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    b8 00 00 00 00[         ]+mov[  ]+eax,0x0
+[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\]
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1]
+[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\]
+[      ]*[0-9a-f]+:    8b 80 01 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
+[      ]*[0-9a-f]+:    8b 80 00 00 00 00[      ]+mov[  ]+eax,(DWORD PTR )?\[eax\]
+[      ]*[0-9a-f]+:    8b 40 01[       ]+mov[  ]+eax,(DWORD PTR )?\[eax\+1\]
+[      ]*[0-9a-f]+:    a1 01 00 00 00[         ]+mov[  ]+eax,ds:0x1
+[      ]*[0-9a-f]+:    a1 ff ff ff ff[         ]+mov[  ]+eax,ds:0xffffffff
+[      ]*[0-9a-f]+:    26 a1 02 00 00 00[      ]+mov[  ]+eax,es:0x2
+#...
+[      ]*[0-9a-f]+:    b8 03 00 00 00[         ]+mov[  ]+eax,0x3
+[      ]*[0-9a-f]+:    a1 04 00 00 00[         ]+mov[  ]+eax,ds:0x4
+[      ]*[0-9a-f]+:    a1 05 00 00 00[         ]+mov[  ]+eax,ds:0x5
+[      ]*[0-9a-f]+:    36 a1 06 00 00 00[      ]+mov[  ]+eax,ss:0x6
+[      ]*[0-9a-f]+:    36 a1 07 00 00 00[      ]+mov[  ]+eax,ss:0x7
+[      ]*[0-9a-f]+:    a1 08 00 00 00[         ]+mov[  ]+eax,ds:0x8
+[      ]*[0-9a-f]+:    9a 05 00 00 00 03 00[   ]+l?call[       ]+0x3[,:]0x5
+[      ]*[0-9a-f]+:    ea 03 00 00 00 05 00[   ]+l?jmp[        ]+0x5[,:]0x3
 #pass
diff --git a/gas/testsuite/gas/i386/intelok.e b/gas/testsuite/gas/i386/intelok.e
new file mode 100644 (file)
index 0000000..8403bf2
--- /dev/null
@@ -0,0 +1,8 @@
+.*: Assembler messages:
+.*:170: Warning: .* taken to mean just .*
+.*:177: Warning: Treating .* as memory reference
+.*:178: Warning: .* taken to mean just .*
+.*:178: Warning: Treating .* as memory reference
+.*:181: Warning: Treating .* as memory reference
+.*:182: Warning: Treating .* as memory reference
+.*:185: Warning: Treating .* as memory reference
index 590d793..a35b38c 100644 (file)
@@ -1,5 +1,12 @@
        .intel_syntax noprefix
+       .equiv byte, 1
+       .equiv word, 2
        .equiv dword, 4
+       .equiv fword, 6
+       .equiv qword, 8
+       .equiv tbyte, 10
+       .equiv oword, 16
+       .equiv xmmword, 16
        .text
 start:
 
@@ -104,10 +111,30 @@ start:
        mov     eax, qword[eax+dword]
        mov     eax, [tbyte+eax+dword*2]
        mov     eax, tbyte[eax+dword*2]
-#      mov     eax, [word+eax*dword]
-#      mov     eax, word[eax*dword]
-#      mov     eax, [xmmword+(eax+1)*dword]
-#      mov     eax, xmmword[(eax+1)*dword]
+       mov     eax, [word+eax*dword]
+       mov     eax, word[eax*dword]
+
+       mov     eax, [eax*+2]
+       mov     eax, [+2*eax]
+       mov     eax, [ecx*dword]
+       mov     eax, [dword*ecx]
+       mov     eax, 1[eax]
+       mov     eax, [eax]+1
+       mov     eax, [eax - 5 + ecx]
+       mov     eax, [eax + 5 and 3 + ecx]
+       mov     eax, [eax + 5*3 + ecx]
+       mov     eax, [oword][eax]
+       mov     eax, [eax][oword]
+       mov     eax, xmmword[eax][ecx]
+       mov     eax, [eax]+1[ecx]
+       mov     eax, [eax][ecx]+1
+       mov     eax, [1][eax][ecx]
+       mov     eax, [eax][1][ecx]
+       mov     eax, [eax][ecx][1]
+       mov     eax, [[eax]]
+       mov     eax, [eax[ecx]]
+       mov     eax, [[eax][ecx]]
+       mov     eax, es:[eax]
 
        # expressions
 
@@ -125,5 +152,41 @@ start:
        push    7 xor 4
        push    8 or 5
 
+       push    +dword
+       push    -dword
+       push    not dword
+       push    not +dword
+       push    not -dword
+       push    not not dword
+
+       # offset expressions
+
+       mov     eax, offset x
+       mov     eax, offset flat:x
+       mov     eax, flat:x
+       mov     eax, offset [x]
+       mov     eax, offset flat:[x]
+       mov     eax, flat:[x]
+       mov     eax, [offset x]
+       mov     eax, [eax + offset x]
+       mov     eax, [eax + offset 1]
+       mov     eax, [offset x + eax]
+       mov     eax, offset x+1[eax]
+       mov     eax, [eax] + offset x
+       mov     eax, [eax] + offset 1
+       mov     eax, offset x + [1]
+       mov     eax, [offset x] - [1]
+       mov     eax, offset x + es:[2]
+       mov     eax, offset x + offset es:[3]
+       mov     eax, [4] + offset x
+       mov     eax, [5] + [offset x]
+       mov     eax, ss:[6] + offset x
+       mov     eax, ss:[7] + [offset x]
+       mov     eax, dword ptr [8]
+
+       # other operands
+       call    3:5
+       jmp     5:3
+
        # Force a good alignment.
        .p2align        4,0
index 92ae3af..7cea081 100644 (file)
@@ -1,6 +1,7 @@
 #as: -J
 #objdump: -dw
 #name: i386 x86_64
+#stderr: x86_64.e
 .*: +file format .*
 
 Disassembly of section .text:
diff --git a/gas/testsuite/gas/i386/x86_64.e b/gas/testsuite/gas/i386/x86_64.e
new file mode 100644 (file)
index 0000000..e11e903
--- /dev/null
@@ -0,0 +1,9 @@
+.*.s: Assembler messages:
+.*:51: Warning: Treating .\[0x22222222\]. as memory reference
+.*:89: Warning: Treating .DWORD PTR \[0x22222222\]. as memory reference
+.*:91: Warning: Treating .\[0x8877665544332211\]. as memory reference
+.*:92: Warning: Treating .\[0x8877665544332211\]. as memory reference
+.*:93: Warning: Treating .\[0x8877665544332211\]. as memory reference
+.*:94: Warning: Treating .\[0x8877665544332211\]. as memory reference
+.*:95: Warning: Treating .\[0x8877665544332211\]. as memory reference
+.*:96: Warning: Treating .\[0x8877665544332211\]. as memory reference
index ad2a48d..4e94a50 100644 (file)
@@ -127,12 +127,12 @@ mov symbol(%rip), %eax
 .intel_syntax noprefix
 
 #immediates - various sizes:
-mov al, flat symbol
-mov ax, flat symbol
-mov eax, flat symbol
-mov rax, flat symbol
+mov al, flat:symbol
+mov ax, flat:symbol
+mov eax, flat:symbol
+mov rax, flat:symbol
 
-#parts aren't supported by the parser
+#parts aren't supported by the parser, yet (and not at all for symbol refs)
 #mov eax, high part symbol
 #mov eax, low part symbol