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:
@@ -1432,23 +1432,7 @@ pub(crate) fn define<'shared>(
|
||||
// TODO Alternative forms for 8-bit immediates, when applicable.
|
||||
|
||||
recipes.add_template_recipe(
|
||||
EncodingRecipeBuilder::new("spaddr4_id", &formats.stack_load, 6)
|
||||
.operands_out(vec![gpr])
|
||||
.emit(
|
||||
r#"
|
||||
let sp = StackRef::sp(stack_slot, &func.stack_slots);
|
||||
let base = stk_base(sp.base);
|
||||
{{PUT_OP}}(bits, rex2(out_reg0, base), sink);
|
||||
modrm_sib_disp8(out_reg0, sink);
|
||||
sib_noindex(base, sink);
|
||||
let imm : i32 = offset.into();
|
||||
sink.put4(sp.offset.checked_add(imm).unwrap() as u32);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
recipes.add_template_recipe(
|
||||
EncodingRecipeBuilder::new("spaddr8_id", &formats.stack_load, 6)
|
||||
EncodingRecipeBuilder::new("spaddr_id", &formats.stack_load, 6)
|
||||
.operands_out(vec![gpr])
|
||||
.emit(
|
||||
r#"
|
||||
|
||||
Reference in New Issue
Block a user