@@ -43,6 +43,8 @@ use syntax::ast;
43
43
use syntax:: ptr:: P ;
44
44
use syntax:: parse:: token;
45
45
46
+ use std:: cmp:: Ordering ;
47
+
46
48
pub fn get_simple_intrinsic ( ccx : & CrateContext , item : & ast:: ForeignItem ) -> Option < ValueRef > {
47
49
let name = match & * item. ident . name . as_str ( ) {
48
50
"sqrtf32" => "llvm.sqrt.f32" ,
@@ -1485,120 +1487,57 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
1485
1487
1486
1488
if in_elem == out_elem { return llargs[ 0 ] ; }
1487
1489
1488
- match ( & in_elem. sty , & out_elem. sty ) {
1489
- ( & ty:: TyInt ( lhs) , & ty:: TyInt ( rhs) ) => {
1490
- match ( lhs, rhs) {
1491
- ( ast:: TyI8 , ast:: TyI8 ) |
1492
- ( ast:: TyI16 , ast:: TyI16 ) |
1493
- ( ast:: TyI32 , ast:: TyI32 ) |
1494
- ( ast:: TyI64 , ast:: TyI64 ) => return llargs[ 0 ] ,
1495
-
1496
- ( ast:: TyI8 , ast:: TyI16 ) |
1497
- ( ast:: TyI8 , ast:: TyI32 ) |
1498
- ( ast:: TyI8 , ast:: TyI64 ) |
1499
- ( ast:: TyI16 , ast:: TyI32 ) |
1500
- ( ast:: TyI16 , ast:: TyI64 ) |
1501
- ( ast:: TyI32 , ast:: TyI64 ) => return SExt ( bcx, llargs[ 0 ] , llret_ty) ,
1502
-
1503
- ( ast:: TyI16 , ast:: TyI8 ) |
1504
- ( ast:: TyI32 , ast:: TyI8 ) |
1505
- ( ast:: TyI32 , ast:: TyI16 ) |
1506
- ( ast:: TyI64 , ast:: TyI8 ) |
1507
- ( ast:: TyI64 , ast:: TyI16 ) |
1508
- ( ast:: TyI64 , ast:: TyI32 ) => return Trunc ( bcx, llargs[ 0 ] , llret_ty) ,
1509
- _ => { }
1490
+ enum Style { Float , Int ( /* is signed? */ bool ) , Unsupported }
1491
+
1492
+ let ( in_style, in_width) = match in_elem. sty {
1493
+ // vectors of pointer-sized integers should've been
1494
+ // disallowed before here, so this unwrap is safe.
1495
+ ty:: TyInt ( i) => ( Style :: Int ( true ) , i. bit_width ( ) . unwrap ( ) ) ,
1496
+ ty:: TyUint ( u) => ( Style :: Int ( false ) , u. bit_width ( ) . unwrap ( ) ) ,
1497
+ ty:: TyFloat ( f) => ( Style :: Float , f. bit_width ( ) ) ,
1498
+ _ => ( Style :: Unsupported , 0 )
1499
+ } ;
1500
+ let ( out_style, out_width) = match out_elem. sty {
1501
+ ty:: TyInt ( i) => ( Style :: Int ( true ) , i. bit_width ( ) . unwrap ( ) ) ,
1502
+ ty:: TyUint ( u) => ( Style :: Int ( false ) , u. bit_width ( ) . unwrap ( ) ) ,
1503
+ ty:: TyFloat ( f) => ( Style :: Float , f. bit_width ( ) ) ,
1504
+ _ => ( Style :: Unsupported , 0 )
1505
+ } ;
1506
+
1507
+ match ( in_style, out_style) {
1508
+ ( Style :: Int ( in_is_signed) , Style :: Int ( _) ) => {
1509
+ return match in_width. cmp ( & out_width) {
1510
+ Ordering :: Greater => Trunc ( bcx, llargs[ 0 ] , llret_ty) ,
1511
+ Ordering :: Equal => llargs[ 0 ] ,
1512
+ Ordering :: Less => if in_is_signed {
1513
+ SExt ( bcx, llargs[ 0 ] , llret_ty)
1514
+ } else {
1515
+ ZExt ( bcx, llargs[ 0 ] , llret_ty)
1516
+ }
1510
1517
}
1511
1518
}
1512
- ( & ty:: TyUint ( lhs) , & ty:: TyUint ( rhs) ) => {
1513
- match ( lhs, rhs) {
1514
- ( ast:: TyU8 , ast:: TyU8 ) |
1515
- ( ast:: TyU16 , ast:: TyU16 ) |
1516
- ( ast:: TyU32 , ast:: TyU32 ) |
1517
- ( ast:: TyU64 , ast:: TyU64 ) => return llargs[ 0 ] ,
1518
-
1519
- ( ast:: TyU8 , ast:: TyU16 ) |
1520
- ( ast:: TyU8 , ast:: TyU32 ) |
1521
- ( ast:: TyU8 , ast:: TyU64 ) |
1522
- ( ast:: TyU16 , ast:: TyU32 ) |
1523
- ( ast:: TyU16 , ast:: TyU64 ) |
1524
- ( ast:: TyU32 , ast:: TyU64 ) => return ZExt ( bcx, llargs[ 0 ] , llret_ty) ,
1525
-
1526
- ( ast:: TyU16 , ast:: TyU8 ) |
1527
- ( ast:: TyU32 , ast:: TyU8 ) |
1528
- ( ast:: TyU32 , ast:: TyU16 ) |
1529
- ( ast:: TyU64 , ast:: TyU8 ) |
1530
- ( ast:: TyU64 , ast:: TyU16 ) |
1531
- ( ast:: TyU64 , ast:: TyU32 ) => return Trunc ( bcx, llargs[ 0 ] , llret_ty) ,
1532
- _ => { }
1519
+ ( Style :: Int ( in_is_signed) , Style :: Float ) => {
1520
+ return if in_is_signed {
1521
+ SIToFP ( bcx, llargs[ 0 ] , llret_ty)
1522
+ } else {
1523
+ UIToFP ( bcx, llargs[ 0 ] , llret_ty)
1533
1524
}
1534
1525
}
1535
- ( & ty:: TyInt ( lhs) , & ty:: TyUint ( rhs) ) => {
1536
- match ( lhs, rhs) {
1537
- ( ast:: TyI8 , ast:: TyU8 ) |
1538
- ( ast:: TyI16 , ast:: TyU16 ) |
1539
- ( ast:: TyI32 , ast:: TyU32 ) |
1540
- ( ast:: TyI64 , ast:: TyU64 ) => return llargs[ 0 ] ,
1541
-
1542
- ( ast:: TyI8 , ast:: TyU16 ) |
1543
- ( ast:: TyI8 , ast:: TyU32 ) |
1544
- ( ast:: TyI8 , ast:: TyU64 ) |
1545
- ( ast:: TyI16 , ast:: TyU32 ) |
1546
- ( ast:: TyI16 , ast:: TyU64 ) |
1547
- ( ast:: TyI32 , ast:: TyU64 ) => return SExt ( bcx, llargs[ 0 ] , llret_ty) ,
1548
-
1549
- ( ast:: TyI16 , ast:: TyU8 ) |
1550
- ( ast:: TyI32 , ast:: TyU8 ) |
1551
- ( ast:: TyI32 , ast:: TyU16 ) |
1552
- ( ast:: TyI64 , ast:: TyU8 ) |
1553
- ( ast:: TyI64 , ast:: TyU16 ) |
1554
- ( ast:: TyI64 , ast:: TyU32 ) => return Trunc ( bcx, llargs[ 0 ] , llret_ty) ,
1555
- _ => { }
1526
+ ( Style :: Float , Style :: Int ( out_is_signed) ) => {
1527
+ return if out_is_signed {
1528
+ FPToSI ( bcx, llargs[ 0 ] , llret_ty)
1529
+ } else {
1530
+ FPToUI ( bcx, llargs[ 0 ] , llret_ty)
1556
1531
}
1557
1532
}
1558
- ( & ty:: TyUint ( lhs) , & ty:: TyInt ( rhs) ) => {
1559
- match ( lhs, rhs) {
1560
- ( ast:: TyU8 , ast:: TyI8 ) |
1561
- ( ast:: TyU16 , ast:: TyI16 ) |
1562
- ( ast:: TyU32 , ast:: TyI32 ) |
1563
- ( ast:: TyU64 , ast:: TyI64 ) => return llargs[ 0 ] ,
1564
-
1565
- ( ast:: TyU8 , ast:: TyI16 ) |
1566
- ( ast:: TyU8 , ast:: TyI32 ) |
1567
- ( ast:: TyU8 , ast:: TyI64 ) |
1568
- ( ast:: TyU16 , ast:: TyI32 ) |
1569
- ( ast:: TyU16 , ast:: TyI64 ) |
1570
- ( ast:: TyU32 , ast:: TyI64 ) => return ZExt ( bcx, llargs[ 0 ] , llret_ty) ,
1571
-
1572
- ( ast:: TyU16 , ast:: TyI8 ) |
1573
- ( ast:: TyU32 , ast:: TyI8 ) |
1574
- ( ast:: TyU32 , ast:: TyI16 ) |
1575
- ( ast:: TyU64 , ast:: TyI8 ) |
1576
- ( ast:: TyU64 , ast:: TyI16 ) |
1577
- ( ast:: TyU64 , ast:: TyI32 ) => return Trunc ( bcx, llargs[ 0 ] , llret_ty) ,
1578
- _ => { }
1533
+ ( Style :: Float , Style :: Float ) => {
1534
+ return match in_width. cmp ( & out_width) {
1535
+ Ordering :: Greater => FPTrunc ( bcx, llargs[ 0 ] , llret_ty) ,
1536
+ Ordering :: Equal => llargs[ 0 ] ,
1537
+ Ordering :: Less => FPExt ( bcx, llargs[ 0 ] , llret_ty)
1579
1538
}
1580
1539
}
1581
-
1582
- ( & ty:: TyInt ( _) , & ty:: TyFloat ( _) ) => {
1583
- return SIToFP ( bcx, llargs[ 0 ] , llret_ty)
1584
- }
1585
- ( & ty:: TyUint ( _) , & ty:: TyFloat ( _) ) => {
1586
- return UIToFP ( bcx, llargs[ 0 ] , llret_ty)
1587
- }
1588
-
1589
- ( & ty:: TyFloat ( _) , & ty:: TyInt ( _) ) => {
1590
- return FPToSI ( bcx, llargs[ 0 ] , llret_ty)
1591
- }
1592
- ( & ty:: TyFloat ( _) , & ty:: TyUint ( _) ) => {
1593
- return FPToUI ( bcx, llargs[ 0 ] , llret_ty)
1594
- }
1595
- ( & ty:: TyFloat ( ast:: TyF32 ) , & ty:: TyFloat ( ast:: TyF64 ) ) => {
1596
- return FPExt ( bcx, llargs[ 0 ] , llret_ty)
1597
- }
1598
- ( & ty:: TyFloat ( ast:: TyF64 ) , & ty:: TyFloat ( ast:: TyF32 ) ) => {
1599
- return FPTrunc ( bcx, llargs[ 0 ] , llret_ty)
1600
- }
1601
- _ => { }
1540
+ _ => { /* Unsupported. Fallthrough. */ }
1602
1541
}
1603
1542
require ! ( false ,
1604
1543
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`" ,
0 commit comments