1 /*
2 * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef CPU_AARCH64_REGISTER_AARCH64_HPP
27 #define CPU_AARCH64_REGISTER_AARCH64_HPP
28
29 #include "asm/register.hpp"
30 #include "utilities/checkedCast.hpp"
31 #include "utilities/powerOfTwo.hpp"
32
33 class VMRegImpl;
34 typedef VMRegImpl* VMReg;
35
36 class Register {
37 private:
38 int _encoding;
39
40 constexpr explicit Register(int encoding) : _encoding(encoding) {}
41
42 public:
43 enum {
44 number_of_registers = 32,
45 number_of_declared_registers = 34, // Including SP and ZR.
46 max_slots_per_register = 2
47 };
48
49 class RegisterImpl: public AbstractRegisterImpl {
50 friend class Register;
51
52 static constexpr const RegisterImpl* first();
53
54 public:
55 // accessors
56 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
57 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
58 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
59
60 // derived registers, offsets, and addresses
61 inline Register successor() const;
62
63 VMReg as_VMReg() const;
64
65 const char* name() const;
66 };
67
68 inline friend constexpr Register as_Register(int encoding);
69
70 constexpr Register() : _encoding(-1) {} // noreg
71
72 int operator==(const Register r) const { return _encoding == r._encoding; }
73 int operator!=(const Register r) const { return _encoding != r._encoding; }
74
75 constexpr const RegisterImpl* operator->() const { return RegisterImpl::first() + _encoding; }
76 };
77
78 extern Register::RegisterImpl all_RegisterImpls[Register::number_of_declared_registers + 1] INTERNAL_VISIBILITY;
79
80 inline constexpr const Register::RegisterImpl* Register::RegisterImpl::first() {
81 return all_RegisterImpls + 1;
82 }
83
84 constexpr Register noreg = Register();
85
86 inline constexpr Register as_Register(int encoding) {
87 if (0 <= encoding && encoding < Register::number_of_declared_registers) {
88 return Register(encoding);
89 }
90 return noreg;
91 }
92
93 inline Register Register::RegisterImpl::successor() const {
94 assert(is_valid(), "sanity");
95 return as_Register(encoding() + 1);
96 }
97
98 // The integer registers of the AArch64 architecture
99 constexpr Register r0 = as_Register( 0);
100 constexpr Register r1 = as_Register( 1);
101 constexpr Register r2 = as_Register( 2);
102 constexpr Register r3 = as_Register( 3);
103 constexpr Register r4 = as_Register( 4);
104 constexpr Register r5 = as_Register( 5);
105 constexpr Register r6 = as_Register( 6);
106 constexpr Register r7 = as_Register( 7);
107 constexpr Register r8 = as_Register( 8);
108 constexpr Register r9 = as_Register( 9);
109 constexpr Register r10 = as_Register(10);
110 constexpr Register r11 = as_Register(11);
111 constexpr Register r12 = as_Register(12);
112 constexpr Register r13 = as_Register(13);
113 constexpr Register r14 = as_Register(14);
114 constexpr Register r15 = as_Register(15);
115 constexpr Register r16 = as_Register(16);
116 constexpr Register r17 = as_Register(17);
117
118 // In the ABI for Windows+AArch64 the register r18 is used to store the pointer
119 // to the current thread's TEB (where TLS variables are stored). We could
120 // carefully save and restore r18 at key places, however Win32 Structured
121 // Exception Handling (SEH) is using TLS to unwind the stack. If r18 is used
122 // for any other purpose at the time of an exception happening, SEH would not
123 // be able to unwind the stack properly and most likely crash.
124 //
125 // It's easier to avoid allocating r18 altogether.
126 //
127 // See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers
128 constexpr Register r18_tls = as_Register(18);
129 constexpr Register r19 = as_Register(19);
130 constexpr Register r20 = as_Register(20);
131 constexpr Register r21 = as_Register(21);
132 constexpr Register r22 = as_Register(22);
133 constexpr Register r23 = as_Register(23);
134 constexpr Register r24 = as_Register(24);
135 constexpr Register r25 = as_Register(25);
136 constexpr Register r26 = as_Register(26);
137 constexpr Register r27 = as_Register(27);
138 constexpr Register r28 = as_Register(28);
139 constexpr Register r29 = as_Register(29);
140 constexpr Register r30 = as_Register(30);
141
142
143 // r31 is not a general purpose register, but represents either the
144 // stack pointer or the zero/discard register depending on the
145 // instruction.
146 constexpr Register r31_sp = as_Register(31);
147 constexpr Register zr = as_Register(32);
148 constexpr Register sp = as_Register(33);
149
150 // Used as a filler in instructions where a register field is unused.
151 constexpr Register dummy_reg = r31_sp;
152
153
154 // The implementation of floating point registers for the architecture
155 class FloatRegister {
156 private:
157 int _encoding;
158
159 constexpr explicit FloatRegister(int encoding) : _encoding(encoding) {}
160
161 public:
162 inline friend constexpr FloatRegister as_FloatRegister(int encoding);
163
164 enum {
165 number_of_registers = 32,
166 max_slots_per_register = 4,
167 save_slots_per_register = 2,
168 slots_per_neon_register = 4,
169 extra_save_slots_per_neon_register = slots_per_neon_register - save_slots_per_register,
170 neon_vl = 16,
171 // VLmax: The maximum sve vector length is determined by the hardware
172 // sve_vl_min <= VLmax <= sve_vl_max.
173 sve_vl_min = 16,
174 // Maximum supported vector length across all CPUs
175 sve_vl_max = 256
176 };
177
178 class FloatRegisterImpl: public AbstractRegisterImpl {
179 friend class FloatRegister;
180
181 static constexpr const FloatRegisterImpl* first();
182
183 public:
184 // accessors
185 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
186 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
187 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
188
189 // derived registers, offsets, and addresses
190 inline FloatRegister successor() const;
191
192 VMReg as_VMReg() const;
193
194 const char* name() const;
195 };
196
197 constexpr FloatRegister() : _encoding(-1) {} // fnoreg
198
199 int operator==(const FloatRegister r) const { return _encoding == r._encoding; }
200 int operator!=(const FloatRegister r) const { return _encoding != r._encoding; }
201
202 constexpr const FloatRegisterImpl* operator->() const { return FloatRegisterImpl::first() + _encoding; }
203 };
204
205 extern FloatRegister::FloatRegisterImpl all_FloatRegisterImpls[FloatRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
206
207 inline constexpr const FloatRegister::FloatRegisterImpl* FloatRegister::FloatRegisterImpl::first() {
208 return all_FloatRegisterImpls + 1;
209 }
210
211 constexpr FloatRegister fnoreg = FloatRegister();
212
213 inline constexpr FloatRegister as_FloatRegister(int encoding) {
214 if (0 <= encoding && encoding < FloatRegister::number_of_registers) {
215 return FloatRegister(encoding);
216 }
217 return fnoreg;
218 }
219
220 inline FloatRegister FloatRegister::FloatRegisterImpl::successor() const {
221 assert(is_valid(), "sanity");
222 return as_FloatRegister((encoding() + 1) % number_of_registers);
223 }
224
225 // The float registers of the AArch64 architecture
226 constexpr FloatRegister v0 = as_FloatRegister( 0);
227 constexpr FloatRegister v1 = as_FloatRegister( 1);
228 constexpr FloatRegister v2 = as_FloatRegister( 2);
229 constexpr FloatRegister v3 = as_FloatRegister( 3);
230 constexpr FloatRegister v4 = as_FloatRegister( 4);
231 constexpr FloatRegister v5 = as_FloatRegister( 5);
232 constexpr FloatRegister v6 = as_FloatRegister( 6);
233 constexpr FloatRegister v7 = as_FloatRegister( 7);
234 constexpr FloatRegister v8 = as_FloatRegister( 8);
235 constexpr FloatRegister v9 = as_FloatRegister( 9);
236 constexpr FloatRegister v10 = as_FloatRegister(10);
237 constexpr FloatRegister v11 = as_FloatRegister(11);
238 constexpr FloatRegister v12 = as_FloatRegister(12);
239 constexpr FloatRegister v13 = as_FloatRegister(13);
240 constexpr FloatRegister v14 = as_FloatRegister(14);
241 constexpr FloatRegister v15 = as_FloatRegister(15);
242 constexpr FloatRegister v16 = as_FloatRegister(16);
243 constexpr FloatRegister v17 = as_FloatRegister(17);
244 constexpr FloatRegister v18 = as_FloatRegister(18);
245 constexpr FloatRegister v19 = as_FloatRegister(19);
246 constexpr FloatRegister v20 = as_FloatRegister(20);
247 constexpr FloatRegister v21 = as_FloatRegister(21);
248 constexpr FloatRegister v22 = as_FloatRegister(22);
249 constexpr FloatRegister v23 = as_FloatRegister(23);
250 constexpr FloatRegister v24 = as_FloatRegister(24);
251 constexpr FloatRegister v25 = as_FloatRegister(25);
252 constexpr FloatRegister v26 = as_FloatRegister(26);
253 constexpr FloatRegister v27 = as_FloatRegister(27);
254 constexpr FloatRegister v28 = as_FloatRegister(28);
255 constexpr FloatRegister v29 = as_FloatRegister(29);
256 constexpr FloatRegister v30 = as_FloatRegister(30);
257 constexpr FloatRegister v31 = as_FloatRegister(31);
258
259 // SVE vector registers, shared with the SIMD&FP v0-v31. Vn maps to Zn[127:0].
260 constexpr FloatRegister z0 = v0;
261 constexpr FloatRegister z1 = v1;
262 constexpr FloatRegister z2 = v2;
263 constexpr FloatRegister z3 = v3;
264 constexpr FloatRegister z4 = v4;
265 constexpr FloatRegister z5 = v5;
266 constexpr FloatRegister z6 = v6;
267 constexpr FloatRegister z7 = v7;
268 constexpr FloatRegister z8 = v8;
269 constexpr FloatRegister z9 = v9;
270 constexpr FloatRegister z10 = v10;
271 constexpr FloatRegister z11 = v11;
272 constexpr FloatRegister z12 = v12;
273 constexpr FloatRegister z13 = v13;
274 constexpr FloatRegister z14 = v14;
275 constexpr FloatRegister z15 = v15;
276 constexpr FloatRegister z16 = v16;
277 constexpr FloatRegister z17 = v17;
278 constexpr FloatRegister z18 = v18;
279 constexpr FloatRegister z19 = v19;
280 constexpr FloatRegister z20 = v20;
281 constexpr FloatRegister z21 = v21;
282 constexpr FloatRegister z22 = v22;
283 constexpr FloatRegister z23 = v23;
284 constexpr FloatRegister z24 = v24;
285 constexpr FloatRegister z25 = v25;
286 constexpr FloatRegister z26 = v26;
287 constexpr FloatRegister z27 = v27;
288 constexpr FloatRegister z28 = v28;
289 constexpr FloatRegister z29 = v29;
290 constexpr FloatRegister z30 = v30;
291 constexpr FloatRegister z31 = v31;
292
293
294 // The implementation of predicate registers for the architecture
295 class PRegister {
296 int _encoding;
297
298 constexpr explicit PRegister(int encoding) : _encoding(encoding) {}
299
300 public:
301 inline friend constexpr PRegister as_PRegister(int encoding);
302
303 enum {
304 number_of_registers = 16,
305 number_of_governing_registers = 8,
306 max_slots_per_register = 1
307 };
308
309 constexpr PRegister() : _encoding(-1) {} // pnoreg
310
311 class PRegisterImpl: public AbstractRegisterImpl {
312 friend class PRegister;
313
314 static constexpr const PRegisterImpl* first();
315
316 public:
317 // accessors
318 int raw_encoding() const { return checked_cast<int>(this - first()); }
319 int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
320 bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
321 bool is_governing() const { return 0 <= raw_encoding() && raw_encoding() < number_of_governing_registers; }
322
323 // derived registers, offsets, and addresses
324 inline PRegister successor() const;
325
326 VMReg as_VMReg() const;
327
328 const char* name() const;
329 };
330
331 int operator==(const PRegister r) const { return _encoding == r._encoding; }
332 int operator!=(const PRegister r) const { return _encoding != r._encoding; }
333
334 const PRegisterImpl* operator->() const { return PRegisterImpl::first() + _encoding; }
335 };
336
337 extern PRegister::PRegisterImpl all_PRegisterImpls[PRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
338
339 inline constexpr const PRegister::PRegisterImpl* PRegister::PRegisterImpl::first() {
340 return all_PRegisterImpls + 1;
341 }
342
343 constexpr PRegister pnoreg = PRegister();
344
345 inline constexpr PRegister as_PRegister(int encoding) {
346 if (0 <= encoding && encoding < PRegister::number_of_registers) {
347 return PRegister(encoding);
348 }
349 return pnoreg;
350 }
351
352 inline PRegister PRegister::PRegisterImpl::successor() const {
353 assert(is_valid(), "sanity");
354 return as_PRegister(encoding() + 1);
355 }
356
357 // The predicate registers of SVE.
358 constexpr PRegister p0 = as_PRegister( 0);
359 constexpr PRegister p1 = as_PRegister( 1);
360 constexpr PRegister p2 = as_PRegister( 2);
361 constexpr PRegister p3 = as_PRegister( 3);
362 constexpr PRegister p4 = as_PRegister( 4);
363 constexpr PRegister p5 = as_PRegister( 5);
364 constexpr PRegister p6 = as_PRegister( 6);
365 constexpr PRegister p7 = as_PRegister( 7);
366 constexpr PRegister p8 = as_PRegister( 8);
367 constexpr PRegister p9 = as_PRegister( 9);
368 constexpr PRegister p10 = as_PRegister(10);
369 constexpr PRegister p11 = as_PRegister(11);
370 constexpr PRegister p12 = as_PRegister(12);
371 constexpr PRegister p13 = as_PRegister(13);
372 constexpr PRegister p14 = as_PRegister(14);
373 constexpr PRegister p15 = as_PRegister(15);
374
375 // Need to know the total number of registers of all sorts for SharedInfo.
376 // Define a class that exports it.
377 class ConcreteRegisterImpl : public AbstractRegisterImpl {
378 public:
379 enum {
380 max_gpr = Register::number_of_registers * Register::max_slots_per_register,
381 max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register,
382 max_pr = max_fpr + PRegister::number_of_registers * PRegister::max_slots_per_register,
383
384 // A big enough number for C2: all the registers plus flags
385 // This number must be large enough to cover REG_COUNT (defined by c2) registers.
386 // There is no requirement that any ordering here matches any ordering c2 gives
387 // it's optoregs.
388 number_of_registers = max_pr + 1 // gpr/fpr/pr + flags
389 };
390 };
391
392 typedef AbstractRegSet<Register> RegSet;
393 typedef AbstractRegSet<FloatRegister> FloatRegSet;
394 typedef AbstractRegSet<PRegister> PRegSet;
395
396 template <>
397 inline Register AbstractRegSet<Register>::first() {
398 if (_bitset == 0) { return noreg; }
399 return as_Register(count_trailing_zeros(_bitset));
400 }
401
402 template <>
403 inline FloatRegister AbstractRegSet<FloatRegister>::first() {
404 if (_bitset == 0) { return fnoreg; }
405 return as_FloatRegister(count_trailing_zeros(_bitset));
406 }
407
408 inline Register as_Register(FloatRegister reg) {
409 return as_Register(reg->encoding());
410 }
411
412 // High-level register class of an OptoReg or a VMReg register.
413 enum RC { rc_bad, rc_int, rc_float, rc_predicate, rc_stack };
414
415 // AArch64 Vector Register Sequence management support
416 //
417 // VSeq implements an indexable (by operator[]) vector register
418 // sequence starting from a fixed base register and with a fixed delta
419 // (defaulted to 1, but sometimes 0 or 2) e.g. VSeq<4>(16) will return
420 // registers v16, ... v19 for indices 0, ... 3.
421 //
422 // Generator methods may iterate across sets of VSeq<4> to schedule an
423 // operation 4 times using distinct input and output registers,
424 // profiting from 4-way instruction parallelism.
425 //
426 // A VSeq<2> can be used to specify registers loaded with special
427 // constants e.g. <v30, v31> --> <MONT_Q, MONT_Q_INV_MOD_R>.
428 //
429 // A VSeq with base n and delta 0 can be used to generate code that
430 // combines values in another VSeq with the constant in register vn.
431 //
432 // A VSeq with base n and delta 2 can be used to select an odd or even
433 // indexed set of registers.
434 //
435 // Methods which accept arguments of type VSeq<8>, may split their
436 // inputs into front and back halves or odd and even halves (see
437 // convenience methods below).
438
439 // helper macro for computing register masks
440 #define VS_MASK_BIT(base, delta, i) (1 << (base + delta * i))
441
442 template<int N> class VSeq {
443 static_assert(N >= 2, "vector sequence length must be greater than 1");
444 private:
445 int _base; // index of first register in sequence
446 int _delta; // increment to derive successive indices
447 public:
448 VSeq(FloatRegister base_reg, int delta = 1) : VSeq(base_reg->encoding(), delta) { }
449 VSeq(int base, int delta = 1) : _base(base), _delta(delta) {
450 assert (_base >= 0 && _base <= 31, "invalid base register");
451 assert ((_base + (N - 1) * _delta) >= 0, "register range underflow");
452 assert ((_base + (N - 1) * _delta) < 32, "register range overflow");
453 }
454 // indexed access to sequence
455 FloatRegister operator [](int i) const {
456 assert (0 <= i && i < N, "index out of bounds");
457 return as_FloatRegister(_base + i * _delta);
458 }
459 int mask() const {
460 int m = 0;
461 for (int i = 0; i < N; i++) {
462 m |= VS_MASK_BIT(_base, _delta, i);
463 }
464 return m;
465 }
466 int base() const { return _base; }
467 int delta() const { return _delta; }
468 bool is_constant() const { return _delta == 0; }
469 };
470
471 // methods for use in asserts to check VSeq inputs and outputs are
472 // either disjoint or equal
473
474 template<int N, int M> bool vs_disjoint(const VSeq<N>& n, const VSeq<M>& m) { return (n.mask() & m.mask()) == 0; }
475 template<int N> bool vs_same(const VSeq<N>& n, const VSeq<N>& m) { return n.mask() == m.mask(); }
476
477 // method for use in asserts to check whether registers appearing in
478 // an output sequence will be written before they are read from an
479 // input sequence.
480
481 template<int N> bool vs_write_before_read(const VSeq<N>& vout, const VSeq<N>& vin) {
482 int b_in = vin.base();
483 int d_in = vin.delta();
484 int b_out = vout.base();
485 int d_out = vout.delta();
486 int bit_in = 1 << b_in;
487 int bit_out = 1 << b_out;
488 int mask_read = vin.mask(); // all pending reads
489 int mask_write = 0; // no writes as yet
490
491
492 for (int i = 0; i < N - 1; i++) {
493 // check whether a pending read clashes with a write
494 if ((mask_write & mask_read) != 0) {
495 return true;
496 }
497 // remove the pending input (so long as this is a constant
498 // sequence)
499 if (d_in != 0) {
500 mask_read ^= VS_MASK_BIT(b_in, d_in, i);
501 }
502 // record the next write
503 mask_write |= VS_MASK_BIT(b_out, d_out, i);
504 }
505 // no write before read
506 return false;
507 }
508
509 // convenience methods for splitting 8-way or 4-way vector register
510 // sequences in half -- needed because vector operations can normally
511 // benefit from 4-way instruction parallelism or, occasionally, 2-way
512 // parallelism
513
514 template<int N>
515 VSeq<N/2> vs_front(const VSeq<N>& v) {
516 static_assert(N > 0 && ((N & 1) == 0), "sequence length must be even");
517 return VSeq<N/2>(v.base(), v.delta());
518 }
519
520 template<int N>
521 VSeq<N/2> vs_back(const VSeq<N>& v) {
522 static_assert(N > 0 && ((N & 1) == 0), "sequence length must be even");
523 return VSeq<N/2>(v.base() + N / 2 * v.delta(), v.delta());
524 }
525
526 template<int N>
527 VSeq<N/2> vs_even(const VSeq<N>& v) {
528 static_assert(N > 0 && ((N & 1) == 0), "sequence length must be even");
529 return VSeq<N/2>(v.base(), v.delta() * 2);
530 }
531
532 template<int N>
533 VSeq<N/2> vs_odd(const VSeq<N>& v) {
534 static_assert(N > 0 && ((N & 1) == 0), "sequence length must be even");
535 return VSeq<N/2>(v.base() + v.delta(), v.delta() * 2);
536 }
537
538 // convenience method to construct a vector register sequence that
539 // indexes its elements in reverse order to the original
540
541 template<int N>
542 VSeq<N> vs_reverse(const VSeq<N>& v) {
543 return VSeq<N>(v.base() + (N - 1) * v.delta(), -v.delta());
544 }
545
546 #endif // CPU_AARCH64_REGISTER_AARCH64_HPP