aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2024-06-28 08:21:48 +0200
committerJan Beulich <jbeulich@suse.com>2024-06-28 08:21:48 +0200
commit2a7f257afb4297394ea4239ed97c507d83220dd7 (patch)
tree3a67e7b84434a6645de61fc328b5bd4859c7ac12 /gas/config/tc-i386.c
parent27ef4876f74717e750102f9273f143bf45541a46 (diff)
downloadbinutils-2a7f257afb4297394ea4239ed97c507d83220dd7.zip
binutils-2a7f257afb4297394ea4239ed97c507d83220dd7.tar.gz
binutils-2a7f257afb4297394ea4239ed97c507d83220dd7.tar.bz2
x86-64: restrict by-imm31 optimization
Avoid changing the encoding when there's no size gain: If there's a REX or REX2 prefix anyway and the base opcode wouldn't be changed, dropping just REX.W / REX2.W has no (size) effect. (Same for the AND-by-imm7 case in the same big conditional.) While there also pull out the .qword check: For the 2-register-operands case whether that's done on the 1st or 2nd operand doesn't matter. Due to reduction in necessary parentheses this improves readability a tiny bit.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 4eb5655..9452b3c 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4809,8 +4809,8 @@ optimize_encoding (void)
}
else if (flag_code == CODE_64BIT
&& i.tm.opcode_space == SPACE_BASE
- && ((i.types[1].bitfield.qword
- && i.reg_operands == 1
+ && i.types[i.operands - 1].bitfield.qword
+ && ((i.reg_operands == 1
&& i.imm_operands == 1
&& i.op[0].imms->X_op == O_constant
&& ((i.tm.base_opcode == 0xb8
@@ -4818,26 +4818,29 @@ optimize_encoding (void)
&& fits_in_unsigned_long (i.op[0].imms->X_add_number))
|| (fits_in_imm31 (i.op[0].imms->X_add_number)
&& (i.tm.base_opcode == 0x24
- || (i.tm.base_opcode == 0x80
- && i.tm.extension_opcode == 0x4)
- || i.tm.mnem_off == MN_test
+ || (((i.tm.base_opcode == 0x80
+ && i.tm.extension_opcode == 0x4)
+ || i.tm.mnem_off == MN_test)
+ && !(i.op[1].regs->reg_flags
+ & (RegRex | RegRex2)))
|| ((i.tm.base_opcode | 1) == 0xc7
&& i.tm.extension_opcode == 0x0)))
|| (fits_in_imm7 (i.op[0].imms->X_add_number)
&& i.tm.base_opcode == 0x83
- && i.tm.extension_opcode == 0x4)))
- || (i.types[0].bitfield.qword
- && ((i.reg_operands == 2
- && i.op[0].regs == i.op[1].regs
- && (i.tm.mnem_off == MN_xor
- || i.tm.mnem_off == MN_sub))
- || i.tm.mnem_off == MN_clr))))
+ && i.tm.extension_opcode == 0x4
+ && !(i.op[1].regs->reg_flags & (RegRex | RegRex2)))))
+ || ((i.reg_operands == 2
+ && i.op[0].regs == i.op[1].regs
+ && (i.tm.mnem_off == MN_xor
+ || i.tm.mnem_off == MN_sub))
+ || i.tm.mnem_off == MN_clr)))
{
/* Optimize: -O:
andq $imm31, %r64 -> andl $imm31, %r32
andq $imm7, %r64 -> andl $imm7, %r32
testq $imm31, %r64 -> testl $imm31, %r32
xorq %r64, %r64 -> xorl %r32, %r32
+ clrq %r64 -> clrl %r32
subq %r64, %r64 -> subl %r32, %r32
movq $imm31, %r64 -> movl $imm31, %r32
movq $imm32, %r64 -> movl $imm32, %r32