| author | |
| committer | |
| log | f6bf24b2f3e1d65ce66625c4466aa2af9edff41c |
| tree | f4534875df693da5f00a91725bf7fbe9f8600dd5 |
| parent | efa4f76c8bb9cbeacc1bcda89d95db4120c821d5 |
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 | } |
| 2406 | 2406 | ||
| 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 without | 2441 | // 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-rt | 148 | // * 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"); |