| ... | ... | @@ -72,11 +72,6 @@ pub const Value = struct { |
| 72 | 72 | empty_array_sentinel, |
| 73 | 73 | /// Pointer and length as sub `Value` objects. |
| 74 | 74 | slice, |
| 75 | | float_16, |
| 76 | | float_32, |
| 77 | | float_64, |
| 78 | | float_80, |
| 79 | | float_128, |
| 80 | 75 | enum_literal, |
| 81 | 76 | /// A specific enum tag, indicated by the field index (declaration order). |
| 82 | 77 | enum_field_index, |
| ... | ... | @@ -160,11 +155,6 @@ pub const Value = struct { |
| 160 | 155 | .decl_ref_mut => Payload.DeclRefMut, |
| 161 | 156 | .elem_ptr => Payload.ElemPtr, |
| 162 | 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 | 158 | .@"error" => Payload.Error, |
| 169 | 159 | .inferred_alloc => Payload.InferredAlloc, |
| 170 | 160 | .inferred_alloc_comptime => Payload.InferredAllocComptime, |
| ... | ... | @@ -395,11 +385,6 @@ pub const Value = struct { |
| 395 | 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 | 388 | .enum_literal => { |
| 404 | 389 | const payload = self.castTag(.enum_literal).?; |
| 405 | 390 | const new_payload = try arena.create(Payload.Bytes); |
| ... | ... | @@ -544,11 +529,6 @@ pub const Value = struct { |
| 544 | 529 | }, |
| 545 | 530 | .empty_array_sentinel => return out_stream.writeAll("(empty array with sentinel)"), |
| 546 | 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 | 532 | .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}), |
| 553 | 533 | .eu_payload => { |
| 554 | 534 | try out_stream.writeAll("(eu_payload) "); |
| ... | ... | @@ -1181,14 +1161,17 @@ pub const Value = struct { |
| 1181 | 1161 | return mod.intValue_big(ty, bigint.toConst()); |
| 1182 | 1162 | } |
| 1183 | 1163 | }, |
| 1184 | | .Float => switch (ty.floatBits(target)) { |
| 1185 | | 16 => return Value.Tag.float_16.create(arena, @bitCast(f16, std.mem.readInt(u16, buffer[0..2], endian))), |
| 1186 | | 32 => return Value.Tag.float_32.create(arena, @bitCast(f32, std.mem.readInt(u32, buffer[0..4], endian))), |
| 1187 | | 64 => return Value.Tag.float_64.create(arena, @bitCast(f64, std.mem.readInt(u64, buffer[0..8], endian))), |
| 1188 | | 80 => return Value.Tag.float_80.create(arena, @bitCast(f80, std.mem.readInt(u80, buffer[0..10], endian))), |
| 1189 | | 128 => return Value.Tag.float_128.create(arena, @bitCast(f128, std.mem.readInt(u128, buffer[0..16], endian))), |
| 1190 | | else => unreachable, |
| 1191 | | }, |
| 1164 | .Float => return (try mod.intern(.{ .float = .{ |
| 1165 | .ty = ty.ip_index, |
| 1166 | .storage = switch (ty.floatBits(target)) { |
| 1167 | 16 => .{ .f16 = @bitCast(f16, std.mem.readInt(u16, buffer[0..2], endian)) }, |
| 1168 | 32 => .{ .f32 = @bitCast(f32, std.mem.readInt(u32, buffer[0..4], endian)) }, |
| 1169 | 64 => .{ .f64 = @bitCast(f64, std.mem.readInt(u64, buffer[0..8], endian)) }, |
| 1170 | 80 => .{ .f80 = @bitCast(f80, std.mem.readInt(u80, buffer[0..10], endian)) }, |
| 1171 | 128 => .{ .f128 = @bitCast(f128, std.mem.readInt(u128, buffer[0..16], endian)) }, |
| 1172 | else => unreachable, |
| 1173 | }, |
| 1174 | } })).toValue(), |
| 1192 | 1175 | .Array => { |
| 1193 | 1176 | const elem_ty = ty.childType(mod); |
| 1194 | 1177 | const elem_size = elem_ty.abiSize(mod); |
| ... | ... | @@ -1294,14 +1277,17 @@ pub const Value = struct { |
| 1294 | 1277 | return mod.intValue_big(ty, bigint.toConst()); |
| 1295 | 1278 | } |
| 1296 | 1279 | }, |
| 1297 | | .Float => switch (ty.floatBits(target)) { |
| 1298 | | 16 => return Value.Tag.float_16.create(arena, @bitCast(f16, std.mem.readPackedInt(u16, buffer, bit_offset, endian))), |
| 1299 | | 32 => return Value.Tag.float_32.create(arena, @bitCast(f32, std.mem.readPackedInt(u32, buffer, bit_offset, endian))), |
| 1300 | | 64 => return Value.Tag.float_64.create(arena, @bitCast(f64, std.mem.readPackedInt(u64, buffer, bit_offset, endian))), |
| 1301 | | 80 => return Value.Tag.float_80.create(arena, @bitCast(f80, std.mem.readPackedInt(u80, buffer, bit_offset, endian))), |
| 1302 | | 128 => return Value.Tag.float_128.create(arena, @bitCast(f128, std.mem.readPackedInt(u128, buffer, bit_offset, endian))), |
| 1303 | | else => unreachable, |
| 1304 | | }, |
| 1280 | .Float => return (try mod.intern(.{ .float = .{ |
| 1281 | .ty = ty.ip_index, |
| 1282 | .storage = switch (ty.floatBits(target)) { |
| 1283 | 16 => .{ .f16 = @bitCast(f16, std.mem.readPackedInt(u16, buffer, bit_offset, endian)) }, |
| 1284 | 32 => .{ .f32 = @bitCast(f32, std.mem.readPackedInt(u32, buffer, bit_offset, endian)) }, |
| 1285 | 64 => .{ .f64 = @bitCast(f64, std.mem.readPackedInt(u64, buffer, bit_offset, endian)) }, |
| 1286 | 80 => .{ .f80 = @bitCast(f80, std.mem.readPackedInt(u80, buffer, bit_offset, endian)) }, |
| 1287 | 128 => .{ .f128 = @bitCast(f128, std.mem.readPackedInt(u128, buffer, bit_offset, endian)) }, |
| 1288 | else => unreachable, |
| 1289 | }, |
| 1290 | } })).toValue(), |
| 1305 | 1291 | .Vector => { |
| 1306 | 1292 | const elem_ty = ty.childType(mod); |
| 1307 | 1293 | const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen(mod))); |
| ... | ... | @@ -1346,28 +1332,20 @@ pub const Value = struct { |
| 1346 | 1332 | |
| 1347 | 1333 | /// Asserts that the value is a float or an integer. |
| 1348 | 1334 | pub fn toFloat(val: Value, comptime T: type, mod: *const Module) T { |
| 1349 | | return switch (val.ip_index) { |
| 1350 | | .none => switch (val.tag()) { |
| 1351 | | .float_16 => @floatCast(T, val.castTag(.float_16).?.data), |
| 1352 | | .float_32 => @floatCast(T, val.castTag(.float_32).?.data), |
| 1353 | | .float_64 => @floatCast(T, val.castTag(.float_64).?.data), |
| 1354 | | .float_80 => @floatCast(T, val.castTag(.float_80).?.data), |
| 1355 | | .float_128 => @floatCast(T, val.castTag(.float_128).?.data), |
| 1356 | | |
| 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 | | }, |
| 1335 | return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 1336 | .int => |int| switch (int.storage) { |
| 1337 | .big_int => |big_int| @floatCast(T, bigIntToFloat(big_int.limbs, big_int.positive)), |
| 1338 | inline .u64, .i64 => |x| { |
| 1339 | if (T == f80) { |
| 1340 | @panic("TODO we can't lower this properly on non-x86 llvm backend yet"); |
| 1341 | } |
| 1342 | return @intToFloat(T, x); |
| 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 | 1530 | |
| 1553 | 1531 | /// Converts an integer or a float to a float. May result in a loss of information. |
| 1554 | 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 | 1534 | const target = mod.getTarget(); |
| 1557 | | switch (dest_ty.floatBits(target)) { |
| 1558 | | 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16, mod)), |
| 1559 | | 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32, mod)), |
| 1560 | | 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64, mod)), |
| 1561 | | 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80, mod)), |
| 1562 | | 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128, mod)), |
| 1563 | | else => unreachable, |
| 1564 | | } |
| 1535 | return (try mod.intern(.{ .float = .{ |
| 1536 | .ty = dest_ty.ip_index, |
| 1537 | .storage = switch (dest_ty.floatBits(target)) { |
| 1538 | 16 => .{ .f16 = self.toFloat(f16, mod) }, |
| 1539 | 32 => .{ .f32 = self.toFloat(f32, mod) }, |
| 1540 | 64 => .{ .f64 = self.toFloat(f64, mod) }, |
| 1541 | 80 => .{ .f80 = self.toFloat(f80, mod) }, |
| 1542 | 128 => .{ .f128 = self.toFloat(f128, mod) }, |
| 1543 | else => unreachable, |
| 1544 | }, |
| 1545 | } })).toValue(); |
| 1565 | 1546 | } |
| 1566 | 1547 | |
| 1567 | 1548 | /// Asserts the value is a float |
| 1568 | | pub fn floatHasFraction(self: Value) bool { |
| 1569 | | return switch (self.tag()) { |
| 1570 | | .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0, |
| 1571 | | .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0, |
| 1572 | | .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0, |
| 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 | | |
| 1549 | pub fn floatHasFraction(self: Value, mod: *const Module) bool { |
| 1550 | return switch (mod.intern_pool.indexToKey(self.ip_index)) { |
| 1551 | .float => |float| switch (float.storage) { |
| 1552 | inline else => |x| @rem(x, 1) != 0, |
| 1553 | }, |
| 1577 | 1554 | else => unreachable, |
| 1578 | 1555 | }; |
| 1579 | 1556 | } |
| ... | ... | @@ -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 | 1614 | .elem_ptr => { |
| 1644 | 1615 | const elem_ptr = lhs.castTag(.elem_ptr).?.data; |
| 1645 | 1616 | switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) { |
| ... | ... | @@ -1662,6 +1633,9 @@ pub const Value = struct { |
| 1662 | 1633 | .big_int => |big_int| big_int.orderAgainstScalar(0), |
| 1663 | 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 | 1639 | else => unreachable, |
| 1666 | 1640 | }, |
| 1667 | 1641 | } |
| ... | ... | @@ -1688,20 +1662,21 @@ pub const Value = struct { |
| 1688 | 1662 | .gt => {}, |
| 1689 | 1663 | } |
| 1690 | 1664 | |
| 1691 | | const lhs_float = lhs.isFloat(); |
| 1692 | | const rhs_float = rhs.isFloat(); |
| 1665 | const lhs_float = lhs.isFloat(mod); |
| 1666 | const rhs_float = rhs.isFloat(mod); |
| 1693 | 1667 | if (lhs_float and rhs_float) { |
| 1694 | 1668 | const lhs_tag = lhs.tag(); |
| 1695 | 1669 | const rhs_tag = rhs.tag(); |
| 1696 | 1670 | if (lhs_tag == rhs_tag) { |
| 1697 | | return switch (lhs.tag()) { |
| 1698 | | .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data), |
| 1699 | | .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data), |
| 1700 | | .float_64 => return std.math.order(lhs.castTag(.float_64).?.data, rhs.castTag(.float_64).?.data), |
| 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, |
| 1671 | const lhs_storage = mod.intern_pool.indexToKey(lhs.ip_index).float.storage; |
| 1672 | const rhs_storage = mod.intern_pool.indexToKey(rhs.ip_index).float.storage; |
| 1673 | const lhs128: f128 = switch (lhs_storage) { |
| 1674 | inline else => |x| x, |
| 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 | 1682 | if (lhs_float or rhs_float) { |
| ... | ... | @@ -1808,12 +1783,12 @@ pub const Value = struct { |
| 1808 | 1783 | mod: *Module, |
| 1809 | 1784 | opt_sema: ?*Sema, |
| 1810 | 1785 | ) Module.CompileError!bool { |
| 1811 | | if (lhs.isInf()) { |
| 1786 | if (lhs.isInf(mod)) { |
| 1812 | 1787 | switch (op) { |
| 1813 | 1788 | .neq => return true, |
| 1814 | 1789 | .eq => return false, |
| 1815 | | .gt, .gte => return !lhs.isNegativeInf(), |
| 1816 | | .lt, .lte => return lhs.isNegativeInf(), |
| 1790 | .gt, .gte => return !lhs.isNegativeInf(mod), |
| 1791 | .lt, .lte => return lhs.isNegativeInf(mod), |
| 1817 | 1792 | } |
| 1818 | 1793 | } |
| 1819 | 1794 | |
| ... | ... | @@ -1841,14 +1816,14 @@ pub const Value = struct { |
| 1841 | 1816 | } |
| 1842 | 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 | 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 | 1828 | return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op); |
| 1854 | 1829 | } |
| ... | ... | @@ -2919,22 +2894,18 @@ pub const Value = struct { |
| 2919 | 2894 | } |
| 2920 | 2895 | |
| 2921 | 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 | 2898 | return switch (self.ip_index) { |
| 2924 | 2899 | .undef => unreachable, |
| 2925 | 2900 | .none => switch (self.tag()) { |
| 2926 | 2901 | .inferred_alloc => unreachable, |
| 2927 | 2902 | .inferred_alloc_comptime => unreachable, |
| 2928 | | |
| 2929 | | .float_16, |
| 2930 | | .float_32, |
| 2931 | | .float_64, |
| 2932 | | .float_80, |
| 2933 | | .float_128, |
| 2934 | | => true, |
| 2935 | 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 | 2922 | const scalar_ty = float_ty.scalarType(mod); |
| 2952 | 2923 | for (result_data, 0..) |*scalar, i| { |
| 2953 | 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 | 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 { |
| 2962 | | const target = mod.getTarget(); |
| 2932 | pub fn intToFloatScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value { |
| 2963 | 2933 | switch (val.ip_index) { |
| 2964 | 2934 | .undef => return val, |
| 2965 | 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 | 2937 | .lazy_align => { |
| 2968 | 2938 | const ty = val.castTag(.lazy_align).?.data; |
| 2969 | 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 | 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 | 2945 | .lazy_size => { |
| 2976 | 2946 | const ty = val.castTag(.lazy_size).?.data; |
| 2977 | 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 | 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 | 2953 | else => unreachable, |
| ... | ... | @@ -2986,35 +2956,29 @@ pub const Value = struct { |
| 2986 | 2956 | .int => |int| switch (int.storage) { |
| 2987 | 2957 | .big_int => |big_int| { |
| 2988 | 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 | 2963 | else => unreachable, |
| 2994 | 2964 | }, |
| 2995 | 2965 | } |
| 2996 | 2966 | } |
| 2997 | 2967 | |
| 2998 | | fn intToFloatInner(x: anytype, arena: Allocator, dest_ty: Type, target: Target) !Value { |
| 2999 | | switch (dest_ty.floatBits(target)) { |
| 3000 | | 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)), |
| 3001 | | 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)), |
| 3002 | | 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)), |
| 3003 | | 80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)), |
| 3004 | | 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)), |
| 3005 | | else => unreachable, |
| 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), |
| 2968 | fn intToFloatInner(x: anytype, dest_ty: Type, mod: *Module) !Value { |
| 2969 | const target = mod.getTarget(); |
| 2970 | const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) { |
| 2971 | 16 => .{ .f16 = @intToFloat(f16, x) }, |
| 2972 | 32 => .{ .f32 = @intToFloat(f32, x) }, |
| 2973 | 64 => .{ .f64 = @intToFloat(f64, x) }, |
| 2974 | 80 => .{ .f80 = @intToFloat(f80, x) }, |
| 2975 | 128 => .{ .f128 = @intToFloat(f128, x) }, |
| 3016 | 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 | 2984 | fn calcLimbLenFloat(scalar: anytype) usize { |
| ... | ... | @@ -3286,8 +3250,8 @@ pub const Value = struct { |
| 3286 | 3250 | /// Supports both floats and ints; handles undefined. |
| 3287 | 3251 | pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value { |
| 3288 | 3252 | if (lhs.isUndef() or rhs.isUndef()) return undef; |
| 3289 | | if (lhs.isNan()) return rhs; |
| 3290 | | if (rhs.isNan()) return lhs; |
| 3253 | if (lhs.isNan(mod)) return rhs; |
| 3254 | if (rhs.isNan(mod)) return lhs; |
| 3291 | 3255 | |
| 3292 | 3256 | return switch (order(lhs, rhs, mod)) { |
| 3293 | 3257 | .lt => rhs, |
| ... | ... | @@ -3298,8 +3262,8 @@ pub const Value = struct { |
| 3298 | 3262 | /// Supports both floats and ints; handles undefined. |
| 3299 | 3263 | pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value { |
| 3300 | 3264 | if (lhs.isUndef() or rhs.isUndef()) return undef; |
| 3301 | | if (lhs.isNan()) return rhs; |
| 3302 | | if (rhs.isNan()) return lhs; |
| 3265 | if (lhs.isNan(mod)) return rhs; |
| 3266 | if (rhs.isNan(mod)) return lhs; |
| 3303 | 3267 | |
| 3304 | 3268 | return switch (order(lhs, rhs, mod)) { |
| 3305 | 3269 | .lt => lhs, |
| ... | ... | @@ -3587,44 +3551,32 @@ pub const Value = struct { |
| 3587 | 3551 | } |
| 3588 | 3552 | |
| 3589 | 3553 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. |
| 3590 | | pub fn isNan(val: Value) bool { |
| 3591 | | return switch (val.ip_index) { |
| 3592 | | .none => switch (val.tag()) { |
| 3593 | | .float_16 => std.math.isNan(val.castTag(.float_16).?.data), |
| 3594 | | .float_32 => std.math.isNan(val.castTag(.float_32).?.data), |
| 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, |
| 3554 | pub fn isNan(val: Value, mod: *const Module) bool { |
| 3555 | if (val.ip_index == .none) return false; |
| 3556 | return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 3557 | .float => |float| switch (float.storage) { |
| 3558 | inline else => |x| std.math.isNan(x), |
| 3599 | 3559 | }, |
| 3600 | 3560 | else => false, |
| 3601 | 3561 | }; |
| 3602 | 3562 | } |
| 3603 | 3563 | |
| 3604 | 3564 | /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. |
| 3605 | | pub fn isInf(val: Value) bool { |
| 3606 | | return switch (val.ip_index) { |
| 3607 | | .none => switch (val.tag()) { |
| 3608 | | .float_16 => std.math.isInf(val.castTag(.float_16).?.data), |
| 3609 | | .float_32 => std.math.isInf(val.castTag(.float_32).?.data), |
| 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, |
| 3565 | pub fn isInf(val: Value, mod: *const Module) bool { |
| 3566 | if (val.ip_index == .none) return false; |
| 3567 | return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 3568 | .float => |float| switch (float.storage) { |
| 3569 | inline else => |x| std.math.isInf(x), |
| 3614 | 3570 | }, |
| 3615 | 3571 | else => false, |
| 3616 | 3572 | }; |
| 3617 | 3573 | } |
| 3618 | 3574 | |
| 3619 | | pub fn isNegativeInf(val: Value) bool { |
| 3620 | | return switch (val.ip_index) { |
| 3621 | | .none => switch (val.tag()) { |
| 3622 | | .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data), |
| 3623 | | .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data), |
| 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, |
| 3575 | pub fn isNegativeInf(val: Value, mod: *const Module) bool { |
| 3576 | if (val.ip_index == .none) return false; |
| 3577 | return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 3578 | .float => |float| switch (float.storage) { |
| 3579 | inline else => |x| std.math.isNegativeInf(x), |
| 3628 | 3580 | }, |
| 3629 | 3581 | else => false, |
| 3630 | 3582 | }; |
| ... | ... | @@ -3636,43 +3588,27 @@ pub const Value = struct { |
| 3636 | 3588 | for (result_data, 0..) |*scalar, i| { |
| 3637 | 3589 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3638 | 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 | 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 | 3599 | const target = mod.getTarget(); |
| 3648 | | switch (float_type.floatBits(target)) { |
| 3649 | | 16 => { |
| 3650 | | const lhs_val = lhs.toFloat(f16, mod); |
| 3651 | | const rhs_val = rhs.toFloat(f16, mod); |
| 3652 | | return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val)); |
| 3653 | | }, |
| 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 | | }, |
| 3600 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3601 | 16 => .{ .f16 = @rem(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, |
| 3602 | 32 => .{ .f32 = @rem(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, |
| 3603 | 64 => .{ .f64 = @rem(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, |
| 3604 | 80 => .{ .f80 = @rem(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, |
| 3605 | 128 => .{ .f128 = @rem(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, |
| 3674 | 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 | 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 | 3617 | for (result_data, 0..) |*scalar, i| { |
| 3682 | 3618 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3683 | 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 | 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 | 3628 | const target = mod.getTarget(); |
| 3693 | | switch (float_type.floatBits(target)) { |
| 3694 | | 16 => { |
| 3695 | | const lhs_val = lhs.toFloat(f16, mod); |
| 3696 | | const rhs_val = rhs.toFloat(f16, mod); |
| 3697 | | return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val)); |
| 3698 | | }, |
| 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 | | }, |
| 3629 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3630 | 16 => .{ .f16 = @mod(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, |
| 3631 | 32 => .{ .f32 = @mod(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, |
| 3632 | 64 => .{ .f64 = @mod(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, |
| 3633 | 80 => .{ .f80 = @mod(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, |
| 3634 | 128 => .{ .f128 = @mod(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, |
| 3719 | 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 | 3643 | pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4035,28 +3955,111 @@ pub const Value = struct { |
| 4035 | 3955 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4036 | 3956 | for (result_data, 0..) |*scalar, i| { |
| 4037 | 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 | 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 | 3965 | pub fn floatNegScalar( |
| 4046 | 3966 | val: Value, |
| 4047 | 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 | 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 | 4009 | ) !Value { |
| 4051 | 4010 | const target = mod.getTarget(); |
| 4052 | | switch (float_type.floatBits(target)) { |
| 4053 | | 16 => return Value.Tag.float_16.create(arena, -val.toFloat(f16, mod)), |
| 4054 | | 32 => return Value.Tag.float_32.create(arena, -val.toFloat(f32, mod)), |
| 4055 | | 64 => return Value.Tag.float_64.create(arena, -val.toFloat(f64, mod)), |
| 4056 | | 80 => return Value.Tag.float_80.create(arena, -val.toFloat(f80, mod)), |
| 4057 | | 128 => return Value.Tag.float_128.create(arena, -val.toFloat(f128, mod)), |
| 4011 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4012 | 16 => .{ .f16 = lhs.toFloat(f16, mod) + rhs.toFloat(f16, mod) }, |
| 4013 | 32 => .{ .f32 = lhs.toFloat(f32, mod) + rhs.toFloat(f32, mod) }, |
| 4014 | 64 => .{ .f64 = lhs.toFloat(f64, mod) + rhs.toFloat(f64, mod) }, |
| 4015 | 80 => .{ .f80 = lhs.toFloat(f80, mod) + rhs.toFloat(f80, mod) }, |
| 4016 | 128 => .{ .f128 = lhs.toFloat(f128, mod) + rhs.toFloat(f128, mod) }, |
| 4058 | 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 | 4065 | pub fn floatDiv( |
| ... | ... | @@ -4071,49 +4074,32 @@ pub const Value = struct { |
| 4071 | 4074 | for (result_data, 0..) |*scalar, i| { |
| 4072 | 4075 | const lhs_elem = try lhs.elemValue(mod, i); |
| 4073 | 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 | 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 | 4084 | pub fn floatDivScalar( |
| 4082 | 4085 | lhs: Value, |
| 4083 | 4086 | rhs: Value, |
| 4084 | 4087 | float_type: Type, |
| 4085 | | arena: Allocator, |
| 4086 | | mod: *const Module, |
| 4088 | mod: *Module, |
| 4087 | 4089 | ) !Value { |
| 4088 | 4090 | const target = mod.getTarget(); |
| 4089 | | switch (float_type.floatBits(target)) { |
| 4090 | | 16 => { |
| 4091 | | const lhs_val = lhs.toFloat(f16, mod); |
| 4092 | | const rhs_val = rhs.toFloat(f16, mod); |
| 4093 | | return Value.Tag.float_16.create(arena, lhs_val / rhs_val); |
| 4094 | | }, |
| 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 | | }, |
| 4091 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4092 | 16 => .{ .f16 = lhs.toFloat(f16, mod) / rhs.toFloat(f16, mod) }, |
| 4093 | 32 => .{ .f32 = lhs.toFloat(f32, mod) / rhs.toFloat(f32, mod) }, |
| 4094 | 64 => .{ .f64 = lhs.toFloat(f64, mod) / rhs.toFloat(f64, mod) }, |
| 4095 | 80 => .{ .f80 = lhs.toFloat(f80, mod) / rhs.toFloat(f80, mod) }, |
| 4096 | 128 => .{ .f128 = lhs.toFloat(f128, mod) / rhs.toFloat(f128, mod) }, |
| 4115 | 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 | 4105 | pub fn floatDivFloor( |
| ... | ... | @@ -4128,49 +4114,32 @@ pub const Value = struct { |
| 4128 | 4114 | for (result_data, 0..) |*scalar, i| { |
| 4129 | 4115 | const lhs_elem = try lhs.elemValue(mod, i); |
| 4130 | 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 | 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 | 4124 | pub fn floatDivFloorScalar( |
| 4139 | 4125 | lhs: Value, |
| 4140 | 4126 | rhs: Value, |
| 4141 | 4127 | float_type: Type, |
| 4142 | | arena: Allocator, |
| 4143 | | mod: *const Module, |
| 4128 | mod: *Module, |
| 4144 | 4129 | ) !Value { |
| 4145 | 4130 | const target = mod.getTarget(); |
| 4146 | | switch (float_type.floatBits(target)) { |
| 4147 | | 16 => { |
| 4148 | | const lhs_val = lhs.toFloat(f16, mod); |
| 4149 | | const rhs_val = rhs.toFloat(f16, mod); |
| 4150 | | return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val)); |
| 4151 | | }, |
| 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 | | }, |
| 4131 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4132 | 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, |
| 4133 | 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, |
| 4134 | 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, |
| 4135 | 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, |
| 4136 | 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, |
| 4172 | 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 | 4145 | pub fn floatDivTrunc( |
| ... | ... | @@ -4185,49 +4154,32 @@ pub const Value = struct { |
| 4185 | 4154 | for (result_data, 0..) |*scalar, i| { |
| 4186 | 4155 | const lhs_elem = try lhs.elemValue(mod, i); |
| 4187 | 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 | 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 | 4164 | pub fn floatDivTruncScalar( |
| 4196 | 4165 | lhs: Value, |
| 4197 | 4166 | rhs: Value, |
| 4198 | 4167 | float_type: Type, |
| 4199 | | arena: Allocator, |
| 4200 | | mod: *const Module, |
| 4168 | mod: *Module, |
| 4201 | 4169 | ) !Value { |
| 4202 | 4170 | const target = mod.getTarget(); |
| 4203 | | switch (float_type.floatBits(target)) { |
| 4204 | | 16 => { |
| 4205 | | const lhs_val = lhs.toFloat(f16, mod); |
| 4206 | | const rhs_val = rhs.toFloat(f16, mod); |
| 4207 | | return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 4208 | | }, |
| 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 | | }, |
| 4171 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4172 | 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, |
| 4173 | 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, |
| 4174 | 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, |
| 4175 | 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, |
| 4176 | 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, |
| 4229 | 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 | 4185 | pub fn floatMul( |
| ... | ... | @@ -4242,49 +4194,32 @@ pub const Value = struct { |
| 4242 | 4194 | for (result_data, 0..) |*scalar, i| { |
| 4243 | 4195 | const lhs_elem = try lhs.elemValue(mod, i); |
| 4244 | 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 | 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 | 4204 | pub fn floatMulScalar( |
| 4253 | 4205 | lhs: Value, |
| 4254 | 4206 | rhs: Value, |
| 4255 | 4207 | float_type: Type, |
| 4256 | | arena: Allocator, |
| 4257 | | mod: *const Module, |
| 4208 | mod: *Module, |
| 4258 | 4209 | ) !Value { |
| 4259 | 4210 | const target = mod.getTarget(); |
| 4260 | | switch (float_type.floatBits(target)) { |
| 4261 | | 16 => { |
| 4262 | | const lhs_val = lhs.toFloat(f16, mod); |
| 4263 | | const rhs_val = rhs.toFloat(f16, mod); |
| 4264 | | return Value.Tag.float_16.create(arena, lhs_val * rhs_val); |
| 4265 | | }, |
| 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 | | }, |
| 4211 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4212 | 16 => .{ .f16 = lhs.toFloat(f16, mod) * rhs.toFloat(f16, mod) }, |
| 4213 | 32 => .{ .f32 = lhs.toFloat(f32, mod) * rhs.toFloat(f32, mod) }, |
| 4214 | 64 => .{ .f64 = lhs.toFloat(f64, mod) * rhs.toFloat(f64, mod) }, |
| 4215 | 80 => .{ .f80 = lhs.toFloat(f80, mod) * rhs.toFloat(f80, mod) }, |
| 4216 | 128 => .{ .f128 = lhs.toFloat(f128, mod) * rhs.toFloat(f128, mod) }, |
| 4286 | 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 | 4225 | pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4292,38 +4227,27 @@ pub const Value = struct { |
| 4292 | 4227 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4293 | 4228 | for (result_data, 0..) |*scalar, i| { |
| 4294 | 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 | 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 | 4238 | const target = mod.getTarget(); |
| 4304 | | switch (float_type.floatBits(target)) { |
| 4305 | | 16 => { |
| 4306 | | const f = val.toFloat(f16, mod); |
| 4307 | | return Value.Tag.float_16.create(arena, @sqrt(f)); |
| 4308 | | }, |
| 4309 | | 32 => { |
| 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 | | }, |
| 4239 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4240 | 16 => .{ .f16 = @sqrt(val.toFloat(f16, mod)) }, |
| 4241 | 32 => .{ .f32 = @sqrt(val.toFloat(f32, mod)) }, |
| 4242 | 64 => .{ .f64 = @sqrt(val.toFloat(f64, mod)) }, |
| 4243 | 80 => .{ .f80 = @sqrt(val.toFloat(f80, mod)) }, |
| 4244 | 128 => .{ .f128 = @sqrt(val.toFloat(f128, mod)) }, |
| 4325 | 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 | 4253 | pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4331,38 +4255,27 @@ pub const Value = struct { |
| 4331 | 4255 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4332 | 4256 | for (result_data, 0..) |*scalar, i| { |
| 4333 | 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 | 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 | 4266 | const target = mod.getTarget(); |
| 4343 | | switch (float_type.floatBits(target)) { |
| 4344 | | 16 => { |
| 4345 | | const f = val.toFloat(f16, mod); |
| 4346 | | return Value.Tag.float_16.create(arena, @sin(f)); |
| 4347 | | }, |
| 4348 | | 32 => { |
| 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 | | }, |
| 4267 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4268 | 16 => .{ .f16 = @sin(val.toFloat(f16, mod)) }, |
| 4269 | 32 => .{ .f32 = @sin(val.toFloat(f32, mod)) }, |
| 4270 | 64 => .{ .f64 = @sin(val.toFloat(f64, mod)) }, |
| 4271 | 80 => .{ .f80 = @sin(val.toFloat(f80, mod)) }, |
| 4272 | 128 => .{ .f128 = @sin(val.toFloat(f128, mod)) }, |
| 4364 | 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 | 4281 | pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4370,38 +4283,27 @@ pub const Value = struct { |
| 4370 | 4283 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4371 | 4284 | for (result_data, 0..) |*scalar, i| { |
| 4372 | 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 | 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 | 4294 | const target = mod.getTarget(); |
| 4382 | | switch (float_type.floatBits(target)) { |
| 4383 | | 16 => { |
| 4384 | | const f = val.toFloat(f16, mod); |
| 4385 | | return Value.Tag.float_16.create(arena, @cos(f)); |
| 4386 | | }, |
| 4387 | | 32 => { |
| 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 | | }, |
| 4295 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4296 | 16 => .{ .f16 = @cos(val.toFloat(f16, mod)) }, |
| 4297 | 32 => .{ .f32 = @cos(val.toFloat(f32, mod)) }, |
| 4298 | 64 => .{ .f64 = @cos(val.toFloat(f64, mod)) }, |
| 4299 | 80 => .{ .f80 = @cos(val.toFloat(f80, mod)) }, |
| 4300 | 128 => .{ .f128 = @cos(val.toFloat(f128, mod)) }, |
| 4403 | 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 | 4309 | pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4409,38 +4311,27 @@ pub const Value = struct { |
| 4409 | 4311 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4410 | 4312 | for (result_data, 0..) |*scalar, i| { |
| 4411 | 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 | 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 | 4322 | const target = mod.getTarget(); |
| 4421 | | switch (float_type.floatBits(target)) { |
| 4422 | | 16 => { |
| 4423 | | const f = val.toFloat(f16, mod); |
| 4424 | | return Value.Tag.float_16.create(arena, @tan(f)); |
| 4425 | | }, |
| 4426 | | 32 => { |
| 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 | | }, |
| 4323 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4324 | 16 => .{ .f16 = @tan(val.toFloat(f16, mod)) }, |
| 4325 | 32 => .{ .f32 = @tan(val.toFloat(f32, mod)) }, |
| 4326 | 64 => .{ .f64 = @tan(val.toFloat(f64, mod)) }, |
| 4327 | 80 => .{ .f80 = @tan(val.toFloat(f80, mod)) }, |
| 4328 | 128 => .{ .f128 = @tan(val.toFloat(f128, mod)) }, |
| 4442 | 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 | 4337 | pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4448,38 +4339,27 @@ pub const Value = struct { |
| 4448 | 4339 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4449 | 4340 | for (result_data, 0..) |*scalar, i| { |
| 4450 | 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 | 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 | 4350 | const target = mod.getTarget(); |
| 4460 | | switch (float_type.floatBits(target)) { |
| 4461 | | 16 => { |
| 4462 | | const f = val.toFloat(f16, mod); |
| 4463 | | return Value.Tag.float_16.create(arena, @exp(f)); |
| 4464 | | }, |
| 4465 | | 32 => { |
| 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 | | }, |
| 4351 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4352 | 16 => .{ .f16 = @exp(val.toFloat(f16, mod)) }, |
| 4353 | 32 => .{ .f32 = @exp(val.toFloat(f32, mod)) }, |
| 4354 | 64 => .{ .f64 = @exp(val.toFloat(f64, mod)) }, |
| 4355 | 80 => .{ .f80 = @exp(val.toFloat(f80, mod)) }, |
| 4356 | 128 => .{ .f128 = @exp(val.toFloat(f128, mod)) }, |
| 4481 | 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 | 4365 | pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4487,38 +4367,27 @@ pub const Value = struct { |
| 4487 | 4367 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4488 | 4368 | for (result_data, 0..) |*scalar, i| { |
| 4489 | 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 | 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 | 4378 | const target = mod.getTarget(); |
| 4499 | | switch (float_type.floatBits(target)) { |
| 4500 | | 16 => { |
| 4501 | | const f = val.toFloat(f16, mod); |
| 4502 | | return Value.Tag.float_16.create(arena, @exp2(f)); |
| 4503 | | }, |
| 4504 | | 32 => { |
| 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 | | }, |
| 4379 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4380 | 16 => .{ .f16 = @exp2(val.toFloat(f16, mod)) }, |
| 4381 | 32 => .{ .f32 = @exp2(val.toFloat(f32, mod)) }, |
| 4382 | 64 => .{ .f64 = @exp2(val.toFloat(f64, mod)) }, |
| 4383 | 80 => .{ .f80 = @exp2(val.toFloat(f80, mod)) }, |
| 4384 | 128 => .{ .f128 = @exp2(val.toFloat(f128, mod)) }, |
| 4520 | 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 | 4393 | pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4526,38 +4395,27 @@ pub const Value = struct { |
| 4526 | 4395 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4527 | 4396 | for (result_data, 0..) |*scalar, i| { |
| 4528 | 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 | 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 | 4406 | const target = mod.getTarget(); |
| 4538 | | switch (float_type.floatBits(target)) { |
| 4539 | | 16 => { |
| 4540 | | const f = val.toFloat(f16, mod); |
| 4541 | | return Value.Tag.float_16.create(arena, @log(f)); |
| 4542 | | }, |
| 4543 | | 32 => { |
| 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 | | }, |
| 4407 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4408 | 16 => .{ .f16 = @log(val.toFloat(f16, mod)) }, |
| 4409 | 32 => .{ .f32 = @log(val.toFloat(f32, mod)) }, |
| 4410 | 64 => .{ .f64 = @log(val.toFloat(f64, mod)) }, |
| 4411 | 80 => .{ .f80 = @log(val.toFloat(f80, mod)) }, |
| 4412 | 128 => .{ .f128 = @log(val.toFloat(f128, mod)) }, |
| 4559 | 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 | 4421 | pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4565,38 +4423,27 @@ pub const Value = struct { |
| 4565 | 4423 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4566 | 4424 | for (result_data, 0..) |*scalar, i| { |
| 4567 | 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 | 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 | 4434 | const target = mod.getTarget(); |
| 4577 | | switch (float_type.floatBits(target)) { |
| 4578 | | 16 => { |
| 4579 | | const f = val.toFloat(f16, mod); |
| 4580 | | return Value.Tag.float_16.create(arena, @log2(f)); |
| 4581 | | }, |
| 4582 | | 32 => { |
| 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 | | }, |
| 4435 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4436 | 16 => .{ .f16 = @log2(val.toFloat(f16, mod)) }, |
| 4437 | 32 => .{ .f32 = @log2(val.toFloat(f32, mod)) }, |
| 4438 | 64 => .{ .f64 = @log2(val.toFloat(f64, mod)) }, |
| 4439 | 80 => .{ .f80 = @log2(val.toFloat(f80, mod)) }, |
| 4440 | 128 => .{ .f128 = @log2(val.toFloat(f128, mod)) }, |
| 4598 | 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 | 4449 | pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4604,38 +4451,27 @@ pub const Value = struct { |
| 4604 | 4451 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4605 | 4452 | for (result_data, 0..) |*scalar, i| { |
| 4606 | 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 | 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 | 4462 | const target = mod.getTarget(); |
| 4616 | | switch (float_type.floatBits(target)) { |
| 4617 | | 16 => { |
| 4618 | | const f = val.toFloat(f16, mod); |
| 4619 | | return Value.Tag.float_16.create(arena, @log10(f)); |
| 4620 | | }, |
| 4621 | | 32 => { |
| 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 | | }, |
| 4463 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4464 | 16 => .{ .f16 = @log10(val.toFloat(f16, mod)) }, |
| 4465 | 32 => .{ .f32 = @log10(val.toFloat(f32, mod)) }, |
| 4466 | 64 => .{ .f64 = @log10(val.toFloat(f64, mod)) }, |
| 4467 | 80 => .{ .f80 = @log10(val.toFloat(f80, mod)) }, |
| 4468 | 128 => .{ .f128 = @log10(val.toFloat(f128, mod)) }, |
| 4637 | 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 | 4477 | pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4643,38 +4479,27 @@ pub const Value = struct { |
| 4643 | 4479 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4644 | 4480 | for (result_data, 0..) |*scalar, i| { |
| 4645 | 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 | 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 | 4490 | const target = mod.getTarget(); |
| 4655 | | switch (float_type.floatBits(target)) { |
| 4656 | | 16 => { |
| 4657 | | const f = val.toFloat(f16, mod); |
| 4658 | | return Value.Tag.float_16.create(arena, @fabs(f)); |
| 4659 | | }, |
| 4660 | | 32 => { |
| 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 | | }, |
| 4491 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4492 | 16 => .{ .f16 = @fabs(val.toFloat(f16, mod)) }, |
| 4493 | 32 => .{ .f32 = @fabs(val.toFloat(f32, mod)) }, |
| 4494 | 64 => .{ .f64 = @fabs(val.toFloat(f64, mod)) }, |
| 4495 | 80 => .{ .f80 = @fabs(val.toFloat(f80, mod)) }, |
| 4496 | 128 => .{ .f128 = @fabs(val.toFloat(f128, mod)) }, |
| 4676 | 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 | 4505 | pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4682,38 +4507,27 @@ pub const Value = struct { |
| 4682 | 4507 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4683 | 4508 | for (result_data, 0..) |*scalar, i| { |
| 4684 | 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 | 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 | 4518 | const target = mod.getTarget(); |
| 4694 | | switch (float_type.floatBits(target)) { |
| 4695 | | 16 => { |
| 4696 | | const f = val.toFloat(f16, mod); |
| 4697 | | return Value.Tag.float_16.create(arena, @floor(f)); |
| 4698 | | }, |
| 4699 | | 32 => { |
| 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 | | }, |
| 4519 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4520 | 16 => .{ .f16 = @floor(val.toFloat(f16, mod)) }, |
| 4521 | 32 => .{ .f32 = @floor(val.toFloat(f32, mod)) }, |
| 4522 | 64 => .{ .f64 = @floor(val.toFloat(f64, mod)) }, |
| 4523 | 80 => .{ .f80 = @floor(val.toFloat(f80, mod)) }, |
| 4524 | 128 => .{ .f128 = @floor(val.toFloat(f128, mod)) }, |
| 4715 | 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 | 4533 | pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4721,38 +4535,27 @@ pub const Value = struct { |
| 4721 | 4535 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4722 | 4536 | for (result_data, 0..) |*scalar, i| { |
| 4723 | 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 | 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 | 4546 | const target = mod.getTarget(); |
| 4733 | | switch (float_type.floatBits(target)) { |
| 4734 | | 16 => { |
| 4735 | | const f = val.toFloat(f16, mod); |
| 4736 | | return Value.Tag.float_16.create(arena, @ceil(f)); |
| 4737 | | }, |
| 4738 | | 32 => { |
| 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 | | }, |
| 4547 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4548 | 16 => .{ .f16 = @ceil(val.toFloat(f16, mod)) }, |
| 4549 | 32 => .{ .f32 = @ceil(val.toFloat(f32, mod)) }, |
| 4550 | 64 => .{ .f64 = @ceil(val.toFloat(f64, mod)) }, |
| 4551 | 80 => .{ .f80 = @ceil(val.toFloat(f80, mod)) }, |
| 4552 | 128 => .{ .f128 = @ceil(val.toFloat(f128, mod)) }, |
| 4754 | 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 | 4561 | pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4760,38 +4563,27 @@ pub const Value = struct { |
| 4760 | 4563 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4761 | 4564 | for (result_data, 0..) |*scalar, i| { |
| 4762 | 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 | 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 | 4574 | const target = mod.getTarget(); |
| 4772 | | switch (float_type.floatBits(target)) { |
| 4773 | | 16 => { |
| 4774 | | const f = val.toFloat(f16, mod); |
| 4775 | | return Value.Tag.float_16.create(arena, @round(f)); |
| 4776 | | }, |
| 4777 | | 32 => { |
| 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 | | }, |
| 4575 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4576 | 16 => .{ .f16 = @round(val.toFloat(f16, mod)) }, |
| 4577 | 32 => .{ .f32 = @round(val.toFloat(f32, mod)) }, |
| 4578 | 64 => .{ .f64 = @round(val.toFloat(f64, mod)) }, |
| 4579 | 80 => .{ .f80 = @round(val.toFloat(f80, mod)) }, |
| 4580 | 128 => .{ .f128 = @round(val.toFloat(f128, mod)) }, |
| 4793 | 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 | 4589 | pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { |
| ... | ... | @@ -4799,38 +4591,27 @@ pub const Value = struct { |
| 4799 | 4591 | const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); |
| 4800 | 4592 | for (result_data, 0..) |*scalar, i| { |
| 4801 | 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 | 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 | 4602 | const target = mod.getTarget(); |
| 4811 | | switch (float_type.floatBits(target)) { |
| 4812 | | 16 => { |
| 4813 | | const f = val.toFloat(f16, mod); |
| 4814 | | return Value.Tag.float_16.create(arena, @trunc(f)); |
| 4815 | | }, |
| 4816 | | 32 => { |
| 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 | | }, |
| 4603 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4604 | 16 => .{ .f16 = @trunc(val.toFloat(f16, mod)) }, |
| 4605 | 32 => .{ .f32 = @trunc(val.toFloat(f32, mod)) }, |
| 4606 | 64 => .{ .f64 = @trunc(val.toFloat(f64, mod)) }, |
| 4607 | 80 => .{ .f80 = @trunc(val.toFloat(f80, mod)) }, |
| 4608 | 128 => .{ .f128 = @trunc(val.toFloat(f128, mod)) }, |
| 4832 | 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 | 4617 | pub fn mulAdd( |
| ... | ... | @@ -4852,13 +4633,12 @@ pub const Value = struct { |
| 4852 | 4633 | mulend1_elem, |
| 4853 | 4634 | mulend2_elem, |
| 4854 | 4635 | addend_elem, |
| 4855 | | arena, |
| 4856 | 4636 | mod, |
| 4857 | 4637 | ); |
| 4858 | 4638 | } |
| 4859 | 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 | 4644 | pub fn mulAddScalar( |
| ... | ... | @@ -4866,43 +4646,21 @@ pub const Value = struct { |
| 4866 | 4646 | mulend1: Value, |
| 4867 | 4647 | mulend2: Value, |
| 4868 | 4648 | addend: Value, |
| 4869 | | arena: Allocator, |
| 4870 | | mod: *const Module, |
| 4649 | mod: *Module, |
| 4871 | 4650 | ) Allocator.Error!Value { |
| 4872 | 4651 | const target = mod.getTarget(); |
| 4873 | | switch (float_type.floatBits(target)) { |
| 4874 | | 16 => { |
| 4875 | | const m1 = mulend1.toFloat(f16, mod); |
| 4876 | | const m2 = mulend2.toFloat(f16, mod); |
| 4877 | | const a = addend.toFloat(f16, mod); |
| 4878 | | return Value.Tag.float_16.create(arena, @mulAdd(f16, m1, m2, a)); |
| 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 | | }, |
| 4652 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 4653 | 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, mod), mulend2.toFloat(f16, mod), addend.toFloat(f16, mod)) }, |
| 4654 | 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, mod), mulend2.toFloat(f32, mod), addend.toFloat(f32, mod)) }, |
| 4655 | 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, mod), mulend2.toFloat(f64, mod), addend.toFloat(f64, mod)) }, |
| 4656 | 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, mod), mulend2.toFloat(f80, mod), addend.toFloat(f80, mod)) }, |
| 4657 | 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, mod), mulend2.toFloat(f128, mod), addend.toFloat(f128, mod)) }, |
| 4904 | 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 | 4666 | /// If the value is represented in-memory as a series of bytes that all |
| ... | ... | @@ -5053,41 +4811,6 @@ pub const Value = struct { |
| 5053 | 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 | 4814 | pub const Error = struct { |
| 5092 | 4815 | base: Payload = .{ .tag = .@"error" }, |
| 5093 | 4816 | data: struct { |
| ... | ... | @@ -5152,7 +4875,6 @@ pub const Value = struct { |
| 5152 | 4875 | pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined }; |
| 5153 | 4876 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined }; |
| 5154 | 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 | 4878 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; |
| 5157 | 4879 | pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined }; |
| 5158 | 4880 | pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined }; |