Separate integers into signed and unsigned.
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.
This commit is contained in:
parent
f578735750
commit
b03ca7f805
4 changed files with 30 additions and 16 deletions
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)) |
|
||||
|
|
|
@ -25,27 +25,38 @@ struct f32x4(f32, f32, f32, f32);
|
|||
#[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
|
||||
|
|
Loading…
Reference in a new issue