use llvm::{ValueRef};
use abi::{Abi, FnType};
use adt;
-use mir::lvalue::LvalueRef;
+use mir::lvalue::{LvalueRef, Alignment};
use base::*;
use common::*;
use declare;
use std::cmp::Ordering;
use std::iter;
-use mir::lvalue::Alignment;
-
fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
let llvm_name = match name {
"sqrtf32" => "llvm.sqrt.f32",
let ccx = bcx.ccx;
let tcx = ccx.tcx();
- let (def_id, substs, fty) = match callee_ty.sty {
- ty::TyFnDef(def_id, substs, ref fty) => (def_id, substs, fty),
+ let (def_id, substs, sig) = match callee_ty.sty {
+ ty::TyFnDef(def_id, substs, sig) => (def_id, substs, sig),
_ => bug!("expected fn item type, found {}", callee_ty)
};
- let sig = tcx.erase_late_bound_regions_and_normalize(&fty.sig);
+ let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = &*tcx.item_name(def_id).as_str();
}
"min_align_of" => {
let tp_ty = substs.type_at(0);
- C_uint(ccx, type_of::align_of(ccx, tp_ty))
+ C_uint(ccx, ccx.align_of(tp_ty))
}
"min_align_of_val" => {
let tp_ty = substs.type_at(0);
glue::size_and_align_of_dst(bcx, tp_ty, llargs[1]);
llalign
} else {
- C_uint(ccx, type_of::align_of(ccx, tp_ty))
+ C_uint(ccx, ccx.align_of(tp_ty))
}
}
"pref_align_of" => {
C_nil(ccx)
}
// Effectively no-ops
- "uninit" | "forget" => {
+ "uninit" => {
C_nil(ccx)
}
"needs_drop" => {
}
let load = bcx.volatile_load(ptr);
unsafe {
- llvm::LLVMSetAlignment(load, type_of::align_of(ccx, tp_ty));
+ llvm::LLVMSetAlignment(load, ccx.align_of(tp_ty));
}
to_immediate(bcx, load, tp_ty)
},
let ptr = bcx.pointercast(llargs[0], val_ty(val).ptr_to());
let store = bcx.volatile_store(val, ptr);
unsafe {
- llvm::LLVMSetAlignment(store, type_of::align_of(ccx, tp_ty));
+ llvm::LLVMSetAlignment(store, ccx.align_of(tp_ty));
}
}
C_nil(ccx)
"ctlz" | "cttz" | "ctpop" | "bswap" |
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
"overflowing_add" | "overflowing_sub" | "overflowing_mul" |
- "unchecked_div" | "unchecked_rem" => {
+ "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => {
let sty = &arg_tys[0].sty;
match int_type_width_signed(sty, ccx) {
Some((width, signed)) =>
} else {
bcx.urem(llargs[0], llargs[1])
},
+ "unchecked_shl" => bcx.shl(llargs[0], llargs[1]),
+ "unchecked_shr" =>
+ if signed {
+ bcx.ashr(llargs[0], llargs[1])
+ } else {
+ bcx.lshr(llargs[0], llargs[1])
+ },
_ => bug!(),
},
None => {
for i in 0..elems.len() {
let val = bcx.extract_value(val, i);
- bcx.store(val, bcx.struct_gep(llresult, i), None);
+ let lval = LvalueRef::new_sized_ty(llresult, ret_ty,
+ Alignment::AbiAligned);
+ let (dest, align) = lval.trans_field_ptr(bcx, i);
+ bcx.store(val, dest, align.to_align());
}
C_nil(ccx)
}
if val_ty(llval) != Type::void(ccx) && machine::llsize_of_alloc(ccx, val_ty(llval)) != 0 {
if let Some(ty) = fn_ty.ret.cast {
let ptr = bcx.pointercast(llresult, ty.ptr_to());
- bcx.store(llval, ptr, Some(type_of::align_of(ccx, ret_ty)));
+ bcx.store(llval, ptr, Some(ccx.align_of(ret_ty)));
} else {
store_ty(bcx, llval, llresult, Alignment::AbiAligned, ret_ty);
}
-> ValueRef {
let ccx = bcx.ccx;
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 align = C_i32(ccx, ccx.align_of(tp_ty) as i32);
let size = machine::llsize_of(ccx, lltp_ty);
let int_size = machine::llbitsize_of_real(ccx, ccx.int_type());
count: ValueRef
) -> ValueRef {
let ccx = bcx.ccx;
- let align = C_i32(ccx, type_of::align_of(ccx, ty) as i32);
+ let align = C_i32(ccx, ccx.align_of(ty) as i32);
let lltp_ty = type_of::type_of(ccx, ty);
let size = machine::llsize_of(ccx, lltp_ty);
let dst = bcx.pointercast(dst, Type::i8p(ccx));
output: Ty<'tcx>,
trans: &mut for<'b> FnMut(Builder<'b, 'tcx>))
-> ValueRef {
- let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false);
-
- let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy {
- unsafety: hir::Unsafety::Unsafe,
- abi: Abi::Rust,
- sig: ty::Binder(sig)
- }));
+ let rust_fn_ty = ccx.tcx().mk_fn_ptr(ty::Binder(ccx.tcx().mk_fn_sig(
+ inputs.into_iter(),
+ output,
+ false,
+ hir::Unsafety::Unsafe,
+ Abi::Rust
+ )));
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
let bcx = Builder::new_block(ccx, llfn, "entry-block");
trans(bcx);
// Define the type up front for the signature of the rust_try function.
let tcx = ccx.tcx();
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
- let fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
- unsafety: hir::Unsafety::Unsafe,
- abi: Abi::Rust,
- sig: ty::Binder(tcx.mk_fn_sig(iter::once(i8p), tcx.mk_nil(), false)),
- }));
+ let fn_ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
+ iter::once(i8p),
+ tcx.mk_nil(),
+ false,
+ hir::Unsafety::Unsafe,
+ Abi::Rust
+ )));
let output = tcx.types.i32;
let rust_try = gen_fn(ccx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans);
ccx.rust_try_fn().set(Some(rust_try));
let tcx = bcx.tcx();
- let sig = tcx.erase_late_bound_regions_and_normalize(callee_ty.fn_sig());
+ let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig());
let arg_tys = sig.inputs();
// every intrinsic takes a SIMD vector as its first argument