From edee1a2b152bfe2716fafa86105cdb3979be9055 Mon Sep 17 00:00:00 2001 From: Nicholas Mazzuca Date: Sat, 24 Oct 2015 18:29:35 -0700 Subject: [PATCH] Unchecked div/rem no longer generic Now they are [ui](8|16|32|64)_unchecked_(div|rem) --- src/libcore/intrinsics.rs | 69 ++++++++++++++++++++------ src/librustc_trans/trans/intrinsic.rs | 23 +++++++-- src/librustc_typeck/check/intrinsic.rs | 19 ++++++- 3 files changed, 91 insertions(+), 20 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 45b1c8a3599ca..ff1fac3305933 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -586,20 +586,6 @@ extern "rust-intrinsic" { /// Returns (a * b) mod 2^N, where N is the width of N in bits. pub fn overflowing_mul(a: T, b: T) -> T; - /// Performs an unchecked signed division, which results in undefined behavior, - /// in cases where y == 0, or x == isize::MIN and y == -1 - pub fn unchecked_sdiv(x: T, y: T) -> T; - /// Performs an unchecked unsigned division, which results in undefined behavior, - /// in cases where y == 0 - pub fn unchecked_udiv(x: T, y: T) -> T; - - /// Returns the remainder of an unchecked signed division, which results in - /// undefined behavior, in cases where y == 0, or x == isize::MIN and y == -1 - pub fn unchecked_srem(x: T, y: T) -> T; - /// Returns the remainder of an unchecked unsigned division, which results in - /// undefined behavior, in cases where y == 0 - pub fn unchecked_urem(x: T, y: T) -> T; - /// Returns the value of the discriminant for the variant in 'v', /// cast to a `u64`; if `T` has no discriminant, returns 0. pub fn discriminant_value(v: &T) -> u64; @@ -609,3 +595,58 @@ extern "rust-intrinsic" { /// is thrown (aka the thread panics). pub fn try(f: fn(*mut u8), data: *mut u8) -> *mut u8; } + +#[cfg(not(stage0))] +extern "rust-intrinsic" { + /// Performs an unchecked `i8` division, resulting in undefined behavior + /// where y = 0 or x = `std::i8::MIN` and y = -1 + pub fn i8_unchecked_div(x: i8, y: i8) -> i8; + /// Performs an unchecked `i16` division, resulting in undefined behavior + /// where y = 0 or x = `std::i16::MIN` and y = -1 + pub fn i16_unchecked_div(x: i16, y: i16) -> i16; + /// Performs an unchecked `i32` division, resulting in undefined behavior + /// where y = 0 or x = `std::i32::MIN` and y = -1 + pub fn i32_unchecked_div(x: i32, y: i32) -> i32; + /// Performs an unchecked `i64` division, resulting in undefined behavior + /// where y = 0 or x = `std::i64::MIN` and y = -1 + pub fn i64_unchecked_div(x: i64, y: i64) -> i64; + + /// Performs an unchecked `u8` division, resulting in undefined behavior + /// where y = 0 + pub fn u8_unchecked_div(x: u8, y: u8) -> u8; + /// Performs an unchecked `u16` division, resulting in undefined behavior + /// where y = 0 + pub fn u16_unchecked_div(x: u16, y: u16) -> u16; + /// Performs an unchecked `u32` division, resulting in undefined behavior + /// where y = 0 + pub fn u32_unchecked_div(x: u32, y: u32) -> u32; + /// Performs an unchecked `u64` division, resulting in undefined behavior + /// where y = 0 + pub fn u64_unchecked_div(x: u64, y: u64) -> u64; + + /// Returns the remainder of an unchecked `i8` division, resulting in + /// undefined behavior where y = 0 or x = `std::i8::MIN` and y = -1 + pub fn i8_unchecked_rem(x: i8, y: i8) -> i8; + /// Returns the remainder of an unchecked `i16` division, resulting in + /// undefined behavior where y = 0 or x = `std::i16::MIN` and y = -1 + pub fn i16_unchecked_rem(x: i16, y: i16) -> i16; + /// Returns the remainder of an unchecked `i32` division, resulting in + /// undefined behavior where y = 0 or x = `std::i32::MIN` and y = -1 + pub fn i32_unchecked_rem(x: i32, y: i32) -> i32; + /// Returns the remainder of an unchecked `i64` division, resulting in + /// undefined behavior where y = 0 or x = `std::i64::MIN` and y = -1 + pub fn i64_unchecked_rem(x: i64, y: i64) -> i64; + + /// Returns the remainder of an unchecked `u8` division, resulting in + /// undefined behavior where y = 0 + pub fn u8_unchecked_rem(x: u8, y: u8) -> u8; + /// Returns the remainder of an unchecked `u16` division, resulting in + /// undefined behavior where y = 0 + pub fn u16_unchecked_rem(x: u16, y: u16) -> u16; + /// Returns the remainder of an unchecked `u32` division, resulting in + /// undefined behavior where y = 0 + pub fn u32_unchecked_rem(x: u32, y: u32) -> u32; + /// Returns the remainder of an unchecked `u64` division, resulting in + /// undefined behavior where y = 0 + pub fn u64_unchecked_rem(x: u64, y: u64) -> u64; +} diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index a8d85ae17e2bb..b5362eeb572ae 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -792,10 +792,25 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, llresult, call_debug_location), - (_, "unchecked_udiv") => UDiv(bcx, llargs[0], llargs[1], call_debug_location), - (_, "unchecked_sdiv") => SDiv(bcx, llargs[0], llargs[1], call_debug_location), - (_, "unchecked_urem") => URem(bcx, llargs[0], llargs[1], call_debug_location), - (_, "unchecked_srem") => SRem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u8_unchecked_div") => UDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u16_unchecked_div") => UDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u32_unchecked_div") => UDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u64_unchecked_div") => UDiv(bcx, llargs[0], llargs[1], call_debug_location), + + (_, "i8_unchecked_div") => SDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i16_unchecked_div") => SDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i32_unchecked_div") => SDiv(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i64_unchecked_div") => SDiv(bcx, llargs[0], llargs[1], call_debug_location), + + (_, "u8_unchecked_rem") => URem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u16_unchecked_rem") => URem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u32_unchecked_rem") => URem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "u64_unchecked_rem") => URem(bcx, llargs[0], llargs[1], call_debug_location), + + (_, "i8_unchecked_rem") => SRem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i16_unchecked_rem") => SRem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i32_unchecked_rem") => SRem(bcx, llargs[0], llargs[1], call_debug_location), + (_, "i64_unchecked_rem") => SRem(bcx, llargs[0], llargs[1], call_debug_location), (_, "overflowing_add") => Add(bcx, llargs[0], llargs[1], call_debug_location), (_, "overflowing_sub") => Sub(bcx, llargs[0], llargs[1], call_debug_location), diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 4afc610f63ea5..6480dd7f5bb5d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -307,8 +307,23 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { (0, vec!(tcx.types.u64, tcx.types.u64), tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))), - "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" => - (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), + "i8_unchecked_div" | "i8_unchecked_rem" => + (0, vec![tcx.types.i8, tcx.types.i8], tcx.types.i8), + "i16_unchecked_div" | "i16_unchecked_rem" => + (0, vec![tcx.types.i16, tcx.types.i16], tcx.types.i16), + "i32_unchecked_div" | "i32_unchecked_rem" => + (0, vec![tcx.types.i32, tcx.types.i32], tcx.types.i32), + "i64_unchecked_div" | "i64_unchecked_rem" => + (0, vec![tcx.types.i64, tcx.types.i64], tcx.types.i64), + + "u8_unchecked_div" | "u8_unchecked_rem" => + (0, vec![tcx.types.u8, tcx.types.u8], tcx.types.u8), + "u16_unchecked_div" | "u16_unchecked_rem" => + (0, vec![tcx.types.u16, tcx.types.u16], tcx.types.u16), + "u32_unchecked_div" | "u32_unchecked_rem" => + (0, vec![tcx.types.u32, tcx.types.u32], tcx.types.u32), + "u64_unchecked_div" | "u64_unchecked_rem" => + (0, vec![tcx.types.u64, tcx.types.u64], tcx.types.u64), "overflowing_add" | "overflowing_sub" | "overflowing_mul" => (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),