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.
This commit is contained in:
@@ -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 {
|
match call_conv {
|
||||||
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match idx {
|
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match intreg_idx {
|
||||||
0 => Some(regs::rax()),
|
0 => Some(regs::rax()),
|
||||||
1 => Some(regs::rdx()),
|
1 => Some(regs::rdx()),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
CallConv::BaldrdashSystemV => {
|
CallConv::BaldrdashSystemV => {
|
||||||
if idx == 0 {
|
if intreg_idx == 0 && retval_idx == 0 {
|
||||||
Some(regs::rax())
|
Some(regs::rax())
|
||||||
} else {
|
} else {
|
||||||
None
|
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 {
|
match call_conv {
|
||||||
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match idx {
|
CallConv::Fast | CallConv::Cold | CallConv::SystemV => match fltreg_idx {
|
||||||
0 => Some(regs::xmm0()),
|
0 => Some(regs::xmm0()),
|
||||||
1 => Some(regs::xmm1()),
|
1 => Some(regs::xmm1()),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
CallConv::BaldrdashSystemV => {
|
CallConv::BaldrdashSystemV => {
|
||||||
if idx == 0 {
|
if fltreg_idx == 0 && retval_idx == 0 {
|
||||||
Some(regs::xmm0())
|
Some(regs::xmm0())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -823,7 +831,7 @@ fn compute_arg_locs(
|
|||||||
let (next_reg, candidate) = if intreg {
|
let (next_reg, candidate) = if intreg {
|
||||||
let candidate = match args_or_rets {
|
let candidate = match args_or_rets {
|
||||||
ArgsOrRets::Args => get_intreg_for_arg_systemv(&call_conv, next_gpr),
|
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
|
debug_assert!(candidate
|
||||||
.map(|r| r.get_class() == RegClass::I64)
|
.map(|r| r.get_class() == RegClass::I64)
|
||||||
@@ -832,7 +840,7 @@ fn compute_arg_locs(
|
|||||||
} else {
|
} else {
|
||||||
let candidate = match args_or_rets {
|
let candidate = match args_or_rets {
|
||||||
ArgsOrRets::Args => get_fltreg_for_arg_systemv(&call_conv, next_vreg),
|
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
|
debug_assert!(candidate
|
||||||
.map(|r| r.get_class() == RegClass::V128)
|
.map(|r| r.get_class() == RegClass::V128)
|
||||||
|
|||||||
Reference in New Issue
Block a user