v / vlib / v2 / gen / x64 / abi.v
103 lines · 87 sloc · 2.13 KB · 1918e1160b29b144758ae6675de359f82939346b
Raw
1// Copyright (c) 2026 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4
5module x64
6
7pub enum X64Abi {
8 sysv
9 windows
10}
11
12const x64_no_arg_reg = -1
13
14fn (abi X64Abi) int_arg_regs() []int {
15 return match abi {
16 .sysv { [int(rdi), int(rsi), int(rdx), int(rcx), int(r8), int(r9)] }
17 .windows { [int(rcx), int(rdx), int(r8), int(r9)] }
18 }
19}
20
21fn (abi X64Abi) sret_arg_regs() []int {
22 return match abi {
23 .sysv { [int(rsi), int(rdx), int(rcx), int(r8), int(r9)] }
24 .windows { [int(rdx), int(r8), int(r9)] }
25 }
26}
27
28fn (abi X64Abi) sret_reg() Reg {
29 return match abi {
30 .sysv { rdi }
31 .windows { rcx }
32 }
33}
34
35fn (abi X64Abi) float_arg_regs() []int {
36 return match abi {
37 .sysv { [0, 1, 2, 3, 4, 5, 6, 7] }
38 .windows { [0, 1, 2, 3] }
39 }
40}
41
42fn (abi X64Abi) uses_positional_arg_regs() bool {
43 return abi == .windows
44}
45
46fn (abi X64Abi) int_arg_reg_at(index int) int {
47 regs := abi.int_arg_regs()
48 if index < 0 || index >= regs.len {
49 return x64_no_arg_reg
50 }
51 return regs[index]
52}
53
54fn (abi X64Abi) float_arg_reg_at(index int) int {
55 regs := abi.float_arg_regs()
56 if index < 0 || index >= regs.len {
57 return x64_no_arg_reg
58 }
59 return regs[index]
60}
61
62fn (abi X64Abi) int_arg_reg_for_position(arg_idx int) int {
63 return match abi {
64 .sysv { abi.int_arg_reg_at(arg_idx) }
65 .windows { abi.int_arg_reg_at(arg_idx) }
66 }
67}
68
69fn (abi X64Abi) float_arg_reg_for_position(arg_idx int) int {
70 return match abi {
71 .sysv { abi.float_arg_reg_at(arg_idx) }
72 .windows { abi.float_arg_reg_at(arg_idx) }
73 }
74}
75
76fn (abi X64Abi) shadow_space_size() int {
77 return match abi {
78 .sysv { 0 }
79 .windows { 32 }
80 }
81}
82
83fn (abi X64Abi) stack_arg_offset(position int) int {
84 return match abi {
85 .sysv { 16 + position * 8 }
86 .windows { 48 + (position - 4) * 8 }
87 }
88}
89
90fn (abi X64Abi) call_stack_arg_offset(position int) int {
91 return match abi {
92 .sysv { position * 8 }
93 .windows { abi.shadow_space_size() + (position - 4) * 8 }
94 }
95}
96
97fn (abi X64Abi) call_frame_size(stack_slots int) int {
98 base := abi.shadow_space_size() + stack_slots * 8
99 if base % 16 == 0 {
100 return base
101 }
102 return base + (16 - (base % 16))
103}
104