x86: Extract extended states from instruction template

Extract extended states from operand types in instruction template.  Set
xstate_zmm for master register move.

	* config/tc-i386.c (_i386_insn): Remove has_regmmx, has_regxmm,
	has_regymm, has_regzmm and has_regtmm.  Add xstate.
	(md_assemble): Set i.xstate from operand types in instruction
	template.
	(build_modrm_byte): Updated.
	(output_insn): Check i.xstate.
	* testsuite/gas/i386/i386.exp: Run property-6 and
	x86-64-property-6.
	* testsuite/gas/i386/property-6.d: New file.
	* testsuite/gas/i386/property-6.s: Updated.
	* testsuite/gas/i386/x86-64-property-6.d: Likewise.
This commit is contained in:
H.J. Lu
2020-07-10 08:43:37 -07:00
parent d249bf8670
commit 921eafeada
6 changed files with 91 additions and 73 deletions

View File

@ -1,3 +1,17 @@
2020-07-10 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (_i386_insn): Remove has_regmmx, has_regxmm,
has_regymm, has_regzmm and has_regtmm. Add xstate.
(md_assemble): Set i.xstate from operand types in instruction
template.
(build_modrm_byte): Updated.
(output_insn): Check i.xstate.
* testsuite/gas/i386/i386.exp: Run property-6 and
x86-64-property-6.
* testsuite/gas/i386/property-6.d: New file.
* testsuite/gas/i386/property-6.s: Updated.
* testsuite/gas/i386/x86-64-property-6.d: Likewise.
2020-07-10 H.J. Lu <hongjiu.lu@intel.com> 2020-07-10 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/gas/i386/property-5.d: Correct test name. * testsuite/gas/i386/property-5.d: Correct test name.

View File

