mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
x86_64: rewrite scalar float equality comparisons
This commit is contained in:
parent
921725427e
commit
ae3d95fc8d
File diff suppressed because it is too large
Load Diff
@ -361,7 +361,7 @@ pub const Mnemonic = enum {
|
|||||||
addps, addss,
|
addps, addss,
|
||||||
andps,
|
andps,
|
||||||
andnps,
|
andnps,
|
||||||
cmpps, cmpss,
|
cmpps, cmpss, comiss,
|
||||||
cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si,
|
cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si,
|
||||||
divps, divss,
|
divps, divss,
|
||||||
fxrstor, fxrstor64, fxsave, fxsave64,
|
fxrstor, fxrstor64, fxsave, fxsave64,
|
||||||
@ -386,7 +386,7 @@ pub const Mnemonic = enum {
|
|||||||
andpd,
|
andpd,
|
||||||
andnpd,
|
andnpd,
|
||||||
cmppd, //cmpsd,
|
cmppd, //cmpsd,
|
||||||
comisd, comiss,
|
comisd,
|
||||||
cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd,
|
cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd,
|
||||||
cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd,
|
cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd,
|
||||||
cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si,
|
cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si,
|
||||||
@ -504,6 +504,7 @@ pub const Mnemonic = enum {
|
|||||||
vstmxcsr,
|
vstmxcsr,
|
||||||
vsubpd, vsubps, vsubsd, vsubss,
|
vsubpd, vsubps, vsubsd, vsubss,
|
||||||
vtestpd, vtestps,
|
vtestpd, vtestps,
|
||||||
|
vucomisd, vucomiss,
|
||||||
vxorpd, vxorps,
|
vxorpd, vxorps,
|
||||||
// F16C
|
// F16C
|
||||||
vcvtph2ps, vcvtps2ph,
|
vcvtph2ps, vcvtps2ph,
|
||||||
|
|||||||
@ -354,6 +354,8 @@ pub const Inst = struct {
|
|||||||
fn_env,
|
fn_env,
|
||||||
/// Float No Wait ___ status word
|
/// Float No Wait ___ status word
|
||||||
fn_sw,
|
fn_sw,
|
||||||
|
/// Float Extended ___
|
||||||
|
fx_,
|
||||||
|
|
||||||
/// ___ in 32-bit and Compatibility Mode
|
/// ___ in 32-bit and Compatibility Mode
|
||||||
_32,
|
_32,
|
||||||
@ -817,8 +819,10 @@ pub const Inst = struct {
|
|||||||
/// Round to integer
|
/// Round to integer
|
||||||
rndint,
|
rndint,
|
||||||
/// Restore x87 FPU state
|
/// Restore x87 FPU state
|
||||||
|
/// Restore x87 FPU, MMX, XMM, and MXCSR state
|
||||||
rstor,
|
rstor,
|
||||||
/// Store x87 FPU state
|
/// Store x87 FPU state
|
||||||
|
/// Save x87 FPU, MMX technology, and MXCSR state
|
||||||
save,
|
save,
|
||||||
/// Scale
|
/// Scale
|
||||||
scale,
|
scale,
|
||||||
@ -923,10 +927,6 @@ pub const Inst = struct {
|
|||||||
/// Extract doubleword
|
/// Extract doubleword
|
||||||
/// Extract quadword
|
/// Extract quadword
|
||||||
extr,
|
extr,
|
||||||
/// Restore x87 FPU, MMX, XMM, and MXCSR state
|
|
||||||
fxrstor,
|
|
||||||
/// Save x87 FPU, MMX technology, and MXCSR state
|
|
||||||
fxsave,
|
|
||||||
/// Insert byte
|
/// Insert byte
|
||||||
/// Insert word
|
/// Insert word
|
||||||
/// Insert doubleword
|
/// Insert doubleword
|
||||||
|
|||||||
@ -366,7 +366,6 @@ pub const Register = enum(u8) {
|
|||||||
@intFromEnum(Register.eax) ... @intFromEnum(Register.r15d) => @intFromEnum(Register.eax),
|
@intFromEnum(Register.eax) ... @intFromEnum(Register.r15d) => @intFromEnum(Register.eax),
|
||||||
@intFromEnum(Register.ax) ... @intFromEnum(Register.r15w) => @intFromEnum(Register.ax),
|
@intFromEnum(Register.ax) ... @intFromEnum(Register.r15w) => @intFromEnum(Register.ax),
|
||||||
@intFromEnum(Register.al) ... @intFromEnum(Register.r15b) => @intFromEnum(Register.al),
|
@intFromEnum(Register.al) ... @intFromEnum(Register.r15b) => @intFromEnum(Register.al),
|
||||||
@intFromEnum(Register.ah) ... @intFromEnum(Register.bh) => @intFromEnum(Register.ah) - 4,
|
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
};
|
};
|
||||||
@ -385,7 +384,10 @@ pub const Register = enum(u8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to8(reg: Register) Register {
|
pub fn to8(reg: Register) Register {
|
||||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.al));
|
return switch (@intFromEnum(reg)) {
|
||||||
|
else => @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.al)),
|
||||||
|
@intFromEnum(Register.ah)...@intFromEnum(Register.bh) => reg,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sseBase(reg: Register) u7 {
|
fn sseBase(reg: Register) u7 {
|
||||||
|
|||||||
@ -437,6 +437,7 @@ pub const table = [_]Entry{
|
|||||||
.{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none, .none },
|
.{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none, .none },
|
||||||
.{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none, .none },
|
.{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none, .none },
|
||||||
|
|
||||||
|
.{ .lahf, .z, &.{}, &.{ 0x9f }, 0, .none, .@"32bit" },
|
||||||
.{ .lahf, .z, &.{}, &.{ 0x9f }, 0, .none, .sahf },
|
.{ .lahf, .z, &.{}, &.{ 0x9f }, 0, .none, .sahf },
|
||||||
|
|
||||||
.{ .lar, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x02 }, 0, .none, .none },
|
.{ .lar, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x02 }, 0, .none, .none },
|
||||||
@ -744,6 +745,7 @@ pub const table = [_]Entry{
|
|||||||
|
|
||||||
.{ .rsm, .z, &.{}, &.{ 0x0f, 0xaa }, 0, .none, .none },
|
.{ .rsm, .z, &.{}, &.{ 0x0f, 0xaa }, 0, .none, .none },
|
||||||
|
|
||||||
|
.{ .sahf, .z, &.{}, &.{ 0x9e }, 0, .none, .@"32bit" },
|
||||||
.{ .sahf, .z, &.{}, &.{ 0x9e }, 0, .none, .sahf },
|
.{ .sahf, .z, &.{}, &.{ 0x9e }, 0, .none, .sahf },
|
||||||
|
|
||||||
.{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none },
|
.{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none },
|
||||||
@ -2275,6 +2277,10 @@ pub const table = [_]Entry{
|
|||||||
.{ .vtestpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x0f }, 0, .vex_128_w0, .avx },
|
.{ .vtestpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x0f }, 0, .vex_128_w0, .avx },
|
||||||
.{ .vtestpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x0f }, 0, .vex_256_w0, .avx },
|
.{ .vtestpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x0f }, 0, .vex_256_w0, .avx },
|
||||||
|
|
||||||
|
.{ .vucomisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2e }, 0, .vex_lig_wig, .avx },
|
||||||
|
|
||||||
|
.{ .vucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .vex_lig_wig, .avx },
|
||||||
|
|
||||||
.{ .vxorpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_128_wig, .avx },
|
.{ .vxorpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_128_wig, .avx },
|
||||||
.{ .vxorpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_256_wig, .avx },
|
.{ .vxorpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_256_wig, .avx },
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,23 @@ const Sse = if (std.Target.x86.featureSetHas(builtin.cpu.features, .avx))
|
|||||||
else
|
else
|
||||||
@Vector(16, u8);
|
@Vector(16, u8);
|
||||||
|
|
||||||
inline fn sign(rhs: anytype) bool {
|
inline fn sign(rhs: anytype) switch (@typeInfo(@TypeOf(rhs))) {
|
||||||
return @call(.always_inline, math.signbit, .{rhs});
|
else => bool,
|
||||||
|
.vector => |vector| @Vector(vector.len, bool),
|
||||||
|
} {
|
||||||
|
switch (@typeInfo(@TypeOf(rhs))) {
|
||||||
|
else => return @as(@Type(.{ .int = .{
|
||||||
|
.signedness = .signed,
|
||||||
|
.bits = @bitSizeOf(@TypeOf(rhs)),
|
||||||
|
} }), @bitCast(rhs)) < 0,
|
||||||
|
.vector => |vector| {
|
||||||
|
const V = @Vector(vector.len, @Type(.{ .int = .{
|
||||||
|
.signedness = .signed,
|
||||||
|
.bits = @bitSizeOf(vector.child),
|
||||||
|
} }));
|
||||||
|
return @as(V, @bitCast(rhs)) < @as(V, @splat(0));
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inline fn boolAnd(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) {
|
inline fn boolAnd(lhs: anytype, rhs: @TypeOf(lhs)) @TypeOf(lhs) {
|
||||||
switch (@typeInfo(@TypeOf(lhs))) {
|
switch (@typeInfo(@TypeOf(lhs))) {
|
||||||
@ -69,12 +84,40 @@ noinline fn checkExpected(expected: anytype, actual: @TypeOf(expected)) !void {
|
|||||||
}) return error.Unexpected;
|
}) return error.Unexpected;
|
||||||
}
|
}
|
||||||
test checkExpected {
|
test checkExpected {
|
||||||
|
if (checkExpected(nan(f16), nan(f16)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(nan(f16), -nan(f16)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f16, 0.0), @as(f16, 0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f16, -0.0), @as(f16, -0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f16, -0.0), @as(f16, 0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f16, 0.0), @as(f16, -0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
if (checkExpected(nan(f32), nan(f32)) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f32), nan(f32)) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(nan(f32), -nan(f32)) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(nan(f32), -nan(f32)) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, 0.0), @as(f32, 0.0)) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, 0.0), @as(f32, 0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, -0.0), @as(f32, -0.0)) == error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, -0.0), @as(f32, -0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, -0.0), @as(f32, 0.0)) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, -0.0), @as(f32, 0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
if (checkExpected(@as(f32, 0.0), @as(f32, -0.0)) != error.Unexpected) return error.Unexpected;
|
if (checkExpected(@as(f32, 0.0), @as(f32, -0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
|
if (checkExpected(nan(f64), nan(f64)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(nan(f64), -nan(f64)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f64, 0.0), @as(f64, 0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f64, -0.0), @as(f64, -0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f64, -0.0), @as(f64, 0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f64, 0.0), @as(f64, -0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
|
if (checkExpected(nan(f80), nan(f80)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(nan(f80), -nan(f80)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f80, 0.0), @as(f80, 0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f80, -0.0), @as(f80, -0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f80, -0.0), @as(f80, 0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f80, 0.0), @as(f80, -0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
|
||||||
|
if (checkExpected(nan(f128), nan(f128)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(nan(f128), -nan(f128)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f128, 0.0), @as(f128, 0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f128, -0.0), @as(f128, -0.0)) == error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f128, -0.0), @as(f128, 0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
|
if (checkExpected(@as(f128, 0.0), @as(f128, -0.0)) != error.Unexpected) return error.Unexpected;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Unary(comptime op: anytype) type {
|
fn Unary(comptime op: anytype) type {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user