Clean up simd_cast translation.
This commit is contained in:
parent
502f9acbe9
commit
b067e4464b
2 changed files with 67 additions and 104 deletions
|
@ -43,6 +43,8 @@ use syntax::ast;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
|
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
|
||||||
let name = match &*item.ident.name.as_str() {
|
let name = match &*item.ident.name.as_str() {
|
||||||
"sqrtf32" => "llvm.sqrt.f32",
|
"sqrtf32" => "llvm.sqrt.f32",
|
||||||
|
@ -1485,120 +1487,57 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
|
||||||
|
|
||||||
if in_elem == out_elem { return llargs[0]; }
|
if in_elem == out_elem { return llargs[0]; }
|
||||||
|
|
||||||
match (&in_elem.sty, &out_elem.sty) {
|
enum Style { Float, Int(/* is signed? */ bool), Unsupported }
|
||||||
(&ty::TyInt(lhs), &ty::TyInt(rhs)) => {
|
|
||||||
match (lhs, rhs) {
|
|
||||||
(ast::TyI8, ast::TyI8) |
|
|
||||||
(ast::TyI16, ast::TyI16) |
|
|
||||||
(ast::TyI32, ast::TyI32) |
|
|
||||||
(ast::TyI64, ast::TyI64) => return llargs[0],
|
|
||||||
|
|
||||||
(ast::TyI8, ast::TyI16) |
|
let (in_style, in_width) = match in_elem.sty {
|
||||||
(ast::TyI8, ast::TyI32) |
|
// vectors of pointer-sized integers should've been
|
||||||
(ast::TyI8, ast::TyI64) |
|
// disallowed before here, so this unwrap is safe.
|
||||||
(ast::TyI16, ast::TyI32) |
|
ty::TyInt(i) => (Style::Int(true), i.bit_width().unwrap()),
|
||||||
(ast::TyI16, ast::TyI64) |
|
ty::TyUint(u) => (Style::Int(false), u.bit_width().unwrap()),
|
||||||
(ast::TyI32, ast::TyI64) => return SExt(bcx, llargs[0], llret_ty),
|
ty::TyFloat(f) => (Style::Float, f.bit_width()),
|
||||||
|
_ => (Style::Unsupported, 0)
|
||||||
|
};
|
||||||
|
let (out_style, out_width) = match out_elem.sty {
|
||||||
|
ty::TyInt(i) => (Style::Int(true), i.bit_width().unwrap()),
|
||||||
|
ty::TyUint(u) => (Style::Int(false), u.bit_width().unwrap()),
|
||||||
|
ty::TyFloat(f) => (Style::Float, f.bit_width()),
|
||||||
|
_ => (Style::Unsupported, 0)
|
||||||
|
};
|
||||||
|
|
||||||
(ast::TyI16, ast::TyI8) |
|
match (in_style, out_style) {
|
||||||
(ast::TyI32, ast::TyI8) |
|
(Style::Int(in_is_signed), Style::Int(_)) => {
|
||||||
(ast::TyI32, ast::TyI16) |
|
return match in_width.cmp(&out_width) {
|
||||||
(ast::TyI64, ast::TyI8) |
|
Ordering::Greater => Trunc(bcx, llargs[0], llret_ty),
|
||||||
(ast::TyI64, ast::TyI16) |
|
Ordering::Equal => llargs[0],
|
||||||
(ast::TyI64, ast::TyI32) => return Trunc(bcx, llargs[0], llret_ty),
|
Ordering::Less => if in_is_signed {
|
||||||
_ => {}
|
SExt(bcx, llargs[0], llret_ty)
|
||||||
|
} else {
|
||||||
|
ZExt(bcx, llargs[0], llret_ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::TyUint(lhs), &ty::TyUint(rhs)) => {
|
(Style::Int(in_is_signed), Style::Float) => {
|
||||||
match (lhs, rhs) {
|
return if in_is_signed {
|
||||||
(ast::TyU8, ast::TyU8) |
|
SIToFP(bcx, llargs[0], llret_ty)
|
||||||
(ast::TyU16, ast::TyU16) |
|
} else {
|
||||||
(ast::TyU32, ast::TyU32) |
|
UIToFP(bcx, llargs[0], llret_ty)
|
||||||
(ast::TyU64, ast::TyU64) => return llargs[0],
|
|
||||||
|
|
||||||
(ast::TyU8, ast::TyU16) |
|
|
||||||
(ast::TyU8, ast::TyU32) |
|
|
||||||
(ast::TyU8, ast::TyU64) |
|
|
||||||
(ast::TyU16, ast::TyU32) |
|
|
||||||
(ast::TyU16, ast::TyU64) |
|
|
||||||
(ast::TyU32, ast::TyU64) => return ZExt(bcx, llargs[0], llret_ty),
|
|
||||||
|
|
||||||
(ast::TyU16, ast::TyU8) |
|
|
||||||
(ast::TyU32, ast::TyU8) |
|
|
||||||
(ast::TyU32, ast::TyU16) |
|
|
||||||
(ast::TyU64, ast::TyU8) |
|
|
||||||
(ast::TyU64, ast::TyU16) |
|
|
||||||
(ast::TyU64, ast::TyU32) => return Trunc(bcx, llargs[0], llret_ty),
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::TyInt(lhs), &ty::TyUint(rhs)) => {
|
(Style::Float, Style::Int(out_is_signed)) => {
|
||||||
match (lhs, rhs) {
|
return if out_is_signed {
|
||||||
(ast::TyI8, ast::TyU8) |
|
FPToSI(bcx, llargs[0], llret_ty)
|
||||||
(ast::TyI16, ast::TyU16) |
|
} else {
|
||||||
(ast::TyI32, ast::TyU32) |
|
FPToUI(bcx, llargs[0], llret_ty)
|
||||||
(ast::TyI64, ast::TyU64) => return llargs[0],
|
|
||||||
|
|
||||||
(ast::TyI8, ast::TyU16) |
|
|
||||||
(ast::TyI8, ast::TyU32) |
|
|
||||||
(ast::TyI8, ast::TyU64) |
|
|
||||||
(ast::TyI16, ast::TyU32) |
|
|
||||||
(ast::TyI16, ast::TyU64) |
|
|
||||||
(ast::TyI32, ast::TyU64) => return SExt(bcx, llargs[0], llret_ty),
|
|
||||||
|
|
||||||
(ast::TyI16, ast::TyU8) |
|
|
||||||
(ast::TyI32, ast::TyU8) |
|
|
||||||
(ast::TyI32, ast::TyU16) |
|
|
||||||
(ast::TyI64, ast::TyU8) |
|
|
||||||
(ast::TyI64, ast::TyU16) |
|
|
||||||
(ast::TyI64, ast::TyU32) => return Trunc(bcx, llargs[0], llret_ty),
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::TyUint(lhs), &ty::TyInt(rhs)) => {
|
(Style::Float, Style::Float) => {
|
||||||
match (lhs, rhs) {
|
return match in_width.cmp(&out_width) {
|
||||||
(ast::TyU8, ast::TyI8) |
|
Ordering::Greater => FPTrunc(bcx, llargs[0], llret_ty),
|
||||||
(ast::TyU16, ast::TyI16) |
|
Ordering::Equal => llargs[0],
|
||||||
(ast::TyU32, ast::TyI32) |
|
Ordering::Less => FPExt(bcx, llargs[0], llret_ty)
|
||||||
(ast::TyU64, ast::TyI64) => return llargs[0],
|
|
||||||
|
|
||||||
(ast::TyU8, ast::TyI16) |
|
|
||||||
(ast::TyU8, ast::TyI32) |
|
|
||||||
(ast::TyU8, ast::TyI64) |
|
|
||||||
(ast::TyU16, ast::TyI32) |
|
|
||||||
(ast::TyU16, ast::TyI64) |
|
|
||||||
(ast::TyU32, ast::TyI64) => return ZExt(bcx, llargs[0], llret_ty),
|
|
||||||
|
|
||||||
(ast::TyU16, ast::TyI8) |
|
|
||||||
(ast::TyU32, ast::TyI8) |
|
|
||||||
(ast::TyU32, ast::TyI16) |
|
|
||||||
(ast::TyU64, ast::TyI8) |
|
|
||||||
(ast::TyU64, ast::TyI16) |
|
|
||||||
(ast::TyU64, ast::TyI32) => return Trunc(bcx, llargs[0], llret_ty),
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {/* Unsupported. Fallthrough. */}
|
||||||
(&ty::TyInt(_), &ty::TyFloat(_)) => {
|
|
||||||
return SIToFP(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
(&ty::TyUint(_), &ty::TyFloat(_)) => {
|
|
||||||
return UIToFP(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
(&ty::TyFloat(_), &ty::TyInt(_)) => {
|
|
||||||
return FPToSI(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
(&ty::TyFloat(_), &ty::TyUint(_)) => {
|
|
||||||
return FPToUI(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
(&ty::TyFloat(ast::TyF32), &ty::TyFloat(ast::TyF64)) => {
|
|
||||||
return FPExt(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
(&ty::TyFloat(ast::TyF64), &ty::TyFloat(ast::TyF32)) => {
|
|
||||||
return FPTrunc(bcx, llargs[0], llret_ty)
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
require!(false,
|
require!(false,
|
||||||
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
|
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
|
||||||
|
|
|
@ -1339,6 +1339,15 @@ impl IntTy {
|
||||||
TyI16 | TyI32 | TyI64 => 3,
|
TyI16 | TyI32 | TyI64 => 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn bit_width(&self) -> Option<usize> {
|
||||||
|
Some(match *self {
|
||||||
|
TyIs => return None,
|
||||||
|
TyI8 => 8,
|
||||||
|
TyI16 => 16,
|
||||||
|
TyI32 => 32,
|
||||||
|
TyI64 => 64,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
||||||
|
@ -1357,6 +1366,15 @@ impl UintTy {
|
||||||
TyU16 | TyU32 | TyU64 => 3,
|
TyU16 | TyU32 | TyU64 => 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn bit_width(&self) -> Option<usize> {
|
||||||
|
Some(match *self {
|
||||||
|
TyUs => return None,
|
||||||
|
TyU8 => 8,
|
||||||
|
TyU16 => 16,
|
||||||
|
TyU32 => 32,
|
||||||
|
TyU64 => 64,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for UintTy {
|
impl fmt::Debug for UintTy {
|
||||||
|
@ -1395,6 +1413,12 @@ impl FloatTy {
|
||||||
TyF32 | TyF64 => 3, // add F128 handling here
|
TyF32 | TyF64 => 3, // add F128 handling here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn bit_width(&self) -> usize {
|
||||||
|
match *self {
|
||||||
|
TyF32 => 32,
|
||||||
|
TyF64 => 64,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind a type to an associated type: `A=Foo`.
|
// Bind a type to an associated type: `A=Foo`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue