Fix overflow detection in the Z80 assembler.
[binutils-gdb.git] / gas / config / tc-i386-intel.c
index fee9063afbe4864d679b68473aff3e70c45776d6..3c01b5ee9e27696b3bfc5e8a4311c2b4b126e7f0 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64
-   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   Copyright (C) 2009-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -52,18 +52,20 @@ intel_state;
 #define O_dword_ptr O_md26
 /* qword ptr X_add_symbol */
 #define O_qword_ptr O_md25
-/* oword ptr X_add_symbol */
-#define O_oword_ptr O_md24
+/* mmword ptr X_add_symbol */
+#define O_mmword_ptr O_qword_ptr
 /* fword ptr X_add_symbol */
-#define O_fword_ptr O_md23
+#define O_fword_ptr O_md24
 /* tbyte ptr X_add_symbol */
-#define O_tbyte_ptr O_md22
+#define O_tbyte_ptr O_md23
+/* oword ptr X_add_symbol */
+#define O_oword_ptr O_md22
 /* xmmword ptr X_add_symbol */
-#define O_xmmword_ptr O_md21
+#define O_xmmword_ptr O_oword_ptr
 /* ymmword ptr X_add_symbol */
-#define O_ymmword_ptr O_md20
+#define O_ymmword_ptr O_md21
 /* zmmword ptr X_add_symbol */
