aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86_64/CodeGen.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-03-29 11:50:25 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-03-30 00:37:42 +0200
commitd447cd940d7da884f0d699d9da679d8bbabb237a (patch)
treee5a70bc4491a70498c4b4c3af473c9503410bbbd /src/arch/x86_64/CodeGen.zig
parent60879bc8ae216ddd33fab2e07d1d460e32636c95 (diff)
downloadzig-d447cd940d7da884f0d699d9da679d8bbabb237a.tar.gz
zig-d447cd940d7da884f0d699d9da679d8bbabb237a.zip
x64: track callee and caller saved registers
This is now required to correctly track and spill registers required for some ops such `mul` or `div` (both required use of `.rax` and `.rdx` registers).
Diffstat (limited to 'src/arch/x86_64/CodeGen.zig')
-rw-r--r--src/arch/x86_64/CodeGen.zig10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 744c7fbf75..854017054b 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -31,6 +31,8 @@ const bits = @import("bits.zig");
const abi = @import("abi.zig");
const Register = bits.Register;
const callee_preserved_regs = abi.callee_preserved_regs;
+const caller_preserved_regs = abi.caller_preserved_regs;
+const allocatable_registers = abi.allocatable_registers;
const c_abi_int_param_regs = abi.c_abi_int_param_regs;
const c_abi_int_return_regs = abi.c_abi_int_return_regs;
@@ -40,7 +42,7 @@ const InnerError = error{
OutOfRegisters,
};
-const RegisterManager = RegisterManagerFn(Self, Register, &callee_preserved_regs);
+const RegisterManager = RegisterManagerFn(Self, Register, &allocatable_registers);
gpa: Allocator,
air: Air,
@@ -3519,6 +3521,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
try self.spillCompareFlagsIfOccupied();
+ for (caller_preserved_regs) |reg| {
+ try self.register_manager.getReg(reg, null);
+ }
+
if (info.return_value == .stack_offset) {
const ret_ty = fn_ty.fnReturnType();
const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
@@ -3715,7 +3721,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
const result: MCValue = result: {
switch (info.return_value) {
.register => |reg| {
- if (RegisterManager.indexOfReg(&callee_preserved_regs, reg) == null) {
+ if (RegisterManager.indexOfRegIntoTracked(reg) == null) {
// Save function return value in a callee saved register
break :result try self.copyToRegisterWithInstTracking(
inst,