aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index e94b937..ae1ef56 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4925,6 +4925,43 @@ optimize_encoding (void)
*/
i.tm.base_opcode = 0x84 | (i.tm.base_opcode & 1);
}
+ else if (!optimize_for_space
+ && i.tm.base_opcode == 0xd0
+ && (i.tm.opcode_space == SPACE_BASE
+ || i.tm.opcode_space == SPACE_EVEXMAP4)
+ && !i.mem_operands)
+ {
+ /* Optimize: -O:
+ shlb $1, %rN -> addb %rN, %rN
+ shlw $1, %rN -> addw %rN, %rN
+ shll $1, %rN -> addl %rN, %rN
+ shlq $1, %rN -> addq %rN, %rN
+
+ shlb $1, %rN, %rM -> addb %rN, %rN, %rM
+ shlw $1, %rN, %rM -> addw %rN, %rN, %rM
+ shll $1, %rN, %rM -> addl %rN, %rN, %rM
+ shlq $1, %rN, %rM -> addq %rN, %rN, %rM
+ */
+ gas_assert (i.tm.extension_opcode == 4);
+ i.tm.base_opcode = 0x00;
+ i.tm.extension_opcode = None;
+ if (i.operands >= 2)
+ {
+ i.tm.operand_types[0] = i.tm.operand_types[1];
+ i.op[0].regs = i.op[1].regs;
+ i.types[0] = i.types[1];
+ }
+ else
+ {
+ /* Legacy form with omitted shift count operand. */
+ i.tm.operand_types[1] = i.tm.operand_types[0];
+ i.op[1].regs = i.op[0].regs;
+ i.types[1] = i.types[0];
+ i.operands = 2;
+ }
+ i.reg_operands++;
+ i.imm_operands = 0;
+ }
else if (i.tm.base_opcode == 0xba
&& i.tm.opcode_space == SPACE_0F
&& i.reg_operands == 1
@@ -5181,6 +5218,48 @@ optimize_encoding (void)
i.op[1].regs = i.op[0].regs;
}
}
+ else if (i.tm.extension_opcode == 6
+ && i.tm.base_opcode >= 0x71
+ && i.tm.base_opcode <= 0x73
+ && i.tm.opcode_space == SPACE_0F
+ && i.op[0].imms->X_op == O_constant
+ && i.op[0].imms->X_add_number == 1
+ && !i.mem_operands)
+ {
+ /* Optimize: -O:
+ psllw $1, %mmxN -> paddw %mmxN, %mmxN
+ psllw $1, %xmmN -> paddw %xmmN, %xmmN
+ vpsllw $1, %xmmN, %xmmM -> vpaddw %xmmN, %xmmN, %xmmM
+ vpsllw $1, %ymmN, %ymmM -> vpaddw %ymmN, %ymmN, %ymmM
+ vpsllw $1, %zmmN, %zmmM -> vpaddw %zmmN, %zmmN, %zmmM
+
+ pslld $1, %mmxN -> paddd %mmxN, %mmxN
+ pslld $1, %xmmN -> paddd %xmmN, %xmmN
+ vpslld $1, %xmmN, %xmmM -> vpaddd %xmmN, %xmmN, %xmmM
+ vpslld $1, %ymmN, %ymmM -> vpaddd %ymmN, %ymmN, %ymmM
+ vpslld $1, %zmmN, %zmmM -> vpaddd %zmmN, %zmmN, %zmmM
+
+ psllq $1, %xmmN -> paddq %xmmN, %xmmN
+ vpsllq $1, %xmmN, %xmmM -> vpaddq %xmmN, %xmmN, %xmmM
+ vpsllq $1, %ymmN, %ymmM -> vpaddq %ymmN, %ymmN, %ymmM
+ vpsllq $1, %zmmN, %zmmM -> vpaddq %zmmN, %zmmN, %zmmM
+ */
+ if (i.tm.base_opcode != 0x73)
+ i.tm.base_opcode |= 0xfc; /* {,v}padd{w,d} */
+ else
+ {
+ gas_assert (i.tm.operand_types[1].bitfield.class != RegMMX);
+ i.tm.base_opcode = 0xd4; /* {,v}paddq */
+ }
+ i.tm.extension_opcode = None;
+ if (i.tm.opcode_modifier.vexvvvv)
+ i.tm.opcode_modifier.vexvvvv = VexVVVV_SRC1;
+ i.tm.operand_types[0] = i.tm.operand_types[1];
+ i.op[0].regs = i.op[1].regs;
+ i.types[0] = i.types[1];
+ i.reg_operands++;
+ i.imm_operands = 0;
+ }
else if (optimize_for_space
&& i.tm.base_opcode == 0x59
&& i.tm.opcode_space == SPACE_0F38