mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: sparc64: Move conditional branch emission out of airCondBr
This commit is contained in:
parent
8b3f7d2ad8
commit
accc3bad63
@ -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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user