]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/intrinsic.rs
Rollup merge of #41249 - GuillaumeGomez:rustdoc-render, r=steveklabnik,frewsxcv
[rust.git] / src / librustc_trans / intrinsic.rs
index 333a0802ee6ff664c75ebdb4d3a4f8d4ae57c735..7077eade61182af2387119e8dd0801d8e3b48062 100644 (file)
@@ -16,7 +16,7 @@
 use llvm::{ValueRef};
 use abi::{Abi, FnType};
 use adt;
-use mir::lvalue::LvalueRef;
+use mir::lvalue::{LvalueRef, Alignment};
 use base::*;
 use common::*;
 use declare;
@@ -36,8 +36,6 @@
 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",
@@ -97,12 +95,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
     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();
@@ -151,7 +149,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
         }
         "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);
@@ -160,7 +158,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                     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" => {
@@ -188,7 +186,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
             C_nil(ccx)
         }
         // Effectively no-ops
-        "uninit" | "forget" => {
+        "uninit" => {
             C_nil(ccx)
         }
         "needs_drop" => {
@@ -234,7 +232,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
             }
             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)
         },
@@ -252,7 +250,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                 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)
@@ -261,7 +259,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
         "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)) =>
@@ -311,6 +309,13 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                             } 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 => {
@@ -615,7 +620,10 @@ fn modify_as_needed<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
 
                     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)
                 }
@@ -627,7 +635,7 @@ fn modify_as_needed<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
     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);
         }
@@ -644,7 +652,7 @@ fn copy_intrinsic<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                             -> 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());
 
@@ -678,7 +686,7 @@ fn memset_intrinsic<'a, 'tcx>(
     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));
@@ -878,13 +886,13 @@ fn gen_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     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);
@@ -905,11 +913,13 @@ fn get_rust_try_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     // 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));
@@ -959,7 +969,7 @@ macro_rules! require_simd {
 
 
     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