authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-24 23:52:13-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:22:55-04:00
log94425fe46edb326c38ccf87872b2167bc8f24643
treef1314273ee8bc88729636ef63e7039a31db3f338
parent6021edd7cee104f69c9ceb1af27e46637cab79e3

cbe: improve floating point type support


5 files changed, 186 insertions(+), 181 deletions(-)

lib/include/zig.h+77-62
...@@ -257,56 +257,116 @@ typedef int64_t zig_i64;...@@ -257,56 +257,116 @@ typedef int64_t zig_i64;
257257
258#if FLT_MANT_DIG == 11258#if FLT_MANT_DIG == 11
259typedef float zig_f16;259typedef float zig_f16;
260#define zig_suffix_f16(x) x##f
261#define zig_builtin_f16(name) __builtin_##name##f
260#elif DBL_MANT_DIG == 11262#elif DBL_MANT_DIG == 11
261typedef double zig_f16;263typedef double zig_f16;
264#define zig_suffix_f16(x) x
265#define zig_builtin_f16(name) __builtin_##name
262#elif LDBL_MANT_DIG == 11266#elif LDBL_MANT_DIG == 11
263typedef long double zig_f16;267typedef long double zig_f16;
268#define zig_suffix_f16(x) x##l
269#define zig_builtin_f16(name) __builtin_##name##l
264#elif FLT16_MANT_DIG == 11270#elif FLT16_MANT_DIG == 11
265typedef _Float16 zig_f16;271typedef _Float16 zig_f16;
272#define zig_suffix_f16(x) x##f16
273#define zig_builtin_f16(name) __builtin_##name
274#elif defined(__SIZEOF_FP16__)
275typedef __fp16 zig_f16;
276#define zig_suffix_f16(x) x
277#define zig_builtin_f16(name) __builtin_##name
266#endif278#endif
267279
268#if FLT_MANT_DIG == 24280#if FLT_MANT_DIG == 24
269typedef float zig_f32;281typedef float zig_f32;
282#define zig_suffix_f32(x) x##f
283#define zig_builtin_f32(name) __builtin_##name##f
270#elif DBL_MANT_DIG == 24284#elif DBL_MANT_DIG == 24
271typedef double zig_f32;285typedef double zig_f32;
286#define zig_suffix_f32(x) x
287#define zig_builtin_f32(name) __builtin_##name
272#elif LDBL_MANT_DIG == 24288#elif LDBL_MANT_DIG == 24
273typedef long double zig_f32;289typedef long double zig_f32;
290#define zig_suffix_f32(x) x##l
291#define zig_builtin_f32(name) __builtin_##name##l
274#elif FLT32_MANT_DIG == 24292#elif FLT32_MANT_DIG == 24
275typedef _Float32 zig_f32;293typedef _Float32 zig_f32;
294#define zig_suffix_f32(x) x##f32
295#define zig_builtin_f32(name) __builtin_##name
276#endif296#endif
277297
278#if FLT_MANT_DIG == 53298#if FLT_MANT_DIG == 53
279typedef float zig_f64;299typedef float zig_f64;
300#define zig_suffix_f64(x) x##f
301#define zig_builtin_f64(name) __builtin_##name##f
280#elif DBL_MANT_DIG == 53302#elif DBL_MANT_DIG == 53
281typedef double zig_f64;303typedef double zig_f64;
304#define zig_suffix_f64(x) x
305#define zig_builtin_f64(name) __builtin_##name
282#elif LDBL_MANT_DIG == 53306#elif LDBL_MANT_DIG == 53
283typedef long double zig_f64;307typedef long double zig_f64;
308#define zig_suffix_f64(x) x##l
309#define zig_builtin_f64(name) __builtin_##name##l
284#elif FLT64_MANT_DIG == 53310#elif FLT64_MANT_DIG == 53
285typedef _Float64 zig_f64;311typedef _Float64 zig_f64;
312#define zig_suffix_f64(x) x##f64
313#define zig_builtin_f64(name) __builtin_##name##l
314#elif FLT32X_MANT_DIG == 53
315typedef _Float32x zig_f64;
316#define zig_suffix_f64(x) x##f32x
317#define zig_builtin_f64(name) __builtin_##name##l
286#endif318#endif
287319
288#if FLT_MANT_DIG == 64320#if FLT_MANT_DIG == 64
289typedef float zig_f80;321typedef float zig_f80;
322#define zig_suffix_f80(x) x##f
323#define zig_builtin_f80(name) __builtin_##name##f
290#elif DBL_MANT_DIG == 64324#elif DBL_MANT_DIG == 64
291typedef double zig_f80;325typedef double zig_f80;
326#define zig_suffix_f80(x) x
327#define zig_builtin_f80(name) __builtin_##name
292#elif LDBL_MANT_DIG == 64328#elif LDBL_MANT_DIG == 64
293typedef long double zig_f80;329typedef long double zig_f80;
330#define zig_suffix_f80(x) x##l
331#define zig_builtin_f80(name) __builtin_##name##l
294#elif FLT80_MANT_DIG == 64332#elif FLT80_MANT_DIG == 64
295typedef _Float80 zig_f80;333typedef _Float80 zig_f80;
334#define zig_suffix_f80(x) x##f80
335#define zig_builtin_f80(name) __builtin_##name##l
336#elif FLT64X_MANT_DIG == 64
337typedef _Float64x zig_f80;
338#define zig_suffix_f80(x) x##f64x
339#define zig_builtin_f80(name) __builtin_##name##l
296#elif defined(__SIZEOF_FLOAT80__)340#elif defined(__SIZEOF_FLOAT80__)
297typedef __float80 zig_f80;341typedef __float80 zig_f80;
342#define zig_suffix_f80(x) x##l
343#define zig_builtin_f80(name) __builtin_##name##l
298#endif344#endif
299345
300#if FLT_MANT_DIG == 113346#if FLT_MANT_DIG == 113
301typedef float zig_f128;347typedef float zig_f128;
348#define zig_suffix_f128(x) x##f
349#define zig_builtin_f128(name) __builtin_##name##f
302#elif DBL_MANT_DIG == 113350#elif DBL_MANT_DIG == 113
303typedef double zig_f128;351typedef double zig_f128;
352#define zig_suffix_f128(x) x
353#define zig_builtin_f128(name) __builtin_##name
304#elif LDBL_MANT_DIG == 113354#elif LDBL_MANT_DIG == 113
305typedef long double zig_f128;355typedef long double zig_f128;
356#define zig_suffix_f128(x) x##l
357#define zig_builtin_f128(name) __builtin_##name##l
306#elif FLT128_MANT_DIG == 113358#elif FLT128_MANT_DIG == 113
307typedef _Float128 zig_f128;359typedef _Float128 zig_f128;
360#define zig_suffix_f128(x) x##f128
361#define zig_builtin_f128(name) __builtin_##name##l
362#elif FLT64X_MANT_DIG == 113
363typedef _Float64x zig_f128;
364#define zig_suffix_f128(x) x##f64x
365#define zig_builtin_f128(name) __builtin_##name##l
308#elif defined(__SIZEOF_FLOAT128__)366#elif defined(__SIZEOF_FLOAT128__)
309typedef __float128 zig_f128;367typedef __float128 zig_f128;
368#define zig_suffix_f128(x) x##l
369#define zig_builtin_f128(name) __builtin_##name##l
310#endif370#endif
311371
312zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);372zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);
...@@ -1416,65 +1476,20 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) {...@@ -1416,65 +1476,20 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) {
14161476
1417/* ========================== Float Point Routines ========================== */1477/* ========================== Float Point Routines ========================== */
14181478
1419static inline zig_f32 zig_bitcast_f32_u32(zig_u32 arg) {1479#define zig_float_builtins(w) \
1420 zig_f32 dest;1480 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
1421 memcpy(&dest, &arg, sizeof dest);1481 return zig_builtin_f##w(trunc)(lhs / rhs); \
1422 return dest;1482 } \
1423}1483\
14241484 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \
1425static inline zig_f64 zig_bitcast_f64_u64(zig_u64 arg) {1485 return zig_builtin_f##w(floor)(lhs / rhs); \
1426 zig_f64 dest;1486 } \
1427 memcpy(&dest, &arg, sizeof dest);1487\
1428 return dest;1488 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
1429}1489 return lhs - zig_div_floor_f##w(lhs, rhs) * rhs; \
14301490 }
1431static inline float zig_div_truncf(float numerator, float denominator) {1491zig_float_builtins(16)
1432 return __builtin_truncf(numerator / denominator);1492zig_float_builtins(32)
1433}1493zig_float_builtins(64)
14341494zig_float_builtins(80)
1435static inline double zig_div_trunc(double numerator, double denominator) {1495zig_float_builtins(128)
1436 return __builtin_trunc(numerator / denominator);
1437}
1438
1439static inline long double zig_div_truncl(long double numerator, long double denominator) {
1440 return __builtin_truncf(numerator / denominator);
1441}
1442
1443#define zig_div_trunc_f16 zig_div_truncf
1444#define zig_div_trunc_f32 zig_div_truncf
1445#define zig_div_trunc_f64 zig_div_trunc
1446#define zig_div_trunc_f80 zig_div_truncl
1447#define zig_div_trunc_f128 zig_div_truncl
1448
1449#define zig_div_floorf(numerator, denominator) \
1450 __builtin_floorf((float)(numerator) / (float)(denominator))
1451
1452#define zig_div_floor(numerator, denominator) \
1453 __builtin_floor((double)(numerator) / (double)(denominator))
1454
1455#define zig_div_floorl(numerator, denominator) \
1456 __builtin_floorl((long double)(numerator) / (long double)(denominator))
1457
1458#define zig_div_floor_f16 zig_div_floorf
1459#define zig_div_floor_f32 zig_div_floorf
1460#define zig_div_floor_f64 zig_div_floor
1461#define zig_div_floor_f80 zig_div_floorl
1462#define zig_div_floor_f128 zig_div_floorl
1463
1464static inline float zig_modf(float numerator, float denominator) {
1465 return (numerator - (zig_div_floorf(numerator, denominator) * denominator));
1466}
1467
1468static inline double zig_mod(double numerator, double denominator) {
1469 return (numerator - (zig_div_floor(numerator, denominator) * denominator));
1470}
1471
1472static inline long double zig_modl(long double numerator, long double denominator) {
1473 return (numerator - (zig_div_floorl(numerator, denominator) * denominator));
1474}
1475
1476#define zig_mod_f16 zig_modf
1477#define zig_mod_f32 zig_modf
1478#define zig_mod_f64 zig_mod
1479#define zig_mod_f80 zig_modl
1480#define zig_mod_f128 zig_modl
src/codegen/c.zig+109-114
...@@ -367,54 +367,6 @@ pub const Function = struct {...@@ -367,54 +367,6 @@ pub const Function = struct {
367 fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {367 fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
368 return f.object.dg.fmtIntLiteral(ty, val);368 return f.object.dg.fmtIntLiteral(ty, val);
369 }369 }
370
371 fn renderTypeForBuiltinFnName(f: *Function, writer: anytype, ty: Type) !void {
372 const target = f.object.dg.module.getTarget();
373 const c_bits = if (ty.isAbiInt()) c_bits: {
374 const int_info = ty.intInfo(target);
375 try writer.writeByte(signAbbrev(int_info.signedness));
376 break :c_bits toCIntBits(int_info.bits) orelse
377 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
378 } else if (ty.isRuntimeFloat()) c_bits: {
379 try writer.writeByte('f');
380 break :c_bits ty.floatBits(target);
381 } else return f.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
382 ty.fmt(f.object.dg.module),
383 });
384 try writer.print("{d}", .{c_bits});
385 }
386
387 fn renderBuiltinInfo(f: *Function, writer: anytype, ty: Type, info: BuiltinInfo) !void {
388 const target = f.object.dg.module.getTarget();
389 switch (info) {
390 .None => {},
391 .Range => {
392 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
393 defer arena.deinit();
394
395 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
396 var stack align(@alignOf(ExpectedContents)) =
397 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
398
399 const int_info = ty.intInfo(target);
400 if (int_info.signedness == .signed) {
401 const min_val = try ty.minInt(stack.get(), target);
402 try writer.print(", {x}", .{try f.object.dg.fmtIntLiteral(ty, min_val)});
403 }
404
405 const max_val = try ty.maxInt(stack.get(), target);
406 try writer.print(", {x}", .{try f.object.dg.fmtIntLiteral(ty, max_val)});
407 },
408 .Bits => {
409 var bits_pl = Value.Payload.U64{
410 .base = .{ .tag = .int_u64 },
411 .data = ty.bitSize(target),
412 };
413 const bits_val = Value.initPayload(&bits_pl.base);
414 try writer.print(", {}", .{try f.object.dg.fmtIntLiteral(Type.u8, bits_val)});
415 },
416 }
417 }
418};370};
419371
420/// This data is available when outputting .c code for a `Module`.372/// This data is available when outputting .c code for a `Module`.
...@@ -657,15 +609,18 @@ pub const DeclGen = struct {...@@ -657,15 +609,18 @@ pub const DeclGen = struct {
657 .Float => {609 .Float => {
658 try writer.writeByte('(');610 try writer.writeByte('(');
659 try dg.renderTypecast(writer, ty);611 try dg.renderTypecast(writer, ty);
660 try writer.writeByte(')');612 try writer.writeAll(")zig_suffix_");
613 try dg.renderTypeForBuiltinFnName(writer, ty);
614 try writer.writeByte('(');
661 switch (ty.floatBits(target)) {615 switch (ty.floatBits(target)) {
662 16 => return writer.print("{x}f", .{@bitCast(f16, undefPattern(u16))}),616 16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(u16))}),
663 32 => return writer.print("{x}f", .{@bitCast(f32, undefPattern(u32))}),617 32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(u32))}),
664 64 => return writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}),618 64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}),
665 80 => return writer.print("{x}l", .{@bitCast(f80, undefPattern(u80))}),619 80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(u80))}),
666 128 => return writer.print("{x}l", .{@bitCast(f128, undefPattern(u128))}),620 128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(u128))}),
667 else => unreachable,621 else => unreachable,
668 }622 }
623 return writer.writeByte(')');
669 },624 },
670 .Pointer => switch (ty.ptrSize()) {625 .Pointer => switch (ty.ptrSize()) {
671 .Slice => {626 .Slice => {
...@@ -821,9 +776,21 @@ pub const DeclGen = struct {...@@ -821,9 +776,21 @@ pub const DeclGen = struct {
821 try dg.renderTypecast(writer, ty);776 try dg.renderTypecast(writer, ty);
822 try writer.writeByte(')');777 try writer.writeByte(')');
823 const f128_val = val.toFloat(f128);778 const f128_val = val.toFloat(f128);
824 if (!std.math.isFinite(f128_val)) {779 if (std.math.signbit(f128_val)) try writer.writeByte('-');
825 if (std.math.signbit(f128_val)) try writer.writeByte('-');780 if (std.math.isFinite(f128_val)) {
826 const fn_name = if (std.math.isSignalNan(f128_val))781 try writer.writeAll("zig_suffix_");
782 try dg.renderTypeForBuiltinFnName(writer, ty);
783 try writer.writeByte('(');
784 switch (ty.floatBits(target)) {
785 16 => try writer.print("{x}", .{@fabs(val.toFloat(f16))}),
786 32 => try writer.print("{x}", .{@fabs(val.toFloat(f32))}),
787 64 => try writer.print("{x}", .{@fabs(val.toFloat(f64))}),
788 80 => try writer.print("{x}", .{@fabs(val.toFloat(f80))}),
789 128 => try writer.print("{x}", .{@fabs(f128_val)}),
790 else => unreachable,
791 }
792 } else {
793 const operation = if (std.math.isSignalNan(f128_val))
827 "nans"794 "nans"
828 else if (std.math.isNan(f128_val))795 else if (std.math.isNan(f128_val))
829 "nan"796 "nan"
...@@ -831,27 +798,23 @@ pub const DeclGen = struct {...@@ -831,27 +798,23 @@ pub const DeclGen = struct {
831 "inf"798 "inf"
832 else799 else
833 unreachable;800 unreachable;
834 try dg.renderFloatFnName(writer, fn_name, ty);801 try writer.writeAll("zig_builtin_");
802 try dg.renderTypeForBuiltinFnName(writer, ty);
835 try writer.writeByte('(');803 try writer.writeByte('(');
804 try writer.writeAll(operation);
805 try writer.writeAll(")(");
836 if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) {806 if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) {
837 // We only actually need to pass the significant, but it will get807 // We only actually need to pass the significand, but it will get
838 // properly masked anyway, so just pass the whole value.808 // properly masked anyway, so just pass the whole value.
839 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, val.toFloat(f16))}),809 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, @fabs(val.toFloat(f16)))}),
840 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, val.toFloat(f32))}),810 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, @fabs(val.toFloat(f32)))}),
841 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, val.toFloat(f64))}),811 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, @fabs(val.toFloat(f64)))}),
842 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, val.toFloat(f80))}),812 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, @fabs(val.toFloat(f80)))}),
843 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, f128_val)}),813 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, @fabs(f128_val))}),
844 else => unreachable,814 else => unreachable,
845 };815 };
846 return writer.writeByte(')');
847 } else switch (ty.floatBits(target)) {
848 16 => return writer.print("{x}f", .{val.toFloat(f16)}),
849 32 => return writer.print("{x}f", .{val.toFloat(f32)}),
850 64 => return writer.print("{x}", .{val.toFloat(f64)}),
851 80 => return writer.print("{x}l", .{val.toFloat(f80)}),
852 128 => return writer.print("{x}l", .{f128_val}),
853 else => unreachable,
854 }816 }
817 return writer.writeByte(')');
855 },818 },
856 .Pointer => switch (val.tag()) {819 .Pointer => switch (val.tag()) {
857 .null_value, .zero => {820 .null_value, .zero => {
...@@ -2041,23 +2004,51 @@ pub const DeclGen = struct {...@@ -2041,23 +2004,51 @@ pub const DeclGen = struct {
2041 }2004 }
2042 }2005 }
20432006
2044 fn renderFloatFnName(dg: *DeclGen, writer: anytype, operation: []const u8, float_ty: Type) !void {2007 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
2045 const target = dg.module.getTarget();2008 const target = dg.module.getTarget();
2046 const float_bits = float_ty.floatBits(target);2009 const c_bits = if (ty.isAbiInt()) c_bits: {
2047 const is_longdouble = float_bits == CType.longdouble.sizeInBits(target);2010 const int_info = ty.intInfo(target);
2048 try writer.writeAll("__");2011 try writer.writeByte(signAbbrev(int_info.signedness));
2049 if (is_longdouble or float_bits != 80) {2012 break :c_bits toCIntBits(int_info.bits) orelse
2050 try writer.writeAll("builtin_");2013 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
2051 }2014 } else if (ty.isRuntimeFloat()) c_bits: {
2052 try writer.writeAll(operation);2015 try writer.writeByte('f');
2053 if (is_longdouble) {2016 break :c_bits ty.floatBits(target);
2054 try writer.writeByte('l');2017 } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
2055 } else switch (float_bits) {2018 ty.fmt(dg.module),
2056 16, 32 => try writer.writeByte('f'),2019 });
2057 64 => {},2020 try writer.print("{d}", .{c_bits});
2058 80 => try writer.writeByte('x'),2021 }
2059 128 => try writer.writeByte('q'),2022
2060 else => unreachable,2023 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {
2024 const target = dg.module.getTarget();
2025 switch (info) {
2026 .None => {},
2027 .Range => {
2028 var arena = std.heap.ArenaAllocator.init(dg.gpa);
2029 defer arena.deinit();
2030
2031 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
2032 var stack align(@alignOf(ExpectedContents)) =
2033 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
2034
2035 const int_info = ty.intInfo(target);
2036 if (int_info.signedness == .signed) {
2037 const min_val = try ty.minInt(stack.get(), target);
2038 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val)});
2039 }
2040
2041 const max_val = try ty.maxInt(stack.get(), target);
2042 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val)});
2043 },
2044 .Bits => {
2045 var bits_pl = Value.Payload.U64{
2046 .base = .{ .tag = .int_u64 },
2047 .data = ty.bitSize(target),
2048 };
2049 const bits_val = Value.initPayload(&bits_pl.base);
2050 try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val)});
2051 },
2061 }2052 }
2062 }2053 }
20632054
...@@ -2760,15 +2751,15 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2760,15 +2751,15 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2760 try writer.writeAll(" = (");2751 try writer.writeAll(" = (");
2761 try f.renderTypecast(writer, inst_ty);2752 try f.renderTypecast(writer, inst_ty);
2762 try writer.writeAll(")zig_wrap_");2753 try writer.writeAll(")zig_wrap_");
2763 try f.renderTypeForBuiltinFnName(writer, field_ty);2754 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);
2764 try writer.writeAll("((");2755 try writer.writeAll("((");
2765 try f.renderTypecast(writer, field_ty);2756 try f.renderTypecast(writer, field_ty);
2766 try writer.writeAll(")zig_shr_");2757 try writer.writeAll(")zig_shr_");
2767 try f.renderTypeForBuiltinFnName(writer, host_ty);2758 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
2768 try writer.writeByte('(');2759 try writer.writeByte('(');
2769 try f.writeCValueDeref(writer, operand);2760 try f.writeCValueDeref(writer, operand);
2770 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});2761 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
2771 try f.renderBuiltinInfo(writer, field_ty, .Bits);2762 try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits);
2772 try writer.writeByte(')');2763 try writer.writeByte(')');
2773 } else {2764 } else {
2774 try writer.writeAll(" = ");2765 try writer.writeAll(" = ");
...@@ -2998,13 +2989,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2998,13 +2989,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
29982989
2999 try f.writeCValueDeref(writer, ptr_val);2990 try f.writeCValueDeref(writer, ptr_val);
3000 try writer.writeAll(" = zig_or_");2991 try writer.writeAll(" = zig_or_");
3001 try f.renderTypeForBuiltinFnName(writer, host_ty);2992 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3002 try writer.writeAll("(zig_and_");2993 try writer.writeAll("(zig_and_");
3003 try f.renderTypeForBuiltinFnName(writer, host_ty);2994 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3004 try writer.writeByte('(');2995 try writer.writeByte('(');
3005 try f.writeCValueDeref(writer, ptr_val);2996 try f.writeCValueDeref(writer, ptr_val);
3006 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});2997 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
3007 try f.renderTypeForBuiltinFnName(writer, host_ty);2998 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3008 try writer.writeAll("((");2999 try writer.writeAll("((");
3009 try f.renderTypecast(writer, host_ty);3000 try f.renderTypecast(writer, host_ty);
3010 try writer.writeByte(')');3001 try writer.writeByte(')');
...@@ -3040,14 +3031,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3040,14 +3031,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3040 try w.writeAll(".field_1 = zig_");3031 try w.writeAll(".field_1 = zig_");
3041 try w.writeAll(operation);3032 try w.writeAll(operation);
3042 try w.writeAll("o_");3033 try w.writeAll("o_");
3043 try f.renderTypeForBuiltinFnName(w, scalar_ty);3034 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3044 try w.writeAll("(&");3035 try w.writeAll("(&");
3045 try f.writeCValueMember(w, local, .{ .identifier = "field_0" });3036 try f.writeCValueMember(w, local, .{ .identifier = "field_0" });
3046 try w.writeAll(", ");3037 try w.writeAll(", ");
3047 try f.writeCValue(w, lhs, .FunctionArgument);3038 try f.writeCValue(w, lhs, .FunctionArgument);
3048 try w.writeAll(", ");3039 try w.writeAll(", ");
3049 try f.writeCValue(w, rhs, .FunctionArgument);3040 try f.writeCValue(w, rhs, .FunctionArgument);
3050 try f.renderBuiltinInfo(w, scalar_ty, info);3041 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
3051 try w.writeAll(");\n");3042 try w.writeAll(");\n");
3052 return local;3043 return local;
3053}3044}
...@@ -4217,17 +4208,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4217,17 +4208,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
42174208
4218 const temp_local = try f.allocLocal(field_int_ty, .Const);4209 const temp_local = try f.allocLocal(field_int_ty, .Const);
4219 try writer.writeAll(" = zig_wrap_");4210 try writer.writeAll(" = zig_wrap_");
4220 try f.renderTypeForBuiltinFnName(writer, field_int_ty);4211 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
4221 try writer.writeAll("((");4212 try writer.writeAll("((");
4222 try f.renderTypecast(writer, field_int_ty);4213 try f.renderTypecast(writer, field_int_ty);
4223 try writer.writeAll(")zig_shr_");4214 try writer.writeAll(")zig_shr_");
4224 try f.renderTypeForBuiltinFnName(writer, struct_ty);4215 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
4225 try writer.writeByte('(');4216 try writer.writeByte('(');
4226 try f.writeCValue(writer, struct_byval, .Other);4217 try f.writeCValue(writer, struct_byval, .Other);
4227 try writer.writeAll(", ");4218 try writer.writeAll(", ");
4228 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);4219 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
4229 try writer.writeByte(')');4220 try writer.writeByte(')');
4230 try f.renderBuiltinInfo(writer, field_int_ty, .Bits);4221 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits);
4231 try writer.writeAll(");\n");4222 try writer.writeAll(");\n");
4232 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;4223 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
42334224
...@@ -4567,10 +4558,10 @@ fn airUnBuiltinCall(...@@ -4567,10 +4558,10 @@ fn airUnBuiltinCall(
4567 try writer.writeAll(" = zig_");4558 try writer.writeAll(" = zig_");
4568 try writer.writeAll(operation);4559 try writer.writeAll(operation);
4569 try writer.writeByte('_');4560 try writer.writeByte('_');
4570 try f.renderTypeForBuiltinFnName(writer, operand_ty);4561 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
4571 try writer.writeByte('(');4562 try writer.writeByte('(');
4572 try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument);4563 try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument);
4573 try f.renderBuiltinInfo(writer, operand_ty, info);4564 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
4574 try writer.writeAll(");\n");4565 try writer.writeAll(");\n");
4575 return local;4566 return local;
4576}4567}
...@@ -4592,12 +4583,12 @@ fn airBinBuiltinCall(...@@ -4592,12 +4583,12 @@ fn airBinBuiltinCall(
4592 try writer.writeAll(" = zig_");4583 try writer.writeAll(" = zig_");
4593 try writer.writeAll(operation);4584 try writer.writeAll(operation);
4594 try writer.writeByte('_');4585 try writer.writeByte('_');
4595 try f.renderTypeForBuiltinFnName(writer, operand_ty);4586 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
4596 try writer.writeByte('(');4587 try writer.writeByte('(');
4597 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);4588 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
4598 try writer.writeAll(", ");4589 try writer.writeAll(", ");
4599 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);4590 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
4600 try f.renderBuiltinInfo(writer, operand_ty, info);4591 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
4601 try writer.writeAll(");\n");4592 try writer.writeAll(");\n");
4602 return local;4593 return local;
4603}4594}
...@@ -4612,7 +4603,7 @@ fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !...@@ -4612,7 +4603,7 @@ fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !
4612 const local = try f.allocLocal(inst_ty, .Const);4603 const local = try f.allocLocal(inst_ty, .Const);
4613 const writer = f.object.writer();4604 const writer = f.object.writer();
4614 try writer.writeAll(" = zig_cmp_");4605 try writer.writeAll(" = zig_cmp_");
4615 try f.renderTypeForBuiltinFnName(writer, operand_ty);4606 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
4616 try writer.writeByte('(');4607 try writer.writeByte('(');
4617 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);4608 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
4618 try writer.writeAll(", ");4609 try writer.writeAll(", ");
...@@ -5027,7 +5018,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5027,7 +5018,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
50275018
5028 if (!empty) {5019 if (!empty) {
5029 try writer.writeAll("zig_or_");5020 try writer.writeAll("zig_or_");
5030 try f.renderTypeForBuiltinFnName(writer, inst_ty);5021 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5031 try writer.writeByte('(');5022 try writer.writeByte('(');
5032 }5023 }
5033 empty = false;5024 empty = false;
...@@ -5039,14 +5030,14 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5039,14 +5030,14 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
50395030
5040 if (!empty) try writer.writeAll(", ");5031 if (!empty) try writer.writeAll(", ");
5041 try writer.writeAll("zig_shlw_");5032 try writer.writeAll("zig_shlw_");
5042 try f.renderTypeForBuiltinFnName(writer, inst_ty);5033 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5043 try writer.writeAll("((");5034 try writer.writeAll("((");
5044 try f.renderTypecast(writer, inst_ty);5035 try f.renderTypecast(writer, inst_ty);
5045 try writer.writeByte(')');5036 try writer.writeByte(')');
5046 try f.writeCValue(writer, try f.resolveInst(element), .Other);5037 try f.writeCValue(writer, try f.resolveInst(element), .Other);
5047 try writer.writeAll(", ");5038 try writer.writeAll(", ");
5048 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);5039 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5049 try f.renderBuiltinInfo(writer, inst_ty, .Bits);5040 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);
5050 try writer.writeByte(')');5041 try writer.writeByte(')');
5051 if (!empty) try writer.writeByte(')');5042 if (!empty) try writer.writeByte(')');
50525043
...@@ -5176,9 +5167,11 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal...@@ -5176,9 +5167,11 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
5176 const inst_ty = f.air.typeOfIndex(inst);5167 const inst_ty = f.air.typeOfIndex(inst);
5177 const operand = try f.resolveInst(un_op);5168 const operand = try f.resolveInst(un_op);
5178 const local = try f.allocLocal(inst_ty, .Const);5169 const local = try f.allocLocal(inst_ty, .Const);
5179 try writer.writeAll(" = ");5170 try writer.writeAll(" = zig_builtin_");
5180 try f.object.dg.renderFloatFnName(writer, operation, inst_ty);5171 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5181 try writer.writeByte('(');5172 try writer.writeByte('(');
5173 try writer.writeAll(operation);
5174 try writer.writeAll(")(");
5182 try f.writeCValue(writer, operand, .FunctionArgument);5175 try f.writeCValue(writer, operand, .FunctionArgument);
5183 try writer.writeAll(");\n");5176 try writer.writeAll(");\n");
5184 return local;5177 return local;
...@@ -5192,9 +5185,11 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -5192,9 +5185,11 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
5192 const lhs = try f.resolveInst(bin_op.lhs);5185 const lhs = try f.resolveInst(bin_op.lhs);
5193 const rhs = try f.resolveInst(bin_op.rhs);5186 const rhs = try f.resolveInst(bin_op.rhs);
5194 const local = try f.allocLocal(inst_ty, .Const);5187 const local = try f.allocLocal(inst_ty, .Const);
5195 try writer.writeAll(" = ");5188 try writer.writeAll(" = zig_builtin_");
5196 try f.object.dg.renderFloatFnName(writer, operation, inst_ty);5189 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5197 try writer.writeByte('(');5190 try writer.writeByte('(');
5191 try writer.writeAll(operation);
5192 try writer.writeAll(")(");
5198 try f.writeCValue(writer, lhs, .FunctionArgument);5193 try f.writeCValue(writer, lhs, .FunctionArgument);
5199 try writer.writeAll(", ");5194 try writer.writeAll(", ");
5200 try f.writeCValue(writer, rhs, .FunctionArgument);5195 try f.writeCValue(writer, rhs, .FunctionArgument);
...@@ -5212,9 +5207,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5212,9 +5207,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
5212 const addend = try f.resolveInst(pl_op.operand);5207 const addend = try f.resolveInst(pl_op.operand);
5213 const writer = f.object.writer();5208 const writer = f.object.writer();
5214 const local = try f.allocLocal(inst_ty, .Const);5209 const local = try f.allocLocal(inst_ty, .Const);
5215 try writer.writeAll(" = ");5210 try writer.writeAll(" = zig_builtin_");
5216 try f.object.dg.renderFloatFnName(writer, "fma", inst_ty);5211 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5217 try writer.writeByte('(');5212 try writer.writeAll("(fma)(");
5218 try f.writeCValue(writer, mulend1, .FunctionArgument);5213 try f.writeCValue(writer, mulend1, .FunctionArgument);
5219 try writer.writeAll(", ");5214 try writer.writeAll(", ");
5220 try f.writeCValue(writer, mulend2, .FunctionArgument);5215 try f.writeCValue(writer, mulend2, .FunctionArgument);
test/behavior/floatop.zig-2
...@@ -670,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {...@@ -670,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
670 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO670 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
671 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO671 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
672 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO672 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
673 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
674673
675 inline for (.{ f16, f32, f64, f80, f128 }) |F| {674 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
676 try expect(math.isNan(@as(F, 0) / @as(F, 0)));675 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
...@@ -763,7 +762,6 @@ test "nan negation f128" {...@@ -763,7 +762,6 @@ test "nan negation f128" {
763 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO762 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
764 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO763 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
765 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO764 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
766 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
767765
768 const nan_comptime = comptime math.nan(f128);766 const nan_comptime = comptime math.nan(f128);
769 const neg_nan_comptime = -nan_comptime;767 const neg_nan_comptime = -nan_comptime;
test/behavior/math.zig-2
...@@ -1146,7 +1146,6 @@ test "comptime float rem int" {...@@ -1146,7 +1146,6 @@ test "comptime float rem int" {
11461146
1147test "remainder division" {1147test "remainder division" {
1148 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1148 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1149 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1150 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1150 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1151 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1294,7 +1293,6 @@ test "@fabs" {...@@ -1294,7 +1293,6 @@ test "@fabs" {
1294 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1293 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1295 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1296 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1295 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1297 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12981296
1299 try testFabs(f128, 12.0);1297 try testFabs(f128, 12.0);
1300 comptime try testFabs(f128, 12.0);1298 comptime try testFabs(f128, 12.0);
test/behavior/muladd.zig-1
...@@ -62,7 +62,6 @@ fn testMulAdd80() !void {...@@ -62,7 +62,6 @@ fn testMulAdd80() !void {
62}62}
6363
64test "@mulAdd f128" {64test "@mulAdd f128" {
65 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO65 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
67 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO66 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO