diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index c7967dde0c..c8859a7164 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -6570,6 +6570,34 @@ fn genBinOp( const lhs_ty = self.typeOf(lhs_air); const rhs_ty = self.typeOf(rhs_air); const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); + + if (lhs_ty.isRuntimeFloat() and switch (lhs_ty.floatBits(self.target.*)) { + 16 => !self.hasFeature(.f16c), + 32, 64 => false, + 80, 128 => true, + else => unreachable, + }) { + var callee: ["__add?f3".len]u8 = undefined; + return self.genCall(.{ .lib = .{ + .return_type = lhs_ty.toIntern(), + .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() }, + .callee = switch (air_tag) { + .add, .sub, .mul, .div_float => std.fmt.bufPrint(&callee, "__{s}{c}f3", .{ + @tagName(air_tag)[0..3], + floatCompilerRtAbiName(lhs_ty.floatBits(self.target.*)), + }), + .min, .max => std.fmt.bufPrint(&callee, "{s}f{s}{s}", .{ + floatLibcAbiPrefix(lhs_ty), + @tagName(air_tag), + floatLibcAbiSuffix(lhs_ty), + }), + else => return self.fail("TODO implement genBinOp for {s} {}", .{ + @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), + }), + } catch unreachable, + } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }); + } + if ((lhs_ty.scalarType(mod).isRuntimeFloat() and lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)) @@ -6830,7 +6858,8 @@ fn genBinOp( const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { else => unreachable, .Float => switch (lhs_ty.floatBits(self.target.*)) { - 16 => if (self.hasFeature(.f16c)) { + 16 => { + assert(self.hasFeature(.f16c)); const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); defer self.register_manager.unlockReg(tmp_lock); @@ -6873,7 +6902,7 @@ fn genBinOp( Immediate.u(0b1_00), ); return dst_mcv; - } else null, + }, 32 => switch (air_tag) { .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, @@ -7134,181 +7163,184 @@ fn genBinOp( else => null, }, .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { - 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen(mod)) { - 1 => { - const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); - const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_lock); + 16 => tag: { + assert(self.hasFeature(.f16c)); + switch (lhs_ty.vectorLen(mod)) { + 1 => { + const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); - if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( - .{ .vp_w, .insr }, - dst_reg, - dst_reg, - src_mcv.mem(.word), - Immediate.u(1), - ) else try self.asmRegisterRegisterRegister( - .{ .vp_, .unpcklwd }, - dst_reg, - dst_reg, - (if (src_mcv.isRegister()) - src_mcv.getReg().? - else - try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), - ); - try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); - try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); - try self.asmRegisterRegisterRegister( - switch (air_tag) { - .add => .{ .v_ss, .add }, - .sub => .{ .v_ss, .sub }, - .mul => .{ .v_ss, .mul }, - .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, - .max => .{ .v_ss, .max }, - .min => .{ .v_ss, .max }, - else => unreachable, - }, - dst_reg, - dst_reg, - tmp_reg, - ); - try self.asmRegisterRegisterImmediate( - .{ .v_, .cvtps2ph }, - dst_reg, - dst_reg, - Immediate.u(0b1_00), - ); - return dst_mcv; - }, - 2 => { - const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); - const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_lock); + if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( + .{ .vp_w, .insr }, + dst_reg, + dst_reg, + src_mcv.mem(.word), + Immediate.u(1), + ) else try self.asmRegisterRegisterRegister( + .{ .vp_, .unpcklwd }, + dst_reg, + dst_reg, + (if (src_mcv.isRegister()) + src_mcv.getReg().? + else + try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), + ); + try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); + try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); + try self.asmRegisterRegisterRegister( + switch (air_tag) { + .add => .{ .v_ss, .add }, + .sub => .{ .v_ss, .sub }, + .mul => .{ .v_ss, .mul }, + .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, + .max => .{ .v_ss, .max }, + .min => .{ .v_ss, .max }, + else => unreachable, + }, + dst_reg, + dst_reg, + tmp_reg, + ); + try self.asmRegisterRegisterImmediate( + .{ .v_, .cvtps2ph }, + dst_reg, + dst_reg, + Immediate.u(0b1_00), + ); + return dst_mcv; + }, + 2 => { + const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); - if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( - .{ .vp_d, .insr }, - dst_reg, - src_mcv.mem(.dword), - Immediate.u(1), - ) else try self.asmRegisterRegisterRegister( - .{ .v_ps, .unpckl }, - dst_reg, - dst_reg, - (if (src_mcv.isRegister()) - src_mcv.getReg().? - else - try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), - ); - try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); - try self.asmRegisterRegisterRegister( - .{ .v_ps, .movhl }, - tmp_reg, - dst_reg, - dst_reg, - ); - try self.asmRegisterRegisterRegister( - switch (air_tag) { - .add => .{ .v_ps, .add }, - .sub => .{ .v_ps, .sub }, - .mul => .{ .v_ps, .mul }, - .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, - .max => .{ .v_ps, .max }, - .min => .{ .v_ps, .max }, - else => unreachable, - }, - dst_reg, - dst_reg, - tmp_reg, - ); - try self.asmRegisterRegisterImmediate( - .{ .v_, .cvtps2ph }, - dst_reg, - dst_reg, - Immediate.u(0b1_00), - ); - return dst_mcv; - }, - 3...4 => { - const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); - const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_lock); + if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( + .{ .vp_d, .insr }, + dst_reg, + src_mcv.mem(.dword), + Immediate.u(1), + ) else try self.asmRegisterRegisterRegister( + .{ .v_ps, .unpckl }, + dst_reg, + dst_reg, + (if (src_mcv.isRegister()) + src_mcv.getReg().? + else + try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), + ); + try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); + try self.asmRegisterRegisterRegister( + .{ .v_ps, .movhl }, + tmp_reg, + dst_reg, + dst_reg, + ); + try self.asmRegisterRegisterRegister( + switch (air_tag) { + .add => .{ .v_ps, .add }, + .sub => .{ .v_ps, .sub }, + .mul => .{ .v_ps, .mul }, + .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, + .max => .{ .v_ps, .max }, + .min => .{ .v_ps, .max }, + else => unreachable, + }, + dst_reg, + dst_reg, + tmp_reg, + ); + try self.asmRegisterRegisterImmediate( + .{ .v_, .cvtps2ph }, + dst_reg, + dst_reg, + Immediate.u(0b1_00), + ); + return dst_mcv; + }, + 3...4 => { + const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); - try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); - if (src_mcv.isMemory()) try self.asmRegisterMemory( - .{ .v_ps, .cvtph2 }, - tmp_reg, - src_mcv.mem(.qword), - ) else try self.asmRegisterRegister( - .{ .v_ps, .cvtph2 }, - tmp_reg, - (if (src_mcv.isRegister()) - src_mcv.getReg().? - else - try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), - ); - try self.asmRegisterRegisterRegister( - switch (air_tag) { - .add => .{ .v_ps, .add }, - .sub => .{ .v_ps, .sub }, - .mul => .{ .v_ps, .mul }, - .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, - .max => .{ .v_ps, .max }, - .min => .{ .v_ps, .max }, - else => unreachable, - }, - dst_reg, - dst_reg, - tmp_reg, - ); - try self.asmRegisterRegisterImmediate( - .{ .v_, .cvtps2ph }, - dst_reg, - dst_reg, - Immediate.u(0b1_00), - ); - return dst_mcv; - }, - 5...8 => { - const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); - const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_lock); + try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); + if (src_mcv.isMemory()) try self.asmRegisterMemory( + .{ .v_ps, .cvtph2 }, + tmp_reg, + src_mcv.mem(.qword), + ) else try self.asmRegisterRegister( + .{ .v_ps, .cvtph2 }, + tmp_reg, + (if (src_mcv.isRegister()) + src_mcv.getReg().? + else + try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), + ); + try self.asmRegisterRegisterRegister( + switch (air_tag) { + .add => .{ .v_ps, .add }, + .sub => .{ .v_ps, .sub }, + .mul => .{ .v_ps, .mul }, + .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, + .max => .{ .v_ps, .max }, + .min => .{ .v_ps, .max }, + else => unreachable, + }, + dst_reg, + dst_reg, + tmp_reg, + ); + try self.asmRegisterRegisterImmediate( + .{ .v_, .cvtps2ph }, + dst_reg, + dst_reg, + Immediate.u(0b1_00), + ); + return dst_mcv; + }, + 5...8 => { + const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); - try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); - if (src_mcv.isMemory()) try self.asmRegisterMemory( - .{ .v_ps, .cvtph2 }, - tmp_reg, - src_mcv.mem(.xword), - ) else try self.asmRegisterRegister( - .{ .v_ps, .cvtph2 }, - tmp_reg, - (if (src_mcv.isRegister()) - src_mcv.getReg().? - else - try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), - ); - try self.asmRegisterRegisterRegister( - switch (air_tag) { - .add => .{ .v_ps, .add }, - .sub => .{ .v_ps, .sub }, - .mul => .{ .v_ps, .mul }, - .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, - .max => .{ .v_ps, .max }, - .min => .{ .v_ps, .max }, - else => unreachable, - }, - dst_reg.to256(), - dst_reg.to256(), - tmp_reg, - ); - try self.asmRegisterRegisterImmediate( - .{ .v_, .cvtps2ph }, - dst_reg, - dst_reg.to256(), - Immediate.u(0b1_00), - ); - return dst_mcv; - }, - else => null, - } else null, + try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); + if (src_mcv.isMemory()) try self.asmRegisterMemory( + .{ .v_ps, .cvtph2 }, + tmp_reg, + src_mcv.mem(.xword), + ) else try self.asmRegisterRegister( + .{ .v_ps, .cvtph2 }, + tmp_reg, + (if (src_mcv.isRegister()) + src_mcv.getReg().? + else + try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), + ); + try self.asmRegisterRegisterRegister( + switch (air_tag) { + .add => .{ .v_ps, .add }, + .sub => .{ .v_ps, .sub }, + .mul => .{ .v_ps, .mul }, + .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, + .max => .{ .v_ps, .max }, + .min => .{ .v_ps, .max }, + else => unreachable, + }, + dst_reg.to256(), + dst_reg.to256(), + tmp_reg, + ); + try self.asmRegisterRegisterImmediate( + .{ .v_, .cvtps2ph }, + dst_reg, + dst_reg.to256(), + Immediate.u(0b1_00), + ); + return dst_mcv; + }, + else => break :tag null, + } + }, 32 => switch (lhs_ty.vectorLen(mod)) { 1 => switch (air_tag) { .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 27a89f3d21..ab9859e08d 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -19,6 +19,99 @@ fn epsForType(comptime T: type) T { }; } +test "add f16" { + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; + + try testAdd(f16); + try comptime testAdd(f16); +} + +test "add f32/f64" { + try testAdd(f32); + try comptime testAdd(f32); + try testAdd(f64); + try comptime testAdd(f64); +} + +test "add f80/f128/c_longdouble" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + + try testAdd(f80); + try comptime testAdd(f80); + try testAdd(f128); + try comptime testAdd(f128); + try testAdd(c_longdouble); + try comptime testAdd(c_longdouble); +} + +fn testAdd(comptime T: type) !void { + var one_point_two_five: T = 1.25; + var two_point_seven_five: T = 2.75; + try expect(one_point_two_five + two_point_seven_five == 4); +} + +test "sub f16" { + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; + + try testSub(f16); + try comptime testSub(f16); +} + +test "sub f32/f64" { + try testSub(f32); + try comptime testSub(f32); + try testSub(f64); + try comptime testSub(f64); +} + +test "sub f80/f128/c_longdouble" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + + try testSub(f80); + try comptime testSub(f80); + try testSub(f128); + try comptime testSub(f128); + try testSub(c_longdouble); + try comptime testSub(c_longdouble); +} + +fn testSub(comptime T: type) !void { + var one_point_two_five: T = 1.25; + var two_point_seven_five: T = 2.75; + try expect(one_point_two_five - two_point_seven_five == -1.5); +} + +test "mul f16" { + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; + + try testMul(f16); + try comptime testMul(f16); +} + +test "mul f32/f64" { + try testMul(f32); + try comptime testMul(f32); + try testMul(f64); + try comptime testMul(f64); +} + +test "mul f80/f128/c_longdouble" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + + try testMul(f80); + try comptime testMul(f80); + try testMul(f128); + try comptime testMul(f128); + try testMul(c_longdouble); + try comptime testMul(c_longdouble); +} + +fn testMul(comptime T: type) !void { + var one_point_two_five: T = 1.25; + var two_point_seven_five: T = 2.75; + try expect(one_point_two_five * two_point_seven_five == 3.4375); +} + test "cmp f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; @@ -216,7 +309,7 @@ test "more @sqrt f16 tests" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; // TODO these are not all passing at comptime try expect(@sqrt(@as(f16, 0.0)) == 0.0); @@ -269,7 +362,6 @@ test "@sin f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testSin(f16); try comptime testSin(f16); @@ -339,7 +431,6 @@ test "@cos f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testCos(f16); try comptime testCos(f16); @@ -409,7 +500,6 @@ test "@tan f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testTan(f16); try comptime testTan(f16); @@ -479,7 +569,6 @@ test "@exp f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testExp(f16); try comptime testExp(f16); @@ -549,7 +638,6 @@ test "@exp2 f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testExp2(f16); try comptime testExp2(f16); @@ -619,7 +707,6 @@ test "@log f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testLog(f16); try comptime testLog(f16); @@ -687,7 +774,6 @@ test "@log2 f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testLog2(f16); try comptime testLog2(f16); @@ -761,7 +847,6 @@ test "@log10 f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; try testLog10(f16); try comptime testLog10(f16); @@ -829,7 +914,7 @@ test "@abs f16" { 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 - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; try testFabs(f16); try comptime testFabs(f16); @@ -1186,7 +1271,7 @@ test "neg f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; if (builtin.os.tag == .freebsd) { // TODO file issue to track this failure diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 801aa2aeaa..91ba47e329 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -7,8 +7,6 @@ const maxInt = std.math.maxInt; const minInt = std.math.minInt; const mem = std.mem; const math = std.math; -const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and - !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c); test "assignment operators" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -1444,7 +1442,6 @@ test "@round f16" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; - if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO try testRound(f16, 12.0); try comptime testRound(f16, 12.0);