]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: correct VCVT{,U}SI2SD
authorJan Beulich <jbeulich@suse.com>
Fri, 24 May 2024 09:50:38 +0000 (11:50 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 24 May 2024 09:50:38 +0000 (11:50 +0200)
Properly reject inappropriate suffixes (No_lSuf / No_qSuf mistakenly
omitted by cf665fee1d6c ["x86: re-work AVX512 embedded rounding / SAE"]),
to avoid emitting bad or arbitrarily guessed instructions. Interestingly
check_{long,qword}_suffix() don't help here, which perhaps is another
indication that the way they work right now isn't quite appropriate.

Sadly correcting just the templates breaks operand ambiguity detection,
since so far that worked from a single template permitting more than one
suffix. Here we have ambiguity though which can now be noticed only when
taking all (matching) templates together. Therefore we need to determine
further matching templates (see code comments for constraints), to then
accumulate permitted suffixes across all of them.

gas/config/tc-i386.c
gas/testsuite/gas/i386/x86-64-inval-avx512f.l
gas/testsuite/gas/i386/x86-64-inval-avx512f.s
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index a84e99977dc11ab06d3b76110a6c9822b4ae72c0..1e580b9f6db2e9dae1eb2b6490357506080b4dd8 100644 (file)
@@ -172,7 +172,7 @@ static void optimize_imm (void);
 static bool optimize_disp (const insn_template *t);
 static const insn_template *match_template (char);
 static int check_string (void);
-static int process_suffix (void);
+static int process_suffix (const insn_template *);
 static int check_byte_reg (void);
 static int check_long_reg (void);
 static int check_qword_reg (void);
@@ -6949,7 +6949,7 @@ md_assemble (char *line)
   if (use_unaligned_vector_move)
     encode_with_unaligned_vector_move ();
 
-  if (!process_suffix ())
+  if (!process_suffix (t))
     return;
 
   /* Check if IP-relative addressing requirements can be satisfied.  */
@@ -8361,12 +8361,16 @@ check_VecOperands (const insn_template *t)
        if (operand_type_check (i.types[op], disp)
            && i.op[op].disps->X_op == O_constant)
          {
+           /* Make sure to leave i.types[op].bitfield.disp8 alone upon
+              secondary invocations of match_template().  */
            if (fits_in_disp8 (i.op[op].disps->X_add_number))
              {
-               i.types[op].bitfield.disp8 = 1;
+               if (!i.tm.mnem_off)
+                 i.types[op].bitfield.disp8 = 1;
                return 0;
              }
-           i.types[op].bitfield.disp8 = 0;
+           if (!i.tm.mnem_off)
+             i.types[op].bitfield.disp8 = 0;
          }
     }
 
@@ -9184,6 +9188,11 @@ match_template (char mnem_suffix)
       return NULL;
     }
 