@ -362,20 +362,20 @@ struct _i386_insn
/* The operand to a branch insn indicates an absolute branch. */ /* The operand to a branch insn indicates an absolute branch. */
bfd_boolean jumpabsolute; bfd_boolean jumpabsolute;
/* Has MMX register operands. */ /* Extended states. */
bfd_boolean has_regmmx; enum
{
/* Has XMM register operands. */ /* Use MMX state. */
bfd_boolean has_regxmm; xstate_mmx = 1 << 0,
/* Use XMM state. */
/* Has YMM register operands. */ xstate_xmm = 1 << 1,
bfd_boolean has_regymm; /* Use YMM state. */
xstate_ymm = 1 << 2 | xstate_xmm,
/* Has ZMM register operands. */ /* Use ZMM state. */
bfd_boolean has_regzmm; xstate_zmm = 1 << 3 | xstate_ymm,
/* Use TMM state. */
/* Has TMM register operands. */ xstate_tmm = 1 << 4
bfd_boolean has_regtmm; } xstate;
/* Has GOTPC or TLS relocation. */ /* Has GOTPC or TLS relocation. */
bfd_boolean has_gotpc_tls_reloc; bfd_boolean has_gotpc_tls_reloc;
@ -4864,9 +4864,32 @@ md_assemble (char *line)
if (!process_suffix ()) if (!process_suffix ())
return; return;
/* Update operand types. */ /* Update operand types and check extended states. */
for (j = 0; j < i.operands; j++) for (j = 0; j < i.operands; j++)
i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]); {
i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]);
switch (i.tm.operand_types[j].bitfield.class)
{
default:
break;
case RegMMX:
i.xstate |= xstate_mmx;
break;
case RegMask:
i.xstate |= xstate_zmm;
break;
case RegSIMD:
if (i.tm.operand_types[j].bitfield.tmmword)
i.xstate |= xstate_tmm;
else if (i.tm.operand_types[j].bitfield.zmmword)
i.xstate |= xstate_zmm;
else if (i.tm.operand_types[j].bitfield.ymmword)
i.xstate |= xstate_ymm;
else if (i.tm.operand_types[j].bitfield.xmmword)
i.xstate |= xstate_xmm;
break;
}
}
/* Make still unresolved immediate matches conform to size of immediate /* Make still unresolved immediate matches conform to size of immediate
given in i.suffix. */ given in i.suffix. */
@ -7958,24 +7981,6 @@ build_modrm_byte (void)
{ {
i.rm.reg = i.op[dest].regs->reg_num; i.rm.reg = i.op[dest].regs->reg_num;
i.rm.regmem = i.op[source].regs->reg_num; i.rm.regmem = i.op[source].regs->reg_num;
if (i.op[dest].regs->reg_type.bitfield.class == RegMMX
|| i.op[source].regs->reg_type.bitfield.class == RegMMX)
i.has_regmmx = TRUE;
else if (i.op[dest].regs->reg_type.bitfield.class == RegSIMD
|| i.op[source].regs->reg_type.bitfield.class == RegSIMD)
{
if (i.types[dest].bitfield.tmmword
|| i.types[source].bitfield.tmmword)
i.has_regtmm = TRUE;
else if (i.types[dest].bitfield.zmmword
|| i.types[source].bitfield.zmmword)
i.has_regzmm = TRUE;
else if (i.types[dest].bitfield.ymmword
|| i.types[source].bitfield.ymmword)
i.has_regymm = TRUE;
else
i.has_regxmm = TRUE;
}
set_rex_vrex (i.op[dest].regs, REX_R, i.tm.opcode_modifier.sse2avx); set_rex_vrex (i.op[dest].regs, REX_R, i.tm.opcode_modifier.sse2avx);
set_rex_vrex (i.op[source].regs, REX_B, FALSE); set_rex_vrex (i.op[source].regs, REX_B, FALSE);
} }
@ -8319,33 +8324,16 @@ build_modrm_byte (void)
unsigned int vex_reg = ~0; unsigned int vex_reg = ~0;
for (op = 0; op < i.operands; op++) for (op = 0; op < i.operands; op++)
{ if (i.types[op].bitfield.class == Reg
if (i.types[op].bitfield.class == Reg || i.types[op].bitfield.class == RegBND
|| i.types[op].bitfield.class == RegBND || i.types[op].bitfield.class == RegMask
|| i.types[op].bitfield.class == RegMask || i.types[op].bitfield.class == SReg
|| i.types[op].bitfield.class == SReg || i.types[op].bitfield.class == RegCR
|| i.types[op].bitfield.class == RegCR || i.types[op].bitfield.class == RegDR
|| i.types[op].bitfield.class == RegDR || i.types[op].bitfield.class == RegTR
|| i.types[op].bitfield.class == RegTR) || i.types[op].bitfield.class == RegSIMD
break; || i.types[op].bitfield.class == RegMMX)
if (i.types[op].bitfield.class == RegSIMD) break;
{
if (i.types[op].bitfield.tmmword)
i.has_regtmm = TRUE;
else if (i.types[op].bitfield.zmmword)
i.has_regzmm = TRUE;
else if (i.types[op].bitfield.ymmword)
i.has_regymm = TRUE;
else
i.has_regxmm = TRUE;
break;
}
if (i.types[op].bitfield.class == RegMMX)
{
i.has_regmmx = TRUE;
break;
}
}
if (vex_3_sources) if (vex_3_sources)
op = dest; op = dest;
@ -9177,22 +9165,15 @@ output_insn (void)
|| i.tm.cpu_flags.bitfield.cpu687 || i.tm.cpu_flags.bitfield.cpu687
|| i.tm.cpu_flags.bitfield.cpufisttp) || i.tm.cpu_flags.bitfield.cpufisttp)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87;
if (i.has_regmmx if ((i.xstate & xstate_mmx)
|| i.tm.base_opcode == 0xf77 /* emms */ || i.tm.base_opcode == 0xf77 /* emms */
|| i.tm.base_opcode == 0xf0e /* femms */ || i.tm.base_opcode == 0xf0e /* femms */)
|| i.tm.base_opcode == 0xf2a /* cvtpi2ps */
|| i.tm.base_opcode == 0x660f2a /* cvtpi2pd */)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX;
if (i.has_regxmm) if ((i.xstate & xstate_xmm))
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM;
if (i.has_regymm if ((i.xstate & xstate_ymm) == xstate_ymm)
|| (i.has_regxmm
&& (i.tm.opcode_modifier.vex
|| i.tm.opcode_modifier.evex)))
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_YMM; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_YMM;
if (i.has_regzmm if ((i.xstate & xstate_zmm) == xstate_zmm)
|| ((i.has_regxmm || i.has_regymm)
&& i.tm.opcode_modifier.evex))
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_ZMM; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_ZMM;
if (i.tm.cpu_flags.bitfield.cpufxsr) if (i.tm.cpu_flags.bitfield.cpufxsr)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_FXSR; x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_FXSR;

View File

@ -624,6 +624,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "property-3" run_dump_test "property-3"
run_dump_test "property-4" run_dump_test "property-4"
run_dump_test "property-5" run_dump_test "property-5"
run_dump_test "property-6"
if {[istarget "*-*-linux*"]} then { if {[istarget "*-*-linux*"]} then {
run_dump_test "align-branch-3" run_dump_test "align-branch-3"
@ -1215,6 +1216,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
run_dump_test "x86-64-property-3" run_dump_test "x86-64-property-3"
run_dump_test "x86-64-property-4" run_dump_test "x86-64-property-4"
run_dump_test "x86-64-property-5" run_dump_test "x86-64-property-5"
run_dump_test "x86-64-property-6"
if {[istarget "*-*-linux*"]} then { if {[istarget "*-*-linux*"]} then {
run_dump_test "x86-64-align-branch-3" run_dump_test "x86-64-align-branch-3"

View File

@ -0,0 +1,9 @@
#name: i386 property 6
#as: -mx86-used-note=yes --generate-missing-build-notes=no
#readelf: -n
Displaying notes found in: .note.gnu.property
[ ]+Owner[ ]+Data size[ ]+Description
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA used: AVX512F
x86 feature used: x86, XMM, YMM, ZMM

View File

@ -0,0 +1,2 @@
.text
kmovw %k1, %k2

View File

@ -0,0 +1,10 @@
#name: x86-64 property 6
#source: property-6.s
#as: -mx86-used-note=yes --generate-missing-build-notes=no
#readelf: -n
Displaying notes found in: .note.gnu.property
[ ]+Owner[ ]+Data size[ ]+Description
GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA used: AVX512F
x86 feature used: x86, XMM, YMM, ZMM