Implement some intrinsics and fix a codegen error
* intrinsic size_of_val for sized types * intrinsic needs_drop * incorrect codegen for UnOp::Not for bools
This commit is contained in:
parent
87c17aba92
commit
0fb7c4d1b9
4 changed files with 66 additions and 9 deletions
|
|
@ -50,6 +50,21 @@ unsafe impl Sync for [u8; 16] {}
|
|||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
|
||||
#[lang = "not"]
|
||||
pub trait Not {
|
||||
type Output;
|
||||
|
||||
fn not(self) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Not for bool {
|
||||
type Output = bool;
|
||||
|
||||
fn not(self) -> bool {
|
||||
!self
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "mul"]
|
||||
pub trait Mul<RHS = Self> {
|
||||
type Output;
|
||||
|
|
@ -211,6 +226,7 @@ pub mod intrinsics {
|
|||
pub fn transmute<T, U>(e: T) -> U;
|
||||
pub fn uninit<T>() -> T;
|
||||
pub fn ctlz_nonzero<T>(x: T) -> T;
|
||||
pub fn needs_drop<T>() -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ unsafe extern "C" fn my_puts(s: *const u8) {
|
|||
// TODO remove when jit supports linking rlibs
|
||||
#[cfg(jit)]
|
||||
fn panic<T>(_: T) {
|
||||
loop {}
|
||||
unsafe {
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "termination"]
|
||||
|
|
@ -113,6 +115,18 @@ fn main() {
|
|||
if intrinsics::size_of_val(a) as u8 != 16 {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
|
||||
if intrinsics::size_of_val(&0u32) as u8 != 4 {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
|
||||
if intrinsics::needs_drop::<u8>() {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
|
||||
if !intrinsics::needs_drop::<NoisyDrop>() {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
let _ = NoisyDrop {
|
||||
|
|
|
|||
17
src/abi.rs
17
src/abi.rs
|
|
@ -660,7 +660,11 @@ fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
|||
}
|
||||
"size_of_val" => {
|
||||
assert_eq!(args.len(), 1);
|
||||
let size = match &substs.type_at(0).sty {
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let size = match &layout.ty.sty {
|
||||
_ if !layout.is_unsized() => {
|
||||
fx.bcx.ins().iconst(fx.module.pointer_type(), layout.size.bytes() as i64)
|
||||
}
|
||||
ty::Slice(elem) => {
|
||||
let len = args[0].load_value_pair(fx).1;
|
||||
let elem_size = fx.layout_of(elem).size.bytes();
|
||||
|
|
@ -821,6 +825,17 @@ fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
|||
let res = CValue::ByVal(fx.bcx.ins().popcnt(arg), args[0].layout());
|
||||
ret.write_cvalue(fx, res);
|
||||
}
|
||||
"needs_drop" => {
|
||||
assert_eq!(args.len(), 0);
|
||||
let ty = substs.type_at(0);
|
||||
let needs_drop = if ty.needs_drop(fx.tcx, ParamEnv::reveal_all()) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let needs_drop = CValue::const_val(fx, fx.tcx.types.bool, needs_drop);
|
||||
ret.write_cvalue(fx, needs_drop);
|
||||
}
|
||||
_ => unimpl!("unsupported intrinsic {}", intrinsic),
|
||||
}
|
||||
|
||||
|
|
|
|||
26
src/base.rs
26
src/base.rs
|
|
@ -432,19 +432,31 @@ fn trans_stmt<'a, 'tcx: 'a>(
|
|||
lval.write_cvalue(fx, res);
|
||||
}
|
||||
Rvalue::UnaryOp(un_op, operand) => {
|
||||
let ty = fx.monomorphize(&operand.ty(&fx.mir.local_decls, fx.tcx));
|
||||
let layout = fx.layout_of(ty);
|
||||
let val = trans_operand(fx, operand).load_value(fx);
|
||||
let operand = trans_operand(fx, operand);
|
||||
let layout = operand.layout();
|
||||
let val = operand.load_value(fx);
|
||||
let res = match un_op {
|
||||
UnOp::Not => fx.bcx.ins().bnot(val),
|
||||
UnOp::Neg => match ty.sty {
|
||||
UnOp::Not => {
|
||||
match layout.ty.sty {
|
||||
ty::Bool => {
|
||||
let val = fx.bcx.ins().uextend(types::I32, val); // WORKAROUND for CraneStation/cranelift#466
|
||||
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
|
||||
fx.bcx.ins().bint(types::I8, res)
|
||||
}
|
||||
ty::Uint(_) | ty::Int(_) => {
|
||||
fx.bcx.ins().bnot(val)
|
||||
}
|
||||
_ => unimplemented!("un op Not for {:?}", layout.ty),
|
||||
}
|
||||
},
|
||||
UnOp::Neg => match layout.ty.sty {
|
||||
ty::Int(_) => {
|
||||
let clif_ty = fx.cton_type(ty).unwrap();
|
||||
let clif_ty = fx.cton_type(layout.ty).unwrap();
|
||||
let zero = fx.bcx.ins().iconst(clif_ty, 0);
|
||||
fx.bcx.ins().isub(zero, val)
|
||||
}
|
||||
ty::Float(_) => fx.bcx.ins().fneg(val),
|
||||
_ => unimplemented!("un op Neg for {:?}", ty),
|
||||
_ => unimplemented!("un op Neg for {:?}", layout.ty),
|
||||
},
|
||||
};
|
||||
lval.write_cvalue(fx, CValue::ByVal(res, layout));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue