mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage2: sparc64: Implement SPARCv9 shifts
This commit is contained in:
parent
513ab4eb56
commit
4d15284c3c
@ -2337,7 +2337,6 @@ fn binOpImmediate(
|
||||
.sllx => .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = ShiftWidth.shift64,
|
||||
.rd = dest_reg,
|
||||
.rs1 = lhs_reg,
|
||||
.rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },
|
||||
@ -2459,7 +2458,6 @@ fn binOpRegister(
|
||||
.sllx => .{
|
||||
.shift = .{
|
||||
.is_imm = false,
|
||||
.width = ShiftWidth.shift64,
|
||||
.rd = dest_reg,
|
||||
.rs1 = lhs_reg,
|
||||
.rs2_or_imm = .{ .rs2 = rhs_reg },
|
||||
@ -2940,7 +2938,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
.data = .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = .shift64,
|
||||
.rd = reg,
|
||||
.rs1 = reg,
|
||||
.rs2_or_imm = .{ .imm = 12 },
|
||||
@ -2971,7 +2968,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
.data = .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = .shift64,
|
||||
.rd = reg,
|
||||
.rs1 = reg,
|
||||
.rs2_or_imm = .{ .imm = 32 },
|
||||
@ -3768,7 +3764,6 @@ fn truncRegister(
|
||||
.data = .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = ShiftWidth.shift64,
|
||||
.rd = dest_reg,
|
||||
.rs1 = operand_reg,
|
||||
.rs2_or_imm = .{ .imm = @intCast(u6, 64 - int_bits) },
|
||||
@ -3783,7 +3778,6 @@ fn truncRegister(
|
||||
.data = .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = ShiftWidth.shift32,
|
||||
.rd = dest_reg,
|
||||
.rs1 = dest_reg,
|
||||
.rs2_or_imm = .{ .imm = @intCast(u6, int_bits) },
|
||||
@ -3800,7 +3794,6 @@ fn truncRegister(
|
||||
.data = .{
|
||||
.shift = .{
|
||||
.is_imm = true,
|
||||
.width = ShiftWidth.shift32,
|
||||
.rd = dest_reg,
|
||||
.rs1 = operand_reg,
|
||||
.rs2_or_imm = .{ .imm = 0 },
|
||||
|
||||
@ -115,12 +115,12 @@ pub fn emitMir(
|
||||
|
||||
.sethi => try emit.mirSethi(inst),
|
||||
|
||||
.sll => @panic("TODO implement sparc64 sll"),
|
||||
.srl => @panic("TODO implement sparc64 srl"),
|
||||
.sra => @panic("TODO implement sparc64 sra"),
|
||||
.sllx => @panic("TODO implement sparc64 sllx"),
|
||||
.srlx => @panic("TODO implement sparc64 srlx"),
|
||||
.srax => @panic("TODO implement sparc64 srax"),
|
||||
.sll => try emit.mirShift(inst),
|
||||
.srl => try emit.mirShift(inst),
|
||||
.sra => try emit.mirShift(inst),
|
||||
.sllx => try emit.mirShift(inst),
|
||||
.srlx => try emit.mirShift(inst),
|
||||
.srax => try emit.mirShift(inst),
|
||||
|
||||
.stb => try emit.mirArithmetic3Op(inst),
|
||||
.sth => try emit.mirArithmetic3Op(inst),
|
||||
@ -370,6 +370,38 @@ fn mirSethi(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
try emit.writeInstruction(Instruction.sethi(imm, rd));
|
||||
}
|
||||
|
||||
fn mirShift(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
const data = emit.mir.instructions.items(.data)[inst].shift;
|
||||
|
||||
const rd = data.rd;
|
||||
const rs1 = data.rs1;
|
||||
|
||||
if (data.is_imm) {
|
||||
const imm = data.rs2_or_imm.imm;
|
||||
switch (tag) {
|
||||
.sll => try emit.writeInstruction(Instruction.sll(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.srl => try emit.writeInstruction(Instruction.srl(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.sra => try emit.writeInstruction(Instruction.sra(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.sllx => try emit.writeInstruction(Instruction.sllx(u6, rs1, imm, rd)),
|
||||
.srlx => try emit.writeInstruction(Instruction.srlx(u6, rs1, imm, rd)),
|
||||
.srax => try emit.writeInstruction(Instruction.srax(u6, rs1, imm, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
} else {
|
||||
const rs2 = data.rs2_or_imm.rs2;
|
||||
switch (tag) {
|
||||
.sll => try emit.writeInstruction(Instruction.sll(Register, rs1, rs2, rd)),
|
||||
.srl => try emit.writeInstruction(Instruction.srl(Register, rs1, rs2, rd)),
|
||||
.sra => try emit.writeInstruction(Instruction.sra(Register, rs1, rs2, rd)),
|
||||
.sllx => try emit.writeInstruction(Instruction.sllx(Register, rs1, rs2, rd)),
|
||||
.srlx => try emit.writeInstruction(Instruction.srlx(Register, rs1, rs2, rd)),
|
||||
.srax => try emit.writeInstruction(Instruction.srax(Register, rs1, rs2, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mirTrap(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
const data = emit.mir.instructions.items(.data)[inst].trap;
|
||||
|
||||
@ -299,7 +299,6 @@ pub const Inst = struct {
|
||||
/// Used by e.g. sllx
|
||||
shift: struct {
|
||||
is_imm: bool,
|
||||
width: Instruction.ShiftWidth,
|
||||
rd: Register,
|
||||
rs1: Register,
|
||||
rs2_or_imm: union {
|
||||
|
||||
@ -1313,6 +1313,54 @@ pub const Instruction = union(enum) {
|
||||
return format2a(0b100, imm, rd);
|
||||
}
|
||||
|
||||
pub fn sll(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0101, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srl(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0110, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sra(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0111, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0111, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sllx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0101, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srlx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0110, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srax(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0111, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0111, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user