+  /* Don't emit diagnostics or install the template when one was already
+     installed, i.e. when called from process_suffix().  */
+  if (i.tm.mnem_off)
+    return t;
+
   if (!quiet_warnings)
     {
       if (!intel_syntax
@@ -9290,7 +9299,7 @@ check_string (void)
 }
 
 static int
-process_suffix (void)
+process_suffix (const insn_template *t)
 {
   bool is_movx = false;
 
@@ -9465,6 +9474,39 @@ process_suffix (void)
       if (flag_code == CODE_64BIT && !i.tm.opcode_modifier.no_qsuf)
        suffixes |= 1 << 5;
 
+      /* Operand size may be ambiguous only across multiple templates.  Avoid
+        the extra effort though if we already know that multiple suffixes /
+        operand sizes are allowed.  Also limit this to non-SIMD operand sizes
+        (i.e. ones expressable via suffixes) for now.
+        There's one special case though that needs excluding: Insns taking
+        Disp<N> operands also match templates permitting BaseIndex.  JMP in
+        particular would thus wrongly trigger the check further down.  Cover
+        JUMP_DWORD insns here as well, just in case.  */
+      if (i.tm.opcode_modifier.jump != JUMP
+         && i.tm.opcode_modifier.jump != JUMP_DWORD)
+       while (!(suffixes & (suffixes - 1)))
+         {
+           /* Sadly check_VecOperands(), running ahead of install_template(),
+              may update i.memshift.  Save and restore the value here.  */
+           unsigned int memshift = i.memshift;
+
+           current_templates.start = t + 1;
+           t = match_template (0);
+           i.memshift = memshift;
+           if (t == NULL)
+             break;
+           if (!t->opcode_modifier.no_bsuf)
+             suffixes |= 1 << 0;
+           if (!t->opcode_modifier.no_wsuf)
+             suffixes |= 1 << 1;
+           if (!t->opcode_modifier.no_lsuf)
+             suffixes |= 1 << 2;
+           if (!t->opcode_modifier.no_ssuf)
+             suffixes |= 1 << 4;
+           if (flag_code == CODE_64BIT && !t->opcode_modifier.no_qsuf)
+             suffixes |= 1 << 5;
+         }
+
       /* For [XYZ]MMWORD operands inspect operand sizes.  While generally
         also suitable for AT&T syntax mode, it was requested that this be
         restricted to just Intel syntax.  */
index 634683f43cae3eeb84d3cb75be81c107951ed948..8eb8b7edb5b8ea3181ee666118e735d2b1aad350 100644 (file)
@@ -41,6 +41,8 @@
 .*:58: Error: .*
 .*:61: Error: .*unsupported broadcast for `vdpbf16ps'
 .*:62: Error: .*unsupported broadcast for `vcvtne2ps2bf16'
+.*:64: Error: .* `vcvtusi2sd'
+.*:65: Error: .* `vcvtusi2sd'
 GAS LISTING .*
 
 
@@ -107,3 +109,7 @@ GAS LISTING .*
 [      ]*60[   ]+\.att_syntax prefix
 [      ]*61[   ]+vdpbf16ps 8\(%rax\)\{1to8\}, %zmm2, %zmm2
 [      ]*62[   ]+vcvtne2ps2bf16 8\(%rax\)\{1to8\}, %zmm2, %zmm2
+[      ]*63[   ]*
+[      ]*64[   ]+vcvtusi2sdq %eax, %xmm0, %xmm0
+[      ]*65[   ]+vcvtusi2sdl %rax, \{rn-sae\}, %xmm0, %xmm0
+#pass
index 934e9061cfde4015481f8400ecf5127990d15a73..731f2ca8c2f66d11c4ec7e832f9a4d61c611833c 100644 (file)
@@ -60,3 +60,6 @@ _start:
        .att_syntax prefix
        vdpbf16ps 8(%rax){1to8}, %zmm2, %zmm2
        vcvtne2ps2bf16 8(%rax){1to8}, %zmm2, %zmm2
+
+       vcvtusi2sdq %eax, %xmm0, %xmm0
+       vcvtusi2sdl %rax, {rn-sae}, %xmm0, %xmm0
index faaa92c8d11cc620dbca5b81f24034134fc35452..b2c50752bd5b3b76d1f269a1fa7fb99c58d1d0c5 100644 (file)
@@ -2372,14 +2372,14 @@ vcvts<sdh>2usi, 0x<sdh:spfx>79, <sdh:cpu>, Modrm|EVexLIG|<sdh:spc1>|Disp8MemShif
 
 vcvtsd2ss, 0xF25A, AVX512F, Modrm|EVexLIG|Masking|Space0F|Src1VVVV|VexW1|Disp8MemShift=3|NoSuf|StaticRounding|SAE, { RegXMM|Qword|Unspecified|BaseIndex, RegXMM, RegXMM }
 
-vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|ATTSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|ATTSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_sSuf|IntelSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|IntelSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|ATTSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|ATTSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_sSuf|IntelSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
-vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|IntelSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_qSuf|No_sSuf|ATTSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|StaticRounding|SAE|ATTSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_qSuf|No_sSuf|IntelSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtsi2sd, 0xF22A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_lSuf|No_sSuf|StaticRounding|SAE|IntelSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_qSuf|No_sSuf|ATTSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|StaticRounding|SAE|ATTSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_qSuf|No_sSuf|IntelSyntax, { Reg32|Unspecified|BaseIndex, RegXMM, RegXMM }
+vcvtusi2sd, 0xF27B, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_lSuf|No_sSuf|StaticRounding|SAE|IntelSyntax, { Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
 
 vcvtsi2ss, 0xF32A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|ATTSyntax, { Reg32|Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
 vcvtsi2ss, 0xF32A, AVX512F, Modrm|EVexLIG|Space0F|Src1VVVV|Disp8ShiftVL|No_bSuf|No_wSuf|No_sSuf|StaticRounding|SAE|IntelSyntax, { Reg32|Reg64|Unspecified|BaseIndex, RegXMM, RegXMM }
index 76cdfd90519c210c56372246f52d9e93453ce4ec..e9a5d69a18f1468e003472f9f332e453abe48926 100644 (file)
@@ -22785,7 +22785,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtsi2sd, 0x2a, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 0, 0, 7, 0, 2, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -22797,7 +22797,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtsi2sd, 0x2a, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 1, 1, 7, 0, 2, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -22809,7 +22809,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtsi2sd, 0x2a, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 0, 0, 7, 0, 1, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -22821,7 +22821,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtsi2sd, 0x2a, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 1, 1, 7, 0, 1, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -34883,7 +34883,7 @@ static const insn_template i386_optab[] =
       { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
          0, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtusi2sd, 0x7b, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 0, 0, 7, 0, 2, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -34895,7 +34895,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtusi2sd, 0x7b, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 1, 1, 7, 0, 2, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -34907,7 +34907,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtusi2sd, 0x7b, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 0, 0, 7, 0, 1, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },
@@ -34919,7 +34919,7 @@ static const insn_template i386_optab[] =
       { { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          1, 0, 0, 0, 0, 0 } } } },
   { MN_vcvtusi2sd, 0x7b, 3, SPACE_0F, None,
-    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 0, 1, 1, 7, 0, 1, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } },