use arena::TypedArena;
use intrinsics::{self, Intrinsic};
+use libc;
use llvm;
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
use middle::subst;
use trans::cleanup;
use trans::cleanup::CleanupMethods;
use trans::common::*;
+use trans::consts;
use trans::datum::*;
use trans::debuginfo::DebugLoc;
use trans::declare;
use middle::subst::Substs;
use syntax::abi::{self, RustIntrinsic};
use syntax::ast;
+use syntax::ptr::P;
use syntax::parse::token;
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
}
}
+ // save the actual AST arguments for later (some places need to do
+ // const-evaluation on them)
+ let expr_arguments = match args {
+ callee::ArgExprs(args) => Some(args),
+ _ => None,
+ };
+
// Push the arguments.
let mut llargs = Vec::new();
bcx = callee::trans_args(bcx,
generic_simd_intrinsic(bcx, name,
substs,
callee_ty,
+ expr_arguments,
&llargs,
ret_ty, llret_ty,
call_debug_location,
return rust_try
}
-fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
- name: &str,
- _substs: subst::Substs<'tcx>,
- callee_ty: Ty<'tcx>,
- llargs: &[ValueRef],
- ret_ty: Ty<'tcx>,
- llret_ty: Type,
- call_debug_location: DebugLoc,
- call_info: NodeIdAndSpan) -> ValueRef {
+fn generic_simd_intrinsic<'blk, 'tcx, 'a>
+ (bcx: Block<'blk, 'tcx>,
+ name: &str,
+ substs: subst::Substs<'tcx>,
+ callee_ty: Ty<'tcx>,
+ args: Option<&[P<ast::Expr>]>,
+ llargs: &[ValueRef],
+ ret_ty: Ty<'tcx>,
+ llret_ty: Type,
+ call_debug_location: DebugLoc,
+ call_info: NodeIdAndSpan) -> ValueRef
+{
let tcx = bcx.tcx();
let arg_tys = match callee_ty.sty {
ty::TyBareFn(_, ref f) => {
Err(_) => tcx.sess.span_bug(call_info.span,
"bad `simd_shuffle` instruction only caught in trans?")
};
- assert_eq!(llargs.len(), 2 + n);
require!(arg_tys[0] == arg_tys[1],
"SIMD shuffle intrinsic monomorphised with different input types");
let total_len = in_len as u64 * 2;
- let indices: Option<Vec<_>> = llargs[2..]
- .iter()
- .enumerate()
- .map(|(i, val)| {
- let arg_idx = i + 2;
- let c = const_to_opt_uint(*val);
+ let vector = match args {
+ Some(args) => &args[2],
+ None => bcx.sess().span_bug(call_info.span,
+ "intrinsic call with unexpected argument shape"),
+ };
+ let vector = consts::const_expr(bcx.ccx(), vector, tcx.mk_substs(substs), None).0;
+
+ let indices: Option<Vec<_>> = (0..n)
+ .map(|i| {
+ let arg_idx = i;
+ let val = const_get_elt(bcx.ccx(), vector, &[i as libc::c_uint]);
+ let c = const_to_opt_uint(val);
match c {
None => {
bcx.sess().span_err(call_info.span,
use {CrateCtxt, require_same_types};
use std::collections::{HashMap};
-use std::iter;
use syntax::abi;
use syntax::attr::AttrMetaMethods;
use syntax::ast;
name if name.starts_with("simd_shuffle") => {
match name["simd_shuffle".len()..].parse() {
Ok(n) => {
- let mut params = vec![param(0), param(0)];
- params.extend(iter::repeat(tcx.types.u32).take(n));
+ let params = vec![param(0), param(0),
+ tcx.mk_ty(ty::TyArray(tcx.types.u32, n))];
let ictxt = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
let ret = ictxt.next_ty_var();