From: Jan Beulich Date: Wed, 6 Jul 2022 13:39:03 +0000 (+0200) Subject: x86: fix 3-operand insn reverse-matching X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c975cec5fffacc073866be11c0599c97054b3052;p=binutils-gdb.git x86: fix 3-operand insn reverse-matching The middle operand would have gone entirely unchecked, allowing e.g. vmovss %xmm0, %esp, %xmm2 to assemble successfully, or e.g. vmovss %xmm0, $4, %xmm2 causing an internal error. Alongside dealing with this also drop a related comment, which hasn't been applicable anymore since the introduction of 3-operand patterns with D set (and which perhaps never had been logical to be there, as reverse-matched insns don't make it there in the first place). --- diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d915b15a6b2..542f5cdf2d0 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6724,8 +6724,12 @@ match_template (char mnem_suffix) /* Try reversing direction of operands. */ overlap0 = operand_type_and (i.types[0], operand_types[i.operands - 1]); overlap1 = operand_type_and (i.types[i.operands - 1], operand_types[0]); + overlap2 = operand_type_and (i.types[1], operand_types[1]); + gas_assert (t->operands != 3 || !check_register); if (!operand_type_match (overlap0, i.types[0]) || !operand_type_match (overlap1, i.types[i.operands - 1]) + || (t->operands == 3 + && !operand_type_match (overlap2, i.types[1])) || (check_register && !operand_type_register_match (i.types[0], operand_types[i.operands - 1], @@ -6797,8 +6801,6 @@ match_template (char mnem_suffix) continue; /* Fall through. */ case 3: - /* Here we make use of the fact that there are no - reverse match 3 operand instructions. */ if (!operand_type_match (overlap2, i.types[2]) || ((check_register & 5) == 5 && !operand_type_register_match (i.types[0], diff --git a/gas/testsuite/gas/i386/inval-avx.l b/gas/testsuite/gas/i386/inval-avx.l index 866987e784f..0b475276dc7 100644 --- a/gas/testsuite/gas/i386/inval-avx.l +++ b/gas/testsuite/gas/i386/inval-avx.l @@ -2,20 +2,13 @@ .*:4: Error: .* .*:5: Error: .* .*:6: Error: .* -.*:9: Error:.* ambiguous .* `vcvtpd2dq' -.*:10: Error:.* ambiguous .* `vcvtpd2ps' -.*:11: Error:.* ambiguous .* `vcvttpd2dq' +.*:8: Error: .* +.*:9: Error: .* +.*:10: Error: .* +.*:11: Error: .* +.*:12: Error: .* +.*:15: Error:.* ambiguous .* `vcvtpd2dq' +.*:16: Error:.* ambiguous .* `vcvtpd2ps' +.*:17: Error:.* ambiguous .* `vcvttpd2dq' GAS LISTING .* - - -[ ]*1[ ]+\# Check illegal AVX instructions -[ ]*2[ ]+\.text -[ ]*3[ ]+_start: -[ ]*4[ ]+vcvtpd2dq \(%ecx\),%xmm2 -[ ]*5[ ]+vcvtpd2ps \(%ecx\),%xmm2 -[ ]*6[ ]+vcvttpd2dq \(%ecx\),%xmm2 -[ ]*7[ ]+ -[ ]*8[ ]+\.intel_syntax noprefix -[ ]*9[ ]+vcvtpd2dq xmm2,\[ecx\] -[ ]*10[ ]+vcvtpd2ps xmm2,\[ecx\] -[ ]*11[ ]+vcvttpd2dq xmm2,\[ecx\] +#pass diff --git a/gas/testsuite/gas/i386/inval-avx.s b/gas/testsuite/gas/i386/inval-avx.s index 94a64f62888..741901a96cf 100644 --- a/gas/testsuite/gas/i386/inval-avx.s +++ b/gas/testsuite/gas/i386/inval-avx.s @@ -5,6 +5,12 @@ _start: vcvtpd2ps (%ecx),%xmm2 vcvttpd2dq (%ecx),%xmm2 + vmovss %xmm0, (%esp), %xmm2 + vmovss %xmm0, $4, %xmm2 + vmovss %xmm0, %cr0, %xmm2 + vmovss %xmm0, %ymm4, %xmm2 + vmovss %xmm0, %mm4, %xmm2 + .intel_syntax noprefix vcvtpd2dq xmm2,[ecx] vcvtpd2ps xmm2,[ecx]