authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-30 17:23:14-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-06 19:27:54-07:00
log287ff4ab58f8af70383b6e334c7c862c8b8fbeec
tree6c4e9281e86886fe58075e78dd332b74cf640e7d
parentfd1284ebd07ded1c67bbaff4c14f093051e56f59

stage2: add more float arithmetic and f80 support

AstGen: Fixed bug where f80 types in source were triggering illegal behavior. Value: handle f80 in floating point arithmetic functions. Value: implement floatRem and floatMod This commit introduces dependencies on compiler-rt that are not implemented. Those are a prerequisite to merging this branch.

4 files changed, 178 insertions(+), 69 deletions(-)

src/AstGen.zig+4-2
......@@ -8409,10 +8409,11 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
84098409 .c_ushort_type,
84108410 .comptime_float_type,
84118411 .comptime_int_type,
8412 .f128_type,
84138412 .f16_type,
84148413 .f32_type,
84158414 .f64_type,
8415 .f80_type,
8416 .f128_type,
84168417 .i16_type,
84178418 .i32_type,
84188419 .i64_type,
......@@ -8648,10 +8649,11 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
86488649 .c_ulong_type,
86498650 .c_ulonglong_type,
86508651 .c_ushort_type,
8651 .f128_type,
86528652 .f16_type,
86538653 .f32_type,
86548654 .f64_type,
8655 .f80_type,
8656 .f128_type,
86558657 .i16_type,
86568658 .i32_type,
86578659 .i64_type,
src/Sema.zig+12-12
......@@ -8187,7 +8187,7 @@ fn analyzeArithmetic(
81878187 } else {
81888188 return sema.addConstant(
81898189 scalar_type,
8190 try lhs_val.floatAdd(rhs_val, scalar_type, sema.arena),
8190 try lhs_val.floatAdd(rhs_val, scalar_type, sema.arena, target),
81918191 );
81928192 }
81938193 } else break :rs .{ .src = rhs_src, .air_tag = .add };
......@@ -8280,7 +8280,7 @@ fn analyzeArithmetic(
82808280 } else {
82818281 return sema.addConstant(
82828282 scalar_type,
8283 try lhs_val.floatSub(rhs_val, scalar_type, sema.arena),
8283 try lhs_val.floatSub(rhs_val, scalar_type, sema.arena, target),
82848284 );
82858285 }
82868286 } else break :rs .{ .src = rhs_src, .air_tag = .sub };
......@@ -8396,7 +8396,7 @@ fn analyzeArithmetic(
83968396 } else {
83978397 return sema.addConstant(
83988398 scalar_type,
8399 try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena),
8399 try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena, target),
84008400 );
84018401 }
84028402 } else {
......@@ -8471,7 +8471,7 @@ fn analyzeArithmetic(
84718471 } else {
84728472 return sema.addConstant(
84738473 scalar_type,
8474 try lhs_val.floatDivTrunc(rhs_val, scalar_type, sema.arena),
8474 try lhs_val.floatDivTrunc(rhs_val, scalar_type, sema.arena, target),
84758475 );
84768476 }
84778477 } else break :rs .{ .src = rhs_src, .air_tag = .div_trunc };
......@@ -8534,7 +8534,7 @@ fn analyzeArithmetic(
85348534 } else {
85358535 return sema.addConstant(
85368536 scalar_type,
8537 try lhs_val.floatDivFloor(rhs_val, scalar_type, sema.arena),
8537 try lhs_val.floatDivFloor(rhs_val, scalar_type, sema.arena, target),
85388538 );
85398539 }
85408540 } else break :rs .{ .src = rhs_src, .air_tag = .div_floor };
......@@ -8586,7 +8586,7 @@ fn analyzeArithmetic(
85868586 // TODO: emit compile error if there is a remainder
85878587 return sema.addConstant(
85888588 scalar_type,
8589 try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena),
8589 try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena, target),
85908590 );
85918591 }
85928592 } else break :rs .{ .src = rhs_src, .air_tag = .div_exact };
......@@ -8641,7 +8641,7 @@ fn analyzeArithmetic(
86418641 } else {
86428642 return sema.addConstant(
86438643 scalar_type,
8644 try lhs_val.floatMul(rhs_val, scalar_type, sema.arena),
8644 try lhs_val.floatMul(rhs_val, scalar_type, sema.arena, target),
86458645 );
86468646 }
86478647 } else break :rs .{ .src = lhs_src, .air_tag = .mul };
......@@ -8797,7 +8797,7 @@ fn analyzeArithmetic(
87978797 }
87988798 return sema.addConstant(
87998799 scalar_type,
8800 try lhs_val.floatRem(rhs_val, sema.arena),
8800 try lhs_val.floatRem(rhs_val, scalar_type, sema.arena, target),
88018801 );
88028802 } else {
88038803 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
......@@ -8858,7 +8858,7 @@ fn analyzeArithmetic(
88588858 if (maybe_rhs_val) |rhs_val| {
88598859 return sema.addConstant(
88608860 scalar_type,
8861 try lhs_val.floatRem(rhs_val, sema.arena),
8861 try lhs_val.floatRem(rhs_val, scalar_type, sema.arena, target),
88628862 );
88638863 } else break :rs .{ .src = rhs_src, .air_tag = .rem };
88648864 } else break :rs .{ .src = lhs_src, .air_tag = .rem };
......@@ -8915,7 +8915,7 @@ fn analyzeArithmetic(
89158915 if (maybe_rhs_val) |rhs_val| {
89168916 return sema.addConstant(
89178917 scalar_type,
8918 try lhs_val.floatMod(rhs_val, sema.arena),
8918 try lhs_val.floatMod(rhs_val, scalar_type, sema.arena, target),
89198919 );
89208920 } else break :rs .{ .src = rhs_src, .air_tag = .mod };
89218921 } else break :rs .{ .src = lhs_src, .air_tag = .mod };
......@@ -14195,12 +14195,12 @@ fn coerce(
1419514195 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {
1419614196 .ComptimeFloat => {
1419714197 const val = try sema.resolveConstValue(block, inst_src, inst);
14198 const result_val = try val.floatCast(sema.arena, dest_ty);
14198 const result_val = try val.floatCast(sema.arena, dest_ty, target);
1419914199 return try sema.addConstant(dest_ty, result_val);
1420014200 },
1420114201 .Float => {
1420214202 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
14203 const result_val = try val.floatCast(sema.arena, dest_ty);
14203 const result_val = try val.floatCast(sema.arena, dest_ty, target);
1420414204 if (!val.eql(result_val, dest_ty)) {
1420514205 return sema.fail(
1420614206 block,
src/value.zig+162-53
......@@ -138,6 +138,7 @@ pub const Value = extern union {
138138 float_16,
139139 float_32,
140140 float_64,
141 float_80,
141142 float_128,
142143 enum_literal,
143144 /// A specific enum tag, indicated by the field index (declaration order).
......@@ -295,6 +296,7 @@ pub const Value = extern union {
295296 .float_16 => Payload.Float_16,
296297 .float_32 => Payload.Float_32,
297298 .float_64 => Payload.Float_64,
299 .float_80 => Payload.Float_80,
298300 .float_128 => Payload.Float_128,
299301 .@"error" => Payload.Error,
300302 .inferred_alloc => Payload.InferredAlloc,
......@@ -546,6 +548,7 @@ pub const Value = extern union {
546548 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),
547549 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),
548550 .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64),
551 .float_80 => return self.copyPayloadShallow(arena, Payload.Float_80),
549552 .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128),
550553 .enum_literal => {
551554 const payload = self.castTag(.enum_literal).?;
......@@ -733,6 +736,7 @@ pub const Value = extern union {
733736 .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}),
734737 .float_32 => return out_stream.print("{}", .{val.castTag(.float_32).?.data}),
735738 .float_64 => return out_stream.print("{}", .{val.castTag(.float_64).?.data}),
739 .float_80 => return out_stream.print("{}", .{val.castTag(.float_80).?.data}),
736740 .float_128 => return out_stream.print("{}", .{val.castTag(.float_128).?.data}),
737741 .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
738742 // TODO to print this it should be error{ Set, Items }!T(val), but we need the type for that
......@@ -1083,6 +1087,7 @@ pub const Value = extern union {
10831087 16 => return Value.Tag.float_16.create(arena, floatReadFromMemory(f16, target, buffer)),
10841088 32 => return Value.Tag.float_32.create(arena, floatReadFromMemory(f32, target, buffer)),
10851089 64 => return Value.Tag.float_64.create(arena, floatReadFromMemory(f64, target, buffer)),
1090 80 => return Value.Tag.float_80.create(arena, floatReadFromMemory(f80, target, buffer)),
10861091 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)),
10871092 else => unreachable,
10881093 },
......@@ -1100,6 +1105,12 @@ pub const Value = extern union {
11001105 }
11011106
11021107 fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F {
1108 if (F == f80) {
1109 // TODO: use std.math.F80Repr
1110 const big_int = std.mem.readInt(u128, buffer[0..16], target.cpu.arch.endian());
1111 const int = @truncate(u80, big_int);
1112 return @bitCast(F, int);
1113 }
11031114 const Int = @Type(.{ .Int = .{
11041115 .signedness = .unsigned,
11051116 .bits = @typeInfo(F).Float.bits,
......@@ -1114,6 +1125,7 @@ pub const Value = extern union {
11141125 .float_16 => @floatCast(T, val.castTag(.float_16).?.data),
11151126 .float_32 => @floatCast(T, val.castTag(.float_32).?.data),
11161127 .float_64 => @floatCast(T, val.castTag(.float_64).?.data),
1128 .float_80 => @floatCast(T, val.castTag(.float_80).?.data),
11171129 .float_128 => @floatCast(T, val.castTag(.float_128).?.data),
11181130
11191131 .zero => 0,
......@@ -1367,14 +1379,13 @@ pub const Value = extern union {
13671379
13681380 /// Converts an integer or a float to a float. May result in a loss of information.
13691381 /// Caller can find out by equality checking the result against the operand.
1370 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type) !Value {
1371 switch (dest_ty.tag()) {
1372 .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),
1373 .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),
1374 .f64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)),
1375 .f128, .comptime_float, .c_longdouble => {
1376 return Value.Tag.float_128.create(arena, self.toFloat(f128));
1377 },
1382 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, target: Target) !Value {
1383 switch (dest_ty.floatBits(target)) {
1384 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),
1385 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),
1386 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)),
1387 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80)),
1388 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128)),
13781389 else => unreachable,
13791390 }
13801391 }
......@@ -1389,8 +1400,8 @@ pub const Value = extern union {
13891400 .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0,
13901401 .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0,
13911402 .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,
1392 // .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
1393 .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"),
1403 .float_80 => @rem(self.castTag(.float_80).?.data, 1) != 0,
1404 .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
13941405
13951406 else => unreachable,
13961407 };
......@@ -1408,6 +1419,7 @@ pub const Value = extern union {
14081419 .float_16 => self.castTag(.float_16).?.data == 0,
14091420 .float_32 => self.castTag(.float_32).?.data == 0,
14101421 .float_64 => self.castTag(.float_64).?.data == 0,
1422 .float_80 => self.castTag(.float_80).?.data == 0,
14111423 .float_128 => self.castTag(.float_128).?.data == 0,
14121424
14131425 .int_big_positive => self.castTag(.int_big_positive).?.asBigInt().eqZero(),
......@@ -1440,6 +1452,7 @@ pub const Value = extern union {
14401452 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
14411453 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
14421454 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
1455 .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
14431456 .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
14441457
14451458 else => unreachable,
......@@ -1471,6 +1484,7 @@ pub const Value = extern union {
14711484 .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data),
14721485 .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data),
14731486 .float_64 => return std.math.order(lhs.castTag(.float_64).?.data, rhs.castTag(.float_64).?.data),
1487 .float_80 => return std.math.order(lhs.castTag(.float_80).?.data, rhs.castTag(.float_80).?.data),
14741488 .float_128 => return std.math.order(lhs.castTag(.float_128).?.data, rhs.castTag(.float_128).?.data),
14751489 else => unreachable,
14761490 };
......@@ -2139,6 +2153,7 @@ pub const Value = extern union {
21392153 .float_16,
21402154 .float_32,
21412155 .float_64,
2156 .float_80,
21422157 .float_128,
21432158 => true,
21442159 else => false,
......@@ -2174,6 +2189,7 @@ pub const Value = extern union {
21742189 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)),
21752190 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)),
21762191 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)),
2192 80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)),
21772193 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)),
21782194 else => unreachable,
21792195 }
......@@ -2184,6 +2200,7 @@ pub const Value = extern union {
21842200 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)),
21852201 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)),
21862202 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)),
2203 80 => return Value.Tag.float_80.create(arena, @floatCast(f80, float)),
21872204 128 => return Value.Tag.float_128.create(arena, float),
21882205 else => unreachable,
21892206 }
......@@ -2281,7 +2298,7 @@ pub const Value = extern union {
22812298 }
22822299
22832300 if (ty.isAnyFloat()) {
2284 return floatAdd(lhs, rhs, ty, arena);
2301 return floatAdd(lhs, rhs, ty, arena, target);
22852302 }
22862303
22872304 const overflow_result = try intAddWithOverflow(lhs, rhs, ty, arena, target);
......@@ -2371,7 +2388,7 @@ pub const Value = extern union {
23712388 }
23722389
23732390 if (ty.isAnyFloat()) {
2374 return floatSub(lhs, rhs, ty, arena);
2391 return floatSub(lhs, rhs, ty, arena, target);
23752392 }
23762393
23772394 const overflow_result = try intSubWithOverflow(lhs, rhs, ty, arena, target);
......@@ -2454,7 +2471,7 @@ pub const Value = extern union {
24542471 }
24552472
24562473 if (ty.isAnyFloat()) {
2457 return floatMul(lhs, rhs, ty, arena);
2474 return floatMul(lhs, rhs, ty, arena, target);
24582475 }
24592476
24602477 const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, target);
......@@ -2753,23 +2770,72 @@ pub const Value = extern union {
27532770 .float_16 => std.math.isNan(val.castTag(.float_16).?.data),
27542771 .float_32 => std.math.isNan(val.castTag(.float_32).?.data),
27552772 .float_64 => std.math.isNan(val.castTag(.float_64).?.data),
2773 .float_80 => std.math.isNan(val.castTag(.float_80).?.data),
27562774 .float_128 => std.math.isNan(val.castTag(.float_128).?.data),
27572775 else => false,
27582776 };
27592777 }
27602778
2761 pub fn floatRem(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2762 _ = lhs;
2763 _ = rhs;
2764 _ = allocator;
2765 @panic("TODO implement Value.floatRem");
2779 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value {
2780 switch (float_type.floatBits(target)) {
2781 16 => {
2782 const lhs_val = lhs.toFloat(f16);
2783 const rhs_val = rhs.toFloat(f16);
2784 return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val));
2785 },
2786 32 => {
2787 const lhs_val = lhs.toFloat(f32);
2788 const rhs_val = rhs.toFloat(f32);
2789 return Value.Tag.float_32.create(arena, @rem(lhs_val, rhs_val));
2790 },
2791 64 => {
2792 const lhs_val = lhs.toFloat(f64);
2793 const rhs_val = rhs.toFloat(f64);
2794 return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val));
2795 },
2796 80 => {
2797 const lhs_val = lhs.toFloat(f80);
2798 const rhs_val = rhs.toFloat(f80);
2799 return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val));
2800 },
2801 128 => {
2802 const lhs_val = lhs.toFloat(f128);
2803 const rhs_val = rhs.toFloat(f128);
2804 return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val));
2805 },
2806 else => unreachable,
2807 }
27662808 }
27672809
2768 pub fn floatMod(lhs: Value, rhs: Value, allocator: Allocator) !Value {
2769 _ = lhs;
2770 _ = rhs;
2771 _ = allocator;
2772 @panic("TODO implement Value.floatMod");
2810 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value {
2811 switch (float_type.floatBits(target)) {
2812 16 => {
2813 const lhs_val = lhs.toFloat(f16);
2814 const rhs_val = rhs.toFloat(f16);
2815 return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val));
2816 },
2817 32 => {
2818 const lhs_val = lhs.toFloat(f32);
2819 const rhs_val = rhs.toFloat(f32);
2820 return Value.Tag.float_32.create(arena, @mod(lhs_val, rhs_val));
2821 },
2822 64 => {
2823 const lhs_val = lhs.toFloat(f64);
2824 const rhs_val = rhs.toFloat(f64);
2825 return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val));
2826 },
2827 80 => {
2828 const lhs_val = lhs.toFloat(f80);
2829 const rhs_val = rhs.toFloat(f80);
2830 return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val));
2831 },
2832 128 => {
2833 const lhs_val = lhs.toFloat(f128);
2834 const rhs_val = rhs.toFloat(f128);
2835 return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val));
2836 },
2837 else => unreachable,
2838 }
27732839 }
27742840
27752841 pub fn intMul(lhs: Value, rhs: Value, allocator: Allocator) !Value {
......@@ -2929,24 +2995,30 @@ pub const Value = extern union {
29292995 rhs: Value,
29302996 float_type: Type,
29312997 arena: Allocator,
2998 target: Target,
29322999 ) !Value {
2933 switch (float_type.tag()) {
2934 .f16 => {
3000 switch (float_type.floatBits(target)) {
3001 16 => {
29353002 const lhs_val = lhs.toFloat(f16);
29363003 const rhs_val = rhs.toFloat(f16);
29373004 return Value.Tag.float_16.create(arena, lhs_val + rhs_val);
29383005 },
2939 .f32 => {
3006 32 => {
29403007 const lhs_val = lhs.toFloat(f32);
29413008 const rhs_val = rhs.toFloat(f32);
29423009 return Value.Tag.float_32.create(arena, lhs_val + rhs_val);
29433010 },
2944 .f64 => {
3011 64 => {
29453012 const lhs_val = lhs.toFloat(f64);
29463013 const rhs_val = rhs.toFloat(f64);
29473014 return Value.Tag.float_64.create(arena, lhs_val + rhs_val);
29483015 },
2949 .f128, .comptime_float, .c_longdouble => {
3016 80 => {
3017 const lhs_val = lhs.toFloat(f80);
3018 const rhs_val = rhs.toFloat(f80);
3019 return Value.Tag.float_80.create(arena, lhs_val + rhs_val);
3020 },
3021 128 => {
29503022 const lhs_val = lhs.toFloat(f128);
29513023 const rhs_val = rhs.toFloat(f128);
29523024 return Value.Tag.float_128.create(arena, lhs_val + rhs_val);
......@@ -2960,24 +3032,30 @@ pub const Value = extern union {
29603032 rhs: Value,
29613033 float_type: Type,
29623034 arena: Allocator,
3035 target: Target,
29633036 ) !Value {
2964 switch (float_type.tag()) {
2965 .f16 => {
3037 switch (float_type.floatBits(target)) {
3038 16 => {
29663039 const lhs_val = lhs.toFloat(f16);
29673040 const rhs_val = rhs.toFloat(f16);
29683041 return Value.Tag.float_16.create(arena, lhs_val - rhs_val);
29693042 },
2970 .f32 => {
3043 32 => {
29713044 const lhs_val = lhs.toFloat(f32);
29723045 const rhs_val = rhs.toFloat(f32);
29733046 return Value.Tag.float_32.create(arena, lhs_val - rhs_val);
29743047 },
2975 .f64 => {
3048 64 => {
29763049 const lhs_val = lhs.toFloat(f64);
29773050 const rhs_val = rhs.toFloat(f64);
29783051 return Value.Tag.float_64.create(arena, lhs_val - rhs_val);
29793052 },
2980 .f128, .comptime_float, .c_longdouble => {
3053 80 => {
3054 const lhs_val = lhs.toFloat(f80);
3055 const rhs_val = rhs.toFloat(f80);
3056 return Value.Tag.float_80.create(arena, lhs_val - rhs_val);
3057 },
3058 128 => {
29813059 const lhs_val = lhs.toFloat(f128);
29823060 const rhs_val = rhs.toFloat(f128);
29833061 return Value.Tag.float_128.create(arena, lhs_val - rhs_val);
......@@ -2991,24 +3069,30 @@ pub const Value = extern union {
29913069 rhs: Value,
29923070 float_type: Type,
29933071 arena: Allocator,
3072 target: Target,
29943073 ) !Value {
2995 switch (float_type.tag()) {
2996 .f16 => {
3074 switch (float_type.floatBits(target)) {
3075 16 => {
29973076 const lhs_val = lhs.toFloat(f16);
29983077 const rhs_val = rhs.toFloat(f16);
29993078 return Value.Tag.float_16.create(arena, lhs_val / rhs_val);
30003079 },
3001 .f32 => {
3080 32 => {
30023081 const lhs_val = lhs.toFloat(f32);
30033082 const rhs_val = rhs.toFloat(f32);
30043083 return Value.Tag.float_32.create(arena, lhs_val / rhs_val);
30053084 },
3006 .f64 => {
3085 64 => {
30073086 const lhs_val = lhs.toFloat(f64);
30083087 const rhs_val = rhs.toFloat(f64);
30093088 return Value.Tag.float_64.create(arena, lhs_val / rhs_val);
30103089 },
3011 .f128, .comptime_float, .c_longdouble => {
3090 80 => {
3091 const lhs_val = lhs.toFloat(f80);
3092 const rhs_val = rhs.toFloat(f80);
3093 return Value.Tag.float_80.create(arena, lhs_val / rhs_val);
3094 },
3095 128 => {
30123096 const lhs_val = lhs.toFloat(f128);
30133097 const rhs_val = rhs.toFloat(f128);
30143098 return Value.Tag.float_128.create(arena, lhs_val / rhs_val);
......@@ -3022,24 +3106,30 @@ pub const Value = extern union {
30223106 rhs: Value,
30233107 float_type: Type,
30243108 arena: Allocator,
3109 target: Target,
30253110 ) !Value {
3026 switch (float_type.tag()) {
3027 .f16 => {
3111 switch (float_type.floatBits(target)) {
3112 16 => {
30283113 const lhs_val = lhs.toFloat(f16);
30293114 const rhs_val = rhs.toFloat(f16);
30303115 return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val));
30313116 },
3032 .f32 => {
3117 32 => {
30333118 const lhs_val = lhs.toFloat(f32);
30343119 const rhs_val = rhs.toFloat(f32);
30353120 return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val));
30363121 },
3037 .f64 => {
3122 64 => {
30383123 const lhs_val = lhs.toFloat(f64);
30393124 const rhs_val = rhs.toFloat(f64);
30403125 return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val));
30413126 },
3042 .f128, .comptime_float, .c_longdouble => {
3127 80 => {
3128 const lhs_val = lhs.toFloat(f80);
3129 const rhs_val = rhs.toFloat(f80);
3130 return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val));
3131 },
3132 128 => {
30433133 const lhs_val = lhs.toFloat(f128);
30443134 const rhs_val = rhs.toFloat(f128);
30453135 return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val));
......@@ -3053,24 +3143,30 @@ pub const Value = extern union {
30533143 rhs: Value,
30543144 float_type: Type,
30553145 arena: Allocator,
3146 target: Target,
30563147 ) !Value {
3057 switch (float_type.tag()) {
3058 .f16 => {
3148 switch (float_type.floatBits(target)) {
3149 16 => {
30593150 const lhs_val = lhs.toFloat(f16);
30603151 const rhs_val = rhs.toFloat(f16);
30613152 return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val));
30623153 },
3063 .f32 => {
3154 32 => {
30643155 const lhs_val = lhs.toFloat(f32);
30653156 const rhs_val = rhs.toFloat(f32);
30663157 return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val));
30673158 },
3068 .f64 => {
3159 64 => {
30693160 const lhs_val = lhs.toFloat(f64);
30703161 const rhs_val = rhs.toFloat(f64);
30713162 return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val));
30723163 },
3073 .f128, .comptime_float, .c_longdouble => {
3164 80 => {
3165 const lhs_val = lhs.toFloat(f80);
3166 const rhs_val = rhs.toFloat(f80);
3167 return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val));
3168 },
3169 128 => {
30743170 const lhs_val = lhs.toFloat(f128);
30753171 const rhs_val = rhs.toFloat(f128);
30763172 return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val));
......@@ -3084,24 +3180,30 @@ pub const Value = extern union {
30843180 rhs: Value,
30853181 float_type: Type,
30863182 arena: Allocator,
3183 target: Target,
30873184 ) !Value {
3088 switch (float_type.tag()) {
3089 .f16 => {
3185 switch (float_type.floatBits(target)) {
3186 16 => {
30903187 const lhs_val = lhs.toFloat(f16);
30913188 const rhs_val = rhs.toFloat(f16);
30923189 return Value.Tag.float_16.create(arena, lhs_val * rhs_val);
30933190 },
3094 .f32 => {
3191 32 => {
30953192 const lhs_val = lhs.toFloat(f32);
30963193 const rhs_val = rhs.toFloat(f32);
30973194 return Value.Tag.float_32.create(arena, lhs_val * rhs_val);
30983195 },
3099 .f64 => {
3196 64 => {
31003197 const lhs_val = lhs.toFloat(f64);
31013198 const rhs_val = rhs.toFloat(f64);
31023199 return Value.Tag.float_64.create(arena, lhs_val * rhs_val);
31033200 },
3104 .f128, .comptime_float, .c_longdouble => {
3201 80 => {
3202 const lhs_val = lhs.toFloat(f80);
3203 const rhs_val = rhs.toFloat(f80);
3204 return Value.Tag.float_80.create(arena, lhs_val * rhs_val);
3205 },
3206 128 => {
31053207 const lhs_val = lhs.toFloat(f128);
31063208 const rhs_val = rhs.toFloat(f128);
31073209 return Value.Tag.float_128.create(arena, lhs_val * rhs_val);
......@@ -3250,6 +3352,13 @@ pub const Value = extern union {
32503352 data: f64,
32513353 };
32523354
3355 pub const Float_80 = struct {
3356 pub const base_tag = Tag.float_80;
3357
3358 base: Payload = .{ .tag = base_tag },
3359 data: f80,
3360 };
3361
32533362 pub const Float_128 = struct {
32543363 pub const base_tag = Tag.float_128;
32553364
test/behavior/math.zig-2
......@@ -768,8 +768,6 @@ test "shift left/right on u0 operand" {
768768}
769769
770770test "comptime float rem int" {
771 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
772
773771 comptime {
774772 var x = @as(f32, 1) % 2;
775773 try expect(x == 1.0);