| ... | ... | @@ -138,6 +138,7 @@ pub const Value = extern union { |
| 138 | 138 | float_16, |
| 139 | 139 | float_32, |
| 140 | 140 | float_64, |
| 141 | float_80, |
| 141 | 142 | float_128, |
| 142 | 143 | enum_literal, |
| 143 | 144 | /// A specific enum tag, indicated by the field index (declaration order). |
| ... | ... | @@ -295,6 +296,7 @@ pub const Value = extern union { |
| 295 | 296 | .float_16 => Payload.Float_16, |
| 296 | 297 | .float_32 => Payload.Float_32, |
| 297 | 298 | .float_64 => Payload.Float_64, |
| 299 | .float_80 => Payload.Float_80, |
| 298 | 300 | .float_128 => Payload.Float_128, |
| 299 | 301 | .@"error" => Payload.Error, |
| 300 | 302 | .inferred_alloc => Payload.InferredAlloc, |
| ... | ... | @@ -546,6 +548,7 @@ pub const Value = extern union { |
| 546 | 548 | .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16), |
| 547 | 549 | .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32), |
| 548 | 550 | .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64), |
| 551 | .float_80 => return self.copyPayloadShallow(arena, Payload.Float_80), |
| 549 | 552 | .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128), |
| 550 | 553 | .enum_literal => { |
| 551 | 554 | const payload = self.castTag(.enum_literal).?; |
| ... | ... | @@ -733,6 +736,7 @@ pub const Value = extern union { |
| 733 | 736 | .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}), |
| 734 | 737 | .float_32 => return out_stream.print("{}", .{val.castTag(.float_32).?.data}), |
| 735 | 738 | .float_64 => return out_stream.print("{}", .{val.castTag(.float_64).?.data}), |
| 739 | .float_80 => return out_stream.print("{}", .{val.castTag(.float_80).?.data}), |
| 736 | 740 | .float_128 => return out_stream.print("{}", .{val.castTag(.float_128).?.data}), |
| 737 | 741 | .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}), |
| 738 | 742 | // TODO to print this it should be error{ Set, Items }!T(val), but we need the type for that |
| ... | ... | @@ -1029,6 +1033,11 @@ pub const Value = extern union { |
| 1029 | 1033 | } |
| 1030 | 1034 | |
| 1031 | 1035 | pub fn writeToMemory(val: Value, ty: Type, target: Target, buffer: []u8) void { |
| 1036 | if (val.isUndef()) { |
| 1037 | const size = @intCast(usize, ty.abiSize(target)); |
| 1038 | std.mem.set(u8, buffer[0..size], 0xaa); |
| 1039 | return; |
| 1040 | } |
| 1032 | 1041 | switch (ty.zigTypeTag()) { |
| 1033 | 1042 | .Int => { |
| 1034 | 1043 | var bigint_buffer: BigIntSpace = undefined; |
| ... | ... | @@ -1064,6 +1073,14 @@ pub const Value = extern union { |
| 1064 | 1073 | buf_off += elem_size; |
| 1065 | 1074 | } |
| 1066 | 1075 | }, |
| 1076 | .Struct => { |
| 1077 | const fields = ty.structFields().values(); |
| 1078 | const field_vals = val.castTag(.@"struct").?.data; |
| 1079 | for (fields) |field, i| { |
| 1080 | const off = @intCast(usize, ty.structFieldOffset(i, target)); |
| 1081 | writeToMemory(field_vals[i], field.ty, target, buffer[off..]); |
| 1082 | } |
| 1083 | }, |
| 1067 | 1084 | else => @panic("TODO implement writeToMemory for more types"), |
| 1068 | 1085 | } |
| 1069 | 1086 | } |
| ... | ... | @@ -1083,6 +1100,7 @@ pub const Value = extern union { |
| 1083 | 1100 | 16 => return Value.Tag.float_16.create(arena, floatReadFromMemory(f16, target, buffer)), |
| 1084 | 1101 | 32 => return Value.Tag.float_32.create(arena, floatReadFromMemory(f32, target, buffer)), |
| 1085 | 1102 | 64 => return Value.Tag.float_64.create(arena, floatReadFromMemory(f64, target, buffer)), |
| 1103 | 80 => return Value.Tag.float_80.create(arena, floatReadFromMemory(f80, target, buffer)), |
| 1086 | 1104 | 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)), |
| 1087 | 1105 | else => unreachable, |
| 1088 | 1106 | }, |
| ... | ... | @@ -1100,6 +1118,12 @@ pub const Value = extern union { |
| 1100 | 1118 | } |
| 1101 | 1119 | |
| 1102 | 1120 | fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F { |
| 1121 | if (F == f80) { |
| 1122 | // TODO: use std.math.F80Repr? |
| 1123 | const int = std.mem.readInt(u128, buffer[0..16], target.cpu.arch.endian()); |
| 1124 | // TODO shouldn't this be a bitcast from u80 to f80 instead of u128 to f80? |
| 1125 | return @bitCast(F, int); |
| 1126 | } |
| 1103 | 1127 | const Int = @Type(.{ .Int = .{ |
| 1104 | 1128 | .signedness = .unsigned, |
| 1105 | 1129 | .bits = @typeInfo(F).Float.bits, |
| ... | ... | @@ -1114,12 +1138,23 @@ pub const Value = extern union { |
| 1114 | 1138 | .float_16 => @floatCast(T, val.castTag(.float_16).?.data), |
| 1115 | 1139 | .float_32 => @floatCast(T, val.castTag(.float_32).?.data), |
| 1116 | 1140 | .float_64 => @floatCast(T, val.castTag(.float_64).?.data), |
| 1141 | .float_80 => @floatCast(T, val.castTag(.float_80).?.data), |
| 1117 | 1142 | .float_128 => @floatCast(T, val.castTag(.float_128).?.data), |
| 1118 | 1143 | |
| 1119 | 1144 | .zero => 0, |
| 1120 | 1145 | .one => 1, |
| 1121 | | .int_u64 => @intToFloat(T, val.castTag(.int_u64).?.data), |
| 1122 | | .int_i64 => @intToFloat(T, val.castTag(.int_i64).?.data), |
| 1146 | .int_u64 => { |
| 1147 | if (T == f80) { |
| 1148 | @panic("TODO we can't lower this properly on non-x86 llvm backend yet"); |
| 1149 | } |
| 1150 | return @intToFloat(T, val.castTag(.int_u64).?.data); |
| 1151 | }, |
| 1152 | .int_i64 => { |
| 1153 | if (T == f80) { |
| 1154 | @panic("TODO we can't lower this properly on non-x86 llvm backend yet"); |
| 1155 | } |
| 1156 | return @intToFloat(T, val.castTag(.int_i64).?.data); |
| 1157 | }, |
| 1123 | 1158 | |
| 1124 | 1159 | .int_big_positive => @floatCast(T, bigIntToFloat(val.castTag(.int_big_positive).?.data, true)), |
| 1125 | 1160 | .int_big_negative => @floatCast(T, bigIntToFloat(val.castTag(.int_big_negative).?.data, false)), |
| ... | ... | @@ -1367,14 +1402,13 @@ pub const Value = extern union { |
| 1367 | 1402 | |
| 1368 | 1403 | /// Converts an integer or a float to a float. May result in a loss of information. |
| 1369 | 1404 | /// Caller can find out by equality checking the result against the operand. |
| 1370 | | pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type) !Value { |
| 1371 | | switch (dest_ty.tag()) { |
| 1372 | | .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)), |
| 1373 | | .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)), |
| 1374 | | .f64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)), |
| 1375 | | .f128, .comptime_float, .c_longdouble => { |
| 1376 | | return Value.Tag.float_128.create(arena, self.toFloat(f128)); |
| 1377 | | }, |
| 1405 | pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, target: Target) !Value { |
| 1406 | switch (dest_ty.floatBits(target)) { |
| 1407 | 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)), |
| 1408 | 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)), |
| 1409 | 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)), |
| 1410 | 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80)), |
| 1411 | 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128)), |
| 1378 | 1412 | else => unreachable, |
| 1379 | 1413 | } |
| 1380 | 1414 | } |
| ... | ... | @@ -1389,8 +1423,10 @@ pub const Value = extern union { |
| 1389 | 1423 | .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0, |
| 1390 | 1424 | .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0, |
| 1391 | 1425 | .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0, |
| 1392 | | // .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0, |
| 1393 | | .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"), |
| 1426 | //.float_80 => @rem(self.castTag(.float_80).?.data, 1) != 0, |
| 1427 | .float_80 => @panic("TODO implement __remx in compiler-rt"), |
| 1428 | //.float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0, |
| 1429 | .float_128 => @panic("TODO implement fmodl in compiler-rt"), |
| 1394 | 1430 | |
| 1395 | 1431 | else => unreachable, |
| 1396 | 1432 | }; |
| ... | ... | @@ -1408,6 +1444,7 @@ pub const Value = extern union { |
| 1408 | 1444 | .float_16 => self.castTag(.float_16).?.data == 0, |
| 1409 | 1445 | .float_32 => self.castTag(.float_32).?.data == 0, |
| 1410 | 1446 | .float_64 => self.castTag(.float_64).?.data == 0, |
| 1447 | .float_80 => self.castTag(.float_80).?.data == 0, |
| 1411 | 1448 | .float_128 => self.castTag(.float_128).?.data == 0, |
| 1412 | 1449 | |
| 1413 | 1450 | .int_big_positive => self.castTag(.int_big_positive).?.asBigInt().eqZero(), |
| ... | ... | @@ -1440,6 +1477,7 @@ pub const Value = extern union { |
| 1440 | 1477 | .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0), |
| 1441 | 1478 | .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0), |
| 1442 | 1479 | .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0), |
| 1480 | .float_80 => std.math.order(lhs.castTag(.float_80).?.data, 0), |
| 1443 | 1481 | .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0), |
| 1444 | 1482 | |
| 1445 | 1483 | else => unreachable, |
| ... | ... | @@ -1471,6 +1509,7 @@ pub const Value = extern union { |
| 1471 | 1509 | .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data), |
| 1472 | 1510 | .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data), |
| 1473 | 1511 | .float_64 => return std.math.order(lhs.castTag(.float_64).?.data, rhs.castTag(.float_64).?.data), |
| 1512 | .float_80 => return std.math.order(lhs.castTag(.float_80).?.data, rhs.castTag(.float_80).?.data), |
| 1474 | 1513 | .float_128 => return std.math.order(lhs.castTag(.float_128).?.data, rhs.castTag(.float_128).?.data), |
| 1475 | 1514 | else => unreachable, |
| 1476 | 1515 | }; |
| ... | ... | @@ -2139,6 +2178,7 @@ pub const Value = extern union { |
| 2139 | 2178 | .float_16, |
| 2140 | 2179 | .float_32, |
| 2141 | 2180 | .float_64, |
| 2181 | .float_80, |
| 2142 | 2182 | .float_128, |
| 2143 | 2183 | => true, |
| 2144 | 2184 | else => false, |
| ... | ... | @@ -2174,6 +2214,9 @@ pub const Value = extern union { |
| 2174 | 2214 | 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)), |
| 2175 | 2215 | 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)), |
| 2176 | 2216 | 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)), |
| 2217 | // We can't lower this properly on non-x86 llvm backends yet |
| 2218 | //80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)), |
| 2219 | 80 => @panic("TODO f80 intToFloat"), |
| 2177 | 2220 | 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)), |
| 2178 | 2221 | else => unreachable, |
| 2179 | 2222 | } |
| ... | ... | @@ -2184,6 +2227,7 @@ pub const Value = extern union { |
| 2184 | 2227 | 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), |
| 2185 | 2228 | 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), |
| 2186 | 2229 | 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)), |
| 2230 | 80 => return Value.Tag.float_80.create(arena, @floatCast(f80, float)), |
| 2187 | 2231 | 128 => return Value.Tag.float_128.create(arena, float), |
| 2188 | 2232 | else => unreachable, |
| 2189 | 2233 | } |
| ... | ... | @@ -2281,7 +2325,7 @@ pub const Value = extern union { |
| 2281 | 2325 | } |
| 2282 | 2326 | |
| 2283 | 2327 | if (ty.isAnyFloat()) { |
| 2284 | | return floatAdd(lhs, rhs, ty, arena); |
| 2328 | return floatAdd(lhs, rhs, ty, arena, target); |
| 2285 | 2329 | } |
| 2286 | 2330 | |
| 2287 | 2331 | const overflow_result = try intAddWithOverflow(lhs, rhs, ty, arena, target); |
| ... | ... | @@ -2371,7 +2415,7 @@ pub const Value = extern union { |
| 2371 | 2415 | } |
| 2372 | 2416 | |
| 2373 | 2417 | if (ty.isAnyFloat()) { |
| 2374 | | return floatSub(lhs, rhs, ty, arena); |
| 2418 | return floatSub(lhs, rhs, ty, arena, target); |
| 2375 | 2419 | } |
| 2376 | 2420 | |
| 2377 | 2421 | const overflow_result = try intSubWithOverflow(lhs, rhs, ty, arena, target); |
| ... | ... | @@ -2454,7 +2498,7 @@ pub const Value = extern union { |
| 2454 | 2498 | } |
| 2455 | 2499 | |
| 2456 | 2500 | if (ty.isAnyFloat()) { |
| 2457 | | return floatMul(lhs, rhs, ty, arena); |
| 2501 | return floatMul(lhs, rhs, ty, arena, target); |
| 2458 | 2502 | } |
| 2459 | 2503 | |
| 2460 | 2504 | const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, target); |
| ... | ... | @@ -2753,23 +2797,84 @@ pub const Value = extern union { |
| 2753 | 2797 | .float_16 => std.math.isNan(val.castTag(.float_16).?.data), |
| 2754 | 2798 | .float_32 => std.math.isNan(val.castTag(.float_32).?.data), |
| 2755 | 2799 | .float_64 => std.math.isNan(val.castTag(.float_64).?.data), |
| 2800 | .float_80 => std.math.isNan(val.castTag(.float_80).?.data), |
| 2756 | 2801 | .float_128 => std.math.isNan(val.castTag(.float_128).?.data), |
| 2757 | 2802 | else => false, |
| 2758 | 2803 | }; |
| 2759 | 2804 | } |
| 2760 | 2805 | |
| 2761 | | pub fn floatRem(lhs: Value, rhs: Value, allocator: Allocator) !Value { |
| 2762 | | _ = lhs; |
| 2763 | | _ = rhs; |
| 2764 | | _ = allocator; |
| 2765 | | @panic("TODO implement Value.floatRem"); |
| 2806 | pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value { |
| 2807 | switch (float_type.floatBits(target)) { |
| 2808 | 16 => { |
| 2809 | const lhs_val = lhs.toFloat(f16); |
| 2810 | const rhs_val = rhs.toFloat(f16); |
| 2811 | return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val)); |
| 2812 | }, |
| 2813 | 32 => { |
| 2814 | const lhs_val = lhs.toFloat(f32); |
| 2815 | const rhs_val = rhs.toFloat(f32); |
| 2816 | return Value.Tag.float_32.create(arena, @rem(lhs_val, rhs_val)); |
| 2817 | }, |
| 2818 | 64 => { |
| 2819 | const lhs_val = lhs.toFloat(f64); |
| 2820 | const rhs_val = rhs.toFloat(f64); |
| 2821 | return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val)); |
| 2822 | }, |
| 2823 | 80 => { |
| 2824 | if (true) { |
| 2825 | @panic("TODO implement compiler_rt __remx"); |
| 2826 | } |
| 2827 | const lhs_val = lhs.toFloat(f80); |
| 2828 | const rhs_val = rhs.toFloat(f80); |
| 2829 | return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val)); |
| 2830 | }, |
| 2831 | 128 => { |
| 2832 | if (true) { |
| 2833 | @panic("TODO implement compiler_rt fmodl"); |
| 2834 | } |
| 2835 | const lhs_val = lhs.toFloat(f128); |
| 2836 | const rhs_val = rhs.toFloat(f128); |
| 2837 | return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val)); |
| 2838 | }, |
| 2839 | else => unreachable, |
| 2840 | } |
| 2766 | 2841 | } |
| 2767 | 2842 | |
| 2768 | | pub fn floatMod(lhs: Value, rhs: Value, allocator: Allocator) !Value { |
| 2769 | | _ = lhs; |
| 2770 | | _ = rhs; |
| 2771 | | _ = allocator; |
| 2772 | | @panic("TODO implement Value.floatMod"); |
| 2843 | pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value { |
| 2844 | switch (float_type.floatBits(target)) { |
| 2845 | 16 => { |
| 2846 | const lhs_val = lhs.toFloat(f16); |
| 2847 | const rhs_val = rhs.toFloat(f16); |
| 2848 | return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val)); |
| 2849 | }, |
| 2850 | 32 => { |
| 2851 | const lhs_val = lhs.toFloat(f32); |
| 2852 | const rhs_val = rhs.toFloat(f32); |
| 2853 | return Value.Tag.float_32.create(arena, @mod(lhs_val, rhs_val)); |
| 2854 | }, |
| 2855 | 64 => { |
| 2856 | const lhs_val = lhs.toFloat(f64); |
| 2857 | const rhs_val = rhs.toFloat(f64); |
| 2858 | return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val)); |
| 2859 | }, |
| 2860 | 80 => { |
| 2861 | if (true) { |
| 2862 | @panic("TODO implement compiler_rt __modx"); |
| 2863 | } |
| 2864 | const lhs_val = lhs.toFloat(f80); |
| 2865 | const rhs_val = rhs.toFloat(f80); |
| 2866 | return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val)); |
| 2867 | }, |
| 2868 | 128 => { |
| 2869 | if (true) { |
| 2870 | @panic("TODO implement compiler_rt fmodl"); |
| 2871 | } |
| 2872 | const lhs_val = lhs.toFloat(f128); |
| 2873 | const rhs_val = rhs.toFloat(f128); |
| 2874 | return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val)); |
| 2875 | }, |
| 2876 | else => unreachable, |
| 2877 | } |
| 2773 | 2878 | } |
| 2774 | 2879 | |
| 2775 | 2880 | pub fn intMul(lhs: Value, rhs: Value, allocator: Allocator) !Value { |
| ... | ... | @@ -2929,24 +3034,30 @@ pub const Value = extern union { |
| 2929 | 3034 | rhs: Value, |
| 2930 | 3035 | float_type: Type, |
| 2931 | 3036 | arena: Allocator, |
| 3037 | target: Target, |
| 2932 | 3038 | ) !Value { |
| 2933 | | switch (float_type.tag()) { |
| 2934 | | .f16 => { |
| 3039 | switch (float_type.floatBits(target)) { |
| 3040 | 16 => { |
| 2935 | 3041 | const lhs_val = lhs.toFloat(f16); |
| 2936 | 3042 | const rhs_val = rhs.toFloat(f16); |
| 2937 | 3043 | return Value.Tag.float_16.create(arena, lhs_val + rhs_val); |
| 2938 | 3044 | }, |
| 2939 | | .f32 => { |
| 3045 | 32 => { |
| 2940 | 3046 | const lhs_val = lhs.toFloat(f32); |
| 2941 | 3047 | const rhs_val = rhs.toFloat(f32); |
| 2942 | 3048 | return Value.Tag.float_32.create(arena, lhs_val + rhs_val); |
| 2943 | 3049 | }, |
| 2944 | | .f64 => { |
| 3050 | 64 => { |
| 2945 | 3051 | const lhs_val = lhs.toFloat(f64); |
| 2946 | 3052 | const rhs_val = rhs.toFloat(f64); |
| 2947 | 3053 | return Value.Tag.float_64.create(arena, lhs_val + rhs_val); |
| 2948 | 3054 | }, |
| 2949 | | .f128, .comptime_float, .c_longdouble => { |
| 3055 | 80 => { |
| 3056 | const lhs_val = lhs.toFloat(f80); |
| 3057 | const rhs_val = rhs.toFloat(f80); |
| 3058 | return Value.Tag.float_80.create(arena, lhs_val + rhs_val); |
| 3059 | }, |
| 3060 | 128 => { |
| 2950 | 3061 | const lhs_val = lhs.toFloat(f128); |
| 2951 | 3062 | const rhs_val = rhs.toFloat(f128); |
| 2952 | 3063 | return Value.Tag.float_128.create(arena, lhs_val + rhs_val); |
| ... | ... | @@ -2960,24 +3071,30 @@ pub const Value = extern union { |
| 2960 | 3071 | rhs: Value, |
| 2961 | 3072 | float_type: Type, |
| 2962 | 3073 | arena: Allocator, |
| 3074 | target: Target, |
| 2963 | 3075 | ) !Value { |
| 2964 | | switch (float_type.tag()) { |
| 2965 | | .f16 => { |
| 3076 | switch (float_type.floatBits(target)) { |
| 3077 | 16 => { |
| 2966 | 3078 | const lhs_val = lhs.toFloat(f16); |
| 2967 | 3079 | const rhs_val = rhs.toFloat(f16); |
| 2968 | 3080 | return Value.Tag.float_16.create(arena, lhs_val - rhs_val); |
| 2969 | 3081 | }, |
| 2970 | | .f32 => { |
| 3082 | 32 => { |
| 2971 | 3083 | const lhs_val = lhs.toFloat(f32); |
| 2972 | 3084 | const rhs_val = rhs.toFloat(f32); |
| 2973 | 3085 | return Value.Tag.float_32.create(arena, lhs_val - rhs_val); |
| 2974 | 3086 | }, |
| 2975 | | .f64 => { |
| 3087 | 64 => { |
| 2976 | 3088 | const lhs_val = lhs.toFloat(f64); |
| 2977 | 3089 | const rhs_val = rhs.toFloat(f64); |
| 2978 | 3090 | return Value.Tag.float_64.create(arena, lhs_val - rhs_val); |
| 2979 | 3091 | }, |
| 2980 | | .f128, .comptime_float, .c_longdouble => { |
| 3092 | 80 => { |
| 3093 | const lhs_val = lhs.toFloat(f80); |
| 3094 | const rhs_val = rhs.toFloat(f80); |
| 3095 | return Value.Tag.float_80.create(arena, lhs_val - rhs_val); |
| 3096 | }, |
| 3097 | 128 => { |
| 2981 | 3098 | const lhs_val = lhs.toFloat(f128); |
| 2982 | 3099 | const rhs_val = rhs.toFloat(f128); |
| 2983 | 3100 | return Value.Tag.float_128.create(arena, lhs_val - rhs_val); |
| ... | ... | @@ -2991,24 +3108,33 @@ pub const Value = extern union { |
| 2991 | 3108 | rhs: Value, |
| 2992 | 3109 | float_type: Type, |
| 2993 | 3110 | arena: Allocator, |
| 3111 | target: Target, |
| 2994 | 3112 | ) !Value { |
| 2995 | | switch (float_type.tag()) { |
| 2996 | | .f16 => { |
| 3113 | switch (float_type.floatBits(target)) { |
| 3114 | 16 => { |
| 2997 | 3115 | const lhs_val = lhs.toFloat(f16); |
| 2998 | 3116 | const rhs_val = rhs.toFloat(f16); |
| 2999 | 3117 | return Value.Tag.float_16.create(arena, lhs_val / rhs_val); |
| 3000 | 3118 | }, |
| 3001 | | .f32 => { |
| 3119 | 32 => { |
| 3002 | 3120 | const lhs_val = lhs.toFloat(f32); |
| 3003 | 3121 | const rhs_val = rhs.toFloat(f32); |
| 3004 | 3122 | return Value.Tag.float_32.create(arena, lhs_val / rhs_val); |
| 3005 | 3123 | }, |
| 3006 | | .f64 => { |
| 3124 | 64 => { |
| 3007 | 3125 | const lhs_val = lhs.toFloat(f64); |
| 3008 | 3126 | const rhs_val = rhs.toFloat(f64); |
| 3009 | 3127 | return Value.Tag.float_64.create(arena, lhs_val / rhs_val); |
| 3010 | 3128 | }, |
| 3011 | | .f128, .comptime_float, .c_longdouble => { |
| 3129 | 80 => { |
| 3130 | if (true) { |
| 3131 | @panic("TODO implement compiler_rt __divxf3"); |
| 3132 | } |
| 3133 | const lhs_val = lhs.toFloat(f80); |
| 3134 | const rhs_val = rhs.toFloat(f80); |
| 3135 | return Value.Tag.float_80.create(arena, lhs_val / rhs_val); |
| 3136 | }, |
| 3137 | 128 => { |
| 3012 | 3138 | const lhs_val = lhs.toFloat(f128); |
| 3013 | 3139 | const rhs_val = rhs.toFloat(f128); |
| 3014 | 3140 | return Value.Tag.float_128.create(arena, lhs_val / rhs_val); |
| ... | ... | @@ -3022,24 +3148,33 @@ pub const Value = extern union { |
| 3022 | 3148 | rhs: Value, |
| 3023 | 3149 | float_type: Type, |
| 3024 | 3150 | arena: Allocator, |
| 3151 | target: Target, |
| 3025 | 3152 | ) !Value { |
| 3026 | | switch (float_type.tag()) { |
| 3027 | | .f16 => { |
| 3153 | switch (float_type.floatBits(target)) { |
| 3154 | 16 => { |
| 3028 | 3155 | const lhs_val = lhs.toFloat(f16); |
| 3029 | 3156 | const rhs_val = rhs.toFloat(f16); |
| 3030 | 3157 | return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3031 | 3158 | }, |
| 3032 | | .f32 => { |
| 3159 | 32 => { |
| 3033 | 3160 | const lhs_val = lhs.toFloat(f32); |
| 3034 | 3161 | const rhs_val = rhs.toFloat(f32); |
| 3035 | 3162 | return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3036 | 3163 | }, |
| 3037 | | .f64 => { |
| 3164 | 64 => { |
| 3038 | 3165 | const lhs_val = lhs.toFloat(f64); |
| 3039 | 3166 | const rhs_val = rhs.toFloat(f64); |
| 3040 | 3167 | return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3041 | 3168 | }, |
| 3042 | | .f128, .comptime_float, .c_longdouble => { |
| 3169 | 80 => { |
| 3170 | if (true) { |
| 3171 | @panic("TODO implement compiler_rt __floorx"); |
| 3172 | } |
| 3173 | const lhs_val = lhs.toFloat(f80); |
| 3174 | const rhs_val = rhs.toFloat(f80); |
| 3175 | return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3176 | }, |
| 3177 | 128 => { |
| 3043 | 3178 | const lhs_val = lhs.toFloat(f128); |
| 3044 | 3179 | const rhs_val = rhs.toFloat(f128); |
| 3045 | 3180 | return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val)); |
| ... | ... | @@ -3053,24 +3188,33 @@ pub const Value = extern union { |
| 3053 | 3188 | rhs: Value, |
| 3054 | 3189 | float_type: Type, |
| 3055 | 3190 | arena: Allocator, |
| 3191 | target: Target, |
| 3056 | 3192 | ) !Value { |
| 3057 | | switch (float_type.tag()) { |
| 3058 | | .f16 => { |
| 3193 | switch (float_type.floatBits(target)) { |
| 3194 | 16 => { |
| 3059 | 3195 | const lhs_val = lhs.toFloat(f16); |
| 3060 | 3196 | const rhs_val = rhs.toFloat(f16); |
| 3061 | 3197 | return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3062 | 3198 | }, |
| 3063 | | .f32 => { |
| 3199 | 32 => { |
| 3064 | 3200 | const lhs_val = lhs.toFloat(f32); |
| 3065 | 3201 | const rhs_val = rhs.toFloat(f32); |
| 3066 | 3202 | return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3067 | 3203 | }, |
| 3068 | | .f64 => { |
| 3204 | 64 => { |
| 3069 | 3205 | const lhs_val = lhs.toFloat(f64); |
| 3070 | 3206 | const rhs_val = rhs.toFloat(f64); |
| 3071 | 3207 | return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3072 | 3208 | }, |
| 3073 | | .f128, .comptime_float, .c_longdouble => { |
| 3209 | 80 => { |
| 3210 | if (true) { |
| 3211 | @panic("TODO implement compiler_rt __truncx"); |
| 3212 | } |
| 3213 | const lhs_val = lhs.toFloat(f80); |
| 3214 | const rhs_val = rhs.toFloat(f80); |
| 3215 | return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3216 | }, |
| 3217 | 128 => { |
| 3074 | 3218 | const lhs_val = lhs.toFloat(f128); |
| 3075 | 3219 | const rhs_val = rhs.toFloat(f128); |
| 3076 | 3220 | return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val)); |
| ... | ... | @@ -3084,24 +3228,33 @@ pub const Value = extern union { |
| 3084 | 3228 | rhs: Value, |
| 3085 | 3229 | float_type: Type, |
| 3086 | 3230 | arena: Allocator, |
| 3231 | target: Target, |
| 3087 | 3232 | ) !Value { |
| 3088 | | switch (float_type.tag()) { |
| 3089 | | .f16 => { |
| 3233 | switch (float_type.floatBits(target)) { |
| 3234 | 16 => { |
| 3090 | 3235 | const lhs_val = lhs.toFloat(f16); |
| 3091 | 3236 | const rhs_val = rhs.toFloat(f16); |
| 3092 | 3237 | return Value.Tag.float_16.create(arena, lhs_val * rhs_val); |
| 3093 | 3238 | }, |
| 3094 | | .f32 => { |
| 3239 | 32 => { |
| 3095 | 3240 | const lhs_val = lhs.toFloat(f32); |
| 3096 | 3241 | const rhs_val = rhs.toFloat(f32); |
| 3097 | 3242 | return Value.Tag.float_32.create(arena, lhs_val * rhs_val); |
| 3098 | 3243 | }, |
| 3099 | | .f64 => { |
| 3244 | 64 => { |
| 3100 | 3245 | const lhs_val = lhs.toFloat(f64); |
| 3101 | 3246 | const rhs_val = rhs.toFloat(f64); |
| 3102 | 3247 | return Value.Tag.float_64.create(arena, lhs_val * rhs_val); |
| 3103 | 3248 | }, |
| 3104 | | .f128, .comptime_float, .c_longdouble => { |
| 3249 | 80 => { |
| 3250 | if (true) { |
| 3251 | @panic("TODO implement compiler_rt __mulxf3"); |
| 3252 | } |
| 3253 | const lhs_val = lhs.toFloat(f80); |
| 3254 | const rhs_val = rhs.toFloat(f80); |
| 3255 | return Value.Tag.float_80.create(arena, lhs_val * rhs_val); |
| 3256 | }, |
| 3257 | 128 => { |
| 3105 | 3258 | const lhs_val = lhs.toFloat(f128); |
| 3106 | 3259 | const rhs_val = rhs.toFloat(f128); |
| 3107 | 3260 | return Value.Tag.float_128.create(arena, lhs_val * rhs_val); |
| ... | ... | @@ -3250,6 +3403,13 @@ pub const Value = extern union { |
| 3250 | 3403 | data: f64, |
| 3251 | 3404 | }; |
| 3252 | 3405 | |
| 3406 | pub const Float_80 = struct { |
| 3407 | pub const base_tag = Tag.float_80; |
| 3408 | |
| 3409 | base: Payload = .{ .tag = base_tag }, |
| 3410 | data: f80, |
| 3411 | }; |
| 3412 | |
| 3253 | 3413 | pub const Float_128 = struct { |
| 3254 | 3414 | pub const base_tag = Tag.float_128; |
| 3255 | 3415 | |