Skip to content

Commit 92a13e6

Browse files
committed
Such large. Very 128. Much bits.
This commit introduces 128-bit integers. Stage 2 builds and produces a working compiler which understands and supports 128-bit integers throughout. The general strategy used is to have rustc_i128 module which provides aliases for iu128, equal to iu64 in stage9 and iu128 later. Since nowhere in rustc we rely on large numbers being supported, this strategy is good enough to get past the first bootstrap stages to end up with a fully working 128-bit capable compiler. In order for this strategy to work, number of locations had to be changed to use associated max_value/min_value instead of MAX/MIN constants as well as the min_value (or was it max_value?) had to be changed to use xor instead of shift so both 64-bit and 128-bit based consteval works (former not necessarily producing the right results in stage1).
1 parent eaf71f8 commit 92a13e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1045
-381
lines changed

src/libcore/clone.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,16 @@ clone_impl! { i8 }
140140
clone_impl! { i16 }
141141
clone_impl! { i32 }
142142
clone_impl! { i64 }
143+
#[cfg(not(stage0))]
144+
clone_impl! { i128 }
143145

144146
clone_impl! { usize }
145147
clone_impl! { u8 }
146148
clone_impl! { u16 }
147149
clone_impl! { u32 }
148150
clone_impl! { u64 }
151+
#[cfg(not(stage0))]
152+
clone_impl! { u128 }
149153

150154
clone_impl! { f32 }
151155
clone_impl! { f64 }

