Add some basic intrinsic support (only size_of atm)

This commit is contained in:
bjorn3 2018-07-21 18:38:08 +02:00
parent 0350f2faa9
commit 4fad0f714f
3 changed files with 83 additions and 22 deletions

View File

@ -3,7 +3,7 @@
#![allow(dead_code)]
#[lang="sized"]
trait Sized {}
pub trait Sized {}
#[lang="copy"]
unsafe trait Copy {}
@ -68,8 +68,11 @@ unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
drop_in_place(to_drop);
}
extern "rust-intrinsic" {
fn copy<T>(src: *const T, dst: *mut T, count: usize);
mod intrinsics {
extern "rust-intrinsic" {
pub fn size_of<T>() -> usize;
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
}
}
fn abc(a: u8) -> u8 {
@ -149,10 +152,20 @@ fn debug_tuple() -> DebugTuple {
DebugTuple(())
}
unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
copy::<u8>(src, dst, 1);
fn size_of<T>() -> usize {
unsafe {
intrinsics::size_of::<T>()
}
}
fn use_size_of() -> usize {
size_of::<u64>()
}
/*unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
intrinsics::copy::<u8>(src, dst, 1);
}*/
/*unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) {
let copy2 = &copy::<u8>;
copy2(src, dst, 1);

View File

@ -12,7 +12,7 @@ pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<
let (call_conv, inputs, _output): (CallConv, Vec<Ty>, Ty) = match sig.abi {
Abi::Rust => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
Abi::RustCall => {
unimplemented!();
unimplemented!("rust-call");
}
Abi::System => bug!("system abi should be selected elsewhere"),
// TODO: properly implement intrinsics
@ -153,25 +153,73 @@ pub fn codegen_call<'a, 'tcx: 'a>(
destination: &Option<(Place<'tcx>, BasicBlock)>,
) {
let func = ::base::trans_operand(fx, func);
let return_place = if let Some((place, _)) = destination {
::base::trans_place(fx, place).expect_addr()
Some(::base::trans_place(fx, place))
} else {
fx.bcx.ins().iconst(types::I64, 0)
None
};
let args = Some(return_place)
let args = args
.into_iter()
.chain(
args
.into_iter()
.map(|arg| {
let arg = ::base::trans_operand(fx, arg);
if let Some(_) = fx.cton_type(arg.layout().ty) {
arg.load_value(fx)
} else {
arg.force_stack(fx)
}
})
).collect::<Vec<_>>();
.map(|arg| {
let arg = ::base::trans_operand(fx, arg);
if let Some(_) = fx.cton_type(arg.layout().ty) {
arg.load_value(fx)
} else {
arg.force_stack(fx)
}
})
.collect::<Vec<_>>();
let fn_ty = func.layout().ty;
if let TypeVariants::TyFnDef(def_id, substs) = fn_ty.sty {
let instance = ty::Instance::resolve(
fx.tcx,
ParamEnv::reveal_all(),
def_id,
substs
).unwrap();
// Handle intrinsics old codegen wants Expr's for, ourselves.
if let InstanceDef::Intrinsic(def_id) = instance.def {
let intrinsic = fx.tcx.item_name(def_id).as_str();
let intrinsic = &intrinsic[..];
let usize_layout = fx.layout_of(fx.tcx.types.usize);
match intrinsic {
"copy" => {
/*let elem_ty = substs.type_at(0);
assert_eq!(args.len(), 3);
let src = args[0];
let dst = args[1];
let count = args[2];*/
unimplemented!("copy");
}
"size_of" => {
let size_of = fx.layout_of(substs.type_at(0)).size.bytes();
let size_of = CValue::const_val(fx, usize_layout.ty, size_of as i64);
return_place.unwrap().write_cvalue(fx, size_of);
}
_ => fx.tcx.sess.fatal(&format!("unsupported intrinsic {}", intrinsic)),
}
if let Some((_, dest)) = *destination {
let ret_ebb = fx.get_ebb(dest);
fx.bcx.ins().jump(ret_ebb, &[]);
} else {
fx.bcx.ins().trap(TrapCode::User(!0));
}
return;
}
}
let return_ptr = match return_place {
Some(place) => place.expect_addr(),
None => fx.bcx.ins().iconst(types::I64, 0),
};
let args = Some(return_ptr).into_iter().chain(args).collect::<Vec<_>>();
match func {
CValue::Func(func, _) => {
fx.bcx.ins().call(func, &args);

View File

@ -168,7 +168,7 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
pub fn layout(&self) -> TyLayout<'tcx> {
match *self {
CPlace::Var(_, layout) |
CPlace::Addr(_, layout) => layout
CPlace::Addr(_, layout) => layout,
}
}