Add some basic intrinsic support (only size_of atm)
This commit is contained in:
parent
0350f2faa9
commit
4fad0f714f
23
example.rs
23
example.rs
@ -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 = ©::<u8>;
|
||||
copy2(src, dst, 1);
|
||||
|
64
src/abi.rs
64
src/abi.rs
@ -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,15 +153,14 @@ 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)
|
||||
.into_iter()
|
||||
.chain(
|
||||
args
|
||||
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
let arg = ::base::trans_operand(fx, arg);
|
||||
@ -171,7 +170,56 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
||||
arg.force_stack(fx)
|
||||
}
|
||||
})
|
||||
).collect::<Vec<_>>();
|
||||
.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);
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user