aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-02-20 12:19:40 +0100
committerJakub Konka <kubkon@jakubkonka.com>2023-02-20 12:19:40 +0100
commit0aee40bd13fa72ac4ca41e133440917c0ed94ffb (patch)
treed3f46db09ea597780d4bb4471249ec2e803dd99f /src/arch
parent528c43233f0f566930efc7fc53c4f001dea4dfda (diff)
downloadzig-0aee40bd13fa72ac4ca41e133440917c0ed94ffb.tar.gz
zig-0aee40bd13fa72ac4ca41e133440917c0ed94ffb.zip
riscv64+sparc64: alloc new mcv in bitcast if cannot reuse operand
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/riscv64/CodeGen.zig15
-rw-r--r--src/arch/sparc64/CodeGen.zig16
2 files changed, 29 insertions, 2 deletions
diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig
index b97ac727c1..afcf4b0bb7 100644
--- a/src/arch/riscv64/CodeGen.zig
+++ b/src/arch/riscv64/CodeGen.zig
@@ -2338,7 +2338,20 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const result = try self.resolveInst(ty_op.operand);
+ const result = if (self.liveness.isUnused(inst)) .dead else result: {
+ const operand = try self.resolveInst(ty_op.operand);
+ if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
+
+ const operand_lock = switch (operand) {
+ .register => |reg| self.register_manager.lockReg(reg),
+ else => null,
+ };
+ defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
+
+ const dest = try self.allocRegOrMem(inst, true);
+ try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);
+ break :result dest;
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig
index 8344b6e0cc..c8f77fe702 100644
--- a/src/arch/sparc64/CodeGen.zig
+++ b/src/arch/sparc64/CodeGen.zig
@@ -1091,7 +1091,21 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const result = try self.resolveInst(ty_op.operand);
+ const result = if (self.liveness.isUnused(inst)) .dead else result: {
+ const operand = try self.resolveInst(ty_op.operand);
+ if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
+
+ const operand_lock = switch (operand) {
+ .register => |reg| self.register_manager.lockReg(reg),
+ .register_with_overflow => |rwo| self.register_manager.lockReg(rwo.reg),
+ else => null,
+ };
+ defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
+
+ const dest = try self.allocRegOrMem(inst, true);
+ try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);
+ break :result dest;
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}