authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-01 09:41:40+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-06 20:34:53+07:00
log9ad74b60874447b81747651e28246d3f2168940a
tree92702f05d1979cac2b233b4910efcf5066f42d5f
parent97c43afefe2938119b0c4d14032f9e4b41926716

stage2: sparc64: Implement SPARCv9 addcc and movcc


2 files changed, 48 insertions(+), 2 deletions(-)

src/arch/sparc64/Emit.zig+32-2
......@@ -79,7 +79,7 @@ pub fn emitMir(
7979 .dbg_epilogue_begin => try emit.mirDebugEpilogueBegin(),
8080
8181 .add => try emit.mirArithmetic3Op(inst),
82 .addcc => @panic("TODO implement sparc64 addcc"),
82 .addcc => try emit.mirArithmetic3Op(inst),
8383
8484 .bpr => try emit.mirConditionalBranch(inst),
8585 .bpcc => try emit.mirConditionalBranch(inst),
......@@ -95,7 +95,7 @@ pub fn emitMir(
9595
9696 .@"or" => try emit.mirArithmetic3Op(inst),
9797
98 .movcc => @panic("TODO implement sparc64 movcc"),
98 .movcc => try emit.mirConditionalMove(inst),
9999
100100 .mulx => try emit.mirArithmetic3Op(inst),
101101
......@@ -212,6 +212,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
212212 const imm = data.rs2_or_imm.imm;
213213 switch (tag) {
214214 .add => try emit.writeInstruction(Instruction.add(i13, rs1, imm, rd)),
215 .addcc => try emit.writeInstruction(Instruction.addcc(i13, rs1, imm, rd)),
215216 .jmpl => try emit.writeInstruction(Instruction.jmpl(i13, rs1, imm, rd)),
216217 .ldub => try emit.writeInstruction(Instruction.ldub(i13, rs1, imm, rd)),
217218 .lduh => try emit.writeInstruction(Instruction.lduh(i13, rs1, imm, rd)),
......@@ -233,6 +234,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
233234 const rs2 = data.rs2_or_imm.rs2;
234235 switch (tag) {
235236 .add => try emit.writeInstruction(Instruction.add(Register, rs1, rs2, rd)),
237 .addcc => try emit.writeInstruction(Instruction.addcc(Register, rs1, rs2, rd)),
236238 .jmpl => try emit.writeInstruction(Instruction.jmpl(Register, rs1, rs2, rd)),
237239 .ldub => try emit.writeInstruction(Instruction.ldub(Register, rs1, rs2, rd)),
238240 .lduh => try emit.writeInstruction(Instruction.lduh(Register, rs1, rs2, rd)),
......@@ -297,6 +299,34 @@ fn mirConditionalBranch(emit: *Emit, inst: Mir.Inst.Index) !void {
297299 }
298300}
299301
302fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void {
303 const tag = emit.mir.instructions.items(.tag)[inst];
304
305 switch (tag) {
306 .movcc => {
307 const data = emit.mir.instructions.items(.data)[inst].conditional_move;
308 if (data.is_imm) {
309 try emit.writeInstruction(Instruction.movcc(
310 i11,
311 data.cond,
312 data.ccr,
313 data.rs2_or_imm.imm,
314 data.rd,
315 ));
316 } else {
317 try emit.writeInstruction(Instruction.movcc(
318 Register,
319 data.cond,
320 data.ccr,
321 data.rs2_or_imm.rs2,
322 data.rd,
323 ));
324 }
325 },
326 else => unreachable,
327 }
328}
329
300330fn mirNop(emit: *Emit) !void {
301331 try emit.writeInstruction(Instruction.nop());
302332}
src/arch/sparc64/bits.zig+16
......@@ -1141,6 +1141,14 @@ pub const Instruction = union(enum) {
11411141 };
11421142 }
11431143
1144 pub fn addcc(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
1145 return switch (s2) {
1146 Register => format3a(0b10, 0b01_0000, rs1, rs2, rd),
1147 i13 => format3b(0b10, 0b01_0000, rs1, rs2, rd),
1148 else => unreachable,
1149 };
1150 }
1151
11441152 pub fn bpcc(cond: ICondition, annul: bool, pt: bool, ccr: CCR, disp: i21) Instruction {
11451153 return format2c(0b001, .{ .icond = cond }, annul, pt, ccr, disp);
11461154 }
......@@ -1197,6 +1205,14 @@ pub const Instruction = union(enum) {
11971205 };
11981206 }
11991207
1208 pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction {
1209 return switch (s2) {
1210 Register => format4c(0b10_1100, cond, ccr, rs2, rd),
1211 i11 => format4d(0b10_1100, cond, ccr, rs2, rd),
1212 else => unreachable,
1213 };
1214 }
1215
12001216 pub fn mulx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
12011217 return switch (s2) {
12021218 Register => format3a(0b10, 0b00_1001, rs1, rs2, rd),