-#define O_zmmword_ptr O_md19
+#define O_zmmword_ptr O_md20
 
 static struct
   {
@@ -105,6 +107,7 @@ const i386_types[] =
     I386_TYPE(dword, 4),
     I386_TYPE(fword, 6),
     I386_TYPE(qword, 8),
+    I386_TYPE(mmword, 8),
     I386_TYPE(tbyte, 10),
     I386_TYPE(oword, 16),
     I386_TYPE(xmmword, 16),
@@ -120,6 +123,16 @@ operatorT i386_operator (const char *name, unsigned int operands, char *pc)
 {
   unsigned int j;
 
+#ifdef SVR4_COMMENT_CHARS
+  if (!name && operands == 2 && *input_line_pointer == '\\')
+    switch (input_line_pointer[1])
+      {
+      case '/': input_line_pointer += 2; return O_divide;
+      case '%': input_line_pointer += 2; return O_modulus;
+      case '*': input_line_pointer += 2; return O_multiply;
+      }
+#endif
+
   if (!intel_syntax)
     return O_absent;
 
@@ -270,6 +283,12 @@ i386_intel_simplify_register (expressionS *e)
   else
     reg_num = e->X_md - 1;
 
+  if (reg_num < 0 || reg_num >= (int) i386_regtab_size)
+    {
+      as_bad (_("invalid register number"));
+      return 0;
+    }
+
   if (!intel_state.in_bracket)
     {
       if (i.op[this_operand].regs)
@@ -277,7 +296,7 @@ i386_intel_simplify_register (expressionS *e)
          as_bad (_("invalid use of register"));
          return 0;
        }
-      if (i386_regtab[reg_num].reg_type.bitfield.sreg3
+      if (i386_regtab[reg_num].reg_type.bitfield.class == SReg
          && i386_regtab[reg_num].reg_num == RegFlat)
        {
          as_bad (_("invalid use of pseudo-register"));
@@ -295,9 +314,15 @@ i386_intel_simplify_register (expressionS *e)
     intel_state.base = i386_regtab + reg_num;
   else if (!intel_state.index)
     {
+      const insn_template *t = current_templates->start;
+
       if (intel_state.in_scale
-         || current_templates->start->base_opcode == 0xf30f1b /* bndmk */
-         || (current_templates->start->base_opcode & ~1) == 0x0f1a /* bnd{ld,st}x */
+         || (t->opcode_modifier.opcodeprefix == PREFIX_0XF3
+             && t->opcode_modifier.opcodespace == SPACE_0F
+             && t->base_opcode == 0x1b /* bndmk */)
+         || (t->opcode_modifier.opcodeprefix == PREFIX_NONE
+             && t->opcode_modifier.opcodespace == SPACE_0F
+             && (t->base_opcode & ~1) == 0x1a /* bnd{ld,st}x */)
          || i386_regtab[reg_num].reg_type.bitfield.baseindex)
        intel_state.index = i386_regtab + reg_num;
       else
@@ -310,7 +335,7 @@ i386_intel_simplify_register (expressionS *e)
   else
     {
       /* esp is invalid as index */
-      intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM;
+      intel_state.index = reg_eax + ESP_REG_NUM;
     }
   return 2;
 }
@@ -377,10 +402,9 @@ static int i386_intel_simplify (expressionS *e)
     case O_word_ptr:
     case O_dword_ptr:
     case O_fword_ptr:
-    case O_qword_ptr:
+    case O_qword_ptr: /* O_mmword_ptr */
     case O_tbyte_ptr:
-    case O_oword_ptr:
-    case O_xmmword_ptr:
+    case O_oword_ptr: /* O_xmmword_ptr */
     case O_ymmword_ptr:
     case O_zmmword_ptr:
     case O_near_ptr:
@@ -476,7 +500,7 @@ static int i386_intel_simplify (expressionS *e)
                break;
              default:
                /* esp is invalid as index */
-               intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM;
+               intel_state.index = reg_eax + ESP_REG_NUM;
                break;
              }
 
@@ -501,7 +525,7 @@ static int i386_intel_simplify (expressionS *e)
 
       /* FALLTHROUGH */
     default:
-fallthrough:
+    fallthrough:
       if (e->X_add_symbol
          && !i386_intel_simplify_symbol (e->X_add_symbol))
        return 0;
@@ -620,7 +644,8 @@ i386_intel_operand (char *operand_string, int got_a_float)
     return 0;
 
   if (intel_state.op_modifier != O_absent
-      && current_templates->start->base_opcode != 0x8d /* lea */)
+      && (current_templates->start->opcode_modifier.opcodespace != SPACE_BASE
+          || current_templates->start->base_opcode != 0x8d /* lea */))
     {
       i.types[this_operand].bitfield.unspecified = 0;
 
@@ -633,12 +658,7 @@ i386_intel_operand (char *operand_string, int got_a_float)
 
        case O_word_ptr:
          i.types[this_operand].bitfield.word = 1;
-         if ((current_templates->start->name[0] == 'l'
-              && current_templates->start->name[2] == 's'
-              && current_templates->start->name[3] == 0)
-             || current_templates->start->base_opcode == 0x62 /* bound */)
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
-         else if (got_a_float == 2)    /* "fi..." */
+         if (got_a_float == 2) /* "fi..." */
            suffix = SHORT_MNEM_SUFFIX;
          else
            suffix = WORD_MNEM_SUFFIX;
@@ -649,12 +669,15 @@ i386_intel_operand (char *operand_string, int got_a_float)
          if ((current_templates->start->name[0] == 'l'
               && current_templates->start->name[2] == 's'
               && current_templates->start->name[3] == 0)
-             || current_templates->start->base_opcode == 0x62 /* bound */)
+             || (current_templates->start->opcode_modifier.opcodespace == SPACE_BASE
+                 && current_templates->start->base_opcode == 0x62 /* bound */))
            suffix = WORD_MNEM_SUFFIX;
-         else if (flag_code == CODE_16BIT
-                  && (current_templates->start->opcode_modifier.jump
-                      || current_templates->start->opcode_modifier.jumpdword))
-           suffix = LONG_DOUBLE_MNEM_SUFFIX;
+         else if (flag_code != CODE_32BIT
+                  && (current_templates->start->opcode_modifier.jump == JUMP
+                      || current_templates->start->opcode_modifier.jump
+                         == JUMP_DWORD))
+           suffix = flag_code == CODE_16BIT ? LONG_DOUBLE_MNEM_SUFFIX
+                                            : WORD_MNEM_SUFFIX;
          else if (got_a_float == 1)    /* "f..." */
            suffix = SHORT_MNEM_SUFFIX;
          else
@@ -673,13 +696,12 @@ i386_intel_operand (char *operand_string, int got_a_float)
                add_prefix (DATA_PREFIX_OPCODE);
              suffix = LONG_DOUBLE_MNEM_SUFFIX;
            }
-         else
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
          break;
 
-       case O_qword_ptr:
+       case O_qword_ptr: /* O_mmword_ptr */
          i.types[this_operand].bitfield.qword = 1;
-         if (current_templates->start->base_opcode == 0x62 /* bound */
+         if ((current_templates->start->opcode_modifier.opcodespace == SPACE_BASE
+              && current_templates->start->base_opcode == 0x62 /* bound */)
              || got_a_float == 1)      /* "f..." */
            suffix = LONG_MNEM_SUFFIX;
          else
@@ -690,12 +712,17 @@ i386_intel_operand (char *operand_string, int got_a_float)
          i.types[this_operand].bitfield.tbyte = 1;
          if (got_a_float == 1)
            suffix = LONG_DOUBLE_MNEM_SUFFIX;
+         else if ((current_templates->start->operand_types[0].bitfield.fword
+                   || current_templates->start->operand_types[0].bitfield.tbyte
+                   || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+                   || current_templates->start->opcode_modifier.jump == JUMP)
+                  && flag_code == CODE_64BIT)
+           suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */
          else
-           suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
+           i.types[this_operand].bitfield.byte = 1; /* cause an error */
          break;
 
-       case O_oword_ptr:
-       case O_xmmword_ptr:
+       case O_oword_ptr: /* O_xmmword_ptr */
          i.types[this_operand].bitfield.xmmword = 1;
          break;
 
@@ -711,11 +738,14 @@ i386_intel_operand (char *operand_string, int got_a_float)
          suffix = LONG_DOUBLE_MNEM_SUFFIX;
          /* FALLTHROUGH */
        case O_near_ptr:
-         if (!current_templates->start->opcode_modifier.jump
-             && !current_templates->start->opcode_modifier.jumpdword)
-           suffix = got_a_float /* so it will cause an error */
-                    ? BYTE_MNEM_SUFFIX
-                    : LONG_DOUBLE_MNEM_SUFFIX;
+         if (current_templates->start->opcode_modifier.jump != JUMP
+             && current_templates->start->opcode_modifier.jump != JUMP_DWORD)
+           {
+             /* cause an error */
+             i.types[this_operand].bitfield.byte = 1;
+             i.types[this_operand].bitfield.tbyte = 1;
+             suffix = i.suffix;
+           }
          break;
 
        default:
@@ -733,21 +763,23 @@ i386_intel_operand (char *operand_string, int got_a_float)
     }
 
   /* Operands for jump/call need special consideration.  */
-  if (current_templates->start->opcode_modifier.jump
-      || current_templates->start->opcode_modifier.jumpdword
-      || current_templates->start->opcode_modifier.jumpintersegment)
+  if (current_templates->start->opcode_modifier.jump == JUMP
+      || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+      || current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT)
     {
+      bool jumpabsolute = false;
+
       if (i.op[this_operand].regs
          || intel_state.base
          || intel_state.index
          || intel_state.is_mem > 1)
-       i.types[this_operand].bitfield.jumpabsolute = 1;
+       jumpabsolute = true;
       else
        switch (intel_state.op_modifier)
          {
          case O_near_ptr:
            if (intel_state.seg)
-             i.types[this_operand].bitfield.jumpabsolute = 1;
+             jumpabsolute = true;
            else
              intel_state.is_mem = 1;
            break;
@@ -759,14 +791,14 @@ i386_intel_operand (char *operand_string, int got_a_float)
                if (intel_state.op_modifier == O_absent)
                  {
                    if (intel_state.is_indirect == 1)
-                     i.types[this_operand].bitfield.jumpabsolute = 1;
+                     jumpabsolute = true;
                    break;
                  }
                as_bad (_("cannot infer the segment part of the operand"));
                return 0;
              }
            else if (S_GET_SEGMENT (intel_state.seg) == reg_section)
-             i.types[this_operand].bitfield.jumpabsolute = 1;
+             jumpabsolute = true;
            else
              {
                i386_operand_type types;
@@ -800,11 +832,14 @@ i386_intel_operand (char *operand_string, int got_a_float)
              }
            break;
          default:
-           i.types[this_operand].bitfield.jumpabsolute = 1;
+           jumpabsolute = true;
            break;
          }
-      if (i.types[this_operand].bitfield.jumpabsolute)
-       intel_state.is_mem |= 1;
+      if (jumpabsolute)
+       {
+         i.jumpabsolute = true;
+         intel_state.is_mem |= 1;
+       }
     }
   else if (intel_state.seg)
     intel_state.is_mem |= 1;
