#[derive(Clone, Hash, Eq, PartialEq)]
pub enum Type {
- Integer(u8),
+ Integer(/* signed */ bool, u8),
Float(u8),
Pointer(Box<Type>),
Vector(Box<Type>, u8),
Named(&'static str),
}
-fn i(width: u8) -> Type { Type::Integer(width) }
+fn i(width: u8) -> Type { Type::Integer(true, width) }
+fn u(width: u8) -> Type { Type::Integer(false, width) }
fn f(width: u8) -> Type { Type::Float(width) }
fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), length) }
fn ty_to_type(ccx: &CrateContext, t: &intrinsics::Type) -> Type {
use intrinsics::Type::*;
match *t {
- Integer(x) => Type::ix(ccx, x as u64),
+ Integer(_signed, x) => Type::ix(ccx, x as u64),
Float(x) => {
match x {
32 => Type::f32(ccx),
};
match *expected {
- Integer(bits) => match (bits, &t.sty) {
- (8, &ty::TyInt(ast::TyI8)) | (8, &ty::TyUint(ast::TyU8)) |
- (16, &ty::TyInt(ast::TyI16)) | (16, &ty::TyUint(ast::TyU16)) |
- (32, &ty::TyInt(ast::TyI32)) | (32, &ty::TyUint(ast::TyU32)) |
- (64, &ty::TyInt(ast::TyI64)) | (64, &ty::TyUint(ast::TyU64)) => {},
+ Integer(signed, bits) => match (signed, bits, &t.sty) {
+ (true, 8, &ty::TyInt(ast::TyI8)) | (false, 8, &ty::TyUint(ast::TyU8)) |
+ (true, 16, &ty::TyInt(ast::TyI16)) | (false, 16, &ty::TyUint(ast::TyU16)) |
+ (true, 32, &ty::TyInt(ast::TyI32)) | (false, 32, &ty::TyUint(ast::TyU32)) |
+ (true, 64, &ty::TyInt(ast::TyI64)) | (false, 64, &ty::TyUint(ast::TyU64)) => {},
_ => simple_error(&format!("`{}`", t),
- &format!("`i{n}` or `u{n}`", n = bits)),
+ &format!("`{}{n}`",
+ if signed {"i"} else {"u"},
+ n = bits)),
},
Float(bits) => match (bits, &t.sty) {
(32, &ty::TyFloat(ast::TyF32)) |
#[repr(simd)]
struct i64x2(i64, i64);
-// signed vs. unsigned doesn't matter
-mod i {
- use i16x8;
+// correct signatures work well
+mod right {
+ use {i16x8, u16x8};
extern "platform-intrinsic" {
fn x86_mm_adds_epi16(x: i16x8, y: i16x8) -> i16x8;
+ fn x86_mm_adds_epu16(x: u16x8, y: u16x8) -> u16x8;
}
}
-mod u {
- use u16x8;
+// but incorrect ones don't.
+
+mod signedness {
+ use {i16x8, u16x8};
+ // signedness matters
extern "platform-intrinsic" {
fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
+ //~^ ERROR intrinsic argument 1 has wrong type
+ //~^^ ERROR intrinsic argument 2 has wrong type
+ //~^^^ ERROR intrinsic return value has wrong type
+ fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
+ //~^ ERROR intrinsic argument 1 has wrong type
+ //~^^ ERROR intrinsic argument 2 has wrong type
+ //~^^^ ERROR intrinsic return value has wrong type
}
}
-// but lengths do
+// as do lengths
extern "platform-intrinsic" {
fn x86_mm_adds_epi16(x: i8x16, y: i32x4) -> i64x2;
//~^ ERROR intrinsic argument 1 has wrong type
//~^^ ERROR intrinsic argument 2 has wrong type
//~^^^ ERROR intrinsic return value has wrong type
}
-// and so does int vs. float
+// and so does int vs. float:
extern "platform-intrinsic" {
fn x86_mm_max_ps(x: i32x4, y: i32x4) -> i32x4;
//~^ ERROR intrinsic argument 1 has wrong type