authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-16 00:13:33+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-16 11:32:05+02:00
logf6bf24b2f3e1d65ce66625c4466aa2af9edff41c
treef4534875df693da5f00a91725bf7fbe9f8600dd5
parentefa4f76c8bb9cbeacc1bcda89d95db4120c821d5

stage2: comptime saturating shl


3 files changed, 38 insertions(+), 6 deletions(-)

src/Sema.zig+5-5
......@@ -6502,13 +6502,13 @@ fn zirShl(
65026502 if (rhs_val.compareWithZero(.eq)) {
65036503 return sema.addConstant(lhs_ty, lhs_val);
65046504 }
6505 const val = try lhs_val.shl(rhs_val, sema.arena);
6506 switch (air_tag) {
6505 const val = switch (air_tag) {
65076506 .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}),
6508 .shl_sat => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_sat", .{}),
6509 .shl => {},
6507 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
6508 .shl => try lhs_val.shl(rhs_val, sema.arena),
65106509 else => unreachable,
6511 }
6510 };
6511
65126512 return sema.addConstant(lhs_ty, val);
65136513 } else rs: {
65146514 if (maybe_rhs_val) |rhs_val| {
src/value.zig+33
......@@ -2404,6 +2404,39 @@ pub const Value = extern union {
24042404 }
24052405 }
24062406
2407 pub fn shlSat(
2408 lhs: Value,
2409 rhs: Value,
2410 ty: Type,
2411 arena: *Allocator,
2412 target: Target,
2413 ) !Value {
2414 // TODO is this a performance issue? maybe we should try the operation without
2415 // resorting to BigInt first.
2416 const info = ty.intInfo(target);
2417
2418 var lhs_space: Value.BigIntSpace = undefined;
2419 const lhs_bigint = lhs.toBigInt(&lhs_space);
2420 const shift = rhs.toUnsignedInt();
2421 const limbs = try arena.alloc(
2422 std.math.big.Limb,
2423 std.math.big.int.calcTwosCompLimbCount(info.bits),
2424 );
2425 var result_bigint = BigIntMutable{
2426 .limbs = limbs,
2427 .positive = undefined,
2428 .len = undefined,
2429 };
2430 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);
2431 const result_limbs = result_bigint.limbs[0..result_bigint.len];
2432
2433 if (result_bigint.positive) {
2434 return Value.Tag.int_big_positive.create(arena, result_limbs);
2435 } else {
2436 return Value.Tag.int_big_negative.create(arena, result_limbs);
2437 }
2438 }
2439
24072440 pub fn shr(lhs: Value, rhs: Value, allocator: *Allocator) !Value {
24082441 // TODO is this a performance issue? maybe we should try the operation without
24092442 // resorting to BigInt first.
test/behavior.zig-1
......@@ -146,7 +146,6 @@ test {
146146 {
147147 // Checklist for getting saturating_arithmetic.zig passing for stage2:
148148 // * add __muloti4 to compiler-rt
149 // * implement comptime saturating shift-left
150149 _ = @import("behavior/saturating_arithmetic.zig");
151150 }
152151 _ = @import("behavior/shuffle.zig");