mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
x86_64: rewrite scalar shifts
This commit is contained in:
parent
aff2be01c9
commit
2361468e23
File diff suppressed because it is too large
Load Diff
@ -592,6 +592,7 @@ pub const Op = enum {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.gphi => .r8,
|
||||||
.segment => .sreg,
|
.segment => .sreg,
|
||||||
.x87 => switch (reg) {
|
.x87 => switch (reg) {
|
||||||
.st0 => .st0,
|
.st0 => .st0,
|
||||||
|
|||||||
@ -384,6 +384,7 @@ pub const Register = enum(u8) {
|
|||||||
|
|
||||||
pub const Class = enum {
|
pub const Class = enum {
|
||||||
general_purpose,
|
general_purpose,
|
||||||
|
gphi,
|
||||||
segment,
|
segment,
|
||||||
x87,
|
x87,
|
||||||
mmx,
|
mmx,
|
||||||
@ -400,7 +401,7 @@ pub const Register = enum(u8) {
|
|||||||
@intFromEnum(Register.eax) ... @intFromEnum(Register.r15d) => .general_purpose,
|
@intFromEnum(Register.eax) ... @intFromEnum(Register.r15d) => .general_purpose,
|
||||||
@intFromEnum(Register.ax) ... @intFromEnum(Register.r15w) => .general_purpose,
|
@intFromEnum(Register.ax) ... @intFromEnum(Register.r15w) => .general_purpose,
|
||||||
@intFromEnum(Register.al) ... @intFromEnum(Register.r15b) => .general_purpose,
|
@intFromEnum(Register.al) ... @intFromEnum(Register.r15b) => .general_purpose,
|
||||||
@intFromEnum(Register.ah) ... @intFromEnum(Register.bh) => .general_purpose,
|
@intFromEnum(Register.ah) ... @intFromEnum(Register.bh) => .gphi,
|
||||||
|
|
||||||
@intFromEnum(Register.ymm0) ... @intFromEnum(Register.ymm15) => .sse,
|
@intFromEnum(Register.ymm0) ... @intFromEnum(Register.ymm15) => .sse,
|
||||||
@intFromEnum(Register.xmm0) ... @intFromEnum(Register.xmm15) => .sse,
|
@intFromEnum(Register.xmm0) ... @intFromEnum(Register.xmm15) => .sse,
|
||||||
@ -525,7 +526,6 @@ pub const Register = enum(u8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gpBase(reg: Register) u7 {
|
fn gpBase(reg: Register) u7 {
|
||||||
assert(reg.class() == .general_purpose);
|
|
||||||
return switch (@intFromEnum(reg)) {
|
return switch (@intFromEnum(reg)) {
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
@intFromEnum(Register.rax) ... @intFromEnum(Register.r15) => @intFromEnum(Register.rax),
|
@intFromEnum(Register.rax) ... @intFromEnum(Register.r15) => @intFromEnum(Register.rax),
|
||||||
@ -577,7 +577,7 @@ pub const Register = enum(u8) {
|
|||||||
/// DWARF register encoding
|
/// DWARF register encoding
|
||||||
pub fn dwarfNum(reg: Register) u6 {
|
pub fn dwarfNum(reg: Register) u6 {
|
||||||
return switch (reg.class()) {
|
return switch (reg.class()) {
|
||||||
.general_purpose => if (reg.isExtended())
|
.general_purpose, .gphi => if (reg.isExtended())
|
||||||
reg.enc()
|
reg.enc()
|
||||||
else
|
else
|
||||||
@as(u3, @truncate(@as(u24, 0o54673120) >> @as(u5, reg.enc()) * 3)),
|
@as(u3, @truncate(@as(u24, 0o54673120) >> @as(u5, reg.enc()) * 3)),
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
const AddOneBit = math.AddOneBit;
|
const AddOneBit = math.AddOneBit;
|
||||||
|
const cast = math.cast;
|
||||||
const checkExpected = math.checkExpected;
|
const checkExpected = math.checkExpected;
|
||||||
const Compare = math.Compare;
|
const Compare = math.Compare;
|
||||||
const DoubleBits = math.DoubleBits;
|
const DoubleBits = math.DoubleBits;
|
||||||
@ -6,6 +7,7 @@ const fmax = math.fmax;
|
|||||||
const fmin = math.fmin;
|
const fmin = math.fmin;
|
||||||
const Gpr = math.Gpr;
|
const Gpr = math.Gpr;
|
||||||
const inf = math.inf;
|
const inf = math.inf;
|
||||||
|
const Log2Int = math.Log2Int;
|
||||||
const math = @import("math.zig");
|
const math = @import("math.zig");
|
||||||
const nan = math.nan;
|
const nan = math.nan;
|
||||||
const Scalar = math.Scalar;
|
const Scalar = math.Scalar;
|
||||||
@ -5582,6 +5584,28 @@ test mod {
|
|||||||
try test_mod.testFloatVectors();
|
try test_mod.testFloatVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn max(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
return @max(lhs, rhs);
|
||||||
|
}
|
||||||
|
test max {
|
||||||
|
const test_max = binary(max, .{});
|
||||||
|
try test_max.testInts();
|
||||||
|
try test_max.testIntVectors();
|
||||||
|
try test_max.testFloats();
|
||||||
|
try test_max.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn min(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
return @min(lhs, rhs);
|
||||||
|
}
|
||||||
|
test min {
|
||||||
|
const test_min = binary(min, .{});
|
||||||
|
try test_min.testInts();
|
||||||
|
try test_min.testIntVectors();
|
||||||
|
try test_min.testFloats();
|
||||||
|
try test_min.testFloatVectors();
|
||||||
|
}
|
||||||
|
|
||||||
inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {
|
inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {
|
||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
}
|
}
|
||||||
@ -5654,6 +5678,48 @@ test bitOr {
|
|||||||
try test_bit_or.testIntVectors();
|
try test_bit_or.testIntVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn shr(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs);
|
||||||
|
const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);
|
||||||
|
return lhs >> if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs;
|
||||||
|
}
|
||||||
|
test shr {
|
||||||
|
const test_shr = binary(shr, .{});
|
||||||
|
try test_shr.testInts();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn shrExact(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs);
|
||||||
|
const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);
|
||||||
|
const final_rhs = if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs;
|
||||||
|
return @shrExact(lhs >> final_rhs << final_rhs, final_rhs);
|
||||||
|
}
|
||||||
|
test shrExact {
|
||||||
|
const test_shr_exact = binary(shrExact, .{});
|
||||||
|
try test_shr_exact.testInts();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn shl(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs);
|
||||||
|
const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);
|
||||||
|
return lhs << if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs;
|
||||||
|
}
|
||||||
|
test shl {
|
||||||
|
const test_shl = binary(shl, .{});
|
||||||
|
try test_shl.testInts();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn shlExact(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||||
|
const bit_cast_rhs: @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Type) } }) = @bitCast(rhs);
|
||||||
|
const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);
|
||||||
|
const final_rhs = if (comptime cast(Log2Int(Type), @bitSizeOf(Type))) |bits| truncate_rhs % bits else truncate_rhs;
|
||||||
|
return @shlExact(lhs << final_rhs >> final_rhs, final_rhs);
|
||||||
|
}
|
||||||
|
test shlExact {
|
||||||
|
const test_shl_exact = binary(shlExact, .{});
|
||||||
|
try test_shl_exact.testInts();
|
||||||
|
}
|
||||||
|
|
||||||
inline fn bitXor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs ^ rhs) {
|
inline fn bitXor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs ^ rhs) {
|
||||||
return lhs ^ rhs;
|
return lhs ^ rhs;
|
||||||
}
|
}
|
||||||
@ -5663,28 +5729,6 @@ test bitXor {
|
|||||||
try test_bit_xor.testIntVectors();
|
try test_bit_xor.testIntVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn min(comptime Type: type, lhs: Type, rhs: Type) Type {
|
|
||||||
return @min(lhs, rhs);
|
|
||||||
}
|
|
||||||
test min {
|
|
||||||
const test_min = binary(min, .{});
|
|
||||||
try test_min.testInts();
|
|
||||||
try test_min.testIntVectors();
|
|
||||||
try test_min.testFloats();
|
|
||||||
try test_min.testFloatVectors();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn max(comptime Type: type, lhs: Type, rhs: Type) Type {
|
|
||||||
return @max(lhs, rhs);
|
|
||||||
}
|
|
||||||
test max {
|
|
||||||
const test_max = binary(max, .{});
|
|
||||||
try test_max.testInts();
|
|
||||||
try test_max.testIntVectors();
|
|
||||||
try test_max.testFloats();
|
|
||||||
try test_max.testFloatVectors();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn optionalsEqual(comptime Type: type, lhs: Type, rhs: Type) bool {
|
inline fn optionalsEqual(comptime Type: type, lhs: Type, rhs: Type) bool {
|
||||||
if (@inComptime()) return lhs == rhs; // workaround https://github.com/ziglang/zig/issues/22636
|
if (@inComptime()) return lhs == rhs; // workaround https://github.com/ziglang/zig/issues/22636
|
||||||
return @as(?Type, lhs) == rhs;
|
return @as(?Type, lhs) == rhs;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const builtin = @import("builtin");
|
|||||||
const math = std.math;
|
const math = std.math;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const cast = math.cast;
|
||||||
pub const fmax = math.floatMax;
|
pub const fmax = math.floatMax;
|
||||||
pub const fmin = math.floatMin;
|
pub const fmin = math.floatMin;
|
||||||
pub const imax = math.maxInt;
|
pub const imax = math.maxInt;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user