Heed uext and sext annotations on RISC-V arguments.
Translate the small integer arguments to i32 or i64 with the appropriate extend and ireduce instructions.
This commit is contained in:
@@ -41,6 +41,13 @@ ebb0(v0: i64):
|
|||||||
return v0
|
return v0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function int_ext(i8, i8 sext, i8 uext) -> i8 {
|
||||||
|
ebb0(v1: i8, v2: i8, v3: i8):
|
||||||
|
; check: $ebb0($v1: i8, $(v2x=$VX): i32, $(v3x=$VX): i32):
|
||||||
|
; check: ireduce.i8 $v2x
|
||||||
|
; check: ireduce.i8 $v3x
|
||||||
|
}
|
||||||
|
|
||||||
function vector_split_args(i64x4) -> i64 {
|
function vector_split_args(i64x4) -> i64 {
|
||||||
ebb0(v0: i64x4):
|
ebb0(v0: i64x4):
|
||||||
; check: $ebb0($(v0al=$VX): i32, $(v0ah=$VX): i32, $(v0bl=$VX): i32, $(v0bh=$VX): i32, $(v0cl=$VX): i32, $(v0ch=$VX): i32, $(v0dl=$VX): i32, $(v0dh=$VX): i32):
|
; check: $ebb0($(v0al=$VX): i32, $(v0ah=$VX): i32, $(v0bl=$VX): i32, $(v0bh=$VX): i32, $(v0cl=$VX): i32, $(v0ch=$VX): i32, $(v0dl=$VX): i32, $(v0dh=$VX): i32):
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
//! This doesn't support the soft-float ABI at the moment.
|
//! This doesn't support the soft-float ABI at the moment.
|
||||||
|
|
||||||
use abi::{ArgAction, ValueConversion, ArgAssigner, legalize_args};
|
use abi::{ArgAction, ValueConversion, ArgAssigner, legalize_args};
|
||||||
use ir::{Signature, ArgumentType, ArgumentLoc};
|
use ir::{Signature, Type, ArgumentType, ArgumentLoc, ArgumentExtension};
|
||||||
use isa::riscv::registers::{GPR, FPR};
|
use isa::riscv::registers::{GPR, FPR};
|
||||||
use settings as shared_settings;
|
use settings as shared_settings;
|
||||||
|
|
||||||
struct Args {
|
struct Args {
|
||||||
pointer_bits: u16,
|
pointer_bits: u16,
|
||||||
pointer_bytes: u32,
|
pointer_bytes: u32,
|
||||||
|
pointer_type: Type,
|
||||||
regs: u32,
|
regs: u32,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
}
|
}
|
||||||
@@ -22,6 +23,7 @@ impl Args {
|
|||||||
Args {
|
Args {
|
||||||
pointer_bits: bits,
|
pointer_bits: bits,
|
||||||
pointer_bytes: bits as u32 / 8,
|
pointer_bytes: bits as u32 / 8,
|
||||||
|
pointer_type: Type::int(bits).unwrap(),
|
||||||
regs: 0,
|
regs: 0,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}
|
}
|
||||||
@@ -50,6 +52,19 @@ impl ArgAssigner for Args {
|
|||||||
return ArgAction::Convert(ValueConversion::IntSplit);
|
return ArgAction::Convert(ValueConversion::IntSplit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Small integers are extended to the size of a pointer register.
|
||||||
|
if ty.is_int() && ty.bits() < self.pointer_bits {
|
||||||
|
match arg.extension {
|
||||||
|
ArgumentExtension::None => {}
|
||||||
|
ArgumentExtension::Uext => {
|
||||||
|
return ArgAction::Convert(ValueConversion::Uext(self.pointer_type))
|
||||||
|
}
|
||||||
|
ArgumentExtension::Sext => {
|
||||||
|
return ArgAction::Convert(ValueConversion::Sext(self.pointer_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.regs < 8 {
|
if self.regs < 8 {
|
||||||
// Assign to a register.
|
// Assign to a register.
|
||||||
let reg = if ty.is_float() {
|
let reg = if ty.is_float() {
|
||||||
|
|||||||
Reference in New Issue
Block a user