Merge pull request #2892 from afonso360/aarch64-multireg-args
Handle i128 arguments in the aarch64 ABI
This commit is contained in:
@@ -1529,10 +1529,21 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
// N.B.: according to the AArch64 ABI, the top bits of a register
|
||||
// (above the bits for the value's type) are undefined, so we
|
||||
// need not extend the return values.
|
||||
let reg = put_input_in_reg(ctx, *input, NarrowValueMode::None);
|
||||
let retval_reg = ctx.retval(i).only_reg().unwrap();
|
||||
let src_regs = put_input_in_regs(ctx, *input);
|
||||
let retval_regs = ctx.retval(i);
|
||||
|
||||
assert_eq!(src_regs.len(), retval_regs.len());
|
||||
let ty = ctx.input_ty(insn, i);
|
||||
ctx.emit(Inst::gen_move(retval_reg, reg, ty));
|
||||
let (_, tys) = Inst::rc_for_type(ty)?;
|
||||
|
||||
src_regs
|
||||
.regs()
|
||||
.iter()
|
||||
.zip(retval_regs.regs().iter())
|
||||
.zip(tys.iter())
|
||||
.for_each(|((&src, &dst), &ty)| {
|
||||
ctx.emit(Inst::gen_move(dst, src, ty));
|
||||
});
|
||||
}
|
||||
// N.B.: the Ret itself is generated by the ABI.
|
||||
}
|
||||
@@ -1710,13 +1721,13 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
assert!(inputs.len() == abi.num_args());
|
||||
for i in abi.get_copy_to_arg_order() {
|
||||
let input = inputs[i];
|
||||
let arg_reg = put_input_in_reg(ctx, input, NarrowValueMode::None);
|
||||
abi.emit_copy_regs_to_arg(ctx, i, ValueRegs::one(arg_reg));
|
||||
let arg_regs = put_input_in_regs(ctx, input);
|
||||
abi.emit_copy_regs_to_arg(ctx, i, arg_regs);
|
||||
}
|
||||
abi.emit_call(ctx);
|
||||
for (i, output) in outputs.iter().enumerate() {
|
||||
let retval_reg = get_output_reg(ctx, *output).only_reg().unwrap();
|
||||
abi.emit_copy_retval_to_regs(ctx, i, ValueRegs::one(retval_reg));
|
||||
let retval_regs = get_output_reg(ctx, *output);
|
||||
abi.emit_copy_retval_to_regs(ctx, i, retval_regs);
|
||||
}
|
||||
abi.emit_stack_post_adjust(ctx);
|
||||
}
|
||||
@@ -2263,7 +2274,39 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
panic!("Vector ops not implemented.");
|
||||
}
|
||||
|
||||
Opcode::Isplit | Opcode::Iconcat => panic!("Vector ops not supported."),
|
||||
Opcode::Isplit => {
|
||||
assert_eq!(
|
||||
ctx.input_ty(insn, 0),
|
||||
I128,
|
||||
"Isplit only implemented for i128's"
|
||||
);
|
||||
assert_eq!(ctx.output_ty(insn, 0), I64);
|
||||
assert_eq!(ctx.output_ty(insn, 1), I64);
|
||||
|
||||
let src_regs = put_input_in_regs(ctx, inputs[0]);
|
||||
let dst_lo = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let dst_hi = get_output_reg(ctx, outputs[1]).only_reg().unwrap();
|
||||
|
||||
ctx.emit(Inst::gen_move(dst_lo, src_regs.regs()[0], I64));
|
||||
ctx.emit(Inst::gen_move(dst_hi, src_regs.regs()[1], I64));
|
||||
}
|
||||
|
||||
Opcode::Iconcat => {
|
||||
assert_eq!(
|
||||
ctx.output_ty(insn, 0),
|
||||
I128,
|
||||
"Iconcat only implemented for i128's"
|
||||
);
|
||||
assert_eq!(ctx.input_ty(insn, 0), I64);
|
||||
assert_eq!(ctx.input_ty(insn, 1), I64);
|
||||
|
||||
let src_lo = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let src_hi = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let dst = get_output_reg(ctx, outputs[0]);
|
||||
|
||||
ctx.emit(Inst::gen_move(dst.regs()[0], src_lo, I64));
|
||||
ctx.emit(Inst::gen_move(dst.regs()[1], src_hi, I64));
|
||||
}
|
||||
|
||||
Opcode::Imax | Opcode::Umax | Opcode::Umin | Opcode::Imin => {
|
||||
let alu_op = match op {
|
||||
|
||||
Reference in New Issue
Block a user