x86_32: fix stack_addr encoding.
Consider this testcase:
target i686
function u0:0() -> i32 system_v {
ss0 = explicit_slot 0
block0:
v2 = stack_addr.i32 ss0
return v2
}
Before this commit, in 32-bit mode the x86 backend would generate
incorrect code for stack addresses:
0: 55 push ebp
1: 89 e5 mov ebp, esp
3: 83 ec 08 sub esp, 8
6: 8d 44 24 00 lea eax, [esp]
a: 00 00 add byte ptr [eax], al
c: 00 83 c4 08 5d c3 add byte ptr [ebx - 0x3ca2f73c], al
This happened because the ModRM byte indicated a disp8 encoding, but
the instruction actually used a disp32 encoding. After this commit,
correct code is generated:
0: 55 push ebp
1: 89 e5 mov ebp, esp
3: 83 ec 08 sub esp, 8
6: 8d 84 24 00 00 00 00 lea eax, [esp]
d: 83 c4 08 add esp, 8
10: 5d pop ebp
11: c3 ret
This commit is contained in:
@@ -2270,8 +2270,7 @@ fn define_entity_ref(
|
||||
let rec_gvaddr8 = r.template("gvaddr8");
|
||||
let rec_pcrel_fnaddr8 = r.template("pcrel_fnaddr8");
|
||||
let rec_pcrel_gvaddr8 = r.template("pcrel_gvaddr8");
|
||||
let rec_spaddr4_id = r.template("spaddr4_id");
|
||||
let rec_spaddr8_id = r.template("spaddr8_id");
|
||||
let rec_spaddr_id = r.template("spaddr_id");
|
||||
|
||||
// Predicates shorthands.
|
||||
let all_ones_funcaddrs_and_not_is_pic =
|
||||
@@ -2359,8 +2358,8 @@ fn define_entity_ref(
|
||||
//
|
||||
// TODO: Add encoding rules for stack_load and stack_store, so that they
|
||||
// don't get legalized to stack_addr + load/store.
|
||||
e.enc32(stack_addr.bind(I32), rec_spaddr4_id.opcodes(&LEA));
|
||||
e.enc64(stack_addr.bind(I64), rec_spaddr8_id.opcodes(&LEA).rex().w());
|
||||
e.enc64(stack_addr.bind(I64), rec_spaddr_id.opcodes(&LEA).rex().w());
|
||||
e.enc32(stack_addr.bind(I32), rec_spaddr_id.opcodes(&LEA));
|
||||
|
||||
// Constant addresses (PIC).
|
||||
e.enc64(const_addr.bind(I64), rec_const_addr.opcodes(&LEA).rex().w());
|
||||
|
||||
Reference in New Issue
Block a user