Skip to content

Commit 1b13437

Browse files
author
Dylan McKay
committed
[AVR] Teach Rust about 16-bit pointers
Rust is now be able to handle 16-bit pointers.
1 parent f9d262e commit 1b13437

File tree

17 files changed

+198
-18
lines changed

17 files changed

+198
-18
lines changed

src/liballoc/raw_vec.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,16 +438,16 @@ impl<T> Drop for RawVec<T> {
438438
// * We don't overflow `usize::MAX` and actually allocate too little
439439
//
440440
// On 64-bit we just need to check for overflow since trying to allocate
441-
// `> isize::MAX` bytes will surely fail. On 32-bit we need to add an extra
442-
// guard for this in case we're running on a platform which can use all 4GB in
443-
// user-space. e.g. PAE or x32
441+
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
442+
// an extra guard for this in case we're running on a platform which can use
443+
// all 4GB in user-space. e.g. PAE or x32
444444

445445
#[inline]
446446
#[cfg(target_pointer_width = "64")]
447447
fn alloc_guard(_alloc_size: usize) { }
448448

449449
#[inline]
450-
#[cfg(target_pointer_width = "32")]
450+
#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
451451
fn alloc_guard(alloc_size: usize) {
452452
assert!(alloc_size <= ::core::isize::MAX as usize, "capacity overflow");
453453
}

src/libcore/fmt/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,9 @@ impl<T> Pointer for *const T {
13411341

13421342
if let None = f.width {
13431343
// The formats need two extra bytes, for the 0x
1344-
if cfg!(target_pointer_width = "32") {
1344+
if cfg!(target_pointer_width = "16") {
1345+
f.width = Some(5);
1346+
} else if cfg!(target_pointer_width = "32") {
13451347
f.width = Some(10);
13461348
} else {
13471349
f.width = Some(18);

src/libcore/fmt/num.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ trait Int: Zero + PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> +
2727
Sub<Output=Self> + Copy {
2828
fn from_u8(u: u8) -> Self;
2929
fn to_u8(&self) -> u8;
30+
fn to_u16(&self) -> u16;
3031
fn to_u32(&self) -> u32;
3132
fn to_u64(&self) -> u64;
3233
}
@@ -35,6 +36,7 @@ macro_rules! doit {
3536
($($t:ident)*) => ($(impl Int for $t {
3637
fn from_u8(u: u8) -> $t { u as $t }
3738
fn to_u8(&self) -> u8 { *self as u8 }
39+
fn to_u16(&self) -> u16 { *self as u16 }
3840
fn to_u32(&self) -> u32 { *self as u32 }
3941
fn to_u64(&self) -> u64 { *self as u64 }
4042
})*)
@@ -312,6 +314,8 @@ macro_rules! impl_Display {
312314

313315
impl_Display!(i8, u8, i16, u16, i32, u32: to_u32);
314316
impl_Display!(i64, u64: to_u64);
317+
#[cfg(target_pointer_width = "16")]
318+
impl_Display!(isize, usize: to_u16);
315319
#[cfg(target_pointer_width = "32")]
316320
impl_Display!(isize, usize: to_u32);
317321
#[cfg(target_pointer_width = "64")]

src/libcore/hash/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ pub trait Hasher {
136136
#[inline]
137137
#[stable(feature = "hasher_write", since = "1.3.0")]
138138
fn write_usize(&mut self, i: usize) {
139-
if cfg!(target_pointer_width = "32") {
139+
if cfg!(target_pointer_width = "16") {
140+
self.write_u16(i as u16);
141+
} else if cfg!(target_pointer_width = "32") {
140142
self.write_u32(i as u32)
141143
} else {
142144
self.write_u64(i as u64)

src/libcore/iter.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,6 +2725,8 @@ step_impl_unsigned!(u64);
27252725
step_impl_signed!(i64);
27262726
#[cfg(target_pointer_width = "32")]
27272727
step_impl_no_between!(u64 i64);
2728+
#[cfg(target_pointer_width = "16")]
2729+
step_impl_no_between!(u64 i64);
27282730

27292731
/// An adapter for stepping range iterators by a custom amount.
27302732
///

src/libcore/mem.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
490490
#[stable(feature = "rust1", since = "1.0.0")]
491491
pub fn drop<T>(_x: T) { }
492492

493+
macro_rules! repeat_u8_as_u16 {
494+
($name:expr) => { (($name as u16) << 8 |
495+
($name as u16)) }
496+
}
493497
macro_rules! repeat_u8_as_u32 {
494498
($name:expr) => { (($name as u32) << 24 |
495499
($name as u32) << 16 |
@@ -515,11 +519,18 @@ macro_rules! repeat_u8_as_u64 {
515519
pub const POST_DROP_U8: u8 = 0x1d;
516520
#[unstable(feature = "filling_drop")]
517521
#[allow(missing_docs)]
522+
pub const POST_DROP_U16: u16 = repeat_u8_as_u16!(POST_DROP_U8);
523+
#[unstable(feature = "filling_drop")]
524+
#[allow(missing_docs)]
518525
pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
519526
#[unstable(feature = "filling_drop")]
520527
#[allow(missing_docs)]
521528
pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);
522529

530+
#[cfg(target_pointer_width = "16")]
531+
#[unstable(feature = "filling_drop")]
532+
#[allow(missing_docs)]
533+
pub const POST_DROP_USIZE: usize = POST_DROP_U16 as usize;
523534
#[cfg(target_pointer_width = "32")]
524535
#[unstable(feature = "filling_drop")]
525536
#[allow(missing_docs)]

src/libcore/num/isize.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414

15+
#[cfg(target_pointer_width = "16")]
16+
int_module! { isize, 16 }
1517
#[cfg(target_pointer_width = "32")]
1618
int_module! { isize, 32 }
1719
#[cfg(target_pointer_width = "64")]

src/libcore/num/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,15 @@ impl i64 {
639639
intrinsics::i64_mul_with_overflow }
640640
}
641641

642+
#[cfg(target_pointer_width = "16")]
643+
#[lang = "isize"]
644+
impl isize {
645+
int_impl! { i16, u16, 16,
646+
intrinsics::i16_add_with_overflow,
647+
intrinsics::i16_sub_with_overflow,
648+
intrinsics::i16_mul_with_overflow }
649+
}
650+
642651
#[cfg(target_pointer_width = "32")]
643652
#[lang = "isize"]
644653
impl isize {
@@ -1209,6 +1218,18 @@ impl u64 {
12091218
intrinsics::u64_mul_with_overflow }
12101219
}
12111220

1221+
#[cfg(target_pointer_width = "16")]
1222+
#[lang = "usize"]
1223+
impl usize {
1224+
uint_impl! { u16, 16,
1225+
intrinsics::ctpop16,
1226+
intrinsics::ctlz16,
1227+
intrinsics::cttz16,
1228+
intrinsics::bswap16,
1229+
intrinsics::u16_add_with_overflow,
1230+
intrinsics::u16_sub_with_overflow,
1231+
intrinsics::u16_mul_with_overflow }
1232+
}
12121233
#[cfg(target_pointer_width = "32")]
12131234
#[lang = "usize"]
12141235
impl usize {

src/libcore/num/wrapping.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,56 @@ impl OverflowingOps for usize {
402402
}
403403
}
404404

405+
#[cfg(target_pointer_width = "16")]
406+
impl OverflowingOps for usize {
407+
#[inline(always)]
408+
fn overflowing_add(self, rhs: usize) -> (usize, bool) {
409+
unsafe {
410+
let res = u16_add_with_overflow(self as u16, rhs as u16);
411+
(res.0 as usize, res.1)
412+
}
413+
}
414+
#[inline(always)]
415+
fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
416+
unsafe {
417+
let res = u16_sub_with_overflow(self as u16, rhs as u16);
418+
(res.0 as usize, res.1)
419+
}
420+
}
421+
#[inline(always)]
422+
fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
423+
unsafe {
424+
let res = u16_mul_with_overflow(self as u16, rhs as u16);
425+
(res.0 as usize, res.1)
426+
}
427+
}
428+
#[inline(always)]
429+
fn overflowing_div(self, rhs: usize) -> (usize, bool) {
430+
let (r, f) = (self as u16).overflowing_div(rhs as u16);
431+
(r as usize, f)
432+
}
433+
#[inline(always)]
434+
fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
435+
let (r, f) = (self as u16).overflowing_rem(rhs as u16);
436+
(r as usize, f)
437+
}
438+
#[inline(always)]
439+
fn overflowing_neg(self) -> (usize, bool) {
440+
let (r, f) = (self as u16).overflowing_neg();
441+
(r as usize, f)
442+
}
443+
#[inline(always)]
444+
fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
445+
let (r, f) = (self as u16).overflowing_shl(rhs);
446+
(r as usize, f)
447+
}
448+
#[inline(always)]
449+
fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
450+
let (r, f) = (self as u16).overflowing_shr(rhs);
451+
(r as usize, f)
452+
}
453+
}
454+
405455
#[cfg(target_pointer_width = "64")]
406456
impl OverflowingOps for isize {
407457
#[inline(always)]
@@ -501,3 +551,53 @@ impl OverflowingOps for isize {
501551
(r as isize, f)
502552
}
503553
}
554+
555+
#[cfg(target_pointer_width = "16")]
556+
impl OverflowingOps for isize {
557+
#[inline(always)]
558+
fn overflowing_add(self, rhs: isize) -> (isize, bool) {
559+
unsafe {
560+
let res = i16_add_with_overflow(self as i16, rhs as i16);
561+
(res.0 as isize, res.1)
562+
}
563+
}
564+
#[inline(always)]
565+
fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
566+
unsafe {
567+
let res = i16_sub_with_overflow(self as i16, rhs as i16);
568+
(res.0 as isize, res.1)
569+
}
570+
}
571+
#[inline(always)]
572+
fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
573+
unsafe {
574+
let res = i16_mul_with_overflow(self as i16, rhs as i16);
575+
(res.0 as isize, res.1)
576+
}
577+
}
578+
#[inline(always)]
579+
fn overflowing_div(self, rhs: isize) -> (isize, bool) {
580+
let (r, f) = (self as i16).overflowing_div(rhs as i16);
581+
(r as isize, f)
582+
}
583+
#[inline(always)]
584+
fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
585+
let (r, f) = (self as i16).overflowing_rem(rhs as i16);
586+
(r as isize, f)
587+
}
588+
#[inline(always)]
589+
fn overflowing_neg(self) -> (isize, bool) {
590+
let (r, f) = (self as i16).overflowing_neg();
591+
(r as isize, f)
592+
}
593+
#[inline(always)]
594+
fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
595+
let (r, f) = (self as i16).overflowing_shl(rhs);
596+
(r as isize, f)
597+
}
598+
#[inline(always)]
599+
fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
600+
let (r, f) = (self as i16).overflowing_shr(rhs);
601+
(r as isize, f)
602+
}
603+
}

src/libcoretest/mem.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ fn size_of_basic() {
1818
assert_eq!(size_of::<u64>(), 8);
1919
}
2020

21+
#[test]
22+
#[cfg(target_pointer_width = "16")]
23+
fn size_of_16() {
24+
assert_eq!(size_of::<usize>(), 2);
25+
assert_eq!(size_of::<*const usize>(), 2);
26+
}
27+
2128
#[test]
2229
#[cfg(target_pointer_width = "32")]
2330
fn size_of_32() {
@@ -47,6 +54,13 @@ fn align_of_basic() {
4754
assert_eq!(align_of::<u32>(), 4);
4855
}
4956

57+
#[test]
58+
#[cfg(target_pointer_width = "16")]
59+
fn align_of_16() {
60+
assert_eq!(align_of::<usize>(), 2);
61+
assert_eq!(align_of::<*const usize>(), 2);
62+
}
63+
5064
#[test]
5165
#[cfg(target_pointer_width = "32")]
5266
fn align_of_32() {

src/librustc_trans/trans/adt.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ pub fn represent_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
177177
repr
178178
}
179179

180+
macro_rules! repeat_u8_as_u16 {
181+
($name:expr) => { (($name as u16) << 8 |
182+
($name as u16)) }
183+
}
180184
macro_rules! repeat_u8_as_u32 {
181185
($name:expr) => { (($name as u32) << 24 |
182186
($name as u32) << 16 |
@@ -203,23 +207,27 @@ pub const DTOR_NEEDED_HINT: u8 = 0x3d;
203207
pub const DTOR_MOVED_HINT: u8 = 0x2d;
204208

205209
pub const DTOR_NEEDED: u8 = 0xd4;
210+
pub const DTOR_NEEDED_U16: u16 = repeat_u8_as_u16!(DTOR_NEEDED);
206211
pub const DTOR_NEEDED_U32: u32 = repeat_u8_as_u32!(DTOR_NEEDED);
207212
pub const DTOR_NEEDED_U64: u64 = repeat_u8_as_u64!(DTOR_NEEDED);
208213
#[allow(dead_code)]
209214
pub fn dtor_needed_usize(ccx: &CrateContext) -> usize {
210215
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
216+
"16" => DTOR_NEEDED_U16 as usize,
211217
"32" => DTOR_NEEDED_U32 as usize,
212218
"64" => DTOR_NEEDED_U64 as usize,
213219
tws => panic!("Unsupported target word size for int: {}", tws),
214220
}
215221
}
216222

217223
pub const DTOR_DONE: u8 = 0x1d;
224+
pub const DTOR_DONE_U16: u16 = repeat_u8_as_u16!(DTOR_DONE);
218225
pub const DTOR_DONE_U32: u32 = repeat_u8_as_u32!(DTOR_DONE);
219226
pub const DTOR_DONE_U64: u64 = repeat_u8_as_u64!(DTOR_DONE);
220227
#[allow(dead_code)]
221228
pub fn dtor_done_usize(ccx: &CrateContext) -> usize {
222229
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
230+
"16" => DTOR_DONE_U16 as usize,
223231
"32" => DTOR_DONE_U32 as usize,
224232
"64" => DTOR_DONE_U64 as usize,
225233
tws => panic!("Unsupported target word size for int: {}", tws),

src/librustc_trans/trans/base.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a
935935
let _icx = push_ctxt("call_memcpy");
936936
let ccx = cx.ccx();
937937
let key = match &ccx.sess().target.target.target_pointer_width[..] {
938+
"16" => "llvm.memcpy.p0i8.p0i8.i16",
938939
"32" => "llvm.memcpy.p0i8.p0i8.i32",
939940
"64" => "llvm.memcpy.p0i8.p0i8.i64",
940941
tws => panic!("Unsupported target word size for memcpy: {}", tws),
@@ -989,6 +990,7 @@ fn memfill<'a, 'tcx>(b: &Builder<'a, 'tcx>, llptr: ValueRef, ty: Ty<'tcx>, byte:
989990
let llty = type_of::type_of(ccx, ty);
990991

991992
let intrinsic_key = match &ccx.sess().target.target.target_pointer_width[..] {
993+
"16" => "llvm.memset.p0i8.i16",
992994
"32" => "llvm.memset.p0i8.i32",
993995
"64" => "llvm.memset.p0i8.i64",
994996
tws => panic!("Unsupported target word size for memset: {}", tws),

src/librustc_trans/trans/common.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,7 @@ pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
834834
let v = i.as_i64();
835835

836836
match machine::llbitsize_of_real(ccx, ccx.int_type()) {
837+
16 => assert!(v < (1<<15) && v >= -(1<<15)),
837838
32 => assert!(v < (1<<31) && v >= -(1<<31)),
838839
64 => {},
839840
n => panic!("unsupported target size: {}", n)
@@ -846,6 +847,7 @@ pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
846847
let v = i.as_u64();
847848

848849
match machine::llbitsize_of_real(ccx, ccx.int_type()) {
850+
16 => assert!(v < (1<<16)),
849851
32 => assert!(v < (1<<32)),
850852
64 => {},
851853
n => panic!("unsupported target size: {}", n)

src/librustc_trans/trans/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
767767
/// address space on 64-bit ARMv8 and x86_64.
768768
pub fn obj_size_bound(&self) -> u64 {
769769
match &self.sess().target.target.target_pointer_width[..] {
770+
"16" => 1 << 15,
770771
"32" => 1 << 31,
771772
"64" => 1 << 47,
772773
_ => unreachable!() // error handled by config::build_target_config
@@ -829,10 +830,13 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
829830
let t_f32 = Type::f32(ccx);
830831
let t_f64 = Type::f64(ccx);
831832

833+
ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
832834
ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
833835
ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
836+
ifn!("llvm.memmove.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
834837
ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
835838
ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
839+
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
836840
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
837841
ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
838842

src/librustc_trans/trans/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,11 +2312,13 @@ impl OverflowOpViaIntrinsic {
23122312

23132313
let new_sty = match ty.sty {
23142314
TyInt(TyIs) => match &tcx.sess.target.target.target_pointer_width[..] {
2315+
"16" => TyInt(TyI16),
23152316
"32" => TyInt(TyI32),
23162317
"64" => TyInt(TyI64),
23172318
_ => panic!("unsupported target word size")
23182319
},
23192320
TyUint(TyUs) => match &tcx.sess.target.target.target_pointer_width[..] {
2321+
"16" => TyUint(TyU16),
23202322
"32" => TyUint(TyU32),
23212323
"64" => TyUint(TyU64),
23222324
_ => panic!("unsupported target word size")

0 commit comments

Comments
 (0)