Fix signed cast to 128bit integer

This commit is contained in:
bjorn3 2019-11-16 16:44:26 +01:00
parent d2eafd858f
commit b0bcb23eb4
2 changed files with 13 additions and 4 deletions

View file

@ -53,7 +53,12 @@ fn main() {
assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128); assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128);
assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 >> 64, 0xFEDCBA98765432u128); assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 >> 64, 0xFEDCBA98765432u128);
assert_eq!(0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64, 0xFEDCBA98765432i128); 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. // Check that all u/i128 <-> float casts work correctly.
let houndred_u128 = 100u128; let houndred_u128 = 100u128;

View file

@ -13,15 +13,19 @@ pub fn clif_intcast(
// extend // extend
(_, types::I128) => { (_, types::I128) => {
let wider = if from == types::I64 { let lo = if from == types::I64 {
val val
} else if signed { } else if signed {
fx.bcx.ins().sextend(types::I64, val) fx.bcx.ins().sextend(types::I64, val)
} else { } else {
fx.bcx.ins().uextend(types::I64, val) fx.bcx.ins().uextend(types::I64, val)
}; };
let zero = fx.bcx.ins().iconst(types::I64, 0); let hi = if signed {
fx.bcx.ins().iconcat(wider, zero) 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 to.wider_or_equal(from) => {
if signed { if signed {