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:
@@ -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),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user