@@ -78,6 +78,7 @@ post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{},
78
78
err: ?*Module.ErrorMsg = null,
79
79
80
80
const std = @import("std");
81
+ const math = std.math;
81
82
const mem = std.mem;
82
83
const Allocator = std.mem.Allocator;
83
84
const assert = std.debug.assert;
@@ -11753,7 +11754,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
11753
11754
return sema.failWithDivideByZero(block, rhs_src);
11754
11755
}
11755
11756
if (maybe_lhs_val) |lhs_val| {
11756
- const rem_result = try lhs_val .intRem(rhs_val , resolved_type, sema.arena, target );
11757
+ const rem_result = try sema .intRem(block , resolved_type, lhs_val, lhs_src, rhs_val, rhs_src );
11757
11758
// If this answer could possibly be different by doing `intMod`,
11758
11759
// we must emit a compile error. Otherwise, it's OK.
11759
11760
if ((try rhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) != (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) and
@@ -11815,6 +11816,60 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
11815
11816
return block.addBinOp(air_tag, casted_lhs, casted_rhs);
11816
11817
}
11817
11818
11819
+ fn intRem(
11820
+ sema: *Sema,
11821
+ block: *Block,
11822
+ ty: Type,
11823
+ lhs: Value,
11824
+ lhs_src: LazySrcLoc,
11825
+ rhs: Value,
11826
+ rhs_src: LazySrcLoc,
11827
+ ) CompileError!Value {
11828
+ if (ty.zigTypeTag() == .Vector) {
11829
+ const result_data = try sema.arena.alloc(Value, ty.vectorLen());
11830
+ for (result_data) |*scalar, i| {
11831
+ scalar.* = try sema.intRemScalar(block, lhs.indexVectorlike(i), lhs_src, rhs.indexVectorlike(i), rhs_src);
11832
+ }
11833
+ return Value.Tag.aggregate.create(sema.arena, result_data);
11834
+ }
11835
+ return sema.intRemScalar(block, lhs, lhs_src, rhs, rhs_src);
11836
+ }
11837
+
11838
+ fn intRemScalar(
11839
+ sema: *Sema,
11840
+ block: *Block,
11841
+ lhs: Value,
11842
+ lhs_src: LazySrcLoc,
11843
+ rhs: Value,
11844
+ rhs_src: LazySrcLoc,
11845
+ ) CompileError!Value {
11846
+ const target = sema.mod.getTarget();
11847
+ // TODO is this a performance issue? maybe we should try the operation without
11848
+ // resorting to BigInt first.
11849
+ var lhs_space: Value.BigIntSpace = undefined;
11850
+ var rhs_space: Value.BigIntSpace = undefined;
11851
+ const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema.kit(block, lhs_src));
11852
+ const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema.kit(block, rhs_src));
11853
+ const limbs_q = try sema.arena.alloc(
11854
+ math.big.Limb,
11855
+ lhs_bigint.limbs.len,
11856
+ );
11857
+ const limbs_r = try sema.arena.alloc(
11858
+ math.big.Limb,
11859
+ // TODO: consider reworking Sema to re-use Values rather than
11860
+ // always producing new Value objects.
11861
+ rhs_bigint.limbs.len,
11862
+ );
11863
+ const limbs_buffer = try sema.arena.alloc(
11864
+ math.big.Limb,
11865
+ math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
11866
+ );
11867
+ var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
11868
+ var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
11869
+ result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
11870
+ return Value.fromBigInt(sema.arena, result_r.toConst());
11871
+ }
11872
+
11818
11873
fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
11819
11874
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
11820
11875
const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
@@ -11979,7 +12034,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
11979
12034
if (maybe_lhs_val) |lhs_val| {
11980
12035
return sema.addConstant(
11981
12036
resolved_type,
11982
- try lhs_val .intRem(rhs_val , resolved_type, sema.arena, target ),
12037
+ try sema .intRem(block , resolved_type, lhs_val, lhs_src, rhs_val, rhs_src ),
11983
12038
);
11984
12039
}
11985
12040
break :rs lhs_src;
0 commit comments