diff options
author | Jan Beulich <jbeulich@suse.com> | 2024-06-28 08:21:48 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2024-06-28 08:21:48 +0200 |
commit | 2a7f257afb4297394ea4239ed97c507d83220dd7 (patch) | |
tree | 3a67e7b84434a6645de61fc328b5bd4859c7ac12 /gas/config/tc-i386.c | |
parent | 27ef4876f74717e750102f9273f143bf45541a46 (diff) | |
download | binutils-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.c | 27 |
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 |