winch_codegen/isa/x64/
regs.rs

1//! X64 register definition.
2
3use crate::isa::reg::Reg;
4use regalloc2::{PReg, RegClass};
5
6const ENC_RAX: u8 = 0;
7const ENC_RCX: u8 = 1;
8const ENC_RDX: u8 = 2;
9const ENC_RBX: u8 = 3;
10const ENC_RSP: u8 = 4;
11const ENC_RBP: u8 = 5;
12const ENC_RSI: u8 = 6;
13const ENC_RDI: u8 = 7;
14const ENC_R8: u8 = 8;
15const ENC_R9: u8 = 9;
16const ENC_R10: u8 = 10;
17const ENC_R11: u8 = 11;
18const ENC_R12: u8 = 12;
19const ENC_R13: u8 = 13;
20const ENC_R14: u8 = 14;
21const ENC_R15: u8 = 15;
22
23fn gpr(enc: u8) -> Reg {
24    Reg::new(PReg::new(enc as usize, RegClass::Int))
25}
26
27/// Constructors for GPR.
28
29pub(crate) fn rsi() -> Reg {
30    gpr(ENC_RSI)
31}
32pub(crate) fn rdi() -> Reg {
33    gpr(ENC_RDI)
34}
35pub(crate) fn rax() -> Reg {
36    gpr(ENC_RAX)
37}
38pub(crate) fn rcx() -> Reg {
39    gpr(ENC_RCX)
40}
41pub(crate) fn rdx() -> Reg {
42    gpr(ENC_RDX)
43}
44pub(crate) fn r8() -> Reg {
45    gpr(ENC_R8)
46}
47pub(crate) fn r9() -> Reg {
48    gpr(ENC_R9)
49}
50pub(crate) fn r10() -> Reg {
51    gpr(ENC_R10)
52}
53pub(crate) fn r12() -> Reg {
54    gpr(ENC_R12)
55}
56pub(crate) fn r13() -> Reg {
57    gpr(ENC_R13)
58}
59/// Used as a pinned register to hold
60/// the `VMContext`.
61/// Non-allocatable in Winch's default
62/// ABI, and callee-saved in SystemV and
63/// Fastcall.
64pub(crate) fn r14() -> Reg {
65    gpr(ENC_R14)
66}
67
68pub(crate) fn vmctx() -> Reg {
69    r14()
70}
71
72pub(crate) fn rbx() -> Reg {
73    gpr(ENC_RBX)
74}
75
76pub(crate) fn r15() -> Reg {
77    gpr(ENC_R15)
78}
79
80pub(crate) fn rsp() -> Reg {
81    gpr(ENC_RSP)
82}
83pub(crate) fn rbp() -> Reg {
84    gpr(ENC_RBP)
85}
86
87/// Used as the scratch register.
88/// Non-allocatable in Winch's default
89/// ABI.
90pub(crate) fn r11() -> Reg {
91    gpr(ENC_R11)
92}
93
94pub(crate) fn scratch() -> Reg {
95    r11()
96}
97
98fn fpr(enc: u8) -> Reg {
99    Reg::new(PReg::new(enc as usize, RegClass::Float))
100}
101
102/// Constructors for FPR.
103
104pub(crate) fn xmm0() -> Reg {
105    fpr(0)
106}
107pub(crate) fn xmm1() -> Reg {
108    fpr(1)
109}
110pub(crate) fn xmm2() -> Reg {
111    fpr(2)
112}
113pub(crate) fn xmm3() -> Reg {
114    fpr(3)
115}
116pub(crate) fn xmm4() -> Reg {
117    fpr(4)
118}
119pub(crate) fn xmm5() -> Reg {
120    fpr(5)
121}
122pub(crate) fn xmm6() -> Reg {
123    fpr(6)
124}
125pub(crate) fn xmm7() -> Reg {
126    fpr(7)
127}
128pub(crate) fn xmm8() -> Reg {
129    fpr(8)
130}
131pub(crate) fn xmm9() -> Reg {
132    fpr(9)
133}
134pub(crate) fn xmm10() -> Reg {
135    fpr(10)
136}
137pub(crate) fn xmm11() -> Reg {
138    fpr(11)
139}
140pub(crate) fn xmm12() -> Reg {
141    fpr(12)
142}
143pub(crate) fn xmm13() -> Reg {
144    fpr(13)
145}
146pub(crate) fn xmm14() -> Reg {
147    fpr(14)
148}
149pub(crate) fn xmm15() -> Reg {
150    fpr(15)
151}
152
153pub(crate) fn scratch_xmm() -> Reg {
154    xmm15()
155}
156
157/// GPR count.
158const GPR: u32 = 16;
159/// FPR count.
160const FPR: u32 = 16;
161/// GPR index bound.
162pub(crate) const MAX_GPR: u32 = GPR;
163/// GPR index bound.
164pub(crate) const MAX_FPR: u32 = FPR;
165const ALLOCATABLE_GPR: u32 = (1 << GPR) - 1;
166const ALLOCATABLE_FPR: u32 = (1 << FPR) - 1;
167/// Bitmask of non-alloctable GPRs.
168// R11: Is used as the scratch register.
169// R14: Is a pinned register, used as the instance register.
170pub(crate) const NON_ALLOCATABLE_GPR: u32 =
171    (1 << ENC_RBP) | (1 << ENC_RSP) | (1 << ENC_R11) | (1 << ENC_R14);
172
173/// Bitmask of non-alloctable FPRs.
174// xmm15: Is used as the scratch register.
175pub(crate) const NON_ALLOCATABLE_FPR: u32 = 1 << 15;
176
177/// Bitmask to represent the available general purpose registers.
178pub(crate) const ALL_GPR: u32 = ALLOCATABLE_GPR & !NON_ALLOCATABLE_GPR;
179/// Bitmask to represent the available floating point registers.
180pub(crate) const ALL_FPR: u32 = ALLOCATABLE_FPR & !NON_ALLOCATABLE_FPR;