Navigation Menu

Skip to content

Commit

Permalink
Switch shuffle intrinsics to arrays of indices.
Browse files Browse the repository at this point in the history
Format:

    fn shuffle_simdNNN<T, U>(x: T, y: T, idx: [u32; NNN]) -> U;
  • Loading branch information
huonw committed Aug 17, 2015
1 parent 2115468 commit 1f5739f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
51 changes: 35 additions & 16 deletions src/librustc_trans/trans/intrinsic.rs
Expand Up @@ -12,6 +12,7 @@

use arena::TypedArena;
use intrinsics::{self, Intrinsic};
use libc;
use llvm;
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
use middle::subst;
Expand All @@ -24,6 +25,7 @@ use trans::callee;
use trans::cleanup;
use trans::cleanup::CleanupMethods;
use trans::common::*;
use trans::consts;
use trans::datum::*;
use trans::debuginfo::DebugLoc;
use trans::declare;
Expand All @@ -38,6 +40,7 @@ use middle::ty::{self, Ty, HasTypeFlags};
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> {
Expand Down Expand Up @@ -343,6 +346,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
}

// 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,
Expand Down Expand Up @@ -805,6 +815,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
generic_simd_intrinsic(bcx, name,
substs,
callee_ty,
expr_arguments,
&llargs,
ret_ty, llret_ty,
call_debug_location,
Expand Down Expand Up @@ -1307,15 +1318,18 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
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) => {
Expand Down Expand Up @@ -1376,7 +1390,6 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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");
Expand All @@ -1394,12 +1407,18 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,

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,
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/intrinsic.rs
Expand Up @@ -21,7 +21,6 @@ use middle::ty_fold::TypeFolder;
use {CrateCtxt, require_same_types};

use std::collections::{HashMap};
use std::iter;
use syntax::abi;
use syntax::attr::AttrMetaMethods;
use syntax::ast;
Expand Down Expand Up @@ -387,8 +386,8 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
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();
Expand Down

0 comments on commit 1f5739f

Please sign in to comment.