1 //! X64 register definition.
2
3 use crate::isa::reg::Reg;
4 use crate::regset::RegBitSet;
5 use regalloc2::{PReg, RegClass};
6
7 const ENC_RAX: u8 = 0;
8 const ENC_RCX: u8 = 1;
9 const ENC_RDX: u8 = 2;
10 const ENC_RBX: u8 = 3;
11 const ENC_RSP: u8 = 4;
12 const ENC_RBP: u8 = 5;
13 const ENC_RSI: u8 = 6;
14 const ENC_RDI: u8 = 7;
15 const ENC_R8: u8 = 8;
16 const ENC_R9: u8 = 9;
17 const ENC_R10: u8 = 10;
18 const ENC_R11: u8 = 11;
19 const ENC_R12: u8 = 12;
20 const ENC_R13: u8 = 13;
21 const ENC_R14: u8 = 14;
22 const ENC_R15: u8 = 15;
23
gpr(enc: u8) -> Reg24 fn gpr(enc: u8) -> Reg {
25 Reg::new(PReg::new(enc as usize, RegClass::Int))
26 }
27
28 /// Constructors for GPR.
29
rsi() -> Reg30 pub(crate) fn rsi() -> Reg {
31 gpr(ENC_RSI)
32 }
rdi() -> Reg33 pub(crate) fn rdi() -> Reg {
34 gpr(ENC_RDI)
35 }
rax() -> Reg36 pub(crate) fn rax() -> Reg {
37 gpr(ENC_RAX)
38 }
rcx() -> Reg39 pub(crate) fn rcx() -> Reg {
40 gpr(ENC_RCX)
41 }
rdx() -> Reg42 pub(crate) fn rdx() -> Reg {
43 gpr(ENC_RDX)
44 }
r8() -> Reg45 pub(crate) fn r8() -> Reg {
46 gpr(ENC_R8)
47 }
r9() -> Reg48 pub(crate) fn r9() -> Reg {
49 gpr(ENC_R9)
50 }
r10() -> Reg51 pub(crate) fn r10() -> Reg {
52 gpr(ENC_R10)
53 }
r12() -> Reg54 pub(crate) fn r12() -> Reg {
55 gpr(ENC_R12)
56 }
r13() -> Reg57 pub(crate) fn r13() -> Reg {
58 gpr(ENC_R13)
59 }
60 /// Used as a pinned register to hold
61 /// the `VMContext`.
62 /// Non-allocatable in Winch's default ABI.
r14() -> Reg63 pub(crate) fn r14() -> Reg {
64 gpr(ENC_R14)
65 }
66
vmctx() -> Reg67 pub(crate) fn vmctx() -> Reg {
68 r14()
69 }
70
rbx() -> Reg71 pub(crate) fn rbx() -> Reg {
72 gpr(ENC_RBX)
73 }
74
r15() -> Reg75 pub(crate) fn r15() -> Reg {
76 gpr(ENC_R15)
77 }
78
rsp() -> Reg79 pub(crate) fn rsp() -> Reg {
80 gpr(ENC_RSP)
81 }
rbp() -> Reg82 pub(crate) fn rbp() -> Reg {
83 gpr(ENC_RBP)
84 }
85
86 /// Used as the scratch register.
87 /// Non-allocatable in Winch's default
88 /// ABI.
r11() -> Reg89 pub(crate) fn r11() -> Reg {
90 gpr(ENC_R11)
91 }
92
fpr(enc: u8) -> Reg93 fn fpr(enc: u8) -> Reg {
94 Reg::new(PReg::new(enc as usize, RegClass::Float))
95 }
96
97 /// Constructors for FPR.
98
xmm0() -> Reg99 pub(crate) fn xmm0() -> Reg {
100 fpr(0)
101 }
xmm1() -> Reg102 pub(crate) fn xmm1() -> Reg {
103 fpr(1)
104 }
xmm2() -> Reg105 pub(crate) fn xmm2() -> Reg {
106 fpr(2)
107 }
xmm3() -> Reg108 pub(crate) fn xmm3() -> Reg {
109 fpr(3)
110 }
xmm4() -> Reg111 pub(crate) fn xmm4() -> Reg {
112 fpr(4)
113 }
xmm5() -> Reg114 pub(crate) fn xmm5() -> Reg {
115 fpr(5)
116 }
xmm6() -> Reg117 pub(crate) fn xmm6() -> Reg {
118 fpr(6)
119 }
xmm7() -> Reg120 pub(crate) fn xmm7() -> Reg {
121 fpr(7)
122 }
xmm8() -> Reg123 pub(crate) fn xmm8() -> Reg {
124 fpr(8)
125 }
xmm9() -> Reg126 pub(crate) fn xmm9() -> Reg {
127 fpr(9)
128 }
xmm10() -> Reg129 pub(crate) fn xmm10() -> Reg {
130 fpr(10)
131 }
xmm11() -> Reg132 pub(crate) fn xmm11() -> Reg {
133 fpr(11)
134 }
xmm12() -> Reg135 pub(crate) fn xmm12() -> Reg {
136 fpr(12)
137 }
xmm13() -> Reg138 pub(crate) fn xmm13() -> Reg {
139 fpr(13)
140 }
xmm14() -> Reg141 pub(crate) fn xmm14() -> Reg {
142 fpr(14)
143 }
xmm15() -> Reg144 pub(crate) fn xmm15() -> Reg {
145 fpr(15)
146 }
147
148 /// GPR count.
149 const GPR: u32 = 16;
150 /// FPR count.
151 const FPR: u32 = 16;
152 /// GPR index bound.
153 const MAX_GPR: u32 = GPR;
154 /// GPR index bound.
155 const MAX_FPR: u32 = FPR;
156 const ALL_GPR: u32 = (1 << GPR) - 1;
157 const ALL_FPR: u32 = (1 << FPR) - 1;
158 /// Bitmask of non-alloctable GPRs.
159 // R11: Is used as the scratch register.
160 // R14: Is a pinned register, used as the instance register.
161 const SCRATCH: u32 = 1 << ENC_R11;
162 const INSTANCE: u32 = 1 << ENC_R14;
163 pub(crate) const NON_ALLOCATABLE_GPR: u32 = (1 << ENC_RBP) | (1 << ENC_RSP) | SCRATCH | INSTANCE;
164
165 /// Bitmask of non-alloctable FPRs.
166 // xmm15: Is used as the scratch register.
167 const SCRATCH_FPR: u32 = 1 << 15;
168 const NON_ALLOCATABLE_FPR: u32 = SCRATCH_FPR;
169
170 /// Bitmask to represent the available general purpose registers.
171 const ALLOCATABLE_GPR: u32 = ALL_GPR & !NON_ALLOCATABLE_GPR;
172 /// Bitmask to represent the available floating point registers.
173 const ALLOCATABLE_FPR: u32 = ALL_FPR & !NON_ALLOCATABLE_FPR;
174
175 /// Allocatable scratch general purpose registers.
176 const ALLOCATABLE_SCRATCH_GPR: u32 = SCRATCH;
177 /// Non-allocatable scratch general purpose registers.
178 const NON_ALLOCATABLE_SCRATCH_GPR: u32 = ALL_GPR & !SCRATCH;
179
180 /// Allocatable scratch floating-point registers.
181 const ALLOCATABLE_SCRATCH_FPR: u32 = SCRATCH_FPR;
182 /// Non-allocatable scratch floating-point registers.
183 const NON_ALLOCATABLE_SCRATCH_FPR: u32 = ALL_FPR & !SCRATCH_FPR;
184
185 /// Bitset for allocatable general purpose registers.
gpr_bit_set() -> RegBitSet186 pub fn gpr_bit_set() -> RegBitSet {
187 RegBitSet::int(
188 ALLOCATABLE_GPR.into(),
189 NON_ALLOCATABLE_GPR.into(),
190 usize::try_from(MAX_GPR).unwrap(),
191 )
192 }
193
194 /// Bitset for allocatable floating point registers.
fpr_bit_set() -> RegBitSet195 pub fn fpr_bit_set() -> RegBitSet {
196 RegBitSet::float(
197 ALLOCATABLE_FPR.into(),
198 NON_ALLOCATABLE_FPR.into(),
199 usize::try_from(MAX_FPR).unwrap(),
200 )
201 }
202
203 /// Bitset for allocatable scratch general purpose registers.
scratch_gpr_bitset() -> RegBitSet204 pub fn scratch_gpr_bitset() -> RegBitSet {
205 RegBitSet::int(
206 ALLOCATABLE_SCRATCH_GPR.into(),
207 NON_ALLOCATABLE_SCRATCH_GPR.into(),
208 usize::try_from(MAX_GPR).unwrap(),
209 )
210 }
211
212 /// Bitset for allocatable scratch floating point registers.
scratch_fpr_bitset() -> RegBitSet213 pub fn scratch_fpr_bitset() -> RegBitSet {
214 RegBitSet::float(
215 ALLOCATABLE_SCRATCH_FPR.into(),
216 NON_ALLOCATABLE_SCRATCH_FPR.into(),
217 usize::try_from(MAX_FPR).unwrap(),
218 )
219 }
220