x86_64: rewrite scalar *|
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -578,6 +578,11 @@ pub const RegisterClass = struct {
|
||||
for (allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
|
||||
break :blk set;
|
||||
};
|
||||
pub const gphi: RegisterBitSet = blk: {
|
||||
var set = RegisterBitSet.initEmpty();
|
||||
for (allocatable_regs, 0..) |reg, index| if (reg.hasHi8()) set.set(index);
|
||||
break :blk set;
|
||||
};
|
||||
pub const x87: RegisterBitSet = blk: {
|
||||
var set = RegisterBitSet.initEmpty();
|
||||
for (allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
|
||||
|
||||
@@ -529,12 +529,36 @@ pub const Register = enum(u8) {
|
||||
16 => reg.to16(),
|
||||
32 => reg.to32(),
|
||||
64 => reg.to64(),
|
||||
80 => reg.to80(),
|
||||
128 => reg.to128(),
|
||||
256 => reg.to256(),
|
||||
512 => reg.to512(),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toSize(reg: Register, size: Memory.Size, target: *const std.Target) Register {
|
||||
return switch (size) {
|
||||
.none => unreachable,
|
||||
.ptr => reg.toBitSize(target.ptrBitWidth()),
|
||||
.gpr => switch (target.cpu.arch) {
|
||||
else => unreachable,
|
||||
.x86 => reg.to32(),
|
||||
.x86_64 => reg.to64(),
|
||||
},
|
||||
.low_byte => reg.toLo8(),
|
||||
.high_byte => reg.toHi8(),
|
||||
.byte => reg.to8(),
|
||||
.word => reg.to16(),
|
||||
.dword => reg.to32(),
|
||||
.qword => reg.to64(),
|
||||
.tbyte => reg.to80(),
|
||||
.xword => reg.to128(),
|
||||
.yword => reg.to256(),
|
||||
.zword => reg.to512(),
|
||||
};
|
||||
}
|
||||
|
||||
fn gpBase(reg: Register) u7 {
|
||||
return switch (@intFromEnum(reg)) {
|
||||
// zig fmt: off
|
||||
@@ -549,24 +573,62 @@ pub const Register = enum(u8) {
|
||||
}
|
||||
|
||||
pub fn to64(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.rax));
|
||||
return switch (reg.class()) {
|
||||
.general_purpose, .gphi => @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.rax)),
|
||||
.segment => unreachable,
|
||||
.x87, .mmx, .cr, .dr => reg,
|
||||
.sse => reg.to128(),
|
||||
.ip => .rip,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn to32(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.eax));
|
||||
return switch (reg.class()) {
|
||||
.general_purpose, .gphi => @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.eax)),
|
||||
.segment => unreachable,
|
||||
.x87, .mmx, .cr, .dr => reg,
|
||||
.sse => reg.to128(),
|
||||
.ip => .eip,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn to16(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ax));
|
||||
return switch (reg.class()) {
|
||||
.general_purpose, .gphi => @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ax)),
|
||||
.segment, .x87, .mmx, .cr, .dr => reg,
|
||||
.sse => reg.to128(),
|
||||
.ip => .ip,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn to8(reg: Register) Register {
|
||||
return switch (@intFromEnum(reg)) {
|
||||
else => @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.al)),
|
||||
@intFromEnum(Register.ah)...@intFromEnum(Register.bh) => reg,
|
||||
return switch (reg.class()) {
|
||||
.general_purpose => reg.toLo8(),
|
||||
.gphi, .segment, .x87, .mmx, .cr, .dr => reg,
|
||||
.sse => reg.to128(),
|
||||
.ip => .ip,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toLo8(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.al));
|
||||
}
|
||||
|
||||
pub fn toHi8(reg: Register) Register {
|
||||
assert(reg.hasHi8());
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ah));
|
||||
}
|
||||
|
||||
pub fn hasHi8(reg: Register) bool {
|
||||
const reg_id = reg.id();
|
||||
return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id();
|
||||
}
|
||||
|
||||
pub fn to80(reg: Register) Register {
|
||||
assert(reg.class() == .x87);
|
||||
return reg;
|
||||
}
|
||||
|
||||
fn sseBase(reg: Register) u8 {
|
||||
assert(reg.class() == .sse);
|
||||
return switch (@intFromEnum(reg)) {
|
||||
@@ -577,6 +639,10 @@ pub const Register = enum(u8) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn to512(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.sseBase() + @intFromEnum(Register.zmm0));
|
||||
}
|
||||
|
||||
pub fn to256(reg: Register) Register {
|
||||
return @enumFromInt(@intFromEnum(reg) - reg.sseBase() + @intFromEnum(Register.ymm0));
|
||||
}
|
||||
@@ -710,6 +776,8 @@ pub const Memory = struct {
|
||||
none,
|
||||
ptr,
|
||||
gpr,
|
||||
low_byte,
|
||||
high_byte,
|
||||
byte,
|
||||
word,
|
||||
dword,
|
||||
@@ -755,7 +823,7 @@ pub const Memory = struct {
|
||||
.x86 => 32,
|
||||
.x86_64 => 64,
|
||||
},
|
||||
.byte => 8,
|
||||
.low_byte, .high_byte, .byte => 8,
|
||||
.word => 16,
|
||||
.dword => 32,
|
||||
.qword => 64,
|
||||
|
||||
@@ -259,13 +259,13 @@ test "saturating mul i64, i128, wasm only" {
|
||||
|
||||
test "saturating multiplication" {
|
||||
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_aarch64) 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_spirv64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_riscv64) 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_llvm and builtin.cpu.arch.isWasm()) {
|
||||
// https://github.com/ziglang/zig/issues/9660
|
||||
|
||||
@@ -5134,6 +5134,14 @@ test mulWrap {
|
||||
try test_mul_wrap.testIntVectors();
|
||||
}
|
||||
|
||||
inline fn mulSat(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||
return lhs *| rhs;
|
||||
}
|
||||
test mulSat {
|
||||
const test_mul_sat = binary(mulSat, .{});
|
||||
try test_mul_sat.testInts();
|
||||
}
|
||||
|
||||
inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) {
|
||||
return lhs * rhs;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user