]> git.lizzy.rs Git - rust.git/commitdiff
Separate integers into signed and unsigned.
authorHuon Wilson <dbau.pp+github@gmail.com>
Fri, 28 Aug 2015 23:32:25 +0000 (16:32 -0700)
committerHuon Wilson <dbau.pp+github@gmail.com>
Sat, 29 Aug 2015 22:36:16 +0000 (15:36 -0700)
This is necessary to reflect the ARM APIs accurately, since some
functions explicitly take an unsigned parameter and a signed one, of the
same integer shape, so the no-duplicates check will fail unless we
distinguish.

src/librustc_platform_intrinsics/lib.rs
src/librustc_trans/trans/intrinsic.rs
src/librustc_typeck/check/intrinsic.rs
src/test/compile-fail/simd-intrinsic-declaration-type.rs

index 134b4c66419b6c4408d9aa9006b269b68364bb40..476b9ee31feb2bae14116f4c9eceda87874f656a 100755 (executable)
@@ -30,7 +30,7 @@ pub struct Intrinsic {
 
 #[derive(Clone, Hash, Eq, PartialEq)]
 pub enum Type {
-    Integer(u8),
+    Integer(/* signed */ bool, u8),
     Float(u8),
     Pointer(Box<Type>),
     Vector(Box<Type>, u8),
@@ -40,7 +40,8 @@ pub enum IntrinsicDef {
     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) }
 
index ded748e9894a01b383c21cbb565bb5218def2978..d6275f2b9e83ac090cc963952867490ada581ad6 100644 (file)
@@ -927,7 +927,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             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),
index 636f17db38c36302789cf2319fbaf63d353e2933..24b63f5d4f4a61cf06fe802f4baaa0e7e134363e 100644 (file)
@@ -456,13 +456,15 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
     };
 
     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)) |
index effa1ed04d8ecf5e9c062b8bb3c302eea3d239cf..ef1f4d6f230b3639026f563c017c1f47d3b4ec04 100644 (file)
@@ -25,27 +25,38 @@ struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8,
 #[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