Auto merge of #33460 - shepmaster:16-bit-pointers, r=Aatch

Support 16-bit pointers as well as i/usize

I'm opening this pull request to get some feedback from the community.

Although Rust doesn't support any platforms with a native 16-bit pointer at the moment, the [AVR-Rust][ar] fork is working towards that goal. Keeping this forked logic up-to-date with the changes in master has been onerous so I'd like to merge these changes so that they get carried along when refactoring happens. I do not believe this should increase the maintenance burden.

This is based on the original work of Dylan McKay (@dylanmckay).

[ar]: https://github.com/avr-rust/rust
This commit is contained in:
bors 2016-06-03 22:32:15 -07:00
commit 7738479d72
18 changed files with 123 additions and 3 deletions

View File

@ -578,9 +578,9 @@ impl<T> Drop for RawVec<T> {
// * We don't overflow `usize::MAX` and actually allocate too little
//
// On 64-bit we just need to check for overflow since trying to allocate
// `> isize::MAX` bytes will surely fail. On 32-bit we need to add an extra
// guard for this in case we're running on a platform which can use all 4GB in
// user-space. e.g. PAE or x32
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
// an extra guard for this in case we're running on a platform which can use
// all 4GB in user-space. e.g. PAE or x32
#[inline]
fn alloc_guard(alloc_size: usize) {

View File

@ -29,6 +29,7 @@ trait Int: Zero + PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> +
Sub<Output=Self> + Copy {
fn from_u8(u: u8) -> Self;
fn to_u8(&self) -> u8;
fn to_u16(&self) -> u16;
fn to_u32(&self) -> u32;
fn to_u64(&self) -> u64;
}
@ -37,6 +38,7 @@ macro_rules! doit {
($($t:ident)*) => ($(impl Int for $t {
fn from_u8(u: u8) -> $t { u as $t }
fn to_u8(&self) -> u8 { *self as u8 }
fn to_u16(&self) -> u16 { *self as u16 }
fn to_u32(&self) -> u32 { *self as u32 }
fn to_u64(&self) -> u64 { *self as u64 }
})*)
@ -256,6 +258,8 @@ macro_rules! impl_Display {
impl_Display!(i8, u8, i16, u16, i32, u32: to_u32);
impl_Display!(i64, u64: to_u64);
#[cfg(target_pointer_width = "16")]
impl_Display!(isize, usize: to_u16);
#[cfg(target_pointer_width = "32")]
impl_Display!(isize, usize: to_u32);
#[cfg(target_pointer_width = "64")]

View File

@ -518,6 +518,10 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }
macro_rules! repeat_u8_as_u16 {
($name:expr) => { (($name as u16) << 8 |
($name as u16)) }
}
macro_rules! repeat_u8_as_u32 {
($name:expr) => { (($name as u32) << 24 |
($name as u32) << 16 |
@ -543,11 +547,18 @@ macro_rules! repeat_u8_as_u64 {
pub const POST_DROP_U8: u8 = 0x1d;
#[unstable(feature = "filling_drop", issue = "5016")]
#[allow(missing_docs)]
pub const POST_DROP_U16: u16 = repeat_u8_as_u16!(POST_DROP_U8);
#[unstable(feature = "filling_drop", issue = "5016")]
#[allow(missing_docs)]
pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
#[unstable(feature = "filling_drop", issue = "5016")]
#[allow(missing_docs)]
pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);
#[cfg(target_pointer_width = "16")]
#[unstable(feature = "filling_drop", issue = "5016")]
#[allow(missing_docs)]
pub const POST_DROP_USIZE: usize = POST_DROP_U16 as usize;
#[cfg(target_pointer_width = "32")]
#[unstable(feature = "filling_drop", issue = "5016")]
#[allow(missing_docs)]

View File

@ -14,6 +14,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_pointer_width = "16")]
int_module! { isize, 16 }
#[cfg(target_pointer_width = "32")]
int_module! { isize, 32 }
#[cfg(target_pointer_width = "64")]

View File

@ -1176,6 +1176,15 @@ impl i64 {
intrinsics::mul_with_overflow }
}
#[cfg(target_pointer_width = "16")]
#[lang = "isize"]
impl isize {
int_impl! { i16, u16, 16,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}
#[cfg(target_pointer_width = "32")]
#[lang = "isize"]
impl isize {
@ -2188,6 +2197,18 @@ impl u64 {
intrinsics::mul_with_overflow }
}
#[cfg(target_pointer_width = "16")]
#[lang = "usize"]
impl usize {
uint_impl! { u16, 16,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
intrinsics::bswap,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}
#[cfg(target_pointer_width = "32")]
#[lang = "usize"]
impl usize {

View File

@ -14,6 +14,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_pointer_width = "16")]
uint_module! { usize, 16 }
#[cfg(target_pointer_width = "32")]
uint_module! { usize, 32 }
#[cfg(target_pointer_width = "64")]

View File

@ -292,6 +292,12 @@ wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
mod shift_max {
#![allow(non_upper_case_globals)]
#[cfg(target_pointer_width = "16")]
mod platform {
pub const usize: u32 = super::u16;
pub const isize: u32 = super::i16;
}
#[cfg(target_pointer_width = "32")]
mod platform {
pub const usize: u32 = super::u32;

View File

@ -18,6 +18,13 @@ fn size_of_basic() {
assert_eq!(size_of::<u64>(), 8);
}
#[test]
#[cfg(target_pointer_width = "16")]
fn size_of_16() {
assert_eq!(size_of::<usize>(), 2);
assert_eq!(size_of::<*const usize>(), 2);
}
#[test]
#[cfg(target_pointer_width = "32")]
fn size_of_32() {
@ -47,6 +54,13 @@ fn align_of_basic() {
assert_eq!(align_of::<u32>(), 4);
}
#[test]
#[cfg(target_pointer_width = "16")]
fn align_of_16() {
assert_eq!(align_of::<usize>(), 2);
assert_eq!(align_of::<*const usize>(), 2);
}
#[test]
#[cfg(target_pointer_width = "32")]
fn align_of_32() {

View File

@ -796,6 +796,7 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
};
let (int_type, uint_type) = match &target.target_pointer_width[..] {
"16" => (ast::IntTy::I16, ast::UintTy::U16),
"32" => (ast::IntTy::I32, ast::UintTy::U32),
"64" => (ast::IntTy::I64, ast::UintTy::U64),
w => panic!(sp.fatal(&format!("target specification was invalid: \

View File

@ -170,6 +170,7 @@ impl TargetDataLayout {
/// address space on 64-bit ARMv8 and x86_64.
pub fn obj_size_bound(&self) -> u64 {
match self.pointer_size.bits() {
16 => 1 << 15,
32 => 1 << 31,
64 => 1 << 47,
bits => bug!("obj_size_bound: unknown pointer bit size {}", bits)
@ -178,6 +179,7 @@ impl TargetDataLayout {
pub fn ptr_sized_integer(&self) -> Integer {
match self.pointer_size.bits() {
16 => I16,
32 => I32,
64 => I64,
bits => bug!("ptr_sized_integer: unknown pointer bit size {}", bits)

View File

@ -62,6 +62,7 @@ impl IntTypeExt for attr::IntType {
SignedInt(ast::IntTy::I32) => ConstInt::I32(0),
SignedInt(ast::IntTy::I64) => ConstInt::I64(0),
SignedInt(ast::IntTy::Is) => match tcx.sess.target.int_type {
ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16(0)),
ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32(0)),
ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64(0)),
_ => bug!(),
@ -71,6 +72,7 @@ impl IntTypeExt for attr::IntType {
UnsignedInt(ast::UintTy::U32) => ConstInt::U32(0),
UnsignedInt(ast::UintTy::U64) => ConstInt::U64(0),
UnsignedInt(ast::UintTy::Us) => match tcx.sess.target.uint_type {
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(0)),
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(0)),
ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(0)),
_ => bug!(),

View File

@ -583,6 +583,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) |
(&LitKind::Int(n, Signed(IntTy::Is)), _) => {
match tcx.sess.target.int_type {
IntTy::I16 => if n == I16_OVERFLOW {
return Ok(Integral(Isize(Is16(::std::i16::MIN))));
},
IntTy::I32 => if n == I32_OVERFLOW {
return Ok(Integral(Isize(Is32(::std::i32::MIN))));
},

View File

@ -77,12 +77,14 @@ impl ConstInt {
(Infer(a @ 0...as_u64::I16MAX), I16(_)) => I16(a as i64 as i16),
(Infer(a @ 0...as_u64::I32MAX), I32(_)) => I32(a as i64 as i32),
(Infer(a @ 0...as_u64::I64MAX), I64(_)) => I64(a as i64),
(Infer(a @ 0...as_u64::I16MAX), Isize(Is16(_))) => Isize(Is16(a as i64 as i16)),
(Infer(a @ 0...as_u64::I32MAX), Isize(Is32(_))) => Isize(Is32(a as i64 as i32)),
(Infer(a @ 0...as_u64::I64MAX), Isize(Is64(_))) => Isize(Is64(a as i64)),
(Infer(a @ 0...as_u64::U8MAX), U8(_)) => U8(a as u8),
(Infer(a @ 0...as_u64::U16MAX), U16(_)) => U16(a as u16),
(Infer(a @ 0...as_u64::U32MAX), U32(_)) => U32(a as u32),
(Infer(a), U64(_)) => U64(a),
(Infer(a @ 0...as_u64::U16MAX), Usize(Us16(_))) => Usize(Us16(a as u16)),
(Infer(a @ 0...as_u64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
(Infer(a), Usize(Us64(_))) => Usize(Us64(a)),
@ -92,6 +94,9 @@ impl ConstInt {
(InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), I16(_)) => I16(a as i16),
(InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), I32(_)) => I32(a as i32),
(InferSigned(a), I64(_)) => I64(a),
(InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), Isize(Is16(_))) => {
Isize(Is16(a as i16))
},
(InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), Isize(Is32(_))) => {
Isize(Is32(a as i32))
},
@ -100,6 +105,7 @@ impl ConstInt {
(InferSigned(a @ 0...as_i64::U16MAX), U16(_)) => U16(a as u16),
(InferSigned(a @ 0...as_i64::U32MAX), U32(_)) => U32(a as u32),
(InferSigned(a @ 0...as_i64::I64MAX), U64(_)) => U64(a as u64),
(InferSigned(a @ 0...as_i64::U16MAX), Usize(Us16(_))) => Usize(Us16(a as u16)),
(InferSigned(a @ 0...as_i64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
(InferSigned(a @ 0...as_i64::I64MAX), Usize(Us64(_))) => Usize(Us64(a as u64)),
(InferSigned(_), _) => return Err(ConstMathErr::NotInRange),
@ -117,6 +123,7 @@ impl ConstInt {
I16(i) if i < 0 => InferSigned(i as i64),
I32(i) if i < 0 => InferSigned(i as i64),
I64(i) if i < 0 => InferSigned(i as i64),
Isize(Is16(i)) if i < 0 => InferSigned(i as i64),
Isize(Is32(i)) if i < 0 => InferSigned(i as i64),
Isize(Is64(i)) if i < 0 => InferSigned(i as i64),
InferSigned(i) => Infer(i as u64),
@ -124,12 +131,14 @@ impl ConstInt {
I16(i) => Infer(i as u64),
I32(i) => Infer(i as u64),
I64(i) => Infer(i as u64),
Isize(Is16(i)) => Infer(i as u64),
Isize(Is32(i)) => Infer(i as u64),
Isize(Is64(i)) => Infer(i as u64),
U8(i) => Infer(i as u64),
U16(i) => Infer(i as u64),
U32(i) => Infer(i as u64),
U64(i) => Infer(i as u64),
Usize(Us16(i)) => Infer(i as u64),
Usize(Us32(i)) => Infer(i as u64),
Usize(Us64(i)) => Infer(i),
}
@ -173,6 +182,7 @@ impl ConstInt {
| Isize(Is64(v))
| I64(v) if v >= 0 && v <= ::std::u32::MAX as i64 => Some(v as u32),
Isize(Is32(v)) if v >= 0 => Some(v as u32),
Isize(Is16(v)) if v >= 0 => Some(v as u32),
U8(v) => Some(v as u32),
U16(v) => Some(v as u32),
U32(v) => Some(v),
@ -180,6 +190,7 @@ impl ConstInt {
| Usize(Us64(v))
| U64(v) if v <= ::std::u32::MAX as u64 => Some(v as u32),
Usize(Us32(v)) => Some(v),
Usize(Us16(v)) => Some(v as u32),
_ => None,
}
}
@ -193,12 +204,14 @@ impl ConstInt {
I16(v) if v >= 0 => Some(v as u64),
I32(v) if v >= 0 => Some(v as u64),
I64(v) if v >= 0 => Some(v as u64),
Isize(Is16(v)) if v >= 0 => Some(v as u64),
Isize(Is32(v)) if v >= 0 => Some(v as u64),
Isize(Is64(v)) if v >= 0 => Some(v as u64),
U8(v) => Some(v as u64),
U16(v) => Some(v as u64),
U32(v) => Some(v as u64),
U64(v) => Some(v),
Usize(Us16(v)) => Some(v as u64),
Usize(Us32(v)) => Some(v as u64),
Usize(Us64(v)) => Some(v),
_ => None,
@ -211,6 +224,7 @@ impl ConstInt {
I16(v) => v < 0,
I32(v) => v < 0,
I64(v) => v < 0,
Isize(Is16(v)) => v < 0,
Isize(Is32(v)) => v < 0,
Isize(Is64(v)) => v < 0,
InferSigned(v) => v < 0,
@ -225,12 +239,14 @@ impl ConstInt {
(I16(a), I16(b)) => Ok(a.cmp(&b)),
(I32(a), I32(b)) => Ok(a.cmp(&b)),
(I64(a), I64(b)) => Ok(a.cmp(&b)),
(Isize(Is16(a)), Isize(Is16(b))) => Ok(a.cmp(&b)),
(Isize(Is32(a)), Isize(Is32(b))) => Ok(a.cmp(&b)),
(Isize(Is64(a)), Isize(Is64(b))) => Ok(a.cmp(&b)),
(U8(a), U8(b)) => Ok(a.cmp(&b)),
(U16(a), U16(b)) => Ok(a.cmp(&b)),
(U32(a), U32(b)) => Ok(a.cmp(&b)),
(U64(a), U64(b)) => Ok(a.cmp(&b)),
(Usize(Us16(a)), Usize(Us16(b))) => Ok(a.cmp(&b)),
(Usize(Us32(a)), Usize(Us32(b))) => Ok(a.cmp(&b)),
(Usize(Us64(a)), Usize(Us64(b))) => Ok(a.cmp(&b)),
(Infer(a), Infer(b)) => Ok(a.cmp(&b)),
@ -249,12 +265,14 @@ impl ConstInt {
ConstInt::I16(i) => ConstInt::I16(add1!(i)),
ConstInt::I32(i) => ConstInt::I32(add1!(i)),
ConstInt::I64(i) => ConstInt::I64(add1!(i)),
ConstInt::Isize(ConstIsize::Is16(i)) => ConstInt::Isize(ConstIsize::Is16(add1!(i))),
ConstInt::Isize(ConstIsize::Is32(i)) => ConstInt::Isize(ConstIsize::Is32(add1!(i))),
ConstInt::Isize(ConstIsize::Is64(i)) => ConstInt::Isize(ConstIsize::Is64(add1!(i))),
ConstInt::U8(i) => ConstInt::U8(add1!(i)),
ConstInt::U16(i) => ConstInt::U16(add1!(i)),
ConstInt::U32(i) => ConstInt::U32(add1!(i)),
ConstInt::U64(i) => ConstInt::U64(add1!(i)),
ConstInt::Usize(ConstUsize::Us16(i)) => ConstInt::Usize(ConstUsize::Us16(add1!(i))),
ConstInt::Usize(ConstUsize::Us32(i)) => ConstInt::Usize(ConstUsize::Us32(add1!(i))),
ConstInt::Usize(ConstUsize::Us64(i)) => ConstInt::Usize(ConstUsize::Us64(add1!(i))),
ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
@ -301,12 +319,14 @@ impl ::std::fmt::Display for ConstInt {
I64(i) => write!(fmt, "{}i64", i),
Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i),
Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i),
Isize(ConstIsize::Is16(i)) => write!(fmt, "{}isize", i),
U8(i) => write!(fmt, "{}u8", i),
U16(i) => write!(fmt, "{}u16", i),
U32(i) => write!(fmt, "{}u32", i),
U64(i) => write!(fmt, "{}u64", i),
Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i),
Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i),
Usize(ConstUsize::Us16(i)) => write!(fmt, "{}usize", i),
}
}
}
@ -331,12 +351,14 @@ macro_rules! impl_binop {
(I16(a), I16(b)) => a.$checked_func(b).map(I16),
(I32(a), I32(b)) => a.$checked_func(b).map(I32),
(I64(a), I64(b)) => a.$checked_func(b).map(I64),
(Isize(Is16(a)), Isize(Is16(b))) => a.$checked_func(b).map(Is16).map(Isize),
(Isize(Is32(a)), Isize(Is32(b))) => a.$checked_func(b).map(Is32).map(Isize),
(Isize(Is64(a)), Isize(Is64(b))) => a.$checked_func(b).map(Is64).map(Isize),
(U8(a), U8(b)) => a.$checked_func(b).map(U8),
(U16(a), U16(b)) => a.$checked_func(b).map(U16),
(U32(a), U32(b)) => a.$checked_func(b).map(U32),
(U64(a), U64(b)) => a.$checked_func(b).map(U64),
(Usize(Us16(a)), Usize(Us16(b))) => a.$checked_func(b).map(Us16).map(Usize),
(Usize(Us32(a)), Usize(Us32(b))) => a.$checked_func(b).map(Us32).map(Usize),
(Usize(Us64(a)), Usize(Us64(b))) => a.$checked_func(b).map(Us64).map(Usize),
(Infer(a), Infer(b)) => a.$checked_func(b).map(Infer),
@ -358,12 +380,14 @@ macro_rules! derive_binop {
(I16(a), I16(b)) => Ok(I16(a.$func(b))),
(I32(a), I32(b)) => Ok(I32(a.$func(b))),
(I64(a), I64(b)) => Ok(I64(a.$func(b))),
(Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a.$func(b)))),
(Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a.$func(b)))),
(Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a.$func(b)))),
(U8(a), U8(b)) => Ok(U8(a.$func(b))),
(U16(a), U16(b)) => Ok(U16(a.$func(b))),
(U32(a), U32(b)) => Ok(U32(a.$func(b))),
(U64(a), U64(b)) => Ok(U64(a.$func(b))),
(Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a.$func(b)))),
(Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a.$func(b)))),
(Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a.$func(b)))),
(Infer(a), Infer(b)) => Ok(Infer(a.$func(b))),
@ -393,6 +417,7 @@ fn check_division(
(I16(_), I16(0)) => Err(zerr),
(I32(_), I32(0)) => Err(zerr),
(I64(_), I64(0)) => Err(zerr),
(Isize(_), Isize(Is16(0))) => Err(zerr),
(Isize(_), Isize(Is32(0))) => Err(zerr),
(Isize(_), Isize(Is64(0))) => Err(zerr),
(InferSigned(_), InferSigned(0)) => Err(zerr),
@ -401,6 +426,7 @@ fn check_division(
(U16(_), U16(0)) => Err(zerr),
(U32(_), U32(0)) => Err(zerr),
(U64(_), U64(0)) => Err(zerr),
(Usize(_), Usize(Us16(0))) => Err(zerr),
(Usize(_), Usize(Us32(0))) => Err(zerr),
(Usize(_), Usize(Us64(0))) => Err(zerr),
(Infer(_), Infer(0)) => Err(zerr),
@ -409,6 +435,7 @@ fn check_division(
(I16(::std::i16::MIN), I16(-1)) => Err(Overflow(op)),
(I32(::std::i32::MIN), I32(-1)) => Err(Overflow(op)),
(I64(::std::i64::MIN), I64(-1)) => Err(Overflow(op)),
(Isize(Is16(::std::i16::MIN)), Isize(Is16(-1))) => Err(Overflow(op)),
(Isize(Is32(::std::i32::MIN)), Isize(Is32(-1))) => Err(Overflow(op)),
(Isize(Is64(::std::i64::MIN)), Isize(Is64(-1))) => Err(Overflow(op)),
(InferSigned(::std::i64::MIN), InferSigned(-1)) => Err(Overflow(op)),
@ -427,6 +454,7 @@ impl ::std::ops::Div for ConstInt {
(I16(a), I16(b)) => Ok(I16(a/b)),
(I32(a), I32(b)) => Ok(I32(a/b)),
(I64(a), I64(b)) => Ok(I64(a/b)),
(Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a/b))),
(Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a/b))),
(Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a/b))),
(InferSigned(a), InferSigned(b)) => Ok(InferSigned(a/b)),
@ -435,6 +463,7 @@ impl ::std::ops::Div for ConstInt {
(U16(a), U16(b)) => Ok(U16(a/b)),
(U32(a), U32(b)) => Ok(U32(a/b)),
(U64(a), U64(b)) => Ok(U64(a/b)),
(Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a/b))),
(Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a/b))),
(Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a/b))),
(Infer(a), Infer(b)) => Ok(Infer(a/b)),
@ -455,6 +484,7 @@ impl ::std::ops::Rem for ConstInt {
(I16(a), I16(b)) => Ok(I16(a%b)),
(I32(a), I32(b)) => Ok(I32(a%b)),
(I64(a), I64(b)) => Ok(I64(a%b)),
(Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a%b))),
(Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a%b))),
(Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a%b))),
(InferSigned(a), InferSigned(b)) => Ok(InferSigned(a%b)),
@ -463,6 +493,7 @@ impl ::std::ops::Rem for ConstInt {
(U16(a), U16(b)) => Ok(U16(a%b)),
(U32(a), U32(b)) => Ok(U32(a%b)),
(U64(a), U64(b)) => Ok(U64(a%b)),
(Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a%b))),
(Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a%b))),
(Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a%b))),
(Infer(a), Infer(b)) => Ok(Infer(a%b)),
@ -481,12 +512,14 @@ impl ::std::ops::Shl<ConstInt> for ConstInt {
I16(a) => Ok(I16(overflowing!(a.overflowing_shl(b), Op::Shl))),
I32(a) => Ok(I32(overflowing!(a.overflowing_shl(b), Op::Shl))),
I64(a) => Ok(I64(overflowing!(a.overflowing_shl(b), Op::Shl))),
Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
U8(a) => Ok(U8(overflowing!(a.overflowing_shl(b), Op::Shl))),
U16(a) => Ok(U16(overflowing!(a.overflowing_shl(b), Op::Shl))),
U32(a) => Ok(U32(overflowing!(a.overflowing_shl(b), Op::Shl))),
U64(a) => Ok(U64(overflowing!(a.overflowing_shl(b), Op::Shl))),
Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
Infer(a) => Ok(Infer(overflowing!(a.overflowing_shl(b), Op::Shl))),
@ -504,12 +537,14 @@ impl ::std::ops::Shr<ConstInt> for ConstInt {
I16(a) => Ok(I16(overflowing!(a.overflowing_shr(b), Op::Shr))),
I32(a) => Ok(I32(overflowing!(a.overflowing_shr(b), Op::Shr))),
I64(a) => Ok(I64(overflowing!(a.overflowing_shr(b), Op::Shr))),
Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
U8(a) => Ok(U8(overflowing!(a.overflowing_shr(b), Op::Shr))),
U16(a) => Ok(U16(overflowing!(a.overflowing_shr(b), Op::Shr))),
U32(a) => Ok(U32(overflowing!(a.overflowing_shr(b), Op::Shr))),
U64(a) => Ok(U64(overflowing!(a.overflowing_shr(b), Op::Shr))),
Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
Infer(a) => Ok(Infer(overflowing!(a.overflowing_shr(b), Op::Shr))),
@ -526,12 +561,14 @@ impl ::std::ops::Neg for ConstInt {
I16(a) => Ok(I16(overflowing!(a.overflowing_neg(), Op::Neg))),
I32(a) => Ok(I32(overflowing!(a.overflowing_neg(), Op::Neg))),
I64(a) => Ok(I64(overflowing!(a.overflowing_neg(), Op::Neg))),
Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_neg(), Op::Neg)))),
Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_neg(), Op::Neg)))),
Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_neg(), Op::Neg)))),
U8(0) => Ok(U8(0)),
U16(0) => Ok(U16(0)),
U32(0) => Ok(U32(0)),
U64(0) => Ok(U64(0)),
Usize(Us16(0)) => Ok(Usize(Us16(0))),
Usize(Us32(0)) => Ok(Usize(Us32(0))),
Usize(Us64(0)) => Ok(Usize(Us64(0))),
U8(_) => Err(UnsignedNegation),
@ -554,12 +591,14 @@ impl ::std::ops::Not for ConstInt {
I16(a) => Ok(I16(!a)),
I32(a) => Ok(I32(!a)),
I64(a) => Ok(I64(!a)),
Isize(Is16(a)) => Ok(Isize(Is16(!a))),
Isize(Is32(a)) => Ok(Isize(Is32(!a))),
Isize(Is64(a)) => Ok(Isize(Is64(!a))),
U8(a) => Ok(U8(!a)),
U16(a) => Ok(U16(!a)),
U32(a) => Ok(U32(!a)),
U64(a) => Ok(U64(!a)),
Usize(Us16(a)) => Ok(Usize(Us16(!a))),
Usize(Us32(a)) => Ok(Usize(Us32(!a))),
Usize(Us64(a)) => Ok(Usize(Us64(!a))),
Infer(a) => Ok(Infer(!a)),

View File

@ -15,6 +15,7 @@ use super::err::*;
/// Anything else is an error. This invariant is checked at several locations
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
pub enum ConstIsize {
Is16(i16),
Is32(i32),
Is64(i64),
}
@ -23,6 +24,7 @@ pub use self::ConstIsize::*;
impl ConstIsize {
pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 {
match (self, target_int_ty) {
(Is16(i), ast::IntTy::I16) => i as i64,
(Is32(i), ast::IntTy::I32) => i as i64,
(Is64(i), ast::IntTy::I64) => i,
_ => panic!("got invalid isize size for target"),
@ -30,6 +32,8 @@ impl ConstIsize {
}
pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
match target_int_ty {
ast::IntTy::I16 if i as i16 as i64 == i => Ok(Is16(i as i16)),
ast::IntTy::I16 => Err(LitOutOfRange(ast::IntTy::Is)),
ast::IntTy::I32 if i as i32 as i64 == i => Ok(Is32(i as i32)),
ast::IntTy::I32 => Err(LitOutOfRange(ast::IntTy::Is)),
ast::IntTy::I64 => Ok(Is64(i)),

View File

@ -15,6 +15,7 @@ use super::err::*;
/// Anything else is an error. This invariant is checked at several locations
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
pub enum ConstUsize {
Us16(u16),
Us32(u32),
Us64(u64),
}
@ -23,6 +24,7 @@ pub use self::ConstUsize::*;
impl ConstUsize {
pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 {
match (self, target_uint_ty) {
(Us16(i), ast::UintTy::U16) => i as u64,
(Us32(i), ast::UintTy::U32) => i as u64,
(Us64(i), ast::UintTy::U64) => i,
_ => panic!("got invalid usize size for target"),
@ -30,6 +32,8 @@ impl ConstUsize {
}
pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
match target_uint_ty {
ast::UintTy::U16 if i as u16 as u64 == i => Ok(Us16(i as u16)),
ast::UintTy::U16 => Err(ULitOutOfRange(ast::UintTy::Us)),
ast::UintTy::U32 if i as u32 as u64 == i => Ok(Us32(i as u32)),
ast::UintTy::U32 => Err(ULitOutOfRange(ast::UintTy::Us)),
ast::UintTy::U64 => Ok(Us64(i)),

View File

@ -2155,11 +2155,13 @@ impl OverflowOpViaIntrinsic {
let new_sty = match ty.sty {
TyInt(Is) => match &tcx.sess.target.target.target_pointer_width[..] {
"16" => TyInt(I16),
"32" => TyInt(I32),
"64" => TyInt(I64),
_ => bug!("unsupported target word size")
},
TyUint(Us) => match &tcx.sess.target.target.target_pointer_width[..] {
"16" => TyUint(U16),
"32" => TyUint(U32),
"64" => TyUint(U64),
_ => bug!("unsupported target word size")

View File

@ -1577,6 +1577,7 @@ fn int_type_width_signed<'tcx>(sty: &ty::TypeVariants<'tcx>, ccx: &CrateContext)
TyInt(t) => Some((match t {
ast::IntTy::Is => {
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
"16" => 16,
"32" => 32,
"64" => 64,
tws => bug!("Unsupported target word size for isize: {}", tws),
@ -1590,6 +1591,7 @@ fn int_type_width_signed<'tcx>(sty: &ty::TypeVariants<'tcx>, ccx: &CrateContext)
TyUint(t) => Some((match t {
ast::UintTy::Us => {
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
"16" => 16,
"32" => 32,
"64" => 64,
tws => bug!("Unsupported target word size for usize: {}", tws),

View File

@ -122,6 +122,7 @@ impl Type {
pub fn int(ccx: &CrateContext) -> Type {
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
"16" => Type::i16(ccx),
"32" => Type::i32(ccx),
"64" => Type::i64(ccx),
tws => bug!("Unsupported target word size for int: {}", tws),