authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-09-30 22:11:51-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-01 15:09:52-04:00
logfbe5bf469e17ffd57b34762fd0206587f5758a52
treee657e3c79c1e9ea76daa7d388bdd55340ebc6d7d
parent1eb023908d50e601f68f2200c3cf126ca3035167

x86_64: implement float arithmetic builtins


3 files changed, 301 insertions(+), 187 deletions(-)

src/arch/x86_64/CodeGen.zig+205-173
...@@ -6570,6 +6570,34 @@ fn genBinOp(...@@ -6570,6 +6570,34 @@ fn genBinOp(
6570 const lhs_ty = self.typeOf(lhs_air);6570 const lhs_ty = self.typeOf(lhs_air);
6571 const rhs_ty = self.typeOf(rhs_air);6571 const rhs_ty = self.typeOf(rhs_air);
6572 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));6572 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));
6573
6574 if (lhs_ty.isRuntimeFloat() and switch (lhs_ty.floatBits(self.target.*)) {
6575 16 => !self.hasFeature(.f16c),
6576 32, 64 => false,
6577 80, 128 => true,
6578 else => unreachable,
6579 }) {
6580 var callee: ["__add?f3".len]u8 = undefined;
6581 return self.genCall(.{ .lib = .{
6582 .return_type = lhs_ty.toIntern(),
6583 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
6584 .callee = switch (air_tag) {
6585 .add, .sub, .mul, .div_float => std.fmt.bufPrint(&callee, "__{s}{c}f3", .{
6586 @tagName(air_tag)[0..3],
6587 floatCompilerRtAbiName(lhs_ty.floatBits(self.target.*)),
6588 }),
6589 .min, .max => std.fmt.bufPrint(&callee, "{s}f{s}{s}", .{
6590 floatLibcAbiPrefix(lhs_ty),
6591 @tagName(air_tag),
6592 floatLibcAbiSuffix(lhs_ty),
6593 }),
6594 else => return self.fail("TODO implement genBinOp for {s} {}", .{
6595 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6596 }),
6597 } catch unreachable,
6598 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } });
6599 }
6600
6573 if ((lhs_ty.scalarType(mod).isRuntimeFloat() and6601 if ((lhs_ty.scalarType(mod).isRuntimeFloat() and
6574 lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or6602 lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or
6575 lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))6603 lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))
...@@ -6830,7 +6858,8 @@ fn genBinOp(...@@ -6830,7 +6858,8 @@ fn genBinOp(
6830 const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {6858 const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
6831 else => unreachable,6859 else => unreachable,
6832 .Float => switch (lhs_ty.floatBits(self.target.*)) {6860 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6833 16 => if (self.hasFeature(.f16c)) {6861 16 => {
6862 assert(self.hasFeature(.f16c));
6834 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();6863 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
6835 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);6864 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6836 defer self.register_manager.unlockReg(tmp_lock);6865 defer self.register_manager.unlockReg(tmp_lock);
...@@ -6873,7 +6902,7 @@ fn genBinOp(...@@ -6873,7 +6902,7 @@ fn genBinOp(
6873 Immediate.u(0b1_00),6902 Immediate.u(0b1_00),
6874 );6903 );
6875 return dst_mcv;6904 return dst_mcv;
6876 } else null,6905 },
6877 32 => switch (air_tag) {6906 32 => switch (air_tag) {
6878 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },6907 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },
6879 .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub },6908 .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub },
...@@ -7134,181 +7163,184 @@ fn genBinOp(...@@ -7134,181 +7163,184 @@ fn genBinOp(
7134 else => null,7163 else => null,
7135 },7164 },
7136 .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) {7165 .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) {
7137 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen(mod)) {7166 16 => tag: {
7138 1 => {7167 assert(self.hasFeature(.f16c));
7139 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();7168 switch (lhs_ty.vectorLen(mod)) {
7140 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7169 1 => {
7141 defer self.register_manager.unlockReg(tmp_lock);7170 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
7171 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7172 defer self.register_manager.unlockReg(tmp_lock);
71427173
7143 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(7174 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
7144 .{ .vp_w, .insr },7175 .{ .vp_w, .insr },
7145 dst_reg,7176 dst_reg,
7146 dst_reg,7177 dst_reg,
7147 src_mcv.mem(.word),7178 src_mcv.mem(.word),
7148 Immediate.u(1),7179 Immediate.u(1),
7149 ) else try self.asmRegisterRegisterRegister(7180 ) else try self.asmRegisterRegisterRegister(
7150 .{ .vp_, .unpcklwd },7181 .{ .vp_, .unpcklwd },
7151 dst_reg,7182 dst_reg,
7152 dst_reg,7183 dst_reg,
7153 (if (src_mcv.isRegister())7184 (if (src_mcv.isRegister())
7154 src_mcv.getReg().?7185 src_mcv.getReg().?
7155 else7186 else
7156 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),7187 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
7157 );7188 );
7158 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);7189 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
7159 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg);7190 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg);
7160 try self.asmRegisterRegisterRegister(7191 try self.asmRegisterRegisterRegister(
7161 switch (air_tag) {7192 switch (air_tag) {
7162 .add => .{ .v_ss, .add },7193 .add => .{ .v_ss, .add },
7163 .sub => .{ .v_ss, .sub },7194 .sub => .{ .v_ss, .sub },
7164 .mul => .{ .v_ss, .mul },7195 .mul => .{ .v_ss, .mul },
7165 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div },7196 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div },
7166 .max => .{ .v_ss, .max },7197 .max => .{ .v_ss, .max },
7167 .min => .{ .v_ss, .max },7198 .min => .{ .v_ss, .max },
7168 else => unreachable,7199 else => unreachable,
7169 },7200 },
7170 dst_reg,7201 dst_reg,
7171 dst_reg,7202 dst_reg,
7172 tmp_reg,7203 tmp_reg,
7173 );7204 );
7174 try self.asmRegisterRegisterImmediate(7205 try self.asmRegisterRegisterImmediate(
7175 .{ .v_, .cvtps2ph },7206 .{ .v_, .cvtps2ph },
7176 dst_reg,7207 dst_reg,
7177 dst_reg,7208 dst_reg,
7178 Immediate.u(0b1_00),7209 Immediate.u(0b1_00),
7179 );7210 );
7180 return dst_mcv;7211 return dst_mcv;
7181 },7212 },
7182 2 => {7213 2 => {
7183 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();7214 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
7184 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7215 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7185 defer self.register_manager.unlockReg(tmp_lock);7216 defer self.register_manager.unlockReg(tmp_lock);
71867217
7187 if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate(7218 if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate(
7188 .{ .vp_d, .insr },7219 .{ .vp_d, .insr },
7189 dst_reg,7220 dst_reg,
7190 src_mcv.mem(.dword),7221 src_mcv.mem(.dword),
7191 Immediate.u(1),7222 Immediate.u(1),
7192 ) else try self.asmRegisterRegisterRegister(7223 ) else try self.asmRegisterRegisterRegister(
7193 .{ .v_ps, .unpckl },7224 .{ .v_ps, .unpckl },
7194 dst_reg,7225 dst_reg,
7195 dst_reg,7226 dst_reg,
7196 (if (src_mcv.isRegister())7227 (if (src_mcv.isRegister())
7197 src_mcv.getReg().?7228 src_mcv.getReg().?
7198 else7229 else
7199 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),7230 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
7200 );7231 );
7201 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);7232 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
7202 try self.asmRegisterRegisterRegister(7233 try self.asmRegisterRegisterRegister(
7203 .{ .v_ps, .movhl },7234 .{ .v_ps, .movhl },
7204 tmp_reg,7235 tmp_reg,
7205 dst_reg,7236 dst_reg,
7206 dst_reg,7237 dst_reg,
7207 );7238 );
7208 try self.asmRegisterRegisterRegister(7239 try self.asmRegisterRegisterRegister(
7209 switch (air_tag) {7240 switch (air_tag) {
7210 .add => .{ .v_ps, .add },7241 .add => .{ .v_ps, .add },
7211 .sub => .{ .v_ps, .sub },7242 .sub => .{ .v_ps, .sub },
7212 .mul => .{ .v_ps, .mul },7243 .mul => .{ .v_ps, .mul },
7213 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },7244 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
7214 .max => .{ .v_ps, .max },7245 .max => .{ .v_ps, .max },
7215 .min => .{ .v_ps, .max },7246 .min => .{ .v_ps, .max },
7216 else => unreachable,7247 else => unreachable,
7217 },7248 },
7218 dst_reg,7249 dst_reg,
7219 dst_reg,7250 dst_reg,
7220 tmp_reg,7251 tmp_reg,
7221 );7252 );
7222 try self.asmRegisterRegisterImmediate(7253 try self.asmRegisterRegisterImmediate(
7223 .{ .v_, .cvtps2ph },7254 .{ .v_, .cvtps2ph },
7224 dst_reg,7255 dst_reg,
7225 dst_reg,7256 dst_reg,
7226 Immediate.u(0b1_00),7257 Immediate.u(0b1_00),
7227 );7258 );
7228 return dst_mcv;7259 return dst_mcv;
7229 },7260 },
7230 3...4 => {7261 3...4 => {
7231 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();7262 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
7232 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7263 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7233 defer self.register_manager.unlockReg(tmp_lock);7264 defer self.register_manager.unlockReg(tmp_lock);
72347265
7235 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);7266 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
7236 if (src_mcv.isMemory()) try self.asmRegisterMemory(7267 if (src_mcv.isMemory()) try self.asmRegisterMemory(
7237 .{ .v_ps, .cvtph2 },7268 .{ .v_ps, .cvtph2 },
7238 tmp_reg,7269 tmp_reg,
7239 src_mcv.mem(.qword),7270 src_mcv.mem(.qword),
7240 ) else try self.asmRegisterRegister(7271 ) else try self.asmRegisterRegister(
7241 .{ .v_ps, .cvtph2 },7272 .{ .v_ps, .cvtph2 },
7242 tmp_reg,7273 tmp_reg,
7243 (if (src_mcv.isRegister())7274 (if (src_mcv.isRegister())
7244 src_mcv.getReg().?7275 src_mcv.getReg().?
7245 else7276 else
7246 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),7277 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
7247 );7278 );
7248 try self.asmRegisterRegisterRegister(7279 try self.asmRegisterRegisterRegister(
7249 switch (air_tag) {7280 switch (air_tag) {
7250 .add => .{ .v_ps, .add },7281 .add => .{ .v_ps, .add },
7251 .sub => .{ .v_ps, .sub },7282 .sub => .{ .v_ps, .sub },
7252 .mul => .{ .v_ps, .mul },7283 .mul => .{ .v_ps, .mul },
7253 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },7284 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
7254 .max => .{ .v_ps, .max },7285 .max => .{ .v_ps, .max },
7255 .min => .{ .v_ps, .max },7286 .min => .{ .v_ps, .max },
7256 else => unreachable,7287 else => unreachable,
7257 },7288 },
7258 dst_reg,7289 dst_reg,
7259 dst_reg,7290 dst_reg,
7260 tmp_reg,7291 tmp_reg,
7261 );7292 );
7262 try self.asmRegisterRegisterImmediate(7293 try self.asmRegisterRegisterImmediate(
7263 .{ .v_, .cvtps2ph },7294 .{ .v_, .cvtps2ph },
7264 dst_reg,7295 dst_reg,
7265 dst_reg,7296 dst_reg,
7266 Immediate.u(0b1_00),7297 Immediate.u(0b1_00),
7267 );7298 );
7268 return dst_mcv;7299 return dst_mcv;
7269 },7300 },
7270 5...8 => {7301 5...8 => {
7271 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256();7302 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256();
7272 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7303 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7273 defer self.register_manager.unlockReg(tmp_lock);7304 defer self.register_manager.unlockReg(tmp_lock);
72747305
7275 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg);7306 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg);
7276 if (src_mcv.isMemory()) try self.asmRegisterMemory(7307 if (src_mcv.isMemory()) try self.asmRegisterMemory(
7277 .{ .v_ps, .cvtph2 },7308 .{ .v_ps, .cvtph2 },
7278 tmp_reg,7309 tmp_reg,
7279 src_mcv.mem(.xword),7310 src_mcv.mem(.xword),
7280 ) else try self.asmRegisterRegister(7311 ) else try self.asmRegisterRegister(
7281 .{ .v_ps, .cvtph2 },7312 .{ .v_ps, .cvtph2 },
7282 tmp_reg,7313 tmp_reg,
7283 (if (src_mcv.isRegister())7314 (if (src_mcv.isRegister())
7284 src_mcv.getReg().?7315 src_mcv.getReg().?
7285 else7316 else
7286 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),7317 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
7287 );7318 );
7288 try self.asmRegisterRegisterRegister(7319 try self.asmRegisterRegisterRegister(
7289 switch (air_tag) {7320 switch (air_tag) {
7290 .add => .{ .v_ps, .add },7321 .add => .{ .v_ps, .add },
7291 .sub => .{ .v_ps, .sub },7322 .sub => .{ .v_ps, .sub },
7292 .mul => .{ .v_ps, .mul },7323 .mul => .{ .v_ps, .mul },
7293 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },7324 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
7294 .max => .{ .v_ps, .max },7325 .max => .{ .v_ps, .max },
7295 .min => .{ .v_ps, .max },7326 .min => .{ .v_ps, .max },
7296 else => unreachable,7327 else => unreachable,
7297 },7328 },
7298 dst_reg.to256(),7329 dst_reg.to256(),
7299 dst_reg.to256(),7330 dst_reg.to256(),
7300 tmp_reg,7331 tmp_reg,
7301 );7332 );
7302 try self.asmRegisterRegisterImmediate(7333 try self.asmRegisterRegisterImmediate(
7303 .{ .v_, .cvtps2ph },7334 .{ .v_, .cvtps2ph },
7304 dst_reg,7335 dst_reg,
7305 dst_reg.to256(),7336 dst_reg.to256(),
7306 Immediate.u(0b1_00),7337 Immediate.u(0b1_00),
7307 );7338 );
7308 return dst_mcv;7339 return dst_mcv;
7309 },7340 },
7310 else => null,7341 else => break :tag null,
7311 } else null,7342 }
7343 },
7312 32 => switch (lhs_ty.vectorLen(mod)) {7344 32 => switch (lhs_ty.vectorLen(mod)) {
7313 1 => switch (air_tag) {7345 1 => switch (air_tag) {
7314 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },7346 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },
test/behavior/floatop.zig+96-11
...@@ -19,6 +19,99 @@ fn epsForType(comptime T: type) T {...@@ -19,6 +19,99 @@ fn epsForType(comptime T: type) T {
19 };19 };
20}20}
2121
22test "add f16" {
23 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
24
25 try testAdd(f16);
26 try comptime testAdd(f16);
27}
28
29test "add f32/f64" {
30 try testAdd(f32);
31 try comptime testAdd(f32);
32 try testAdd(f64);
33 try comptime testAdd(f64);
34}
35
36test "add f80/f128/c_longdouble" {
37 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
38
39 try testAdd(f80);
40 try comptime testAdd(f80);
41 try testAdd(f128);
42 try comptime testAdd(f128);
43 try testAdd(c_longdouble);
44 try comptime testAdd(c_longdouble);
45}
46
47fn testAdd(comptime T: type) !void {
48 var one_point_two_five: T = 1.25;
49 var two_point_seven_five: T = 2.75;
50 try expect(one_point_two_five + two_point_seven_five == 4);
51}
52
53test "sub f16" {
54 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
55
56 try testSub(f16);
57 try comptime testSub(f16);
58}
59
60test "sub f32/f64" {
61 try testSub(f32);
62 try comptime testSub(f32);
63 try testSub(f64);
64 try comptime testSub(f64);
65}
66
67test "sub f80/f128/c_longdouble" {
68 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
69
70 try testSub(f80);
71 try comptime testSub(f80);
72 try testSub(f128);
73 try comptime testSub(f128);
74 try testSub(c_longdouble);
75 try comptime testSub(c_longdouble);
76}
77
78fn testSub(comptime T: type) !void {
79 var one_point_two_five: T = 1.25;
80 var two_point_seven_five: T = 2.75;
81 try expect(one_point_two_five - two_point_seven_five == -1.5);
82}
83
84test "mul f16" {
85 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
86
87 try testMul(f16);
88 try comptime testMul(f16);
89}
90
91test "mul f32/f64" {
92 try testMul(f32);
93 try comptime testMul(f32);
94 try testMul(f64);
95 try comptime testMul(f64);
96}
97
98test "mul f80/f128/c_longdouble" {
99 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
100
101 try testMul(f80);
102 try comptime testMul(f80);
103 try testMul(f128);
104 try comptime testMul(f128);
105 try testMul(c_longdouble);
106 try comptime testMul(c_longdouble);
107}
108
109fn testMul(comptime T: type) !void {
110 var one_point_two_five: T = 1.25;
111 var two_point_seven_five: T = 2.75;
112 try expect(one_point_two_five * two_point_seven_five == 3.4375);
113}
114
22test "cmp f16" {115test "cmp f16" {
23 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;117 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
...@@ -216,7 +309,7 @@ test "more @sqrt f16 tests" {...@@ -216,7 +309,7 @@ test "more @sqrt f16 tests" {
216 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO309 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
218 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;311 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
219 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;312 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
220313
221 // TODO these are not all passing at comptime314 // TODO these are not all passing at comptime
222 try expect(@sqrt(@as(f16, 0.0)) == 0.0);315 try expect(@sqrt(@as(f16, 0.0)) == 0.0);
...@@ -269,7 +362,6 @@ test "@sin f16" {...@@ -269,7 +362,6 @@ test "@sin f16" {
269 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO362 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
270 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;363 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
271 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;364 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
272 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
273365
274 try testSin(f16);366 try testSin(f16);
275 try comptime testSin(f16);367 try comptime testSin(f16);
...@@ -339,7 +431,6 @@ test "@cos f16" {...@@ -339,7 +431,6 @@ test "@cos f16" {
339 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO431 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
340 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;432 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
341 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;433 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
342 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
343434
344 try testCos(f16);435 try testCos(f16);
345 try comptime testCos(f16);436 try comptime testCos(f16);
...@@ -409,7 +500,6 @@ test "@tan f16" {...@@ -409,7 +500,6 @@ test "@tan f16" {
409 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
410 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;501 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
411 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;502 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
412 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
413503
414 try testTan(f16);504 try testTan(f16);
415 try comptime testTan(f16);505 try comptime testTan(f16);
...@@ -479,7 +569,6 @@ test "@exp f16" {...@@ -479,7 +569,6 @@ test "@exp f16" {
479 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO569 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
480 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;570 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
481 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;571 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
482 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
483572
484 try testExp(f16);573 try testExp(f16);
485 try comptime testExp(f16);574 try comptime testExp(f16);
...@@ -549,7 +638,6 @@ test "@exp2 f16" {...@@ -549,7 +638,6 @@ test "@exp2 f16" {
549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO638 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
550 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;639 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
551 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;640 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
552 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
553641
554 try testExp2(f16);642 try testExp2(f16);
555 try comptime testExp2(f16);643 try comptime testExp2(f16);
...@@ -619,7 +707,6 @@ test "@log f16" {...@@ -619,7 +707,6 @@ test "@log f16" {
619 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO707 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
620 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;708 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
621 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;709 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
622 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
623710
624 try testLog(f16);711 try testLog(f16);
625 try comptime testLog(f16);712 try comptime testLog(f16);
...@@ -687,7 +774,6 @@ test "@log2 f16" {...@@ -687,7 +774,6 @@ test "@log2 f16" {
687 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO774 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
688 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;775 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
689 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;776 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
690 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
691777
692 try testLog2(f16);778 try testLog2(f16);
693 try comptime testLog2(f16);779 try comptime testLog2(f16);
...@@ -761,7 +847,6 @@ test "@log10 f16" {...@@ -761,7 +847,6 @@ test "@log10 f16" {
761 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO847 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
762 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;848 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
763 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;849 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
764 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
765850
766 try testLog10(f16);851 try testLog10(f16);
767 try comptime testLog10(f16);852 try comptime testLog10(f16);
...@@ -829,7 +914,7 @@ test "@abs f16" {...@@ -829,7 +914,7 @@ test "@abs f16" {
829 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO914 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
830 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO915 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
831 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO916 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
832 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;917 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
833918
834 try testFabs(f16);919 try testFabs(f16);
835 try comptime testFabs(f16);920 try comptime testFabs(f16);
...@@ -1186,7 +1271,7 @@ test "neg f16" {...@@ -1186,7 +1271,7 @@ test "neg f16" {
1186 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1271 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1272 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1188 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;1273 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1189 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;1274 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
11901275
1191 if (builtin.os.tag == .freebsd) {1276 if (builtin.os.tag == .freebsd) {
1192 // TODO file issue to track this failure1277 // TODO file issue to track this failure
test/behavior/math.zig-3
...@@ -7,8 +7,6 @@ const maxInt = std.math.maxInt;...@@ -7,8 +7,6 @@ const maxInt = std.math.maxInt;
7const minInt = std.math.minInt;7const minInt = std.math.minInt;
8const mem = std.mem;8const mem = std.mem;
9const math = std.math;9const math = std.math;
10const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and
11 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);
1210
13test "assignment operators" {11test "assignment operators" {
14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1444,7 +1442,6 @@ test "@round f16" {...@@ -1444,7 +1442,6 @@ test "@round f16" {
1444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1442 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1445 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1443 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1446 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;1444 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
1447 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
14481445
1449 try testRound(f16, 12.0);1446 try testRound(f16, 12.0);
1450 try comptime testRound(f16, 12.0);1447 try comptime testRound(f16, 12.0);