Browse Source

x86: optimize LEA

Over the years I've seen a number of instances where people used

    lea     (%reg1), %reg2

or

    lea     symbol, %reg

despite the same thing being expressable via MOV. Since additionally
LEA often has restrictions towards the ports it can be issued to, while
MOV typically gets dealt with simply by register renaming, transform to
MOV when possible (without growing opcode size and without altering
involved relocation types).

Note that for Mach-O the new 64-bit testcases would fail (for
BFD_RELOC_X86_64_32S not having a representation), and hence get skipped
there.
binutils-2_37-branch
Jan Beulich 5 years ago
parent
commit
fe134c6569
  1. 13
      gas/ChangeLog
  2. 142
      gas/config/tc-i386.c
  3. 3
      gas/testsuite/gas/i386/i386.exp
  4. 41
      gas/testsuite/gas/i386/lea-optimize.d
  5. 39
      gas/testsuite/gas/i386/lea.d
  6. 1
      gas/testsuite/gas/i386/lea.e
  7. 54
      gas/testsuite/gas/i386/lea.s
  8. 48
      gas/testsuite/gas/i386/lea16-optimize.d
  9. 7
      gas/testsuite/gas/i386/lea16.s
  10. 71
      gas/testsuite/gas/i386/lea64-optimize.d
  11. 70
      gas/testsuite/gas/i386/lea64.d
  12. 4
      gas/testsuite/gas/i386/lea64.e
  13. 84
      gas/testsuite/gas/i386/lea64.s
  14. 5
      opcodes/ChangeLog
  15. 2
      opcodes/i386-opc.tbl
  16. 2
      opcodes/i386-tbl.h

13
gas/ChangeLog

@ -1,3 +1,16 @@
2021-04-26 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (want_disp32): Also check for SIZE32.
(optimize_encoding): Handle LEA.
* testsuite/gas/i386/lea.s, testsuite/gas/i386/lea.d,
testsuite/gas/i386/lea.e, testsuite/gas/i386/lea-optimize.d:
Add many more forms.
* testsuite/gas/i386/lea16.s, testsuite/gas/i386/lea16-optimize.d,
testsuite/gas/i386/lea64.s, testsuite/gas/i386/lea64.d,
testsuite/gas/i386/lea64.e, testsuite/gas/i386/lea64-optimize.d:
New.
* testsuite/gas/i386/i386.exp: Run new tests.
2021-04-26 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (md_apply_fix): Mark BFD_RELOC_X86_64_32S as

142
gas/config/tc-i386.c

