@@ -43,6 +43,8 @@ use syntax::ast;
4343use syntax:: ptr:: P ;
4444use syntax:: parse:: token;
4545
46+ use std:: cmp:: Ordering ;
47+
4648pub fn get_simple_intrinsic ( ccx : & CrateContext , item : & ast:: ForeignItem ) -> Option < ValueRef > {
4749 let name = match & * item. ident . name . as_str ( ) {
4850 "sqrtf32" => "llvm.sqrt.f32" ,
@@ -1485,120 +1487,57 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
14851487
14861488 if in_elem == out_elem { return llargs[ 0 ] ; }
14871489
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+ }
15101517 }
15111518 }
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)
15331524 }
15341525 }
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)
15561531 }
15571532 }
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)
15791538 }
15801539 }
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. */ }
16021541 }
16031542 require ! ( false ,
16041543 "unsupported cast from `{}` with element `{}` to `{}` with element `{}`" ,
0 commit comments