12
12
13
13
use arena:: TypedArena ;
14
14
use intrinsics:: { self , Intrinsic } ;
15
+ use libc;
15
16
use llvm;
16
17
use llvm:: { SequentiallyConsistent , Acquire , Release , AtomicXchg , ValueRef , TypeKind } ;
17
18
use middle:: subst;
@@ -24,6 +25,7 @@ use trans::callee;
24
25
use trans:: cleanup;
25
26
use trans:: cleanup:: CleanupMethods ;
26
27
use trans:: common:: * ;
28
+ use trans:: consts;
27
29
use trans:: datum:: * ;
28
30
use trans:: debuginfo:: DebugLoc ;
29
31
use trans:: declare;
@@ -38,6 +40,7 @@ use middle::ty::{self, Ty, HasTypeFlags};
38
40
use middle:: subst:: Substs ;
39
41
use syntax:: abi:: { self , RustIntrinsic } ;
40
42
use syntax:: ast;
43
+ use syntax:: ptr:: P ;
41
44
use syntax:: parse:: token;
42
45
43
46
pub fn get_simple_intrinsic ( ccx : & CrateContext , item : & ast:: ForeignItem ) -> Option < ValueRef > {
@@ -343,6 +346,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
343
346
}
344
347
}
345
348
349
+ // save the actual AST arguments for later (some places need to do
350
+ // const-evaluation on them)
351
+ let expr_arguments = match args {
352
+ callee:: ArgExprs ( args) => Some ( args) ,
353
+ _ => None ,
354
+ } ;
355
+
346
356
// Push the arguments.
347
357
let mut llargs = Vec :: new ( ) ;
348
358
bcx = callee:: trans_args ( bcx,
@@ -805,6 +815,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
805
815
generic_simd_intrinsic ( bcx, name,
806
816
substs,
807
817
callee_ty,
818
+ expr_arguments,
808
819
& llargs,
809
820
ret_ty, llret_ty,
810
821
call_debug_location,
@@ -1307,15 +1318,18 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
1307
1318
return rust_try
1308
1319
}
1309
1320
1310
- fn generic_simd_intrinsic < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
1311
- name : & str ,
1312
- _substs : subst:: Substs < ' tcx > ,
1313
- callee_ty : Ty < ' tcx > ,
1314
- llargs : & [ ValueRef ] ,
1315
- ret_ty : Ty < ' tcx > ,
1316
- llret_ty : Type ,
1317
- call_debug_location : DebugLoc ,
1318
- call_info : NodeIdAndSpan ) -> ValueRef {
1321
+ fn generic_simd_intrinsic < ' blk , ' tcx , ' a >
1322
+ ( bcx : Block < ' blk , ' tcx > ,
1323
+ name : & str ,
1324
+ substs : subst:: Substs < ' tcx > ,
1325
+ callee_ty : Ty < ' tcx > ,
1326
+ args : Option < & [ P < ast:: Expr > ] > ,
1327
+ llargs : & [ ValueRef ] ,
1328
+ ret_ty : Ty < ' tcx > ,
1329
+ llret_ty : Type ,
1330
+ call_debug_location : DebugLoc ,
1331
+ call_info : NodeIdAndSpan ) -> ValueRef
1332
+ {
1319
1333
let tcx = bcx. tcx ( ) ;
1320
1334
let arg_tys = match callee_ty. sty {
1321
1335
ty:: TyBareFn ( _, ref f) => {
@@ -1376,7 +1390,6 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1376
1390
Err ( _) => tcx. sess . span_bug ( call_info. span ,
1377
1391
"bad `simd_shuffle` instruction only caught in trans?" )
1378
1392
} ;
1379
- assert_eq ! ( llargs. len( ) , 2 + n) ;
1380
1393
1381
1394
require ! ( arg_tys[ 0 ] == arg_tys[ 1 ] ,
1382
1395
"SIMD shuffle intrinsic monomorphised with different input types" ) ;
@@ -1394,12 +1407,18 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1394
1407
1395
1408
let total_len = in_len as u64 * 2 ;
1396
1409
1397
- let indices: Option < Vec < _ > > = llargs[ 2 ..]
1398
- . iter ( )
1399
- . enumerate ( )
1400
- . map ( |( i, val) | {
1401
- let arg_idx = i + 2 ;
1402
- let c = const_to_opt_uint ( * val) ;
1410
+ let vector = match args {
1411
+ Some ( args) => & args[ 2 ] ,
1412
+ None => bcx. sess ( ) . span_bug ( call_info. span ,
1413
+ "intrinsic call with unexpected argument shape" ) ,
1414
+ } ;
1415
+ let vector = consts:: const_expr ( bcx. ccx ( ) , vector, tcx. mk_substs ( substs) , None ) . 0 ;
1416
+
1417
+ let indices: Option < Vec < _ > > = ( 0 ..n)
1418
+ . map ( |i| {
1419
+ let arg_idx = i;
1420
+ let val = const_get_elt ( bcx. ccx ( ) , vector, & [ i as libc:: c_uint ] ) ;
1421
+ let c = const_to_opt_uint ( val) ;
1403
1422
match c {
1404
1423
None => {
1405
1424
bcx. sess ( ) . span_err ( call_info. span ,
0 commit comments