@ -3562,7 +3562,8 @@ want_disp32 (const insn_template *t)
|| i.prefix[ADDR_PREFIX]
|| (t->base_opcode == 0x8d
&& t->opcode_modifier.opcodespace == SPACE_BASE
&& !i.types[1].bitfield.qword);
&& (!i.types[1].bitfield.qword
|| t->opcode_modifier.size == SIZE32));
}
static int
@ -4069,6 +4070,145 @@ optimize_encoding (void)
{
unsigned int j;
if (i.tm.opcode_modifier.opcodespace == SPACE_BASE
&& i.tm.base_opcode == 0x8d)
{
/* Optimize: -O:
lea symbol, %rN -> mov $symbol, %rN
lea (%rM), %rN -> mov %rM, %rN
lea (,%rM,1), %rN -> mov %rM, %rN
and in 32-bit mode for 16-bit addressing
lea (%rM), %rN -> movzx %rM, %rN
and in 64-bit mode zap 32-bit addressing in favor of using a
32-bit (or less) destination.
*/
if (flag_code == CODE_64BIT && i.prefix[ADDR_PREFIX])
{
if (!i.op[1].regs->reg_type.bitfield.word)
i.tm.opcode_modifier.size = SIZE32;
i.prefix[ADDR_PREFIX] = 0;
}
if (!i.index_reg && !i.base_reg)
{
/* Handle:
lea symbol, %rN -> mov $symbol, %rN
*/
if (flag_code == CODE_64BIT)
{
/* Don't transform a relocation to a 16-bit one. */
if (i.op[0].disps
&& i.op[0].disps->X_op != O_constant
&& i.op[1].regs->reg_type.bitfield.word)
return;
if (!i.op[1].regs->reg_type.bitfield.qword
|| i.tm.opcode_modifier.size == SIZE32)
{
i.tm.base_opcode = 0xb8;
i.tm.opcode_modifier.modrm = 0;
if (!i.op[1].regs->reg_type.bitfield.word)
i.types[0].bitfield.imm32 = 1;
else
{
i.tm.opcode_modifier.size = SIZE16;
i.types[0].bitfield.imm16 = 1;
}
}
else
{
/* Subject to further optimization below. */
i.tm.base_opcode = 0xc7;
i.tm.extension_opcode = 0;
i.types[0].bitfield.imm32s = 1;
i.types[0].bitfield.baseindex = 0;
}
}
/* Outside of 64-bit mode address and operand sizes have to match if
a relocation is involved, as otherwise we wouldn't (currently) or
even couldn't express the relocation correctly. */
else if (i.op[0].disps
&& i.op[0].disps->X_op != O_constant
&& ((!i.prefix[ADDR_PREFIX])
!= (flag_code == CODE_32BIT
? i.op[1].regs->reg_type.bitfield.dword
: i.op[1].regs->reg_type.bitfield.word)))
return;
else
{
i.tm.base_opcode = 0xb8;
i.tm.opcode_modifier.modrm = 0;
if (i.op[1].regs->reg_type.bitfield.dword)
i.types[0].bitfield.imm32 = 1;
else
i.types[0].bitfield.imm16 = 1;
if (i.op[0].disps
&& i.op[0].disps->X_op == O_constant
&& i.op[1].regs->reg_type.bitfield.dword
&& !i.prefix[ADDR_PREFIX] != (flag_code == CODE_32BIT))
i.op[0].disps->X_add_number &= 0xffff;
}
i.tm.operand_types[0] = i.types[0];
i.imm_operands = 1;
if (!i.op[0].imms)
{
i.op[0].imms = &im_expressions[0];
i.op[0].imms->X_op = O_absent;
}
}
else if (i.op[0].disps
&& (i.op[0].disps->X_op != O_constant
|| i.op[0].disps->X_add_number))
return;
else
{
/* Handle:
lea (%rM), %rN -> mov %rM, %rN
lea (,%rM,1), %rN -> mov %rM, %rN
lea (%rM), %rN -> movzx %rM, %rN
*/
const reg_entry *addr_reg;
if (!i.index_reg && i.base_reg->reg_num != RegIP)
addr_reg = i.base_reg;
else if (!i.base_reg
&& i.index_reg->reg_num != RegIZ
&& !i.log2_scale_factor)
addr_reg = i.index_reg;
else
return;
if (addr_reg->reg_type.bitfield.word
&& i.op[1].regs->reg_type.bitfield.dword)
{
if (flag_code != CODE_32BIT)
return;
i.tm.opcode_modifier.opcodespace = SPACE_0F;
i.tm.base_opcode = 0xb7;
}
else
i.tm.base_opcode = 0x8b;
if (addr_reg->reg_type.bitfield.dword
&& i.op[1].regs->reg_type.bitfield.qword)
i.tm.opcode_modifier.size = SIZE32;
i.op[0].regs = addr_reg;
i.reg_operands = 2;
}
i.mem_operands = 0;
i.disp_operands = 0;
i.prefix[ADDR_PREFIX] = 0;
i.prefix[SEG_PREFIX] = 0;
i.seg[0] = NULL;
}
if (optimize_for_space
&& i.tm.opcode_modifier.opcodespace == SPACE_BASE
&& i.reg_operands == 1

3
gas/testsuite/gas/i386/i386.exp

@ -538,6 +538,7 @@ if [gas_32_check] then {
run_dump_test "optimize-6b"
run_list_test "optimize-7" "-I${srcdir}/$subdir -march=+noavx2 -al"
run_dump_test "lea-optimize"
run_dump_test "lea16-optimize"
run_dump_test "align-branch-1a"
run_dump_test "align-branch-1b"
run_dump_test "align-branch-1c"
@ -1194,6 +1195,8 @@ if [gas_64_check] then {
run_dump_test "x86-64-align-branch-2a"
run_dump_test "x86-64-align-branch-2b"
run_dump_test "x86-64-align-branch-2c"
run_dump_test "lea64"
run_dump_test "lea64-optimize"
}
run_dump_test "x86-64-align-branch-4a"
run_dump_test "x86-64-align-branch-4b"

41
gas/testsuite/gas/i386/lea-optimize.d

@ -1,6 +1,6 @@
#as: -O -q
#objdump: -dw
#name: i386 LEA-like segment overrride dropping
#name: i386 LEA optimizations
#source: lea.s
.*: +file format .*
@ -8,6 +8,41 @@
Disassembly of section .text:
0+ <start>:
[ ]*[0-9a-f]+:[ ]+8d 00[ ]+lea[ ]+\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+8d 00[ ]+lea[ ]+\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 08[ ]+lea[ ]+\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 08[ ]+lea[ ]+\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 48 01[ ]+lea[ ]+0x1\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 88 00 00 00 00[ ]+lea[ ]+0x0\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 0c 25 00 00 00 00[ ]+lea[ ]+0x0\(,(%eiz)?(,1)?\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 04 00[ ]+lea[ ]+\(%eax,%eax(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 45 00 00 00 00[ ]+lea[ ]+0x0\(,%eax,2\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0\(,(%eiz)?(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 8d 00[ ]+lea[ ]+\(%bx,%si\),%eax
[ ]*[0-9a-f]+:[ ]+8b c0[ ]+mov[ ]+%eax,%eax
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+0f b7 c6[ ]+movzwl[ ]+%si,%eax
[ ]*[0-9a-f]+:[ ]+0f b7 f6[ ]+movzwl[ ]+%si,%esi
[ ]*[0-9a-f]+:[ ]+0f b7 c6[ ]+movzwl[ ]+%si,%eax
[ ]*[0-9a-f]+:[ ]+66 8b c0[ ]+mov[ ]+%ax,%ax
[ ]*[0-9a-f]+:[ ]+66 8b c8[ ]+mov[ ]+%ax,%cx
[ ]*[0-9a-f]+:[ ]+66 8b c8[ ]+mov[ ]+%ax,%cx
[ ]*[0-9a-f]+:[ ]+66 8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+66 8b f6[ ]+mov[ ]+%si,%si
[ ]*[0-9a-f]+:[ ]+8b c9[ ]+mov[ ]+%ecx,%ecx
[ ]*[0-9a-f]+:[ ]+8b c1[ ]+mov[ ]+%ecx,%eax
[ ]*[0-9a-f]+:[ ]+b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 02 00[ ]+mov[ ]+\$0x2,%ax
[ ]*[0-9a-f]+:[ ]+b8 ff ff ff ff[ ]+mov[ ]+\$0xffffffff,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 fe ff[ ]+mov[ ]+\$0xfffe,%ax
[ ]*[0-9a-f]+:[ ]+b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 02 00[ ]+mov[ ]+\$0x2,%ax
[ ]*[0-9a-f]+:[ ]+b8 ff ff 00 00[ ]+mov[ ]+\$0xffff,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 fe ff[ ]+mov[ ]+\$0xfffe,%ax
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 05 00 00 00 00[ ]+lea[ ]+0x0,%ax
[ ]*[0-9a-f]+:[ ]+67 8d 06 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 00 00[ ]+mov[ ]+\$0x0,%ax
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 00 00[ ]+mov[ ]+\$0x0,%ax
#pass

39
gas/testsuite/gas/i386/lea.d

@ -7,6 +7,41 @@
Disassembly of section .text:
0+ <start>:
[ ]*[0-9a-f]+:[ ]+36 8d 00[ ]+lea[ ]+%ss:\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+36 8d 00[ ]+lea[ ]+%ss:\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+36 8d 04 08[ ]+lea[ ]+%ss:\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+36 8d 04 08[ ]+lea[ ]+%ss:\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 48 01[ ]+lea[ ]+0x1\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 88 00 00 00 00[ ]+lea[ ]+0x0\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 0c 25 00 00 00 00[ ]+lea[ ]+0x0\(,(%eiz)?(,1)?\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 04 00[ ]+lea[ ]+\(%eax,%eax(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 45 00 00 00 00[ ]+lea[ ]+0x0\(,%eax,2\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0\(,(%eiz)?(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 8d 00[ ]+lea[ ]+\(%bx,%si\),%eax
[ ]*[0-9a-f]+:[ ]+8d 00[ ]+lea[ ]+\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+8d 08[ ]+lea[ ]+\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 08[ ]+lea[ ]+\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+65 8d 08[ ]+lea[ ]+%gs:\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+67 8d 04[ ]+lea[ ]+\(%si\),%eax
[ ]*[0-9a-f]+:[ ]+67 8d 34[ ]+lea[ ]+\(%si\),%esi
[ ]*[0-9a-f]+:[ ]+67 8d 04[ ]+lea[ ]+\(%si\),%eax
[ ]*[0-9a-f]+:[ ]+66 8d 00[ ]+lea[ ]+\(%eax\),%ax
[ ]*[0-9a-f]+:[ ]+66 8d 08[ ]+lea[ ]+\(%eax\),%cx
[ ]*[0-9a-f]+:[ ]+66 8d 08[ ]+lea[ ]+\(%eax\),%cx
[ ]*[0-9a-f]+:[ ]+67 66 8d 04[ ]+lea[ ]+\(%si\),%ax
[ ]*[0-9a-f]+:[ ]+67 66 8d 34[ ]+lea[ ]+\(%si\),%si
[ ]*[0-9a-f]+:[ ]+8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 05 01 00 00 00[ ]+lea[ ]+0x1,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 05 02 00 00 00[ ]+lea[ ]+0x2,%ax
[ ]*[0-9a-f]+:[ ]+8d 05 ff ff ff ff[ ]+lea[ ]+0xffffffff,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 05 fe ff ff ff[ ]+lea[ ]+0xfffffffe,%ax
[ ]*[0-9a-f]+:[ ]+67 8d 06 01 00[ ]+lea[ ]+0x1,%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 06 02 00[ ]+lea[ ]+0x2,%ax
[ ]*[0-9a-f]+:[ ]+67 8d 06 ff ff[ ]+lea[ ]+-0x1,%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 06 fe ff[ ]+lea[ ]+-0x2,%ax
[ ]*[0-9a-f]+:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 05 00 00 00 00[ ]+lea[ ]+0x0,%ax
[ ]*[0-9a-f]+:[ ]+67 8d 06 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 06 00 00[ ]+lea[ ]+0x0,%ax
[ ]*[0-9a-f]+:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 05 00 00 00 00[ ]+lea[ ]+0x0,%ax
#pass

1
gas/testsuite/gas/i386/lea.e

@ -1,3 +1,4 @@
.*: Assembler messages:
.*:3: Warning: .* `lea' .*
.*:4: Warning: .* `lea' .*
.*:19: Warning: .* `lea' .*

54
gas/testsuite/gas/i386/lea.s

@ -1,4 +1,54 @@
.text
start:
lea %ss:(%eax), %eax
ss lea (%eax), %eax
lea %ss:(%eax,%ecx), %eax
ss lea (%eax,%ecx), %eax
.allow_index_reg
lea 1(%eax), %ecx
lea sym(%eax), %ecx
lea sym(,%eiz), %ecx
lea (%eax,%eax), %eax
lea (,%eax,2), %eax
lea (,%eiz), %eax
lea (%bx,%si), %eax
lea (%eax), %eax
lea (%eax), %ecx
lea 1-1(%eax), %ecx
lea %gs:(%eax), %ecx
lea (%si), %eax
lea (%si), %esi
leal (%si), %eax
lea (%eax), %ax
lea (%eax), %cx
leaw (%eax), %cx
lea (%si), %ax
lea (%si), %si
lea (,%ecx,1), %ecx
lea (,%ecx,1), %eax
lea 1, %eax
lea 2, %ax
lea -1, %eax
lea -2, %ax
addr16 lea 1, %eax
addr16 lea 2, %ax
addr16 lea -1, %eax
addr16 lea -2, %ax
lea sym, %eax
lea sym, %ax
addr16 lea sym, %eax
addr16 lea sym, %ax
lea (,1), %eax
lea (,1), %ax

48
gas/testsuite/gas/i386/lea16-optimize.d

@ -0,0 +1,48 @@
#as: -O -q -I${srcdir}/$subdir
#objdump: -dw -Mi8086
#name: i386 16-bit LEA optimizations
#source: lea16.s
.*: +file format .*
Disassembly of section .text:
0+ <start>:
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 08[ ]+lea[ ]+\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 08[ ]+lea[ ]+\(%eax,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 48 01[ ]+lea[ ]+0x1\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+67 66 8d 88 00 00 00 00[ ]+lea[ ]+0x0\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+67 66 8d 0c 25 00 00 00 00[ ]+addr32 lea[ ]+0x0,%ecx
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 00[ ]+lea[ ]+\(%eax,%eax(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 45 00 00 00 00[ ]+lea[ ]+0x0\(,%eax,2\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 25 00 00 00 00[ ]+addr32 lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 00[ ]+lea[ ]+\(%bx,%si\),%eax
[ ]*[0-9a-f]+:[ ]+66 8b c0[ ]+mov[ ]+%eax,%eax
[ ]*[0-9a-f]+:[ ]+66 8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+66 8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+66 8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+66 8d 04[ ]+lea[ ]+\(%si\),%eax
[ ]*[0-9a-f]+:[ ]+66 8d 34[ ]+lea[ ]+\(%si\),%esi
[ ]*[0-9a-f]+:[ ]+66 8d 04[ ]+lea[ ]+\(%si\),%eax
[ ]*[0-9a-f]+:[ ]+8b c0[ ]+mov[ ]+%ax,%ax
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%ax,%cx
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%ax,%cx
[ ]*[0-9a-f]+:[ ]+8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+8b f6[ ]+mov[ ]+%si,%si
[ ]*[0-9a-f]+:[ ]+66 8b c9[ ]+mov[ ]+%ecx,%ecx
[ ]*[0-9a-f]+:[ ]+66 8b c1[ ]+mov[ ]+%ecx,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+b8 02 00[ ]+mov[ ]+\$0x2,%ax
[ ]*[0-9a-f]+:[ ]+66 b8 ff ff 00 00[ ]+mov[ ]+\$0xffff,%eax
[ ]*[0-9a-f]+:[ ]+b8 fe ff[ ]+mov[ ]+\$0xfffe,%ax
[ ]*[0-9a-f]+:[ ]+66 b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+b8 02 00[ ]+mov[ ]+\$0x2,%ax
[ ]*[0-9a-f]+:[ ]+66 b8 ff ff ff ff[ ]+mov[ ]+\$0xffffffff,%eax
[ ]*[0-9a-f]+:[ ]+b8 fe ff[ ]+mov[ ]+\$0xfffe,%ax
[ ]*[0-9a-f]+:[ ]+66 8d 06 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+b8 00 00[ ]+mov[ ]+\$0x0,%ax
[ ]*[0-9a-f]+:[ ]+66 b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax
[ ]*[0-9a-f]+:[ ]+67 8d 05 00 00 00 00[ ]+addr32 lea[ ]+0x0,%ax
[ ]*[0-9a-f]+:[ ]+66 b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax
[ ]*[0-9a-f]+:[ ]+b8 00 00[ ]+mov[ ]+\$0x0,%ax
#pass

7
gas/testsuite/gas/i386/lea16.s

@ -0,0 +1,7 @@
.code16
.macro addr16 mnem:req opnds:vararg
addr32 \mnem \opnds
.endm
.include "lea.s"

71
gas/testsuite/gas/i386/lea64-optimize.d

@ -0,0 +1,71 @@
#as: -O -q
#objdump: -drw
#name: x86-64 LEA optimizations
#source: lea64.s
.*: +file format .*
Disassembly of section .text:
0+ <start>:
[ ]*[0-9a-f]+:[ ]+8d 04 08[ ]+lea[ ]+\(%rax,%rcx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 08[ ]+lea[ ]+\(%rax,%rcx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 48 01[ ]+lea[ ]+0x1\(%rax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 88 00 00 00 00[ ]+lea[ ]+0x0\(%rax\),%ecx[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+8d 0c 25 00 00 00 00[ ]+lea[ ]+0x0,%ecx[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+8d 04 00[ ]+lea[ ]+\(%rax,%rax(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 45 00 00 00 00[ ]+lea[ ]+0x0\(,%rax,2\),%eax
[ ]*[0-9a-f]+:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0x0\(%rip\),%eax($| *#.*)
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+48 8b c0[ ]+mov[ ]+%rax,%rax
[ ]*[0-9a-f]+:[ ]+48 8b c8[ ]+mov[ ]+%rax,%rcx
[ ]*[0-9a-f]+:[ ]+48 8b c8[ ]+mov[ ]+%rax,%rcx
[ ]*[0-9a-f]+:[ ]+48 8b c8[ ]+mov[ ]+%rax,%rcx
[ ]*[0-9a-f]+:[ ]+8b c6[ ]+mov[ ]+%esi,%eax
[ ]*[0-9a-f]+:[ ]+8b f6[ ]+mov[ ]+%esi,%esi
[ ]*[0-9a-f]+:[ ]+8b c6[ ]+mov[ ]+%esi,%eax
[ ]*[0-9a-f]+:[ ]+66 8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+66 8b f6[ ]+mov[ ]+%si,%si
[ ]*[0-9a-f]+:[ ]+66 8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+8b c0[ ]+mov[ ]+%eax,%eax
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+8b c0[ ]+mov[ ]+%eax,%eax
[ ]*[0-9a-f]+:[ ]+8b c8[ ]+mov[ ]+%eax,%ecx
[ ]*[0-9a-f]+:[ ]+66 8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+66 8b f6[ ]+mov[ ]+%si,%si
[ ]*[0-9a-f]+:[ ]+66 8b c6[ ]+mov[ ]+%si,%ax
[ ]*[0-9a-f]+:[ ]+48 8b c9[ ]+mov[ ]+%rcx,%rcx
[ ]*[0-9a-f]+:[ ]+48 8b c1[ ]+mov[ ]+%rcx,%rax
[ ]*[0-9a-f]+:[ ]+8b c9[ ]+mov[ ]+%ecx,%ecx
[ ]*[0-9a-f]+:[ ]+8b c1[ ]+mov[ ]+%ecx,%eax
[ ]*[0-9a-f]+:[ ]+66 8b c9[ ]+mov[ ]+%cx,%cx
[ ]*[0-9a-f]+:[ ]+66 8b c1[ ]+mov[ ]+%cx,%ax
[ ]*[0-9a-f]+:[ ]+8b c9[ ]+mov[ ]+%ecx,%ecx
[ ]*[0-9a-f]+:[ ]+8b c1[ ]+mov[ ]+%ecx,%eax
[ ]*[0-9a-f]+:[ ]+8b c9[ ]+mov[ ]+%ecx,%ecx
[ ]*[0-9a-f]+:[ ]+8b c1[ ]+mov[ ]+%ecx,%eax
[ ]*[0-9a-f]+:[ ]+66 8b c9[ ]+mov[ ]+%cx,%cx
[ ]*[0-9a-f]+:[ ]+66 8b c1[ ]+mov[ ]+%cx,%ax
[ ]*[0-9a-f]+:[ ]+b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+b8 02 00 00 00[ ]+mov[ ]+\$0x2,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 03 00[ ]+mov[ ]+\$0x3,%ax
[ ]*[0-9a-f]+:[ ]+48 c7 c0 ff ff ff ff[ ]+mov[ ]+\$0xffffffffffffffff,%rax
[ ]*[0-9a-f]+:[ ]+b8 fe ff ff ff[ ]+mov[ ]+\$0xfffffffe,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 fd ff[ ]+mov[ ]+\$0xfffd,%ax
[ ]*[0-9a-f]+:[ ]+b8 01 00 00 00[ ]+mov[ ]+\$0x1,%eax
[ ]*[0-9a-f]+:[ ]+b8 02 00 00 00[ ]+mov[ ]+\$0x2,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 03 00[ ]+mov[ ]+\$0x3,%ax
[ ]*[0-9a-f]+:[ ]+b8 ff ff ff ff[ ]+mov[ ]+\$0xffffffff,%eax
[ ]*[0-9a-f]+:[ ]+b8 fe ff ff ff[ ]+mov[ ]+\$0xfffffffe,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 fd ff[ ]+mov[ ]+\$0xfffd,%ax
[ ]*[0-9a-f]+:[ ]+48 c7 c0 00 00 00 00[ ]+mov[ ]+\$0x0,%rax[ ]+[0-9a-f]+: R_X86_64_32S[ ]+sym
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%ax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%ax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+48 c7 c0 00 00 00 00[ ]+mov[ ]+\$0x0,%rax
[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+mov[ ]+\$0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 b8 00 00[ ]+mov[ ]+\$0x0,%ax
#pass

70
gas/testsuite/gas/i386/lea64.d

@ -0,0 +1,70 @@
#objdump: -drw
#name: x86-64 LEA
#warning_output: lea64.e
.*: +file format .*
Disassembly of section .text:
0+ <start>:
[ ]*[0-9a-f]+:[ ]+64 8d 04 08[ ]+lea[ ]+%fs:\(%rax,%rcx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+65 8d 04 08[ ]+lea[ ]+%gs:\(%rax,%rcx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 48 01[ ]+lea[ ]+0x1\(%rax\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 88 00 00 00 00[ ]+lea[ ]+0x0\(%rax\),%ecx[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+8d 0c 25 00 00 00 00[ ]+lea[ ]+0x0,%ecx[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+8d 04 00[ ]+lea[ ]+\(%rax,%rax(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+8d 04 45 00 00 00 00[ ]+lea[ ]+0x0\(,%rax,2\),%eax
[ ]*[0-9a-f]+:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0x0\(%rip\),%eax($| *#.*)
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+48 8d 00[ ]+lea[ ]+\(%rax\),%rax
[ ]*[0-9a-f]+:[ ]+48 8d 08[ ]+lea[ ]+\(%rax\),%rcx
[ ]*[0-9a-f]+:[ ]+48 8d 08[ ]+lea[ ]+\(%rax\),%rcx
[ ]*[0-9a-f]+:[ ]+65 48 8d 08[ ]+lea[ ]+%gs:\(%rax\),%rcx
[ ]*[0-9a-f]+:[ ]+8d 06[ ]+lea[ ]+\(%rsi\),%eax
[ ]*[0-9a-f]+:[ ]+8d 36[ ]+lea[ ]+\(%rsi\),%esi
[ ]*[0-9a-f]+:[ ]+8d 06[ ]+lea[ ]+\(%rsi\),%eax
[ ]*[0-9a-f]+:[ ]+66 8d 06[ ]+lea[ ]+\(%rsi\),%ax
[ ]*[0-9a-f]+:[ ]+66 8d 36[ ]+lea[ ]+\(%rsi\),%si
[ ]*[0-9a-f]+:[ ]+66 8d 06[ ]+lea[ ]+\(%rsi\),%ax
[ ]*[0-9a-f]+:[ ]+67 48 8d 00[ ]+lea[ ]+\(%eax\),%rax
[ ]*[0-9a-f]+:[ ]+67 48 8d 08[ ]+lea[ ]+\(%eax\),%rcx
[ ]*[0-9a-f]+:[ ]+67 48 8d 08[ ]+lea[ ]+\(%eax\),%rcx
[ ]*[0-9a-f]+:[ ]+67 8d 00[ ]+lea[ ]+\(%eax\),%eax
[ ]*[0-9a-f]+:[ ]+67 8d 08[ ]+lea[ ]+\(%eax\),%ecx
[ ]*[0-9a-f]+:[ ]+67 66 8d 06[ ]+lea[ ]+\(%esi\),%ax
[ ]*[0-9a-f]+:[ ]+67 66 8d 36[ ]+lea[ ]+\(%esi\),%si
[ ]*[0-9a-f]+:[ ]+67 66 8d 06[ ]+lea[ ]+\(%esi\),%ax
[ ]*[0-9a-f]+:[ ]+48 8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%rcx
[ ]*[0-9a-f]+:[ ]+48 8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%rax
[ ]*[0-9a-f]+:[ ]+8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%ecx
[ ]*[0-9a-f]+:[ ]+8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+66 8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%cx
[ ]*[0-9a-f]+:[ ]+66 8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%rcx(,1)?\),%ax
[ ]*[0-9a-f]+:[ ]+67 48 8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%rcx
[ ]*[0-9a-f]+:[ ]+67 48 8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%rax
[ ]*[0-9a-f]+:[ ]+67 8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%ecx
[ ]*[0-9a-f]+:[ ]+67 8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 0c 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%cx
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 0d 00 00 00 00[ ]+lea[ ]+0x0\(,%ecx(,1)?\),%ax
[ ]*[0-9a-f]+:[ ]+48 8d 04 25 01 00 00 00[ ]+lea[ ]+0x1,%rax
[ ]*[0-9a-f]+:[ ]+8d 04 25 02 00 00 00[ ]+lea[ ]+0x2,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 03 00 00 00[ ]+lea[ ]+0x3,%ax
[ ]*[0-9a-f]+:[ ]+48 8d 04 25 ff ff ff ff[ ]+lea[ ]+0xffffffffffffffff,%rax
[ ]*[0-9a-f]+:[ ]+8d 04 25 fe ff ff ff[ ]+lea[ ]+0xfffffffffffffffe,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 fd ff ff ff[ ]+lea[ ]+0xfffffffffffffffd,%ax
[ ]*[0-9a-f]+:[ ]+67 48 8d 04 25 01 00 00 00[ ]+lea[ ]+0x1\(,%eiz,1\),%rax
[ ]*[0-9a-f]+:[ ]+67 8d 04 25 02 00 00 00[ ]+lea[ ]+0x2\(,%eiz,1\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 25 03 00 00 00[ ]+lea[ ]+0x3\(,%eiz,1\),%ax
[ ]*[0-9a-f]+:[ ]+67 48 8d 04 25 ff ff ff ff[ ]+lea[ ]+0xffffffff\(,%eiz,1\),%rax
[ ]*[0-9a-f]+:[ ]+67 8d 04 25 fe ff ff ff[ ]+lea[ ]+0xfffffffe\(,%eiz,1\),%eax
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 25 fd ff ff ff[ ]+lea[ ]+0xfffffffd\(,%eiz,1\),%ax
[ ]*[0-9a-f]+:[ ]+48 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%rax[ ]+[0-9a-f]+: R_X86_64_32S[ ]+sym
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%eax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%ax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+67 48 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0\(,%eiz,1\),%rax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+67 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0\(,%eiz,1\),%eax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+67 66 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0\(,%eiz,1\),%ax[ ]+[0-9a-f]+: R_X86_64_32[ ]+sym
[ ]*[0-9a-f]+:[ ]+48 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%rax
[ ]*[0-9a-f]+:[ ]+8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%eax
[ ]*[0-9a-f]+:[ ]+66 8d 04 25 00 00 00 00[ ]+lea[ ]+0x0,%ax
#pass

4
gas/testsuite/gas/i386/lea64.e

@ -0,0 +1,4 @@
.*: Assembler messages:
.*:3: Warning: .* `lea' .*
.*:4: Warning: .* `lea' .*
.*:19: Warning: .* `lea' .*

84
gas/testsuite/gas/i386/lea64.s

@ -0,0 +1,84 @@
.text
start:
lea %fs:(%rax,%rcx), %eax
gs lea (%rax,%rcx), %eax
.allow_index_reg
lea 1(%rax), %ecx
lea sym(%rax), %ecx
lea sym(,%riz), %ecx
lea (%rax,%rax), %eax
lea (,%rax,2), %eax
lea (%rip), %eax
lea (,%riz), %eax
lea (%rax), %rax
lea (%rax), %rcx
lea 1-1(%rax), %rcx
lea %gs:(%rax), %rcx
lea (%rsi), %eax
lea (%rsi), %esi
leal (%rsi), %eax
lea (%rsi), %ax
lea (%rsi), %si
leaw (%rsi), %ax
lea (%eax), %rax
lea (%eax), %rcx
leaq (%eax), %rcx
lea (%eax), %eax
lea (%eax), %ecx
lea (%esi), %ax
lea (%esi), %si
leaw (%esi), %ax
lea (,%rcx,1), %rcx
lea (,%rcx,1), %rax
lea (,%rcx,1), %ecx
lea (,%rcx,1), %eax
lea (,%rcx,1), %cx
lea (,%rcx,1), %ax
lea (,%ecx,1), %rcx
lea (,%ecx,1), %rax
lea (,%ecx,1), %ecx
lea (,%ecx,1), %eax
lea (,%ecx,1), %cx
lea (,%ecx,1), %ax
lea 1, %rax
lea 2, %eax
lea 3, %ax
lea -1, %rax
lea -2, %eax
lea -3, %ax
addr32 lea 1, %rax
addr32 lea 2, %eax
addr32 lea 3, %ax
addr32 lea -1, %rax
addr32 lea -2, %eax
addr32 lea -3, %ax
lea sym, %rax
lea sym, %eax
lea sym, %ax
addr32 lea sym, %rax
addr32 lea sym, %eax
addr32 lea sym, %ax
lea (,1), %rax
lea (,1), %eax
lea (,1), %ax

5
opcodes/ChangeLog

@ -1,3 +1,8 @@
2021-04-26 Jan Beulich <jbeulich@suse.com>
* i386-opc.tbl (lea): Add Optimize.
* opcodes/i386-tbl.h: Re-generate.
2020-04-23 Max Filippov <jcmvbkbc@gmail.com>
* xtensa-dis.c (print_xtensa_operand): For PC-relative operand

2
opcodes/i386-opc.tbl

@ -228,7 +228,7 @@ out, 0xe6, None, 0, W|No_sSuf|No_qSuf|No_ldSuf, { Imm8 }
out, 0xee, None, 0, W|No_sSuf|No_qSuf|No_ldSuf, { InOutPortReg }
// Load effective address.
lea, 0x8d, None, 0, Modrm|Anysize|No_bSuf|No_sSuf|No_ldSuf, { BaseIndex, Reg16|Reg32|Reg64 }
lea, 0x8d, None, 0, Modrm|Anysize|No_bSuf|No_sSuf|No_ldSuf|Optimize, { BaseIndex, Reg16|Reg32|Reg64 }
// Load segment registers from memory.
lds, 0xc5, None, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Unspecified|BaseIndex, Reg16|Reg32 }

2
opcodes/i386-tbl.h

@ -1121,7 +1121,7 @@ const insn_template i386_optab[] =
{ "lea", 0x8d, None, 2,
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Loading…
Cancel
Save