src/libcore/cmp.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ mod impls {
593593
partial_eq_impl! {
594594
bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64
595595
}
596+
#[cfg(not(stage0))]
597+
partial_eq_impl! { u128 i128 }
596598

597599
macro_rules! eq_impl {
598600
($($t:ty)*) => ($(
@@ -602,6 +604,8 @@ mod impls {
602604
}
603605

604606
eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
607+
#[cfg(not(stage0))]
608+
eq_impl! { u128 i128 }
605609

606610
macro_rules! partial_ord_impl {
607611
($($t:ty)*) => ($(
@@ -691,6 +695,8 @@ mod impls {
691695
}
692696

693697
ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
698+
#[cfg(not(stage0))]
699+
ord_impl! { u128 i128 }
694700

695701
#[unstable(feature = "never_type", issue = "35121")]
696702
impl PartialEq for ! {

src/libcore/default.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,16 @@ default_impl! { u8, 0 }
144144
default_impl! { u16, 0 }
145145
default_impl! { u32, 0 }
146146
default_impl! { u64, 0 }
147+
#[cfg(not(stage0))]
148+
default_impl! { u128, 0 }
147149

148150
default_impl! { isize, 0 }
149151
default_impl! { i8, 0 }
150152
default_impl! { i16, 0 }
151153
default_impl! { i32, 0 }
152154
default_impl! { i64, 0 }
155+
#[cfg(not(stage0))]
156+
default_impl! { i128, 0 }
153157

154158
default_impl! { f32, 0.0f32 }
155159
default_impl! { f64, 0.0f64 }

src/libcore/fmt/num.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ trait Int: Zero + PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> +
3030
fn to_u16(&self) -> u16;
3131
fn to_u32(&self) -> u32;
3232
fn to_u64(&self) -> u64;
33+
#[cfg(not(stage0))]
34+
fn to_u128(&self) -> u128;
3335
}
3436

3537
macro_rules! doit {
@@ -39,9 +41,13 @@ macro_rules! doit {
3941
fn to_u16(&self) -> u16 { *self as u16 }
4042
fn to_u32(&self) -> u32 { *self as u32 }
4143
fn to_u64(&self) -> u64 { *self as u64 }
44+
#[cfg(not(stage0))]
45+
fn to_u128(&self) -> u128 { *self as u128 }
4246
})*)
4347
}
4448
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
49+
#[cfg(not(stage0))]
50+
doit! { i128 u128 }
4551

4652
/// A type that represents a specific radix
4753
#[doc(hidden)]
@@ -59,11 +65,11 @@ trait GenericRadix {
5965

6066
/// Format an integer using the radix using a formatter.
6167
fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
62-
// The radix can be as low as 2, so we need a buffer of at least 64
68+
// The radix can be as low as 2, so we need a buffer of at least 128
6369
// characters for a base 2 number.
6470
let zero = T::zero();
6571
let is_nonnegative = x >= zero;
66-
let mut buf = [0; 64];
72+
let mut buf = [0; 128];
6773
let mut curr = buf.len();
6874
let base = T::from_u8(self.base());
6975
if is_nonnegative {
@@ -182,6 +188,8 @@ integer! { i8, u8 }
182188
integer! { i16, u16 }
183189
integer! { i32, u32 }
184190
integer! { i64, u64 }
191+
#[cfg(not(stage0))]
192+
integer! { i128, u128 }
185193

186194
const DEC_DIGITS_LUT: &'static[u8] =
187195
b"0001020304050607080910111213141516171819\
@@ -203,14 +211,15 @@ macro_rules! impl_Display {
203211
// convert the negative num to positive by summing 1 to it's 2 complement
204212
(!self.$conv_fn()).wrapping_add(1)
205213
};
206-
let mut buf: [u8; 20] = unsafe { mem::uninitialized() };
214+
let mut buf: [u8; 40] = unsafe { mem::uninitialized() };
207215
let mut curr = buf.len() as isize;
208216
let buf_ptr = buf.as_mut_ptr();
209217
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
210218

211219
unsafe {
212-
// eagerly decode 4 characters at a time
213-
if <$t>::max_value() as u64 >= 10000 {
220+
// need at least 16 bits for the 4-characters-at-a-time to work.
221+
if ::mem::size_of::<$t>() >= 2 {
222+
// eagerly decode 4 characters at a time
214223
while n >= 10000 {
215224
let rem = (n % 10000) as isize;
216225
n /= 10000;
@@ -256,6 +265,8 @@ macro_rules! impl_Display {
256265

257266
impl_Display!(i8, u8, i16, u16, i32, u32: to_u32);
258267
impl_Display!(i64, u64: to_u64);
268+
#[cfg(not(stage0))]
269+
impl_Display!(i128, u128: to_u128);
259270
#[cfg(target_pointer_width = "16")]
260271
impl_Display!(isize, usize: to_u16);
261272
#[cfg(target_pointer_width = "32")]

src/libcore/hash/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ pub trait Hasher {
177177
fn write_u64(&mut self, i: u64) {
178178
self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
179179
}
180+
#[cfg(not(stage0))]
181+
/// Write a single `u128` into this hasher.
182+
#[inline]
183+
#[unstable(feature = "i128", issue = "35118")]
184+
fn write_u128(&mut self, i: u128) {
185+
self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) })
186+
}
180187
/// Write a single `usize` into this hasher.
181188
#[inline]
182189
#[stable(feature = "hasher_write", since = "1.3.0")]
@@ -211,6 +218,13 @@ pub trait Hasher {
211218
fn write_i64(&mut self, i: i64) {
212219
self.write_u64(i as u64)
213220
}
221+
#[cfg(not(stage0))]
222+
/// Write a single `i128` into this hasher.
223+
#[inline]
224+
#[unstable(feature = "i128", issue = "35118")]
225+
fn write_i128(&mut self, i: i128) {
226+
self.write_u128(i as u128)
227+
}
214228
/// Write a single `isize` into this hasher.
215229
#[inline]
216230
#[stable(feature = "hasher_write", since = "1.3.0")]
@@ -319,6 +333,11 @@ mod impls {
319333
(i64, write_i64),
320334
(isize, write_isize),
321335
}
336+
#[cfg(not(stage0))]
337+
impl_write! {
338+
(u128, write_u128),
339+
(i128, write_i128),
340+
}
322341

323342
#[stable(feature = "rust1", since = "1.0.0")]
324343
impl Hash for bool {

src/libcore/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,20 @@ mod uint_macros;
118118
#[path = "num/i32.rs"] pub mod i32;
119119
#[path = "num/i64.rs"] pub mod i64;
120120

121+
// SNAP
122+
#[cfg(not(stage0))]
123+
#[path = "num/i128.rs"] pub mod i128;
124+
121125
#[path = "num/usize.rs"] pub mod usize;
122126
#[path = "num/u8.rs"] pub mod u8;
123127
#[path = "num/u16.rs"] pub mod u16;
124128
#[path = "num/u32.rs"] pub mod u32;
125129
#[path = "num/u64.rs"] pub mod u64;
126130

131+
// SNAP
132+
#[cfg(not(stage0))]
133+
#[path = "num/u128.rs"] pub mod u128;
134+
127135
#[path = "num/f32.rs"] pub mod f32;
128136
#[path = "num/f64.rs"] pub mod f64;
129137

src/libcore/nonzero.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ unsafe impl Zeroable for i32 {}
3030
unsafe impl Zeroable for u32 {}
3131
unsafe impl Zeroable for i64 {}
3232
unsafe impl Zeroable for u64 {}
33+
#[cfg(not(stage0))]
34+
unsafe impl Zeroable for i128 {}
35+
#[cfg(not(stage0))]
36+
unsafe impl Zeroable for u128 {}
3337

3438
/// A wrapper type for raw pointers and integers that will never be
3539
/// NULL or 0 that might allow certain optimizations.

src/libcore/num/i128.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! The 128-bit signed integer type.
12+
//!
13+
//! *[See also the `i128` primitive type](../../std/primitive.i128.html).*
14+
15+
#![unstable(feature = "i128", issue="35118")]
16+
17+
int_module! { i128 }

src/libcore/num/i16.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616

17-
int_module! { i16, 16 }
17+
int_module! { i16 }

src/libcore/num/i32.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616

17-
int_module! { i32, 32 }
17+
int_module! { i32 }

src/libcore/num/i64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616

17-
int_module! { i64, 64 }
17+
int_module! { i64 }

src/libcore/num/i8.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616

17-
int_module! { i8, 8 }
17+
int_module! { i8 }

src/libcore/num/int_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![doc(hidden)]
1212

13-
macro_rules! int_module { ($T:ident, $bits:expr) => (
13+
macro_rules! int_module { ($T:ident) => (
1414

1515
/// The smallest value that can be represented by this integer type.
1616
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/num/isize.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,4 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616

17-
#[cfg(target_pointer_width = "16")]
18-
int_module! { isize, 16 }
19-
#[cfg(target_pointer_width = "32")]
20-
int_module! { isize, 32 }
21-
#[cfg(target_pointer_width = "64")]
22-
int_module! { isize, 64 }
17+
int_module! { isize }

0 commit comments

Comments
 (0)