| ... | @@ -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 { |
| 1346 | | 1332 | |
| 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 | } |
| 1356 | | 1342 | 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 | } |
| 1373 | | 1351 | |
| ... | @@ -1552,28 +1530,27 @@ pub const Value = struct { | ... | @@ -1552,28 +1530,27 @@ pub const Value = struct { |
| 1552 | | 1530 | |
| 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 | } |
| 1566 | | 1547 | |
| 1567 | /// Asserts the value is a float | 1548 | /// 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 | }, |
| 1636 | | 1613 | |
| 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 | } |
| 1690 | | 1664 | |
| 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 | } |
| 1819 | | 1794 | |
| ... | @@ -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 | } |
| 2920 | | 2895 | |
| 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 | } |
| 2940 | | 2911 | |
| ... | @@ -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 | } |
| 2960 | | 2931 | |
| 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, u0 | 2936 | .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 | } |
| 2997 | | 2967 | |
| 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 | } |
| 3019 | | 2983 | |
| 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; |
| 3291 | | 3255 | |
| 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; |
| 3303 | | 3267 | |
| 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 | } |
| 3588 | | 3552 | |
| 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 | } |
| 3603 | | 3563 | |
| 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 | } |
| 3618 | | 3574 | |
| 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 | } |
| 3645 | | 3597 | |
| 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 | } |
| 3677 | | 3613 | |
| 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 | } |
| 3690 | | 3626 | |
| 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 | } |
| 3722 | | 3642 | |
| 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 | } |
| 4044 | | 3964 | |
| 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 | } |
| 4061 | | 4064 | |
| 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 | } |
| 4080 | | 4083 | |
| 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 | } |
| 4118 | | 4104 | |
| 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 | } |
| 4137 | | 4123 | |
| 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 | } |
| 4175 | | 4144 | |
| 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 | } |
| 4194 | | 4163 | |
| 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 | } |
| 4232 | | 4184 | |
| 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 | } |
| 4251 | | 4203 | |
| 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 | } |
| 4289 | | 4224 | |
| 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 | } |
| 4301 | | 4236 | |
| 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 | } |
| 4328 | | 4252 | |
| 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 | } |
| 4340 | | 4264 | |
| 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 | } |
| 4367 | | 4280 | |
| 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 | } |
| 4379 | | 4292 | |
| 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 | } |
| 4406 | | 4308 | |
| 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 | } |
| 4418 | | 4320 | |
| 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 | } |
| 4445 | | 4336 | |
| 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 | } |
| 4457 | | 4348 | |
| 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 | } |
| 4484 | | 4364 | |
| 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 | } |
| 4496 | | 4376 | |
| 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 | } |
| 4523 | | 4392 | |
| 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 | } |
| 4535 | | 4404 | |
| 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 | } |
| 4562 | | 4420 | |
| 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 | } |
| 4574 | | 4432 | |
| 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 | } |
| 4601 | | 4448 | |
| 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 | } |
| 4613 | | 4460 | |
| 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 | } |
| 4640 | | 4476 | |
| 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 | } |
| 4652 | | 4488 | |
| 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 | } |
| 4679 | | 4504 | |
| 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 | } |
| 4691 | | 4516 | |
| 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 | } |
| 4718 | | 4532 | |
| 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 | } |
| 4730 | | 4544 | |
| 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 | } |
| 4757 | | 4560 | |
| 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 | } |
| 4769 | | 4572 | |
| 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 | } |
| 4796 | | 4588 | |
| 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 | } |
| 4808 | | 4600 | |
| 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 | } |
| 4835 | | 4616 | |
| 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 | } |
| 4863 | | 4643 | |
| 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 | } |
| 4907 | | 4665 | |
| 4908 | /// If the value is represented in-memory as a series of bytes that all | 4666 | /// 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 | }; |
| 5055 | | 4813 | |
| 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 }; |