Baldrdash: implement support for sign-extension in returns;

This commit is contained in:
Benjamin Bouvier
2020-04-10 14:50:39 +02:00
parent 241c164e25
commit 5b8b75def0
4 changed files with 83 additions and 18 deletions

View File

@@ -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 {

View File

@@ -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,