aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2024-06-21 14:40:44 +0200
committerJan Beulich <jbeulich@suse.com>2024-06-21 14:40:44 +0200
commitf4a966a91d23ae78000d577665502edff7274fd9 (patch)
tree39003f6ed23e61899ec60657a8af6492d1f363d7 /gas/config/tc-i386.c
parentfa2c4239f1ab70b198f6d404f727d0d744221595 (diff)
downloadbinutils-f4a966a91d23ae78000d577665502edff7274fd9.zip
binutils-f4a966a91d23ae78000d577665502edff7274fd9.tar.gz
binutils-f4a966a91d23ae78000d577665502edff7274fd9.tar.bz2
x86: optimize {,V}PEXTR{D,Q} with immediate of 0
Such are equivalent to simple moves, which are up to 3 bytes shorter to encode (and perhaps also cheaper to execute).
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ae1ef56..ab52692 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -5287,6 +5287,44 @@ optimize_encoding (void)
swap_2_operands (1, 2);
}
+ else if (i.tm.base_opcode == 0x16
+ && i.tm.opcode_space == SPACE_0F3A
+ && i.op[0].imms->X_op == O_constant
+ && i.op[0].imms->X_add_number == 0)
+ {
+ /* Optimize: -O:
+ pextrd $0, %xmmN, ... -> movd %xmmN, ...
+ pextrq $0, %xmmN, ... -> movq %xmmN, ...
+ vpextrd $0, %xmmN, ... -> vmovd %xmmN, ...
+ vpextrq $0, %xmmN, ... -> vmovq %xmmN, ...
+ */
+ i.tm.opcode_space = SPACE_0F;
+ if (!i.mem_operands
+ || i.tm.opcode_modifier.evex
+ || (i.tm.opcode_modifier.vexw != VEXW1
+ && i.tm.opcode_modifier.size != SIZE64))
+ i.tm.base_opcode = 0x7e;
+ else
+ {
+ i.tm.base_opcode = 0xd6;
+ i.tm.opcode_modifier.size = 0;
+ i.tm.opcode_modifier.vexw
+ = i.tm.opcode_modifier.sse2avx ? VEXW0 : VEXWIG;
+ }
+
+ i.op[0].regs = i.op[1].regs;
+ i.types[0] = i.types[1];
+ i.flags[0] = i.flags[1];
+ i.tm.operand_types[0] = i.tm.operand_types[1];
+
+ i.op[1].regs = i.op[2].regs;
+ i.types[1] = i.types[2];
+ i.flags[1] = i.flags[2];
+ i.tm.operand_types[1] = i.tm.operand_types[2];
+
+ i.operands = 2;
+ i.imm_operands = 0;
+ }
}
static void