From accc3bad6377394531a9ee772e1f90018d058d06 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Sun, 12 Jun 2022 23:35:25 +0700 Subject: [PATCH] stage2: sparc64: Move conditional branch emission out of airCondBr --- src/arch/sparc64/CodeGen.zig | 87 +++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 28a1ab2a24..07f30fd40a 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -1231,46 +1231,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; const liveness_condbr = self.liveness.getCondBr(inst); - // Here we either emit a BPcc for branching on CCR content, - // or emit a BPr to branch on register content. - const reloc: Mir.Inst.Index = switch (condition) { - .condition_flags => |flags| try self.addInst(.{ - .tag = .bpcc, - .data = .{ - .branch_predict_int = .{ - .ccr = flags.ccr, - // Here we map to the opposite condition because the jump is to the false branch. - .cond = flags.cond.icond.negate(), - .inst = undefined, // Will be filled by performReloc - }, - }, - }), - else => blk: { - const reg = switch (condition) { - .register => |r| r, - else => try self.copyToTmpRegister(Type.bool, condition), - }; - - break :blk try self.addInst(.{ - .tag = .bpr, - .data = .{ - .branch_predict_reg = .{ - .cond = .eq_zero, - .rs1 = reg, - .inst = undefined, // populated later through performReloc - }, - }, - }); - }, - }; - - // Regardless of the branch type that's emitted, we need to reserve - // a space for the delay slot. - // TODO Find a way to fill this delay slot - _ = try self.addInst(.{ - .tag = .nop, - .data = .{ .nop = {} }, - }); + // Here we emit a branch to the false section. + const reloc: Mir.Inst.Index = try self.condBr(condition); // If the condition dies here in this condbr instruction, process // that death now instead of later as this has an effect on @@ -2424,6 +2386,51 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { block_data.relocs.appendAssumeCapacity(br_index); } +fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index { + // Here we either emit a BPcc for branching on CCR content, + // or emit a BPr to branch on register content. + const reloc: Mir.Inst.Index = switch (condition) { + .condition_flags => |flags| try self.addInst(.{ + .tag = .bpcc, + .data = .{ + .branch_predict_int = .{ + .ccr = flags.ccr, + // Here we map to the opposite condition because the jump is to the false branch. + .cond = flags.cond.icond.negate(), + .inst = undefined, // Will be filled by performReloc + }, + }, + }), + else => blk: { + const reg = switch (condition) { + .register => |r| r, + else => try self.copyToTmpRegister(Type.bool, condition), + }; + + break :blk try self.addInst(.{ + .tag = .bpr, + .data = .{ + .branch_predict_reg = .{ + .cond = .eq_zero, + .rs1 = reg, + .inst = undefined, // populated later through performReloc + }, + }, + }); + }, + }; + + // Regardless of the branch type that's emitted, we need to reserve + // a space for the delay slot. + // TODO Find a way to fill this delay slot + _ = try self.addInst(.{ + .tag = .nop, + .data = .{ .nop = {} }, + }); + + return reloc; +} + /// Copies a value to a register without tracking the register. The register is not considered /// allocated. A second call to `copyToTmpRegister` may return the same register. /// This can have a side effect of spilling instructions to the stack to free up a register.