Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/winch/codegen/src/isa/x64/regs.rs
1693 views
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
24
fn gpr(enc: u8) -> Reg {
25
Reg::new(PReg::new(enc as usize, RegClass::Int))
26
}
27
28
/// Constructors for GPR.
29
30
pub(crate) fn rsi() -> Reg {
31
gpr(ENC_RSI)
32
}
33
pub(crate) fn rdi() -> Reg {
34
gpr(ENC_RDI)
35
}
36
pub(crate) fn rax() -> Reg {
37
gpr(ENC_RAX)
38
}
39
pub(crate) fn rcx() -> Reg {
40
gpr(ENC_RCX)
41
}
42
pub(crate) fn rdx() -> Reg {
43
gpr(ENC_RDX)
44
}
45
pub(crate) fn r8() -> Reg {
46
gpr(ENC_R8)
47
}
48
pub(crate) fn r9() -> Reg {
49
gpr(ENC_R9)
50
}
51
pub(crate) fn r10() -> Reg {
52
gpr(ENC_R10)
53
}
54
pub(crate) fn r12() -> Reg {
55
gpr(ENC_R12)
56
}
57
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
63
/// ABI, and callee-saved in SystemV and
64
/// Fastcall.
65
pub(crate) fn r14() -> Reg {
66
gpr(ENC_R14)
67
}
68
69
pub(crate) fn vmctx() -> Reg {
70
r14()
71
}
72
73
pub(crate) fn rbx() -> Reg {
74
gpr(ENC_RBX)
75
}
76
77
pub(crate) fn r15() -> Reg {
78
gpr(ENC_R15)
79
}
80
81
pub(crate) fn rsp() -> Reg {
82
gpr(ENC_RSP)
83
}
84
pub(crate) fn rbp() -> Reg {
85
gpr(ENC_RBP)
86
}
87
88
/// Used as the scratch register.
89
/// Non-allocatable in Winch's default
90
/// ABI.
91
pub(crate) fn r11() -> Reg {
92
gpr(ENC_R11)
93
}
94
95
fn fpr(enc: u8) -> Reg {
96
Reg::new(PReg::new(enc as usize, RegClass::Float))
97
}
98
99
/// Constructors for FPR.
100
101
pub(crate) fn xmm0() -> Reg {
102
fpr(0)
103
}
104
pub(crate) fn xmm1() -> Reg {
105
fpr(1)
106
}
107
pub(crate) fn xmm2() -> Reg {
108
fpr(2)
109
}
110
pub(crate) fn xmm3() -> Reg {
111
fpr(3)
112
}
113
pub(crate) fn xmm4() -> Reg {
114
fpr(4)
115
}
116
pub(crate) fn xmm5() -> Reg {
117
fpr(5)
118
}
119
pub(crate) fn xmm6() -> Reg {
120
fpr(6)
121
}
122
pub(crate) fn xmm7() -> Reg {
123
fpr(7)
124
}
125
pub(crate) fn xmm8() -> Reg {
126
fpr(8)
127
}
128
pub(crate) fn xmm9() -> Reg {
129
fpr(9)
130
}
131
pub(crate) fn xmm10() -> Reg {
132
fpr(10)
133
}
134
pub(crate) fn xmm11() -> Reg {
135
fpr(11)
136
}
137
pub(crate) fn xmm12() -> Reg {
138
fpr(12)
139
}
140
pub(crate) fn xmm13() -> Reg {
141
fpr(13)
142
}
143
pub(crate) fn xmm14() -> Reg {
144
fpr(14)
145
}
146
pub(crate) fn xmm15() -> Reg {
147
fpr(15)
148
}
149
150
/// GPR count.
151
const GPR: u32 = 16;
152
/// FPR count.
153
const FPR: u32 = 16;
154
/// GPR index bound.
155
const MAX_GPR: u32 = GPR;
156
/// GPR index bound.
157
const MAX_FPR: u32 = FPR;
158
const ALL_GPR: u32 = (1 << GPR) - 1;
159
const ALL_FPR: u32 = (1 << FPR) - 1;
160
/// Bitmask of non-alloctable GPRs.
161
// R11: Is used as the scratch register.
162
// R14: Is a pinned register, used as the instance register.
163
const SCRATCH: u32 = 1 << ENC_R11;
164
const INSTANCE: u32 = 1 << ENC_R14;
165
pub(crate) const NON_ALLOCATABLE_GPR: u32 = (1 << ENC_RBP) | (1 << ENC_RSP) | SCRATCH | INSTANCE;
166
167
/// Bitmask of non-alloctable FPRs.
168
// xmm15: Is used as the scratch register.
169
const SCRATCH_FPR: u32 = 1 << 15;
170
const NON_ALLOCATABLE_FPR: u32 = SCRATCH_FPR;
171
172
/// Bitmask to represent the available general purpose registers.
173
const ALLOCATABLE_GPR: u32 = ALL_GPR & !NON_ALLOCATABLE_GPR;
174
/// Bitmask to represent the available floating point registers.
175
const ALLOCATABLE_FPR: u32 = ALL_FPR & !NON_ALLOCATABLE_FPR;
176
177
/// Allocatable scratch general purpose registers.
178
const ALLOCATABLE_SCRATCH_GPR: u32 = SCRATCH;
179
/// Non-allocatable scratch general purpose registers.
180
const NON_ALLOCATABLE_SCRATCH_GPR: u32 = ALL_GPR & !SCRATCH;
181
182
/// Allocatable scratch floating-point registers.
183
const ALLOCATABLE_SCRATCH_FPR: u32 = SCRATCH_FPR;
184
/// Non-allocatable scratch floating-point registers.
185
const NON_ALLOCATABLE_SCRATCH_FPR: u32 = ALL_FPR & !SCRATCH_FPR;
186
187
/// Bitset for allocatable general purpose registers.
188
pub fn gpr_bit_set() -> RegBitSet {
189
RegBitSet::int(
190
ALLOCATABLE_GPR.into(),
191
NON_ALLOCATABLE_GPR.into(),
192
usize::try_from(MAX_GPR).unwrap(),
193
)
194
}
195
196
/// Bitset for allocatable floating point registers.
197
pub fn fpr_bit_set() -> RegBitSet {
198
RegBitSet::float(
199
ALLOCATABLE_FPR.into(),
200
NON_ALLOCATABLE_FPR.into(),
201
usize::try_from(MAX_FPR).unwrap(),
202
)
203
}
204
205
/// Bitset for allocatable scratch general purpose registers.
206
pub fn scratch_gpr_bitset() -> RegBitSet {
207
RegBitSet::int(
208
ALLOCATABLE_SCRATCH_GPR.into(),
209
NON_ALLOCATABLE_SCRATCH_GPR.into(),
210
usize::try_from(MAX_GPR).unwrap(),
211
)
212
}
213
214
/// Bitset for allocatable scratch floating point registers.
215
pub fn scratch_fpr_bitset() -> RegBitSet {
216
RegBitSet::float(
217
ALLOCATABLE_SCRATCH_FPR.into(),
218
NON_ALLOCATABLE_SCRATCH_FPR.into(),
219
usize::try_from(MAX_FPR).unwrap(),
220
)
221
}
222
223