x86: make sure all PUSH/POP honor DefaultSize
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index fcd6215a26a8b908ad0171e8064bd134b39cb2e6..b8babed68ba0b96c6df9530582f47f8a4dffe1af 100644 (file)
@@ -2066,11 +2066,9 @@ operand_size_match (const insn_template *t)
 {
   unsigned int j, match = MATCH_STRAIGHT;
 
-  /* Don't check jump instructions.  */
+  /* Don't check non-absolute jump instructions.  */
   if (t->opcode_modifier.jump
-      || t->opcode_modifier.jumpbyte
-      || t->opcode_modifier.jumpdword
-      || t->opcode_modifier.jumpintersegment)
+      && t->opcode_modifier.jump != JUMP_ABSOLUTE)
     return match;
 
   /* Check memory and accumulator operand size.  */
@@ -4462,9 +4460,9 @@ md_assemble (char *line)
       i.imm_operands = 0;
     }
 
-  if ((i.tm.opcode_modifier.jump
-       || i.tm.opcode_modifier.jumpbyte
-       || i.tm.opcode_modifier.jumpdword)
+  if ((i.tm.opcode_modifier.jump == JUMP
+       || i.tm.opcode_modifier.jump == JUMP_BYTE
+       || i.tm.opcode_modifier.jump == JUMP_DWORD)
       && i.op[0].disps->X_op == O_constant)
     {
       /* Convert "jmp constant" (and "call constant") to a jump (call) to
@@ -4764,8 +4762,8 @@ check_suffix:
        }
     }
 
-  if (current_templates->start->opcode_modifier.jump
-      || current_templates->start->opcode_modifier.jumpbyte)
+  if (current_templates->start->opcode_modifier.jump == JUMP
+      || current_templates->start->opcode_modifier.jump == JUMP_BYTE)
     {
       /* Check for a branch hint.  We allow ",pt" and ",pn" for
         predict taken and predict not taken respectively.
@@ -5745,11 +5743,11 @@ match_template (char mnem_suffix)
 
       /* This is intentionally not
 
-        if (i.jumpabsolute != t->opcode_modifier.jumpabsolute)
+        if (i.jumpabsolute != (t->opcode_modifier.jump == JUMP_ABSOLUTE))
 
         as the case of a missing * on the operand is accepted (perhaps with
         a warning, issued further down).  */
-      if (i.jumpabsolute && !t->opcode_modifier.jumpabsolute)
+      if (i.jumpabsolute && t->opcode_modifier.jump != JUMP_ABSOLUTE)
        {
          i.error = operand_type_mismatch;
          continue;
@@ -6132,7 +6130,7 @@ check_reverse:
   if (!quiet_warnings)
     {
       if (!intel_syntax
-         && (i.jumpabsolute != t->opcode_modifier.jumpabsolute))
+         && (i.jumpabsolute != (t->opcode_modifier.jump == JUMP_ABSOLUTE)))
        as_warn (_("indirect %s without `*'"), t->name);
 
       if (t->opcode_modifier.isprefix
@@ -6209,10 +6207,11 @@ process_suffix (void)
     i.suffix = LONG_MNEM_SUFFIX;
   else if (i.tm.opcode_modifier.size == SIZE64)
     i.suffix = QWORD_MNEM_SUFFIX;
-  else if (i.reg_operands)
+  else if (i.reg_operands
+          && (i.operands > 1 || i.types[0].bitfield.class == Reg))
     {
       /* If there's no instruction mnemonic suffix we try to invent one
-        based on register operands.  */
+        based on GPR operands.  */
       if (!i.suffix)
        {
          /* We take i.suffix from the last register operand specified,
@@ -6313,27 +6312,34 @@ process_suffix (void)
   else if (i.tm.opcode_modifier.defaultsize
           && !i.suffix
           /* exclude fldenv/frstor/fsave/fstenv */
-          && i.tm.opcode_modifier.no_ssuf)
+          && i.tm.opcode_modifier.no_ssuf
+          /* exclude sysret */
+          && i.tm.base_opcode != 0x0f07)
     {
-      if (stackop_size == LONG_MNEM_SUFFIX
-         && i.tm.base_opcode == 0xcf)
+      i.suffix = stackop_size;
+      if (stackop_size == LONG_MNEM_SUFFIX)
        {
          /* stackop_size is set to LONG_MNEM_SUFFIX for the
             .code16gcc directive to support 16-bit mode with
             32-bit address.  For IRET without a suffix, generate
             16-bit IRET (opcode 0xcf) to return from an interrupt
             handler.  */
-         i.suffix = WORD_MNEM_SUFFIX;
-         as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+         if (i.tm.base_opcode == 0xcf)
+           {
+             i.suffix = WORD_MNEM_SUFFIX;
+             as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+           }
+         /* Warn about changed behavior for segment register push/pop.  */
+         else if ((i.tm.base_opcode | 1) == 0x07)
+           as_warn (_("generating 32-bit `%s', unlike earlier gas versions"),
+                    i.tm.name);
        }
-      else
-       i.suffix = stackop_size;
     }
   else if (intel_syntax
           && !i.suffix
-          && (i.tm.opcode_modifier.jumpabsolute
-              || i.tm.opcode_modifier.jumpbyte
-              || i.tm.opcode_modifier.jumpintersegment
+          && (i.tm.opcode_modifier.jump == JUMP_ABSOLUTE
+              || i.tm.opcode_modifier.jump == JUMP_BYTE
+              || i.tm.opcode_modifier.jump == JUMP_INTERSEGMENT
               || (i.tm.base_opcode == 0x0f01 /* [ls][gi]dt */
                   && i.tm.extension_opcode <= 3)))
     {
@@ -6443,11 +6449,11 @@ process_suffix (void)
               && !is_any_vex_encoding (&i.tm)
               && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
                   || (flag_code == CODE_64BIT
-                      && i.tm.opcode_modifier.jumpbyte)))
+                      && i.tm.opcode_modifier.jump == JUMP_BYTE)))
        {
          unsigned int prefix = DATA_PREFIX_OPCODE;
 
-         if (i.tm.opcode_modifier.jumpbyte) /* jcxz, loop */
+         if (i.tm.opcode_modifier.jump == JUMP_BYTE) /* jcxz, loop */
            prefix = ADDR_PREFIX_OPCODE;
 
          if (!add_prefix (prefix))
@@ -7898,7 +7904,7 @@ output_jump (void)
   fixS *fixP;
   bfd_reloc_code_real_type jump_reloc = i.reloc[0];
 
-  if (i.tm.opcode_modifier.jumpbyte)
+  if (i.tm.opcode_modifier.jump == JUMP_BYTE)
     {
       /* This is a loop or jecxz type instruction.  */
       size = 1;
@@ -8289,12 +8295,12 @@ output_insn (void)
   insn_start_off = frag_now_fix ();
 
   /* Output jumps.  */
-  if (i.tm.opcode_modifier.jump)
+  if (i.tm.opcode_modifier.jump == JUMP)
     output_branch ();
-  else if (i.tm.opcode_modifier.jumpbyte
-          || i.tm.opcode_modifier.jumpdword)
+  else if (i.tm.opcode_modifier.jump == JUMP_BYTE
+          || i.tm.opcode_modifier.jump == JUMP_DWORD)
     output_jump ();
-  else if (i.tm.opcode_modifier.jumpintersegment)
+  else if (i.tm.opcode_modifier.jump == JUMP_INTERSEGMENT)
     output_interseg_jump ();
   else
     {
@@ -9474,8 +9480,8 @@ i386_displacement (char *disp_start, char *disp_end)
 
   operand_type_set (&bigdisp, 0);
   if (i.jumpabsolute
-      || (!current_templates->start->opcode_modifier.jump
-         && !current_templates->start->opcode_modifier.jumpdword))
+      || (current_templates->start->opcode_modifier.jump != JUMP
+         && current_templates->start->opcode_modifier.jump != JUMP_DWORD))
     {
       bigdisp.bitfield.disp32 = 1;
       override = (i.prefix[ADDR_PREFIX] != 0);
This page took 0.02769 seconds and 4 git commands to generate.