mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
x86_64: rewrite most of the remaining float ops
This commit is contained in:
parent
39119088f9
commit
fa9b0fa6d3
8 changed files with 16770 additions and 3225 deletions
|
|
@ -450,7 +450,7 @@ pub fn build(b: *std.Build) !void {
|
||||||
.skip_non_native = skip_non_native,
|
.skip_non_native = skip_non_native,
|
||||||
.skip_libc = skip_libc,
|
.skip_libc = skip_libc,
|
||||||
.use_llvm = use_llvm,
|
.use_llvm = use_llvm,
|
||||||
.max_rss = 1.25 * 1024 * 1024 * 1024,
|
.max_rss = 2 * 1024 * 1024 * 1024,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
test_modules_step.dependOn(tests.addModuleTests(b, .{
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -177,7 +177,13 @@ pub const Condition = enum(u5) {
|
||||||
|
|
||||||
/// The immediate operand of vcvtps2ph.
|
/// The immediate operand of vcvtps2ph.
|
||||||
pub const RoundMode = packed struct(u5) {
|
pub const RoundMode = packed struct(u5) {
|
||||||
mode: enum(u4) {
|
direction: Direction = .mxcsr,
|
||||||
|
precision: enum(u1) {
|
||||||
|
normal = 0b0,
|
||||||
|
inexact = 0b1,
|
||||||
|
} = .normal,
|
||||||
|
|
||||||
|
pub const Direction = enum(u4) {
|
||||||
/// Round to nearest (even)
|
/// Round to nearest (even)
|
||||||
nearest = 0b0_00,
|
nearest = 0b0_00,
|
||||||
/// Round down (toward -∞)
|
/// Round down (toward -∞)
|
||||||
|
|
@ -188,11 +194,7 @@ pub const RoundMode = packed struct(u5) {
|
||||||
zero = 0b0_11,
|
zero = 0b0_11,
|
||||||
/// Use current rounding mode of MXCSR.RC
|
/// Use current rounding mode of MXCSR.RC
|
||||||
mxcsr = 0b1_00,
|
mxcsr = 0b1_00,
|
||||||
} = .mxcsr,
|
};
|
||||||
precision: enum(u1) {
|
|
||||||
normal = 0b0,
|
|
||||||
inexact = 0b1,
|
|
||||||
} = .normal,
|
|
||||||
|
|
||||||
pub fn imm(mode: RoundMode) Immediate {
|
pub fn imm(mode: RoundMode) Immediate {
|
||||||
return .u(@as(@typeInfo(RoundMode).@"struct".backing_integer.?, @bitCast(mode)));
|
return .u(@as(@typeInfo(RoundMode).@"struct".backing_integer.?, @bitCast(mode)));
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ pub const table = [_]Entry{
|
||||||
.{ .aad, .zi, &.{ .imm8 }, &.{ 0xd5 }, 0, .none, .@"32bit" },
|
.{ .aad, .zi, &.{ .imm8 }, &.{ 0xd5 }, 0, .none, .@"32bit" },
|
||||||
|
|
||||||
.{ .aam, .z, &.{ }, &.{ 0xd4, 0x0a }, 0, .none, .@"32bit" },
|
.{ .aam, .z, &.{ }, &.{ 0xd4, 0x0a }, 0, .none, .@"32bit" },
|
||||||
.{ .aam, .z, &.{ .imm8 }, &.{ 0xd4 }, 0, .none, .@"32bit" },
|
.{ .aam, .zi, &.{ .imm8 }, &.{ 0xd4 }, 0, .none, .@"32bit" },
|
||||||
|
|
||||||
.{ .aas, .z, &.{}, &.{ 0x3f }, 0, .none, .@"32bit" },
|
.{ .aas, .z, &.{}, &.{ 0x3f }, 0, .none, .@"32bit" },
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,13 @@ test "cmp f128" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "cmp f80/c_longdouble" {
|
test "cmp f80/c_longdouble" {
|
||||||
if (true) return error.SkipZigTest;
|
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 and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testCmp(f80);
|
try testCmp(f80);
|
||||||
try comptime testCmp(f80);
|
try comptime testCmp(f80);
|
||||||
|
|
@ -453,7 +459,7 @@ test "@sin with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testSinWithVectors();
|
try testSinWithVectors();
|
||||||
|
|
@ -526,7 +532,7 @@ test "@cos with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testCosWithVectors();
|
try testCosWithVectors();
|
||||||
|
|
@ -600,7 +606,7 @@ test "@tan with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testTanWithVectors();
|
try testTanWithVectors();
|
||||||
|
|
@ -677,7 +683,7 @@ test "@exp with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testExpWithVectors();
|
try testExpWithVectors();
|
||||||
|
|
@ -749,7 +755,7 @@ test "@exp2 with @vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testExp2WithVectors();
|
try testExp2WithVectors();
|
||||||
|
|
@ -822,7 +828,7 @@ test "@log with @vectors" {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -896,7 +902,7 @@ test "@log2 with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_llvm and
|
if (builtin.zig_backend == .stage2_llvm and
|
||||||
builtin.cpu.arch == .aarch64 and
|
builtin.cpu.arch == .aarch64 and
|
||||||
builtin.os.tag == .windows) return error.SkipZigTest;
|
builtin.os.tag == .windows) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
|
||||||
try testLog2WithVectors();
|
try testLog2WithVectors();
|
||||||
try comptime testLog2WithVectors();
|
try comptime testLog2WithVectors();
|
||||||
|
|
@ -967,7 +973,7 @@ test "@log10 with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) 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_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try testLog10WithVectors();
|
try testLog10WithVectors();
|
||||||
|
|
@ -1188,8 +1194,7 @@ test "@floor with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_x86_64 and
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
|
|
||||||
|
|
||||||
try testFloorWithVectors();
|
try testFloorWithVectors();
|
||||||
try comptime testFloorWithVectors();
|
try comptime testFloorWithVectors();
|
||||||
|
|
@ -1286,8 +1291,7 @@ test "@ceil with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_x86_64 and
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
|
|
||||||
|
|
||||||
try testCeilWithVectors();
|
try testCeilWithVectors();
|
||||||
try comptime testCeilWithVectors();
|
try comptime testCeilWithVectors();
|
||||||
|
|
@ -1384,8 +1388,7 @@ test "@trunc with vectors" {
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_x86_64 and
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
|
|
||||||
|
|
||||||
try testTruncWithVectors();
|
try testTruncWithVectors();
|
||||||
try comptime testTruncWithVectors();
|
try comptime testTruncWithVectors();
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,12 @@ const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const expect = std.testing.expect;
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
const no_x86_64_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and
|
|
||||||
!std.Target.x86.featureSetHas(builtin.cpu.features, .fma);
|
|
||||||
|
|
||||||
test "@mulAdd" {
|
test "@mulAdd" {
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
||||||
|
|
||||||
if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) 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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime testMulAdd();
|
try comptime testMulAdd();
|
||||||
try testMulAdd();
|
try testMulAdd();
|
||||||
|
|
@ -110,10 +106,10 @@ fn vector16() !void {
|
||||||
|
|
||||||
test "vector f16" {
|
test "vector f16" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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
|
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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime vector16();
|
try comptime vector16();
|
||||||
|
|
@ -135,11 +131,11 @@ fn vector32() !void {
|
||||||
|
|
||||||
test "vector f32" {
|
test "vector f32" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
||||||
if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) 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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime vector32();
|
try comptime vector32();
|
||||||
try vector32();
|
try vector32();
|
||||||
|
|
@ -160,11 +156,11 @@ fn vector64() !void {
|
||||||
|
|
||||||
test "vector f64" {
|
test "vector f64" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
||||||
if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) 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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime vector64();
|
try comptime vector64();
|
||||||
try vector64();
|
try vector64();
|
||||||
|
|
@ -184,12 +180,12 @@ fn vector80() !void {
|
||||||
|
|
||||||
test "vector f80" {
|
test "vector f80" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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
|
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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime vector80();
|
try comptime vector80();
|
||||||
|
|
@ -211,12 +207,12 @@ fn vector128() !void {
|
||||||
|
|
||||||
test "vector f128" {
|
test "vector f128" {
|
||||||
if (builtin.zig_backend == .stage2_wasm) 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
|
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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
try comptime vector128();
|
try comptime vector128();
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ test "vector float operators" {
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||||
|
|
||||||
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
|
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
|
||||||
// Triggers an assertion with LLVM 18:
|
// Triggers an assertion with LLVM 18:
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,14 @@ inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type {
|
||||||
.vector => @splat(scalar),
|
.vector => @splat(scalar),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// inline to avoid a runtime `@select`
|
||||||
|
inline fn select(cond: anytype, lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) {
|
||||||
|
return switch (@typeInfo(@TypeOf(cond))) {
|
||||||
|
.bool => if (cond) lhs else rhs,
|
||||||
|
.vector => @select(Scalar(@TypeOf(lhs)), cond, lhs, rhs),
|
||||||
|
else => @compileError(@typeName(@TypeOf(cond))),
|
||||||
|
};
|
||||||
|
}
|
||||||
fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) {
|
fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) {
|
||||||
else => bool,
|
else => bool,
|
||||||
.vector => |vector| @Vector(vector.len, bool),
|
.vector => |vector| @Vector(vector.len, bool),
|
||||||
|
|
@ -84,65 +92,78 @@ fn boolOr(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) {
|
||||||
@compileError("unsupported boolOr type: " ++ @typeName(@TypeOf(lhs)));
|
@compileError("unsupported boolOr type: " ++ @typeName(@TypeOf(lhs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Compare = enum { strict, relaxed, approx, approx_int };
|
||||||
// noinline for a more helpful stack trace
|
// noinline for a more helpful stack trace
|
||||||
noinline fn checkExpected(expected: anytype, actual: @TypeOf(expected), comptime strict: bool) !void {
|
noinline fn checkExpected(expected: anytype, actual: @TypeOf(expected), comptime compare: Compare) !void {
|
||||||
const info = @typeInfo(@TypeOf(expected));
|
const Expected = @TypeOf(expected);
|
||||||
const unexpected = unexpected: switch (switch (info) {
|
const unexpected = unexpected: switch (@typeInfo(Scalar(Expected))) {
|
||||||
else => info,
|
|
||||||
.vector => |vector| @typeInfo(vector.child),
|
|
||||||
}) {
|
|
||||||
else => expected != actual,
|
else => expected != actual,
|
||||||
.float => {
|
.float => switch (compare) {
|
||||||
|
.strict, .relaxed => {
|
||||||
const unequal = boolAnd(expected != actual, boolOr(expected == expected, actual == actual));
|
const unequal = boolAnd(expected != actual, boolOr(expected == expected, actual == actual));
|
||||||
break :unexpected switch (strict) {
|
break :unexpected switch (compare) {
|
||||||
false => unequal,
|
.strict => boolOr(unequal, sign(expected) != sign(actual)),
|
||||||
true => boolOr(unequal, sign(expected) != sign(actual)),
|
.relaxed => unequal,
|
||||||
|
.approx, .approx_int => comptime unreachable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.approx, .approx_int => {
|
||||||
|
const epsilon = math.floatEps(Scalar(Expected));
|
||||||
|
const tolerance = @sqrt(epsilon);
|
||||||
|
break :unexpected @abs(expected - actual) > @max(
|
||||||
|
@abs(expected) * splat(Expected, tolerance),
|
||||||
|
splat(Expected, switch (compare) {
|
||||||
|
.strict, .relaxed => comptime unreachable,
|
||||||
|
.approx => tolerance,
|
||||||
|
.approx_int => 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if (switch (info) {
|
if (switch (@typeInfo(Expected)) {
|
||||||
else => unexpected,
|
else => unexpected,
|
||||||
.vector => @reduce(.Or, unexpected),
|
.vector => @reduce(.Or, unexpected),
|
||||||
}) return error.Unexpected;
|
}) return error.Unexpected;
|
||||||
}
|
}
|
||||||
test checkExpected {
|
test checkExpected {
|
||||||
if (checkExpected(nan(f16), nan(f16), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f16), nan(f16), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f16), -nan(f16), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f16), -nan(f16), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f16, 0.0), @as(f16, 0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f16, 0.0), @as(f16, 0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f16, -0.0), @as(f16, -0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f16, -0.0), @as(f16, -0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f16, -0.0), @as(f16, 0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f16, -0.0), @as(f16, 0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f16, 0.0), @as(f16, -0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f16, 0.0), @as(f16, -0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
if (checkExpected(nan(f32), nan(f32), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f32), nan(f32), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f32), -nan(f32), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f32), -nan(f32), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, 0.0), @as(f32, 0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, 0.0), @as(f32, 0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, -0.0), @as(f32, -0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, -0.0), @as(f32, -0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, -0.0), @as(f32, 0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, -0.0), @as(f32, 0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, 0.0), @as(f32, -0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, 0.0), @as(f32, -0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
if (checkExpected(nan(f64), nan(f64), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f64), nan(f64), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f64), -nan(f64), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f64), -nan(f64), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f64, 0.0), @as(f64, 0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f64, 0.0), @as(f64, 0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f64, -0.0), @as(f64, -0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f64, -0.0), @as(f64, -0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f64, -0.0), @as(f64, 0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f64, -0.0), @as(f64, 0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f64, 0.0), @as(f64, -0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f64, 0.0), @as(f64, -0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
if (checkExpected(nan(f80), nan(f80), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f80), nan(f80), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f80), -nan(f80), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f80), -nan(f80), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f80, 0.0), @as(f80, 0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f80, 0.0), @as(f80, 0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f80, -0.0), @as(f80, -0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f80, -0.0), @as(f80, -0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f80, -0.0), @as(f80, 0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f80, -0.0), @as(f80, 0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f80, 0.0), @as(f80, -0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f80, 0.0), @as(f80, -0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
if (checkExpected(nan(f128), nan(f128), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f128), nan(f128), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f128), -nan(f128), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f128), -nan(f128), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f128, 0.0), @as(f128, 0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f128, 0.0), @as(f128, 0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f128, -0.0), @as(f128, -0.0), true) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f128, -0.0), @as(f128, -0.0), .strict) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f128, -0.0), @as(f128, 0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f128, -0.0), @as(f128, 0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f128, 0.0), @as(f128, -0.0), true) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f128, 0.0), @as(f128, -0.0), .strict) != error.Unexpected) return error.Unexpected;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unary(comptime op: anytype, comptime opts: struct { strict: bool = false }) type {
|
fn unary(comptime op: anytype, comptime opts: struct { compare: Compare = .relaxed }) type {
|
||||||
return struct {
|
return struct {
|
||||||
// noinline so that `mem_arg` is on the stack
|
// noinline so that `mem_arg` is on the stack
|
||||||
noinline fn testArgKinds(
|
noinline fn testArgKinds(
|
||||||
|
|
@ -169,9 +190,9 @@ fn unary(comptime op: anytype, comptime opts: struct { strict: bool = false }) t
|
||||||
const expected = comptime op(Type, imm_arg);
|
const expected = comptime op(Type, imm_arg);
|
||||||
var reg_arg = mem_arg;
|
var reg_arg = mem_arg;
|
||||||
_ = .{®_arg};
|
_ = .{®_arg};
|
||||||
try checkExpected(expected, op(Type, reg_arg), opts.strict);
|
try checkExpected(expected, op(Type, reg_arg), opts.compare);
|
||||||
try checkExpected(expected, op(Type, mem_arg), opts.strict);
|
try checkExpected(expected, op(Type, mem_arg), opts.compare);
|
||||||
try checkExpected(expected, op(Type, imm_arg), opts.strict);
|
try checkExpected(expected, op(Type, imm_arg), opts.compare);
|
||||||
}
|
}
|
||||||
// noinline for a more helpful stack trace
|
// noinline for a more helpful stack trace
|
||||||
noinline fn testArgs(comptime Type: type, comptime imm_arg: Type) !void {
|
noinline fn testArgs(comptime Type: type, comptime imm_arg: Type) !void {
|
||||||
|
|
@ -1628,7 +1649,7 @@ fn unary(comptime op: anytype, comptime opts: struct { strict: bool = false }) t
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast(comptime op: anytype, comptime opts: struct { strict: bool = false }) type {
|
fn cast(comptime op: anytype, comptime opts: struct { compare: Compare = .relaxed }) type {
|
||||||
return struct {
|
return struct {
|
||||||
// noinline so that `mem_arg` is on the stack
|
// noinline so that `mem_arg` is on the stack
|
||||||
noinline fn testArgKinds(
|
noinline fn testArgKinds(
|
||||||
|
|
@ -1656,9 +1677,9 @@ fn cast(comptime op: anytype, comptime opts: struct { strict: bool = false }) ty
|
||||||
const expected = comptime op(Result, Type, imm_arg, imm_arg);
|
const expected = comptime op(Result, Type, imm_arg, imm_arg);
|
||||||
var reg_arg = mem_arg;
|
var reg_arg = mem_arg;
|
||||||
_ = .{®_arg};
|
_ = .{®_arg};
|
||||||
try checkExpected(expected, op(Result, Type, reg_arg, imm_arg), opts.strict);
|
try checkExpected(expected, op(Result, Type, reg_arg, imm_arg), opts.compare);
|
||||||
try checkExpected(expected, op(Result, Type, mem_arg, imm_arg), opts.strict);
|
try checkExpected(expected, op(Result, Type, mem_arg, imm_arg), opts.compare);
|
||||||
try checkExpected(expected, op(Result, Type, imm_arg, imm_arg), opts.strict);
|
try checkExpected(expected, op(Result, Type, imm_arg, imm_arg), opts.compare);
|
||||||
}
|
}
|
||||||
// noinline for a more helpful stack trace
|
// noinline for a more helpful stack trace
|
||||||
noinline fn testArgs(comptime Result: type, comptime Type: type, comptime imm_arg: Type) !void {
|
noinline fn testArgs(comptime Result: type, comptime Type: type, comptime imm_arg: Type) !void {
|
||||||
|
|
@ -8504,7 +8525,7 @@ fn cast(comptime op: anytype, comptime opts: struct { strict: bool = false }) ty
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary(comptime op: anytype, comptime opts: struct { strict: bool = false }) type {
|
fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .relaxed }) type {
|
||||||
return struct {
|
return struct {
|
||||||
// noinline so that `mem_lhs` and `mem_rhs` are on the stack
|
// noinline so that `mem_lhs` and `mem_rhs` are on the stack
|
||||||
noinline fn testArgKinds(
|
noinline fn testArgKinds(
|
||||||
|
|
@ -8534,14 +8555,14 @@ fn binary(comptime op: anytype, comptime opts: struct { strict: bool = false })
|
||||||
var reg_lhs = mem_lhs;
|
var reg_lhs = mem_lhs;
|
||||||
var reg_rhs = mem_rhs;
|
var reg_rhs = mem_rhs;
|
||||||
_ = .{ ®_lhs, ®_rhs };
|
_ = .{ ®_lhs, ®_rhs };
|
||||||
try checkExpected(expected, op(Type, reg_lhs, reg_rhs), opts.strict);
|
try checkExpected(expected, op(Type, reg_lhs, reg_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, reg_lhs, mem_rhs), opts.strict);
|
try checkExpected(expected, op(Type, reg_lhs, mem_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, reg_lhs, imm_rhs), opts.strict);
|
try checkExpected(expected, op(Type, reg_lhs, imm_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, mem_lhs, reg_rhs), opts.strict);
|
try checkExpected(expected, op(Type, mem_lhs, reg_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, mem_lhs, mem_rhs), opts.strict);
|
try checkExpected(expected, op(Type, mem_lhs, mem_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, mem_lhs, imm_rhs), opts.strict);
|
try checkExpected(expected, op(Type, mem_lhs, imm_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, imm_lhs, reg_rhs), opts.strict);
|
try checkExpected(expected, op(Type, imm_lhs, reg_rhs), opts.compare);
|
||||||
try checkExpected(expected, op(Type, imm_lhs, mem_rhs), opts.strict);
|
try checkExpected(expected, op(Type, imm_lhs, mem_rhs), opts.compare);
|
||||||
}
|
}
|
||||||
// noinline for a more helpful stack trace
|
// noinline for a more helpful stack trace
|
||||||
noinline fn testArgs(comptime Type: type, comptime imm_lhs: Type, comptime imm_rhs: Type) !void {
|
noinline fn testArgs(comptime Type: type, comptime imm_lhs: Type, comptime imm_rhs: Type) !void {
|
||||||
|
|
@ -11315,6 +11336,124 @@ fn binary(comptime op: anytype, comptime opts: struct { strict: bool = false })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn add(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs + rhs) {
|
||||||
|
return lhs + rhs;
|
||||||
|
}
|
||||||
|
test add {
|
||||||
|
const test_add = binary(add, .{});
|
||||||
|
try test_add.testFloats();
|
||||||
|
try test_add.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn subtract(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs - rhs) {
|
||||||
|
return lhs - rhs;
|
||||||
|
}
|
||||||
|
test subtract {
|
||||||
|
const test_subtract = binary(subtract, .{});
|
||||||
|
try test_subtract.testFloats();
|
||||||
|
try test_subtract.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) {
|
||||||
|
if (@inComptime() and @typeInfo(Type) == .vector) {
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22743
|
||||||
|
// TODO: return @select(Scalar(Type), boolAnd(lhs == lhs, rhs == rhs), lhs * rhs, lhs + rhs);
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22744
|
||||||
|
var res: Type = undefined;
|
||||||
|
for (0..@typeInfo(Type).vector.len) |i| res[i] = lhs[i] * rhs[i];
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22745
|
||||||
|
// TODO: return lhs * rhs;
|
||||||
|
var rt_lhs = lhs;
|
||||||
|
var rt_rhs = rhs;
|
||||||
|
_ = .{ &rt_lhs, &rt_rhs };
|
||||||
|
return rt_lhs * rt_rhs;
|
||||||
|
}
|
||||||
|
test multiply {
|
||||||
|
const test_multiply = binary(multiply, .{});
|
||||||
|
try test_multiply.testFloats();
|
||||||
|
try test_multiply.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn divide(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) {
|
||||||
|
return lhs / rhs;
|
||||||
|
}
|
||||||
|
test divide {
|
||||||
|
const test_divide = binary(divide, .{ .compare = .approx });
|
||||||
|
try test_divide.testFloats();
|
||||||
|
try test_divide.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// TODO: @TypeOf(@divTrunc(lhs, rhs))
|
||||||
|
inline fn divTrunc(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) {
|
||||||
|
if (@inComptime()) {
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
return @trunc(lhs / rhs);
|
||||||
|
}
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22749
|
||||||
|
// TODO: return @divTrunc(lhs, rhs);
|
||||||
|
var rt_lhs = lhs;
|
||||||
|
var rt_rhs = rhs;
|
||||||
|
_ = .{ &rt_lhs, &rt_rhs };
|
||||||
|
return @divTrunc(rt_lhs, rt_rhs);
|
||||||
|
}
|
||||||
|
test divTrunc {
|
||||||
|
const test_div_trunc = binary(divTrunc, .{ .compare = .approx_int });
|
||||||
|
try test_div_trunc.testFloats();
|
||||||
|
try test_div_trunc.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// TODO: @TypeOf(@divFloor(lhs, rhs))
|
||||||
|
inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) {
|
||||||
|
if (@inComptime()) {
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
return @floor(lhs / rhs);
|
||||||
|
}
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22749
|
||||||
|
// TODO: return @divFloor(lhs, rhs);
|
||||||
|
var rt_lhs = lhs;
|
||||||
|
var rt_rhs = rhs;
|
||||||
|
_ = &rt_lhs;
|
||||||
|
_ = &rt_rhs;
|
||||||
|
return @divFloor(rt_lhs, rt_rhs);
|
||||||
|
}
|
||||||
|
test divFloor {
|
||||||
|
const test_div_floor = binary(divFloor, .{ .compare = .approx_int });
|
||||||
|
try test_div_floor.testFloats();
|
||||||
|
try test_div_floor.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// TODO: @TypeOf(@rem(lhs, rhs))
|
||||||
|
inline fn rem(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
if (@inComptime()) {
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
switch (@typeInfo(Type)) {
|
||||||
|
else => return if (rhs != 0) @rem(lhs, rhs) else nan(Type),
|
||||||
|
.vector => |info| {
|
||||||
|
var res: Type = undefined;
|
||||||
|
inline for (0..info.len) |i| res[i] = if (rhs[i] != 0) @rem(lhs[i], rhs[i]) else nan(Scalar(Type));
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// workaround https://github.com/ziglang/zig/issues/22748
|
||||||
|
// TODO: return @rem(lhs, rhs);
|
||||||
|
var rt_rhs = rhs;
|
||||||
|
_ = &rt_rhs;
|
||||||
|
return @rem(lhs, rt_rhs);
|
||||||
|
}
|
||||||
|
test rem {
|
||||||
|
const test_rem = binary(rem, .{});
|
||||||
|
try test_rem.testFloats();
|
||||||
|
try test_rem.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
inline fn bitNot(comptime Type: type, rhs: Type) @TypeOf(~rhs) {
|
inline fn bitNot(comptime Type: type, rhs: Type) @TypeOf(~rhs) {
|
||||||
return ~rhs;
|
return ~rhs;
|
||||||
}
|
}
|
||||||
|
|
@ -11324,17 +11463,6 @@ test bitNot {
|
||||||
try test_bit_not.testIntVectors();
|
try test_bit_not.testIntVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn abs(comptime Type: type, rhs: Type) @TypeOf(@abs(rhs)) {
|
|
||||||
return @abs(rhs);
|
|
||||||
}
|
|
||||||
test abs {
|
|
||||||
const test_abs = unary(abs, .{ .strict = true });
|
|
||||||
try test_abs.testInts();
|
|
||||||
try test_abs.testIntVectors();
|
|
||||||
try test_abs.testFloats();
|
|
||||||
try test_abs.testFloatVectors();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn clz(comptime Type: type, rhs: Type) @TypeOf(@clz(rhs)) {
|
inline fn clz(comptime Type: type, rhs: Type) @TypeOf(@clz(rhs)) {
|
||||||
return @clz(rhs);
|
return @clz(rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -11344,6 +11472,143 @@ test clz {
|
||||||
try test_clz.testIntVectors();
|
try test_clz.testIntVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn sqrt(comptime Type: type, rhs: Type) @TypeOf(@sqrt(rhs)) {
|
||||||
|
return @sqrt(rhs);
|
||||||
|
}
|
||||||
|
test sqrt {
|
||||||
|
const test_sqrt = unary(sqrt, .{});
|
||||||
|
try test_sqrt.testFloats();
|
||||||
|
try test_sqrt.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn sin(comptime Type: type, rhs: Type) @TypeOf(@sin(rhs)) {
|
||||||
|
return @sin(rhs);
|
||||||
|
}
|
||||||
|
test sin {
|
||||||
|
const test_sin = unary(sin, .{ .compare = .strict });
|
||||||
|
try test_sin.testFloats();
|
||||||
|
try test_sin.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn cos(comptime Type: type, rhs: Type) @TypeOf(@cos(rhs)) {
|
||||||
|
return @cos(rhs);
|
||||||
|
}
|
||||||
|
test cos {
|
||||||
|
const test_cos = unary(cos, .{ .compare = .strict });
|
||||||
|
try test_cos.testFloats();
|
||||||
|
try test_cos.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn tan(comptime Type: type, rhs: Type) @TypeOf(@tan(rhs)) {
|
||||||
|
return @tan(rhs);
|
||||||
|
}
|
||||||
|
test tan {
|
||||||
|
const test_tan = unary(tan, .{ .compare = .strict });
|
||||||
|
try test_tan.testFloats();
|
||||||
|
try test_tan.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn exp(comptime Type: type, rhs: Type) @TypeOf(@exp(rhs)) {
|
||||||
|
return @exp(rhs);
|
||||||
|
}
|
||||||
|
test exp {
|
||||||
|
const test_exp = unary(exp, .{ .compare = .strict });
|
||||||
|
try test_exp.testFloats();
|
||||||
|
try test_exp.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn exp2(comptime Type: type, rhs: Type) @TypeOf(@exp2(rhs)) {
|
||||||
|
return @exp2(rhs);
|
||||||
|
}
|
||||||
|
test exp2 {
|
||||||
|
const test_exp2 = unary(exp2, .{ .compare = .strict });
|
||||||
|
try test_exp2.testFloats();
|
||||||
|
try test_exp2.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn log(comptime Type: type, rhs: Type) @TypeOf(@log(rhs)) {
|
||||||
|
return @log(rhs);
|
||||||
|
}
|
||||||
|
test log {
|
||||||
|
const test_log = unary(log, .{ .compare = .strict });
|
||||||
|
try test_log.testFloats();
|
||||||
|
try test_log.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn log2(comptime Type: type, rhs: Type) @TypeOf(@log2(rhs)) {
|
||||||
|
return @log2(rhs);
|
||||||
|
}
|
||||||
|
test log2 {
|
||||||
|
const test_log2 = unary(log2, .{ .compare = .strict });
|
||||||
|
try test_log2.testFloats();
|
||||||
|
try test_log2.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn log10(comptime Type: type, rhs: Type) @TypeOf(@log10(rhs)) {
|
||||||
|
return @log10(rhs);
|
||||||
|
}
|
||||||
|
test log10 {
|
||||||
|
const test_log10 = unary(log10, .{ .compare = .strict });
|
||||||
|
try test_log10.testFloats();
|
||||||
|
try test_log10.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn abs(comptime Type: type, rhs: Type) @TypeOf(@abs(rhs)) {
|
||||||
|
return @abs(rhs);
|
||||||
|
}
|
||||||
|
test abs {
|
||||||
|
const test_abs = unary(abs, .{ .compare = .strict });
|
||||||
|
try test_abs.testInts();
|
||||||
|
try test_abs.testIntVectors();
|
||||||
|
try test_abs.testFloats();
|
||||||
|
try test_abs.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn floor(comptime Type: type, rhs: Type) @TypeOf(@floor(rhs)) {
|
||||||
|
return @floor(rhs);
|
||||||
|
}
|
||||||
|
test floor {
|
||||||
|
const test_floor = unary(floor, .{ .compare = .strict });
|
||||||
|
try test_floor.testFloats();
|
||||||
|
try test_floor.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn ceil(comptime Type: type, rhs: Type) @TypeOf(@ceil(rhs)) {
|
||||||
|
return @ceil(rhs);
|
||||||
|
}
|
||||||
|
test ceil {
|
||||||
|
const test_ceil = unary(ceil, .{ .compare = .strict });
|
||||||
|
try test_ceil.testFloats();
|
||||||
|
try test_ceil.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn round(comptime Type: type, rhs: Type) @TypeOf(@round(rhs)) {
|
||||||
|
return @round(rhs);
|
||||||
|
}
|
||||||
|
test round {
|
||||||
|
const test_round = unary(round, .{ .compare = .strict });
|
||||||
|
try test_round.testFloats();
|
||||||
|
try test_round.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn trunc(comptime Type: type, rhs: Type) @TypeOf(@trunc(rhs)) {
|
||||||
|
return @trunc(rhs);
|
||||||
|
}
|
||||||
|
test trunc {
|
||||||
|
const test_trunc = unary(trunc, .{ .compare = .strict });
|
||||||
|
try test_trunc.testFloats();
|
||||||
|
try test_trunc.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn negate(comptime Type: type, rhs: Type) @TypeOf(-rhs) {
|
||||||
|
return -rhs;
|
||||||
|
}
|
||||||
|
test negate {
|
||||||
|
const test_negate = unary(negate, .{ .compare = .strict });
|
||||||
|
try test_negate.testFloats();
|
||||||
|
try test_negate.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
inline fn intCast(comptime Result: type, comptime Type: type, rhs: Type, comptime ct_rhs: Type) Result {
|
inline fn intCast(comptime Result: type, comptime Type: type, rhs: Type, comptime ct_rhs: Type) Result {
|
||||||
@setRuntimeSafety(false); // TODO
|
@setRuntimeSafety(false); // TODO
|
||||||
const res_info = switch (@typeInfo(Result)) {
|
const res_info = switch (@typeInfo(Result)) {
|
||||||
|
|
@ -11407,7 +11672,7 @@ inline fn floatCast(comptime Result: type, comptime Type: type, rhs: Type, compt
|
||||||
return @floatCast(rhs);
|
return @floatCast(rhs);
|
||||||
}
|
}
|
||||||
test floatCast {
|
test floatCast {
|
||||||
const test_float_cast = cast(floatCast, .{ .strict = true });
|
const test_float_cast = cast(floatCast, .{ .compare = .strict });
|
||||||
try test_float_cast.testFloats();
|
try test_float_cast.testFloats();
|
||||||
try test_float_cast.testFloatVectors();
|
try test_float_cast.testFloatVectors();
|
||||||
}
|
}
|
||||||
|
|
@ -11610,3 +11875,12 @@ test optionalsNotEqual {
|
||||||
try test_optionals_not_equal.testInts();
|
try test_optionals_not_equal.testInts();
|
||||||
try test_optionals_not_equal.testFloats();
|
try test_optionals_not_equal.testFloats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn mulAdd(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mulAdd(Type, lhs, rhs, rhs)) {
|
||||||
|
return @mulAdd(Type, lhs, rhs, rhs);
|
||||||
|
}
|
||||||
|
test mulAdd {
|
||||||
|
const test_mul_add = binary(mulAdd, .{ .compare = .approx });
|
||||||
|
try test_mul_add.testFloats();
|
||||||
|
try test_mul_add.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue