diff --git a/example/std_example.rs b/example/std_example.rs index 50f794733e3..d6734e74498 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -53,7 +53,12 @@ fn main() { assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128); assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 >> 64, 0xFEDCBA98765432u128); assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64, 0xFEDCBA98765432i128); - assert_eq!(353985398u128 * 932490u128, 330087843781020u128); + + let tmp = 353985398u128; + assert_eq!(tmp * 932490u128, 330087843781020u128); + + let tmp = -0x1234_5678_9ABC_DEF0i64; + assert_eq!(tmp as i128, -0x1234_5678_9ABC_DEF0i128); // Check that all u/i128 <-> float casts work correctly. let houndred_u128 = 100u128; diff --git a/src/cast.rs b/src/cast.rs index 41503ea86c8..870c316f41d 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -13,15 +13,19 @@ pub fn clif_intcast( // extend (_, types::I128) => { - let wider = if from == types::I64 { + let lo = 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) + let hi = if signed { + fx.bcx.ins().sshr_imm(lo, 63) + } else { + fx.bcx.ins().iconst(types::I64, 0) + }; + fx.bcx.ins().iconcat(lo, hi) } (_, _) if to.wider_or_equal(from) => { if signed {