mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
cbe: improve floating point type support
This commit is contained in:
parent
6021edd7ce
commit
94425fe46e
@ -257,56 +257,116 @@ typedef int64_t zig_i64;
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
zig_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) {
|
||||
|
||||
/* ========================== Float Point Routines ========================== */
|
||||
|
||||
static inline zig_f32 zig_bitcast_f32_u32(zig_u32 arg) {
|
||||
zig_f32 dest;
|
||||
memcpy(&dest, &arg, sizeof dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static inline zig_f64 zig_bitcast_f64_u64(zig_u64 arg) {
|
||||
zig_f64 dest;
|
||||
memcpy(&dest, &arg, sizeof dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static inline float zig_div_truncf(float numerator, float denominator) {
|
||||
return __builtin_truncf(numerator / denominator);
|
||||
}
|
||||
|
||||
static inline double zig_div_trunc(double numerator, double denominator) {
|
||||
return __builtin_trunc(numerator / denominator);
|
||||
}
|
||||
|
||||
static inline long double zig_div_truncl(long double numerator, long double denominator) {
|
||||
return __builtin_truncf(numerator / denominator);
|
||||
}
|
||||
|
||||
#define zig_div_trunc_f16 zig_div_truncf
|
||||
#define zig_div_trunc_f32 zig_div_truncf
|
||||
#define zig_div_trunc_f64 zig_div_trunc
|
||||
#define zig_div_trunc_f80 zig_div_truncl
|
||||
#define zig_div_trunc_f128 zig_div_truncl
|
||||
|
||||
#define zig_div_floorf(numerator, denominator) \
|
||||
__builtin_floorf((float)(numerator) / (float)(denominator))
|
||||
|
||||
#define zig_div_floor(numerator, denominator) \
|
||||
__builtin_floor((double)(numerator) / (double)(denominator))
|
||||
|
||||
#define zig_div_floorl(numerator, denominator) \
|
||||
__builtin_floorl((long double)(numerator) / (long double)(denominator))
|
||||
|
||||
#define zig_div_floor_f16 zig_div_floorf
|
||||
#define zig_div_floor_f32 zig_div_floorf
|
||||
#define zig_div_floor_f64 zig_div_floor
|
||||
#define zig_div_floor_f80 zig_div_floorl
|
||||
#define zig_div_floor_f128 zig_div_floorl
|
||||
|
||||
static inline float zig_modf(float numerator, float denominator) {
|
||||
return (numerator - (zig_div_floorf(numerator, denominator) * denominator));
|
||||
}
|
||||
|
||||
static inline double zig_mod(double numerator, double denominator) {
|
||||
return (numerator - (zig_div_floor(numerator, denominator) * denominator));
|
||||
}
|
||||
|
||||
static inline long double zig_modl(long double numerator, long double denominator) {
|
||||
return (numerator - (zig_div_floorl(numerator, denominator) * denominator));
|
||||
}
|
||||
|
||||
#define zig_mod_f16 zig_modf
|
||||
#define zig_mod_f32 zig_modf
|
||||
#define zig_mod_f64 zig_mod
|
||||
#define zig_mod_f80 zig_modl
|
||||
#define zig_mod_f128 zig_modl
|
||||
#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); \
|
||||
} \
|
||||
\
|
||||
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_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
|
||||
return lhs - zig_div_floor_f##w(lhs, rhs) * rhs; \
|
||||
}
|
||||
zig_float_builtins(16)
|
||||
zig_float_builtins(32)
|
||||
zig_float_builtins(64)
|
||||
zig_float_builtins(80)
|
||||
zig_float_builtins(128)
|
||||
|
||||
@ -367,54 +367,6 @@ pub const Function = struct {
|
||||
fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
|
||||
return f.object.dg.fmtIntLiteral(ty, val);
|
||||
}
|
||||
|
||||
fn renderTypeForBuiltinFnName(f: *Function, writer: anytype, ty: Type) !void {
|
||||
const target = f.object.dg.module.getTarget();
|
||||
const c_bits = if (ty.isAbiInt()) c_bits: {
|
||||
const int_info = ty.intInfo(target);
|
||||
try writer.writeByte(signAbbrev(int_info.signedness));
|
||||
break :c_bits toCIntBits(int_info.bits) orelse
|
||||
return f.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);
|
||||
} else return f.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
|
||||
ty.fmt(f.object.dg.module),
|
||||
});
|
||||
try writer.print("{d}", .{c_bits});
|
||||
}
|
||||
|
||||
fn renderBuiltinInfo(f: *Function, writer: anytype, ty: Type, info: BuiltinInfo) !void {
|
||||
const target = f.object.dg.module.getTarget();
|
||||
switch (info) {
|
||||
.None => {},
|
||||
.Range => {
|
||||
var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
|
||||
defer arena.deinit();
|
||||
|
||||
const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
|
||||
var stack align(@alignOf(ExpectedContents)) =
|
||||
std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
|
||||
|
||||
const int_info = ty.intInfo(target);
|
||||
if (int_info.signedness == .signed) {
|
||||
const min_val = try ty.minInt(stack.get(), target);
|
||||
try writer.print(", {x}", .{try f.object.dg.fmtIntLiteral(ty, min_val)});
|
||||
}
|
||||
|
||||
const max_val = try ty.maxInt(stack.get(), target);
|
||||
try writer.print(", {x}", .{try f.object.dg.fmtIntLiteral(ty, max_val)});
|
||||
},
|
||||
.Bits => {
|
||||
var bits_pl = Value.Payload.U64{
|
||||
.base = .{ .tag = .int_u64 },
|
||||
.data = ty.bitSize(target),
|
||||
};
|
||||
const bits_val = Value.initPayload(&bits_pl.base);
|
||||
try writer.print(", {}", .{try f.object.dg.fmtIntLiteral(Type.u8, bits_val)});
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// This data is available when outputting .c code for a `Module`.
|
||||
@ -657,15 +609,18 @@ pub const DeclGen = struct {
|
||||
.Float => {
|
||||
try writer.writeByte('(');
|
||||
try dg.renderTypecast(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
try writer.writeAll(")zig_suffix_");
|
||||
try dg.renderTypeForBuiltinFnName(writer, ty);
|
||||
try writer.writeByte('(');
|
||||
switch (ty.floatBits(target)) {
|
||||
16 => return writer.print("{x}f", .{@bitCast(f16, undefPattern(u16))}),
|
||||
32 => return writer.print("{x}f", .{@bitCast(f32, undefPattern(u32))}),
|
||||
64 => return writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}),
|
||||
80 => return writer.print("{x}l", .{@bitCast(f80, undefPattern(u80))}),
|
||||
128 => return writer.print("{x}l", .{@bitCast(f128, undefPattern(u128))}),
|
||||
16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(u16))}),
|
||||
32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(u32))}),
|
||||
64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}),
|
||||
80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(u80))}),
|
||||
128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(u128))}),
|
||||
else => unreachable,
|
||||
}
|
||||
return writer.writeByte(')');
|
||||
},
|
||||
.Pointer => switch (ty.ptrSize()) {
|
||||
.Slice => {
|
||||
@ -821,9 +776,21 @@ pub const DeclGen = struct {
|
||||
try dg.renderTypecast(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
const f128_val = val.toFloat(f128);
|
||||
if (!std.math.isFinite(f128_val)) {
|
||||
if (std.math.signbit(f128_val)) try writer.writeByte('-');
|
||||
const fn_name = if (std.math.isSignalNan(f128_val))
|
||||
if (std.math.signbit(f128_val)) try writer.writeByte('-');
|
||||
if (std.math.isFinite(f128_val)) {
|
||||
try writer.writeAll("zig_suffix_");
|
||||
try dg.renderTypeForBuiltinFnName(writer, ty);
|
||||
try writer.writeByte('(');
|
||||
switch (ty.floatBits(target)) {
|
||||
16 => try writer.print("{x}", .{@fabs(val.toFloat(f16))}),
|
||||
32 => try writer.print("{x}", .{@fabs(val.toFloat(f32))}),
|
||||
64 => try writer.print("{x}", .{@fabs(val.toFloat(f64))}),
|
||||
80 => try writer.print("{x}", .{@fabs(val.toFloat(f80))}),
|
||||
128 => try writer.print("{x}", .{@fabs(f128_val)}),
|
||||
else => unreachable,
|
||||
}
|
||||
} else {
|
||||
const operation = if (std.math.isSignalNan(f128_val))
|
||||
"nans"
|
||||
else if (std.math.isNan(f128_val))
|
||||
"nan"
|
||||
@ -831,27 +798,23 @@ pub const DeclGen = struct {
|
||||
"inf"
|
||||
else
|
||||
unreachable;
|
||||
try dg.renderFloatFnName(writer, fn_name, ty);
|
||||
try writer.writeAll("zig_builtin_");
|
||||
try dg.renderTypeForBuiltinFnName(writer, ty);
|
||||
try writer.writeByte('(');
|
||||
try writer.writeAll(operation);
|
||||
try writer.writeAll(")(");
|
||||
if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) {
|
||||
// We only actually need to pass the significant, but it will get
|
||||
// We only actually need to pass the significand, but it will get
|
||||
// properly masked anyway, so just pass the whole value.
|
||||
16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, val.toFloat(f16))}),
|
||||
32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, val.toFloat(f32))}),
|
||||
64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, val.toFloat(f64))}),
|
||||
80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, val.toFloat(f80))}),
|
||||
128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, f128_val)}),
|
||||
16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, @fabs(val.toFloat(f16)))}),
|
||||
32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, @fabs(val.toFloat(f32)))}),
|
||||
64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, @fabs(val.toFloat(f64)))}),
|
||||
80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, @fabs(val.toFloat(f80)))}),
|
||||
128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, @fabs(f128_val))}),
|
||||
else => unreachable,
|
||||
};
|
||||
return writer.writeByte(')');
|
||||
} else switch (ty.floatBits(target)) {
|
||||
16 => return writer.print("{x}f", .{val.toFloat(f16)}),
|
||||
32 => return writer.print("{x}f", .{val.toFloat(f32)}),
|
||||
64 => return writer.print("{x}", .{val.toFloat(f64)}),
|
||||
80 => return writer.print("{x}l", .{val.toFloat(f80)}),
|
||||
128 => return writer.print("{x}l", .{f128_val}),
|
||||
else => unreachable,
|
||||
}
|
||||
return writer.writeByte(')');
|
||||
},
|
||||
.Pointer => switch (val.tag()) {
|
||||
.null_value, .zero => {
|
||||
@ -2041,23 +2004,51 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn renderFloatFnName(dg: *DeclGen, writer: anytype, operation: []const u8, float_ty: Type) !void {
|
||||
fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
|
||||
const target = dg.module.getTarget();
|
||||
const float_bits = float_ty.floatBits(target);
|
||||
const is_longdouble = float_bits == CType.longdouble.sizeInBits(target);
|
||||
try writer.writeAll("__");
|
||||
if (is_longdouble or float_bits != 80) {
|
||||
try writer.writeAll("builtin_");
|
||||
}
|
||||
try writer.writeAll(operation);
|
||||
if (is_longdouble) {
|
||||
try writer.writeByte('l');
|
||||
} else switch (float_bits) {
|
||||
16, 32 => try writer.writeByte('f'),
|
||||
64 => {},
|
||||
80 => try writer.writeByte('x'),
|
||||
128 => try writer.writeByte('q'),
|
||||
else => unreachable,
|
||||
const c_bits = if (ty.isAbiInt()) c_bits: {
|
||||
const int_info = ty.intInfo(target);
|
||||
try writer.writeByte(signAbbrev(int_info.signedness));
|
||||
break :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);
|
||||
} 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 {
|
||||
const target = dg.module.getTarget();
|
||||
switch (info) {
|
||||
.None => {},
|
||||
.Range => {
|
||||
var arena = std.heap.ArenaAllocator.init(dg.gpa);
|
||||
defer arena.deinit();
|
||||
|
||||
const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
|
||||
var stack align(@alignOf(ExpectedContents)) =
|
||||
std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
|
||||
|
||||
const int_info = ty.intInfo(target);
|
||||
if (int_info.signedness == .signed) {
|
||||
const min_val = try ty.minInt(stack.get(), target);
|
||||
try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val)});
|
||||
}
|
||||
|
||||
const max_val = try ty.maxInt(stack.get(), target);
|
||||
try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val)});
|
||||
},
|
||||
.Bits => {
|
||||
var bits_pl = Value.Payload.U64{
|
||||
.base = .{ .tag = .int_u64 },
|
||||
.data = ty.bitSize(target),
|
||||
};
|
||||
const bits_val = Value.initPayload(&bits_pl.base);
|
||||
try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val)});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -2760,15 +2751,15 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
try writer.writeAll(" = (");
|
||||
try f.renderTypecast(writer, inst_ty);
|
||||
try writer.writeAll(")zig_wrap_");
|
||||
try f.renderTypeForBuiltinFnName(writer, field_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);
|
||||
try writer.writeAll("((");
|
||||
try f.renderTypecast(writer, field_ty);
|
||||
try writer.writeAll(")zig_shr_");
|
||||
try f.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValueDeref(writer, operand);
|
||||
try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
|
||||
try f.renderBuiltinInfo(writer, field_ty, .Bits);
|
||||
try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits);
|
||||
try writer.writeByte(')');
|
||||
} else {
|
||||
try writer.writeAll(" = ");
|
||||
@ -2998,13 +2989,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
try f.writeCValueDeref(writer, ptr_val);
|
||||
try writer.writeAll(" = zig_or_");
|
||||
try f.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try writer.writeAll("(zig_and_");
|
||||
try f.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValueDeref(writer, ptr_val);
|
||||
try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
|
||||
try f.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
|
||||
try writer.writeAll("((");
|
||||
try f.renderTypecast(writer, host_ty);
|
||||
try writer.writeByte(')');
|
||||
@ -3040,14 +3031,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
|
||||
try w.writeAll(".field_1 = zig_");
|
||||
try w.writeAll(operation);
|
||||
try w.writeAll("o_");
|
||||
try f.renderTypeForBuiltinFnName(w, scalar_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
|
||||
try w.writeAll("(&");
|
||||
try f.writeCValueMember(w, local, .{ .identifier = "field_0" });
|
||||
try w.writeAll(", ");
|
||||
try f.writeCValue(w, lhs, .FunctionArgument);
|
||||
try w.writeAll(", ");
|
||||
try f.writeCValue(w, rhs, .FunctionArgument);
|
||||
try f.renderBuiltinInfo(w, scalar_ty, info);
|
||||
try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
|
||||
try w.writeAll(");\n");
|
||||
return local;
|
||||
}
|
||||
@ -4217,17 +4208,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
const temp_local = try f.allocLocal(field_int_ty, .Const);
|
||||
try writer.writeAll(" = zig_wrap_");
|
||||
try f.renderTypeForBuiltinFnName(writer, field_int_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
|
||||
try writer.writeAll("((");
|
||||
try f.renderTypecast(writer, field_int_ty);
|
||||
try writer.writeAll(")zig_shr_");
|
||||
try f.renderTypeForBuiltinFnName(writer, struct_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValue(writer, struct_byval, .Other);
|
||||
try writer.writeAll(", ");
|
||||
try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
|
||||
try writer.writeByte(')');
|
||||
try f.renderBuiltinInfo(writer, field_int_ty, .Bits);
|
||||
try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits);
|
||||
try writer.writeAll(");\n");
|
||||
if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
|
||||
|
||||
@ -4567,10 +4558,10 @@ fn airUnBuiltinCall(
|
||||
try writer.writeAll(" = zig_");
|
||||
try writer.writeAll(operation);
|
||||
try writer.writeByte('_');
|
||||
try f.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument);
|
||||
try f.renderBuiltinInfo(writer, operand_ty, info);
|
||||
try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
|
||||
try writer.writeAll(");\n");
|
||||
return local;
|
||||
}
|
||||
@ -4592,12 +4583,12 @@ fn airBinBuiltinCall(
|
||||
try writer.writeAll(" = zig_");
|
||||
try writer.writeAll(operation);
|
||||
try writer.writeByte('_');
|
||||
try f.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
|
||||
try writer.writeAll(", ");
|
||||
try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
|
||||
try f.renderBuiltinInfo(writer, operand_ty, info);
|
||||
try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
|
||||
try writer.writeAll(");\n");
|
||||
return local;
|
||||
}
|
||||
@ -4612,7 +4603,7 @@ fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
const writer = f.object.writer();
|
||||
try writer.writeAll(" = zig_cmp_");
|
||||
try f.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
|
||||
try writer.writeByte('(');
|
||||
try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
|
||||
try writer.writeAll(", ");
|
||||
@ -5027,7 +5018,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
if (!empty) {
|
||||
try writer.writeAll("zig_or_");
|
||||
try f.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try writer.writeByte('(');
|
||||
}
|
||||
empty = false;
|
||||
@ -5039,14 +5030,14 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
if (!empty) try writer.writeAll(", ");
|
||||
try writer.writeAll("zig_shlw_");
|
||||
try f.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try writer.writeAll("((");
|
||||
try f.renderTypecast(writer, inst_ty);
|
||||
try writer.writeByte(')');
|
||||
try f.writeCValue(writer, try f.resolveInst(element), .Other);
|
||||
try writer.writeAll(", ");
|
||||
try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
|
||||
try f.renderBuiltinInfo(writer, inst_ty, .Bits);
|
||||
try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);
|
||||
try writer.writeByte(')');
|
||||
if (!empty) try writer.writeByte(')');
|
||||
|
||||
@ -5176,9 +5167,11 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
|
||||
const inst_ty = f.air.typeOfIndex(inst);
|
||||
const operand = try f.resolveInst(un_op);
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
try writer.writeAll(" = ");
|
||||
try f.object.dg.renderFloatFnName(writer, operation, inst_ty);
|
||||
try writer.writeAll(" = zig_builtin_");
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try writer.writeByte('(');
|
||||
try writer.writeAll(operation);
|
||||
try writer.writeAll(")(");
|
||||
try f.writeCValue(writer, operand, .FunctionArgument);
|
||||
try writer.writeAll(");\n");
|
||||
return local;
|
||||
@ -5192,9 +5185,11 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
|
||||
const lhs = try f.resolveInst(bin_op.lhs);
|
||||
const rhs = try f.resolveInst(bin_op.rhs);
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
try writer.writeAll(" = ");
|
||||
try f.object.dg.renderFloatFnName(writer, operation, inst_ty);
|
||||
try writer.writeAll(" = zig_builtin_");
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try writer.writeByte('(');
|
||||
try writer.writeAll(operation);
|
||||
try writer.writeAll(")(");
|
||||
try f.writeCValue(writer, lhs, .FunctionArgument);
|
||||
try writer.writeAll(", ");
|
||||
try f.writeCValue(writer, rhs, .FunctionArgument);
|
||||
@ -5212,9 +5207,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const addend = try f.resolveInst(pl_op.operand);
|
||||
const writer = f.object.writer();
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
try writer.writeAll(" = ");
|
||||
try f.object.dg.renderFloatFnName(writer, "fma", inst_ty);
|
||||
try writer.writeByte('(');
|
||||
try writer.writeAll(" = zig_builtin_");
|
||||
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
|
||||
try writer.writeAll("(fma)(");
|
||||
try f.writeCValue(writer, mulend1, .FunctionArgument);
|
||||
try writer.writeAll(", ");
|
||||
try f.writeCValue(writer, mulend2, .FunctionArgument);
|
||||
|
||||
@ -670,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) 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_c) return error.SkipZigTest; // TODO
|
||||
|
||||
inline for (.{ f16, f32, f64, f80, f128 }) |F| {
|
||||
try expect(math.isNan(@as(F, 0) / @as(F, 0)));
|
||||
@ -763,7 +762,6 @@ test "nan negation f128" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) 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_c) return error.SkipZigTest; // TODO
|
||||
|
||||
const nan_comptime = comptime math.nan(f128);
|
||||
const neg_nan_comptime = -nan_comptime;
|
||||
|
||||
@ -1146,7 +1146,6 @@ test "comptime float rem int" {
|
||||
|
||||
test "remainder division" {
|
||||
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
|
||||
@ -1294,7 +1293,6 @@ test "@fabs" {
|
||||
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 testFabs(f128, 12.0);
|
||||
comptime try testFabs(f128, 12.0);
|
||||
|
||||
@ -62,7 +62,6 @@ fn testMulAdd80() !void {
|
||||
}
|
||||
|
||||
test "@mulAdd f128" {
|
||||
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_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user