pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
let _icx = push_ctxt("call_memcpy");
let ccx = cx.ccx();
- let key = match &ccx.sess().target.target.target_pointer_width[..] {
- "32" => "llvm.memcpy.p0i8.p0i8.i32",
- "64" => "llvm.memcpy.p0i8.p0i8.i64",
- tws => panic!("Unsupported target word size for memcpy: {}", tws),
- };
+ let ptr_width = &ccx.sess().target.target.target_pointer_width[..];
+ let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
let memcpy = ccx.get_intrinsic(&key);
let src_ptr = PointerCast(cx, src, Type::i8p(ccx));
let dst_ptr = PointerCast(cx, dst, Type::i8p(ccx));
let ccx = b.ccx;
let llty = type_of::type_of(ccx, ty);
-
- let intrinsic_key = match &ccx.sess().target.target.target_pointer_width[..] {
- "32" => "llvm.memset.p0i8.i32",
- "64" => "llvm.memset.p0i8.i64",
- tws => panic!("Unsupported target word size for memset: {}", tws),
- };
+ let ptr_width = &ccx.sess().target.target.target_pointer_width[..];
+ let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
let llintrinsicfn = ccx.get_intrinsic(&intrinsic_key);
let llptr = b.pointercast(llptr, Type::i8(ccx).ptr_to());
pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
let v = i.as_i64();
- match machine::llbitsize_of_real(ccx, ccx.int_type()) {
- 32 => assert!(v < (1<<31) && v >= -(1<<31)),
- 64 => {},
- n => panic!("unsupported target size: {}", n)
+ let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type());
+
+ if bit_size < 64 {
+ // make sure it doesn't overflow
+ assert!(v < (1<<(bit_size-1)) && v >= -(1<<(bit_size-1)));
}
C_integral(ccx.int_type(), v as u64, true)
pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
let v = i.as_u64();
- match machine::llbitsize_of_real(ccx, ccx.int_type()) {
- 32 => assert!(v < (1<<32)),
- 64 => {},
- n => panic!("unsupported target size: {}", n)
+ let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type());
+
+ if bit_size < 64 {
+ // make sure it doesn't overflow
+ assert!(v < (1<<bit_size));
}
C_integral(ccx.int_type(), v, false)
self.local.builder.b
}
- pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
+ pub fn get_intrinsic(&self, key: &str) -> ValueRef {
if let Some(v) = self.intrinsics().borrow().get(key).cloned() {
return v;
}
}
/// Declare any llvm intrinsics that you might need
-fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
+fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> {
macro_rules! ifn {
($name:expr, fn() -> $ret:expr) => (
- if *key == $name {
+ if key == $name {
let f = declare::declare_cfn(ccx, $name, Type::func(&[], &$ret),
ccx.tcx().mk_nil());
ccx.intrinsics().borrow_mut().insert($name, f.clone());
}
);
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
- if *key == $name {
+ if key == $name {
let f = declare::declare_cfn(ccx, $name, Type::func(&[$($arg),*], &$ret),
ccx.tcx().mk_nil());
ccx.intrinsics().borrow_mut().insert($name, f.clone());
let t_f32 = Type::f32(ccx);
let t_f64 = Type::f64(ccx);
+ ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
+ ifn!("llvm.memmove.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
+ ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
// The `if key == $name` is already in ifn!
ifn!($name, fn($($arg),*) -> void);
- } else if *key == $name {
+ } else if key == $name {
let f = declare::declare_cfn(ccx, stringify!($cname),
Type::func(&[$($arg),*], &void),
ccx.tcx().mk_nil());
if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
// The `if key == $name` is already in ifn!
ifn!($name, fn($($arg),*) -> $ret);
- } else if *key == $name {
+ } else if key == $name {
let f = declare::declare_cfn(ccx, stringify!($cname),
Type::func(&[$($arg),*], &$ret),
ccx.tcx().mk_nil());
let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
let size = machine::llsize_of(ccx, lltp_ty);
let int_size = machine::llbitsize_of_real(ccx, ccx.int_type());
- let name = if allow_overlap {
- if int_size == 32 {
- "llvm.memmove.p0i8.p0i8.i32"
- } else {
- "llvm.memmove.p0i8.p0i8.i64"
- }
+
+ let operation = if allow_overlap {
+ "memmove"
} else {
- if int_size == 32 {
- "llvm.memcpy.p0i8.p0i8.i32"
- } else {
- "llvm.memcpy.p0i8.p0i8.i64"
- }
+ "memcpy"
};
+ let name = format!("llvm.{}.p0i8.p0i8.i{}", operation, int_size);
+
let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
let src_ptr = PointerCast(bcx, src, Type::i8p(ccx));
let llfn = ccx.get_intrinsic(&name);
let lltp_ty = type_of::type_of(ccx, tp_ty);
let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
let size = machine::llsize_of(ccx, lltp_ty);
- let name = if machine::llbitsize_of_real(ccx, ccx.int_type()) == 32 {
- "llvm.memset.p0i8.i32"
- } else {
- "llvm.memset.p0i8.i64"
- };
+ let int_size = machine::llbitsize_of_real(ccx, ccx.int_type());
+
+ let name = format!("llvm.memset.p0i8.i{}", int_size);
let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
let llfn = ccx.get_intrinsic(&name);