Skip to content

Commit

Permalink
Add cfg(no_128_bit) to core: removes most u128/i128 operations
Browse files Browse the repository at this point in the history
  • Loading branch information
GKFX committed Jan 22, 2023
1 parent cef633d commit 8122fb6
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 14 deletions.
2 changes: 1 addition & 1 deletion library/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description = "The Rust Core Library"
autotests = false
autobenches = false
# If you update this, be sure to update it in a bunch of other places too!
# As of 2022, it was the ci/pgo.sh script and the core-no-fp-fmt-parse test.
# As of 2023, it was the ci/pgo.sh script and the core-no-fp-fmt-parse/core-no-128-bit tests.
edition = "2021"

[lib]
Expand Down
38 changes: 35 additions & 3 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,12 @@ integer! { i8, u8 }
integer! { i16, u16 }
integer! { i32, u32 }
integer! { i64, u64 }
#[cfg(not(no_128_bit))]
integer! { i128, u128 }

macro_rules! debug {
($($T:ident)*) => {$(
($($( #[$cfg:meta] )? $T:ident)*) => {$(
$( #[$cfg] )?
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for $T {
#[inline]
Expand All @@ -195,8 +198,30 @@ macro_rules! debug {
)*};
}
debug! {
i8 i16 i32 i64 i128 isize
u8 u16 u32 u64 u128 usize
i8 i16 i32 i64 #[cfg(not(no_128_bit))] i128 isize
u8 u16 u32 u64 #[cfg(not(no_128_bit))] u128 usize
}

macro_rules! fake_debug {
($($( #[$cfg:meta] )? $T:ident)*) => {$(
$( #[$cfg] )?
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for $T {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Debug formats are not stable so this is a legitimate implementation.
// It would be possible to hexdump the contents instead, or to
// fail or panic, but for an application which has specifically
// recompiled core to avoid i128, the former seems unnecessary
// and the latter needlessly harmful.
f.write_str(stringify!($T))
}
}
)*}
}
fake_debug! {
#[cfg(no_128_bit)] i128
#[cfg(no_128_bit)] u128
}

// 2 digit decimal look up table
Expand Down Expand Up @@ -476,9 +501,11 @@ mod imp {
impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32);
impl_Exp!(i64, u64 as u64 via to_u64 named exp_u64);
}
#[cfg(not(no_128_bit))]
impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128);

/// Helper function for writing a u64 into `buf` going from last to first, with `curr`.
#[cfg(not(no_128_bit))] // unused for `no_128_bit`
fn parse_u64_into<const N: usize>(mut n: u64, buf: &mut [MaybeUninit<u8>; N], curr: &mut usize) {
let buf_ptr = MaybeUninit::slice_as_mut_ptr(buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
Expand Down Expand Up @@ -566,13 +593,15 @@ fn parse_u64_into<const N: usize>(mut n: u64, buf: &mut [MaybeUninit<u8>; N], cu
}

#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(no_128_bit))]
impl fmt::Display for u128 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_u128(*self, true, f)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(no_128_bit))]
impl fmt::Display for i128 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let is_nonnegative = *self >= 0;
Expand All @@ -590,6 +619,7 @@ impl fmt::Display for i128 {
/// into at most 2 u64s, and then chunks by 10e16, 10e8, 10e4, 10e2, and then 10e1.
/// It also has to handle 1 last item, as 10^40 > 2^128 > 10^39, whereas
/// 10^20 > 2^64 > 10^19.
#[cfg(not(no_128_bit))]
fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
Expand Down Expand Up @@ -649,6 +679,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
/// in Proc. of the SIGPLAN94 Conference on Programming Language Design and
/// Implementation, 1994, pp. 61–72
///
#[cfg(not(no_128_bit))]
fn udiv_1e19(n: u128) -> (u128, u64) {
const DIV: u64 = 1e19 as u64;
const FACTOR: u128 = 156927543384667019095894735580191660403;
Expand All @@ -665,6 +696,7 @@ fn udiv_1e19(n: u128) -> (u128, u64) {

/// Multiply unsigned 128 bit integers, return upper 128 bits of the result
#[inline]
#[cfg(not(no_128_bit))]
fn u128_mulhi(x: u128, y: u128) -> u128 {
let x_lo = x as u64;
let x_hi = (x >> 64) as u64;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
not(test),
any(not(feature = "miri-test-libstd"), test, doctest),
no_fp_fmt_parse,
no_128_bit,
target_pointer_width = "16",
target_pointer_width = "32",
target_pointer_width = "64",
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ macro_rules! int_impl {
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
$reversed:expr, $le_bytes:expr, $be_bytes:expr,
$to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr,
$bound_condition:expr) => {
$bound_condition:expr $(, #[$intrinsics_cfg:meta])?) => {
/// The smallest value that can be represented by this integer type
#[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ")")]
///
Expand Down Expand Up @@ -62,6 +62,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")]
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
$( #[$intrinsics_cfg] )?
pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
from_str_radix(src, radix)
}
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl i128 {
"[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
"[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "" }
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "", #[cfg(not(no_128_bit))] }
}

#[cfg(target_pointer_width = "16")]
Expand Down Expand Up @@ -940,7 +940,7 @@ impl u128 {
0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
"[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
"", "", ""}
"", "", "", #[cfg(not(no_128_bit))]}
}

#[cfg(target_pointer_width = "16")]
Expand Down
20 changes: 14 additions & 6 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ macro_rules! impl_nonzero_fmt {
}

macro_rules! nonzero_integers {
( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => {
( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $(#[$cfg: meta])? $Ty: ident($Int: ty); )+ ) => {
$(
/// An integer that is known not to equal zero.
///
Expand Down Expand Up @@ -154,9 +154,12 @@ macro_rules! nonzero_integers {
}
}

$(#[$cfg])?
impl_nonzero_fmt! {
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
#[$stability] (Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}

impl_nonzero_fmt!(#[$stability] (Debug) for $Ty);
)+
}
}
Expand All @@ -166,13 +169,15 @@ nonzero_integers! {
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
#[cfg(not(no_128_bit))] NonZeroU128(u128);
#[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")]
#[cfg(not(no_128_bit))] NonZeroI128(i128);
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

Expand All @@ -191,8 +196,11 @@ macro_rules! from_str_radix_nzint_impl {
)*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroIsize }

#[cfg(not(no_128_bit))]
from_str_radix_nzint_impl! { NonZeroU128 NonZeroI128 }

macro_rules! nonzero_leading_trailing_zeros {
( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ macro_rules! uint_impl {
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
$reversed:expr, $le_bytes:expr, $be_bytes:expr,
$to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr,
$bound_condition:expr) => {
$bound_condition:expr $(, #[$intrinsics_cfg:meta])?) => {
/// The smallest value that can be represented by this integer type.
///
/// # Examples
Expand Down Expand Up @@ -63,6 +63,7 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")]
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
$( #[$intrinsics_cfg] )?
pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
from_str_radix(src, radix)
}
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
(Some(Mode::Codegen), "parallel_compiler", None),
(Some(Mode::Std), "stdarch_intel_sde", None),
(Some(Mode::Std), "no_fp_fmt_parse", None),
(Some(Mode::Std), "no_128_bit", None),
(Some(Mode::Std), "no_global_oom_handling", None),
(Some(Mode::Std), "no_rc", None),
(Some(Mode::Std), "no_sync", None),
Expand Down
8 changes: 8 additions & 0 deletions tests/run-make-fulldeps/core-no-128-bit/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include ../tools.mk

all:
$(RUSTC) --edition=2021 --crate-type=rlib --crate-name=core ../../../library/core/src/lib.rs --cfg no_128_bit
$(RUSTC) --edition=2021 --crate-type=staticlib --crate-name=demo --sysroot=. -C panic=abort lib.rs
# Expect that objdump succeeds and grep fails. The grep pattern is for names like __multi3.
# There is no pipefail on dash so echo a string that will fail the test if objump fails.
(objdump -t $(TMPDIR)/libdemo.a || echo __objdumpfailedti) | (! grep -w '__[a-z]\+ti[0-9]\?')
31 changes: 31 additions & 0 deletions tests/run-make-fulldeps/core-no-128-bit/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#![feature(no_core)]

#![no_std]
#![no_core] // supress compiler-builtins
extern crate core;
use core::prelude::rust_2021::*;
use core::fmt::Write;

// An empty file might be sufficient here, but since formatting is one of the
// features affected by no_128_bit it seems worth including some.

struct X(pub usize);
impl core::fmt::Write for X {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
self.0 += s.len();
Ok(())
}
}

#[no_mangle]
extern "C" fn demo() -> usize {
let mut x = X(0);
// Writes "i128 u128 foo" due to the removal of u/i128 formatting.
core::write!(x, "{:?} {:?} {}", i128::MAX, u128::MIN, "foo").unwrap();
x.0
}

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}

0 comments on commit 8122fb6

Please sign in to comment.