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(...@@ -6502,13 +6502,13 @@ fn zirShl(
6502 if (rhs_val.compareWithZero(.eq)) {6502 if (rhs_val.compareWithZero(.eq)) {
6503 return sema.addConstant(lhs_ty, lhs_val);6503 return sema.addConstant(lhs_ty, lhs_val);
6504 }6504 }
6505 const val = try lhs_val.shl(rhs_val, sema.arena);6505 const val = switch (air_tag) {
6506 switch (air_tag) {
6507 .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}),6506 .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", .{}),6507 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
6509 .shl => {},6508 .shl => try lhs_val.shl(rhs_val, sema.arena),
6510 else => unreachable,6509 else => unreachable,
6511 }6510 };
6511
6512 return sema.addConstant(lhs_ty, val);6512 return sema.addConstant(lhs_ty, val);
6513 } else rs: {6513 } else rs: {
6514 if (maybe_rhs_val) |rhs_val| {6514 if (maybe_rhs_val) |rhs_val| {
src/value.zig+33
...@@ -2404,6 +2404,39 @@ pub const Value = extern union {...@@ -2404,6 +2404,39 @@ pub const Value = extern union {
2404 }2404 }
2405 }2405 }
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
2407 pub fn shr(lhs: Value, rhs: Value, allocator: *Allocator) !Value {2440 pub fn shr(lhs: Value, rhs: Value, allocator: *Allocator) !Value {
2408 // TODO is this a performance issue? maybe we should try the operation without2441 // TODO is this a performance issue? maybe we should try the operation without
2409 // resorting to BigInt first.2442 // resorting to BigInt first.
test/behavior.zig-1
...@@ -146,7 +146,6 @@ test {...@@ -146,7 +146,6 @@ test {
146 {146 {
147 // Checklist for getting saturating_arithmetic.zig passing for stage2:147 // Checklist for getting saturating_arithmetic.zig passing for stage2:
148 // * add __muloti4 to compiler-rt148 // * add __muloti4 to compiler-rt
149 // * implement comptime saturating shift-left
150 _ = @import("behavior/saturating_arithmetic.zig");149 _ = @import("behavior/saturating_arithmetic.zig");
151 }150 }
152 _ = @import("behavior/shuffle.zig");151 _ = @import("behavior/shuffle.zig");