| ... | @@ -138,6 +138,7 @@ pub const Value = extern union { | ... | @@ -138,6 +138,7 @@ pub const Value = extern union { |
| 138 | float_16, | 138 | float_16, |
| 139 | float_32, | 139 | float_32, |
| 140 | float_64, | 140 | float_64, |
| | 141 | float_80, |
| 141 | float_128, | 142 | float_128, |
| 142 | enum_literal, | 143 | enum_literal, |
| 143 | /// A specific enum tag, indicated by the field index (declaration order). | 144 | /// A specific enum tag, indicated by the field index (declaration order). |
| ... | @@ -295,6 +296,7 @@ pub const Value = extern union { | ... | @@ -295,6 +296,7 @@ pub const Value = extern union { |
| 295 | .float_16 => Payload.Float_16, | 296 | .float_16 => Payload.Float_16, |
| 296 | .float_32 => Payload.Float_32, | 297 | .float_32 => Payload.Float_32, |
| 297 | .float_64 => Payload.Float_64, | 298 | .float_64 => Payload.Float_64, |
| | 299 | .float_80 => Payload.Float_80, |
| 298 | .float_128 => Payload.Float_128, | 300 | .float_128 => Payload.Float_128, |
| 299 | .@"error" => Payload.Error, | 301 | .@"error" => Payload.Error, |
| 300 | .inferred_alloc => Payload.InferredAlloc, | 302 | .inferred_alloc => Payload.InferredAlloc, |
| ... | @@ -546,6 +548,7 @@ pub const Value = extern union { | ... | @@ -546,6 +548,7 @@ pub const Value = extern union { |
| 546 | .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16), | 548 | .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16), |
| 547 | .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32), | 549 | .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32), |
| 548 | .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64), | 550 | .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64), |
| | 551 | .float_80 => return self.copyPayloadShallow(arena, Payload.Float_80), |
| 549 | .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128), | 552 | .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128), |
| 550 | .enum_literal => { | 553 | .enum_literal => { |
| 551 | const payload = self.castTag(.enum_literal).?; | 554 | const payload = self.castTag(.enum_literal).?; |
| ... | @@ -733,6 +736,7 @@ pub const Value = extern union { | ... | @@ -733,6 +736,7 @@ pub const Value = extern union { |
| 733 | .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}), | 736 | .float_16 => return out_stream.print("{}", .{val.castTag(.float_16).?.data}), |
| 734 | .float_32 => return out_stream.print("{}", .{val.castTag(.float_32).?.data}), | 737 | .float_32 => return out_stream.print("{}", .{val.castTag(.float_32).?.data}), |
| 735 | .float_64 => return out_stream.print("{}", .{val.castTag(.float_64).?.data}), | 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 | .float_128 => return out_stream.print("{}", .{val.castTag(.float_128).?.data}), | 740 | .float_128 => return out_stream.print("{}", .{val.castTag(.float_128).?.data}), |
| 737 | .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}), | 741 | .@"error" => return out_stream.print("error.{s}", .{val.castTag(.@"error").?.data.name}), |
| 738 | // TODO to print this it should be error{ Set, Items }!T(val), but we need the type for that | 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,6 +1033,11 @@ pub const Value = extern union { |
| 1029 | } | 1033 | } |
| 1030 | | 1034 | |
| 1031 | pub fn writeToMemory(val: Value, ty: Type, target: Target, buffer: []u8) void { | 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 | switch (ty.zigTypeTag()) { | 1041 | switch (ty.zigTypeTag()) { |
| 1033 | .Int => { | 1042 | .Int => { |
| 1034 | var bigint_buffer: BigIntSpace = undefined; | 1043 | var bigint_buffer: BigIntSpace = undefined; |
| ... | @@ -1064,6 +1073,14 @@ pub const Value = extern union { | ... | @@ -1064,6 +1073,14 @@ pub const Value = extern union { |
| 1064 | buf_off += elem_size; | 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 | else => @panic("TODO implement writeToMemory for more types"), | 1084 | else => @panic("TODO implement writeToMemory for more types"), |
| 1068 | } | 1085 | } |
| 1069 | } | 1086 | } |
| ... | @@ -1083,6 +1100,7 @@ pub const Value = extern union { | ... | @@ -1083,6 +1100,7 @@ pub const Value = extern union { |
| 1083 | 16 => return Value.Tag.float_16.create(arena, floatReadFromMemory(f16, target, buffer)), | 1100 | 16 => return Value.Tag.float_16.create(arena, floatReadFromMemory(f16, target, buffer)), |
| 1084 | 32 => return Value.Tag.float_32.create(arena, floatReadFromMemory(f32, target, buffer)), | 1101 | 32 => return Value.Tag.float_32.create(arena, floatReadFromMemory(f32, target, buffer)), |
| 1085 | 64 => return Value.Tag.float_64.create(arena, floatReadFromMemory(f64, target, buffer)), | 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 | 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)), | 1104 | 128 => return Value.Tag.float_128.create(arena, floatReadFromMemory(f128, target, buffer)), |
| 1087 | else => unreachable, | 1105 | else => unreachable, |
| 1088 | }, | 1106 | }, |
| ... | @@ -1100,6 +1118,12 @@ pub const Value = extern union { | ... | @@ -1100,6 +1118,12 @@ pub const Value = extern union { |
| 1100 | } | 1118 | } |
| 1101 | | 1119 | |
| 1102 | fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F { | 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 | const Int = @Type(.{ .Int = .{ | 1127 | const Int = @Type(.{ .Int = .{ |
| 1104 | .signedness = .unsigned, | 1128 | .signedness = .unsigned, |
| 1105 | .bits = @typeInfo(F).Float.bits, | 1129 | .bits = @typeInfo(F).Float.bits, |
| ... | @@ -1114,12 +1138,23 @@ pub const Value = extern union { | ... | @@ -1114,12 +1138,23 @@ pub const Value = extern union { |
| 1114 | .float_16 => @floatCast(T, val.castTag(.float_16).?.data), | 1138 | .float_16 => @floatCast(T, val.castTag(.float_16).?.data), |
| 1115 | .float_32 => @floatCast(T, val.castTag(.float_32).?.data), | 1139 | .float_32 => @floatCast(T, val.castTag(.float_32).?.data), |
| 1116 | .float_64 => @floatCast(T, val.castTag(.float_64).?.data), | 1140 | .float_64 => @floatCast(T, val.castTag(.float_64).?.data), |
| | 1141 | .float_80 => @floatCast(T, val.castTag(.float_80).?.data), |
| 1117 | .float_128 => @floatCast(T, val.castTag(.float_128).?.data), | 1142 | .float_128 => @floatCast(T, val.castTag(.float_128).?.data), |
| 1118 | | 1143 | |
| 1119 | .zero => 0, | 1144 | .zero => 0, |
| 1120 | .one => 1, | 1145 | .one => 1, |
| 1121 | .int_u64 => @intToFloat(T, val.castTag(.int_u64).?.data), | 1146 | .int_u64 => { |
| 1122 | .int_i64 => @intToFloat(T, val.castTag(.int_i64).?.data), | 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 | .int_big_positive => @floatCast(T, bigIntToFloat(val.castTag(.int_big_positive).?.data, true)), | 1159 | .int_big_positive => @floatCast(T, bigIntToFloat(val.castTag(.int_big_positive).?.data, true)), |
| 1125 | .int_big_negative => @floatCast(T, bigIntToFloat(val.castTag(.int_big_negative).?.data, false)), | 1160 | .int_big_negative => @floatCast(T, bigIntToFloat(val.castTag(.int_big_negative).?.data, false)), |
| ... | @@ -1367,14 +1402,13 @@ pub const Value = extern union { | ... | @@ -1367,14 +1402,13 @@ pub const Value = extern union { |
| 1367 | | 1402 | |
| 1368 | /// Converts an integer or a float to a float. May result in a loss of information. | 1403 | /// Converts an integer or a float to a float. May result in a loss of information. |
| 1369 | /// Caller can find out by equality checking the result against the operand. | 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 { | 1405 | pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, target: Target) !Value { |
| 1371 | switch (dest_ty.tag()) { | 1406 | switch (dest_ty.floatBits(target)) { |
| 1372 | .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)), | 1407 | 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)), |
| 1373 | .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)), | 1408 | 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)), |
| 1374 | .f64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)), | 1409 | 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)), |
| 1375 | .f128, .comptime_float, .c_longdouble => { | 1410 | 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80)), |
| 1376 | return Value.Tag.float_128.create(arena, self.toFloat(f128)); | 1411 | 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128)), |
| 1377 | }, | | |
| 1378 | else => unreachable, | 1412 | else => unreachable, |
| 1379 | } | 1413 | } |
| 1380 | } | 1414 | } |
| ... | @@ -1389,8 +1423,10 @@ pub const Value = extern union { | ... | @@ -1389,8 +1423,10 @@ pub const Value = extern union { |
| 1389 | .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0, | 1423 | .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0, |
| 1390 | .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0, | 1424 | .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0, |
| 1391 | .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0, | 1425 | .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0, |
| 1392 | // .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0, | 1426 | //.float_80 => @rem(self.castTag(.float_80).?.data, 1) != 0, |
| 1393 | .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"), | 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 | else => unreachable, | 1431 | else => unreachable, |
| 1396 | }; | 1432 | }; |
| ... | @@ -1408,6 +1444,7 @@ pub const Value = extern union { | ... | @@ -1408,6 +1444,7 @@ pub const Value = extern union { |
| 1408 | .float_16 => self.castTag(.float_16).?.data == 0, | 1444 | .float_16 => self.castTag(.float_16).?.data == 0, |
| 1409 | .float_32 => self.castTag(.float_32).?.data == 0, | 1445 | .float_32 => self.castTag(.float_32).?.data == 0, |
| 1410 | .float_64 => self.castTag(.float_64).?.data == 0, | 1446 | .float_64 => self.castTag(.float_64).?.data == 0, |
| | 1447 | .float_80 => self.castTag(.float_80).?.data == 0, |
| 1411 | .float_128 => self.castTag(.float_128).?.data == 0, | 1448 | .float_128 => self.castTag(.float_128).?.data == 0, |
| 1412 | | 1449 | |
| 1413 | .int_big_positive => self.castTag(.int_big_positive).?.asBigInt().eqZero(), | 1450 | .int_big_positive => self.castTag(.int_big_positive).?.asBigInt().eqZero(), |
| ... | @@ -1440,6 +1477,7 @@ pub const Value = extern union { | ... | @@ -1440,6 +1477,7 @@ pub const Value = extern union { |
| 1440 | .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0), | 1477 | .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0), |
| 1441 | .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0), | 1478 | .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0), |
| 1442 | .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0), | 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 | .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0), | 1481 | .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0), |
| 1444 | | 1482 | |
| 1445 | else => unreachable, | 1483 | else => unreachable, |
| ... | @@ -1471,6 +1509,7 @@ pub const Value = extern union { | ... | @@ -1471,6 +1509,7 @@ pub const Value = extern union { |
| 1471 | .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data), | 1509 | .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data), |
| 1472 | .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data), | 1510 | .float_32 => return std.math.order(lhs.castTag(.float_32).?.data, rhs.castTag(.float_32).?.data), |
| 1473 | .float_64 => return std.math.order(lhs.castTag(.float_64).?.data, rhs.castTag(.float_64).?.data), | 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 | .float_128 => return std.math.order(lhs.castTag(.float_128).?.data, rhs.castTag(.float_128).?.data), | 1513 | .float_128 => return std.math.order(lhs.castTag(.float_128).?.data, rhs.castTag(.float_128).?.data), |
| 1475 | else => unreachable, | 1514 | else => unreachable, |
| 1476 | }; | 1515 | }; |
| ... | @@ -2139,6 +2178,7 @@ pub const Value = extern union { | ... | @@ -2139,6 +2178,7 @@ pub const Value = extern union { |
| 2139 | .float_16, | 2178 | .float_16, |
| 2140 | .float_32, | 2179 | .float_32, |
| 2141 | .float_64, | 2180 | .float_64, |
| | 2181 | .float_80, |
| 2142 | .float_128, | 2182 | .float_128, |
| 2143 | => true, | 2183 | => true, |
| 2144 | else => false, | 2184 | else => false, |
| ... | @@ -2174,6 +2214,9 @@ pub const Value = extern union { | ... | @@ -2174,6 +2214,9 @@ pub const Value = extern union { |
| 2174 | 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)), | 2214 | 16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)), |
| 2175 | 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)), | 2215 | 32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)), |
| 2176 | 64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)), | 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 | 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)), | 2220 | 128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)), |
| 2178 | else => unreachable, | 2221 | else => unreachable, |
| 2179 | } | 2222 | } |
| ... | @@ -2184,6 +2227,7 @@ pub const Value = extern union { | ... | @@ -2184,6 +2227,7 @@ pub const Value = extern union { |
| 2184 | 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), | 2227 | 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), |
| 2185 | 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), | 2228 | 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), |
| 2186 | 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)), | 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 | 128 => return Value.Tag.float_128.create(arena, float), | 2231 | 128 => return Value.Tag.float_128.create(arena, float), |
| 2188 | else => unreachable, | 2232 | else => unreachable, |
| 2189 | } | 2233 | } |
| ... | @@ -2281,7 +2325,7 @@ pub const Value = extern union { | ... | @@ -2281,7 +2325,7 @@ pub const Value = extern union { |
| 2281 | } | 2325 | } |
| 2282 | | 2326 | |
| 2283 | if (ty.isAnyFloat()) { | 2327 | if (ty.isAnyFloat()) { |
| 2284 | return floatAdd(lhs, rhs, ty, arena); | 2328 | return floatAdd(lhs, rhs, ty, arena, target); |
| 2285 | } | 2329 | } |
| 2286 | | 2330 | |
| 2287 | const overflow_result = try intAddWithOverflow(lhs, rhs, ty, arena, target); | 2331 | const overflow_result = try intAddWithOverflow(lhs, rhs, ty, arena, target); |
| ... | @@ -2371,7 +2415,7 @@ pub const Value = extern union { | ... | @@ -2371,7 +2415,7 @@ pub const Value = extern union { |
| 2371 | } | 2415 | } |
| 2372 | | 2416 | |
| 2373 | if (ty.isAnyFloat()) { | 2417 | if (ty.isAnyFloat()) { |
| 2374 | return floatSub(lhs, rhs, ty, arena); | 2418 | return floatSub(lhs, rhs, ty, arena, target); |
| 2375 | } | 2419 | } |
| 2376 | | 2420 | |
| 2377 | const overflow_result = try intSubWithOverflow(lhs, rhs, ty, arena, target); | 2421 | const overflow_result = try intSubWithOverflow(lhs, rhs, ty, arena, target); |
| ... | @@ -2454,7 +2498,7 @@ pub const Value = extern union { | ... | @@ -2454,7 +2498,7 @@ pub const Value = extern union { |
| 2454 | } | 2498 | } |
| 2455 | | 2499 | |
| 2456 | if (ty.isAnyFloat()) { | 2500 | if (ty.isAnyFloat()) { |
| 2457 | return floatMul(lhs, rhs, ty, arena); | 2501 | return floatMul(lhs, rhs, ty, arena, target); |
| 2458 | } | 2502 | } |
| 2459 | | 2503 | |
| 2460 | const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, target); | 2504 | const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, target); |
| ... | @@ -2753,23 +2797,84 @@ pub const Value = extern union { | ... | @@ -2753,23 +2797,84 @@ pub const Value = extern union { |
| 2753 | .float_16 => std.math.isNan(val.castTag(.float_16).?.data), | 2797 | .float_16 => std.math.isNan(val.castTag(.float_16).?.data), |
| 2754 | .float_32 => std.math.isNan(val.castTag(.float_32).?.data), | 2798 | .float_32 => std.math.isNan(val.castTag(.float_32).?.data), |
| 2755 | .float_64 => std.math.isNan(val.castTag(.float_64).?.data), | 2799 | .float_64 => std.math.isNan(val.castTag(.float_64).?.data), |
| | 2800 | .float_80 => std.math.isNan(val.castTag(.float_80).?.data), |
| 2756 | .float_128 => std.math.isNan(val.castTag(.float_128).?.data), | 2801 | .float_128 => std.math.isNan(val.castTag(.float_128).?.data), |
| 2757 | else => false, | 2802 | else => false, |
| 2758 | }; | 2803 | }; |
| 2759 | } | 2804 | } |
| 2760 | | 2805 | |
| 2761 | pub fn floatRem(lhs: Value, rhs: Value, allocator: Allocator) !Value { | 2806 | pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value { |
| 2762 | _ = lhs; | 2807 | switch (float_type.floatBits(target)) { |
| 2763 | _ = rhs; | 2808 | 16 => { |
| 2764 | _ = allocator; | 2809 | const lhs_val = lhs.toFloat(f16); |
| 2765 | @panic("TODO implement Value.floatRem"); | 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 { | 2843 | pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value { |
| 2769 | _ = lhs; | 2844 | switch (float_type.floatBits(target)) { |
| 2770 | _ = rhs; | 2845 | 16 => { |
| 2771 | _ = allocator; | 2846 | const lhs_val = lhs.toFloat(f16); |
| 2772 | @panic("TODO implement Value.floatMod"); | 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 | pub fn intMul(lhs: Value, rhs: Value, allocator: Allocator) !Value { | 2880 | pub fn intMul(lhs: Value, rhs: Value, allocator: Allocator) !Value { |
| ... | @@ -2929,24 +3034,30 @@ pub const Value = extern union { | ... | @@ -2929,24 +3034,30 @@ pub const Value = extern union { |
| 2929 | rhs: Value, | 3034 | rhs: Value, |
| 2930 | float_type: Type, | 3035 | float_type: Type, |
| 2931 | arena: Allocator, | 3036 | arena: Allocator, |
| | 3037 | target: Target, |
| 2932 | ) !Value { | 3038 | ) !Value { |
| 2933 | switch (float_type.tag()) { | 3039 | switch (float_type.floatBits(target)) { |
| 2934 | .f16 => { | 3040 | 16 => { |
| 2935 | const lhs_val = lhs.toFloat(f16); | 3041 | const lhs_val = lhs.toFloat(f16); |
| 2936 | const rhs_val = rhs.toFloat(f16); | 3042 | const rhs_val = rhs.toFloat(f16); |
| 2937 | return Value.Tag.float_16.create(arena, lhs_val + rhs_val); | 3043 | return Value.Tag.float_16.create(arena, lhs_val + rhs_val); |
| 2938 | }, | 3044 | }, |
| 2939 | .f32 => { | 3045 | 32 => { |
| 2940 | const lhs_val = lhs.toFloat(f32); | 3046 | const lhs_val = lhs.toFloat(f32); |
| 2941 | const rhs_val = rhs.toFloat(f32); | 3047 | const rhs_val = rhs.toFloat(f32); |
| 2942 | return Value.Tag.float_32.create(arena, lhs_val + rhs_val); | 3048 | return Value.Tag.float_32.create(arena, lhs_val + rhs_val); |
| 2943 | }, | 3049 | }, |
| 2944 | .f64 => { | 3050 | 64 => { |
| 2945 | const lhs_val = lhs.toFloat(f64); | 3051 | const lhs_val = lhs.toFloat(f64); |
| 2946 | const rhs_val = rhs.toFloat(f64); | 3052 | const rhs_val = rhs.toFloat(f64); |
| 2947 | return Value.Tag.float_64.create(arena, lhs_val + rhs_val); | 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 | const lhs_val = lhs.toFloat(f128); | 3061 | const lhs_val = lhs.toFloat(f128); |
| 2951 | const rhs_val = rhs.toFloat(f128); | 3062 | const rhs_val = rhs.toFloat(f128); |
| 2952 | return Value.Tag.float_128.create(arena, lhs_val + rhs_val); | 3063 | return Value.Tag.float_128.create(arena, lhs_val + rhs_val); |
| ... | @@ -2960,24 +3071,30 @@ pub const Value = extern union { | ... | @@ -2960,24 +3071,30 @@ pub const Value = extern union { |
| 2960 | rhs: Value, | 3071 | rhs: Value, |
| 2961 | float_type: Type, | 3072 | float_type: Type, |
| 2962 | arena: Allocator, | 3073 | arena: Allocator, |
| | 3074 | target: Target, |
| 2963 | ) !Value { | 3075 | ) !Value { |
| 2964 | switch (float_type.tag()) { | 3076 | switch (float_type.floatBits(target)) { |
| 2965 | .f16 => { | 3077 | 16 => { |
| 2966 | const lhs_val = lhs.toFloat(f16); | 3078 | const lhs_val = lhs.toFloat(f16); |
| 2967 | const rhs_val = rhs.toFloat(f16); | 3079 | const rhs_val = rhs.toFloat(f16); |
| 2968 | return Value.Tag.float_16.create(arena, lhs_val - rhs_val); | 3080 | return Value.Tag.float_16.create(arena, lhs_val - rhs_val); |
| 2969 | }, | 3081 | }, |
| 2970 | .f32 => { | 3082 | 32 => { |
| 2971 | const lhs_val = lhs.toFloat(f32); | 3083 | const lhs_val = lhs.toFloat(f32); |
| 2972 | const rhs_val = rhs.toFloat(f32); | 3084 | const rhs_val = rhs.toFloat(f32); |
| 2973 | return Value.Tag.float_32.create(arena, lhs_val - rhs_val); | 3085 | return Value.Tag.float_32.create(arena, lhs_val - rhs_val); |
| 2974 | }, | 3086 | }, |
| 2975 | .f64 => { | 3087 | 64 => { |
| 2976 | const lhs_val = lhs.toFloat(f64); | 3088 | const lhs_val = lhs.toFloat(f64); |
| 2977 | const rhs_val = rhs.toFloat(f64); | 3089 | const rhs_val = rhs.toFloat(f64); |
| 2978 | return Value.Tag.float_64.create(arena, lhs_val - rhs_val); | 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 | const lhs_val = lhs.toFloat(f128); | 3098 | const lhs_val = lhs.toFloat(f128); |
| 2982 | const rhs_val = rhs.toFloat(f128); | 3099 | const rhs_val = rhs.toFloat(f128); |
| 2983 | return Value.Tag.float_128.create(arena, lhs_val - rhs_val); | 3100 | return Value.Tag.float_128.create(arena, lhs_val - rhs_val); |
| ... | @@ -2991,24 +3108,33 @@ pub const Value = extern union { | ... | @@ -2991,24 +3108,33 @@ pub const Value = extern union { |
| 2991 | rhs: Value, | 3108 | rhs: Value, |
| 2992 | float_type: Type, | 3109 | float_type: Type, |
| 2993 | arena: Allocator, | 3110 | arena: Allocator, |
| | 3111 | target: Target, |
| 2994 | ) !Value { | 3112 | ) !Value { |
| 2995 | switch (float_type.tag()) { | 3113 | switch (float_type.floatBits(target)) { |
| 2996 | .f16 => { | 3114 | 16 => { |
| 2997 | const lhs_val = lhs.toFloat(f16); | 3115 | const lhs_val = lhs.toFloat(f16); |
| 2998 | const rhs_val = rhs.toFloat(f16); | 3116 | const rhs_val = rhs.toFloat(f16); |
| 2999 | return Value.Tag.float_16.create(arena, lhs_val / rhs_val); | 3117 | return Value.Tag.float_16.create(arena, lhs_val / rhs_val); |
| 3000 | }, | 3118 | }, |
| 3001 | .f32 => { | 3119 | 32 => { |
| 3002 | const lhs_val = lhs.toFloat(f32); | 3120 | const lhs_val = lhs.toFloat(f32); |
| 3003 | const rhs_val = rhs.toFloat(f32); | 3121 | const rhs_val = rhs.toFloat(f32); |
| 3004 | return Value.Tag.float_32.create(arena, lhs_val / rhs_val); | 3122 | return Value.Tag.float_32.create(arena, lhs_val / rhs_val); |
| 3005 | }, | 3123 | }, |
| 3006 | .f64 => { | 3124 | 64 => { |
| 3007 | const lhs_val = lhs.toFloat(f64); | 3125 | const lhs_val = lhs.toFloat(f64); |
| 3008 | const rhs_val = rhs.toFloat(f64); | 3126 | const rhs_val = rhs.toFloat(f64); |
| 3009 | return Value.Tag.float_64.create(arena, lhs_val / rhs_val); | 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 | const lhs_val = lhs.toFloat(f128); | 3138 | const lhs_val = lhs.toFloat(f128); |
| 3013 | const rhs_val = rhs.toFloat(f128); | 3139 | const rhs_val = rhs.toFloat(f128); |
| 3014 | return Value.Tag.float_128.create(arena, lhs_val / rhs_val); | 3140 | return Value.Tag.float_128.create(arena, lhs_val / rhs_val); |
| ... | @@ -3022,24 +3148,33 @@ pub const Value = extern union { | ... | @@ -3022,24 +3148,33 @@ pub const Value = extern union { |
| 3022 | rhs: Value, | 3148 | rhs: Value, |
| 3023 | float_type: Type, | 3149 | float_type: Type, |
| 3024 | arena: Allocator, | 3150 | arena: Allocator, |
| | 3151 | target: Target, |
| 3025 | ) !Value { | 3152 | ) !Value { |
| 3026 | switch (float_type.tag()) { | 3153 | switch (float_type.floatBits(target)) { |
| 3027 | .f16 => { | 3154 | 16 => { |
| 3028 | const lhs_val = lhs.toFloat(f16); | 3155 | const lhs_val = lhs.toFloat(f16); |
| 3029 | const rhs_val = rhs.toFloat(f16); | 3156 | const rhs_val = rhs.toFloat(f16); |
| 3030 | return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val)); | 3157 | return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3031 | }, | 3158 | }, |
| 3032 | .f32 => { | 3159 | 32 => { |
| 3033 | const lhs_val = lhs.toFloat(f32); | 3160 | const lhs_val = lhs.toFloat(f32); |
| 3034 | const rhs_val = rhs.toFloat(f32); | 3161 | const rhs_val = rhs.toFloat(f32); |
| 3035 | return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val)); | 3162 | return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val)); |
| 3036 | }, | 3163 | }, |
| 3037 | .f64 => { | 3164 | 64 => { |
| 3038 | const lhs_val = lhs.toFloat(f64); | 3165 | const lhs_val = lhs.toFloat(f64); |
| 3039 | const rhs_val = rhs.toFloat(f64); | 3166 | const rhs_val = rhs.toFloat(f64); |
| 3040 | return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val)); | 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 | const lhs_val = lhs.toFloat(f128); | 3178 | const lhs_val = lhs.toFloat(f128); |
| 3044 | const rhs_val = rhs.toFloat(f128); | 3179 | const rhs_val = rhs.toFloat(f128); |
| 3045 | return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val)); | 3180 | return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val)); |
| ... | @@ -3053,24 +3188,33 @@ pub const Value = extern union { | ... | @@ -3053,24 +3188,33 @@ pub const Value = extern union { |
| 3053 | rhs: Value, | 3188 | rhs: Value, |
| 3054 | float_type: Type, | 3189 | float_type: Type, |
| 3055 | arena: Allocator, | 3190 | arena: Allocator, |
| | 3191 | target: Target, |
| 3056 | ) !Value { | 3192 | ) !Value { |
| 3057 | switch (float_type.tag()) { | 3193 | switch (float_type.floatBits(target)) { |
| 3058 | .f16 => { | 3194 | 16 => { |
| 3059 | const lhs_val = lhs.toFloat(f16); | 3195 | const lhs_val = lhs.toFloat(f16); |
| 3060 | const rhs_val = rhs.toFloat(f16); | 3196 | const rhs_val = rhs.toFloat(f16); |
| 3061 | return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val)); | 3197 | return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3062 | }, | 3198 | }, |
| 3063 | .f32 => { | 3199 | 32 => { |
| 3064 | const lhs_val = lhs.toFloat(f32); | 3200 | const lhs_val = lhs.toFloat(f32); |
| 3065 | const rhs_val = rhs.toFloat(f32); | 3201 | const rhs_val = rhs.toFloat(f32); |
| 3066 | return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val)); | 3202 | return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val)); |
| 3067 | }, | 3203 | }, |
| 3068 | .f64 => { | 3204 | 64 => { |
| 3069 | const lhs_val = lhs.toFloat(f64); | 3205 | const lhs_val = lhs.toFloat(f64); |
| 3070 | const rhs_val = rhs.toFloat(f64); | 3206 | const rhs_val = rhs.toFloat(f64); |
| 3071 | return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val)); | 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 | const lhs_val = lhs.toFloat(f128); | 3218 | const lhs_val = lhs.toFloat(f128); |
| 3075 | const rhs_val = rhs.toFloat(f128); | 3219 | const rhs_val = rhs.toFloat(f128); |
| 3076 | return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val)); | 3220 | return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val)); |
| ... | @@ -3084,24 +3228,33 @@ pub const Value = extern union { | ... | @@ -3084,24 +3228,33 @@ pub const Value = extern union { |
| 3084 | rhs: Value, | 3228 | rhs: Value, |
| 3085 | float_type: Type, | 3229 | float_type: Type, |
| 3086 | arena: Allocator, | 3230 | arena: Allocator, |
| | 3231 | target: Target, |
| 3087 | ) !Value { | 3232 | ) !Value { |
| 3088 | switch (float_type.tag()) { | 3233 | switch (float_type.floatBits(target)) { |
| 3089 | .f16 => { | 3234 | 16 => { |
| 3090 | const lhs_val = lhs.toFloat(f16); | 3235 | const lhs_val = lhs.toFloat(f16); |
| 3091 | const rhs_val = rhs.toFloat(f16); | 3236 | const rhs_val = rhs.toFloat(f16); |
| 3092 | return Value.Tag.float_16.create(arena, lhs_val * rhs_val); | 3237 | return Value.Tag.float_16.create(arena, lhs_val * rhs_val); |
| 3093 | }, | 3238 | }, |
| 3094 | .f32 => { | 3239 | 32 => { |
| 3095 | const lhs_val = lhs.toFloat(f32); | 3240 | const lhs_val = lhs.toFloat(f32); |
| 3096 | const rhs_val = rhs.toFloat(f32); | 3241 | const rhs_val = rhs.toFloat(f32); |
| 3097 | return Value.Tag.float_32.create(arena, lhs_val * rhs_val); | 3242 | return Value.Tag.float_32.create(arena, lhs_val * rhs_val); |
| 3098 | }, | 3243 | }, |
| 3099 | .f64 => { | 3244 | 64 => { |
| 3100 | const lhs_val = lhs.toFloat(f64); | 3245 | const lhs_val = lhs.toFloat(f64); |
| 3101 | const rhs_val = rhs.toFloat(f64); | 3246 | const rhs_val = rhs.toFloat(f64); |
| 3102 | return Value.Tag.float_64.create(arena, lhs_val * rhs_val); | 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 | const lhs_val = lhs.toFloat(f128); | 3258 | const lhs_val = lhs.toFloat(f128); |
| 3106 | const rhs_val = rhs.toFloat(f128); | 3259 | const rhs_val = rhs.toFloat(f128); |
| 3107 | return Value.Tag.float_128.create(arena, lhs_val * rhs_val); | 3260 | return Value.Tag.float_128.create(arena, lhs_val * rhs_val); |
| ... | @@ -3250,6 +3403,13 @@ pub const Value = extern union { | ... | @@ -3250,6 +3403,13 @@ pub const Value = extern union { |
| 3250 | data: f64, | 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 | pub const Float_128 = struct { | 3413 | pub const Float_128 = struct { |
| 3254 | pub const base_tag = Tag.float_128; | 3414 | pub const base_tag = Tag.float_128; |
| 3255 | | 3415 | |