authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-26 07:40:40+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-04 11:25:29+02:00
loga73369244471cf15ed8eda624e86c435a5df295f
treef3141373dbf9aa9b90d998a3749a91864cb55a97
parentb58cf6dab6ff64c3403d3776a430694534f7b818

Update Value.intTrunc to use new big int truncate


2 files changed, 19 insertions(+), 7 deletions(-)

src/Sema.zig+1-1
......@@ -9017,7 +9017,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
90179017
90189018 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
90199019 if (val.isUndef()) return sema.addConstUndef(dest_ty);
9020 return sema.addConstant(dest_ty, try val.intTrunc(sema.arena, dest_info.bits));
9020 return sema.addConstant(dest_ty, try val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits));
90219021 }
90229022
90239023 try sema.requireRuntimeBlock(block, src);
src/value.zig+18-6
......@@ -2136,12 +2136,24 @@ pub const Value = extern union {
21362136 }
21372137 }
21382138
2139 pub fn intTrunc(val: Value, arena: *Allocator, bits: u16) !Value {
2140 const x = val.toUnsignedInt(); // TODO: implement comptime truncate on big ints
2141 if (bits == 64) return val;
2142 const mask = (@as(u64, 1) << @intCast(u6, bits)) - 1;
2143 const truncated = x & mask;
2144 return Tag.int_u64.create(arena, truncated);
2139 pub fn intTrunc(val: Value, allocator: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
2140 var val_space: Value.BigIntSpace = undefined;
2141 const val_bigint = val.toBigInt(&val_space);
2142
2143 const limbs = try allocator.alloc(
2144 std.math.big.Limb,
2145 std.math.big.int.calcTwosCompLimbCount(bits),
2146 );
2147 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
2148
2149 result_bigint.truncate(val_bigint, signedness, bits);
2150 const result_limbs = result_bigint.limbs[0..result_bigint.len];
2151
2152 if (result_bigint.positive) {
2153 return Value.Tag.int_big_positive.create(allocator, result_limbs);
2154 } else {
2155 return Value.Tag.int_big_negative.create(allocator, result_limbs);
2156 }
21452157 }
21462158
21472159 pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value {