x86: further refine SSE check (SSE4a, SHA, GFNI)
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index fcd6215a26a8b908ad0171e8064bd134b39cb2e6..accb6342038a5de8ea520fd19451fa96dce5bf77 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.  */
@@ -4288,14 +4286,17 @@ md_assemble (char *line)
   if (sse_check != check_none
       && !i.tm.opcode_modifier.noavx
       && !i.tm.cpu_flags.bitfield.cpuavx
+      && !i.tm.cpu_flags.bitfield.cpuavx512f
       && (i.tm.cpu_flags.bitfield.cpusse
          || i.tm.cpu_flags.bitfield.cpusse2
          || i.tm.cpu_flags.bitfield.cpusse3
          || i.tm.cpu_flags.bitfield.cpussse3
          || i.tm.cpu_flags.bitfield.cpusse4_1
          || i.tm.cpu_flags.bitfield.cpusse4_2
+         || i.tm.cpu_flags.bitfield.cpusse4a
          || i.tm.cpu_flags.bitfield.cpupclmul
          || i.tm.cpu_flags.bitfield.cpuaes
+         || i.tm.cpu_flags.bitfield.cpusha
          || i.tm.cpu_flags.bitfield.cpugfni))
     {
       (sse_check == check_warning
@@ -4462,9 +4463,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 +4765,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 +5746,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 +6133,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 +6210,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 +6315,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 +6452,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 +7907,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;
@@ -8253,15 +8262,9 @@ output_insn (void)
          || i.tm.cpu_flags.bitfield.cpu687
          || i.tm.cpu_flags.bitfield.cpufisttp)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87;
-      /* Don't set GNU_PROPERTY_X86_FEATURE_2_MMX for prefetchtXXX nor
-        Xfence instructions.  */
-      if (i.tm.base_opcode != 0xf18
-         && i.tm.base_opcode != 0xf0d
-         && i.tm.base_opcode != 0xfaef8
-         && (i.has_regmmx
-             || i.tm.cpu_flags.bitfield.cpummx
-             || i.tm.cpu_flags.bitfield.cpua3dnow
-             || i.tm.cpu_flags.bitfield.cpua3dnowa))
+      if (i.has_regmmx
+         || i.tm.base_opcode == 0xf77 /* emms */
+         || i.tm.base_opcode == 0xf0e /* femms */)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX;
       if (i.has_regxmm)
        x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM;
@@ -8289,12 +8292,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 +9477,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.027654 seconds and 4 git commands to generate.