@@ -846,9 +881,9 @@ i386_intel_operand (char *operand_string, int got_a_float)
             ljmp       0x9090,0x90909090
           */
 
-         if ((current_templates->start->opcode_modifier.jumpintersegment
-              || current_templates->start->opcode_modifier.jumpdword
-              || current_templates->start->opcode_modifier.jump)
+         if ((current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT
+              || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+              || current_templates->start->opcode_modifier.jump == JUMP)
              && this_operand == 1
              && intel_state.seg == NULL
              && i.mem_operands == 1
@@ -925,12 +960,13 @@ i386_intel_operand (char *operand_string, int got_a_float)
 
          if (flag_code == CODE_64BIT)
            {
-             i.types[this_operand].bitfield.disp32 = 1;
              if (!i.prefix[ADDR_PREFIX])
                {
                  i.types[this_operand].bitfield.disp64 = 1;
                  i.types[this_operand].bitfield.disp32s = 1;
                }
+             else
+               i.types[this_operand].bitfield.disp32 = 1;
            }
          else if (!i.prefix[ADDR_PREFIX] ^ (flag_code == CODE_16BIT))
            i.types[this_operand].bitfield.disp32 = 1;
@@ -978,8 +1014,7 @@ i386_intel_operand (char *operand_string, int got_a_float)
              as_bad (_("segment register name expected"));
              return 0;
            }
-         if (!i386_regtab[expP->X_add_number].reg_type.bitfield.sreg2
-             && !i386_regtab[expP->X_add_number].reg_type.bitfield.sreg3)
+         if (i386_regtab[expP->X_add_number].reg_type.bitfield.class != SReg)
            {
              as_bad (_("invalid use of register"));
              return 0;
@@ -993,16 +1028,10 @@ i386_intel_operand (char *operand_string, int got_a_float)
              as_warn (_("redundant segment overrides"));
              break;
            }
-         switch (i386_regtab[expP->X_add_number].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;
-           case RegFlat: i.seg[i.mem_operands] = NULL; break;
-           }
+         if (i386_regtab[expP->X_add_number].reg_num == RegFlat)
+           i.seg[i.mem_operands] = NULL;
+         else
+           i.seg[i.mem_operands] = &i386_regtab[expP->X_add_number];
        }
 
       if (!i386_index_check (operand_string))