Browse Source

machinst x64: baldrdash: fix multi-value when both gpr and xmm are returned;

In baldrdash, only the first return value may live in a register, be it
an integer or a floating point value.
pull/2072/head
Benjamin Bouvier 4 years ago
parent
commit
4b26f5b120
  1. 24
      cranelift/codegen/src/isa/x64/abi.rs

24
cranelift/codegen/src/isa/x64/abi.rs

@ -129,15 +129,19 @@ fn get_fltreg_for_arg_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
}
}
fn get_intreg_for_retval_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
fn get_intreg_for_retval_systemv(
call_conv: &CallConv,
intreg_idx: usize,
retval_idx: usize,
) -> Option<Reg> {
match call_conv {
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match idx {
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match intreg_idx {
0 => Some(regs::rax()),
1 => Some(regs::rdx()),
_ => None,
},
CallConv::BaldrdashSystemV => {
if idx == 0 {
if intreg_idx == 0 && retval_idx == 0 {
Some(regs::rax())
} else {
None
@ -147,15 +151,19 @@ fn get_intreg_for_retval_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg
}
}
fn get_fltreg_for_retval_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
fn get_fltreg_for_retval_systemv(
call_conv: &CallConv,
fltreg_idx: usize,
retval_idx: usize,
) -> Option<Reg> {
match call_conv {
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match idx {
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match fltreg_idx {
0 => Some(regs::xmm0()),
1 => Some(regs::xmm1()),
_ => None,
},
CallConv::BaldrdashSystemV => {
if idx == 0 {
if fltreg_idx == 0 && retval_idx == 0 {
Some(regs::xmm0())
} else {
None
@ -823,7 +831,7 @@ fn compute_arg_locs(
let (next_reg, candidate) = if intreg {
let candidate = match args_or_rets {
ArgsOrRets::Args => get_intreg_for_arg_systemv(&call_conv, next_gpr),
ArgsOrRets::Rets => get_intreg_for_retval_systemv(&call_conv, next_gpr),
ArgsOrRets::Rets => get_intreg_for_retval_systemv(&call_conv, next_gpr, i),
};
debug_assert!(candidate
.map(|r| r.get_class() == RegClass::I64)
@ -832,7 +840,7 @@ fn compute_arg_locs(
} else {
let candidate = match args_or_rets {
ArgsOrRets::Args => get_fltreg_for_arg_systemv(&call_conv, next_vreg),
ArgsOrRets::Rets => get_fltreg_for_retval_systemv(&call_conv, next_vreg),
ArgsOrRets::Rets => get_fltreg_for_retval_systemv(&call_conv, next_vreg, i),
};
debug_assert!(candidate
.map(|r| r.get_class() == RegClass::V128)

Loading…
Cancel
Save