authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-12 23:35:25+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-24 21:08:41+07:00
logaccc3bad6377394531a9ee772e1f90018d058d06
tree01e30a832fd389b4e01259cbd329e92065d44ec0
parent8b3f7d2ad8953009ecb983dfb466ce3995a4cb38

stage2: sparc64: Move conditional branch emission out of airCondBr


1 files changed, 47 insertions(+), 40 deletions(-)

src/arch/sparc64/CodeGen.zig+47-40
......@@ -1231,46 +1231,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
12311231 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
12321232 const liveness_condbr = self.liveness.getCondBr(inst);
12331233
1234 // Here we either emit a BPcc for branching on CCR content,
1235 // or emit a BPr to branch on register content.
1236 const reloc: Mir.Inst.Index = switch (condition) {
1237 .condition_flags => |flags| try self.addInst(.{
1238 .tag = .bpcc,
1239 .data = .{
1240 .branch_predict_int = .{
1241 .ccr = flags.ccr,
1242 // Here we map to the opposite condition because the jump is to the false branch.
1243 .cond = flags.cond.icond.negate(),
1244 .inst = undefined, // Will be filled by performReloc
1245 },
1246 },
1247 }),
1248 else => blk: {
1249 const reg = switch (condition) {
1250 .register => |r| r,
1251 else => try self.copyToTmpRegister(Type.bool, condition),
1252 };
1253
1254 break :blk try self.addInst(.{
1255 .tag = .bpr,
1256 .data = .{
1257 .branch_predict_reg = .{
1258 .cond = .eq_zero,
1259 .rs1 = reg,
1260 .inst = undefined, // populated later through performReloc
1261 },
1262 },
1263 });
1264 },
1265 };
1266
1267 // Regardless of the branch type that's emitted, we need to reserve
1268 // a space for the delay slot.
1269 // TODO Find a way to fill this delay slot
1270 _ = try self.addInst(.{
1271 .tag = .nop,
1272 .data = .{ .nop = {} },
1273 });
1234 // Here we emit a branch to the false section.
1235 const reloc: Mir.Inst.Index = try self.condBr(condition);
12741236
12751237 // If the condition dies here in this condbr instruction, process
12761238 // 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 {
24242386 block_data.relocs.appendAssumeCapacity(br_index);
24252387}
24262388
2389fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index {
2390 // Here we either emit a BPcc for branching on CCR content,
2391 // or emit a BPr to branch on register content.
2392 const reloc: Mir.Inst.Index = switch (condition) {
2393 .condition_flags => |flags| try self.addInst(.{
2394 .tag = .bpcc,
2395 .data = .{
2396 .branch_predict_int = .{
2397 .ccr = flags.ccr,
2398 // Here we map to the opposite condition because the jump is to the false branch.
2399 .cond = flags.cond.icond.negate(),
2400 .inst = undefined, // Will be filled by performReloc
2401 },
2402 },
2403 }),
2404 else => blk: {
2405 const reg = switch (condition) {
2406 .register => |r| r,
2407 else => try self.copyToTmpRegister(Type.bool, condition),
2408 };
2409
2410 break :blk try self.addInst(.{
2411 .tag = .bpr,
2412 .data = .{
2413 .branch_predict_reg = .{
2414 .cond = .eq_zero,
2415 .rs1 = reg,
2416 .inst = undefined, // populated later through performReloc
2417 },
2418 },
2419 });
2420 },
2421 };
2422
2423 // Regardless of the branch type that's emitted, we need to reserve
2424 // a space for the delay slot.
2425 // TODO Find a way to fill this delay slot
2426 _ = try self.addInst(.{
2427 .tag = .nop,
2428 .data = .{ .nop = {} },
2429 });
2430
2431 return reloc;
2432}
2433
24272434/// Copies a value to a register without tracking the register. The register is not considered
24282435/// allocated. A second call to `copyToTmpRegister` may return the same register.
24292436/// This can have a side effect of spilling instructions to the stack to free up a register.