From 9ad74b60874447b81747651e28246d3f2168940a Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 1 Jun 2022 09:41:40 +0700 Subject: [PATCH] stage2: sparc64: Implement SPARCv9 addcc and movcc --- src/arch/sparc64/Emit.zig | 34 ++++++++++++++++++++++++++++++++-- src/arch/sparc64/bits.zig | 16 ++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/arch/sparc64/Emit.zig b/src/arch/sparc64/Emit.zig index 2383e6c146..44c14752e4 100644 --- a/src/arch/sparc64/Emit.zig +++ b/src/arch/sparc64/Emit.zig @@ -79,7 +79,7 @@ pub fn emitMir( .dbg_epilogue_begin => try emit.mirDebugEpilogueBegin(), .add => try emit.mirArithmetic3Op(inst), - .addcc => @panic("TODO implement sparc64 addcc"), + .addcc => try emit.mirArithmetic3Op(inst), .bpr => try emit.mirConditionalBranch(inst), .bpcc => try emit.mirConditionalBranch(inst), @@ -95,7 +95,7 @@ pub fn emitMir( .@"or" => try emit.mirArithmetic3Op(inst), - .movcc => @panic("TODO implement sparc64 movcc"), + .movcc => try emit.mirConditionalMove(inst), .mulx => try emit.mirArithmetic3Op(inst), @@ -212,6 +212,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { const imm = data.rs2_or_imm.imm; switch (tag) { .add => try emit.writeInstruction(Instruction.add(i13, rs1, imm, rd)), + .addcc => try emit.writeInstruction(Instruction.addcc(i13, rs1, imm, rd)), .jmpl => try emit.writeInstruction(Instruction.jmpl(i13, rs1, imm, rd)), .ldub => try emit.writeInstruction(Instruction.ldub(i13, rs1, imm, rd)), .lduh => try emit.writeInstruction(Instruction.lduh(i13, rs1, imm, rd)), @@ -233,6 +234,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { const rs2 = data.rs2_or_imm.rs2; switch (tag) { .add => try emit.writeInstruction(Instruction.add(Register, rs1, rs2, rd)), + .addcc => try emit.writeInstruction(Instruction.addcc(Register, rs1, rs2, rd)), .jmpl => try emit.writeInstruction(Instruction.jmpl(Register, rs1, rs2, rd)), .ldub => try emit.writeInstruction(Instruction.ldub(Register, rs1, rs2, rd)), .lduh => try emit.writeInstruction(Instruction.lduh(Register, rs1, rs2, rd)), @@ -297,6 +299,34 @@ fn mirConditionalBranch(emit: *Emit, inst: Mir.Inst.Index) !void { } } +fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void { + const tag = emit.mir.instructions.items(.tag)[inst]; + + switch (tag) { + .movcc => { + const data = emit.mir.instructions.items(.data)[inst].conditional_move; + if (data.is_imm) { + try emit.writeInstruction(Instruction.movcc( + i11, + data.cond, + data.ccr, + data.rs2_or_imm.imm, + data.rd, + )); + } else { + try emit.writeInstruction(Instruction.movcc( + Register, + data.cond, + data.ccr, + data.rs2_or_imm.rs2, + data.rd, + )); + } + }, + else => unreachable, + } +} + fn mirNop(emit: *Emit) !void { try emit.writeInstruction(Instruction.nop()); } diff --git a/src/arch/sparc64/bits.zig b/src/arch/sparc64/bits.zig index 27c4a79c7d..615c224ae7 100644 --- a/src/arch/sparc64/bits.zig +++ b/src/arch/sparc64/bits.zig @@ -1141,6 +1141,14 @@ pub const Instruction = union(enum) { }; } + pub fn addcc(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { + return switch (s2) { + Register => format3a(0b10, 0b01_0000, rs1, rs2, rd), + i13 => format3b(0b10, 0b01_0000, rs1, rs2, rd), + else => unreachable, + }; + } + pub fn bpcc(cond: ICondition, annul: bool, pt: bool, ccr: CCR, disp: i21) Instruction { return format2c(0b001, .{ .icond = cond }, annul, pt, ccr, disp); } @@ -1197,6 +1205,14 @@ pub const Instruction = union(enum) { }; } + pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction { + return switch (s2) { + Register => format4c(0b10_1100, cond, ccr, rs2, rd), + i11 => format4d(0b10_1100, cond, ccr, rs2, rd), + else => unreachable, + }; + } + pub fn mulx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { return switch (s2) { Register => format3a(0b10, 0b00_1001, rs1, rs2, rd),