From bf3ec3be3e595780d842ac3069bb07f3c50f54b8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 13 Jul 2019 16:55:08 +0200 Subject: [PATCH 01/26] Implement checked binops --- example/mini_core.rs | 48 +++++++++++++++++++++++ example/mini_core_hello_world.rs | 17 +++++++++ src/base.rs | 65 ++++++++++++++++++++++++++------ 3 files changed, 119 insertions(+), 11 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index d900776c5..8c372450a 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -128,6 +128,14 @@ impl Add for u8 { } } +impl Add for i8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + impl Add for usize { type Output = Self; @@ -151,6 +159,30 @@ impl Sub for usize { } } +impl Sub for u8 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for i8 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for i16 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + #[lang = "bitor"] pub trait BitOr { type Output; @@ -270,6 +302,22 @@ pub trait Neg { fn neg(self) -> Self::Output; } +impl Neg for i8 { + type Output = i8; + + fn neg(self) -> i8 { + -self + } +} + +impl Neg for i16 { + type Output = i16; + + fn neg(self) -> i16 { + -self + } +} + impl Neg for isize { type Output = isize; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index e51f257f6..15f0442b6 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -236,4 +236,21 @@ fn main() { unsafe { assert_eq!(ABC as usize, 0); } &mut (|| Some(0 as *const ())) as &mut FnMut() -> Option<*const ()>; + + // checked binops + let zeroi8 = 0i8; + let oneu8 = 1u8; + let onei8 = 1i8; + zeroi8 - 1; + oneu8 - 1; + zeroi8 - -2i8; + #[allow(unreachable_code)] + { + if false { + let minustwoi8 = -2i8; + oneu8 + 255; + onei8 + 127; + minustwoi8 - 127; + } + } } diff --git a/src/base.rs b/src/base.rs index 1adcec046..7b29d15e5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -241,7 +241,7 @@ fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>) } else { fx.bcx.ins().brz(cond, target, &[]); }; - trap_panic(fx, format!("[panic] Assert {:?} failed.", msg)); + trap_panic(fx, format!("[panic] Assert {:?} failed at {:?}.", msg, bb_data.terminator().source_info.span)); } TerminatorKind::SwitchInt { @@ -948,17 +948,62 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - let res = match bin_op { - BinOp::Add => fx.bcx.ins().iadd(lhs, rhs), - BinOp::Sub => fx.bcx.ins().isub(lhs, rhs), - BinOp::Mul => fx.bcx.ins().imul(lhs, rhs), - BinOp::Shl => fx.bcx.ins().ishl(lhs, rhs), + let (res, has_overflow) = match bin_op { + BinOp::Add => { + /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); + (val, c_out)*/ + // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16 + let val = fx.bcx.ins().iadd(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedLessThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let slt = fx.bcx.ins().icmp(IntCC::SignedLessThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, slt) + }; + (val, has_overflow) + } + BinOp::Sub => { + /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs); + (val, b_out)*/ + // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16 + let val = fx.bcx.ins().isub(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let sgt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, sgt) + }; + (val, has_overflow) + } + BinOp::Mul => { + let val = fx.bcx.ins().imul(lhs, rhs); + /*let val_hi = if !signed { + fx.bcx.ins().umulhi(lhs, rhs) + } else { + fx.bcx.ins().smulhi(lhs, rhs) + }; + let has_overflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, val_hi, 0);*/ + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + BinOp::Shl => { + let val = fx.bcx.ins().ishl(lhs, rhs); + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } BinOp::Shr => { - if !signed { + let val = if !signed { fx.bcx.ins().ushr(lhs, rhs) } else { fx.bcx.ins().sshr(lhs, rhs) - } + }; + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) } _ => bug!( "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", @@ -968,9 +1013,7 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>( ), }; - // TODO: check for overflow - let has_overflow = fx.bcx.ins().iconst(types::I8, 0); - + let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow); let out_place = CPlace::new_stack_slot(fx, out_ty); let out_layout = out_place.layout(); out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout)); From de32ddad23abbc831ae60d5efefab0df84e8910b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 12 Jun 2019 20:54:38 +0200 Subject: [PATCH 02/26] [WIP] Basic i128 support --- Cargo.lock | 60 +++++-------- Cargo.toml | 10 +-- example/mini_core.rs | 8 ++ example/mini_core_hello_world.rs | 136 +---------------------------- src/abi.rs | 2 +- src/base.rs | 145 ++++++++++++++++++------------- src/common.rs | 4 +- src/value_and_place.rs | 28 ++++-- 8 files changed, 144 insertions(+), 249 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e9f0955a..675210800 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,28 +117,25 @@ dependencies = [ [[package]] name = "cranelift" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-frontend 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", + "cranelift-frontend 0.36.0", ] [[package]] name = "cranelift-bforest" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-entity 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-entity 0.36.0", ] [[package]] name = "cranelift-codegen" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-bforest 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-codegen-meta 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-entity 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-bforest 0.36.0", + "cranelift-codegen-meta 0.36.0", + "cranelift-entity 0.36.0", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -148,23 +145,20 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-entity 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-entity 0.36.0", ] [[package]] name = "cranelift-entity" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" [[package]] name = "cranelift-faerie" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-module 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", + "cranelift-module 0.36.0", "faerie 0.10.1 (git+https://github.com/m4b/faerie.git)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -174,9 +168,8 @@ dependencies = [ [[package]] name = "cranelift-frontend" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -184,10 +177,9 @@ dependencies = [ [[package]] name = "cranelift-module" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-entity 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", + "cranelift-entity 0.36.0", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -195,9 +187,8 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -205,11 +196,10 @@ dependencies = [ [[package]] name = "cranelift-simplejit" version = "0.36.0" -source = "git+https://github.com/CraneStation/cranelift.git#e7f2b719eebfb9280c3e38eae42a9ee25221a4e3" dependencies = [ - "cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-module 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-native 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-codegen 0.36.0", + "cranelift-module 0.36.0", + "cranelift-native 0.36.0", "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -611,10 +601,10 @@ dependencies = [ "ar 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-faerie 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-module 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", - "cranelift-simplejit 0.36.0 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift 0.36.0", + "cranelift-faerie 0.36.0", + "cranelift-module 0.36.0", + "cranelift-simplejit 0.36.0", "faerie 0.10.1 (git+https://github.com/m4b/faerie.git)", "gimli 0.19.0 (git+https://github.com/gimli-rs/gimli.git)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -882,16 +872,6 @@ dependencies = [ "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum cranelift 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-bforest 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-codegen 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-codegen-meta 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-entity 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-faerie 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-frontend 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-module 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-native 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-simplejit 0.36.0 (git+https://github.com/CraneStation/cranelift.git)" = "" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" diff --git a/Cargo.toml b/Cargo.toml index 59d66d07f..64126d917 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,11 +28,11 @@ indexmap = "1.0.2" object = "0.12.0" # Uncomment to use local checkout of cranelift -#[patch."https://github.com/CraneStation/cranelift.git"] -#cranelift = { path = "../cranelift/cranelift-umbrella" } -#cranelift-module = { path = "../cranelift/cranelift-module" } -#cranelift-simplejit = { path = "../cranelift/cranelift-simplejit" } -#cranelift-faerie = { path = "../cranelift/cranelift-faerie" } +[patch."https://github.com/CraneStation/cranelift.git"] +cranelift = { path = "../cranelift/cranelift-umbrella" } +cranelift-module = { path = "../cranelift/cranelift-module" } +cranelift-simplejit = { path = "../cranelift/cranelift-simplejit" } +cranelift-faerie = { path = "../cranelift/cranelift-faerie" } #[patch."https://github.com/gimli-rs/gimli.git"] #gimli = { path = "../" } diff --git a/example/mini_core.rs b/example/mini_core.rs index 8c372450a..745e86de4 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -144,6 +144,14 @@ impl Add for usize { } } +impl Add for u128 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + #[lang = "sub"] pub trait Sub { type Output; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 15f0442b6..23a92c737 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -118,139 +118,5 @@ fn take_f32(_f: f32) {} fn take_unique(_u: Unique<()>) {} fn main() { - take_unique(Unique { - pointer: 0 as *const (), - _marker: PhantomData, - }); - take_f32(0.1); - - //return; - - unsafe { - printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8); - - let hello: &[u8] = b"Hello\0" as &[u8; 6]; - let ptr: *const u8 = hello as *const [u8] as *const u8; - puts(ptr); - - let world: Box<&str> = box "World!\0"; - puts(*world as *const str as *const u8); - world as Box; - - assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8); - - assert_eq!(intrinsics::bswap(0xabu8), 0xabu8); - assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16); - assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32); - assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64); - - assert_eq!(intrinsics::size_of_val(hello) as u8, 6); - - let chars = &['C', 'h', 'a', 'r', 's']; - let chars = chars as &[char]; - assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5); - - let a: &dyn SomeTrait = &"abc\0"; - a.object_safe(); - - assert_eq!(intrinsics::size_of_val(a) as u8, 16); - assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); - - assert_eq!(intrinsics::min_align_of::() as u8, 2); - assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); - - assert!(!intrinsics::needs_drop::()); - assert!(intrinsics::needs_drop::()); - - Unique { - pointer: 0 as *const &str, - _marker: PhantomData, - } as Unique; - - struct MyDst(T); - - intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>); - - struct Foo { - x: u8, - y: !, - } - - unsafe fn zeroed() -> T { - intrinsics::init::() - } - - unsafe fn uninitialized() -> T { - MaybeUninit { uninit: () }.value - } - - zeroed::<(u8, u8)>(); - #[allow(unreachable_code)] - { - if false { - zeroed::(); - zeroed::(); - uninitialized::(); - } - } - } - - let _ = box NoisyDrop { - text: "Boxed outer got dropped!\0", - inner: NoisyDropInner, - } as Box; - - const FUNC_REF: Option = Some(main); - match FUNC_REF { - Some(_) => {}, - None => assert!(false), - } - - match Ordering::Less { - Ordering::Less => {}, - _ => assert!(false), - } - - [NoisyDropInner, NoisyDropInner]; - - let x = &[0u32, 42u32] as &[u32]; - match x { - [] => assert_eq!(0u32, 1), - [_, ref y..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), - } - - assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); - - extern { - #[linkage = "weak"] - static ABC: *const u8; - } - - { - extern { - #[linkage = "weak"] - static ABC: *const u8; - } - } - - unsafe { assert_eq!(ABC as usize, 0); } - - &mut (|| Some(0 as *const ())) as &mut FnMut() -> Option<*const ()>; - - // checked binops - let zeroi8 = 0i8; - let oneu8 = 1u8; - let onei8 = 1i8; - zeroi8 - 1; - oneu8 - 1; - zeroi8 - -2i8; - #[allow(unreachable_code)] - { - if false { - let minustwoi8 = -2i8; - oneu8 + 255; - onei8 + 127; - minustwoi8 - 127; - } - } + assert_eq!((1u128 + 2) as u16, 3); } diff --git a/src/abi.rs b/src/abi.rs index 2397da9be..b7e7d0a83 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -87,7 +87,7 @@ pub fn scalar_to_clif_type(tcx: TyCtxt, scalar: Scalar) -> Type { Integer::I16 => types::I16, Integer::I32 => types::I32, Integer::I64 => types::I64, - Integer::I128 => unimpl!("u/i128"), + Integer::I128 => types::I128, }, Primitive::Float(flt) => match flt { FloatTy::F32 => types::F32, diff --git a/src/base.rs b/src/base.rs index 7b29d15e5..f8bd56723 100644 --- a/src/base.rs +++ b/src/base.rs @@ -899,6 +899,19 @@ pub fn trans_int_binop<'a, 'tcx: 'a>( "int binop requires lhs and rhs of same type" ); } + + if out_ty == fx.tcx.types.u128 || out_ty == fx.tcx.types.i128 { + return match (bin_op, signed) { + _ => { + let layout = fx.layout_of(out_ty); + let a = fx.bcx.ins().iconst(types::I64, 42); + let b = fx.bcx.ins().iconst(types::I64, 0); + let val = fx.bcx.ins().iconcat(a, b); + CValue::by_val(val, layout) + } + } + } + binop_match! { fx, bin_op, signed, lhs, rhs, out_ty, "int/uint"; Add (_) iadd; @@ -948,69 +961,79 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - let (res, has_overflow) = match bin_op { - BinOp::Add => { - /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); - (val, c_out)*/ - // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16 - let val = fx.bcx.ins().iadd(lhs, rhs); - let has_overflow = if !signed { - fx.bcx.ins().icmp(IntCC::UnsignedLessThan, val, lhs) - } else { - let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); - let slt = fx.bcx.ins().icmp(IntCC::SignedLessThan, val, lhs); - fx.bcx.ins().bxor(rhs_is_negative, slt) - }; - (val, has_overflow) - } - BinOp::Sub => { - /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs); - (val, b_out)*/ - // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16 - let val = fx.bcx.ins().isub(lhs, rhs); - let has_overflow = if !signed { - fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, val, lhs) - } else { - let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); - let sgt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, val, lhs); - fx.bcx.ins().bxor(rhs_is_negative, sgt) - }; - (val, has_overflow) - } - BinOp::Mul => { - let val = fx.bcx.ins().imul(lhs, rhs); - /*let val_hi = if !signed { - fx.bcx.ins().umulhi(lhs, rhs) - } else { - fx.bcx.ins().smulhi(lhs, rhs) - }; - let has_overflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, val_hi, 0);*/ - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) - } - BinOp::Shl => { - let val = fx.bcx.ins().ishl(lhs, rhs); - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) + let (res, has_overflow) = if in_lhs.layout().ty == fx.tcx.types.u128 || in_lhs.layout().ty == fx.tcx.types.i128 { + match (bin_op, signed) { + _ => { + let a = fx.bcx.ins().iconst(types::I64, 42); + let b = fx.bcx.ins().iconst(types::I64, 0); + (fx.bcx.ins().iconcat(a, b), fx.bcx.ins().bconst(types::B1, false)) + } } - BinOp::Shr => { - let val = if !signed { - fx.bcx.ins().ushr(lhs, rhs) - } else { - fx.bcx.ins().sshr(lhs, rhs) - }; - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) + } else { + match bin_op { + BinOp::Add => { + /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); + (val, c_out)*/ + // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16 + let val = fx.bcx.ins().iadd(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedLessThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let slt = fx.bcx.ins().icmp(IntCC::SignedLessThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, slt) + }; + (val, has_overflow) + } + BinOp::Sub => { + /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs); + (val, b_out)*/ + // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16 + let val = fx.bcx.ins().isub(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let sgt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, sgt) + }; + (val, has_overflow) + } + BinOp::Mul => { + let val = fx.bcx.ins().imul(lhs, rhs); + /*let val_hi = if !signed { + fx.bcx.ins().umulhi(lhs, rhs) + } else { + fx.bcx.ins().smulhi(lhs, rhs) + }; + let has_overflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, val_hi, 0);*/ + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + BinOp::Shl => { + let val = fx.bcx.ins().ishl(lhs, rhs); + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + BinOp::Shr => { + let val = if !signed { + fx.bcx.ins().ushr(lhs, rhs) + } else { + fx.bcx.ins().sshr(lhs, rhs) + }; + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + _ => bug!( + "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", + bin_op, + in_lhs, + in_rhs + ), } - _ => bug!( - "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", - bin_op, - in_lhs, - in_rhs - ), }; let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow); diff --git a/src/common.rs b/src/common.rs index bffa526c8..30f343d02 100644 --- a/src/common.rs +++ b/src/common.rs @@ -28,7 +28,7 @@ pub fn clif_type_from_ty<'tcx>( UintTy::U16 => types::I16, UintTy::U32 => types::I32, UintTy::U64 => types::I64, - UintTy::U128 => unimpl!("u128"), + UintTy::U128 => types::I128, UintTy::Usize => pointer_ty(tcx), }, ty::Int(size) => match size { @@ -36,7 +36,7 @@ pub fn clif_type_from_ty<'tcx>( IntTy::I16 => types::I16, IntTy::I32 => types::I32, IntTy::I64 => types::I64, - IntTy::I128 => unimpl!("i128"), + IntTy::I128 => types::I128, IntTy::Isize => pointer_ty(tcx), }, ty::Char => types::I32, diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 716a81c5d..6bd82265b 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -34,6 +34,16 @@ enum CValueInner { ByValPair(Value, Value), } +fn store_scalar<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>, value: Value, addr: Value, offset: i32) { + if fx.bcx.func.dfg.value_type(value) == types::I128 { + let (a, b) = fx.bcx.ins().isplit(value); + fx.bcx.ins().store(MemFlags::new(), a, addr, offset); + fx.bcx.ins().store(MemFlags::new(), b, addr, offset + 8); + } else { + fx.bcx.ins().store(MemFlags::new(), value, addr, offset); + } +} + impl<'tcx> CValue<'tcx> { pub fn by_ref(value: Value, layout: TyLayout<'tcx>) -> CValue<'tcx> { CValue(CValueInner::ByRef(value), layout) @@ -147,7 +157,15 @@ impl<'tcx> CValue<'tcx> { { let clif_ty = fx.clif_type(ty).unwrap(); let layout = fx.layout_of(ty); - CValue::by_val(fx.bcx.ins().iconst(clif_ty, const_val), layout) + let val = if clif_ty == types::I128 { + // FIXME don't assume little-endian arch + let lsb = fx.bcx.ins().iconst(types::I64, const_val); + let msb = fx.bcx.ins().iconst(types::I64, 0); + fx.bcx.ins().iconcat(lsb, msb) + } else { + fx.bcx.ins().iconst(clif_ty, const_val) + }; + CValue::by_val(val, layout) } pub fn unchecked_cast_to(self, layout: TyLayout<'tcx>) -> Self { @@ -343,15 +361,15 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> { match from.0 { CValueInner::ByVal(val) => { - fx.bcx.ins().store(MemFlags::new(), val, addr, 0); + store_scalar(fx, val, addr, 0); } CValueInner::ByValPair(value, extra) => { match dst_layout.abi { Abi::ScalarPair(ref a_scalar, ref b_scalar) => { let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); - fx.bcx.ins().store(MemFlags::new(), value, addr, 0); - fx.bcx.ins().store( - MemFlags::new(), + store_scalar(fx, value, addr, 0); + store_scalar( + fx, extra, addr, b_offset, From d629d97f25d02d59144b3d2de144022bff9e3151 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 17 Jun 2019 21:13:02 +0200 Subject: [PATCH 03/26] Fix some things --- src/common.rs | 3 +++ src/value_and_place.rs | 23 +++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/common.rs b/src/common.rs index 30f343d02..810744527 100644 --- a/src/common.rs +++ b/src/common.rs @@ -88,6 +88,9 @@ pub fn clif_intcast<'a, 'tcx: 'a>( } else { fx.bcx.ins().uextend(to, val) } + } else if from == types::I128 { + let (lsb, msb) = fx.bcx.ins().isplit(val); + fx.bcx.ins().ireduce(to, lsb) } else { fx.bcx.ins().ireduce(to, val) } diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 6bd82265b..3589d7705 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -44,6 +44,21 @@ fn store_scalar<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>, value } } +fn load_scalar<'a, 'tcx: 'a>( + fx: &mut FunctionCx<'a, 'tcx, impl Backend>, + clif_ty: Type, + addr: Value, + offset: i32, +) -> Value { + if clif_ty == types::I128 { + let a = fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset); + let b = fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset + 8); + fx.bcx.ins().iconcat(a, b) + } else { + fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset) + } +} + impl<'tcx> CValue<'tcx> { pub fn by_ref(value: Value, layout: TyLayout<'tcx>) -> CValue<'tcx> { CValue(CValueInner::ByRef(value), layout) @@ -89,7 +104,7 @@ impl<'tcx> CValue<'tcx> { _ => unreachable!(), }; let clif_ty = scalar_to_clif_type(fx.tcx, scalar); - fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, 0) + load_scalar(fx, clif_ty, addr, 0) } CValueInner::ByVal(value) => value, CValueInner::ByValPair(_, _) => bug!("Please use load_scalar_pair for ByValPair"), @@ -111,10 +126,10 @@ impl<'tcx> CValue<'tcx> { let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone()); let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar.clone()); - let val1 = fx.bcx.ins().load(clif_ty1, MemFlags::new(), addr, 0); - let val2 = fx.bcx.ins().load( + let val1 = load_scalar(fx, clif_ty1, addr, 0); + let val2 = load_scalar( + fx, clif_ty2, - MemFlags::new(), addr, b_offset, ); From 596fdd5a6463d55d8dedd202c41a6392eca2c4c8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 17 Jun 2019 21:19:08 +0200 Subject: [PATCH 04/26] Fix type in load_scalar --- src/intrinsics.rs | 2 +- src/value_and_place.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 08a829ff1..792d7c993 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -103,7 +103,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( // Insert non returning intrinsics here match intrinsic { "abort" => { - trap_panic(fx, "Called intrinisc::abort."); + trap_panic(fx, "Called intrinsic::abort."); } "unreachable" => { trap_unreachable(fx, "[corruption] Called intrinsic::unreachable."); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 3589d7705..8b5c764f6 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -51,8 +51,8 @@ fn load_scalar<'a, 'tcx: 'a>( offset: i32, ) -> Value { if clif_ty == types::I128 { - let a = fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset); - let b = fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset + 8); + let a = fx.bcx.ins().load(types::I64, MemFlags::new(), addr, offset); + let b = fx.bcx.ins().load(types::I64, MemFlags::new(), addr, offset + 8); fx.bcx.ins().iconcat(a, b) } else { fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset) From c814ee0d2a7b9f67cf2be6a6488d07105606c64c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 27 Jun 2019 20:49:39 +0200 Subject: [PATCH 05/26] [WIP] --- build_sysroot/Cargo.toml | 2 +- example/mini_core_hello_world.rs | 2 +- example/std_example.rs | 27 +--------- src/base.rs | 89 +++----------------------------- src/common.rs | 11 +++- 5 files changed, 20 insertions(+), 111 deletions(-) diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index 45484027e..532216ba8 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -14,7 +14,7 @@ alloc_system = { path = "./alloc_system" } [patch.crates-io] rustc-std-workspace-core = { path = "./sysroot_src/src/tools/rustc-std-workspace-core" } rustc-std-workspace-alloc = { path = "./rustc-std-workspace-alloc" } -compiler_builtins = { path = "./compiler_builtins" } +#compiler_builtins = { path = "./compiler_builtins" } [profile.release] debug = true diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 23a92c737..d435e3470 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -118,5 +118,5 @@ fn take_f32(_f: f32) {} fn take_unique(_u: Unique<()>) {} fn main() { - assert_eq!((1u128 + 2) as u16, 3); + } diff --git a/example/std_example.rs b/example/std_example.rs index 98d9ed17b..ae77616a8 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -3,32 +3,7 @@ use std::io::Write; fn main() { - let _ = ::std::iter::repeat('a' as u8).take(10).collect::>(); - let stderr = ::std::io::stderr(); - let mut stderr = stderr.lock(); - - writeln!(stderr, "some {} text", "").unwrap(); - - let _ = std::process::Command::new("true").env("c", "d").spawn(); - - println!("cargo:rustc-link-lib=z"); - - static ONCE: std::sync::Once = std::sync::ONCE_INIT; - ONCE.call_once(|| {}); - - LoopState::Continue(()) == LoopState::Break(()); - - // Make sure ByValPair values with differently sized components are correctly passed - map(None::<(u8, Box)>); - - println!("{}", 2.3f32.exp()); - println!("{}", 2.3f32.exp2()); - println!("{}", 2.3f32.abs()); - println!("{}", 2.3f32.sqrt()); - println!("{}", 2.3f32.floor()); - println!("{}", 2.3f32.ceil()); - println!("{}", 2.3f32.min(1.0)); - println!("{}", 2.3f32.max(1.0)); + assert_eq!((1u128 + 2) as u16, 3); } #[derive(PartialEq)] diff --git a/src/base.rs b/src/base.rs index f8bd56723..7163c0949 100644 --- a/src/base.rs +++ b/src/base.rs @@ -11,83 +11,6 @@ pub fn trans_fn<'a, 'clif, 'tcx: 'a, B: Backend + 'static>( let mir = tcx.instance_mir(instance.def); - // Check fn sig for u128 and i128 and replace those functions with a trap. - { - // FIXME implement u128 and i128 support - - // Check sig for u128 and i128 - let fn_sig = tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &instance.fn_sig(tcx)); - - struct UI128Visitor<'tcx>(TyCtxt<'tcx>, bool); - - impl<'tcx> rustc::ty::fold::TypeVisitor<'tcx> for UI128Visitor<'tcx> { - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - if t.sty == self.0.types.u128.sty || t.sty == self.0.types.i128.sty { - self.1 = true; - return false; // stop visiting - } - - t.super_visit_with(self) - } - } - - let mut visitor = UI128Visitor(tcx, false); - fn_sig.visit_with(&mut visitor); - - //If found replace function with a trap. - if visitor.1 { - tcx.sess.warn("u128 and i128 are not yet supported. \ - Functions using these as args will be replaced with a trap."); - - // Declare function with fake signature - let sig = Signature { - params: vec![AbiParam::new(types::INVALID)], - returns: vec![], - call_conv: CallConv::Fast, - }; - let name = tcx.symbol_name(instance).as_str(); - let func_id = cx.module.declare_function(&*name, linkage, &sig).unwrap(); - - // Create trapping function - let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig); - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut func, &mut func_ctx); - let start_ebb = bcx.create_ebb(); - bcx.append_ebb_params_for_function_params(start_ebb); - bcx.switch_to_block(start_ebb); - - let mut fx = FunctionCx { - tcx, - module: cx.module, - pointer_type: pointer_ty(tcx), - - instance, - mir, - - bcx, - ebb_map: HashMap::new(), - local_map: HashMap::new(), - - clif_comments: crate::pretty_clif::CommentWriter::new(tcx, instance), - constants: &mut cx.ccx, - caches: &mut cx.caches, - source_info_set: indexmap::IndexSet::new(), - }; - - crate::trap::trap_unreachable(&mut fx, "[unimplemented] Called function with u128 or i128 as argument."); - fx.bcx.seal_all_blocks(); - fx.bcx.finalize(); - - // Define function - cx.caches.context.func = func; - cx.module - .define_function(func_id, &mut cx.caches.context) - .unwrap(); - cx.caches.context.clear(); - return; - } - } - // Declare function let (name, sig) = get_function_name_and_sig(tcx, instance, false); let func_id = cx.module.declare_function(&name, linkage, &sig).unwrap(); @@ -391,7 +314,7 @@ fn trans_stmt<'a, 'tcx: 'a>( let rhs = trans_operand(fx, rhs); let res = match ty.sty { - ty::Bool => trans_bool_binop(fx, *bin_op, lhs, rhs, lval.layout().ty), + ty::Bool => trans_bool_binop(fx, *bin_op, lhs, rhs), ty::Uint(_) => { trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, false) } @@ -666,7 +589,7 @@ fn trans_stmt<'a, 'tcx: 'a>( clobbers, // Vec volatile, // bool alignstack, // bool - dialect, // syntax::ast::AsmDialect + dialect: _, // syntax::ast::AsmDialect asm_str_style: _, ctxt: _, } = asm; @@ -705,6 +628,9 @@ fn trans_stmt<'a, 'tcx: 'a>( crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported"); } + _ if fx.tcx.symbol_name(fx.instance).as_str() == "__rust_probestack" => { + crate::trap::trap_unimplemented(fx, "__rust_probestack is not supported"); + } _ => unimpl!("Inline assembly is not supported"), } } @@ -856,10 +782,9 @@ fn trans_bool_binop<'a, 'tcx: 'a>( bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, - ty: Ty<'tcx>, ) -> CValue<'tcx> { let res = binop_match! { - fx, bin_op, false, lhs, rhs, ty, "bool"; + fx, bin_op, false, lhs, rhs, fx.tcx.types.bool, "bool"; Add (_) bug; Sub (_) bug; Mul (_) bug; @@ -900,7 +825,7 @@ pub fn trans_int_binop<'a, 'tcx: 'a>( ); } - if out_ty == fx.tcx.types.u128 || out_ty == fx.tcx.types.i128 { + if lhs.layout().ty == fx.tcx.types.u128 || lhs.layout().ty == fx.tcx.types.i128 { return match (bin_op, signed) { _ => { let layout = fx.layout_of(out_ty); diff --git a/src/common.rs b/src/common.rs index 810744527..57794a66b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -82,6 +82,15 @@ pub fn clif_intcast<'a, 'tcx: 'a>( if from == to { return val; } + if to == types::I128 { + let wider = if signed { + fx.bcx.ins().sextend(types::I64, val) + } else { + fx.bcx.ins().uextend(types::I64, val) + }; + let zero = fx.bcx.ins().iconst(types::I64, 0); + return fx.bcx.ins().iconcat(wider, zero); + } if to.wider_or_equal(from) { if signed { fx.bcx.ins().sextend(to, val) @@ -89,7 +98,7 @@ pub fn clif_intcast<'a, 'tcx: 'a>( fx.bcx.ins().uextend(to, val) } } else if from == types::I128 { - let (lsb, msb) = fx.bcx.ins().isplit(val); + let (lsb, _msb) = fx.bcx.ins().isplit(val); fx.bcx.ins().ireduce(to, lsb) } else { fx.bcx.ins().ireduce(to, val) From 79f4c3d002c1265220d2b39b74a7b4b37b6e2f54 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 27 Jun 2019 20:53:21 +0200 Subject: [PATCH 06/26] [WIP] --- src/base.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/base.rs b/src/base.rs index 7163c0949..7720296cf 100644 --- a/src/base.rs +++ b/src/base.rs @@ -826,14 +826,16 @@ pub fn trans_int_binop<'a, 'tcx: 'a>( } if lhs.layout().ty == fx.tcx.types.u128 || lhs.layout().ty == fx.tcx.types.i128 { - return match (bin_op, signed) { - _ => { - let layout = fx.layout_of(out_ty); - let a = fx.bcx.ins().iconst(types::I64, 42); - let b = fx.bcx.ins().iconst(types::I64, 0); - let val = fx.bcx.ins().iconcat(a, b); - CValue::by_val(val, layout) - } + if out_ty == fx.tcx.types.bool { + let layout = fx.layout_of(fx.tcx.types.bool); + let val = fx.bcx.ins().iconst(types::I8, 0); + return CValue::by_val(val, layout); + } else { + let layout = fx.layout_of(out_ty); + let a = fx.bcx.ins().iconst(types::I64, 42); + let b = fx.bcx.ins().iconst(types::I64, 0); + let val = fx.bcx.ins().iconcat(a, b); + return CValue::by_val(val, layout); } } From 45de0336a5ca03834f74189af6682462d874f980 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 29 Jun 2019 16:43:20 +0200 Subject: [PATCH 07/26] Fix some more stuff --- example/mini_core.rs | 28 +++++++++++++++++ example/mini_core_hello_world.rs | 18 ++++++++++- src/base.rs | 19 +++++++++-- src/common.rs | 54 +++++++++++++++++++++----------- src/intrinsics.rs | 26 +++++++++++++-- 5 files changed, 120 insertions(+), 25 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 745e86de4..fa47831b6 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -44,10 +44,12 @@ unsafe impl Copy for u8 {} unsafe impl Copy for u16 {} unsafe impl Copy for u32 {} unsafe impl Copy for u64 {} +unsafe impl Copy for u128 {} unsafe impl Copy for usize {} unsafe impl Copy for i8 {} unsafe impl Copy for i16 {} unsafe impl Copy for i32 {} +unsafe impl Copy for i128 {} unsafe impl Copy for isize {} unsafe impl Copy for char {} unsafe impl<'a, T: ?Sized> Copy for &'a T {} @@ -152,6 +154,14 @@ impl Add for u128 { } } +impl Add for i128 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + #[lang = "sub"] pub trait Sub { type Output; @@ -276,6 +286,15 @@ impl PartialEq for i32 { } } +impl PartialEq for i128 { + fn eq(&self, other: &i128) -> bool { + (*self) == (*other) + } + fn ne(&self, other: &i128) -> bool { + (*self) != (*other) + } +} + impl PartialEq for isize { fn eq(&self, other: &isize) -> bool { (*self) == (*other) @@ -322,6 +341,14 @@ impl Neg for i16 { type Output = i16; fn neg(self) -> i16 { + self + } +} + +impl Neg for i128 { + type Output = i128; + + fn neg(self) -> i128 { -self } } @@ -446,6 +473,7 @@ pub mod intrinsics { pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; + pub fn unchecked_div(lhs: T, rhs: T) -> T; } } diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index d435e3470..4a26577af 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -117,6 +117,22 @@ impl CoerceUnsized> for Unique where T: Unsiz fn take_f32(_f: f32) {} fn take_unique(_u: Unique<()>) {} -fn main() { +fn checked_div_i128(lhs: i128, rhs: i128) -> Option { + if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) { + None + } else { + Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) + } +} +fn checked_div_u128(lhs: u128, rhs: u128) -> Option { + match rhs { + 0 => None, + rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) + } +} + +fn main() { + checked_div_i128(0i128, 2i128); + checked_div_u128(0u128, 2u128); } diff --git a/src/base.rs b/src/base.rs index 7720296cf..94ba93de1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -357,15 +357,28 @@ fn trans_stmt<'a, 'tcx: 'a>( let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0); fx.bcx.ins().bint(types::I8, res) } - ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val), + ty::Uint(_) | ty::Int(_) => { + if fx.bcx.func.dfg.value_type(val) == types::I128 { + let (a, b) = fx.bcx.ins().isplit(val); + let a = fx.bcx.ins().bnot(a); + let b = fx.bcx.ins().bnot(b); + fx.bcx.ins().iconcat(a, b) + } else { + fx.bcx.ins().bnot(val) + } + } _ => unimplemented!("un op Not for {:?}", layout.ty), } } UnOp::Neg => match layout.ty.sty { ty::Int(_) => { let clif_ty = fx.clif_type(layout.ty).unwrap(); - let zero = fx.bcx.ins().iconst(clif_ty, 0); - fx.bcx.ins().isub(zero, val) + if clif_ty == types::I128 { + crate::trap::trap_unreachable_ret_value(fx, layout, "i128 neg is not yet supported").load_scalar(fx) + } else { + let zero = fx.bcx.ins().iconst(clif_ty, 0); + fx.bcx.ins().isub(zero, val) + } } ty::Float(_) => fx.bcx.ins().fneg(val), _ => unimplemented!("un op Neg for {:?}", layout.ty), diff --git a/src/common.rs b/src/common.rs index 57794a66b..6c9077204 100644 --- a/src/common.rs +++ b/src/common.rs @@ -82,26 +82,42 @@ pub fn clif_intcast<'a, 'tcx: 'a>( if from == to { return val; } - if to == types::I128 { - let wider = if signed { - fx.bcx.ins().sextend(types::I64, val) - } else { - fx.bcx.ins().uextend(types::I64, val) - }; - let zero = fx.bcx.ins().iconst(types::I64, 0); - return fx.bcx.ins().iconcat(wider, zero); - } - if to.wider_or_equal(from) { - if signed { - fx.bcx.ins().sextend(to, val) - } else { - fx.bcx.ins().uextend(to, val) + match (from, to) { + // equal + (_, _) if from == to => val, + + // extend + (_, types::I128) => { + let wider = if from == types::I64 { + val + } else if signed { + fx.bcx.ins().sextend(types::I64, val) + } else { + fx.bcx.ins().uextend(types::I64, val) + }; + let zero = fx.bcx.ins().iconst(types::I64, 0); + fx.bcx.ins().iconcat(wider, zero) + } + (_, _) if to.wider_or_equal(from) => { + if signed { + fx.bcx.ins().sextend(to, val) + } else { + fx.bcx.ins().uextend(to, val) + } + } + + // reduce + (types::I128, _) => { + let (lsb, _msb) = fx.bcx.ins().isplit(val); + if to == types::I64 { + lsb + } else { + fx.bcx.ins().ireduce(to, lsb) + } + } + (_, _) => { + fx.bcx.ins().ireduce(to, val) } - } else if from == types::I128 { - let (lsb, _msb) = fx.bcx.ins().isplit(val); - fx.bcx.ins().ireduce(to, lsb) - } else { - fx.bcx.ins().ireduce(to, val) } } diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 792d7c993..aaf462217 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -390,11 +390,33 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count); }; ctlz | ctlz_nonzero, (v arg) { - let res = CValue::by_val(fx.bcx.ins().clz(arg), fx.layout_of(T)); + let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 { + // FIXME verify this algorithm is correct + let (lsb, msb) = fx.bcx.ins().isplit(arg); + let lsb_lz = fx.bcx.ins().clz(lsb); + let msb_lz = fx.bcx.ins().clz(msb); + let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64); + let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64); + fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz) + } else { + fx.bcx.ins().clz(arg) + }; + let res = CValue::by_val(res, fx.layout_of(T)); ret.write_cvalue(fx, res); }; cttz | cttz_nonzero, (v arg) { - let res = CValue::by_val(fx.bcx.ins().ctz(arg), fx.layout_of(T)); + let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 { + // FIXME verify this algorithm is correct + let (lsb, msb) = fx.bcx.ins().isplit(arg); + let lsb_tz = fx.bcx.ins().ctz(lsb); + let msb_tz = fx.bcx.ins().ctz(msb); + let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64); + let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64); + fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz) + } else { + fx.bcx.ins().ctz(arg) + }; + let res = CValue::by_val(res, fx.layout_of(T)); ret.write_cvalue(fx, res); }; ctpop, (v arg) { From d8cae099d0ec6c2db802f1cb6ee392ed117910dc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 29 Jun 2019 16:53:20 +0200 Subject: [PATCH 08/26] Fix it --- src/intrinsics.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/intrinsics.rs b/src/intrinsics.rs index aaf462217..f521a07d9 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -494,7 +494,13 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( let or_tmp6 = bcx.ins().bor(or_tmp3, or_tmp4); bcx.ins().bor(or_tmp5, or_tmp6) } - ty => unimplemented!("bwap {}", ty), + types::I128 => { + let (lo, hi) = bcx.ins().isplit(v); + let lo = swap(bcx, lo); + let hi = swap(bcx, hi); + bcx.ins().iconcat(hi, lo) + } + ty => unimplemented!("bswap {}", ty), } }; let res = CValue::by_val(swap(&mut fx.bcx, arg), fx.layout_of(T)); From 8b3628028e270f18ec945b24360341363b8383bf Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 29 Jun 2019 17:02:34 +0200 Subject: [PATCH 09/26] Don't special case u/i128 for UnOp::not --- src/base.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/base.rs b/src/base.rs index 94ba93de1..88964a34e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -358,14 +358,7 @@ fn trans_stmt<'a, 'tcx: 'a>( fx.bcx.ins().bint(types::I8, res) } ty::Uint(_) | ty::Int(_) => { - if fx.bcx.func.dfg.value_type(val) == types::I128 { - let (a, b) = fx.bcx.ins().isplit(val); - let a = fx.bcx.ins().bnot(a); - let b = fx.bcx.ins().bnot(b); - fx.bcx.ins().iconcat(a, b) - } else { - fx.bcx.ins().bnot(val) - } + fx.bcx.ins().bnot(val) } _ => unimplemented!("un op Not for {:?}", layout.ty), } From 3080c73f50a286a7a6199bf88d7bad7570c2e646 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 29 Jun 2019 17:43:25 +0200 Subject: [PATCH 10/26] Remove unnecessary if statement --- src/common.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/common.rs b/src/common.rs index 6c9077204..838ea6c8f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -79,9 +79,6 @@ pub fn clif_intcast<'a, 'tcx: 'a>( signed: bool, ) -> Value { let from = fx.bcx.func.dfg.value_type(val); - if from == to { - return val; - } match (from, to) { // equal (_, _) if from == to => val, From 641a210ff688d8101688b32650d09c270d381b02 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 7 Jul 2019 18:08:38 +0200 Subject: [PATCH 11/26] Implement most 128bit binops --- example/std_example.rs | 20 +----- src/abi.rs | 2 +- src/base.rs | 151 +++++++++++++++++++---------------------- src/codegen_i128.rs | 107 +++++++++++++++++++++++++++++ src/lib.rs | 1 + 5 files changed, 178 insertions(+), 103 deletions(-) create mode 100644 src/codegen_i128.rs diff --git a/example/std_example.rs b/example/std_example.rs index ae77616a8..c0ec0bb5b 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -3,23 +3,5 @@ use std::io::Write; fn main() { - assert_eq!((1u128 + 2) as u16, 3); -} - -#[derive(PartialEq)] -enum LoopState { - Continue(()), - Break(()) -} - -pub enum Instruction { - Increment, - Loop, -} - -fn map(a: Option<(u8, Box)>) -> Option> { - match a { - None => None, - Some((_, instr)) => Some(instr), - } + assert_eq!(1u128 + 2, 3); } diff --git a/src/abi.rs b/src/abi.rs index b7e7d0a83..c5dbe6dff 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -846,7 +846,7 @@ pub fn codegen_drop<'a, 'tcx: 'a>( ); drop_place.write_place_ref(fx, arg_place); let arg_value = arg_place.to_cvalue(fx); - crate::abi::codegen_call_inner( + codegen_call_inner( fx, None, drop_fn_ty, diff --git a/src/base.rs b/src/base.rs index 88964a34e..8821a6295 100644 --- a/src/base.rs +++ b/src/base.rs @@ -831,18 +831,8 @@ pub fn trans_int_binop<'a, 'tcx: 'a>( ); } - if lhs.layout().ty == fx.tcx.types.u128 || lhs.layout().ty == fx.tcx.types.i128 { - if out_ty == fx.tcx.types.bool { - let layout = fx.layout_of(fx.tcx.types.bool); - let val = fx.bcx.ins().iconst(types::I8, 0); - return CValue::by_val(val, layout); - } else { - let layout = fx.layout_of(out_ty); - let a = fx.bcx.ins().iconst(types::I64, 42); - let b = fx.bcx.ins().iconst(types::I64, 0); - let val = fx.bcx.ins().iconcat(a, b); - return CValue::by_val(val, layout); - } + if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, false, signed, lhs, rhs, out_ty) { + return res; } binop_match! { @@ -894,79 +884,74 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - let (res, has_overflow) = if in_lhs.layout().ty == fx.tcx.types.u128 || in_lhs.layout().ty == fx.tcx.types.i128 { - match (bin_op, signed) { - _ => { - let a = fx.bcx.ins().iconst(types::I64, 42); - let b = fx.bcx.ins().iconst(types::I64, 0); - (fx.bcx.ins().iconcat(a, b), fx.bcx.ins().bconst(types::B1, false)) - } + + if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, true, signed, in_lhs, in_rhs, out_ty) { + return res; + } + + let (res, has_overflow) = match bin_op { + BinOp::Add => { + /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); + (val, c_out)*/ + // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16 + let val = fx.bcx.ins().iadd(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedLessThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let slt = fx.bcx.ins().icmp(IntCC::SignedLessThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, slt) + }; + (val, has_overflow) } - } else { - match bin_op { - BinOp::Add => { - /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); - (val, c_out)*/ - // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16 - let val = fx.bcx.ins().iadd(lhs, rhs); - let has_overflow = if !signed { - fx.bcx.ins().icmp(IntCC::UnsignedLessThan, val, lhs) - } else { - let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); - let slt = fx.bcx.ins().icmp(IntCC::SignedLessThan, val, lhs); - fx.bcx.ins().bxor(rhs_is_negative, slt) - }; - (val, has_overflow) - } - BinOp::Sub => { - /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs); - (val, b_out)*/ - // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16 - let val = fx.bcx.ins().isub(lhs, rhs); - let has_overflow = if !signed { - fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, val, lhs) - } else { - let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); - let sgt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, val, lhs); - fx.bcx.ins().bxor(rhs_is_negative, sgt) - }; - (val, has_overflow) - } - BinOp::Mul => { - let val = fx.bcx.ins().imul(lhs, rhs); - /*let val_hi = if !signed { - fx.bcx.ins().umulhi(lhs, rhs) - } else { - fx.bcx.ins().smulhi(lhs, rhs) - }; - let has_overflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, val_hi, 0);*/ - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) - } - BinOp::Shl => { - let val = fx.bcx.ins().ishl(lhs, rhs); - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) - } - BinOp::Shr => { - let val = if !signed { - fx.bcx.ins().ushr(lhs, rhs) - } else { - fx.bcx.ins().sshr(lhs, rhs) - }; - // TODO: check for overflow - let has_overflow = fx.bcx.ins().bconst(types::B1, false); - (val, has_overflow) - } - _ => bug!( - "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", - bin_op, - in_lhs, - in_rhs - ), + BinOp::Sub => { + /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs); + (val, b_out)*/ + // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16 + let val = fx.bcx.ins().isub(lhs, rhs); + let has_overflow = if !signed { + fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, val, lhs) + } else { + let rhs_is_negative = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, rhs, 0); + let sgt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, val, lhs); + fx.bcx.ins().bxor(rhs_is_negative, sgt) + }; + (val, has_overflow) + } + BinOp::Mul => { + let val = fx.bcx.ins().imul(lhs, rhs); + /*let val_hi = if !signed { + fx.bcx.ins().umulhi(lhs, rhs) + } else { + fx.bcx.ins().smulhi(lhs, rhs) + }; + let has_overflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, val_hi, 0);*/ + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + BinOp::Shl => { + let val = fx.bcx.ins().ishl(lhs, rhs); + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) + } + BinOp::Shr => { + let val = if !signed { + fx.bcx.ins().ushr(lhs, rhs) + } else { + fx.bcx.ins().sshr(lhs, rhs) + }; + // TODO: check for overflow + let has_overflow = fx.bcx.ins().bconst(types::B1, false); + (val, has_overflow) } + _ => bug!( + "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", + bin_op, + in_lhs, + in_rhs + ), }; let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow); diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs new file mode 100644 index 000000000..ded6b597f --- /dev/null +++ b/src/codegen_i128.rs @@ -0,0 +1,107 @@ +//! Replaces 128-bit operators with lang item calls + +use crate::prelude::*; + +pub fn maybe_codegen<'a, 'tcx>( + fx: &mut FunctionCx<'a, 'tcx, impl Backend>, + bin_op: BinOp, + checked: bool, + is_signed: bool, + lhs: CValue<'tcx>, + rhs: CValue<'tcx>, + out_ty: Ty<'tcx>, +) -> Option> { + if lhs.layout().ty != fx.tcx.types.u128 && lhs.layout().ty != fx.tcx.types.i128 { + return None; + } + + let lhs_val = lhs.load_scalar(fx); + let rhs_val = rhs.load_scalar(fx); + + match bin_op { + BinOp::Add | BinOp::Sub | BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => return None, + BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), + BinOp::Mul => { + let res = if checked { + if is_signed { + let oflow_place = CPlace::new_stack_slot(fx, fx.tcx.types.i32); + let oflow_addr = oflow_place.to_addr(fx); + let oflow_addr = CValue::by_val(oflow_addr, fx.layout_of(fx.tcx.mk_mut_ptr(fx.tcx.types.i32))); + let val = fx.easy_call("__muloti4", &[lhs, rhs, oflow_addr], fx.tcx.types.i128); + let val = val.load_scalar(fx); + let oflow = oflow_place.to_cvalue(fx).load_scalar(fx); + let oflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, oflow, 0); + let oflow = fx.bcx.ins().bint(types::I8, oflow); + CValue::by_val_pair(val, oflow, fx.layout_of(out_ty)) + } else { + // FIXME implement it + let out_layout = fx.layout_of(out_ty); + return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop unsigned mul"))); + } + } else { + let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; + fx.easy_call("__multi3", &[lhs, rhs], val_ty) + }; + return Some(res); + } + BinOp::Div => { + let res = if checked { + // FIXME implement it + let out_layout = fx.layout_of(out_ty); + return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop div"))); + } else { + if is_signed { + fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128) + } else { + fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128) + } + }; + return Some(res); + } + BinOp::Rem => { + let res = if checked { + // FIXME implement it + let out_layout = fx.layout_of(out_ty); + return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop rem"))); + } else { + if is_signed { + fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128) + } else { + fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128) + } + }; + return Some(res); + } + BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { + assert!(!checked); + let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val); + let (rhs_lsb, rhs_msb) = fx.bcx.ins().isplit(rhs_val); + let res = match (bin_op, is_signed) { + (BinOp::Eq, _) => { + let lsb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_lsb, rhs_lsb); + let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb); + fx.bcx.ins().band(lsb_eq, msb_eq) + } + (BinOp::Ne, _) => { + let lsb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_lsb, rhs_lsb); + let msb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_msb, rhs_msb); + fx.bcx.ins().bor(lsb_ne, msb_ne) + } + _ => { + // FIXME implement it + let out_layout = fx.layout_of(out_ty); + return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit binop {:?}", bin_op))); + }, + }; + + let res = fx.bcx.ins().bint(types::I8, res); + let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.bool)); + return Some(res); + } + BinOp::Shl | BinOp::Shr => { + // FIXME implement it + let out_layout = fx.layout_of(out_ty); + return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit binop {:?}", bin_op))); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index c6f77954a..9bd985e3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ mod allocator; mod analyze; mod archive; mod base; +mod codegen_i128; mod common; mod constant; mod debuginfo; From 834a3bf49c9e6cc422a0028926654d46dc5749ba Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 17 Jul 2019 20:45:54 +0200 Subject: [PATCH 12/26] [WIP] --- example/mini_core_hello_world.rs | 129 +++++++++++++++++++++++++++---- example/std_example.rs | 18 +++++ 2 files changed, 133 insertions(+), 14 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 4a26577af..e51f257f6 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -117,22 +117,123 @@ impl CoerceUnsized> for Unique where T: Unsiz fn take_f32(_f: f32) {} fn take_unique(_u: Unique<()>) {} -fn checked_div_i128(lhs: i128, rhs: i128) -> Option { - if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) { - None - } else { - Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) +fn main() { + take_unique(Unique { + pointer: 0 as *const (), + _marker: PhantomData, + }); + take_f32(0.1); + + //return; + + unsafe { + printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8); + + let hello: &[u8] = b"Hello\0" as &[u8; 6]; + let ptr: *const u8 = hello as *const [u8] as *const u8; + puts(ptr); + + let world: Box<&str> = box "World!\0"; + puts(*world as *const str as *const u8); + world as Box; + + assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8); + + assert_eq!(intrinsics::bswap(0xabu8), 0xabu8); + assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16); + assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32); + assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64); + + assert_eq!(intrinsics::size_of_val(hello) as u8, 6); + + let chars = &['C', 'h', 'a', 'r', 's']; + let chars = chars as &[char]; + assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5); + + let a: &dyn SomeTrait = &"abc\0"; + a.object_safe(); + + assert_eq!(intrinsics::size_of_val(a) as u8, 16); + assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); + + assert_eq!(intrinsics::min_align_of::() as u8, 2); + assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); + + assert!(!intrinsics::needs_drop::()); + assert!(intrinsics::needs_drop::()); + + Unique { + pointer: 0 as *const &str, + _marker: PhantomData, + } as Unique; + + struct MyDst(T); + + intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>); + + struct Foo { + x: u8, + y: !, + } + + unsafe fn zeroed() -> T { + intrinsics::init::() + } + + unsafe fn uninitialized() -> T { + MaybeUninit { uninit: () }.value + } + + zeroed::<(u8, u8)>(); + #[allow(unreachable_code)] + { + if false { + zeroed::(); + zeroed::(); + uninitialized::(); + } + } } -} -fn checked_div_u128(lhs: u128, rhs: u128) -> Option { - match rhs { - 0 => None, - rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) + let _ = box NoisyDrop { + text: "Boxed outer got dropped!\0", + inner: NoisyDropInner, + } as Box; + + const FUNC_REF: Option = Some(main); + match FUNC_REF { + Some(_) => {}, + None => assert!(false), } -} -fn main() { - checked_div_i128(0i128, 2i128); - checked_div_u128(0u128, 2u128); + match Ordering::Less { + Ordering::Less => {}, + _ => assert!(false), + } + + [NoisyDropInner, NoisyDropInner]; + + let x = &[0u32, 42u32] as &[u32]; + match x { + [] => assert_eq!(0u32, 1), + [_, ref y..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), + } + + assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); + + extern { + #[linkage = "weak"] + static ABC: *const u8; + } + + { + extern { + #[linkage = "weak"] + static ABC: *const u8; + } + } + + unsafe { assert_eq!(ABC as usize, 0); } + + &mut (|| Some(0 as *const ())) as &mut FnMut() -> Option<*const ()>; } diff --git a/example/std_example.rs b/example/std_example.rs index c0ec0bb5b..a67ca2f79 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -1,7 +1,25 @@ #![feature(core_intrinsics)] use std::io::Write; +use std::intrinsics; + +fn checked_div_i128(lhs: i128, rhs: i128) -> Option { + if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) { + None + } else { + Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) + } +} + +fn checked_div_u128(lhs: u128, rhs: u128) -> Option { + match rhs { + 0 => None, + rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) + } +} fn main() { + checked_div_i128(0i128, 2i128); + checked_div_u128(0u128, 2u128); assert_eq!(1u128 + 2, 3); } From 869372832788b8949ef03cd1a421542f5b96eb79 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Jul 2019 17:05:43 +0200 Subject: [PATCH 13/26] Respect sess.overflow_checks() --- src/base.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base.rs b/src/base.rs index 8821a6295..7f99f4ad4 100644 --- a/src/base.rs +++ b/src/base.rs @@ -874,6 +874,10 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>( out_ty: Ty<'tcx>, signed: bool, ) -> CValue<'tcx> { + if !fx.tcx.sess.overflow_checks() { + return trans_int_binop(fx, bin_op, in_lhs, in_rhs, out_ty, signed); + } + if bin_op != BinOp::Shl && bin_op != BinOp::Shr { assert_eq!( in_lhs.layout().ty, From 88ad25f45e9adbf08871ce77449e1b1193d23df4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Jul 2019 17:44:41 +0200 Subject: [PATCH 14/26] Implement 128bit shl and shr binops --- src/abi.rs | 1 + src/codegen_i128.rs | 84 ++++++++++++++++++++++++++++++++++++++++++--- src/common.rs | 46 ++++++++++++++++++++++++- 3 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index c5dbe6dff..1c9f84b37 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -270,6 +270,7 @@ impl<'a, 'tcx: 'a, B: Backend + 'a> FunctionCx<'a, 'tcx, B> { .module .declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); + self.add_comment(call_inst, format!("easy_call {}", name)); if output_ty.is_none() { return None; } diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index ded6b597f..81388573c 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -19,7 +19,13 @@ pub fn maybe_codegen<'a, 'tcx>( let rhs_val = rhs.load_scalar(fx); match bin_op { - BinOp::Add | BinOp::Sub | BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => return None, + BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => { + assert!(!checked); + return None; + } + BinOp::Add | BinOp::Sub => { + return None; // FIXME implement checked versions + } BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Mul => { let res = if checked { @@ -99,9 +105,79 @@ pub fn maybe_codegen<'a, 'tcx>( return Some(res); } BinOp::Shl | BinOp::Shr => { - // FIXME implement it - let out_layout = fx.layout_of(out_ty); - return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit binop {:?}", bin_op))); + let is_overflow = if checked { + // rhs >= 128 + + // FIXME support non 128bit rhs + /*let (rhs_lsb, rhs_msb) = fx.bcx.ins().isplit(rhs_val); + let rhs_msb_gt_0 = fx.bcx.ins().icmp_imm(IntCC::NotEqual, rhs_msb, 0); + let rhs_lsb_ge_128 = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThan, rhs_lsb, 127); + let is_overflow = fx.bcx.ins().bor(rhs_msb_gt_0, rhs_lsb_ge_128);*/ + let is_overflow = fx.bcx.ins().bconst(types::B1, false); + + Some(fx.bcx.ins().bint(types::I8, is_overflow)) + } else { + None + }; + + // Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit + // integer into its lsb and msb. + // https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217 + if let Some(64) = resolve_value_imm(fx.bcx.func, rhs_val) { + let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val); + let all_zeros = fx.bcx.ins().iconst(types::I64, 0); + let val = match (bin_op, is_signed) { + (BinOp::Shr, false) => { + let val = fx.bcx.ins().iconcat(lhs_msb, all_zeros); + Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.u128))) + } + (BinOp::Shr, true) => { + let sign = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, lhs_msb, 0); + let all_ones = fx.bcx.ins().iconst(types::I64, u64::max_value() as i64); + let all_sign_bits = fx.bcx.ins().select(sign, all_zeros, all_ones); + + let val = fx.bcx.ins().iconcat(lhs_msb, all_sign_bits); + Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128))) + } + (BinOp::Shl, _) => { + let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb); + Some(CValue::by_val(val, fx.layout_of(out_ty))) + } + _ => None + }; + if let Some(val) = val { + if let Some(is_overflow) = is_overflow { + let val = val.load_scalar(fx); + return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))) + } else { + return Some(val); + } + } + } + + let truncated_rhs = clif_intcast(fx, rhs_val, types::I32, false); + let truncated_rhs = CValue::by_val(truncated_rhs, fx.layout_of(fx.tcx.types.u32)); + let val = match (bin_op, is_signed) { + (BinOp::Shl, false) => { + fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.u128) + } + (BinOp::Shl, true) => { + fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.i128) + } + (BinOp::Shr, false) => { + fx.easy_call("__lshrti3", &[lhs, truncated_rhs], fx.tcx.types.u128) + } + (BinOp::Shr, true) => { + fx.easy_call("__ashrti3", &[lhs, truncated_rhs], fx.tcx.types.i128) + } + (_, _) => unreachable!(), + }; + if let Some(is_overflow) = is_overflow { + let val = val.load_scalar(fx); + Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))) + } else { + Some(val) + } } } } diff --git a/src/common.rs b/src/common.rs index 838ea6c8f..6a00d1341 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,5 +1,6 @@ use rustc_target::spec::{HasTargetSpec, Target}; +use cranelift::codegen::ir::{Opcode, InstructionData, ValueDef}; use cranelift_module::Module; use crate::prelude::*; @@ -62,7 +63,7 @@ pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: V let rhs_ty = bcx.func.dfg.value_type(rhs); assert_eq!(lhs_ty, rhs_ty); if lhs_ty == types::I8 || lhs_ty == types::I16 { - // FIXME workaround for missing enocding for select.i8 + // FIXME workaround for missing encoding for select.i8 let lhs = bcx.ins().uextend(types::I32, lhs); let rhs = bcx.ins().uextend(types::I32, rhs); let res = bcx.ins().select(cond, lhs, rhs); @@ -118,6 +119,49 @@ pub fn clif_intcast<'a, 'tcx: 'a>( } } +fn resolve_normal_value_imm(func: &Function, val: Value) -> Option { + if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { + if let InstructionData::UnaryImm { + opcode: Opcode::Iconst, + imm, + } = func.dfg[inst] { + Some(imm.into()) + } else { + None + } + } else { + None + } +} + +fn resolve_128bit_value_imm(func: &Function, val: Value) -> Option { + let (lsb, msb) = if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { + if let InstructionData::Binary { + opcode: Opcode::Iconcat, + args: [lsb, msb], + } = func.dfg[inst] { + (lsb, msb) + } else { + return None; + } + } else { + return None; + }; + + let lsb = resolve_normal_value_imm(func, lsb)? as u64 as u128; + let msb = resolve_normal_value_imm(func, msb)? as u64 as u128; + + Some(msb << 64 | lsb) +} + +pub fn resolve_value_imm(func: &Function, val: Value) -> Option { + if func.dfg.value_type(val) == types::I128 { + resolve_128bit_value_imm(func, val) + } else { + resolve_normal_value_imm(func, val).map(|imm| imm as u64 as u128) + } +} + pub struct FunctionCx<'a, 'tcx: 'a, B: Backend> { // FIXME use a reference to `CodegenCx` instead of `tcx`, `module` and `constants` and `caches` pub tcx: TyCtxt<'tcx>, From 65e337cdf3e9a54dbabcdb92aebdfb79b5660e24 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Jul 2019 17:57:00 +0200 Subject: [PATCH 15/26] Implement 128bit multiply with overflow --- example/std_example.rs | 5 +++++ src/abi.rs | 36 +++++++++++++------------------ src/codegen_i128.rs | 49 ++++++++++++------------------------------ 3 files changed, 34 insertions(+), 56 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index a67ca2f79..9e9a7a67e 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -22,4 +22,9 @@ fn main() { checked_div_i128(0i128, 2i128); checked_div_u128(0u128, 2u128); assert_eq!(1u128 + 2, 3); + + println!("{}", 0b100010000000000000000000000000000u128 >> 10); + println!("{}", 0xFEDCBA987654321123456789ABCDEFu128 >> 64); + println!("{} >> 64 == {}", 0xFEDCBA987654321123456789ABCDEFu128 as i128, 0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64); + println!("{}", 353985398u128 * 932490u128); } diff --git a/src/abi.rs b/src/abi.rs index 1c9f84b37..b884d80b3 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -252,14 +252,12 @@ impl<'a, 'tcx: 'a, B: Backend + 'a> FunctionCx<'a, 'tcx, B> { &mut self, name: &str, input_tys: Vec, - output_ty: Option, + output_tys: Vec, args: &[Value], - ) -> Option { + ) -> &[Value] { let sig = Signature { params: input_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output_ty - .map(|output_ty| vec![AbiParam::new(output_ty)]) - .unwrap_or(Vec::new()), + returns: output_tys.iter().cloned().map(AbiParam::new).collect(), call_conv: CallConv::SystemV, }; let func_id = self @@ -271,12 +269,9 @@ impl<'a, 'tcx: 'a, B: Backend + 'a> FunctionCx<'a, 'tcx, B> { .declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); self.add_comment(call_inst, format!("easy_call {}", name)); - if output_ty.is_none() { - return None; - } let results = self.bcx.inst_results(call_inst); - assert_eq!(results.len(), 1); - Some(results[0]) + assert!(results.len() <= 2, "{}", results.len()); + results } pub fn easy_call( @@ -295,23 +290,22 @@ impl<'a, 'tcx: 'a, B: Backend + 'a> FunctionCx<'a, 'tcx, B> { }) .unzip(); let return_layout = self.layout_of(return_ty); - let return_ty = if let ty::Tuple(tup) = return_ty.sty { - if !tup.is_empty() { - bug!("easy_call( (...) -> ) is not allowed"); - } - None + let return_tys = if let ty::Tuple(tup) = return_ty.sty { + tup.types().map(|ty| self.clif_type(ty).unwrap()).collect() } else { - Some(self.clif_type(return_ty).unwrap()) + vec![self.clif_type(return_ty).unwrap()] }; - if let Some(val) = self.lib_call(name, input_tys, return_ty, &args) { - CValue::by_val(val, return_layout) - } else { - CValue::by_ref( + let ret_vals = self.lib_call(name, input_tys, return_tys, &args); + match *ret_vals { + [] => CValue::by_ref( self.bcx .ins() .iconst(self.pointer_type, self.pointer_type.bytes() as i64), return_layout, - ) + ), + [val] => CValue::by_val(val, return_layout), + [val, extra] => CValue::by_val_pair(val, extra, return_layout), + _ => unreachable!(), } } diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 81388573c..b5e2bb6b3 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -30,19 +30,9 @@ pub fn maybe_codegen<'a, 'tcx>( BinOp::Mul => { let res = if checked { if is_signed { - let oflow_place = CPlace::new_stack_slot(fx, fx.tcx.types.i32); - let oflow_addr = oflow_place.to_addr(fx); - let oflow_addr = CValue::by_val(oflow_addr, fx.layout_of(fx.tcx.mk_mut_ptr(fx.tcx.types.i32))); - let val = fx.easy_call("__muloti4", &[lhs, rhs, oflow_addr], fx.tcx.types.i128); - let val = val.load_scalar(fx); - let oflow = oflow_place.to_cvalue(fx).load_scalar(fx); - let oflow = fx.bcx.ins().icmp_imm(IntCC::NotEqual, oflow, 0); - let oflow = fx.bcx.ins().bint(types::I8, oflow); - CValue::by_val_pair(val, oflow, fx.layout_of(out_ty)) + fx.easy_call("__rust_i128_mulo", &[lhs, rhs], out_ty) } else { - // FIXME implement it - let out_layout = fx.layout_of(out_ty); - return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop unsigned mul"))); + fx.easy_call("__rust_u128_mulo", &[lhs, rhs], out_ty) } } else { let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; @@ -51,32 +41,20 @@ pub fn maybe_codegen<'a, 'tcx>( return Some(res); } BinOp::Div => { - let res = if checked { - // FIXME implement it - let out_layout = fx.layout_of(out_ty); - return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop div"))); + assert!(!checked); + if is_signed { + Some(fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128)) } else { - if is_signed { - fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128) - } else { - fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128) - } - }; - return Some(res); + Some(fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128)) + } } BinOp::Rem => { - let res = if checked { - // FIXME implement it - let out_layout = fx.layout_of(out_ty); - return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit checked binop rem"))); + assert!(!checked); + if is_signed { + Some(fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128)) } else { - if is_signed { - fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128) - } else { - fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128) - } - }; - return Some(res); + Some(fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128)) + } } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { assert!(!checked); @@ -140,8 +118,9 @@ pub fn maybe_codegen<'a, 'tcx>( Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128))) } (BinOp::Shl, _) => { + let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb); - Some(CValue::by_val(val, fx.layout_of(out_ty))) + Some(CValue::by_val(val, fx.layout_of(val_ty))) } _ => None }; From 4d35be684da8c82ac699093132bda4a5292f9578 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 24 Jul 2019 13:08:31 +0200 Subject: [PATCH 16/26] Implement 128bit comparison binops --- src/codegen_i128.rs | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index b5e2bb6b3..76d0fcb30 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -60,22 +60,43 @@ pub fn maybe_codegen<'a, 'tcx>( assert!(!checked); let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val); let (rhs_lsb, rhs_msb) = fx.bcx.ins().isplit(rhs_val); - let res = match (bin_op, is_signed) { - (BinOp::Eq, _) => { + + let res = match bin_op { + BinOp::Eq => { let lsb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_lsb, rhs_lsb); let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb); fx.bcx.ins().band(lsb_eq, msb_eq) } - (BinOp::Ne, _) => { + BinOp::Ne => { let lsb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_lsb, rhs_lsb); let msb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_msb, rhs_msb); fx.bcx.ins().bor(lsb_ne, msb_ne) } _ => { - // FIXME implement it - let out_layout = fx.layout_of(out_ty); - return Some(crate::trap::trap_unreachable_ret_value(fx, out_layout, format!("unimplemented 128bit binop {:?}", bin_op))); - }, + // if msb_eq { + // lhs_cc + // } else { + // msb_cc + // } + let cc = match (bin_op, is_signed) { + (BinOp::Ge, false) => IntCC::UnsignedGreaterThanOrEqual, + (BinOp::Gt, false) => IntCC::UnsignedGreaterThan, + (BinOp::Lt, false) => IntCC::UnsignedLessThan, + (BinOp::Le, false) => IntCC::UnsignedLessThanOrEqual, + + (BinOp::Ge, true) => IntCC::SignedGreaterThanOrEqual, + (BinOp::Gt, true) => IntCC::SignedGreaterThan, + (BinOp::Lt, true) => IntCC::SignedLessThan, + (BinOp::Le, true) => IntCC::SignedLessThanOrEqual, + _ => unreachable!(), + }; + + let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb); + let lsb_cc = fx.bcx.ins().icmp(cc, lhs_lsb, rhs_lsb); + let msb_cc = fx.bcx.ins().icmp(cc, lhs_msb, rhs_msb); + + fx.bcx.ins().select(msb_eq, lsb_cc, msb_cc) + } }; let res = fx.bcx.ins().bint(types::I8, res); From 63b82238bbe54643c63a8693299d6a9f4c0b0358 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 24 Jul 2019 13:16:36 +0200 Subject: [PATCH 17/26] Implement 128bit checked add and sub --- example/mini_core.rs | 27 --------------------------- example/std_example.rs | 3 +++ src/codegen_i128.rs | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index fa47831b6..221cdb3e8 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -44,12 +44,10 @@ unsafe impl Copy for u8 {} unsafe impl Copy for u16 {} unsafe impl Copy for u32 {} unsafe impl Copy for u64 {} -unsafe impl Copy for u128 {} unsafe impl Copy for usize {} unsafe impl Copy for i8 {} unsafe impl Copy for i16 {} unsafe impl Copy for i32 {} -unsafe impl Copy for i128 {} unsafe impl Copy for isize {} unsafe impl Copy for char {} unsafe impl<'a, T: ?Sized> Copy for &'a T {} @@ -146,22 +144,6 @@ impl Add for usize { } } -impl Add for u128 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i128 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - #[lang = "sub"] pub trait Sub { type Output; @@ -286,15 +268,6 @@ impl PartialEq for i32 { } } -impl PartialEq for i128 { - fn eq(&self, other: &i128) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &i128) -> bool { - (*self) != (*other) - } -} - impl PartialEq for isize { fn eq(&self, other: &isize) -> bool { (*self) == (*other) diff --git a/example/std_example.rs b/example/std_example.rs index 9e9a7a67e..f9fc1f2cd 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -23,6 +23,9 @@ fn main() { checked_div_u128(0u128, 2u128); assert_eq!(1u128 + 2, 3); + // overflow panic + // 0xFEDCBA987654321123456789ABCDEFu128 + 0xFEDCBA987654321123456789ABCDEFu128; + println!("{}", 0b100010000000000000000000000000000u128 >> 10); println!("{}", 0xFEDCBA987654321123456789ABCDEFu128 >> 64); println!("{} >> 64 == {}", 0xFEDCBA987654321123456789ABCDEFu128 as i128, 0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64); diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 76d0fcb30..9cd6bc8c7 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -23,8 +23,20 @@ pub fn maybe_codegen<'a, 'tcx>( assert!(!checked); return None; } - BinOp::Add | BinOp::Sub => { - return None; // FIXME implement checked versions + BinOp::Add | BinOp::Sub if !checked => return None, + BinOp::Add => { + return Some(if is_signed { + fx.easy_call("__rust_i128_addo", &[lhs, rhs], out_ty) + } else { + fx.easy_call("__rust_u128_addo", &[lhs, rhs], out_ty) + }) + } + BinOp::Sub => { + return Some(if is_signed { + fx.easy_call("__rust_i128_subo", &[lhs, rhs], out_ty) + } else { + fx.easy_call("__rust_u128_subo", &[lhs, rhs], out_ty) + }) } BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Mul => { From 5180becc7c11573d267166437abf3d9951c6b0c7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 24 Jul 2019 17:16:31 +0200 Subject: [PATCH 18/26] Fix 128bit CValue::const_val --- example/std_example.rs | 3 +++ src/base.rs | 8 ++++---- src/constant.rs | 10 +++------- src/intrinsics.rs | 18 +++++++++--------- src/lib.rs | 2 +- src/value_and_place.rs | 29 +++++++++++++++++++++-------- 6 files changed, 41 insertions(+), 29 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index f9fc1f2cd..465b61435 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -19,6 +19,9 @@ fn checked_div_u128(lhs: u128, rhs: u128) -> Option { } fn main() { + assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26); + assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); + checked_div_i128(0i128, 2i128); checked_div_u128(0u128, 2u128); assert_eq!(1u128 + 2, 3); diff --git a/src/base.rs b/src/base.rs index 7f99f4ad4..6476de765 100644 --- a/src/base.rs +++ b/src/base.rs @@ -266,7 +266,7 @@ fn trans_stmt<'a, 'tcx: 'a>( .discriminant_for_variant(fx.tcx, *variant_index) .unwrap() .val; - let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64); + let discr = CValue::const_val(fx, ptr.layout().ty, to); ptr.write_cvalue(fx, discr); } layout::Variants::Multiple { @@ -289,7 +289,7 @@ fn trans_stmt<'a, 'tcx: 'a>( let niche_llval = if niche_value == 0 { CValue::const_val(fx, niche.layout().ty, 0) } else { - CValue::const_val(fx, niche.layout().ty, niche_value as u64 as i64) + CValue::const_val(fx, niche.layout().ty, niche_value) }; niche.write_cvalue(fx, niche_llval); } @@ -562,7 +562,7 @@ fn trans_stmt<'a, 'tcx: 'a>( .ty .is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())); let ty_size = fx.layout_of(ty).size.bytes(); - let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size as i64); + let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size.into()); lval.write_cvalue(fx, val); } Rvalue::Aggregate(kind, operands) => match **kind { @@ -679,7 +679,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>( .map_or(index.as_u32() as u128, |def| { def.discriminant_for_variant(fx.tcx, *index).val }); - return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64); + return CValue::const_val(fx, dest_layout.ty, discr_val); } layout::Variants::Multiple { discr, discr_index, discr_kind, variants: _ } => { (discr, *discr_index, discr_kind) diff --git a/src/constant.rs b/src/constant.rs index 9a2b0cf36..10f757ffc 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -113,17 +113,13 @@ pub fn trans_const_value<'a, 'tcx: 'a>( let ty = fx.monomorphize(&const_.ty); let layout = fx.layout_of(ty); match ty.sty { - ty::Bool => { + ty::Bool | ty::Uint(_) => { let bits = const_.val.try_to_bits(layout.size).unwrap(); - CValue::const_val(fx, ty, bits as u64 as i64) - } - ty::Uint(_) => { - let bits = const_.val.try_to_bits(layout.size).unwrap(); - CValue::const_val(fx, ty, bits as u64 as i64) + CValue::const_val(fx, ty, bits) } ty::Int(_) => { let bits = const_.val.try_to_bits(layout.size).unwrap(); - CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size) as i128 as i64) + CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size)) } ty::FnDef(_def_id, _substs) => CValue::by_ref( fx.bcx diff --git a/src/intrinsics.rs b/src/intrinsics.rs index f521a07d9..ee00924ad 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -150,7 +150,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( }; size_of, () { let size_of = fx.layout_of(T).size.bytes(); - let size_of = CValue::const_val(fx, usize_layout.ty, size_of as i64); + let size_of = CValue::const_val(fx, usize_layout.ty, size_of.into()); ret.write_cvalue(fx, size_of); }; size_of_val, (c ptr) { @@ -169,7 +169,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( }; min_align_of, () { let min_align = fx.layout_of(T).align.abi.bytes(); - let min_align = CValue::const_val(fx, usize_layout.ty, min_align as i64); + let min_align = CValue::const_val(fx, usize_layout.ty, min_align.into()); ret.write_cvalue(fx, min_align); }; min_align_of_val, (c ptr) { @@ -188,14 +188,14 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( }; pref_align_of, () { let pref_align = fx.layout_of(T).align.pref.bytes(); - let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align as i64); + let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align.into()); ret.write_cvalue(fx, pref_align); }; type_id, () { let type_id = fx.tcx.type_id_hash(T); - let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64); + let type_id = CValue::const_val(fx, u64_layout.ty, type_id.into()); ret.write_cvalue(fx, type_id); }; type_name, () { @@ -395,9 +395,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( let (lsb, msb) = fx.bcx.ins().isplit(arg); let lsb_lz = fx.bcx.ins().clz(lsb); let msb_lz = fx.bcx.ins().clz(msb); - let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64); + let msb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, msb, 0); let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64); - fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz) + fx.bcx.ins().select(msb_is_zero, lsb_lz_plus_64, msb_lz) } else { fx.bcx.ins().clz(arg) }; @@ -410,9 +410,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( let (lsb, msb) = fx.bcx.ins().isplit(arg); let lsb_tz = fx.bcx.ins().ctz(lsb); let msb_tz = fx.bcx.ins().ctz(msb); - let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64); - let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64); - fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz) + let lsb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb, 0); + let msb_tz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64); + fx.bcx.ins().select(lsb_is_zero, msb_tz_plus_64, lsb_tz) } else { fx.bcx.ins().ctz(arg) }; diff --git a/src/lib.rs b/src/lib.rs index 9bd985e3d..df53d741a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ mod vtable; mod prelude { pub use std::any::Any; pub use std::collections::{HashMap, HashSet}; - pub use std::convert::TryInto; + pub use std::convert::{TryFrom, TryInto}; pub use syntax::ast::{FloatTy, IntTy, UintTy}; pub use syntax::source_map::{Pos, Span, DUMMY_SP}; diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 8b5c764f6..21c90d0d9 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -162,24 +162,37 @@ impl<'tcx> CValue<'tcx> { crate::unsize::coerce_unsized_into(fx, self, dest); } + /// If `ty` is signed, `const_val` must already be sign extended. pub fn const_val<'a>( fx: &mut FunctionCx<'a, 'tcx, impl Backend>, ty: Ty<'tcx>, - const_val: i64, + const_val: u128, ) -> CValue<'tcx> where 'tcx: 'a, { let clif_ty = fx.clif_type(ty).unwrap(); let layout = fx.layout_of(ty); - let val = if clif_ty == types::I128 { - // FIXME don't assume little-endian arch - let lsb = fx.bcx.ins().iconst(types::I64, const_val); - let msb = fx.bcx.ins().iconst(types::I64, 0); - fx.bcx.ins().iconcat(lsb, msb) - } else { - fx.bcx.ins().iconst(clif_ty, const_val) + + let val = match ty.sty { + ty::TyKind::Uint(UintTy::U128) | ty::TyKind::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::TyKind::Bool => { + assert!(const_val == 0 || const_val == 1, "Invalid bool 0x{:032X}", const_val); + fx.bcx.ins().iconst(types::I8, const_val as i64) + } + ty::TyKind::Uint(_) | ty::TyKind::Ref(..) | ty::TyKind::RawPtr(.. )=> { + fx.bcx.ins().iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64) + } + ty::TyKind::Int(_) => { + fx.bcx.ins().iconst(clif_ty, const_val as i128 as i64) + } + _ => panic!("CValue::const_val for non bool/integer/pointer type {:?} is not allowed", ty), }; + CValue::by_val(val, layout) } From 7f5c2dab9dfcf128336422bcefded78a99ff1c42 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 24 Jul 2019 17:23:23 +0200 Subject: [PATCH 19/26] Remove some unnecessary changes --- example/mini_core.rs | 1 - example/std_example.rs | 76 ++++++++++++++++++++++++++++++++---------- src/value_and_place.rs | 41 +++++------------------ 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 221cdb3e8..191f465fb 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -446,7 +446,6 @@ pub mod intrinsics { pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; - pub fn unchecked_div(lhs: T, rhs: T) -> T; } } diff --git a/example/std_example.rs b/example/std_example.rs index 465b61435..bd51a37f2 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -3,6 +3,65 @@ use std::io::Write; use std::intrinsics; +fn main() { + let _ = ::std::iter::repeat('a' as u8).take(10).collect::>(); + let stderr = ::std::io::stderr(); + let mut stderr = stderr.lock(); + + writeln!(stderr, "some {} text", "").unwrap(); + + let _ = std::process::Command::new("true").env("c", "d").spawn(); + + println!("cargo:rustc-link-lib=z"); + + static ONCE: std::sync::Once = std::sync::ONCE_INIT; + ONCE.call_once(|| {}); + + LoopState::Continue(()) == LoopState::Break(()); + + // Make sure ByValPair values with differently sized components are correctly passed + map(None::<(u8, Box)>); + + println!("{}", 2.3f32.exp()); + println!("{}", 2.3f32.exp2()); + println!("{}", 2.3f32.abs()); + println!("{}", 2.3f32.sqrt()); + println!("{}", 2.3f32.floor()); + println!("{}", 2.3f32.ceil()); + println!("{}", 2.3f32.min(1.0)); + println!("{}", 2.3f32.max(1.0)); + + assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26); + assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); + + checked_div_i128(0i128, 2i128); + checked_div_u128(0u128, 2u128); + assert_eq!(1u128 + 2, 3); + + assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128); + assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 >> 64, 0xFEDCBA98765432u128); + assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64, 0xFEDCBA98765432i128); + assert_eq!(353985398u128 * 932490u128, 330087843781020u128); +} + +#[derive(PartialEq)] +enum LoopState { + Continue(()), + Break(()) +} + +pub enum Instruction { + Increment, + Loop, +} + +fn map(a: Option<(u8, Box)>) -> Option> { + match a { + None => None, + Some((_, instr)) => Some(instr), + } +} + fn checked_div_i128(lhs: i128, rhs: i128) -> Option { if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) { None @@ -17,20 +76,3 @@ fn checked_div_u128(lhs: u128, rhs: u128) -> Option { rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) } } - -fn main() { - assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26); - assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); - - checked_div_i128(0i128, 2i128); - checked_div_u128(0u128, 2u128); - assert_eq!(1u128 + 2, 3); - - // overflow panic - // 0xFEDCBA987654321123456789ABCDEFu128 + 0xFEDCBA987654321123456789ABCDEFu128; - - println!("{}", 0b100010000000000000000000000000000u128 >> 10); - println!("{}", 0xFEDCBA987654321123456789ABCDEFu128 >> 64); - println!("{} >> 64 == {}", 0xFEDCBA987654321123456789ABCDEFu128 as i128, 0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64); - println!("{}", 353985398u128 * 932490u128); -} diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 21c90d0d9..a8b3a2954 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -34,31 +34,6 @@ enum CValueInner { ByValPair(Value, Value), } -fn store_scalar<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>, value: Value, addr: Value, offset: i32) { - if fx.bcx.func.dfg.value_type(value) == types::I128 { - let (a, b) = fx.bcx.ins().isplit(value); - fx.bcx.ins().store(MemFlags::new(), a, addr, offset); - fx.bcx.ins().store(MemFlags::new(), b, addr, offset + 8); - } else { - fx.bcx.ins().store(MemFlags::new(), value, addr, offset); - } -} - -fn load_scalar<'a, 'tcx: 'a>( - fx: &mut FunctionCx<'a, 'tcx, impl Backend>, - clif_ty: Type, - addr: Value, - offset: i32, -) -> Value { - if clif_ty == types::I128 { - let a = fx.bcx.ins().load(types::I64, MemFlags::new(), addr, offset); - let b = fx.bcx.ins().load(types::I64, MemFlags::new(), addr, offset + 8); - fx.bcx.ins().iconcat(a, b) - } else { - fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, offset) - } -} - impl<'tcx> CValue<'tcx> { pub fn by_ref(value: Value, layout: TyLayout<'tcx>) -> CValue<'tcx> { CValue(CValueInner::ByRef(value), layout) @@ -104,7 +79,7 @@ impl<'tcx> CValue<'tcx> { _ => unreachable!(), }; let clif_ty = scalar_to_clif_type(fx.tcx, scalar); - load_scalar(fx, clif_ty, addr, 0) + fx.bcx.ins().load(clif_ty, MemFlags::new(), addr, 0) } CValueInner::ByVal(value) => value, CValueInner::ByValPair(_, _) => bug!("Please use load_scalar_pair for ByValPair"), @@ -126,10 +101,10 @@ impl<'tcx> CValue<'tcx> { let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone()); let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar.clone()); - let val1 = load_scalar(fx, clif_ty1, addr, 0); - let val2 = load_scalar( - fx, + let val1 = fx.bcx.ins().load(clif_ty1, MemFlags::new(), addr, 0); + let val2 = fx.bcx.ins().load( clif_ty2, + MemFlags::new(), addr, b_offset, ); @@ -389,15 +364,15 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> { match from.0 { CValueInner::ByVal(val) => { - store_scalar(fx, val, addr, 0); + fx.bcx.ins().store(MemFlags::new(), val, addr, 0); } CValueInner::ByValPair(value, extra) => { match dst_layout.abi { Abi::ScalarPair(ref a_scalar, ref b_scalar) => { let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); - store_scalar(fx, value, addr, 0); - store_scalar( - fx, + fx.bcx.ins().store(MemFlags::new(), value, addr, 0); + fx.bcx.ins().store( + MemFlags::new(), extra, addr, b_offset, From 81fa33da3d3a7fa747e332de5f6adafcf4ac7bdf Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 24 Jul 2019 17:56:16 +0200 Subject: [PATCH 20/26] Fix arg header comments --- src/abi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index b884d80b3..5e041e6c6 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -341,7 +341,7 @@ fn add_arg_comment<'a, 'tcx: 'a>( }; let pass_mode = format!("{:?}", pass_mode); fx.add_global_comment(format!( - "{msg:5} {local:>3}{local_field:<5} {params:10} {pass_mode:20} {ssa:10} {ty:?}", + "{msg:5} {local:>3}{local_field:<5} {params:10} {pass_mode:36} {ssa:10} {ty:?}", msg = msg, local = format!("{:?}", local), local_field = local_field, @@ -355,7 +355,7 @@ fn add_arg_comment<'a, 'tcx: 'a>( #[cfg(debug_assertions)] fn add_local_header_comment(fx: &mut FunctionCx) { fx.add_global_comment(format!( - "msg loc.idx param pass mode ssa flags ty" + "msg loc.idx param pass mode ssa flags ty" )); } From 718a5a2e3f8190d30c527692cf700fdd761d3712 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Jul 2019 14:52:37 +0200 Subject: [PATCH 21/26] Display span in Assert panic message --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 6476de765..3d09b7cef 100644 --- a/src/base.rs +++ b/src/base.rs @@ -164,7 +164,7 @@ fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>) } else { fx.bcx.ins().brz(cond, target, &[]); }; - trap_panic(fx, format!("[panic] Assert {:?} failed at {:?}.", msg, bb_data.terminator().source_info.span)); + trap_panic(fx, format!("[panic] Assert {:?} at {:?} failed.", msg, bb_data.terminator().source_info.span)); } TerminatorKind::SwitchInt { From b46c8bfb7e2803f50cde344bd21e8f9deb59d62d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Jul 2019 14:55:55 +0200 Subject: [PATCH 22/26] Use std checked_div --- example/std_example.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index bd51a37f2..a09e050ce 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -34,8 +34,8 @@ fn main() { assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26); assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); - checked_div_i128(0i128, 2i128); - checked_div_u128(0u128, 2u128); + 0i128.checked_div(2i128); + 0u128.checked_div(2u128); assert_eq!(1u128 + 2, 3); assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128); @@ -61,18 +61,3 @@ fn map(a: Option<(u8, Box)>) -> Option> { Some((_, instr)) => Some(instr), } } - -fn checked_div_i128(lhs: i128, rhs: i128) -> Option { - if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) { - None - } else { - Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) - } -} - -fn checked_div_u128(lhs: u128, rhs: u128) -> Option { - match rhs { - 0 => None, - rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) }) - } -} From 0a833ba8a1b04281ec06892262ca326d259d1e41 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Jul 2019 15:49:38 +0200 Subject: [PATCH 23/26] [WIP] --- build_sysroot/Cargo.toml | 8 +--- build_sysroot/build_sysroot.sh | 2 - build_sysroot/compiler-builtins | 1 + build_sysroot/compiler_builtins/Cargo.toml | 20 ---------- build_sysroot/compiler_builtins/lib.rs | 9 ----- example/alloc_example.rs | 25 ++----------- src/lib.rs | 2 + test.sh | 43 ---------------------- 8 files changed, 9 insertions(+), 101 deletions(-) create mode 160000 build_sysroot/compiler-builtins delete mode 100644 build_sysroot/compiler_builtins/Cargo.toml delete mode 100644 build_sysroot/compiler_builtins/lib.rs diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index 532216ba8..af199c757 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -5,16 +5,12 @@ version = "0.0.0" [dependencies] core = { path = "./sysroot_src/src/libcore" } -compiler_builtins = "0.1" -alloc = { path = "./sysroot_src/src/liballoc" } -std = { path = "./sysroot_src/src/libstd" } - -alloc_system = { path = "./alloc_system" } +compiler_builtins = { version = "0.1", features = ["rustc-dep-of-std"] } [patch.crates-io] rustc-std-workspace-core = { path = "./sysroot_src/src/tools/rustc-std-workspace-core" } rustc-std-workspace-alloc = { path = "./rustc-std-workspace-alloc" } -#compiler_builtins = { path = "./compiler_builtins" } +compiler_builtins = { path = "./compiler-builtins" } [profile.release] debug = true diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index 57752c402..ea5e4a169 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -4,8 +4,6 @@ cd $(dirname "$0") # Cleanup for previous run # v Clean target dir except for build scripts and incremental cache -rm -r target/*/{debug,release}/{build,deps,examples,libsysroot*,native} || true -rm Cargo.lock 2>/dev/null || true rm -r sysroot 2>/dev/null || true # FIXME find a better way to get the target triple diff --git a/build_sysroot/compiler-builtins b/build_sysroot/compiler-builtins new file mode 160000 index 000000000..36da64f20 --- /dev/null +++ b/build_sysroot/compiler-builtins @@ -0,0 +1 @@ +Subproject commit 36da64f20e96206ac279f700586817c8abe3bdf8 diff --git a/build_sysroot/compiler_builtins/Cargo.toml b/build_sysroot/compiler_builtins/Cargo.toml deleted file mode 100644 index 724a637a2..000000000 --- a/build_sysroot/compiler_builtins/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "compiler_builtins" -# Make sure the `compiler_builtins` from crates.io doesn't take precedence over this -# replacement by specifying a higher version than the one on crates.io. -version = "0.1.100" -authors = ["bjorn3 "] -edition = "2018" - -[lib] -name = "compiler_builtins" -path = "lib.rs" -test = false -doc = false - -[dependencies] -core = { path = "../sysroot_src/src/libcore" } - -[features] -rustc-dep-of-std = [] -c = [] diff --git a/build_sysroot/compiler_builtins/lib.rs b/build_sysroot/compiler_builtins/lib.rs deleted file mode 100644 index 79a54a3a4..000000000 --- a/build_sysroot/compiler_builtins/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(compiler_builtins, staged_api)] -#![compiler_builtins] -#![no_std] - -#![unstable( - feature = "compiler_builtins_lib", - reason = "Compiler builtins. Will never become stable.", - issue = "0" -)] diff --git a/example/alloc_example.rs b/example/alloc_example.rs index 20a8642cb..497f5fbdb 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,16 +1,6 @@ -#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)] +#![feature(start, box_syntax, core_intrinsics, alloc_error_handler)] #![no_std] -extern crate alloc; -extern crate alloc_system; - -use alloc::prelude::v1::*; - -use alloc_system::System; - -#[global_allocator] -static ALLOC: System = System; - #[link(name = "c")] extern "C" { fn puts(s: *const u8); @@ -23,19 +13,12 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { } } -#[alloc_error_handler] -fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { - unsafe { - core::intrinsics::abort(); - } -} - #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { - let world: Box<&str> = box "Hello World!\0"; - unsafe { - puts(*world as *const str as *const u8); + extern "C" { + fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool); } + assert_eq!(unsafe { __rust_u128_mulo(353985398u128, 932490u128).0 }, 330087843781020u128); 0 } diff --git a/src/lib.rs b/src/lib.rs index df53d741a..8a4e79d54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -243,6 +243,8 @@ fn build_isa(sess: &Session) -> Box { "false" }).unwrap(); + flags_builder.set("opt_level", "best").unwrap(); + // FIXME enable again when https://github.com/CraneStation/cranelift/issues/664 is fixed /* use rustc::session::config::OptLevel; diff --git a/test.sh b/test.sh index 1dfbf9247..2b8f9ad73 100755 --- a/test.sh +++ b/test.sh @@ -4,52 +4,9 @@ source config.sh rm -r target/out || true mkdir -p target/out/clif -echo "[BUILD] mini_core" -$RUSTC example/mini_core.rs --crate-name mini_core --crate-type dylib - -echo "[BUILD] example" -$RUSTC example/example.rs --crate-type lib - -echo "[JIT] mini_core_hello_world" -SHOULD_RUN=1 JIT_ARGS="abc bcd" $RUSTC --crate-type bin example/mini_core_hello_world.rs --cfg jit - -echo "[AOT] mini_core_hello_world" -$RUSTC example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin -./target/out/mini_core_hello_world abc bcd - -echo "[AOT] arbitrary_self_types_pointers_and_wrappers" -$RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin -./target/out/arbitrary_self_types_pointers_and_wrappers - echo "[BUILD] sysroot" time ./build_sysroot/build_sysroot.sh echo "[BUILD+RUN] alloc_example" $RUSTC example/alloc_example.rs --crate-type bin ./target/out/alloc_example - -echo "[BUILD+RUN] std_example" -$RUSTC example/std_example.rs --crate-type bin -./target/out/std_example - -echo "[BUILD] mod_bench" -$RUSTC example/mod_bench.rs --crate-type bin - -# FIXME linker gives multiple definitions error on Linux -#echo "[BUILD] sysroot in release mode" -#./build_sysroot/build_sysroot.sh --release - -COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline" -COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o target/out/mod_bench_llvm_0 -Cpanic=abort" -COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o target/out/mod_bench_llvm_1 -Cpanic=abort" -COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o target/out/mod_bench_llvm_2 -Cpanic=abort" -COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o target/out/mod_bench_llvm_3 -Cpanic=abort" - -# Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow -hyperfine --runs 100 "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3" - -echo -echo "[Bench] mod_bench" -hyperfine ./target/out/mod_bench{,_inline} ./target/out/mod_bench_llvm_* - -cat target/out/log.txt | sort | uniq -c From ffa34ae328c2132cf589b4f2937b507d3331add4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Jul 2019 11:45:01 +0200 Subject: [PATCH 24/26] Remove unnecessary changes --- build_sysroot/Cargo.toml | 7 ++++-- build_sysroot/build_sysroot.sh | 2 ++ build_sysroot/compiler-builtins | 1 - example/alloc_example.rs | 25 ++++++++++++++++--- example/mini_core.rs | 8 ------ test.sh | 43 +++++++++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 15 deletions(-) delete mode 160000 build_sysroot/compiler-builtins diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index af199c757..90d245522 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -5,12 +5,15 @@ version = "0.0.0" [dependencies] core = { path = "./sysroot_src/src/libcore" } -compiler_builtins = { version = "0.1", features = ["rustc-dep-of-std"] } +compiler_builtins = "0.1" +alloc = { path = "./sysroot_src/src/liballoc" } +std = { path = "./sysroot_src/src/libstd" } + +alloc_system = { path = "./alloc_system" } [patch.crates-io] rustc-std-workspace-core = { path = "./sysroot_src/src/tools/rustc-std-workspace-core" } rustc-std-workspace-alloc = { path = "./rustc-std-workspace-alloc" } -compiler_builtins = { path = "./compiler-builtins" } [profile.release] debug = true diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index ea5e4a169..57752c402 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -4,6 +4,8 @@ cd $(dirname "$0") # Cleanup for previous run # v Clean target dir except for build scripts and incremental cache +rm -r target/*/{debug,release}/{build,deps,examples,libsysroot*,native} || true +rm Cargo.lock 2>/dev/null || true rm -r sysroot 2>/dev/null || true # FIXME find a better way to get the target triple diff --git a/build_sysroot/compiler-builtins b/build_sysroot/compiler-builtins deleted file mode 160000 index 36da64f20..000000000 --- a/build_sysroot/compiler-builtins +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 36da64f20e96206ac279f700586817c8abe3bdf8 diff --git a/example/alloc_example.rs b/example/alloc_example.rs index 497f5fbdb..20a8642cb 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,6 +1,16 @@ -#![feature(start, box_syntax, core_intrinsics, alloc_error_handler)] +#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)] #![no_std] +extern crate alloc; +extern crate alloc_system; + +use alloc::prelude::v1::*; + +use alloc_system::System; + +#[global_allocator] +static ALLOC: System = System; + #[link(name = "c")] extern "C" { fn puts(s: *const u8); @@ -13,12 +23,19 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { } } +#[alloc_error_handler] +fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { + unsafe { + core::intrinsics::abort(); + } +} + #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { - extern "C" { - fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool); + let world: Box<&str> = box "Hello World!\0"; + unsafe { + puts(*world as *const str as *const u8); } - assert_eq!(unsafe { __rust_u128_mulo(353985398u128, 932490u128).0 }, 330087843781020u128); 0 } diff --git a/example/mini_core.rs b/example/mini_core.rs index 191f465fb..069a930e0 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -318,14 +318,6 @@ impl Neg for i16 { } } -impl Neg for i128 { - type Output = i128; - - fn neg(self) -> i128 { - -self - } -} - impl Neg for isize { type Output = isize; diff --git a/test.sh b/test.sh index 2b8f9ad73..1dfbf9247 100755 --- a/test.sh +++ b/test.sh @@ -4,9 +4,52 @@ source config.sh rm -r target/out || true mkdir -p target/out/clif +echo "[BUILD] mini_core" +$RUSTC example/mini_core.rs --crate-name mini_core --crate-type dylib + +echo "[BUILD] example" +$RUSTC example/example.rs --crate-type lib + +echo "[JIT] mini_core_hello_world" +SHOULD_RUN=1 JIT_ARGS="abc bcd" $RUSTC --crate-type bin example/mini_core_hello_world.rs --cfg jit + +echo "[AOT] mini_core_hello_world" +$RUSTC example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin +./target/out/mini_core_hello_world abc bcd + +echo "[AOT] arbitrary_self_types_pointers_and_wrappers" +$RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin +./target/out/arbitrary_self_types_pointers_and_wrappers + echo "[BUILD] sysroot" time ./build_sysroot/build_sysroot.sh echo "[BUILD+RUN] alloc_example" $RUSTC example/alloc_example.rs --crate-type bin ./target/out/alloc_example + +echo "[BUILD+RUN] std_example" +$RUSTC example/std_example.rs --crate-type bin +./target/out/std_example + +echo "[BUILD] mod_bench" +$RUSTC example/mod_bench.rs --crate-type bin + +# FIXME linker gives multiple definitions error on Linux +#echo "[BUILD] sysroot in release mode" +#./build_sysroot/build_sysroot.sh --release + +COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline" +COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o target/out/mod_bench_llvm_0 -Cpanic=abort" +COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o target/out/mod_bench_llvm_1 -Cpanic=abort" +COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o target/out/mod_bench_llvm_2 -Cpanic=abort" +COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o target/out/mod_bench_llvm_3 -Cpanic=abort" + +# Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow +hyperfine --runs 100 "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3" + +echo +echo "[Bench] mod_bench" +hyperfine ./target/out/mod_bench{,_inline} ./target/out/mod_bench_llvm_* + +cat target/out/log.txt | sort | uniq -c From ca714e4f01d921b4627e913c26081df1fbacb627 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Jul 2019 11:47:27 +0200 Subject: [PATCH 25/26] Update Readme.md --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 5fc18c82e..56b65cf3e 100644 --- a/Readme.md +++ b/Readme.md @@ -29,10 +29,9 @@ $ RUSTFLAGS="-Cpanic=abort -Zcodegen-backend=$cg_clif_dir/target/debug/librustc_ ## Not yet supported -* Good non-rust abi support ([scalar pair and vector are passed by-ref](https://github.com/bjorn3/rustc_codegen_cranelift/issues/10)) +* Good non-rust abi support ([vectors are passed by-ref](https://github.com/bjorn3/rustc_codegen_cranelift/issues/10)) * Checked binops ([some missing instructions in cranelift](https://github.com/CraneStation/cranelift/issues/460)) * Inline assembly ([no cranelift support](https://github.com/CraneStation/cranelift/issues/444)) -* u128 and i128 ([no cranelift support](https://github.com/CraneStation/cranelift/issues/354)) * SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171)) ## Troubleshooting From 770c12ac9723cd4ecfa549a0903adf68a6c2be48 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Jul 2019 12:02:51 +0200 Subject: [PATCH 26/26] Use own branch of clif instead of local checkout --- Cargo.lock | 60 ++++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 16 ++++++++++----- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 675210800..139fb70fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,25 +117,28 @@ dependencies = [ [[package]] name = "cranelift" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", - "cranelift-frontend 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-frontend 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", ] [[package]] name = "cranelift-bforest" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-entity 0.36.0", + "cranelift-entity 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", ] [[package]] name = "cranelift-codegen" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-bforest 0.36.0", - "cranelift-codegen-meta 0.36.0", - "cranelift-entity 0.36.0", + "cranelift-bforest 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-codegen-meta 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-entity 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -145,20 +148,23 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-entity 0.36.0", + "cranelift-entity 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", ] [[package]] name = "cranelift-entity" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" [[package]] name = "cranelift-faerie" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", - "cranelift-module 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-module 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "faerie 0.10.1 (git+https://github.com/m4b/faerie.git)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -168,8 +174,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -177,9 +184,10 @@ dependencies = [ [[package]] name = "cranelift-module" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", - "cranelift-entity 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-entity 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -187,8 +195,9 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -196,10 +205,11 @@ dependencies = [ [[package]] name = "cranelift-simplejit" version = "0.36.0" +source = "git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128#ca836a8e0d0b62e2ddecb5902cd5091b468a4db3" dependencies = [ - "cranelift-codegen 0.36.0", - "cranelift-module 0.36.0", - "cranelift-native 0.36.0", + "cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-module 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-native 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -601,10 +611,10 @@ dependencies = [ "ar 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift 0.36.0", - "cranelift-faerie 0.36.0", - "cranelift-module 0.36.0", - "cranelift-simplejit 0.36.0", + "cranelift 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-faerie 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-module 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", + "cranelift-simplejit 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)", "faerie 0.10.1 (git+https://github.com/m4b/faerie.git)", "gimli 0.19.0 (git+https://github.com/gimli-rs/gimli.git)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -872,6 +882,16 @@ dependencies = [ "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum cranelift 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-bforest 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-codegen 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-codegen-meta 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-entity 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-faerie 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-frontend 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-module 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-native 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" +"checksum cranelift-simplejit 0.36.0 (git+https://github.com/bjorn3/cretonne.git?branch=do_not_remove_cg_clif_i128)" = "" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" diff --git a/Cargo.toml b/Cargo.toml index 64126d917..414423d72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,18 @@ gimli = { git = "https://github.com/gimli-rs/gimli.git" } indexmap = "1.0.2" object = "0.12.0" -# Uncomment to use local checkout of cranelift [patch."https://github.com/CraneStation/cranelift.git"] -cranelift = { path = "../cranelift/cranelift-umbrella" } -cranelift-module = { path = "../cranelift/cranelift-module" } -cranelift-simplejit = { path = "../cranelift/cranelift-simplejit" } -cranelift-faerie = { path = "../cranelift/cranelift-faerie" } +cranelift = { git = "https://github.com/bjorn3/cretonne.git", branch = "do_not_remove_cg_clif_i128" } +cranelift-module = { git = "https://github.com/bjorn3/cretonne.git", branch = "do_not_remove_cg_clif_i128" } +cranelift-simplejit = { git = "https://github.com/bjorn3/cretonne.git", branch = "do_not_remove_cg_clif_i128" } +cranelift-faerie = { git = "https://github.com/bjorn3/cretonne.git", branch = "do_not_remove_cg_clif_i128" } + +# Uncomment to use local checkout of cranelift +#[patch."https://github.com/CraneStation/cranelift.git"] +#cranelift = { path = "../cranelift/cranelift-umbrella" } +#cranelift-module = { path = "../cranelift/cranelift-module" } +#cranelift-simplejit = { path = "../cranelift/cranelift-simplejit" } +#cranelift-faerie = { path = "../cranelift/cranelift-faerie" } #[patch."https://github.com/gimli-rs/gimli.git"] #gimli = { path = "../" }