Skip to content

Commit

Permalink
Support 16-bit pointers as well as i/usize
Browse files Browse the repository at this point in the history
This is based on the original work of Dylan McKay for the
[avr-rust project][ar].

[ar]: https://github.com/avr-rust/rust
  • Loading branch information
shepmaster committed May 19, 2016
1 parent 2fb6f8e commit bc7595c
Show file tree
Hide file tree
Showing 18 changed files with 123 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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 }
})*)
Expand Down Expand Up @@ -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")]
Expand Down
11 changes: 11 additions & 0 deletions src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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)]
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/num/isize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
21 changes: 21 additions & 0 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/num/usize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
6 changes: 6 additions & 0 deletions src/libcore/num/wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions src/libcoretest/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,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: \
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
Expand All @@ -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!(),
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_const_eval/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,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))));
},
Expand Down
Loading

0 comments on commit bc7595c

Please sign in to comment.