[binutils-gdb] x86: optimize LEA
Jan Beulich
jbeulich@sourceware.org
Mon Apr 26 08:37:50 GMT 2021
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fe134c656991cda74ab7bad80947930f666f8907
commit fe134c656991cda74ab7bad80947930f666f8907
Author: Jan Beulich <jbeulich@suse.com>
Date: Mon Apr 26 10:37:30 2021 +0200
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.
Diff:
---
gas/ChangeLog | 13 +++
gas/config/tc-i386.c | 142 +++++++++++++++++++++++++++++++-
gas/testsuite/gas/i386/i386.exp | 3 +
gas/testsuite/gas/i386/lea-optimize.d | 41 ++++++++-
gas/testsuite/gas/i386/lea.d | 39 ++++++++-
gas/testsuite/gas/i386/lea.e | 1 +
gas/testsuite/gas/i386/lea.s | 54 +++++++++++-
gas/testsuite/gas/i386/lea16-optimize.d | 48 +++++++++++
gas/testsuite/gas/i386/lea16.s | 7 ++
gas/testsuite/gas/i386/lea64-optimize.d | 71 ++++++++++++++++
gas/testsuite/gas/i386/lea64.d | 70 ++++++++++++++++
gas/testsuite/gas/i386/lea64.e | 4 +
gas/testsuite/gas/i386/lea64.s | 84 +++++++++++++++++++
opcodes/ChangeLog | 5 ++
opcodes/i386-opc.tbl | 2 +-
opcodes/i386-tbl.h | 2 +-
16 files changed, 576 insertions(+), 10 deletions(-)
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 585c98b2521..1e056f7f8ff 100644
--- a/gas/ChangeLog
+++ b/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
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1f9844dcb52..116b9db518f 100644
--- a/gas/config/tc-i386.c
+++ b/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
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index a9a2a6403bb..00866458726 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/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"
diff --git a/gas/testsuite/gas/i386/lea-optimize.d b/gas/testsuite/gas/i386/lea-optimize.d
index 16e5b82daea..283b994bbfc 100644
--- a/gas/testsuite/gas/i386/lea-optimize.d
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea.d b/gas/testsuite/gas/i386/lea.d
index aa0414b912a..bfc9c13559a 100644
--- a/gas/testsuite/gas/i386/lea.d
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea.e b/gas/testsuite/gas/i386/lea.e
index be965b39ee9..d0d47aeb3eb 100644
--- a/gas/testsuite/gas/i386/lea.e
+++ b/gas/testsuite/gas/i386/lea.e
@@ -1,3 +1,4 @@
.*: Assembler messages:
.*:3: Warning: .* `lea' .*
.*:4: Warning: .* `lea' .*
+.*:19: Warning: .* `lea' .*
diff --git a/gas/testsuite/gas/i386/lea.s b/gas/testsuite/gas/i386/lea.s
index 4324ad0c6cc..1fb6aa85003 100644
--- a/gas/testsuite/gas/i386/lea.s
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea16-optimize.d b/gas/testsuite/gas/i386/lea16-optimize.d
new file mode 100644
index 00000000000..e45b7377207
--- /dev/null
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea16.s b/gas/testsuite/gas/i386/lea16.s
new file mode 100644
index 00000000000..024a4e9c457
--- /dev/null
+++ b/gas/testsuite/gas/i386/lea16.s
@@ -0,0 +1,7 @@
+ .code16
+
+ .macro addr16 mnem:req opnds:vararg
+ addr32 \mnem \opnds
+ .endm
+
+ .include "lea.s"
diff --git a/gas/testsuite/gas/i386/lea64-optimize.d b/gas/testsuite/gas/i386/lea64-optimize.d
new file mode 100644
index 00000000000..301805a53e6
--- /dev/null
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea64.d b/gas/testsuite/gas/i386/lea64.d
new file mode 100644
index 00000000000..80136ffe6e3
--- /dev/null
+++ b/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
diff --git a/gas/testsuite/gas/i386/lea64.e b/gas/testsuite/gas/i386/lea64.e
new file mode 100644
index 00000000000..d0d47aeb3eb
--- /dev/null
+++ b/gas/testsuite/gas/i386/lea64.e
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:3: Warning: .* `lea' .*
+.*:4: Warning: .* `lea' .*
+.*:19: Warning: .* `lea' .*
diff --git a/gas/testsuite/gas/i386/lea64.s b/gas/testsuite/gas/i386/lea64.s
new file mode 100644
index 00000000000..1778adc4851
--- /dev/null
+++ b/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
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index bf495d02a07..f0840e34d9d 100644
--- a/opcodes/ChangeLog
+++ b/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
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 0c35848a22a..b0530e5fb82 100644
--- a/opcodes/i386-opc.tbl
+++ b/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 }
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h
index d2ca247f028..df139ba6121 100644
--- a/opcodes/i386-tbl.h
+++ b/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,
More information about the Binutils-cvs
mailing list