mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
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:
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
9
gas/testsuite/gas/i386/property-6.d
Normal file
9
gas/testsuite/gas/i386/property-6.d
Normal 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
|
2
gas/testsuite/gas/i386/property-6.s
Normal file
2
gas/testsuite/gas/i386/property-6.s
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.text
|
||||||
|
kmovw %k1, %k2
|
10
gas/testsuite/gas/i386/x86-64-property-6.d
Normal file
10
gas/testsuite/gas/i386/x86-64-property-6.d
Normal 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
|
Reference in New Issue
Block a user