diff options
author | Jan Beulich <jbeulich@suse.com> | 2024-06-28 08:24:45 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2024-06-28 08:24:45 +0200 |
commit | 2513312930b2b8a0b50fb681f2781372cce3c2f6 (patch) | |
tree | 3f7c66674e212d581fa147903114aa3cef58d30e /gas/config/tc-i386.c | |
parent | 7add9939175aa71faa37c40dcedcb9190e3b37d8 (diff) | |
download | fsf-binutils-gdb-2513312930b2b8a0b50fb681f2781372cce3c2f6.zip fsf-binutils-gdb-2513312930b2b8a0b50fb681f2781372cce3c2f6.tar.gz fsf-binutils-gdb-2513312930b2b8a0b50fb681f2781372cce3c2f6.tar.bz2 |
x86/APX: apply NDD-to-legacy transformation to further CMOVcc forms
With both sources being registers, these insns are almost commutative;
the only extra adjustment needed is inversion of the encoded condition.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 4de5c01..2e19431 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -456,6 +456,9 @@ struct _i386_insn /* Disable instruction size optimization. */ bool no_optimize; + /* Invert the condition encoded in a base opcode. */ + bool invert_cond; + /* How to encode instructions. */ enum { @@ -3918,6 +3921,11 @@ install_template (const insn_template *t) i.tm.base_opcode >>= 8; } + /* For CMOVcc having undergone NDD-to-legacy optimization with its source + operands being swapped, we need to invert the encoded condition. */ + if (i.invert_cond) + i.tm.base_opcode ^= 1; + /* Note that for pseudo prefixes this produces a length of 1. But for them the length isn't interesting at all. */ for (l = 1; l < 4; ++l) @@ -9845,7 +9853,14 @@ match_template (char mnem_suffix) && !i.op[i.operands - 1].regs->reg_type.bitfield.qword))) { if (i.operands > 2 && match_dest_op == i.operands - 3) - swap_2_operands (match_dest_op, i.operands - 2); + { + swap_2_operands (match_dest_op, i.operands - 2); + + /* CMOVcc is marked commutative, but then also needs its + encoded condition inverted. */ + if ((t->base_opcode | 0xf) == 0x4f) + i.invert_cond = true; + } --i.operands; --i.reg_operands; |