From e20d2b3151607fe078b43331ea27d5b34f95360b Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Tue, 25 Oct 2022 07:00:17 -0400 Subject: [PATCH] cbe: fix floating point builtins --- lib/include/zig.h | 90 +++++++++++++++++++++++------------------- src/codegen/c.zig | 20 +++++----- test/behavior/cast.zig | 1 - test/behavior/math.zig | 13 ------ 4 files changed, 59 insertions(+), 65 deletions(-) diff --git a/lib/include/zig.h b/lib/include/zig.h index b64e157b98..95c7b8b4b3 100644 --- a/lib/include/zig.h +++ b/lib/include/zig.h @@ -216,7 +216,6 @@ typedef signed long int zig_c_long; typedef unsigned long int zig_c_ulong; typedef signed long long int zig_c_longlong; typedef unsigned long long int zig_c_ulonglong; -typedef long double zig_c_longdouble; typedef uint8_t zig_u8; typedef int8_t zig_i8; @@ -255,120 +254,111 @@ typedef int64_t zig_i64; #define zig_minInt_i64 INT64_MIN #define zig_maxInt_i64 INT64_MAX +#define zig_builtin_f16(name) __##name##h +#define zig_builtin_constant_f16(name) zig_suffix_f16(__builtin_##name) #if FLT_MANT_DIG == 11 typedef float zig_f16; #define zig_suffix_f16(x) x##f -#define zig_builtin_f16(name) __builtin_##name##f #elif DBL_MANT_DIG == 11 typedef double zig_f16; #define zig_suffix_f16(x) x -#define zig_builtin_f16(name) __builtin_##name #elif LDBL_MANT_DIG == 11 typedef long double zig_f16; #define zig_suffix_f16(x) x##l -#define zig_builtin_f16(name) __builtin_##name##l #elif FLT16_MANT_DIG == 11 typedef _Float16 zig_f16; #define zig_suffix_f16(x) x##f16 -#define zig_builtin_f16(name) __builtin_##name #elif defined(__SIZEOF_FP16__) typedef __fp16 zig_f16; -#define zig_suffix_f16(x) x -#define zig_builtin_f16(name) __builtin_##name +#define zig_suffix_f16(x) x##f16 #endif +#define zig_builtin_f32(name) name##f +#define zig_builtin_constant_f32(name) zig_suffix_f32(__builtin_##name) #if FLT_MANT_DIG == 24 typedef float zig_f32; #define zig_suffix_f32(x) x##f -#define zig_builtin_f32(name) __builtin_##name##f #elif DBL_MANT_DIG == 24 typedef double zig_f32; #define zig_suffix_f32(x) x -#define zig_builtin_f32(name) __builtin_##name #elif LDBL_MANT_DIG == 24 typedef long double zig_f32; #define zig_suffix_f32(x) x##l -#define zig_builtin_f32(name) __builtin_##name##l #elif FLT32_MANT_DIG == 24 typedef _Float32 zig_f32; #define zig_suffix_f32(x) x##f32 -#define zig_builtin_f32(name) __builtin_##name #endif +#define zig_builtin_f64(name) name +#define zig_builtin_constant_f64(name) zig_suffix_f64(__builtin_##name) #if FLT_MANT_DIG == 53 typedef float zig_f64; #define zig_suffix_f64(x) x##f -#define zig_builtin_f64(name) __builtin_##name##f #elif DBL_MANT_DIG == 53 typedef double zig_f64; #define zig_suffix_f64(x) x -#define zig_builtin_f64(name) __builtin_##name #elif LDBL_MANT_DIG == 53 typedef long double zig_f64; #define zig_suffix_f64(x) x##l -#define zig_builtin_f64(name) __builtin_##name##l #elif FLT64_MANT_DIG == 53 typedef _Float64 zig_f64; #define zig_suffix_f64(x) x##f64 -#define zig_builtin_f64(name) __builtin_##name##l #elif FLT32X_MANT_DIG == 53 typedef _Float32x zig_f64; #define zig_suffix_f64(x) x##f32x -#define zig_builtin_f64(name) __builtin_##name##l #endif +#define zig_builtin_f80(name) __##name##x +#define zig_builtin_constant_f80(name) zig_suffix_f80(__builtin_##name) #if FLT_MANT_DIG == 64 typedef float zig_f80; #define zig_suffix_f80(x) x##f -#define zig_builtin_f80(name) __builtin_##name##f #elif DBL_MANT_DIG == 64 typedef double zig_f80; #define zig_suffix_f80(x) x -#define zig_builtin_f80(name) __builtin_##name #elif LDBL_MANT_DIG == 64 typedef long double zig_f80; #define zig_suffix_f80(x) x##l -#define zig_builtin_f80(name) __builtin_##name##l #elif FLT80_MANT_DIG == 64 typedef _Float80 zig_f80; #define zig_suffix_f80(x) x##f80 -#define zig_builtin_f80(name) __builtin_##name##l #elif FLT64X_MANT_DIG == 64 typedef _Float64x zig_f80; #define zig_suffix_f80(x) x##f64x -#define zig_builtin_f80(name) __builtin_##name##l #elif defined(__SIZEOF_FLOAT80__) typedef __float80 zig_f80; #define zig_suffix_f80(x) x##l -#define zig_builtin_f80(name) __builtin_##name##l #endif +#define zig_builtin_f128(name) name##q +#define zig_builtin_constant_f128(name) zig_suffix_f80(__builtin_##name) #if FLT_MANT_DIG == 113 typedef float zig_f128; #define zig_suffix_f128(x) x##f -#define zig_builtin_f128(name) __builtin_##name##f #elif DBL_MANT_DIG == 113 typedef double zig_f128; #define zig_suffix_f128(x) x -#define zig_builtin_f128(name) __builtin_##name #elif LDBL_MANT_DIG == 113 typedef long double zig_f128; #define zig_suffix_f128(x) x##l -#define zig_builtin_f128(name) __builtin_##name##l #elif FLT128_MANT_DIG == 113 typedef _Float128 zig_f128; #define zig_suffix_f128(x) x##f128 -#define zig_builtin_f128(name) __builtin_##name##l #elif FLT64X_MANT_DIG == 113 typedef _Float64x zig_f128; #define zig_suffix_f128(x) x##f64x -#define zig_builtin_f128(name) __builtin_##name##l #elif defined(__SIZEOF_FLOAT128__) typedef __float128 zig_f128; -#define zig_suffix_f128(x) x##l -#define zig_builtin_f128(name) __builtin_##name##l +#define zig_suffix_f128(x) x##q +#undef zig_builtin_constant_f128 +#define zig_builtin_constant_f128(name) __builtin_##name##f128 #endif +typedef long double zig_c_longdouble; +#define zig_suffix_c_longdouble(x) x##l +#define zig_builtin_c_longdouble(name) zig_suffix_c_longdouble(name) +#define zig_builtin_constant_c_longdouble(name) zig_suffix_c_longdouble(__builtin_##name) + zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize); zig_extern_c void *memset (void *, int, zig_usize); @@ -1476,20 +1466,38 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { /* ========================== Float Point Routines ========================== */ -#define zig_float_builtins(w) \ - static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ - return zig_builtin_f##w(trunc)(lhs / rhs); \ +#define zig_float_builtins(Type) \ + zig_extern_c zig_##Type zig_builtin_##Type(sqrt)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(sin)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(cos)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(tan)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(exp)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(exp2)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(log)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(log2)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(log10)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(fabs)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(floor)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(ceil)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(round)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(trunc)(zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(fmod)(zig_##Type, zig_##Type); \ + zig_extern_c zig_##Type zig_builtin_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \ +\ + static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \ + return zig_builtin_##Type(trunc)(lhs / rhs); \ } \ \ - static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \ - return zig_builtin_f##w(floor)(lhs / rhs); \ + static inline zig_##Type zig_div_floor_##Type(zig_##Type lhs, zig_##Type rhs) { \ + return zig_builtin_##Type(floor)(lhs / rhs); \ } \ \ - static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ - return lhs - zig_div_floor_f##w(lhs, rhs) * rhs; \ + static inline zig_##Type zig_mod_##Type(zig_##Type lhs, zig_##Type rhs) { \ + return lhs - zig_div_floor_##Type(lhs, rhs) * rhs; \ } -zig_float_builtins(16) -zig_float_builtins(32) -zig_float_builtins(64) -zig_float_builtins(80) -zig_float_builtins(128) +zig_float_builtins(f16) +zig_float_builtins(f32) +zig_float_builtins(f64) +zig_float_builtins(f80) +zig_float_builtins(f128) +zig_float_builtins(c_longdouble) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 74a4fb178a..098424524f 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -798,7 +798,7 @@ pub const DeclGen = struct { "inf" else unreachable; - try writer.writeAll("zig_builtin_"); + try writer.writeAll("zig_builtin_constant_"); try dg.renderTypeForBuiltinFnName(writer, ty); try writer.writeByte('('); try writer.writeAll(operation); @@ -2006,18 +2006,16 @@ pub const DeclGen = struct { fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void { const target = dg.module.getTarget(); - const c_bits = if (ty.isAbiInt()) c_bits: { + if (ty.isAbiInt()) { const int_info = ty.intInfo(target); - try writer.writeByte(signAbbrev(int_info.signedness)); - break :c_bits toCIntBits(int_info.bits) orelse + const c_bits = toCIntBits(int_info.bits) orelse return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); - } else if (ty.isRuntimeFloat()) c_bits: { - try writer.writeByte('f'); - break :c_bits ty.floatBits(target); + try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits }); + } else if (ty.isRuntimeFloat()) { + try ty.print(writer, dg.module); } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{ ty.fmt(dg.module), }); - try writer.print("{d}", .{c_bits}); } fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void { @@ -3077,7 +3075,8 @@ fn airBinOp( const operand_ty = f.air.typeOf(bin_op.lhs); const target = f.object.dg.module.getTarget(); - if (operand_ty.bitSize(target) > 64) return try airBinBuiltinCall(f, inst, operation, info); + if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) + return try airBinBuiltinCall(f, inst, operation, info); const inst_ty = f.air.typeOfIndex(inst); const lhs = try f.resolveInst(bin_op.lhs); @@ -3104,7 +3103,8 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { const operand_ty = f.air.typeOf(bin_op.lhs); const target = f.object.dg.module.getTarget(); - if (operand_ty.bitSize(target) > 64) return try airCmpBuiltinCall(f, inst, operator); + if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) + return try airCmpBuiltinCall(f, inst, operator); const inst_ty = f.air.typeOfIndex(inst); const lhs = try f.resolveInst(bin_op.lhs); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 4e49935f7c..2cbfdd1d4a 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1379,7 +1379,6 @@ test "pointer to empty struct literal to mutable slice" { } test "coerce between pointers of compatible differently-named floats" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/math.zig b/test/behavior/math.zig index b3558094f9..17a4c5e64b 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -990,7 +990,6 @@ test "allow signed integer division/remainder when values are comptime-known and } test "quad hex float literal parsing accurate" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -1178,7 +1177,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void { test "float remainder division using @rem" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1222,7 +1220,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void { test "float modulo division using @mod" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1349,7 +1346,6 @@ test "@floor f80" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 try testFloor(f80, 12.0); @@ -1361,7 +1357,6 @@ test "@floor f128" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try testFloor(f128, 12.0); comptime try testFloor(f128, 12.0); @@ -1397,7 +1392,6 @@ test "@ceil f80" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 try testCeil(f80, 12.0); @@ -1409,7 +1403,6 @@ test "@ceil f128" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try testCeil(f128, 12.0); comptime try testCeil(f128, 12.0); @@ -1445,7 +1438,6 @@ test "@trunc f80" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 try testTrunc(f80, 12.0); @@ -1463,7 +1455,6 @@ test "@trunc f128" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try testTrunc(f128, 12.0); comptime try testTrunc(f128, 12.0); @@ -1507,7 +1498,6 @@ test "@round f80" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 try testRound(f80, 12.0); @@ -1519,7 +1509,6 @@ test "@round f128" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try testRound(f128, 12.0); comptime try testRound(f128, 12.0); @@ -1553,7 +1542,6 @@ test "vector integer addition" { } test "NaN comparison" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -1570,7 +1558,6 @@ test "NaN comparison" { } test "NaN comparison f80" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO