authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-12 21:31:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-15 19:06:39-07:00
logdf983b30d2b890e21fba214145ccc4f4a263359d
tree73fd28891eac924b27c7e4ed6a6c13d8daf3f54c
parent69645e28171829a3c53ee5359e08562bddd174f7

stage2: implement comptime division


2 files changed, 71 insertions(+), 0 deletions(-)

src/Module.zig+64
......@@ -4585,6 +4585,37 @@ pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
45854585 }
45864586}
45874587
4588pub fn intDiv(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
4589 // TODO is this a performance issue? maybe we should try the operation without
4590 // resorting to BigInt first.
4591 var lhs_space: Value.BigIntSpace = undefined;
4592 var rhs_space: Value.BigIntSpace = undefined;
4593 const lhs_bigint = lhs.toBigInt(&lhs_space);
4594 const rhs_bigint = rhs.toBigInt(&rhs_space);
4595 const limbs_q = try allocator.alloc(
4596 std.math.big.Limb,
4597 lhs_bigint.limbs.len + rhs_bigint.limbs.len + 1,
4598 );
4599 const limbs_r = try allocator.alloc(
4600 std.math.big.Limb,
4601 lhs_bigint.limbs.len,
4602 );
4603 const limbs_buffer = try allocator.alloc(
4604 std.math.big.Limb,
4605 std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
4606 );
4607 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
4608 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
4609 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer, null);
4610 const result_limbs = result_q.limbs[0..result_q.len];
4611
4612 if (result_q.positive) {
4613 return Value.Tag.int_big_positive.create(allocator, result_limbs);
4614 } else {
4615 return Value.Tag.int_big_negative.create(allocator, result_limbs);
4616 }
4617}
4618
45884619pub fn floatAdd(
45894620 arena: *Allocator,
45904621 float_type: Type,
......@@ -4651,6 +4682,39 @@ pub fn floatSub(
46514682 }
46524683}
46534684
4685pub fn floatDiv(
4686 arena: *Allocator,
4687 float_type: Type,
4688 src: LazySrcLoc,
4689 lhs: Value,
4690 rhs: Value,
4691) !Value {
4692 switch (float_type.tag()) {
4693 .f16 => {
4694 @panic("TODO add __trunctfhf2 to compiler-rt");
4695 //const lhs_val = lhs.toFloat(f16);
4696 //const rhs_val = rhs.toFloat(f16);
4697 //return Value.Tag.float_16.create(arena, lhs_val / rhs_val);
4698 },
4699 .f32 => {
4700 const lhs_val = lhs.toFloat(f32);
4701 const rhs_val = rhs.toFloat(f32);
4702 return Value.Tag.float_32.create(arena, lhs_val / rhs_val);
4703 },
4704 .f64 => {
4705 const lhs_val = lhs.toFloat(f64);
4706 const rhs_val = rhs.toFloat(f64);
4707 return Value.Tag.float_64.create(arena, lhs_val / rhs_val);
4708 },
4709 .f128, .comptime_float, .c_longdouble => {
4710 const lhs_val = lhs.toFloat(f128);
4711 const rhs_val = rhs.toFloat(f128);
4712 return Value.Tag.float_128.create(arena, lhs_val / rhs_val);
4713 },
4714 else => unreachable,
4715 }
4716}
4717
46544718pub fn simplePtrType(
46554719 mod: *Module,
46564720 arena: *Allocator,
src/Sema.zig+7
......@@ -4139,6 +4139,13 @@ fn analyzeArithmetic(
41394139 try Module.floatSub(sema.arena, scalar_type, src, lhs_val, rhs_val);
41404140 break :blk val;
41414141 },
4142 .div => blk: {
4143 const val = if (is_int)
4144 try Module.intDiv(sema.arena, lhs_val, rhs_val)
4145 else
4146 try Module.floatDiv(sema.arena, scalar_type, src, lhs_val, rhs_val);
4147 break :blk val;
4148 },
41424149 else => return sema.mod.fail(&block.base, src, "TODO Implement arithmetic operand '{s}'", .{@tagName(zir_tag)}),
41434150 };
41444151