Merge pull request #2134 from cfallin/fix-abi-extension

AArch64 ABI: properly store full 64-bit width of extended args/retvals.
This commit is contained in:
Chris Fallin
2020-08-18 08:39:30 -07:00
committed by GitHub
2 changed files with 64 additions and 3 deletions

View File

@@ -674,11 +674,12 @@ impl<M: ABIMachineImpl> ABIBody for ABIBodyImpl<M> {
_ => ret.push(M::gen_move(dest_reg, from_reg.to_reg(), ty)), _ => ret.push(M::gen_move(dest_reg, from_reg.to_reg(), ty)),
}; };
} }
&ABIArg::Stack(off, ty, ext) => { &ABIArg::Stack(off, mut ty, ext) => {
let from_bits = ty_bits(ty) as u8; let from_bits = ty_bits(ty) as u8;
// Trash the from_reg; it should be its last use. // Trash the from_reg; it should be its last use.
match (ext, from_bits) { match (ext, from_bits) {
(ArgumentExtension::Uext, n) | (ArgumentExtension::Sext, n) if n < 64 => { (ArgumentExtension::Uext, n) | (ArgumentExtension::Sext, n) if n < 64 => {
assert_eq!(RegClass::I64, from_reg.to_reg().get_class());
let signed = ext == ArgumentExtension::Sext; let signed = ext == ArgumentExtension::Sext;
ret.push(M::gen_extend( ret.push(M::gen_extend(
from_reg, from_reg,
@@ -687,6 +688,8 @@ impl<M: ABIMachineImpl> ABIBody for ABIBodyImpl<M> {
from_bits, from_bits,
/* to_bits = */ 64, /* to_bits = */ 64,
)); ));
// Store the extended version.
ty = I64;
} }
_ => {} _ => {}
}; };
@@ -1083,7 +1086,7 @@ impl<M: ABIMachineImpl> ABICall for ABICallImpl<M> {
&ABIArg::Reg(reg, ty, _) => { &ABIArg::Reg(reg, ty, _) => {
ctx.emit(M::gen_move(Writable::from_reg(reg.to_reg()), from_reg, ty)); ctx.emit(M::gen_move(Writable::from_reg(reg.to_reg()), from_reg, ty));
} }
&ABIArg::Stack(off, ty, ext) => { &ABIArg::Stack(off, mut ty, ext) => {
if ext != ir::ArgumentExtension::None && ty_bits(ty) < 64 { if ext != ir::ArgumentExtension::None && ty_bits(ty) < 64 {
assert_eq!(RegClass::I64, from_reg.get_class()); assert_eq!(RegClass::I64, from_reg.get_class());
let signed = match ext { let signed = match ext {
@@ -1101,6 +1104,8 @@ impl<M: ABIMachineImpl> ABICall for ABICallImpl<M> {
ty_bits(ty) as u8, ty_bits(ty) as u8,
64, 64,
)); ));
// Store the extended version.
ty = I64;
} }
ctx.emit(M::gen_store_stack( ctx.emit(M::gen_store_stack(
StackAMode::SPOffset(off, ty), StackAMode::SPOffset(off, ty),

View File

@@ -63,7 +63,7 @@ block0(v0: i32):
; nextln: ldp fp, lr, [sp], #16 ; nextln: ldp fp, lr, [sp], #16
; nextln: ret ; nextln: ret
function %f3(i32) -> i32 sext { function %f5(i32) -> i32 sext {
block0(v0: i32): block0(v0: i32):
return v0 return v0
} }
@@ -74,3 +74,59 @@ block0(v0: i32):
; nextln: mov sp, fp ; nextln: mov sp, fp
; nextln: ldp fp, lr, [sp], #16 ; nextln: ldp fp, lr, [sp], #16
; nextln: ret ; nextln: ret
function %f6(i8) -> i64 {
fn0 = %g(i32, i32, i32, i32, i32, i32, i32, i32, i8 sext) -> i64
block0(v0: i8):
v1 = iconst.i32 42
v2 = call fn0(v1, v1, v1, v1, v1, v1, v1, v1, v0)
return v2
}
; check: stp fp, lr, [sp, #-16]!
; nextln: mov fp, sp
; nextln: mov x8, x0
; nextln: sub sp, sp, #16
; nextln: virtual_sp_offset_adjust 16
; nextln: movz x0, #42
; nextln: movz x1, #42
; nextln: movz x2, #42
; nextln: movz x3, #42
; nextln: movz x4, #42
; nextln: movz x5, #42
; nextln: movz x6, #42
; nextln: movz x7, #42
; nextln: sxtb x8, w8
; nextln: stur x8, [sp]
; nextln: ldr x16, 8 ; b 12 ; data
; nextln: blr x16
; nextln: add sp, sp, #16
; nextln: virtual_sp_offset_adjust -16
; nextln: mov sp, fp
; nextln: ldp fp, lr, [sp], #16
; nextln: ret
function %f7(i8) -> i32, i32, i32, i32, i32, i32, i32, i32, i8 sext {
block0(v0: i8):
v1 = iconst.i32 42
return v1, v1, v1, v1, v1, v1, v1, v1, v0
}
; check: stp fp, lr, [sp, #-16]!
; nextln: mov fp, sp
; nextln: mov x9, x0
; nextln: mov x8, x1
; nextln: movz x0, #42
; nextln: movz x1, #42
; nextln: movz x2, #42
; nextln: movz x3, #42
; nextln: movz x4, #42
; nextln: movz x5, #42
; nextln: movz x6, #42
; nextln: movz x7, #42
; nextln: sxtb x9, w9
; nextln: stur x9, [x8]
; nextln: mov sp, fp
; nextln: ldp fp, lr, [sp], #16
; nextln: ret