Skip to content

Commit b067e44

Browse files
committed
Clean up simd_cast translation.
1 parent 502f9ac commit b067e44

File tree

2 files changed

+69
-106
lines changed

2 files changed

+69
-106
lines changed

src/librustc_trans/trans/intrinsic.rs

+45-106
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ use syntax::ast;
4343
use syntax::ptr::P;
4444
use syntax::parse::token;
4545

46+
use std::cmp::Ordering;
47+
4648
pub 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 `{}`",

src/libsyntax/ast.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,15 @@ impl IntTy {
13391339
TyI16 | TyI32 | TyI64 => 3,
13401340
}
13411341
}
1342+
pub fn bit_width(&self) -> Option<usize> {
1343+
Some(match *self {
1344+
TyIs => return None,
1345+
TyI8 => 8,
1346+
TyI16 => 16,
1347+
TyI32 => 32,
1348+
TyI64 => 64,
1349+
})
1350+
}
13421351
}
13431352

13441353
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@@ -1357,6 +1366,15 @@ impl UintTy {
13571366
TyU16 | TyU32 | TyU64 => 3,
13581367
}
13591368
}
1369+
pub fn bit_width(&self) -> Option<usize> {
1370+
Some(match *self {
1371+
TyUs => return None,
1372+
TyU8 => 8,
1373+
TyU16 => 16,
1374+
TyU32 => 32,
1375+
TyU64 => 64,
1376+
})
1377+
}
13601378
}
13611379

13621380
impl fmt::Debug for UintTy {
@@ -1395,6 +1413,12 @@ impl FloatTy {
13951413
TyF32 | TyF64 => 3, // add F128 handling here
13961414
}
13971415
}
1416+
pub fn bit_width(&self) -> usize {
1417+
match *self {
1418+
TyF32 => 32,
1419+
TyF64 => 64,
1420+
}
1421+
}
13981422
}
13991423

14001424
// Bind a type to an associated type: `A=Foo`.

0 commit comments

Comments
 (0)