Baldrdash: implement support for sign-extension in returns;
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
use crate::ir;
|
||||
use crate::ir::types;
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::StackSlot;
|
||||
use crate::ir::{ArgumentExtension, StackSlot};
|
||||
use crate::isa;
|
||||
use crate::isa::aarch64::inst::*;
|
||||
use crate::isa::aarch64::{self, inst::*};
|
||||
use crate::machinst::*;
|
||||
use crate::settings;
|
||||
|
||||
@@ -469,11 +469,67 @@ impl ABIBody for AArch64ABIBody {
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_copy_reg_to_retval(&self, idx: usize, from_reg: Reg) -> Inst {
|
||||
fn gen_copy_reg_to_retval(
|
||||
&self,
|
||||
idx: usize,
|
||||
from_reg: Writable<Reg>,
|
||||
ext: ArgumentExtension,
|
||||
) -> Vec<Inst> {
|
||||
let mut ret = Vec::new();
|
||||
match &self.sig.rets[idx] {
|
||||
&ABIArg::Reg(r, ty) => Inst::gen_move(Writable::from_reg(r.to_reg()), from_reg, ty),
|
||||
&ABIArg::Stack(off, ty) => store_stack(off + self.frame_size(), from_reg, ty),
|
||||
&ABIArg::Reg(r, ty) => {
|
||||
let from_bits = aarch64::lower::ty_bits(ty) as u8;
|
||||
let dest_reg = Writable::from_reg(r.to_reg());
|
||||
match (ext, from_bits) {
|
||||
(ArgumentExtension::Uext, n) if n < 64 => {
|
||||
ret.push(Inst::Extend {
|
||||
rd: dest_reg,
|
||||
rn: from_reg.to_reg(),
|
||||
signed: false,
|
||||
from_bits,
|
||||
to_bits: 64,
|
||||
});
|
||||
}
|
||||
(ArgumentExtension::Sext, n) if n < 64 => {
|
||||
ret.push(Inst::Extend {
|
||||
rd: dest_reg,
|
||||
rn: from_reg.to_reg(),
|
||||
signed: true,
|
||||
from_bits,
|
||||
to_bits: 64,
|
||||
});
|
||||
}
|
||||
_ => ret.push(Inst::gen_move(dest_reg, from_reg.to_reg(), ty)),
|
||||
};
|
||||
}
|
||||
&ABIArg::Stack(off, ty) => {
|
||||
let from_bits = aarch64::lower::ty_bits(ty) as u8;
|
||||
// Trash the from_reg; it should be its last use.
|
||||
match (ext, from_bits) {
|
||||
(ArgumentExtension::Uext, n) if n < 64 => {
|
||||
ret.push(Inst::Extend {
|
||||
rd: from_reg,
|
||||
rn: from_reg.to_reg(),
|
||||
signed: false,
|
||||
from_bits,
|
||||
to_bits: 64,
|
||||
});
|
||||
}
|
||||
(ArgumentExtension::Sext, n) if n < 64 => {
|
||||
ret.push(Inst::Extend {
|
||||
rd: from_reg,
|
||||
rn: from_reg.to_reg(),
|
||||
signed: true,
|
||||
from_bits,
|
||||
to_bits: 64,
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
ret.push(store_stack(off + self.frame_size(), from_reg.to_reg(), ty))
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn gen_ret(&self) -> Inst {
|
||||
|
||||
@@ -2364,7 +2364,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
|
||||
//=============================================================================
|
||||
// Helpers for instruction lowering.
|
||||
fn ty_bits(ty: Type) -> usize {
|
||||
|
||||
/// Returns the size (in bits) of a given type.
|
||||
pub fn ty_bits(ty: Type) -> usize {
|
||||
match ty {
|
||||
B1 => 1,
|
||||
B8 | I8 => 8,
|
||||
|
||||
Reference in New Issue
Block a user