mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: sparc64: Implement airBr
This commit is contained in:
parent
b6de8d2565
commit
2770f9a034
@ -543,7 +543,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.assembly => try self.airAsm(inst),
|
||||
.bitcast => @panic("TODO try self.airBitCast(inst)"),
|
||||
.block => try self.airBlock(inst),
|
||||
.br => @panic("TODO try self.airBr(inst)"),
|
||||
.br => try self.airBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(),
|
||||
.ret_addr => @panic("TODO try self.airRetAddr(inst)"),
|
||||
.frame_addr => @panic("TODO try self.airFrameAddress(inst)"),
|
||||
@ -852,6 +852,12 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return self.finishAir(inst, result, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airBr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const branch = self.air.instructions.items(.data)[inst].br;
|
||||
try self.br(branch.block_inst, branch.operand);
|
||||
return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airBreakpoint(self: *Self) !void {
|
||||
// ta 0x01
|
||||
_ = try self.addInst(.{
|
||||
@ -1365,6 +1371,56 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
|
||||
return MCValue{ .stack_offset = stack_offset };
|
||||
}
|
||||
|
||||
fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
|
||||
const block_data = self.blocks.getPtr(block).?;
|
||||
|
||||
if (self.air.typeOf(operand).hasRuntimeBits()) {
|
||||
const operand_mcv = try self.resolveInst(operand);
|
||||
const block_mcv = block_data.mcv;
|
||||
if (block_mcv == .none) {
|
||||
block_data.mcv = switch (operand_mcv) {
|
||||
.none, .dead, .unreach => unreachable,
|
||||
.register, .stack_offset, .memory => operand_mcv,
|
||||
.immediate => blk: {
|
||||
const new_mcv = try self.allocRegOrMem(block, true);
|
||||
try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
|
||||
break :blk new_mcv;
|
||||
},
|
||||
else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
|
||||
};
|
||||
} else {
|
||||
try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
|
||||
}
|
||||
}
|
||||
return self.brVoid(block);
|
||||
}
|
||||
|
||||
fn brVoid(self: *Self, block: Air.Inst.Index) !void {
|
||||
const block_data = self.blocks.getPtr(block).?;
|
||||
|
||||
// Emit a jump with a relocation. It will be patched up after the block ends.
|
||||
try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);
|
||||
|
||||
const br_index = try self.addInst(.{
|
||||
.tag = .bpcc,
|
||||
.data = .{
|
||||
.branch_predict_int = .{
|
||||
.ccr = .xcc,
|
||||
.cond = .al,
|
||||
.inst = undefined, // Will be filled by performReloc
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO Find a way to fill this delay slot
|
||||
_ = try self.addInst(.{
|
||||
.tag = .nop,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
|
||||
block_data.relocs.appendAssumeCapacity(br_index);
|
||||
}
|
||||
|
||||
/// 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