authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-05-09 17:06:10+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:30-07:00
log466328d1ca29f3f6dd142f74dda13b26687e71e0
tree40d1310c7ae5dc98fce899884cfdaa2b310728b2
parent5881a2d63771b070107bdc2325aa1bc455b2d926

InternPool: transition float values


8 files changed, 792 insertions(+), 975 deletions(-)

src/InternPool.zig+191-4
...@@ -155,6 +155,7 @@ pub const Key = union(enum) {...@@ -155,6 +155,7 @@ pub const Key = union(enum) {
155 lib_name: u32,155 lib_name: u32,
156 },156 },
157 int: Key.Int,157 int: Key.Int,
158 float: Key.Float,
158 ptr: Ptr,159 ptr: Ptr,
159 opt: Opt,160 opt: Opt,
160 enum_tag: struct {161 enum_tag: struct {
...@@ -361,6 +362,20 @@ pub const Key = union(enum) {...@@ -361,6 +362,20 @@ pub const Key = union(enum) {
361 };362 };
362 };363 };
363364
365 pub const Float = struct {
366 ty: Index,
367 /// The storage used must match the size of the float type being represented.
368 storage: Storage,
369
370 pub const Storage = union(enum) {
371 f16: f16,
372 f32: f32,
373 f64: f64,
374 f80: f80,
375 f128: f128,
376 };
377 };
378
364 pub const Ptr = struct {379 pub const Ptr = struct {
365 ty: Index,380 ty: Index,
366 addr: Addr,381 addr: Addr,
...@@ -436,6 +451,16 @@ pub const Key = union(enum) {...@@ -436,6 +451,16 @@ pub const Key = union(enum) {
436 for (big_int.limbs) |limb| std.hash.autoHash(hasher, limb);451 for (big_int.limbs) |limb| std.hash.autoHash(hasher, limb);
437 },452 },
438453
454 .float => |float| {
455 std.hash.autoHash(hasher, float.ty);
456 switch (float.storage) {
457 inline else => |val| std.hash.autoHash(
458 hasher,
459 @bitCast(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(val))), val),
460 ),
461 }
462 },
463
439 .ptr => |ptr| {464 .ptr => |ptr| {
440 std.hash.autoHash(hasher, ptr.ty);465 std.hash.autoHash(hasher, ptr.ty);
441 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.466 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.
...@@ -561,6 +586,32 @@ pub const Key = union(enum) {...@@ -561,6 +586,32 @@ pub const Key = union(enum) {
561 };586 };
562 },587 },
563588
589 .float => |a_info| {
590 const b_info = b.float;
591
592 if (a_info.ty != b_info.ty)
593 return false;
594
595 if (a_info.ty == .c_longdouble_type and a_info.storage != .f80) {
596 // These are strange: we'll sometimes represent them as f128, even if the
597 // underlying type is smaller. f80 is an exception: see float_c_longdouble_f80.
598 const a_val = switch (a_info.storage) {
599 inline else => |val| @floatCast(f128, val),
600 };
601 const b_val = switch (b_info.storage) {
602 inline else => |val| @floatCast(f128, val),
603 };
604 return a_val == b_val;
605 }
606
607 const StorageTag = @typeInfo(Key.Float.Storage).Union.tag_type.?;
608 assert(@as(StorageTag, a_info.storage) == @as(StorageTag, b_info.storage));
609
610 return switch (a_info.storage) {
611 inline else => |val, tag| val == @field(b_info.storage, @tagName(tag)),
612 };
613 },
614
564 .enum_tag => |a_info| {615 .enum_tag => |a_info| {
565 const b_info = b.enum_tag;616 const b_info = b.enum_tag;
566 _ = a_info;617 _ = a_info;
...@@ -601,6 +652,7 @@ pub const Key = union(enum) {...@@ -601,6 +652,7 @@ pub const Key = union(enum) {
601652
602 inline .ptr,653 inline .ptr,
603 .int,654 .int,
655 .float,
604 .opt,656 .opt,
605 .extern_func,657 .extern_func,
606 .enum_tag,658 .enum_tag,
...@@ -1115,15 +1167,35 @@ pub const Tag = enum(u8) {...@@ -1115,15 +1167,35 @@ pub const Tag = enum(u8) {
1115 /// An enum tag identified by a negative integer value.1167 /// An enum tag identified by a negative integer value.
1116 /// data is a limbs index to Int.1168 /// data is a limbs index to Int.
1117 enum_tag_negative,1169 enum_tag_negative,
1170 /// An f16 value.
1171 /// data is float value bitcasted to u16 and zero-extended.
1172 float_f16,
1118 /// An f32 value.1173 /// An f32 value.
1119 /// data is float value bitcasted to u32.1174 /// data is float value bitcasted to u32.
1120 float_f32,1175 float_f32,
1121 /// An f64 value.1176 /// An f64 value.
1122 /// data is extra index to Float64.1177 /// data is extra index to Float64.
1123 float_f64,1178 float_f64,
1179 /// An f80 value.
1180 /// data is extra index to Float80.
1181 float_f80,
1124 /// An f128 value.1182 /// An f128 value.
1125 /// data is extra index to Float128.1183 /// data is extra index to Float128.
1126 float_f128,1184 float_f128,
1185 /// A c_longdouble value of 80 bits.
1186 /// data is extra index to Float80.
1187 /// This is used when a c_longdouble value is provided as an f80, because f80 has unnormalized
1188 /// values which cannot be losslessly represented as f128. It should only be used when the type
1189 /// underlying c_longdouble for the target is 80 bits.
1190 float_c_longdouble_f80,
1191 /// A c_longdouble value of 128 bits.
1192 /// data is extra index to Float128.
1193 /// This is used when a c_longdouble value is provided as any type other than an f80, since all
1194 /// other float types can be losslessly converted to and from f128.
1195 float_c_longdouble_f128,
1196 /// A comptime_float value.
1197 /// data is extra index to Float128.
1198 float_comptime_float,
1127 /// An extern function.1199 /// An extern function.
1128 extern_func,1200 extern_func,
1129 /// A regular function.1201 /// A regular function.
...@@ -1339,7 +1411,38 @@ pub const Float64 = struct {...@@ -1339,7 +1411,38 @@ pub const Float64 = struct {
13391411
1340 pub fn get(self: Float64) f64 {1412 pub fn get(self: Float64) f64 {
1341 const int_bits = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32);1413 const int_bits = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32);
1342 return @bitCast(u64, int_bits);1414 return @bitCast(f64, int_bits);
1415 }
1416
1417 fn pack(val: f64) Float64 {
1418 const bits = @bitCast(u64, val);
1419 return .{
1420 .piece0 = @truncate(u32, bits),
1421 .piece1 = @truncate(u32, bits >> 32),
1422 };
1423 }
1424};
1425
1426/// A f80 value, broken up into 2 u32 parts and a u16 part zero-padded to a u32.
1427pub const Float80 = struct {
1428 piece0: u32,
1429 piece1: u32,
1430 piece2: u32, // u16 part, top bits
1431
1432 pub fn get(self: Float80) f80 {
1433 const int_bits = @as(u80, self.piece0) |
1434 (@as(u80, self.piece1) << 32) |
1435 (@as(u80, self.piece2) << 64);
1436 return @bitCast(f80, int_bits);
1437 }
1438
1439 fn pack(val: f80) Float80 {
1440 const bits = @bitCast(u80, val);
1441 return .{
1442 .piece0 = @truncate(u32, bits),
1443 .piece1 = @truncate(u32, bits >> 32),
1444 .piece2 = @truncate(u16, bits >> 64),
1445 };
1343 }1446 }
1344};1447};
13451448
...@@ -1357,6 +1460,16 @@ pub const Float128 = struct {...@@ -1357,6 +1460,16 @@ pub const Float128 = struct {
1357 (@as(u128, self.piece3) << 96);1460 (@as(u128, self.piece3) << 96);
1358 return @bitCast(f128, int_bits);1461 return @bitCast(f128, int_bits);
1359 }1462 }
1463
1464 fn pack(val: f128) Float128 {
1465 const bits = @bitCast(u128, val);
1466 return .{
1467 .piece0 = @truncate(u32, bits),
1468 .piece1 = @truncate(u32, bits >> 32),
1469 .piece2 = @truncate(u32, bits >> 64),
1470 .piece3 = @truncate(u32, bits >> 96),
1471 };
1472 }
1360};1473};
13611474
1362pub fn init(ip: *InternPool, gpa: Allocator) !void {1475pub fn init(ip: *InternPool, gpa: Allocator) !void {
...@@ -1576,9 +1689,38 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1576,9 +1689,38 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1576 .int_negative => indexToKeyBigInt(ip, data, false),1689 .int_negative => indexToKeyBigInt(ip, data, false),
1577 .enum_tag_positive => @panic("TODO"),1690 .enum_tag_positive => @panic("TODO"),
1578 .enum_tag_negative => @panic("TODO"),1691 .enum_tag_negative => @panic("TODO"),
1579 .float_f32 => @panic("TODO"),1692 .float_f16 => .{ .float = .{
1580 .float_f64 => @panic("TODO"),1693 .ty = .f16_type,
1581 .float_f128 => @panic("TODO"),1694 .storage = .{ .f16 = @bitCast(f16, @intCast(u16, data)) },
1695 } },
1696 .float_f32 => .{ .float = .{
1697 .ty = .f32_type,
1698 .storage = .{ .f32 = @bitCast(f32, data) },
1699 } },
1700 .float_f64 => .{ .float = .{
1701 .ty = .f64_type,
1702 .storage = .{ .f64 = ip.extraData(Float64, data).get() },
1703 } },
1704 .float_f80 => .{ .float = .{
1705 .ty = .f80_type,
1706 .storage = .{ .f80 = ip.extraData(Float80, data).get() },
1707 } },
1708 .float_f128 => .{ .float = .{
1709 .ty = .f128_type,
1710 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
1711 } },
1712 .float_c_longdouble_f80 => .{ .float = .{
1713 .ty = .c_longdouble_type,
1714 .storage = .{ .f80 = ip.extraData(Float80, data).get() },
1715 } },
1716 .float_c_longdouble_f128 => .{ .float = .{
1717 .ty = .c_longdouble_type,
1718 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
1719 } },
1720 .float_comptime_float => .{ .float = .{
1721 .ty = .comptime_float_type,
1722 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
1723 } },
1582 .extern_func => @panic("TODO"),1724 .extern_func => @panic("TODO"),
1583 .func => @panic("TODO"),1725 .func => @panic("TODO"),
1584 .only_possible_value => {1726 .only_possible_value => {
...@@ -1982,6 +2124,46 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -1982,6 +2124,46 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
1982 }2124 }
1983 },2125 },
19842126
2127 .float => |float| {
2128 switch (float.ty) {
2129 .f16_type => ip.items.appendAssumeCapacity(.{
2130 .tag = .float_f16,
2131 .data = @bitCast(u16, float.storage.f16),
2132 }),
2133 .f32_type => ip.items.appendAssumeCapacity(.{
2134 .tag = .float_f32,
2135 .data = @bitCast(u32, float.storage.f32),
2136 }),
2137 .f64_type => ip.items.appendAssumeCapacity(.{
2138 .tag = .float_f64,
2139 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),
2140 }),
2141 .f80_type => ip.items.appendAssumeCapacity(.{
2142 .tag = .float_f80,
2143 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),
2144 }),
2145 .f128_type => ip.items.appendAssumeCapacity(.{
2146 .tag = .float_f128,
2147 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
2148 }),
2149 .c_longdouble_type => switch (float.storage) {
2150 .f80 => |x| ip.items.appendAssumeCapacity(.{
2151 .tag = .float_c_longdouble_f80,
2152 .data = try ip.addExtra(gpa, Float80.pack(x)),
2153 }),
2154 inline .f16, .f32, .f64, .f128 => |x| ip.items.appendAssumeCapacity(.{
2155 .tag = .float_c_longdouble_f128,
2156 .data = try ip.addExtra(gpa, Float128.pack(x)),
2157 }),
2158 },
2159 .comptime_float_type => ip.items.appendAssumeCapacity(.{
2160 .tag = .float_comptime_float,
2161 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
2162 }),
2163 else => unreachable,
2164 }
2165 },
2166
1985 .enum_tag => |enum_tag| {2167 .enum_tag => |enum_tag| {
1986 const tag: Tag = if (enum_tag.tag.positive) .enum_tag_positive else .enum_tag_negative;2168 const tag: Tag = if (enum_tag.tag.positive) .enum_tag_positive else .enum_tag_negative;
1987 try addInt(ip, gpa, enum_tag.ty, tag, enum_tag.tag.limbs);2169 try addInt(ip, gpa, enum_tag.ty, tag, enum_tag.tag.limbs);
...@@ -2645,9 +2827,14 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {...@@ -2645,9 +2827,14 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
2645 break :b @sizeOf(Int) + int.limbs_len * 8;2827 break :b @sizeOf(Int) + int.limbs_len * 8;
2646 },2828 },
26472829
2830 .float_f16 => 0,
2648 .float_f32 => 0,2831 .float_f32 => 0,
2649 .float_f64 => @sizeOf(Float64),2832 .float_f64 => @sizeOf(Float64),
2833 .float_f80 => @sizeOf(Float80),
2650 .float_f128 => @sizeOf(Float128),2834 .float_f128 => @sizeOf(Float128),
2835 .float_c_longdouble_f80 => @sizeOf(Float80),
2836 .float_c_longdouble_f128 => @sizeOf(Float128),
2837 .float_comptime_float => @sizeOf(Float128),
2651 .extern_func => @panic("TODO"),2838 .extern_func => @panic("TODO"),
2652 .func => @panic("TODO"),2839 .func => @panic("TODO"),
2653 .only_possible_value => 0,2840 .only_possible_value => 0,
src/Module.zig+18
...@@ -6940,6 +6940,24 @@ pub fn unionValue(mod: *Module, union_ty: Type, tag: Value, val: Value) Allocato...@@ -6940,6 +6940,24 @@ pub fn unionValue(mod: *Module, union_ty: Type, tag: Value, val: Value) Allocato
6940 return i.toValue();6940 return i.toValue();
6941}6941}
69426942
6943/// This function casts the float representation down to the representation of the type, potentially
6944/// losing data if the representation wasn't correct.
6945pub fn floatValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6946 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(mod.getTarget())) {
6947 16 => .{ .f16 = @floatCast(f16, x) },
6948 32 => .{ .f32 = @floatCast(f32, x) },
6949 64 => .{ .f64 = @floatCast(f64, x) },
6950 80 => .{ .f80 = @floatCast(f80, x) },
6951 128 => .{ .f128 = @floatCast(f128, x) },
6952 else => unreachable,
6953 };
6954 const i = try intern(mod, .{ .float = .{
6955 .ty = ty.ip_index,
6956 .storage = storage,
6957 } });
6958 return i.toValue();
6959}
6960
6943pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {6961pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
6944 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));6962 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));
6945}6963}
src/Sema.zig+55-159
...@@ -3225,7 +3225,7 @@ fn zirOpaqueDecl(...@@ -3225,7 +3225,7 @@ fn zirOpaqueDecl(
3225 const new_namespace = mod.namespacePtr(new_namespace_index);3225 const new_namespace = mod.namespacePtr(new_namespace_index);
3226 errdefer mod.destroyNamespace(new_namespace_index);3226 errdefer mod.destroyNamespace(new_namespace_index);
32273227
3228 const opaque_ty = try mod.intern_pool.get(gpa, .{ .opaque_type = .{3228 const opaque_ty = try mod.intern(.{ .opaque_type = .{
3229 .decl = new_decl_index,3229 .decl = new_decl_index,
3230 .namespace = new_namespace_index,3230 .namespace = new_namespace_index,
3231 } });3231 } });
...@@ -5196,23 +5196,21 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5196,23 +5196,21 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
51965196
5197fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5197fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5198 _ = block;5198 _ = block;
5199 const arena = sema.arena;
5200 const number = sema.code.instructions.items(.data)[inst].float;5199 const number = sema.code.instructions.items(.data)[inst].float;
5201 return sema.addConstant(5200 return sema.addConstant(
5202 Type.comptime_float,5201 Type.comptime_float,
5203 try Value.Tag.float_64.create(arena, number),5202 try sema.mod.floatValue(Type.comptime_float, number),
5204 );5203 );
5205}5204}
52065205
5207fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5206fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5208 _ = block;5207 _ = block;
5209 const arena = sema.arena;
5210 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5208 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5211 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;5209 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
5212 const number = extra.get();5210 const number = extra.get();
5213 return sema.addConstant(5211 return sema.addConstant(
5214 Type.comptime_float,5212 Type.comptime_float,
5215 try Value.Tag.float_128.create(arena, number),5213 try sema.mod.floatValue(Type.comptime_float, number),
5216 );5214 );
5217}5215}
52185216
...@@ -9952,7 +9950,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -9952,7 +9950,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9952 }9950 }
99539951
9954 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {9952 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
9955 return sema.addConstant(dest_ty, try operand_val.floatCast(sema.arena, dest_ty, mod));9953 return sema.addConstant(dest_ty, try operand_val.floatCast(dest_ty, mod));
9956 }9954 }
9957 if (dest_is_comptime_float) {9955 if (dest_is_comptime_float) {
9958 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_float'", .{});9956 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_float'", .{});
...@@ -13302,7 +13300,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13302,7 +13300,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13302 if (!lhs_val.isUndef()) {13300 if (!lhs_val.isUndef()) {
13303 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13301 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13304 const scalar_zero = switch (scalar_tag) {13302 const scalar_zero = switch (scalar_tag) {
13305 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13303 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13306 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13304 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13307 else => unreachable,13305 else => unreachable,
13308 };13306 };
...@@ -13441,7 +13439,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13441,7 +13439,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13441 } else {13439 } else {
13442 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13440 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13443 const scalar_zero = switch (scalar_tag) {13441 const scalar_zero = switch (scalar_tag) {
13444 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13442 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13445 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13443 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13446 else => unreachable,13444 else => unreachable,
13447 };13445 };
...@@ -13526,7 +13524,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13526,7 +13524,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13526 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);13524 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1352713525
13528 const scalar_zero = switch (scalar_tag) {13526 const scalar_zero = switch (scalar_tag) {
13529 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13527 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13530 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13528 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13531 else => unreachable,13529 else => unreachable,
13532 };13530 };
...@@ -13616,7 +13614,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13616,7 +13614,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13616 if (!lhs_val.isUndef()) {13614 if (!lhs_val.isUndef()) {
13617 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13615 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13618 const scalar_zero = switch (scalar_tag) {13616 const scalar_zero = switch (scalar_tag) {
13619 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13617 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13620 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13618 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13621 else => unreachable,13619 else => unreachable,
13622 };13620 };
...@@ -13737,7 +13735,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13737,7 +13735,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13737 if (!lhs_val.isUndef()) {13735 if (!lhs_val.isUndef()) {
13738 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13736 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13739 const scalar_zero = switch (scalar_tag) {13737 const scalar_zero = switch (scalar_tag) {
13740 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13738 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13741 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13739 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13742 else => unreachable,13740 else => unreachable,
13743 };13741 };
...@@ -13895,7 +13893,10 @@ fn addDivByZeroSafety(...@@ -13895,7 +13893,10 @@ fn addDivByZeroSafety(
13895 if (maybe_rhs_val != null) return;13893 if (maybe_rhs_val != null) return;
1389613894
13897 const mod = sema.mod;13895 const mod = sema.mod;
13898 const scalar_zero = if (is_int) try mod.intValue(resolved_type.scalarType(mod), 0) else Value.float_zero; // TODO migrate to internpool13896 const scalar_zero = if (is_int)
13897 try mod.intValue(resolved_type.scalarType(mod), 0)
13898 else
13899 try mod.floatValue(resolved_type.scalarType(mod), 0);
13899 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {13900 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
13900 const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero);13901 const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero);
13901 const zero = try sema.addConstant(resolved_type, zero_val);13902 const zero = try sema.addConstant(resolved_type, zero_val);
...@@ -13981,7 +13982,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13981,7 +13982,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13981 }13982 }
13982 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13983 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13983 const scalar_zero = switch (scalar_tag) {13984 const scalar_zero = switch (scalar_tag) {
13984 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool13985 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13985 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),13986 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13986 else => unreachable,13987 else => unreachable,
13987 };13988 };
...@@ -14641,7 +14642,7 @@ fn analyzeArithmetic(...@@ -14641,7 +14642,7 @@ fn analyzeArithmetic(
14641 } else {14642 } else {
14642 return sema.addConstant(14643 return sema.addConstant(
14643 resolved_type,14644 resolved_type,
14644 try sema.floatAdd(lhs_val, rhs_val, resolved_type),14645 try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod),
14645 );14646 );
14646 }14647 }
14647 } else break :rs .{ .src = rhs_src, .air_tag = air_tag };14648 } else break :rs .{ .src = rhs_src, .air_tag = air_tag };
...@@ -14738,7 +14739,7 @@ fn analyzeArithmetic(...@@ -14738,7 +14739,7 @@ fn analyzeArithmetic(
14738 } else {14739 } else {
14739 return sema.addConstant(14740 return sema.addConstant(
14740 resolved_type,14741 resolved_type,
14741 try sema.floatSub(lhs_val, rhs_val, resolved_type),14742 try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod),
14742 );14743 );
14743 }14744 }
14744 } else break :rs .{ .src = rhs_src, .air_tag = air_tag };14745 } else break :rs .{ .src = rhs_src, .air_tag = air_tag };
...@@ -14808,22 +14809,25 @@ fn analyzeArithmetic(...@@ -14808,22 +14809,25 @@ fn analyzeArithmetic(
14808 // the result is nan.14809 // the result is nan.
14809 // If either of the operands are nan, the result is nan.14810 // If either of the operands are nan, the result is nan.
14810 const scalar_zero = switch (scalar_tag) {14811 const scalar_zero = switch (scalar_tag) {
14811 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool14812 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14812 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),14813 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14813 else => unreachable,14814 else => unreachable,
14814 };14815 };
14815 if (maybe_lhs_val) |lhs_val| {14816 if (maybe_lhs_val) |lhs_val| {
14816 if (!lhs_val.isUndef()) {14817 if (!lhs_val.isUndef()) {
14817 if (lhs_val.isNan()) {14818 if (lhs_val.isNan(mod)) {
14818 return sema.addConstant(resolved_type, lhs_val);14819 return sema.addConstant(resolved_type, lhs_val);
14819 }14820 }
14820 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) lz: {14821 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) lz: {
14821 if (maybe_rhs_val) |rhs_val| {14822 if (maybe_rhs_val) |rhs_val| {
14822 if (rhs_val.isNan()) {14823 if (rhs_val.isNan(mod)) {
14823 return sema.addConstant(resolved_type, rhs_val);14824 return sema.addConstant(resolved_type, rhs_val);
14824 }14825 }
14825 if (rhs_val.isInf()) {14826 if (rhs_val.isInf(mod)) {
14826 return sema.addConstant(resolved_type, try Value.Tag.float_32.create(sema.arena, std.math.nan_f32));14827 return sema.addConstant(
14828 resolved_type,
14829 try mod.floatValue(resolved_type, std.math.nan_f128),
14830 );
14827 }14831 }
14828 } else if (resolved_type.isAnyFloat()) {14832 } else if (resolved_type.isAnyFloat()) {
14829 break :lz;14833 break :lz;
...@@ -14847,13 +14851,16 @@ fn analyzeArithmetic(...@@ -14847,13 +14851,16 @@ fn analyzeArithmetic(
14847 return sema.addConstUndef(resolved_type);14851 return sema.addConstUndef(resolved_type);
14848 }14852 }
14849 }14853 }
14850 if (rhs_val.isNan()) {14854 if (rhs_val.isNan(mod)) {
14851 return sema.addConstant(resolved_type, rhs_val);14855 return sema.addConstant(resolved_type, rhs_val);
14852 }14856 }
14853 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) rz: {14857 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) rz: {
14854 if (maybe_lhs_val) |lhs_val| {14858 if (maybe_lhs_val) |lhs_val| {
14855 if (lhs_val.isInf()) {14859 if (lhs_val.isInf(mod)) {
14856 return sema.addConstant(resolved_type, try Value.Tag.float_32.create(sema.arena, std.math.nan_f32));14860 return sema.addConstant(
14861 resolved_type,
14862 try mod.floatValue(resolved_type, std.math.nan_f128),
14863 );
14857 }14864 }
14858 } else if (resolved_type.isAnyFloat()) {14865 } else if (resolved_type.isAnyFloat()) {
14859 break :rz;14866 break :rz;
...@@ -14896,7 +14903,7 @@ fn analyzeArithmetic(...@@ -14896,7 +14903,7 @@ fn analyzeArithmetic(
14896 // If either of the operands are one, result is the other operand.14903 // If either of the operands are one, result is the other operand.
14897 // If either of the operands are undefined, result is undefined.14904 // If either of the operands are undefined, result is undefined.
14898 const scalar_zero = switch (scalar_tag) {14905 const scalar_zero = switch (scalar_tag) {
14899 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool14906 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14900 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),14907 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14901 else => unreachable,14908 else => unreachable,
14902 };14909 };
...@@ -14944,7 +14951,7 @@ fn analyzeArithmetic(...@@ -14944,7 +14951,7 @@ fn analyzeArithmetic(
14944 // If either of the operands are one, result is the other operand.14951 // If either of the operands are one, result is the other operand.
14945 // If either of the operands are undefined, result is undefined.14952 // If either of the operands are undefined, result is undefined.
14946 const scalar_zero = switch (scalar_tag) {14953 const scalar_zero = switch (scalar_tag) {
14947 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool14954 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14948 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),14955 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14949 else => unreachable,14956 else => unreachable,
14950 };14957 };
...@@ -19167,7 +19174,7 @@ fn zirReify(...@@ -19167,7 +19174,7 @@ fn zirReify(
19167 const new_namespace = mod.namespacePtr(new_namespace_index);19174 const new_namespace = mod.namespacePtr(new_namespace_index);
19168 errdefer mod.destroyNamespace(new_namespace_index);19175 errdefer mod.destroyNamespace(new_namespace_index);
1916919176
19170 const opaque_ty = try mod.intern_pool.get(gpa, .{ .opaque_type = .{19177 const opaque_ty = try mod.intern(.{ .opaque_type = .{
19171 .decl = new_decl_index,19178 .decl = new_decl_index,
19172 .namespace = new_namespace_index,19179 .namespace = new_namespace_index,
19173 } });19180 } });
...@@ -25678,7 +25685,7 @@ fn coerceExtra(...@@ -25678,7 +25685,7 @@ fn coerceExtra(
25678 // Keep the comptime Value representation; take the new type.25685 // Keep the comptime Value representation; take the new type.
25679 return sema.addConstant(dest_ty, val);25686 return sema.addConstant(dest_ty, val);
25680 } else {25687 } else {
25681 const new_val = try mod.intern_pool.getCoerced(mod.gpa, val.ip_index, dest_ty.ip_index);25688 const new_val = try mod.intern_pool.getCoerced(sema.gpa, val.ip_index, dest_ty.ip_index);
25682 return sema.addConstant(dest_ty, new_val.toValue());25689 return sema.addConstant(dest_ty, new_val.toValue());
25683 }25690 }
25684 }25691 }
...@@ -26032,7 +26039,7 @@ fn coerceExtra(...@@ -26032,7 +26039,7 @@ fn coerceExtra(
26032 break :float;26039 break :float;
26033 };26040 };
2603426041
26035 if (val.floatHasFraction()) {26042 if (val.floatHasFraction(mod)) {
26036 return sema.fail(26043 return sema.fail(
26037 block,26044 block,
26038 inst_src,26045 inst_src,
...@@ -26081,7 +26088,7 @@ fn coerceExtra(...@@ -26081,7 +26088,7 @@ fn coerceExtra(
26081 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {26088 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {
26082 .ComptimeFloat => {26089 .ComptimeFloat => {
26083 const val = try sema.resolveConstValue(block, .unneeded, inst, "");26090 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
26084 const result_val = try val.floatCast(sema.arena, dest_ty, mod);26091 const result_val = try val.floatCast(dest_ty, mod);
26085 return try sema.addConstant(dest_ty, result_val);26092 return try sema.addConstant(dest_ty, result_val);
26086 },26093 },
26087 .Float => {26094 .Float => {
...@@ -26089,7 +26096,7 @@ fn coerceExtra(...@@ -26089,7 +26096,7 @@ fn coerceExtra(
26089 return sema.addConstUndef(dest_ty);26096 return sema.addConstUndef(dest_ty);
26090 }26097 }
26091 if (try sema.resolveMaybeUndefVal(inst)) |val| {26098 if (try sema.resolveMaybeUndefVal(inst)) |val| {
26092 const result_val = try val.floatCast(sema.arena, dest_ty, mod);26099 const result_val = try val.floatCast(dest_ty, mod);
26093 if (!val.eql(result_val, inst_ty, sema.mod)) {26100 if (!val.eql(result_val, inst_ty, sema.mod)) {
26094 return sema.fail(26101 return sema.fail(
26095 block,26102 block,
...@@ -30071,7 +30078,7 @@ fn cmpNumeric(...@@ -30071,7 +30078,7 @@ fn cmpNumeric(
30071 if (lhs_val.isUndef() or rhs_val.isUndef()) {30078 if (lhs_val.isUndef() or rhs_val.isUndef()) {
30072 return sema.addConstUndef(Type.bool);30079 return sema.addConstUndef(Type.bool);
30073 }30080 }
30074 if (lhs_val.isNan() or rhs_val.isNan()) {30081 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
30075 if (op == std.math.CompareOperator.neq) {30082 if (op == std.math.CompareOperator.neq) {
30076 return Air.Inst.Ref.bool_true;30083 return Air.Inst.Ref.bool_true;
30077 } else {30084 } else {
...@@ -30166,15 +30173,15 @@ fn cmpNumeric(...@@ -30166,15 +30173,15 @@ fn cmpNumeric(
30166 try sema.resolveLazyValue(lhs_val);30173 try sema.resolveLazyValue(lhs_val);
30167 if (lhs_val.isUndef())30174 if (lhs_val.isUndef())
30168 return sema.addConstUndef(Type.bool);30175 return sema.addConstUndef(Type.bool);
30169 if (lhs_val.isNan()) switch (op) {30176 if (lhs_val.isNan(mod)) switch (op) {
30170 .neq => return Air.Inst.Ref.bool_true,30177 .neq => return Air.Inst.Ref.bool_true,
30171 else => return Air.Inst.Ref.bool_false,30178 else => return Air.Inst.Ref.bool_false,
30172 };30179 };
30173 if (lhs_val.isInf()) switch (op) {30180 if (lhs_val.isInf(mod)) switch (op) {
30174 .neq => return Air.Inst.Ref.bool_true,30181 .neq => return Air.Inst.Ref.bool_true,
30175 .eq => return Air.Inst.Ref.bool_false,30182 .eq => return Air.Inst.Ref.bool_false,
30176 .gt, .gte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,30183 .gt, .gte => return if (lhs_val.isNegativeInf(mod)) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
30177 .lt, .lte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,30184 .lt, .lte => return if (lhs_val.isNegativeInf(mod)) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
30178 };30185 };
30179 if (!rhs_is_signed) {30186 if (!rhs_is_signed) {
30180 switch (lhs_val.orderAgainstZero(mod)) {30187 switch (lhs_val.orderAgainstZero(mod)) {
...@@ -30191,7 +30198,7 @@ fn cmpNumeric(...@@ -30191,7 +30198,7 @@ fn cmpNumeric(
30191 }30198 }
30192 }30199 }
30193 if (lhs_is_float) {30200 if (lhs_is_float) {
30194 if (lhs_val.floatHasFraction()) {30201 if (lhs_val.floatHasFraction(mod)) {
30195 switch (op) {30202 switch (op) {
30196 .eq => return Air.Inst.Ref.bool_false,30203 .eq => return Air.Inst.Ref.bool_false,
30197 .neq => return Air.Inst.Ref.bool_true,30204 .neq => return Air.Inst.Ref.bool_true,
...@@ -30201,7 +30208,7 @@ fn cmpNumeric(...@@ -30201,7 +30208,7 @@ fn cmpNumeric(
3020130208
30202 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod));30209 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod));
30203 defer bigint.deinit();30210 defer bigint.deinit();
30204 if (lhs_val.floatHasFraction()) {30211 if (lhs_val.floatHasFraction(mod)) {
30205 if (lhs_is_signed) {30212 if (lhs_is_signed) {
30206 try bigint.addScalar(&bigint, -1);30213 try bigint.addScalar(&bigint, -1);
30207 } else {30214 } else {
...@@ -30225,15 +30232,15 @@ fn cmpNumeric(...@@ -30225,15 +30232,15 @@ fn cmpNumeric(
30225 try sema.resolveLazyValue(rhs_val);30232 try sema.resolveLazyValue(rhs_val);
30226 if (rhs_val.isUndef())30233 if (rhs_val.isUndef())
30227 return sema.addConstUndef(Type.bool);30234 return sema.addConstUndef(Type.bool);
30228 if (rhs_val.isNan()) switch (op) {30235 if (rhs_val.isNan(mod)) switch (op) {
30229 .neq => return Air.Inst.Ref.bool_true,30236 .neq => return Air.Inst.Ref.bool_true,
30230 else => return Air.Inst.Ref.bool_false,30237 else => return Air.Inst.Ref.bool_false,
30231 };30238 };
30232 if (rhs_val.isInf()) switch (op) {30239 if (rhs_val.isInf(mod)) switch (op) {
30233 .neq => return Air.Inst.Ref.bool_true,30240 .neq => return Air.Inst.Ref.bool_true,
30234 .eq => return Air.Inst.Ref.bool_false,30241 .eq => return Air.Inst.Ref.bool_false,
30235 .gt, .gte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,30242 .gt, .gte => return if (rhs_val.isNegativeInf(mod)) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
30236 .lt, .lte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,30243 .lt, .lte => return if (rhs_val.isNegativeInf(mod)) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
30237 };30244 };
30238 if (!lhs_is_signed) {30245 if (!lhs_is_signed) {
30239 switch (rhs_val.orderAgainstZero(mod)) {30246 switch (rhs_val.orderAgainstZero(mod)) {
...@@ -30250,7 +30257,7 @@ fn cmpNumeric(...@@ -30250,7 +30257,7 @@ fn cmpNumeric(
30250 }30257 }
30251 }30258 }
30252 if (rhs_is_float) {30259 if (rhs_is_float) {
30253 if (rhs_val.floatHasFraction()) {30260 if (rhs_val.floatHasFraction(mod)) {
30254 switch (op) {30261 switch (op) {
30255 .eq => return Air.Inst.Ref.bool_false,30262 .eq => return Air.Inst.Ref.bool_false,
30256 .neq => return Air.Inst.Ref.bool_true,30263 .neq => return Air.Inst.Ref.bool_true,
...@@ -30260,7 +30267,7 @@ fn cmpNumeric(...@@ -30260,7 +30267,7 @@ fn cmpNumeric(
3026030267
30261 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod));30268 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod));
30262 defer bigint.deinit();30269 defer bigint.deinit();
30263 if (rhs_val.floatHasFraction()) {30270 if (rhs_val.floatHasFraction(mod)) {
30264 if (rhs_is_signed) {30271 if (rhs_is_signed) {
30265 try bigint.addScalar(&bigint, -1);30272 try bigint.addScalar(&bigint, -1);
30266 } else {30273 } else {
...@@ -31713,6 +31720,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31713,6 +31720,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31713 .simple_value => unreachable,31720 .simple_value => unreachable,
31714 .extern_func => unreachable,31721 .extern_func => unreachable,
31715 .int => unreachable,31722 .int => unreachable,
31723 .float => unreachable,
31716 .ptr => unreachable,31724 .ptr => unreachable,
31717 .opt => unreachable,31725 .opt => unreachable,
31718 .enum_tag => unreachable,31726 .enum_tag => unreachable,
...@@ -33216,6 +33224,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33216,6 +33224,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33216 .simple_value => unreachable,33224 .simple_value => unreachable,
33217 .extern_func => unreachable,33225 .extern_func => unreachable,
33218 .int => unreachable,33226 .int => unreachable,
33227 .float => unreachable,
33219 .ptr => unreachable,33228 .ptr => unreachable,
33220 .opt => unreachable,33229 .opt => unreachable,
33221 .enum_tag => unreachable,33230 .enum_tag => unreachable,
...@@ -33777,6 +33786,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33777,6 +33786,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33777 .simple_value => unreachable,33786 .simple_value => unreachable,
33778 .extern_func => unreachable,33787 .extern_func => unreachable,
33779 .int => unreachable,33788 .int => unreachable,
33789 .float => unreachable,
33780 .ptr => unreachable,33790 .ptr => unreachable,
33781 .opt => unreachable,33791 .opt => unreachable,
33782 .enum_tag => unreachable,33792 .enum_tag => unreachable,
...@@ -33935,7 +33945,7 @@ fn numberAddWrapScalar(...@@ -33935,7 +33945,7 @@ fn numberAddWrapScalar(
33935 }33945 }
3393633946
33937 if (ty.isAnyFloat()) {33947 if (ty.isAnyFloat()) {
33938 return sema.floatAdd(lhs, rhs, ty);33948 return Value.floatAdd(lhs, rhs, ty, sema.arena, mod);
33939 }33949 }
3394033950
33941 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);33951 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);
...@@ -33989,127 +33999,13 @@ fn numberSubWrapScalar(...@@ -33989,127 +33999,13 @@ fn numberSubWrapScalar(
33989 }33999 }
3399034000
33991 if (ty.isAnyFloat()) {34001 if (ty.isAnyFloat()) {
33992 return sema.floatSub(lhs, rhs, ty);34002 return Value.floatSub(lhs, rhs, ty, sema.arena, mod);
33993 }34003 }
3399434004
33995 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);34005 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);
33996 return overflow_result.wrapped_result;34006 return overflow_result.wrapped_result;
33997}34007}
3399834008
33999fn floatAdd(
34000 sema: *Sema,
34001 lhs: Value,
34002 rhs: Value,
34003 float_type: Type,
34004) !Value {
34005 const mod = sema.mod;
34006 if (float_type.zigTypeTag(mod) == .Vector) {
34007 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));
34008 for (result_data, 0..) |*scalar, i| {
34009 const lhs_elem = try lhs.elemValue(sema.mod, i);
34010 const rhs_elem = try rhs.elemValue(sema.mod, i);
34011 scalar.* = try sema.floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
34012 }
34013 return Value.Tag.aggregate.create(sema.arena, result_data);
34014 }
34015 return sema.floatAddScalar(lhs, rhs, float_type);
34016}
34017
34018fn floatAddScalar(
34019 sema: *Sema,
34020 lhs: Value,
34021 rhs: Value,
34022 float_type: Type,
34023) !Value {
34024 const mod = sema.mod;
34025 const target = sema.mod.getTarget();
34026 switch (float_type.floatBits(target)) {
34027 16 => {
34028 const lhs_val = lhs.toFloat(f16, mod);
34029 const rhs_val = rhs.toFloat(f16, mod);
34030 return Value.Tag.float_16.create(sema.arena, lhs_val + rhs_val);
34031 },
34032 32 => {
34033 const lhs_val = lhs.toFloat(f32, mod);
34034 const rhs_val = rhs.toFloat(f32, mod);
34035 return Value.Tag.float_32.create(sema.arena, lhs_val + rhs_val);
34036 },
34037 64 => {
34038 const lhs_val = lhs.toFloat(f64, mod);
34039 const rhs_val = rhs.toFloat(f64, mod);
34040 return Value.Tag.float_64.create(sema.arena, lhs_val + rhs_val);
34041 },
34042 80 => {
34043 const lhs_val = lhs.toFloat(f80, mod);
34044 const rhs_val = rhs.toFloat(f80, mod);
34045 return Value.Tag.float_80.create(sema.arena, lhs_val + rhs_val);
34046 },
34047 128 => {
34048 const lhs_val = lhs.toFloat(f128, mod);
34049 const rhs_val = rhs.toFloat(f128, mod);
34050 return Value.Tag.float_128.create(sema.arena, lhs_val + rhs_val);
34051 },
34052 else => unreachable,
34053 }
34054}
34055
34056fn floatSub(
34057 sema: *Sema,
34058 lhs: Value,
34059 rhs: Value,
34060 float_type: Type,
34061) !Value {
34062 const mod = sema.mod;
34063 if (float_type.zigTypeTag(mod) == .Vector) {
34064 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));
34065 for (result_data, 0..) |*scalar, i| {
34066 const lhs_elem = try lhs.elemValue(sema.mod, i);
34067 const rhs_elem = try rhs.elemValue(sema.mod, i);
34068 scalar.* = try sema.floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
34069 }
34070 return Value.Tag.aggregate.create(sema.arena, result_data);
34071 }
34072 return sema.floatSubScalar(lhs, rhs, float_type);
34073}
34074
34075fn floatSubScalar(
34076 sema: *Sema,
34077 lhs: Value,
34078 rhs: Value,
34079 float_type: Type,
34080) !Value {
34081 const mod = sema.mod;
34082 const target = sema.mod.getTarget();
34083 switch (float_type.floatBits(target)) {
34084 16 => {
34085 const lhs_val = lhs.toFloat(f16, mod);
34086 const rhs_val = rhs.toFloat(f16, mod);
34087 return Value.Tag.float_16.create(sema.arena, lhs_val - rhs_val);
34088 },
34089 32 => {
34090 const lhs_val = lhs.toFloat(f32, mod);
34091 const rhs_val = rhs.toFloat(f32, mod);
34092 return Value.Tag.float_32.create(sema.arena, lhs_val - rhs_val);
34093 },
34094 64 => {
34095 const lhs_val = lhs.toFloat(f64, mod);
34096 const rhs_val = rhs.toFloat(f64, mod);
34097 return Value.Tag.float_64.create(sema.arena, lhs_val - rhs_val);
34098 },
34099 80 => {
34100 const lhs_val = lhs.toFloat(f80, mod);
34101 const rhs_val = rhs.toFloat(f80, mod);
34102 return Value.Tag.float_80.create(sema.arena, lhs_val - rhs_val);
34103 },
34104 128 => {
34105 const lhs_val = lhs.toFloat(f128, mod);
34106 const rhs_val = rhs.toFloat(f128, mod);
34107 return Value.Tag.float_128.create(sema.arena, lhs_val - rhs_val);
34108 },
34109 else => unreachable,
34110 }
34111}
34112
34113fn intSubWithOverflow(34009fn intSubWithOverflow(
34114 sema: *Sema,34010 sema: *Sema,
34115 lhs: Value,34011 lhs: Value,
src/TypedValue.zig+3-5
...@@ -283,11 +283,6 @@ pub fn print(...@@ -283,11 +283,6 @@ pub fn print(
283 }283 }
284 return writer.writeAll(" }");284 return writer.writeAll(" }");
285 },285 },
286 .float_16 => return writer.print("{d}", .{val.castTag(.float_16).?.data}),
287 .float_32 => return writer.print("{d}", .{val.castTag(.float_32).?.data}),
288 .float_64 => return writer.print("{d}", .{val.castTag(.float_64).?.data}),
289 .float_80 => return writer.print("{d}", .{@floatCast(f64, val.castTag(.float_80).?.data)}),
290 .float_128 => return writer.print("{d}", .{@floatCast(f64, val.castTag(.float_128).?.data)}),
291 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),286 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
292 .eu_payload => {287 .eu_payload => {
293 val = val.castTag(.eu_payload).?.data;288 val = val.castTag(.eu_payload).?.data;
...@@ -363,6 +358,9 @@ pub fn print(...@@ -363,6 +358,9 @@ pub fn print(
363 .int => |int| switch (int.storage) {358 .int => |int| switch (int.storage) {
364 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),359 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
365 },360 },
361 .float => |float| switch (float.storage) {
362 inline else => |x| return writer.print("{}", .{x}),
363 },
366 else => return writer.print("{}", .{val.ip_index}),364 else => return writer.print("{}", .{val.ip_index}),
367 }365 }
368 },366 },
src/codegen/c.zig+3-14
...@@ -6612,7 +6612,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6612,7 +6612,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6612 const mod = f.object.dg.module;6612 const mod = f.object.dg.module;
6613 const reduce = f.air.instructions.items(.data)[inst].reduce;6613 const reduce = f.air.instructions.items(.data)[inst].reduce;
66146614
6615 const target = mod.getTarget();
6616 const scalar_ty = f.typeOfIndex(inst);6615 const scalar_ty = f.typeOfIndex(inst);
6617 const operand = try f.resolveInst(reduce.operand);6616 const operand = try f.resolveInst(reduce.operand);
6618 try reap(f, inst, &.{reduce.operand});6617 try reap(f, inst, &.{reduce.operand});
...@@ -6679,16 +6678,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6679,16 +6678,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6679 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);6678 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
6680 defer arena.deinit();6679 defer arena.deinit();
66816680
6682 const ExpectedContents = union {
6683 f16: Value.Payload.Float_16,
6684 f32: Value.Payload.Float_32,
6685 f64: Value.Payload.Float_64,
6686 f80: Value.Payload.Float_80,
6687 f128: Value.Payload.Float_128,
6688 };
6689 var stack align(@alignOf(ExpectedContents)) =
6690 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
6691
6692 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {6681 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
6693 .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0),6682 .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0),
6694 .And => switch (scalar_ty.zigTypeTag(mod)) {6683 .And => switch (scalar_ty.zigTypeTag(mod)) {
...@@ -6701,13 +6690,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6701,13 +6690,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6701 .Min => switch (scalar_ty.zigTypeTag(mod)) {6690 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6702 .Bool => Value.one_comptime_int,6691 .Bool => Value.one_comptime_int,
6703 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),6692 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),
6704 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6693 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
6705 else => unreachable,6694 else => unreachable,
6706 },6695 },
6707 .Max => switch (scalar_ty.zigTypeTag(mod)) {6696 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6708 .Bool => try mod.intValue(scalar_ty, 0),6697 .Bool => try mod.intValue(scalar_ty, 0),
6709 .Int => try scalar_ty.minInt(stack.get(), mod),6698 .Int => try scalar_ty.minInt(arena.allocator(), mod),
6710 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6699 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
6711 else => unreachable,6700 else => unreachable,
6712 },6701 },
6713 .Mul => try mod.intValue(Type.comptime_int, 1),6702 .Mul => try mod.intValue(Type.comptime_int, 1),
src/codegen/llvm.zig+7-10
...@@ -9238,22 +9238,19 @@ pub const FuncGen = struct {...@@ -9238,22 +9238,19 @@ pub const FuncGen = struct {
9238 }) catch unreachable,9238 }) catch unreachable,
9239 else => unreachable,9239 else => unreachable,
9240 };9240 };
9241 var init_value_payload = Value.Payload.Float_32{
9242 .data = switch (reduce.operation) {
9243 .Min => std.math.nan(f32),
9244 .Max => std.math.nan(f32),
9245 .Add => -0.0,
9246 .Mul => 1.0,
9247 else => unreachable,
9248 },
9249 };
92509241
9251 const param_llvm_ty = try self.dg.lowerType(scalar_ty);9242 const param_llvm_ty = try self.dg.lowerType(scalar_ty);
9252 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };9243 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };
9253 const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty);9244 const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
9254 const init_value = try self.dg.lowerValue(.{9245 const init_value = try self.dg.lowerValue(.{
9255 .ty = scalar_ty,9246 .ty = scalar_ty,
9256 .val = Value.initPayload(&init_value_payload.base),9247 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
9248 .Min => std.math.nan(f32),
9249 .Max => std.math.nan(f32),
9250 .Add => -0.0,
9251 .Mul => 1.0,
9252 else => unreachable,
9253 }),
9257 });9254 });
9258 return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(mod), init_value);9255 return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(mod), init_value);
9259 }9256 }
src/type.zig+10
...@@ -133,6 +133,7 @@ pub const Type = struct {...@@ -133,6 +133,7 @@ pub const Type = struct {
133 .un => unreachable,133 .un => unreachable,
134 .extern_func => unreachable,134 .extern_func => unreachable,
135 .int => unreachable,135 .int => unreachable,
136 .float => unreachable,
136 .ptr => unreachable,137 .ptr => unreachable,
137 .opt => unreachable,138 .opt => unreachable,
138 .enum_tag => unreachable,139 .enum_tag => unreachable,
...@@ -1434,6 +1435,7 @@ pub const Type = struct {...@@ -1434,6 +1435,7 @@ pub const Type = struct {
1434 .simple_value => unreachable,1435 .simple_value => unreachable,
1435 .extern_func => unreachable,1436 .extern_func => unreachable,
1436 .int => unreachable,1437 .int => unreachable,
1438 .float => unreachable,
1437 .ptr => unreachable,1439 .ptr => unreachable,
1438 .opt => unreachable,1440 .opt => unreachable,
1439 .enum_tag => unreachable,1441 .enum_tag => unreachable,
...@@ -1687,6 +1689,7 @@ pub const Type = struct {...@@ -1687,6 +1689,7 @@ pub const Type = struct {
1687 .simple_value => unreachable,1689 .simple_value => unreachable,
1688 .extern_func => unreachable,1690 .extern_func => unreachable,
1689 .int => unreachable,1691 .int => unreachable,
1692 .float => unreachable,
1690 .ptr => unreachable,1693 .ptr => unreachable,
1691 .opt => unreachable,1694 .opt => unreachable,
1692 .enum_tag => unreachable,1695 .enum_tag => unreachable,
...@@ -1803,6 +1806,7 @@ pub const Type = struct {...@@ -1803,6 +1806,7 @@ pub const Type = struct {
1803 .simple_value => unreachable,1806 .simple_value => unreachable,
1804 .extern_func => unreachable,1807 .extern_func => unreachable,
1805 .int => unreachable,1808 .int => unreachable,
1809 .float => unreachable,
1806 .ptr => unreachable,1810 .ptr => unreachable,
1807 .opt => unreachable,1811 .opt => unreachable,
1808 .enum_tag => unreachable,1812 .enum_tag => unreachable,
...@@ -2195,6 +2199,7 @@ pub const Type = struct {...@@ -2195,6 +2199,7 @@ pub const Type = struct {
2195 .simple_value => unreachable,2199 .simple_value => unreachable,
2196 .extern_func => unreachable,2200 .extern_func => unreachable,
2197 .int => unreachable,2201 .int => unreachable,
2202 .float => unreachable,
2198 .ptr => unreachable,2203 .ptr => unreachable,
2199 .opt => unreachable,2204 .opt => unreachable,
2200 .enum_tag => unreachable,2205 .enum_tag => unreachable,
...@@ -2612,6 +2617,7 @@ pub const Type = struct {...@@ -2612,6 +2617,7 @@ pub const Type = struct {
2612 .simple_value => unreachable,2617 .simple_value => unreachable,
2613 .extern_func => unreachable,2618 .extern_func => unreachable,
2614 .int => unreachable,2619 .int => unreachable,
2620 .float => unreachable,
2615 .ptr => unreachable,2621 .ptr => unreachable,
2616 .opt => unreachable,2622 .opt => unreachable,
2617 .enum_tag => unreachable,2623 .enum_tag => unreachable,
...@@ -2866,6 +2872,7 @@ pub const Type = struct {...@@ -2866,6 +2872,7 @@ pub const Type = struct {
2866 .simple_value => unreachable,2872 .simple_value => unreachable,
2867 .extern_func => unreachable,2873 .extern_func => unreachable,
2868 .int => unreachable,2874 .int => unreachable,
2875 .float => unreachable,
2869 .ptr => unreachable,2876 .ptr => unreachable,
2870 .opt => unreachable,2877 .opt => unreachable,
2871 .enum_tag => unreachable,2878 .enum_tag => unreachable,
...@@ -3632,6 +3639,7 @@ pub const Type = struct {...@@ -3632,6 +3639,7 @@ pub const Type = struct {
3632 .simple_value => unreachable,3639 .simple_value => unreachable,
3633 .extern_func => unreachable,3640 .extern_func => unreachable,
3634 .int => unreachable,3641 .int => unreachable,
3642 .float => unreachable,
3635 .ptr => unreachable,3643 .ptr => unreachable,
3636 .opt => unreachable,3644 .opt => unreachable,
3637 .enum_tag => unreachable,3645 .enum_tag => unreachable,
...@@ -3996,6 +4004,7 @@ pub const Type = struct {...@@ -3996,6 +4004,7 @@ pub const Type = struct {
3996 .simple_value => unreachable,4004 .simple_value => unreachable,
3997 .extern_func => unreachable,4005 .extern_func => unreachable,
3998 .int => unreachable,4006 .int => unreachable,
4007 .float => unreachable,
3999 .ptr => unreachable,4008 .ptr => unreachable,
4000 .opt => unreachable,4009 .opt => unreachable,
4001 .enum_tag => unreachable,4010 .enum_tag => unreachable,
...@@ -4157,6 +4166,7 @@ pub const Type = struct {...@@ -4157,6 +4166,7 @@ pub const Type = struct {
4157 .simple_value => unreachable,4166 .simple_value => unreachable,
4158 .extern_func => unreachable,4167 .extern_func => unreachable,
4159 .int => unreachable,4168 .int => unreachable,
4169 .float => unreachable,
4160 .ptr => unreachable,4170 .ptr => unreachable,
4161 .opt => unreachable,4171 .opt => unreachable,
4162 .enum_tag => unreachable,4172 .enum_tag => unreachable,
src/value.zig+505-783
...@@ -72,11 +72,6 @@ pub const Value = struct {...@@ -72,11 +72,6 @@ pub const Value = struct {
72 empty_array_sentinel,72 empty_array_sentinel,
73 /// Pointer and length as sub `Value` objects.73 /// Pointer and length as sub `Value` objects.
74 slice,74 slice,
75 float_16,
76 float_32,
77 float_64,
78 float_80,
79 float_128,
80 enum_literal,75 enum_literal,
81 /// A specific enum tag, indicated by the field index (declaration order).76 /// A specific enum tag, indicated by the field index (declaration order).
82 enum_field_index,77 enum_field_index,
...@@ -160,11 +155,6 @@ pub const Value = struct {...@@ -160,11 +155,6 @@ pub const Value = struct {
160 .decl_ref_mut => Payload.DeclRefMut,155 .decl_ref_mut => Payload.DeclRefMut,
161 .elem_ptr => Payload.ElemPtr,156 .elem_ptr => Payload.ElemPtr,
162 .field_ptr => Payload.FieldPtr,157 .field_ptr => Payload.FieldPtr,
163 .float_16 => Payload.Float_16,
164 .float_32 => Payload.Float_32,
165 .float_64 => Payload.Float_64,
166 .float_80 => Payload.Float_80,
167 .float_128 => Payload.Float_128,
168 .@"error" => Payload.Error,158 .@"error" => Payload.Error,
169 .inferred_alloc => Payload.InferredAlloc,159 .inferred_alloc => Payload.InferredAlloc,
170 .inferred_alloc_comptime => Payload.InferredAllocComptime,160 .inferred_alloc_comptime => Payload.InferredAllocComptime,
...@@ -395,11 +385,6 @@ pub const Value = struct {...@@ -395,11 +385,6 @@ pub const Value = struct {
395 .legacy = .{ .ptr_otherwise = &new_payload.base },385 .legacy = .{ .ptr_otherwise = &new_payload.base },
396 };386 };
397 },387 },
398 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),
399 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),
400 .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64),
401 .float_80 => return self.copyPayloadShallow(arena, Payload.Float_80),
402 .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128),
403 .enum_literal => {388 .enum_literal => {
404 const payload = self.castTag(.enum_literal).?;389 const payload = self.castTag(.enum_literal).?;
405 const new_payload = try arena.create(Payload.Bytes);390 const new_payload = try arena.create(Payload.Bytes);
...@@ -544,11 +529,6 @@ pub const Value = struct {...@@ -544,11 +529,6 @@ pub const Value = struct {
544 },529 },
545 .empty_array_sentinel => return out_stream.writeAll("(empty array with sentinel)"),530 .empty_array_sentinel => return out_stream.writeAll("(empty array with sentinel)"),
546 .slice => return out_stream.writeAll("(slice)"),531 .slice => return out_stream.writeAll("(slice)"),
547 .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}),
548 .float_32 => return out_stream.print("{}", .{val.castTag(.float_32).?.data}),
549 .float_64 => return out_stream.print("{}", .{val.castTag(.float_64).?.data}),
550 .float_80 => return out_stream.print("{}", .{val.castTag(.float_80).?.data}),
551 .float_128 => return out_stream.print("{}", .{val.castTag(.float_128).?.data}),
552 .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}),532 .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
553 .eu_payload => {533 .eu_payload => {
554 try out_stream.writeAll("(eu_payload) ");534 try out_stream.writeAll("(eu_payload) ");
...@@ -1181,14 +1161,17 @@ pub const Value = struct {...@@ -1181,14 +1161,17 @@ pub const Value = struct {
1181 return mod.intValue_big(ty, bigint.toConst());1161 return mod.intValue_big(ty, bigint.toConst());
1182 }1162 }
1183 },1163 },
1184 .Float => switch (ty.floatBits(target)) {1164 .Float => return (try mod.intern(.{ .float = .{
1185 16 => return Value.Tag.float_16.create(arena, @bitCast(f16, std.mem.readInt(u16, buffer[0..2], endian))),1165 .ty = ty.ip_index,
1186 32 => return Value.Tag.float_32.create(arena, @bitCast(f32, std.mem.readInt(u32, buffer[0..4], endian))),1166 .storage = switch (ty.floatBits(target)) {
1187 64 => return Value.Tag.float_64.create(arena, @bitCast(f64, std.mem.readInt(u64, buffer[0..8], endian))),1167 16 => .{ .f16 = @bitCast(f16, std.mem.readInt(u16, buffer[0..2], endian)) },
1188 80 => return Value.Tag.float_80.create(arena, @bitCast(f80, std.mem.readInt(u80, buffer[0..10], endian))),1168 32 => .{ .f32 = @bitCast(f32, std.mem.readInt(u32, buffer[0..4], endian)) },
1189 128 => return Value.Tag.float_128.create(arena, @bitCast(f128, std.mem.readInt(u128, buffer[0..16], endian))),1169 64 => .{ .f64 = @bitCast(f64, std.mem.readInt(u64, buffer[0..8], endian)) },
1190 else => unreachable,1170 80 => .{ .f80 = @bitCast(f80, std.mem.readInt(u80, buffer[0..10], endian)) },
1191 },1171 128 => .{ .f128 = @bitCast(f128, std.mem.readInt(u128, buffer[0..16], endian)) },
1172 else => unreachable,
1173 },
1174 } })).toValue(),
1192 .Array => {1175 .Array => {
1193 const elem_ty = ty.childType(mod);1176 const elem_ty = ty.childType(mod);
1194 const elem_size = elem_ty.abiSize(mod);1177 const elem_size = elem_ty.abiSize(mod);
...@@ -1294,14 +1277,17 @@ pub const Value = struct {...@@ -1294,14 +1277,17 @@ pub const Value = struct {
1294 return mod.intValue_big(ty, bigint.toConst());1277 return mod.intValue_big(ty, bigint.toConst());
1295 }1278 }
1296 },1279 },
1297 .Float => switch (ty.floatBits(target)) {1280 .Float => return (try mod.intern(.{ .float = .{
1298 16 => return Value.Tag.float_16.create(arena, @bitCast(f16, std.mem.readPackedInt(u16, buffer, bit_offset, endian))),1281 .ty = ty.ip_index,
1299 32 => return Value.Tag.float_32.create(arena, @bitCast(f32, std.mem.readPackedInt(u32, buffer, bit_offset, endian))),1282 .storage = switch (ty.floatBits(target)) {
1300 64 => return Value.Tag.float_64.create(arena, @bitCast(f64, std.mem.readPackedInt(u64, buffer, bit_offset, endian))),1283 16 => .{ .f16 = @bitCast(f16, std.mem.readPackedInt(u16, buffer, bit_offset, endian)) },
1301 80 => return Value.Tag.float_80.create(arena, @bitCast(f80, std.mem.readPackedInt(u80, buffer, bit_offset, endian))),1284 32 => .{ .f32 = @bitCast(f32, std.mem.readPackedInt(u32, buffer, bit_offset, endian)) },
1302 128 => return Value.Tag.float_128.create(arena, @bitCast(f128, std.mem.readPackedInt(u128, buffer, bit_offset, endian))),1285 64 => .{ .f64 = @bitCast(f64, std.mem.readPackedInt(u64, buffer, bit_offset, endian)) },
1303 else => unreachable,1286 80 => .{ .f80 = @bitCast(f80, std.mem.readPackedInt(u80, buffer, bit_offset, endian)) },
1304 },1287 128 => .{ .f128 = @bitCast(f128, std.mem.readPackedInt(u128, buffer, bit_offset, endian)) },
1288 else => unreachable,
1289 },
1290 } })).toValue(),
1305 .Vector => {1291 .Vector => {
1306 const elem_ty = ty.childType(mod);1292 const elem_ty = ty.childType(mod);
1307 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen(mod)));1293 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen(mod)));
...@@ -1346,28 +1332,20 @@ pub const Value = struct {...@@ -1346,28 +1332,20 @@ pub const Value = struct {
13461332
1347 /// Asserts that the value is a float or an integer.1333 /// Asserts that the value is a float or an integer.
1348 pub fn toFloat(val: Value, comptime T: type, mod: *const Module) T {1334 pub fn toFloat(val: Value, comptime T: type, mod: *const Module) T {
1349 return switch (val.ip_index) {1335 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
1350 .none => switch (val.tag()) {1336 .int => |int| switch (int.storage) {
1351 .float_16 => @floatCast(T, val.castTag(.float_16).?.data),1337 .big_int => |big_int| @floatCast(T, bigIntToFloat(big_int.limbs, big_int.positive)),
1352 .float_32 => @floatCast(T, val.castTag(.float_32).?.data),1338 inline .u64, .i64 => |x| {
1353 .float_64 => @floatCast(T, val.castTag(.float_64).?.data),1339 if (T == f80) {
1354 .float_80 => @floatCast(T, val.castTag(.float_80).?.data),1340 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");
1355 .float_128 => @floatCast(T, val.castTag(.float_128).?.data),1341 }
13561342 return @intToFloat(T, x);
1357 else => unreachable,
1358 },
1359 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1360 .int => |int| switch (int.storage) {
1361 .big_int => |big_int| @floatCast(T, bigIntToFloat(big_int.limbs, big_int.positive)),
1362 inline .u64, .i64 => |x| {
1363 if (T == f80) {
1364 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");
1365 }
1366 return @intToFloat(T, x);
1367 },
1368 },1343 },
1369 else => unreachable,
1370 },1344 },
1345 .float => |float| switch (float.storage) {
1346 inline else => |x| @floatCast(T, x),
1347 },
1348 else => unreachable,
1371 };1349 };
1372 }1350 }
13731351
...@@ -1552,28 +1530,27 @@ pub const Value = struct {...@@ -1552,28 +1530,27 @@ pub const Value = struct {
15521530
1553 /// Converts an integer or a float to a float. May result in a loss of information.1531 /// Converts an integer or a float to a float. May result in a loss of information.
1554 /// Caller can find out by equality checking the result against the operand.1532 /// Caller can find out by equality checking the result against the operand.
1555 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, mod: *const Module) !Value {1533 pub fn floatCast(self: Value, dest_ty: Type, mod: *Module) !Value {
1556 const target = mod.getTarget();1534 const target = mod.getTarget();
1557 switch (dest_ty.floatBits(target)) {1535 return (try mod.intern(.{ .float = .{
1558 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16, mod)),1536 .ty = dest_ty.ip_index,
1559 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32, mod)),1537 .storage = switch (dest_ty.floatBits(target)) {
1560 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64, mod)),1538 16 => .{ .f16 = self.toFloat(f16, mod) },
1561 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80, mod)),1539 32 => .{ .f32 = self.toFloat(f32, mod) },
1562 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128, mod)),1540 64 => .{ .f64 = self.toFloat(f64, mod) },
1563 else => unreachable,1541 80 => .{ .f80 = self.toFloat(f80, mod) },
1564 }1542 128 => .{ .f128 = self.toFloat(f128, mod) },
1543 else => unreachable,
1544 },
1545 } })).toValue();
1565 }1546 }
15661547
1567 /// Asserts the value is a float1548 /// Asserts the value is a float
1568 pub fn floatHasFraction(self: Value) bool {1549 pub fn floatHasFraction(self: Value, mod: *const Module) bool {
1569 return switch (self.tag()) {1550 return switch (mod.intern_pool.indexToKey(self.ip_index)) {
1570 .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0,1551 .float => |float| switch (float.storage) {
1571 .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0,1552 inline else => |x| @rem(x, 1) != 0,
1572 .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,1553 },
1573 //.float_80 => @rem(self.castTag(.float_80).?.data, 1) != 0,
1574 .float_80 => @panic("TODO implement __remx in compiler-rt"),
1575 .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
1576
1577 else => unreachable,1554 else => unreachable,
1578 };1555 };
1579 }1556 }
...@@ -1634,12 +1611,6 @@ pub const Value = struct {...@@ -1634,12 +1611,6 @@ pub const Value = struct {
1634 }1611 }
1635 },1612 },
16361613
1637 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
1638 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
1639 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
1640 .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0),
1641 .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
1642
1643 .elem_ptr => {1614 .elem_ptr => {
1644 const elem_ptr = lhs.castTag(.elem_ptr).?.data;1615 const elem_ptr = lhs.castTag(.elem_ptr).?.data;
1645 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {1616 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
...@@ -1662,6 +1633,9 @@ pub const Value = struct {...@@ -1662,6 +1633,9 @@ pub const Value = struct {
1662 .big_int => |big_int| big_int.orderAgainstScalar(0),1633 .big_int => |big_int| big_int.orderAgainstScalar(0),
1663 inline .u64, .i64 => |x| std.math.order(x, 0),1634 inline .u64, .i64 => |x| std.math.order(x, 0),
1664 },1635 },
1636 .float => |float| switch (float.storage) {
1637 inline else => |x| std.math.order(x, 0),
1638 },
1665 else => unreachable,1639 else => unreachable,
1666 },1640 },
1667 }1641 }
...@@ -1688,20 +1662,21 @@ pub const Value = struct {...@@ -1688,20 +1662,21 @@ pub const Value = struct {
1688 .gt => {},1662 .gt => {},
1689 }1663 }
16901664
1691 const lhs_float = lhs.isFloat();1665 const lhs_float = lhs.isFloat(mod);
1692 const rhs_float = rhs.isFloat();1666 const rhs_float = rhs.isFloat(mod);
1693 if (lhs_float and rhs_float) {1667 if (lhs_float and rhs_float) {
1694 const lhs_tag = lhs.tag();1668 const lhs_tag = lhs.tag();
1695 const rhs_tag = rhs.tag();1669 const rhs_tag = rhs.tag();
1696 if (lhs_tag == rhs_tag) {1670 if (lhs_tag == rhs_tag) {
1697 return switch (lhs.tag()) {1671 const lhs_storage = mod.intern_pool.indexToKey(lhs.ip_index).float.storage;
1698 .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data),1672 const rhs_storage = mod.intern_pool.indexToKey(rhs.ip_index).float.storage;
1699 .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data),1673 const lhs128: f128 = switch (lhs_storage) {
1700 .float_64 => return std.math.order(lhs.castTag(.float_64).?.data, rhs.castTag(.float_64).?.data),1674 inline else => |x| x,
1701 .float_80 => return std.math.order(lhs.castTag(.float_80).?.data, rhs.castTag(.float_80).?.data),
1702 .float_128 => return std.math.order(lhs.castTag(.float_128).?.data, rhs.castTag(.float_128).?.data),
1703 else => unreachable,
1704 };1675 };
1676 const rhs128: f128 = switch (rhs_storage) {
1677 inline else => |x| x,
1678 };
1679 return std.math.order(lhs128, rhs128);
1705 }1680 }
1706 }1681 }
1707 if (lhs_float or rhs_float) {1682 if (lhs_float or rhs_float) {
...@@ -1808,12 +1783,12 @@ pub const Value = struct {...@@ -1808,12 +1783,12 @@ pub const Value = struct {
1808 mod: *Module,1783 mod: *Module,
1809 opt_sema: ?*Sema,1784 opt_sema: ?*Sema,
1810 ) Module.CompileError!bool {1785 ) Module.CompileError!bool {
1811 if (lhs.isInf()) {1786 if (lhs.isInf(mod)) {
1812 switch (op) {1787 switch (op) {
1813 .neq => return true,1788 .neq => return true,
1814 .eq => return false,1789 .eq => return false,
1815 .gt, .gte => return !lhs.isNegativeInf(),1790 .gt, .gte => return !lhs.isNegativeInf(mod),
1816 .lt, .lte => return lhs.isNegativeInf(),1791 .lt, .lte => return lhs.isNegativeInf(mod),
1817 }1792 }
1818 }1793 }
18191794
...@@ -1841,14 +1816,14 @@ pub const Value = struct {...@@ -1841,14 +1816,14 @@ pub const Value = struct {
1841 }1816 }
1842 return true;1817 return true;
1843 },1818 },
1844 .float_16 => if (std.math.isNan(lhs.castTag(.float_16).?.data)) return op == .neq,
1845 .float_32 => if (std.math.isNan(lhs.castTag(.float_32).?.data)) return op == .neq,
1846 .float_64 => if (std.math.isNan(lhs.castTag(.float_64).?.data)) return op == .neq,
1847 .float_80 => if (std.math.isNan(lhs.castTag(.float_80).?.data)) return op == .neq,
1848 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,
1849 else => {},1819 else => {},
1850 },1820 },
1851 else => {},1821 else => switch (mod.intern_pool.indexToKey(lhs.ip_index)) {
1822 .float => |float| switch (float.storage) {
1823 inline else => |x| if (std.math.isNan(x)) return op == .neq,
1824 },
1825 else => {},
1826 },
1852 }1827 }
1853 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);1828 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);
1854 }1829 }
...@@ -2919,22 +2894,18 @@ pub const Value = struct {...@@ -2919,22 +2894,18 @@ pub const Value = struct {
2919 }2894 }
29202895
2921 /// Valid for all types. Asserts the value is not undefined.2896 /// Valid for all types. Asserts the value is not undefined.
2922 pub fn isFloat(self: Value) bool {2897 pub fn isFloat(self: Value, mod: *const Module) bool {
2923 return switch (self.ip_index) {2898 return switch (self.ip_index) {
2924 .undef => unreachable,2899 .undef => unreachable,
2925 .none => switch (self.tag()) {2900 .none => switch (self.tag()) {
2926 .inferred_alloc => unreachable,2901 .inferred_alloc => unreachable,
2927 .inferred_alloc_comptime => unreachable,2902 .inferred_alloc_comptime => unreachable,
2928
2929 .float_16,
2930 .float_32,
2931 .float_64,
2932 .float_80,
2933 .float_128,
2934 => true,
2935 else => false,2903 else => false,
2936 },2904 },
2937 else => false,2905 else => switch (mod.intern_pool.indexToKey(self.ip_index)) {
2906 .float => true,
2907 else => false,
2908 },
2938 };2909 };
2939 }2910 }
29402911
...@@ -2951,33 +2922,32 @@ pub const Value = struct {...@@ -2951,33 +2922,32 @@ pub const Value = struct {
2951 const scalar_ty = float_ty.scalarType(mod);2922 const scalar_ty = float_ty.scalarType(mod);
2952 for (result_data, 0..) |*scalar, i| {2923 for (result_data, 0..) |*scalar, i| {
2953 const elem_val = try val.elemValue(mod, i);2924 const elem_val = try val.elemValue(mod, i);
2954 scalar.* = try intToFloatScalar(elem_val, arena, scalar_ty, mod, opt_sema);2925 scalar.* = try intToFloatScalar(elem_val, scalar_ty, mod, opt_sema);
2955 }2926 }
2956 return Value.Tag.aggregate.create(arena, result_data);2927 return Value.Tag.aggregate.create(arena, result_data);
2957 }2928 }
2958 return intToFloatScalar(val, arena, float_ty, mod, opt_sema);2929 return intToFloatScalar(val, float_ty, mod, opt_sema);
2959 }2930 }
29602931
2961 pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {2932 pub fn intToFloatScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {
2962 const target = mod.getTarget();
2963 switch (val.ip_index) {2933 switch (val.ip_index) {
2964 .undef => return val,2934 .undef => return val,
2965 .none => switch (val.tag()) {2935 .none => switch (val.tag()) {
2966 .the_only_possible_value => return Value.float_zero, // for i0, u02936 .the_only_possible_value => return mod.floatValue(float_ty, 0), // for i0, u0
2967 .lazy_align => {2937 .lazy_align => {
2968 const ty = val.castTag(.lazy_align).?.data;2938 const ty = val.castTag(.lazy_align).?.data;
2969 if (opt_sema) |sema| {2939 if (opt_sema) |sema| {
2970 return intToFloatInner((try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar, arena, float_ty, target);2940 return intToFloatInner((try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar, float_ty, mod);
2971 } else {2941 } else {
2972 return intToFloatInner(ty.abiAlignment(mod), arena, float_ty, target);2942 return intToFloatInner(ty.abiAlignment(mod), float_ty, mod);
2973 }2943 }
2974 },2944 },
2975 .lazy_size => {2945 .lazy_size => {
2976 const ty = val.castTag(.lazy_size).?.data;2946 const ty = val.castTag(.lazy_size).?.data;
2977 if (opt_sema) |sema| {2947 if (opt_sema) |sema| {
2978 return intToFloatInner((try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar, arena, float_ty, target);2948 return intToFloatInner((try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar, float_ty, mod);
2979 } else {2949 } else {
2980 return intToFloatInner(ty.abiSize(mod), arena, float_ty, target);2950 return intToFloatInner(ty.abiSize(mod), float_ty, mod);
2981 }2951 }
2982 },2952 },
2983 else => unreachable,2953 else => unreachable,
...@@ -2986,35 +2956,29 @@ pub const Value = struct {...@@ -2986,35 +2956,29 @@ pub const Value = struct {
2986 .int => |int| switch (int.storage) {2956 .int => |int| switch (int.storage) {
2987 .big_int => |big_int| {2957 .big_int => |big_int| {
2988 const float = bigIntToFloat(big_int.limbs, big_int.positive);2958 const float = bigIntToFloat(big_int.limbs, big_int.positive);
2989 return floatToValue(float, arena, float_ty, target);2959 return mod.floatValue(float_ty, float);
2990 },2960 },
2991 inline .u64, .i64 => |x| intToFloatInner(x, arena, float_ty, target),2961 inline .u64, .i64 => |x| intToFloatInner(x, float_ty, mod),
2992 },2962 },
2993 else => unreachable,2963 else => unreachable,
2994 },2964 },
2995 }2965 }
2996 }2966 }
29972967
2998 fn intToFloatInner(x: anytype, arena: Allocator, dest_ty: Type, target: Target) !Value {2968 fn intToFloatInner(x: anytype, dest_ty: Type, mod: *Module) !Value {
2999 switch (dest_ty.floatBits(target)) {2969 const target = mod.getTarget();
3000 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)),2970 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {
3001 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)),2971 16 => .{ .f16 = @intToFloat(f16, x) },
3002 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)),2972 32 => .{ .f32 = @intToFloat(f32, x) },
3003 80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)),2973 64 => .{ .f64 = @intToFloat(f64, x) },
3004 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)),2974 80 => .{ .f80 = @intToFloat(f80, x) },
3005 else => unreachable,2975 128 => .{ .f128 = @intToFloat(f128, x) },
3006 }
3007 }
3008
3009 pub fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value {
3010 switch (dest_ty.floatBits(target)) {
3011 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)),
3012 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)),
3013 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)),
3014 80 => return Value.Tag.float_80.create(arena, @floatCast(f80, float)),
3015 128 => return Value.Tag.float_128.create(arena, float),
3016 else => unreachable,2976 else => unreachable,
3017 }2977 };
2978 return (try mod.intern(.{ .float = .{
2979 .ty = dest_ty.ip_index,
2980 .storage = storage,
2981 } })).toValue();
3018 }2982 }
30192983
3020 fn calcLimbLenFloat(scalar: anytype) usize {2984 fn calcLimbLenFloat(scalar: anytype) usize {
...@@ -3286,8 +3250,8 @@ pub const Value = struct {...@@ -3286,8 +3250,8 @@ pub const Value = struct {
3286 /// Supports both floats and ints; handles undefined.3250 /// Supports both floats and ints; handles undefined.
3287 pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {3251 pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {
3288 if (lhs.isUndef() or rhs.isUndef()) return undef;3252 if (lhs.isUndef() or rhs.isUndef()) return undef;
3289 if (lhs.isNan()) return rhs;3253 if (lhs.isNan(mod)) return rhs;
3290 if (rhs.isNan()) return lhs;3254 if (rhs.isNan(mod)) return lhs;
32913255
3292 return switch (order(lhs, rhs, mod)) {3256 return switch (order(lhs, rhs, mod)) {
3293 .lt => rhs,3257 .lt => rhs,
...@@ -3298,8 +3262,8 @@ pub const Value = struct {...@@ -3298,8 +3262,8 @@ pub const Value = struct {
3298 /// Supports both floats and ints; handles undefined.3262 /// Supports both floats and ints; handles undefined.
3299 pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {3263 pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {
3300 if (lhs.isUndef() or rhs.isUndef()) return undef;3264 if (lhs.isUndef() or rhs.isUndef()) return undef;
3301 if (lhs.isNan()) return rhs;3265 if (lhs.isNan(mod)) return rhs;
3302 if (rhs.isNan()) return lhs;3266 if (rhs.isNan(mod)) return lhs;
33033267
3304 return switch (order(lhs, rhs, mod)) {3268 return switch (order(lhs, rhs, mod)) {
3305 .lt => lhs,3269 .lt => lhs,
...@@ -3587,44 +3551,32 @@ pub const Value = struct {...@@ -3587,44 +3551,32 @@ pub const Value = struct {
3587 }3551 }
35883552
3589 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.3553 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
3590 pub fn isNan(val: Value) bool {3554 pub fn isNan(val: Value, mod: *const Module) bool {
3591 return switch (val.ip_index) {3555 if (val.ip_index == .none) return false;
3592 .none => switch (val.tag()) {3556 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3593 .float_16 => std.math.isNan(val.castTag(.float_16).?.data),3557 .float => |float| switch (float.storage) {
3594 .float_32 => std.math.isNan(val.castTag(.float_32).?.data),3558 inline else => |x| std.math.isNan(x),
3595 .float_64 => std.math.isNan(val.castTag(.float_64).?.data),
3596 .float_80 => std.math.isNan(val.castTag(.float_80).?.data),
3597 .float_128 => std.math.isNan(val.castTag(.float_128).?.data),
3598 else => false,
3599 },3559 },
3600 else => false,3560 else => false,
3601 };3561 };
3602 }3562 }
36033563
3604 /// Returns true if the value is a floating point type and is infinite. Returns false otherwise.3564 /// Returns true if the value is a floating point type and is infinite. Returns false otherwise.
3605 pub fn isInf(val: Value) bool {3565 pub fn isInf(val: Value, mod: *const Module) bool {
3606 return switch (val.ip_index) {3566 if (val.ip_index == .none) return false;
3607 .none => switch (val.tag()) {3567 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3608 .float_16 => std.math.isInf(val.castTag(.float_16).?.data),3568 .float => |float| switch (float.storage) {
3609 .float_32 => std.math.isInf(val.castTag(.float_32).?.data),3569 inline else => |x| std.math.isInf(x),
3610 .float_64 => std.math.isInf(val.castTag(.float_64).?.data),
3611 .float_80 => std.math.isInf(val.castTag(.float_80).?.data),
3612 .float_128 => std.math.isInf(val.castTag(.float_128).?.data),
3613 else => false,
3614 },3570 },
3615 else => false,3571 else => false,
3616 };3572 };
3617 }3573 }
36183574
3619 pub fn isNegativeInf(val: Value) bool {3575 pub fn isNegativeInf(val: Value, mod: *const Module) bool {
3620 return switch (val.ip_index) {3576 if (val.ip_index == .none) return false;
3621 .none => switch (val.tag()) {3577 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3622 .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data),3578 .float => |float| switch (float.storage) {
3623 .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data),3579 inline else => |x| std.math.isNegativeInf(x),
3624 .float_64 => std.math.isNegativeInf(val.castTag(.float_64).?.data),
3625 .float_80 => std.math.isNegativeInf(val.castTag(.float_80).?.data),
3626 .float_128 => std.math.isNegativeInf(val.castTag(.float_128).?.data),
3627 else => false,
3628 },3580 },
3629 else => false,3581 else => false,
3630 };3582 };
...@@ -3636,43 +3588,27 @@ pub const Value = struct {...@@ -3636,43 +3588,27 @@ pub const Value = struct {
3636 for (result_data, 0..) |*scalar, i| {3588 for (result_data, 0..) |*scalar, i| {
3637 const lhs_elem = try lhs.elemValue(mod, i);3589 const lhs_elem = try lhs.elemValue(mod, i);
3638 const rhs_elem = try rhs.elemValue(mod, i);3590 const rhs_elem = try rhs.elemValue(mod, i);
3639 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);3591 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
3640 }3592 }
3641 return Value.Tag.aggregate.create(arena, result_data);3593 return Value.Tag.aggregate.create(arena, result_data);
3642 }3594 }
3643 return floatRemScalar(lhs, rhs, float_type, arena, mod);3595 return floatRemScalar(lhs, rhs, float_type, mod);
3644 }3596 }
36453597
3646 pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *const Module) !Value {3598 pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {
3647 const target = mod.getTarget();3599 const target = mod.getTarget();
3648 switch (float_type.floatBits(target)) {3600 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3649 16 => {3601 16 => .{ .f16 = @rem(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },
3650 const lhs_val = lhs.toFloat(f16, mod);3602 32 => .{ .f32 = @rem(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },
3651 const rhs_val = rhs.toFloat(f16, mod);3603 64 => .{ .f64 = @rem(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },
3652 return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val));3604 80 => .{ .f80 = @rem(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },
3653 },3605 128 => .{ .f128 = @rem(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },
3654 32 => {
3655 const lhs_val = lhs.toFloat(f32, mod);
3656 const rhs_val = rhs.toFloat(f32, mod);
3657 return Value.Tag.float_32.create(arena, @rem(lhs_val, rhs_val));
3658 },
3659 64 => {
3660 const lhs_val = lhs.toFloat(f64, mod);
3661 const rhs_val = rhs.toFloat(f64, mod);
3662 return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val));
3663 },
3664 80 => {
3665 const lhs_val = lhs.toFloat(f80, mod);
3666 const rhs_val = rhs.toFloat(f80, mod);
3667 return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val));
3668 },
3669 128 => {
3670 const lhs_val = lhs.toFloat(f128, mod);
3671 const rhs_val = rhs.toFloat(f128, mod);
3672 return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val));
3673 },
3674 else => unreachable,3606 else => unreachable,
3675 }3607 };
3608 return (try mod.intern(.{ .float = .{
3609 .ty = float_type.ip_index,
3610 .storage = storage,
3611 } })).toValue();
3676 }3612 }
36773613
3678 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3614 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -3681,43 +3617,27 @@ pub const Value = struct {...@@ -3681,43 +3617,27 @@ pub const Value = struct {
3681 for (result_data, 0..) |*scalar, i| {3617 for (result_data, 0..) |*scalar, i| {
3682 const lhs_elem = try lhs.elemValue(mod, i);3618 const lhs_elem = try lhs.elemValue(mod, i);
3683 const rhs_elem = try rhs.elemValue(mod, i);3619 const rhs_elem = try rhs.elemValue(mod, i);
3684 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);3620 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
3685 }3621 }
3686 return Value.Tag.aggregate.create(arena, result_data);3622 return Value.Tag.aggregate.create(arena, result_data);
3687 }3623 }
3688 return floatModScalar(lhs, rhs, float_type, arena, mod);3624 return floatModScalar(lhs, rhs, float_type, mod);
3689 }3625 }
36903626
3691 pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *const Module) !Value {3627 pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {
3692 const target = mod.getTarget();3628 const target = mod.getTarget();
3693 switch (float_type.floatBits(target)) {3629 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3694 16 => {3630 16 => .{ .f16 = @mod(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },
3695 const lhs_val = lhs.toFloat(f16, mod);3631 32 => .{ .f32 = @mod(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },
3696 const rhs_val = rhs.toFloat(f16, mod);3632 64 => .{ .f64 = @mod(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },
3697 return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val));3633 80 => .{ .f80 = @mod(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },
3698 },3634 128 => .{ .f128 = @mod(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },
3699 32 => {
3700 const lhs_val = lhs.toFloat(f32, mod);
3701 const rhs_val = rhs.toFloat(f32, mod);
3702 return Value.Tag.float_32.create(arena, @mod(lhs_val, rhs_val));
3703 },
3704 64 => {
3705 const lhs_val = lhs.toFloat(f64, mod);
3706 const rhs_val = rhs.toFloat(f64, mod);
3707 return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val));
3708 },
3709 80 => {
3710 const lhs_val = lhs.toFloat(f80, mod);
3711 const rhs_val = rhs.toFloat(f80, mod);
3712 return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val));
3713 },
3714 128 => {
3715 const lhs_val = lhs.toFloat(f128, mod);
3716 const rhs_val = rhs.toFloat(f128, mod);
3717 return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val));
3718 },
3719 else => unreachable,3635 else => unreachable,
3720 }3636 };
3637 return (try mod.intern(.{ .float = .{
3638 .ty = float_type.ip_index,
3639 .storage = storage,
3640 } })).toValue();
3721 }3641 }
37223642
3723 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3643 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
...@@ -4035,28 +3955,111 @@ pub const Value = struct {...@@ -4035,28 +3955,111 @@ pub const Value = struct {
4035 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));3955 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4036 for (result_data, 0..) |*scalar, i| {3956 for (result_data, 0..) |*scalar, i| {
4037 const elem_val = try val.elemValue(mod, i);3957 const elem_val = try val.elemValue(mod, i);
4038 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(mod), arena, mod);3958 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(mod), mod);
4039 }3959 }
4040 return Value.Tag.aggregate.create(arena, result_data);3960 return Value.Tag.aggregate.create(arena, result_data);
4041 }3961 }
4042 return floatNegScalar(val, float_type, arena, mod);3962 return floatNegScalar(val, float_type, mod);
4043 }3963 }
40443964
4045 pub fn floatNegScalar(3965 pub fn floatNegScalar(
4046 val: Value,3966 val: Value,
4047 float_type: Type,3967 float_type: Type,
3968 mod: *Module,
3969 ) !Value {
3970 const target = mod.getTarget();
3971 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3972 16 => .{ .f16 = -val.toFloat(f16, mod) },
3973 32 => .{ .f32 = -val.toFloat(f32, mod) },
3974 64 => .{ .f64 = -val.toFloat(f64, mod) },
3975 80 => .{ .f80 = -val.toFloat(f80, mod) },
3976 128 => .{ .f128 = -val.toFloat(f128, mod) },
3977 else => unreachable,
3978 };
3979 return (try mod.intern(.{ .float = .{
3980 .ty = float_type.ip_index,
3981 .storage = storage,
3982 } })).toValue();
3983 }
3984
3985 pub fn floatAdd(
3986 lhs: Value,
3987 rhs: Value,
3988 float_type: Type,
4048 arena: Allocator,3989 arena: Allocator,
4049 mod: *const Module,3990 mod: *Module,
3991 ) !Value {
3992 if (float_type.zigTypeTag(mod) == .Vector) {
3993 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
3994 for (result_data, 0..) |*scalar, i| {
3995 const lhs_elem = try lhs.elemValue(mod, i);
3996 const rhs_elem = try rhs.elemValue(mod, i);
3997 scalar.* = try floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
3998 }
3999 return Value.Tag.aggregate.create(arena, result_data);
4000 }
4001 return floatAddScalar(lhs, rhs, float_type, mod);
4002 }
4003
4004 pub fn floatAddScalar(
4005 lhs: Value,
4006 rhs: Value,
4007 float_type: Type,
4008 mod: *Module,
4050 ) !Value {4009 ) !Value {
4051 const target = mod.getTarget();4010 const target = mod.getTarget();
4052 switch (float_type.floatBits(target)) {4011 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4053 16 => return Value.Tag.float_16.create(arena, -val.toFloat(f16, mod)),4012 16 => .{ .f16 = lhs.toFloat(f16, mod) + rhs.toFloat(f16, mod) },
4054 32 => return Value.Tag.float_32.create(arena, -val.toFloat(f32, mod)),4013 32 => .{ .f32 = lhs.toFloat(f32, mod) + rhs.toFloat(f32, mod) },
4055 64 => return Value.Tag.float_64.create(arena, -val.toFloat(f64, mod)),4014 64 => .{ .f64 = lhs.toFloat(f64, mod) + rhs.toFloat(f64, mod) },
4056 80 => return Value.Tag.float_80.create(arena, -val.toFloat(f80, mod)),4015 80 => .{ .f80 = lhs.toFloat(f80, mod) + rhs.toFloat(f80, mod) },
4057 128 => return Value.Tag.float_128.create(arena, -val.toFloat(f128, mod)),4016 128 => .{ .f128 = lhs.toFloat(f128, mod) + rhs.toFloat(f128, mod) },
4058 else => unreachable,4017 else => unreachable,
4018 };
4019 return (try mod.intern(.{ .float = .{
4020 .ty = float_type.ip_index,
4021 .storage = storage,
4022 } })).toValue();
4023 }
4024
4025 pub fn floatSub(
4026 lhs: Value,
4027 rhs: Value,
4028 float_type: Type,
4029 arena: Allocator,
4030 mod: *Module,
4031 ) !Value {
4032 if (float_type.zigTypeTag(mod) == .Vector) {
4033 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4034 for (result_data, 0..) |*scalar, i| {
4035 const lhs_elem = try lhs.elemValue(mod, i);
4036 const rhs_elem = try rhs.elemValue(mod, i);
4037 scalar.* = try floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
4038 }
4039 return Value.Tag.aggregate.create(arena, result_data);
4059 }4040 }
4041 return floatSubScalar(lhs, rhs, float_type, mod);
4042 }
4043
4044 pub fn floatSubScalar(
4045 lhs: Value,
4046 rhs: Value,
4047 float_type: Type,
4048 mod: *Module,
4049 ) !Value {
4050 const target = mod.getTarget();
4051 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4052 16 => .{ .f16 = lhs.toFloat(f16, mod) - rhs.toFloat(f16, mod) },
4053 32 => .{ .f32 = lhs.toFloat(f32, mod) - rhs.toFloat(f32, mod) },
4054 64 => .{ .f64 = lhs.toFloat(f64, mod) - rhs.toFloat(f64, mod) },
4055 80 => .{ .f80 = lhs.toFloat(f80, mod) - rhs.toFloat(f80, mod) },
4056 128 => .{ .f128 = lhs.toFloat(f128, mod) - rhs.toFloat(f128, mod) },
4057 else => unreachable,
4058 };
4059 return (try mod.intern(.{ .float = .{
4060 .ty = float_type.ip_index,
4061 .storage = storage,
4062 } })).toValue();
4060 }4063 }
40614064
4062 pub fn floatDiv(4065 pub fn floatDiv(
...@@ -4071,49 +4074,32 @@ pub const Value = struct {...@@ -4071,49 +4074,32 @@ pub const Value = struct {
4071 for (result_data, 0..) |*scalar, i| {4074 for (result_data, 0..) |*scalar, i| {
4072 const lhs_elem = try lhs.elemValue(mod, i);4075 const lhs_elem = try lhs.elemValue(mod, i);
4073 const rhs_elem = try rhs.elemValue(mod, i);4076 const rhs_elem = try rhs.elemValue(mod, i);
4074 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);4077 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
4075 }4078 }
4076 return Value.Tag.aggregate.create(arena, result_data);4079 return Value.Tag.aggregate.create(arena, result_data);
4077 }4080 }
4078 return floatDivScalar(lhs, rhs, float_type, arena, mod);4081 return floatDivScalar(lhs, rhs, float_type, mod);
4079 }4082 }
40804083
4081 pub fn floatDivScalar(4084 pub fn floatDivScalar(
4082 lhs: Value,4085 lhs: Value,
4083 rhs: Value,4086 rhs: Value,
4084 float_type: Type,4087 float_type: Type,
4085 arena: Allocator,4088 mod: *Module,
4086 mod: *const Module,
4087 ) !Value {4089 ) !Value {
4088 const target = mod.getTarget();4090 const target = mod.getTarget();
4089 switch (float_type.floatBits(target)) {4091 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4090 16 => {4092 16 => .{ .f16 = lhs.toFloat(f16, mod) / rhs.toFloat(f16, mod) },
4091 const lhs_val = lhs.toFloat(f16, mod);4093 32 => .{ .f32 = lhs.toFloat(f32, mod) / rhs.toFloat(f32, mod) },
4092 const rhs_val = rhs.toFloat(f16, mod);4094 64 => .{ .f64 = lhs.toFloat(f64, mod) / rhs.toFloat(f64, mod) },
4093 return Value.Tag.float_16.create(arena, lhs_val / rhs_val);4095 80 => .{ .f80 = lhs.toFloat(f80, mod) / rhs.toFloat(f80, mod) },
4094 },4096 128 => .{ .f128 = lhs.toFloat(f128, mod) / rhs.toFloat(f128, mod) },
4095 32 => {
4096 const lhs_val = lhs.toFloat(f32, mod);
4097 const rhs_val = rhs.toFloat(f32, mod);
4098 return Value.Tag.float_32.create(arena, lhs_val / rhs_val);
4099 },
4100 64 => {
4101 const lhs_val = lhs.toFloat(f64, mod);
4102 const rhs_val = rhs.toFloat(f64, mod);
4103 return Value.Tag.float_64.create(arena, lhs_val / rhs_val);
4104 },
4105 80 => {
4106 const lhs_val = lhs.toFloat(f80, mod);
4107 const rhs_val = rhs.toFloat(f80, mod);
4108 return Value.Tag.float_80.create(arena, lhs_val / rhs_val);
4109 },
4110 128 => {
4111 const lhs_val = lhs.toFloat(f128, mod);
4112 const rhs_val = rhs.toFloat(f128, mod);
4113 return Value.Tag.float_128.create(arena, lhs_val / rhs_val);
4114 },
4115 else => unreachable,4097 else => unreachable,
4116 }4098 };
4099 return (try mod.intern(.{ .float = .{
4100 .ty = float_type.ip_index,
4101 .storage = storage,
4102 } })).toValue();
4117 }4103 }
41184104
4119 pub fn floatDivFloor(4105 pub fn floatDivFloor(
...@@ -4128,49 +4114,32 @@ pub const Value = struct {...@@ -4128,49 +4114,32 @@ pub const Value = struct {
4128 for (result_data, 0..) |*scalar, i| {4114 for (result_data, 0..) |*scalar, i| {
4129 const lhs_elem = try lhs.elemValue(mod, i);4115 const lhs_elem = try lhs.elemValue(mod, i);
4130 const rhs_elem = try rhs.elemValue(mod, i);4116 const rhs_elem = try rhs.elemValue(mod, i);
4131 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);4117 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
4132 }4118 }
4133 return Value.Tag.aggregate.create(arena, result_data);4119 return Value.Tag.aggregate.create(arena, result_data);
4134 }4120 }
4135 return floatDivFloorScalar(lhs, rhs, float_type, arena, mod);4121 return floatDivFloorScalar(lhs, rhs, float_type, mod);
4136 }4122 }
41374123
4138 pub fn floatDivFloorScalar(4124 pub fn floatDivFloorScalar(
4139 lhs: Value,4125 lhs: Value,
4140 rhs: Value,4126 rhs: Value,
4141 float_type: Type,4127 float_type: Type,
4142 arena: Allocator,4128 mod: *Module,
4143 mod: *const Module,
4144 ) !Value {4129 ) !Value {
4145 const target = mod.getTarget();4130 const target = mod.getTarget();
4146 switch (float_type.floatBits(target)) {4131 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4147 16 => {4132 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },
4148 const lhs_val = lhs.toFloat(f16, mod);4133 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },
4149 const rhs_val = rhs.toFloat(f16, mod);4134 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },
4150 return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val));4135 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },
4151 },4136 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },
4152 32 => {
4153 const lhs_val = lhs.toFloat(f32, mod);
4154 const rhs_val = rhs.toFloat(f32, mod);
4155 return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val));
4156 },
4157 64 => {
4158 const lhs_val = lhs.toFloat(f64, mod);
4159 const rhs_val = rhs.toFloat(f64, mod);
4160 return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val));
4161 },
4162 80 => {
4163 const lhs_val = lhs.toFloat(f80, mod);
4164 const rhs_val = rhs.toFloat(f80, mod);
4165 return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val));
4166 },
4167 128 => {
4168 const lhs_val = lhs.toFloat(f128, mod);
4169 const rhs_val = rhs.toFloat(f128, mod);
4170 return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val));
4171 },
4172 else => unreachable,4137 else => unreachable,
4173 }4138 };
4139 return (try mod.intern(.{ .float = .{
4140 .ty = float_type.ip_index,
4141 .storage = storage,
4142 } })).toValue();
4174 }4143 }
41754144
4176 pub fn floatDivTrunc(4145 pub fn floatDivTrunc(
...@@ -4185,49 +4154,32 @@ pub const Value = struct {...@@ -4185,49 +4154,32 @@ pub const Value = struct {
4185 for (result_data, 0..) |*scalar, i| {4154 for (result_data, 0..) |*scalar, i| {
4186 const lhs_elem = try lhs.elemValue(mod, i);4155 const lhs_elem = try lhs.elemValue(mod, i);
4187 const rhs_elem = try rhs.elemValue(mod, i);4156 const rhs_elem = try rhs.elemValue(mod, i);
4188 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);4157 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
4189 }4158 }
4190 return Value.Tag.aggregate.create(arena, result_data);4159 return Value.Tag.aggregate.create(arena, result_data);
4191 }4160 }
4192 return floatDivTruncScalar(lhs, rhs, float_type, arena, mod);4161 return floatDivTruncScalar(lhs, rhs, float_type, mod);
4193 }4162 }
41944163
4195 pub fn floatDivTruncScalar(4164 pub fn floatDivTruncScalar(
4196 lhs: Value,4165 lhs: Value,
4197 rhs: Value,4166 rhs: Value,
4198 float_type: Type,4167 float_type: Type,
4199 arena: Allocator,4168 mod: *Module,
4200 mod: *const Module,
4201 ) !Value {4169 ) !Value {
4202 const target = mod.getTarget();4170 const target = mod.getTarget();
4203 switch (float_type.floatBits(target)) {4171 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4204 16 => {4172 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },
4205 const lhs_val = lhs.toFloat(f16, mod);4173 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },
4206 const rhs_val = rhs.toFloat(f16, mod);4174 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },
4207 return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val));4175 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },
4208 },4176 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },
4209 32 => {
4210 const lhs_val = lhs.toFloat(f32, mod);
4211 const rhs_val = rhs.toFloat(f32, mod);
4212 return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val));
4213 },
4214 64 => {
4215 const lhs_val = lhs.toFloat(f64, mod);
4216 const rhs_val = rhs.toFloat(f64, mod);
4217 return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val));
4218 },
4219 80 => {
4220 const lhs_val = lhs.toFloat(f80, mod);
4221 const rhs_val = rhs.toFloat(f80, mod);
4222 return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val));
4223 },
4224 128 => {
4225 const lhs_val = lhs.toFloat(f128, mod);
4226 const rhs_val = rhs.toFloat(f128, mod);
4227 return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val));
4228 },
4229 else => unreachable,4177 else => unreachable,
4230 }4178 };
4179 return (try mod.intern(.{ .float = .{
4180 .ty = float_type.ip_index,
4181 .storage = storage,
4182 } })).toValue();
4231 }4183 }
42324184
4233 pub fn floatMul(4185 pub fn floatMul(
...@@ -4242,49 +4194,32 @@ pub const Value = struct {...@@ -4242,49 +4194,32 @@ pub const Value = struct {
4242 for (result_data, 0..) |*scalar, i| {4194 for (result_data, 0..) |*scalar, i| {
4243 const lhs_elem = try lhs.elemValue(mod, i);4195 const lhs_elem = try lhs.elemValue(mod, i);
4244 const rhs_elem = try rhs.elemValue(mod, i);4196 const rhs_elem = try rhs.elemValue(mod, i);
4245 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);4197 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), mod);
4246 }4198 }
4247 return Value.Tag.aggregate.create(arena, result_data);4199 return Value.Tag.aggregate.create(arena, result_data);
4248 }4200 }
4249 return floatMulScalar(lhs, rhs, float_type, arena, mod);4201 return floatMulScalar(lhs, rhs, float_type, mod);
4250 }4202 }
42514203
4252 pub fn floatMulScalar(4204 pub fn floatMulScalar(
4253 lhs: Value,4205 lhs: Value,
4254 rhs: Value,4206 rhs: Value,
4255 float_type: Type,4207 float_type: Type,
4256 arena: Allocator,4208 mod: *Module,
4257 mod: *const Module,
4258 ) !Value {4209 ) !Value {
4259 const target = mod.getTarget();4210 const target = mod.getTarget();
4260 switch (float_type.floatBits(target)) {4211 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4261 16 => {4212 16 => .{ .f16 = lhs.toFloat(f16, mod) * rhs.toFloat(f16, mod) },
4262 const lhs_val = lhs.toFloat(f16, mod);4213 32 => .{ .f32 = lhs.toFloat(f32, mod) * rhs.toFloat(f32, mod) },
4263 const rhs_val = rhs.toFloat(f16, mod);4214 64 => .{ .f64 = lhs.toFloat(f64, mod) * rhs.toFloat(f64, mod) },
4264 return Value.Tag.float_16.create(arena, lhs_val * rhs_val);4215 80 => .{ .f80 = lhs.toFloat(f80, mod) * rhs.toFloat(f80, mod) },
4265 },4216 128 => .{ .f128 = lhs.toFloat(f128, mod) * rhs.toFloat(f128, mod) },
4266 32 => {
4267 const lhs_val = lhs.toFloat(f32, mod);
4268 const rhs_val = rhs.toFloat(f32, mod);
4269 return Value.Tag.float_32.create(arena, lhs_val * rhs_val);
4270 },
4271 64 => {
4272 const lhs_val = lhs.toFloat(f64, mod);
4273 const rhs_val = rhs.toFloat(f64, mod);
4274 return Value.Tag.float_64.create(arena, lhs_val * rhs_val);
4275 },
4276 80 => {
4277 const lhs_val = lhs.toFloat(f80, mod);
4278 const rhs_val = rhs.toFloat(f80, mod);
4279 return Value.Tag.float_80.create(arena, lhs_val * rhs_val);
4280 },
4281 128 => {
4282 const lhs_val = lhs.toFloat(f128, mod);
4283 const rhs_val = rhs.toFloat(f128, mod);
4284 return Value.Tag.float_128.create(arena, lhs_val * rhs_val);
4285 },
4286 else => unreachable,4217 else => unreachable,
4287 }4218 };
4219 return (try mod.intern(.{ .float = .{
4220 .ty = float_type.ip_index,
4221 .storage = storage,
4222 } })).toValue();
4288 }4223 }
42894224
4290 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4225 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4292,38 +4227,27 @@ pub const Value = struct {...@@ -4292,38 +4227,27 @@ pub const Value = struct {
4292 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4227 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4293 for (result_data, 0..) |*scalar, i| {4228 for (result_data, 0..) |*scalar, i| {
4294 const elem_val = try val.elemValue(mod, i);4229 const elem_val = try val.elemValue(mod, i);
4295 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(mod), arena, mod);4230 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(mod), mod);
4296 }4231 }
4297 return Value.Tag.aggregate.create(arena, result_data);4232 return Value.Tag.aggregate.create(arena, result_data);
4298 }4233 }
4299 return sqrtScalar(val, float_type, arena, mod);4234 return sqrtScalar(val, float_type, mod);
4300 }4235 }
43014236
4302 pub fn sqrtScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4237 pub fn sqrtScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4303 const target = mod.getTarget();4238 const target = mod.getTarget();
4304 switch (float_type.floatBits(target)) {4239 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4305 16 => {4240 16 => .{ .f16 = @sqrt(val.toFloat(f16, mod)) },
4306 const f = val.toFloat(f16, mod);4241 32 => .{ .f32 = @sqrt(val.toFloat(f32, mod)) },
4307 return Value.Tag.float_16.create(arena, @sqrt(f));4242 64 => .{ .f64 = @sqrt(val.toFloat(f64, mod)) },
4308 },4243 80 => .{ .f80 = @sqrt(val.toFloat(f80, mod)) },
4309 32 => {4244 128 => .{ .f128 = @sqrt(val.toFloat(f128, mod)) },
4310 const f = val.toFloat(f32, mod);
4311 return Value.Tag.float_32.create(arena, @sqrt(f));
4312 },
4313 64 => {
4314 const f = val.toFloat(f64, mod);
4315 return Value.Tag.float_64.create(arena, @sqrt(f));
4316 },
4317 80 => {
4318 const f = val.toFloat(f80, mod);
4319 return Value.Tag.float_80.create(arena, @sqrt(f));
4320 },
4321 128 => {
4322 const f = val.toFloat(f128, mod);
4323 return Value.Tag.float_128.create(arena, @sqrt(f));
4324 },
4325 else => unreachable,4245 else => unreachable,
4326 }4246 };
4247 return (try mod.intern(.{ .float = .{
4248 .ty = float_type.ip_index,
4249 .storage = storage,
4250 } })).toValue();
4327 }4251 }
43284252
4329 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4253 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4331,38 +4255,27 @@ pub const Value = struct {...@@ -4331,38 +4255,27 @@ pub const Value = struct {
4331 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4255 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4332 for (result_data, 0..) |*scalar, i| {4256 for (result_data, 0..) |*scalar, i| {
4333 const elem_val = try val.elemValue(mod, i);4257 const elem_val = try val.elemValue(mod, i);
4334 scalar.* = try sinScalar(elem_val, float_type.scalarType(mod), arena, mod);4258 scalar.* = try sinScalar(elem_val, float_type.scalarType(mod), mod);
4335 }4259 }
4336 return Value.Tag.aggregate.create(arena, result_data);4260 return Value.Tag.aggregate.create(arena, result_data);
4337 }4261 }
4338 return sinScalar(val, float_type, arena, mod);4262 return sinScalar(val, float_type, mod);
4339 }4263 }
43404264
4341 pub fn sinScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4265 pub fn sinScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4342 const target = mod.getTarget();4266 const target = mod.getTarget();
4343 switch (float_type.floatBits(target)) {4267 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4344 16 => {4268 16 => .{ .f16 = @sin(val.toFloat(f16, mod)) },
4345 const f = val.toFloat(f16, mod);4269 32 => .{ .f32 = @sin(val.toFloat(f32, mod)) },
4346 return Value.Tag.float_16.create(arena, @sin(f));4270 64 => .{ .f64 = @sin(val.toFloat(f64, mod)) },
4347 },4271 80 => .{ .f80 = @sin(val.toFloat(f80, mod)) },
4348 32 => {4272 128 => .{ .f128 = @sin(val.toFloat(f128, mod)) },
4349 const f = val.toFloat(f32, mod);
4350 return Value.Tag.float_32.create(arena, @sin(f));
4351 },
4352 64 => {
4353 const f = val.toFloat(f64, mod);
4354 return Value.Tag.float_64.create(arena, @sin(f));
4355 },
4356 80 => {
4357 const f = val.toFloat(f80, mod);
4358 return Value.Tag.float_80.create(arena, @sin(f));
4359 },
4360 128 => {
4361 const f = val.toFloat(f128, mod);
4362 return Value.Tag.float_128.create(arena, @sin(f));
4363 },
4364 else => unreachable,4273 else => unreachable,
4365 }4274 };
4275 return (try mod.intern(.{ .float = .{
4276 .ty = float_type.ip_index,
4277 .storage = storage,
4278 } })).toValue();
4366 }4279 }
43674280
4368 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4281 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4370,38 +4283,27 @@ pub const Value = struct {...@@ -4370,38 +4283,27 @@ pub const Value = struct {
4370 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4283 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4371 for (result_data, 0..) |*scalar, i| {4284 for (result_data, 0..) |*scalar, i| {
4372 const elem_val = try val.elemValue(mod, i);4285 const elem_val = try val.elemValue(mod, i);
4373 scalar.* = try cosScalar(elem_val, float_type.scalarType(mod), arena, mod);4286 scalar.* = try cosScalar(elem_val, float_type.scalarType(mod), mod);
4374 }4287 }
4375 return Value.Tag.aggregate.create(arena, result_data);4288 return Value.Tag.aggregate.create(arena, result_data);
4376 }4289 }
4377 return cosScalar(val, float_type, arena, mod);4290 return cosScalar(val, float_type, mod);
4378 }4291 }
43794292
4380 pub fn cosScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4293 pub fn cosScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4381 const target = mod.getTarget();4294 const target = mod.getTarget();
4382 switch (float_type.floatBits(target)) {4295 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4383 16 => {4296 16 => .{ .f16 = @cos(val.toFloat(f16, mod)) },
4384 const f = val.toFloat(f16, mod);4297 32 => .{ .f32 = @cos(val.toFloat(f32, mod)) },
4385 return Value.Tag.float_16.create(arena, @cos(f));4298 64 => .{ .f64 = @cos(val.toFloat(f64, mod)) },
4386 },4299 80 => .{ .f80 = @cos(val.toFloat(f80, mod)) },
4387 32 => {4300 128 => .{ .f128 = @cos(val.toFloat(f128, mod)) },
4388 const f = val.toFloat(f32, mod);
4389 return Value.Tag.float_32.create(arena, @cos(f));
4390 },
4391 64 => {
4392 const f = val.toFloat(f64, mod);
4393 return Value.Tag.float_64.create(arena, @cos(f));
4394 },
4395 80 => {
4396 const f = val.toFloat(f80, mod);
4397 return Value.Tag.float_80.create(arena, @cos(f));
4398 },
4399 128 => {
4400 const f = val.toFloat(f128, mod);
4401 return Value.Tag.float_128.create(arena, @cos(f));
4402 },
4403 else => unreachable,4301 else => unreachable,
4404 }4302 };
4303 return (try mod.intern(.{ .float = .{
4304 .ty = float_type.ip_index,
4305 .storage = storage,
4306 } })).toValue();
4405 }4307 }
44064308
4407 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4309 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4409,38 +4311,27 @@ pub const Value = struct {...@@ -4409,38 +4311,27 @@ pub const Value = struct {
4409 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4311 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4410 for (result_data, 0..) |*scalar, i| {4312 for (result_data, 0..) |*scalar, i| {
4411 const elem_val = try val.elemValue(mod, i);4313 const elem_val = try val.elemValue(mod, i);
4412 scalar.* = try tanScalar(elem_val, float_type.scalarType(mod), arena, mod);4314 scalar.* = try tanScalar(elem_val, float_type.scalarType(mod), mod);
4413 }4315 }
4414 return Value.Tag.aggregate.create(arena, result_data);4316 return Value.Tag.aggregate.create(arena, result_data);
4415 }4317 }
4416 return tanScalar(val, float_type, arena, mod);4318 return tanScalar(val, float_type, mod);
4417 }4319 }
44184320
4419 pub fn tanScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4321 pub fn tanScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4420 const target = mod.getTarget();4322 const target = mod.getTarget();
4421 switch (float_type.floatBits(target)) {4323 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4422 16 => {4324 16 => .{ .f16 = @tan(val.toFloat(f16, mod)) },
4423 const f = val.toFloat(f16, mod);4325 32 => .{ .f32 = @tan(val.toFloat(f32, mod)) },
4424 return Value.Tag.float_16.create(arena, @tan(f));4326 64 => .{ .f64 = @tan(val.toFloat(f64, mod)) },
4425 },4327 80 => .{ .f80 = @tan(val.toFloat(f80, mod)) },
4426 32 => {4328 128 => .{ .f128 = @tan(val.toFloat(f128, mod)) },
4427 const f = val.toFloat(f32, mod);
4428 return Value.Tag.float_32.create(arena, @tan(f));
4429 },
4430 64 => {
4431 const f = val.toFloat(f64, mod);
4432 return Value.Tag.float_64.create(arena, @tan(f));
4433 },
4434 80 => {
4435 const f = val.toFloat(f80, mod);
4436 return Value.Tag.float_80.create(arena, @tan(f));
4437 },
4438 128 => {
4439 const f = val.toFloat(f128, mod);
4440 return Value.Tag.float_128.create(arena, @tan(f));
4441 },
4442 else => unreachable,4329 else => unreachable,
4443 }4330 };
4331 return (try mod.intern(.{ .float = .{
4332 .ty = float_type.ip_index,
4333 .storage = storage,
4334 } })).toValue();
4444 }4335 }
44454336
4446 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4337 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4448,38 +4339,27 @@ pub const Value = struct {...@@ -4448,38 +4339,27 @@ pub const Value = struct {
4448 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4339 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4449 for (result_data, 0..) |*scalar, i| {4340 for (result_data, 0..) |*scalar, i| {
4450 const elem_val = try val.elemValue(mod, i);4341 const elem_val = try val.elemValue(mod, i);
4451 scalar.* = try expScalar(elem_val, float_type.scalarType(mod), arena, mod);4342 scalar.* = try expScalar(elem_val, float_type.scalarType(mod), mod);
4452 }4343 }
4453 return Value.Tag.aggregate.create(arena, result_data);4344 return Value.Tag.aggregate.create(arena, result_data);
4454 }4345 }
4455 return expScalar(val, float_type, arena, mod);4346 return expScalar(val, float_type, mod);
4456 }4347 }
44574348
4458 pub fn expScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4349 pub fn expScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4459 const target = mod.getTarget();4350 const target = mod.getTarget();
4460 switch (float_type.floatBits(target)) {4351 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4461 16 => {4352 16 => .{ .f16 = @exp(val.toFloat(f16, mod)) },
4462 const f = val.toFloat(f16, mod);4353 32 => .{ .f32 = @exp(val.toFloat(f32, mod)) },
4463 return Value.Tag.float_16.create(arena, @exp(f));4354 64 => .{ .f64 = @exp(val.toFloat(f64, mod)) },
4464 },4355 80 => .{ .f80 = @exp(val.toFloat(f80, mod)) },
4465 32 => {4356 128 => .{ .f128 = @exp(val.toFloat(f128, mod)) },
4466 const f = val.toFloat(f32, mod);
4467 return Value.Tag.float_32.create(arena, @exp(f));
4468 },
4469 64 => {
4470 const f = val.toFloat(f64, mod);
4471 return Value.Tag.float_64.create(arena, @exp(f));
4472 },
4473 80 => {
4474 const f = val.toFloat(f80, mod);
4475 return Value.Tag.float_80.create(arena, @exp(f));
4476 },
4477 128 => {
4478 const f = val.toFloat(f128, mod);
4479 return Value.Tag.float_128.create(arena, @exp(f));
4480 },
4481 else => unreachable,4357 else => unreachable,
4482 }4358 };
4359 return (try mod.intern(.{ .float = .{
4360 .ty = float_type.ip_index,
4361 .storage = storage,
4362 } })).toValue();
4483 }4363 }
44844364
4485 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4365 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4487,38 +4367,27 @@ pub const Value = struct {...@@ -4487,38 +4367,27 @@ pub const Value = struct {
4487 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4367 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4488 for (result_data, 0..) |*scalar, i| {4368 for (result_data, 0..) |*scalar, i| {
4489 const elem_val = try val.elemValue(mod, i);4369 const elem_val = try val.elemValue(mod, i);
4490 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(mod), arena, mod);4370 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(mod), mod);
4491 }4371 }
4492 return Value.Tag.aggregate.create(arena, result_data);4372 return Value.Tag.aggregate.create(arena, result_data);
4493 }4373 }
4494 return exp2Scalar(val, float_type, arena, mod);4374 return exp2Scalar(val, float_type, mod);
4495 }4375 }
44964376
4497 pub fn exp2Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4377 pub fn exp2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4498 const target = mod.getTarget();4378 const target = mod.getTarget();
4499 switch (float_type.floatBits(target)) {4379 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4500 16 => {4380 16 => .{ .f16 = @exp2(val.toFloat(f16, mod)) },
4501 const f = val.toFloat(f16, mod);4381 32 => .{ .f32 = @exp2(val.toFloat(f32, mod)) },
4502 return Value.Tag.float_16.create(arena, @exp2(f));4382 64 => .{ .f64 = @exp2(val.toFloat(f64, mod)) },
4503 },4383 80 => .{ .f80 = @exp2(val.toFloat(f80, mod)) },
4504 32 => {4384 128 => .{ .f128 = @exp2(val.toFloat(f128, mod)) },
4505 const f = val.toFloat(f32, mod);
4506 return Value.Tag.float_32.create(arena, @exp2(f));
4507 },
4508 64 => {
4509 const f = val.toFloat(f64, mod);
4510 return Value.Tag.float_64.create(arena, @exp2(f));
4511 },
4512 80 => {
4513 const f = val.toFloat(f80, mod);
4514 return Value.Tag.float_80.create(arena, @exp2(f));
4515 },
4516 128 => {
4517 const f = val.toFloat(f128, mod);
4518 return Value.Tag.float_128.create(arena, @exp2(f));
4519 },
4520 else => unreachable,4385 else => unreachable,
4521 }4386 };
4387 return (try mod.intern(.{ .float = .{
4388 .ty = float_type.ip_index,
4389 .storage = storage,
4390 } })).toValue();
4522 }4391 }
45234392
4524 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4393 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4526,38 +4395,27 @@ pub const Value = struct {...@@ -4526,38 +4395,27 @@ pub const Value = struct {
4526 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4395 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4527 for (result_data, 0..) |*scalar, i| {4396 for (result_data, 0..) |*scalar, i| {
4528 const elem_val = try val.elemValue(mod, i);4397 const elem_val = try val.elemValue(mod, i);
4529 scalar.* = try logScalar(elem_val, float_type.scalarType(mod), arena, mod);4398 scalar.* = try logScalar(elem_val, float_type.scalarType(mod), mod);
4530 }4399 }
4531 return Value.Tag.aggregate.create(arena, result_data);4400 return Value.Tag.aggregate.create(arena, result_data);
4532 }4401 }
4533 return logScalar(val, float_type, arena, mod);4402 return logScalar(val, float_type, mod);
4534 }4403 }
45354404
4536 pub fn logScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4405 pub fn logScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4537 const target = mod.getTarget();4406 const target = mod.getTarget();
4538 switch (float_type.floatBits(target)) {4407 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4539 16 => {4408 16 => .{ .f16 = @log(val.toFloat(f16, mod)) },
4540 const f = val.toFloat(f16, mod);4409 32 => .{ .f32 = @log(val.toFloat(f32, mod)) },
4541 return Value.Tag.float_16.create(arena, @log(f));4410 64 => .{ .f64 = @log(val.toFloat(f64, mod)) },
4542 },4411 80 => .{ .f80 = @log(val.toFloat(f80, mod)) },
4543 32 => {4412 128 => .{ .f128 = @log(val.toFloat(f128, mod)) },
4544 const f = val.toFloat(f32, mod);
4545 return Value.Tag.float_32.create(arena, @log(f));
4546 },
4547 64 => {
4548 const f = val.toFloat(f64, mod);
4549 return Value.Tag.float_64.create(arena, @log(f));
4550 },
4551 80 => {
4552 const f = val.toFloat(f80, mod);
4553 return Value.Tag.float_80.create(arena, @log(f));
4554 },
4555 128 => {
4556 const f = val.toFloat(f128, mod);
4557 return Value.Tag.float_128.create(arena, @log(f));
4558 },
4559 else => unreachable,4413 else => unreachable,
4560 }4414 };
4415 return (try mod.intern(.{ .float = .{
4416 .ty = float_type.ip_index,
4417 .storage = storage,
4418 } })).toValue();
4561 }4419 }
45624420
4563 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4421 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4565,38 +4423,27 @@ pub const Value = struct {...@@ -4565,38 +4423,27 @@ pub const Value = struct {
4565 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4423 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4566 for (result_data, 0..) |*scalar, i| {4424 for (result_data, 0..) |*scalar, i| {
4567 const elem_val = try val.elemValue(mod, i);4425 const elem_val = try val.elemValue(mod, i);
4568 scalar.* = try log2Scalar(elem_val, float_type.scalarType(mod), arena, mod);4426 scalar.* = try log2Scalar(elem_val, float_type.scalarType(mod), mod);
4569 }4427 }
4570 return Value.Tag.aggregate.create(arena, result_data);4428 return Value.Tag.aggregate.create(arena, result_data);
4571 }4429 }
4572 return log2Scalar(val, float_type, arena, mod);4430 return log2Scalar(val, float_type, mod);
4573 }4431 }
45744432
4575 pub fn log2Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4433 pub fn log2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4576 const target = mod.getTarget();4434 const target = mod.getTarget();
4577 switch (float_type.floatBits(target)) {4435 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4578 16 => {4436 16 => .{ .f16 = @log2(val.toFloat(f16, mod)) },
4579 const f = val.toFloat(f16, mod);4437 32 => .{ .f32 = @log2(val.toFloat(f32, mod)) },
4580 return Value.Tag.float_16.create(arena, @log2(f));4438 64 => .{ .f64 = @log2(val.toFloat(f64, mod)) },
4581 },4439 80 => .{ .f80 = @log2(val.toFloat(f80, mod)) },
4582 32 => {4440 128 => .{ .f128 = @log2(val.toFloat(f128, mod)) },
4583 const f = val.toFloat(f32, mod);
4584 return Value.Tag.float_32.create(arena, @log2(f));
4585 },
4586 64 => {
4587 const f = val.toFloat(f64, mod);
4588 return Value.Tag.float_64.create(arena, @log2(f));
4589 },
4590 80 => {
4591 const f = val.toFloat(f80, mod);
4592 return Value.Tag.float_80.create(arena, @log2(f));
4593 },
4594 128 => {
4595 const f = val.toFloat(f128, mod);
4596 return Value.Tag.float_128.create(arena, @log2(f));
4597 },
4598 else => unreachable,4441 else => unreachable,
4599 }4442 };
4443 return (try mod.intern(.{ .float = .{
4444 .ty = float_type.ip_index,
4445 .storage = storage,
4446 } })).toValue();
4600 }4447 }
46014448
4602 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4449 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4604,38 +4451,27 @@ pub const Value = struct {...@@ -4604,38 +4451,27 @@ pub const Value = struct {
4604 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4451 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4605 for (result_data, 0..) |*scalar, i| {4452 for (result_data, 0..) |*scalar, i| {
4606 const elem_val = try val.elemValue(mod, i);4453 const elem_val = try val.elemValue(mod, i);
4607 scalar.* = try log10Scalar(elem_val, float_type.scalarType(mod), arena, mod);4454 scalar.* = try log10Scalar(elem_val, float_type.scalarType(mod), mod);
4608 }4455 }
4609 return Value.Tag.aggregate.create(arena, result_data);4456 return Value.Tag.aggregate.create(arena, result_data);
4610 }4457 }
4611 return log10Scalar(val, float_type, arena, mod);4458 return log10Scalar(val, float_type, mod);
4612 }4459 }
46134460
4614 pub fn log10Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4461 pub fn log10Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4615 const target = mod.getTarget();4462 const target = mod.getTarget();
4616 switch (float_type.floatBits(target)) {4463 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4617 16 => {4464 16 => .{ .f16 = @log10(val.toFloat(f16, mod)) },
4618 const f = val.toFloat(f16, mod);4465 32 => .{ .f32 = @log10(val.toFloat(f32, mod)) },
4619 return Value.Tag.float_16.create(arena, @log10(f));4466 64 => .{ .f64 = @log10(val.toFloat(f64, mod)) },
4620 },4467 80 => .{ .f80 = @log10(val.toFloat(f80, mod)) },
4621 32 => {4468 128 => .{ .f128 = @log10(val.toFloat(f128, mod)) },
4622 const f = val.toFloat(f32, mod);
4623 return Value.Tag.float_32.create(arena, @log10(f));
4624 },
4625 64 => {
4626 const f = val.toFloat(f64, mod);
4627 return Value.Tag.float_64.create(arena, @log10(f));
4628 },
4629 80 => {
4630 const f = val.toFloat(f80, mod);
4631 return Value.Tag.float_80.create(arena, @log10(f));
4632 },
4633 128 => {
4634 const f = val.toFloat(f128, mod);
4635 return Value.Tag.float_128.create(arena, @log10(f));
4636 },
4637 else => unreachable,4469 else => unreachable,
4638 }4470 };
4471 return (try mod.intern(.{ .float = .{
4472 .ty = float_type.ip_index,
4473 .storage = storage,
4474 } })).toValue();
4639 }4475 }
46404476
4641 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4477 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4643,38 +4479,27 @@ pub const Value = struct {...@@ -4643,38 +4479,27 @@ pub const Value = struct {
4643 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4479 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4644 for (result_data, 0..) |*scalar, i| {4480 for (result_data, 0..) |*scalar, i| {
4645 const elem_val = try val.elemValue(mod, i);4481 const elem_val = try val.elemValue(mod, i);
4646 scalar.* = try fabsScalar(elem_val, float_type.scalarType(mod), arena, mod);4482 scalar.* = try fabsScalar(elem_val, float_type.scalarType(mod), mod);
4647 }4483 }
4648 return Value.Tag.aggregate.create(arena, result_data);4484 return Value.Tag.aggregate.create(arena, result_data);
4649 }4485 }
4650 return fabsScalar(val, float_type, arena, mod);4486 return fabsScalar(val, float_type, mod);
4651 }4487 }
46524488
4653 pub fn fabsScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4489 pub fn fabsScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4654 const target = mod.getTarget();4490 const target = mod.getTarget();
4655 switch (float_type.floatBits(target)) {4491 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4656 16 => {4492 16 => .{ .f16 = @fabs(val.toFloat(f16, mod)) },
4657 const f = val.toFloat(f16, mod);4493 32 => .{ .f32 = @fabs(val.toFloat(f32, mod)) },
4658 return Value.Tag.float_16.create(arena, @fabs(f));4494 64 => .{ .f64 = @fabs(val.toFloat(f64, mod)) },
4659 },4495 80 => .{ .f80 = @fabs(val.toFloat(f80, mod)) },
4660 32 => {4496 128 => .{ .f128 = @fabs(val.toFloat(f128, mod)) },
4661 const f = val.toFloat(f32, mod);
4662 return Value.Tag.float_32.create(arena, @fabs(f));
4663 },
4664 64 => {
4665 const f = val.toFloat(f64, mod);
4666 return Value.Tag.float_64.create(arena, @fabs(f));
4667 },
4668 80 => {
4669 const f = val.toFloat(f80, mod);
4670 return Value.Tag.float_80.create(arena, @fabs(f));
4671 },
4672 128 => {
4673 const f = val.toFloat(f128, mod);
4674 return Value.Tag.float_128.create(arena, @fabs(f));
4675 },
4676 else => unreachable,4497 else => unreachable,
4677 }4498 };
4499 return (try mod.intern(.{ .float = .{
4500 .ty = float_type.ip_index,
4501 .storage = storage,
4502 } })).toValue();
4678 }4503 }
46794504
4680 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4505 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4682,38 +4507,27 @@ pub const Value = struct {...@@ -4682,38 +4507,27 @@ pub const Value = struct {
4682 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4507 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4683 for (result_data, 0..) |*scalar, i| {4508 for (result_data, 0..) |*scalar, i| {
4684 const elem_val = try val.elemValue(mod, i);4509 const elem_val = try val.elemValue(mod, i);
4685 scalar.* = try floorScalar(elem_val, float_type.scalarType(mod), arena, mod);4510 scalar.* = try floorScalar(elem_val, float_type.scalarType(mod), mod);
4686 }4511 }
4687 return Value.Tag.aggregate.create(arena, result_data);4512 return Value.Tag.aggregate.create(arena, result_data);
4688 }4513 }
4689 return floorScalar(val, float_type, arena, mod);4514 return floorScalar(val, float_type, mod);
4690 }4515 }
46914516
4692 pub fn floorScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4517 pub fn floorScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4693 const target = mod.getTarget();4518 const target = mod.getTarget();
4694 switch (float_type.floatBits(target)) {4519 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4695 16 => {4520 16 => .{ .f16 = @floor(val.toFloat(f16, mod)) },
4696 const f = val.toFloat(f16, mod);4521 32 => .{ .f32 = @floor(val.toFloat(f32, mod)) },
4697 return Value.Tag.float_16.create(arena, @floor(f));4522 64 => .{ .f64 = @floor(val.toFloat(f64, mod)) },
4698 },4523 80 => .{ .f80 = @floor(val.toFloat(f80, mod)) },
4699 32 => {4524 128 => .{ .f128 = @floor(val.toFloat(f128, mod)) },
4700 const f = val.toFloat(f32, mod);
4701 return Value.Tag.float_32.create(arena, @floor(f));
4702 },
4703 64 => {
4704 const f = val.toFloat(f64, mod);
4705 return Value.Tag.float_64.create(arena, @floor(f));
4706 },
4707 80 => {
4708 const f = val.toFloat(f80, mod);
4709 return Value.Tag.float_80.create(arena, @floor(f));
4710 },
4711 128 => {
4712 const f = val.toFloat(f128, mod);
4713 return Value.Tag.float_128.create(arena, @floor(f));
4714 },
4715 else => unreachable,4525 else => unreachable,
4716 }4526 };
4527 return (try mod.intern(.{ .float = .{
4528 .ty = float_type.ip_index,
4529 .storage = storage,
4530 } })).toValue();
4717 }4531 }
47184532
4719 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4533 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4721,38 +4535,27 @@ pub const Value = struct {...@@ -4721,38 +4535,27 @@ pub const Value = struct {
4721 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4535 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4722 for (result_data, 0..) |*scalar, i| {4536 for (result_data, 0..) |*scalar, i| {
4723 const elem_val = try val.elemValue(mod, i);4537 const elem_val = try val.elemValue(mod, i);
4724 scalar.* = try ceilScalar(elem_val, float_type.scalarType(mod), arena, mod);4538 scalar.* = try ceilScalar(elem_val, float_type.scalarType(mod), mod);
4725 }4539 }
4726 return Value.Tag.aggregate.create(arena, result_data);4540 return Value.Tag.aggregate.create(arena, result_data);
4727 }4541 }
4728 return ceilScalar(val, float_type, arena, mod);4542 return ceilScalar(val, float_type, mod);
4729 }4543 }
47304544
4731 pub fn ceilScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4545 pub fn ceilScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4732 const target = mod.getTarget();4546 const target = mod.getTarget();
4733 switch (float_type.floatBits(target)) {4547 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4734 16 => {4548 16 => .{ .f16 = @ceil(val.toFloat(f16, mod)) },
4735 const f = val.toFloat(f16, mod);4549 32 => .{ .f32 = @ceil(val.toFloat(f32, mod)) },
4736 return Value.Tag.float_16.create(arena, @ceil(f));4550 64 => .{ .f64 = @ceil(val.toFloat(f64, mod)) },
4737 },4551 80 => .{ .f80 = @ceil(val.toFloat(f80, mod)) },
4738 32 => {4552 128 => .{ .f128 = @ceil(val.toFloat(f128, mod)) },
4739 const f = val.toFloat(f32, mod);
4740 return Value.Tag.float_32.create(arena, @ceil(f));
4741 },
4742 64 => {
4743 const f = val.toFloat(f64, mod);
4744 return Value.Tag.float_64.create(arena, @ceil(f));
4745 },
4746 80 => {
4747 const f = val.toFloat(f80, mod);
4748 return Value.Tag.float_80.create(arena, @ceil(f));
4749 },
4750 128 => {
4751 const f = val.toFloat(f128, mod);
4752 return Value.Tag.float_128.create(arena, @ceil(f));
4753 },
4754 else => unreachable,4553 else => unreachable,
4755 }4554 };
4555 return (try mod.intern(.{ .float = .{
4556 .ty = float_type.ip_index,
4557 .storage = storage,
4558 } })).toValue();
4756 }4559 }
47574560
4758 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4561 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4760,38 +4563,27 @@ pub const Value = struct {...@@ -4760,38 +4563,27 @@ pub const Value = struct {
4760 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4563 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4761 for (result_data, 0..) |*scalar, i| {4564 for (result_data, 0..) |*scalar, i| {
4762 const elem_val = try val.elemValue(mod, i);4565 const elem_val = try val.elemValue(mod, i);
4763 scalar.* = try roundScalar(elem_val, float_type.scalarType(mod), arena, mod);4566 scalar.* = try roundScalar(elem_val, float_type.scalarType(mod), mod);
4764 }4567 }
4765 return Value.Tag.aggregate.create(arena, result_data);4568 return Value.Tag.aggregate.create(arena, result_data);
4766 }4569 }
4767 return roundScalar(val, float_type, arena, mod);4570 return roundScalar(val, float_type, mod);
4768 }4571 }
47694572
4770 pub fn roundScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4573 pub fn roundScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4771 const target = mod.getTarget();4574 const target = mod.getTarget();
4772 switch (float_type.floatBits(target)) {4575 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4773 16 => {4576 16 => .{ .f16 = @round(val.toFloat(f16, mod)) },
4774 const f = val.toFloat(f16, mod);4577 32 => .{ .f32 = @round(val.toFloat(f32, mod)) },
4775 return Value.Tag.float_16.create(arena, @round(f));4578 64 => .{ .f64 = @round(val.toFloat(f64, mod)) },
4776 },4579 80 => .{ .f80 = @round(val.toFloat(f80, mod)) },
4777 32 => {4580 128 => .{ .f128 = @round(val.toFloat(f128, mod)) },
4778 const f = val.toFloat(f32, mod);
4779 return Value.Tag.float_32.create(arena, @round(f));
4780 },
4781 64 => {
4782 const f = val.toFloat(f64, mod);
4783 return Value.Tag.float_64.create(arena, @round(f));
4784 },
4785 80 => {
4786 const f = val.toFloat(f80, mod);
4787 return Value.Tag.float_80.create(arena, @round(f));
4788 },
4789 128 => {
4790 const f = val.toFloat(f128, mod);
4791 return Value.Tag.float_128.create(arena, @round(f));
4792 },
4793 else => unreachable,4581 else => unreachable,
4794 }4582 };
4583 return (try mod.intern(.{ .float = .{
4584 .ty = float_type.ip_index,
4585 .storage = storage,
4586 } })).toValue();
4795 }4587 }
47964588
4797 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4589 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
...@@ -4799,38 +4591,27 @@ pub const Value = struct {...@@ -4799,38 +4591,27 @@ pub const Value = struct {
4799 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4591 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4800 for (result_data, 0..) |*scalar, i| {4592 for (result_data, 0..) |*scalar, i| {
4801 const elem_val = try val.elemValue(mod, i);4593 const elem_val = try val.elemValue(mod, i);
4802 scalar.* = try truncScalar(elem_val, float_type.scalarType(mod), arena, mod);4594 scalar.* = try truncScalar(elem_val, float_type.scalarType(mod), mod);
4803 }4595 }
4804 return Value.Tag.aggregate.create(arena, result_data);4596 return Value.Tag.aggregate.create(arena, result_data);
4805 }4597 }
4806 return truncScalar(val, float_type, arena, mod);4598 return truncScalar(val, float_type, mod);
4807 }4599 }
48084600
4809 pub fn truncScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {4601 pub fn truncScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {
4810 const target = mod.getTarget();4602 const target = mod.getTarget();
4811 switch (float_type.floatBits(target)) {4603 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4812 16 => {4604 16 => .{ .f16 = @trunc(val.toFloat(f16, mod)) },
4813 const f = val.toFloat(f16, mod);4605 32 => .{ .f32 = @trunc(val.toFloat(f32, mod)) },
4814 return Value.Tag.float_16.create(arena, @trunc(f));4606 64 => .{ .f64 = @trunc(val.toFloat(f64, mod)) },
4815 },4607 80 => .{ .f80 = @trunc(val.toFloat(f80, mod)) },
4816 32 => {4608 128 => .{ .f128 = @trunc(val.toFloat(f128, mod)) },
4817 const f = val.toFloat(f32, mod);
4818 return Value.Tag.float_32.create(arena, @trunc(f));
4819 },
4820 64 => {
4821 const f = val.toFloat(f64, mod);
4822 return Value.Tag.float_64.create(arena, @trunc(f));
4823 },
4824 80 => {
4825 const f = val.toFloat(f80, mod);
4826 return Value.Tag.float_80.create(arena, @trunc(f));
4827 },
4828 128 => {
4829 const f = val.toFloat(f128, mod);
4830 return Value.Tag.float_128.create(arena, @trunc(f));
4831 },
4832 else => unreachable,4609 else => unreachable,
4833 }4610 };
4611 return (try mod.intern(.{ .float = .{
4612 .ty = float_type.ip_index,
4613 .storage = storage,
4614 } })).toValue();
4834 }4615 }
48354616
4836 pub fn mulAdd(4617 pub fn mulAdd(
...@@ -4852,13 +4633,12 @@ pub const Value = struct {...@@ -4852,13 +4633,12 @@ pub const Value = struct {
4852 mulend1_elem,4633 mulend1_elem,
4853 mulend2_elem,4634 mulend2_elem,
4854 addend_elem,4635 addend_elem,
4855 arena,
4856 mod,4636 mod,
4857 );4637 );
4858 }4638 }
4859 return Value.Tag.aggregate.create(arena, result_data);4639 return Value.Tag.aggregate.create(arena, result_data);
4860 }4640 }
4861 return mulAddScalar(float_type, mulend1, mulend2, addend, arena, mod);4641 return mulAddScalar(float_type, mulend1, mulend2, addend, mod);
4862 }4642 }
48634643
4864 pub fn mulAddScalar(4644 pub fn mulAddScalar(
...@@ -4866,43 +4646,21 @@ pub const Value = struct {...@@ -4866,43 +4646,21 @@ pub const Value = struct {
4866 mulend1: Value,4646 mulend1: Value,
4867 mulend2: Value,4647 mulend2: Value,
4868 addend: Value,4648 addend: Value,
4869 arena: Allocator,4649 mod: *Module,
4870 mod: *const Module,
4871 ) Allocator.Error!Value {4650 ) Allocator.Error!Value {
4872 const target = mod.getTarget();4651 const target = mod.getTarget();
4873 switch (float_type.floatBits(target)) {4652 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
4874 16 => {4653 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, mod), mulend2.toFloat(f16, mod), addend.toFloat(f16, mod)) },
4875 const m1 = mulend1.toFloat(f16, mod);4654 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, mod), mulend2.toFloat(f32, mod), addend.toFloat(f32, mod)) },
4876 const m2 = mulend2.toFloat(f16, mod);4655 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, mod), mulend2.toFloat(f64, mod), addend.toFloat(f64, mod)) },
4877 const a = addend.toFloat(f16, mod);4656 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, mod), mulend2.toFloat(f80, mod), addend.toFloat(f80, mod)) },
4878 return Value.Tag.float_16.create(arena, @mulAdd(f16, m1, m2, a));4657 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, mod), mulend2.toFloat(f128, mod), addend.toFloat(f128, mod)) },
4879 },
4880 32 => {
4881 const m1 = mulend1.toFloat(f32, mod);
4882 const m2 = mulend2.toFloat(f32, mod);
4883 const a = addend.toFloat(f32, mod);
4884 return Value.Tag.float_32.create(arena, @mulAdd(f32, m1, m2, a));
4885 },
4886 64 => {
4887 const m1 = mulend1.toFloat(f64, mod);
4888 const m2 = mulend2.toFloat(f64, mod);
4889 const a = addend.toFloat(f64, mod);
4890 return Value.Tag.float_64.create(arena, @mulAdd(f64, m1, m2, a));
4891 },
4892 80 => {
4893 const m1 = mulend1.toFloat(f80, mod);
4894 const m2 = mulend2.toFloat(f80, mod);
4895 const a = addend.toFloat(f80, mod);
4896 return Value.Tag.float_80.create(arena, @mulAdd(f80, m1, m2, a));
4897 },
4898 128 => {
4899 const m1 = mulend1.toFloat(f128, mod);
4900 const m2 = mulend2.toFloat(f128, mod);
4901 const a = addend.toFloat(f128, mod);
4902 return Value.Tag.float_128.create(arena, @mulAdd(f128, m1, m2, a));
4903 },
4904 else => unreachable,4658 else => unreachable,
4905 }4659 };
4660 return (try mod.intern(.{ .float = .{
4661 .ty = float_type.ip_index,
4662 .storage = storage,
4663 } })).toValue();
4906 }4664 }
49074665
4908 /// If the value is represented in-memory as a series of bytes that all4666 /// If the value is represented in-memory as a series of bytes that all
...@@ -5053,41 +4811,6 @@ pub const Value = struct {...@@ -5053,41 +4811,6 @@ pub const Value = struct {
5053 data: Type,4811 data: Type,
5054 };4812 };
50554813
5056 pub const Float_16 = struct {
5057 pub const base_tag = Tag.float_16;
5058
5059 base: Payload = .{ .tag = base_tag },
5060 data: f16,
5061 };
5062
5063 pub const Float_32 = struct {
5064 pub const base_tag = Tag.float_32;
5065
5066 base: Payload = .{ .tag = base_tag },
5067 data: f32,
5068 };
5069
5070 pub const Float_64 = struct {
5071 pub const base_tag = Tag.float_64;
5072
5073 base: Payload = .{ .tag = base_tag },
5074 data: f64,
5075 };
5076
5077 pub const Float_80 = struct {
5078 pub const base_tag = Tag.float_80;
5079
5080 base: Payload = .{ .tag = base_tag },
5081 data: f80,
5082 };
5083
5084 pub const Float_128 = struct {
5085 pub const base_tag = Tag.float_128;
5086
5087 base: Payload = .{ .tag = base_tag },
5088 data: f128,
5089 };
5090
5091 pub const Error = struct {4814 pub const Error = struct {
5092 base: Payload = .{ .tag = .@"error" },4815 base: Payload = .{ .tag = .@"error" },
5093 data: struct {4816 data: struct {
...@@ -5152,7 +4875,6 @@ pub const Value = struct {...@@ -5152,7 +4875,6 @@ pub const Value = struct {
5152 pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined };4875 pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined };
5153 pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined };4876 pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined };
5154 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };4877 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };
5155 pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this!
5156 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };4878 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
5157 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };4879 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };
5158 pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };4880 pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };