1 /*
2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #ifndef CPU_ARM_VM_REGISTER_ARM_HPP
26 #define CPU_ARM_VM_REGISTER_ARM_HPP
27 
28 #include "asm/register.hpp"
29 #include "runtime/vm_version.hpp"
30 
31 class VMRegImpl;
32 typedef VMRegImpl* VMReg;
33 
34 // These are declared ucontext.h
35 #undef R0
36 #undef R1
37 #undef R2
38 #undef R3
39 #undef R4
40 #undef R5
41 #undef R6
42 #undef R7
43 #undef R8
44 #undef R9
45 #undef R10
46 #undef R11
47 #undef R12
48 #undef R13
49 #undef R14
50 #undef R15
51 
52 #define R(r)   ((Register)(r))
53 
54 /////////////////////////////////
55 // Support for different ARM ABIs
56 // Note: default ABI is for linux
57 
58 
59 // R9_IS_SCRATCHED
60 //
61 // The ARM ABI does not guarantee that R9 is callee saved.
62 // Set R9_IS_SCRATCHED to 1 to ensure it is properly saved/restored by
63 // the caller.
64 #ifndef R9_IS_SCRATCHED
65 // Default: R9 is callee saved
66 #define R9_IS_SCRATCHED 0
67 #endif
68 
69 #ifndef AARCH64
70 // FP_REG_NUM
71 //
72 // The ARM ABI does not state which register is used for the frame pointer.
73 // Note: for the ABIs we are currently aware of, FP is currently
74 // either R7 or R11. Code may have to be extended if a third register
75 // register must be supported (see altFP_7_11).
76 #ifndef FP_REG_NUM
77 // Default: FP is R11
78 #define FP_REG_NUM 11
79 #endif
80 #endif // AARCH64
81 
82 // ALIGN_WIDE_ARGUMENTS
83 //
84 // The ARM ABI requires 64-bits arguments to be aligned on 4 words
85 // or on even registers. Set ALIGN_WIDE_ARGUMENTS to 1 for that behavior.
86 //
87 // Unfortunately, some platforms do not endorse that part of the ABI.
88 //
89 // We are aware of one which expects 64-bit arguments to only be 4
90 // bytes aligned and can for instance use R3 + a stack slot for such
91 // an argument.
92 //
93 // This is the behavor implemented if (ALIGN_WIDE_ARGUMENTS == 0)
94 #ifndef  ALIGN_WIDE_ARGUMENTS
95 // Default: align on 8 bytes and avoid using <r3+stack>
96 #define ALIGN_WIDE_ARGUMENTS 1
97 #endif
98 
99 #define R0     ((Register)0)
100 #define R1     ((Register)1)
101 #define R2     ((Register)2)
102 #define R3     ((Register)3)
103 #define R4     ((Register)4)
104 #define R5     ((Register)5)
105 #define R6     ((Register)6)
106 #define R7     ((Register)7)
107 #define R8     ((Register)8)
108 #define R9     ((Register)9)
109 #define R10    ((Register)10)
110 #define R11    ((Register)11)
111 #define R12    ((Register)12)
112 #define R13    ((Register)13)
113 #define R14    ((Register)14)
114 #define R15    ((Register)15)
115 
116 #ifdef AARCH64
117 
118 #define R16    ((Register)16)
119 #define R17    ((Register)17)
120 #define R18    ((Register)18)
121 #define R19    ((Register)19)
122 #define R20    ((Register)20)
123 #define R21    ((Register)21)
124 #define R22    ((Register)22)
125 #define R23    ((Register)23)
126 #define R24    ((Register)24)
127 #define R25    ((Register)25)
128 #define R26    ((Register)26)
129 #define R27    ((Register)27)
130 #define R28    ((Register)28)
131 #define R29    ((Register)29)
132 #define R30    ((Register)30)
133 #define ZR     ((Register)31)
134 #define SP     ((Register)32)
135 
136 #define FP     R29
137 #define LR     R30
138 
139 #define altFP_7_11 R7
140 
141 #else // !AARCH64
142 
143 #define FP     ((Register)FP_REG_NUM)
144 
145 // Safe use of registers which may be FP on some platforms.
146 //
147 // altFP_7_11: R7 if not equal to FP, else R11 (the default FP)
148 //
149 // Note: add additional altFP_#_11 for each register potentially used
150 // as FP on supported ABIs (and replace R# by altFP_#_11). altFP_#_11
151 // must be #define to R11 if and only if # is FP_REG_NUM.
152 #if (FP_REG_NUM == 7)
153 #define altFP_7_11     ((Register)11)
154 #else
155 #define altFP_7_11     ((Register)7)
156 #endif
157 #define SP     R13
158 #define LR     R14
159 #define PC     R15
160 
161 #endif // !AARCH64
162 
163 
164 class RegisterImpl;
165 typedef RegisterImpl* Register;
166 
as_Register(int encoding)167 inline Register as_Register(int encoding) {
168   return (Register)(intptr_t)encoding;
169 }
170 
171 class RegisterImpl : public AbstractRegisterImpl {
172  public:
173   enum {
174 #ifdef AARCH64
175     number_of_gprs = 31,
176     zr_sp_encoding = 31,
177 #endif
178     number_of_registers = AARCH64_ONLY(number_of_gprs + 2) NOT_AARCH64(16)
179   };
180 
successor() const181   Register successor() const      { return as_Register(encoding() + 1); }
182 
183   inline friend Register as_Register(int encoding);
184 
185   VMReg as_VMReg();
186 
187   // accessors
encoding() const188   int   encoding() const          { assert(is_valid(), "invalid register"); return value(); }
189   const char* name() const;
190 
191 #ifdef AARCH64
encoding_with_zr() const192   int encoding_with_zr() const   { assert (is_valid_gpr_or_zr(), "invalid register"); return (this == ZR) ? zr_sp_encoding : value(); }
encoding_with_sp() const193   int encoding_with_sp() const   { assert (is_valid_gpr_or_sp(), "invalid register"); return (this == SP) ? zr_sp_encoding : value(); }
194 #endif
195 
196   // testers
is_valid() const197   bool is_valid() const           { return 0 <= value() && value() < number_of_registers; }
198 
199 #ifdef AARCH64
is_valid_gpr() const200   bool is_valid_gpr()       const  { return (0 <= value() && value() < number_of_gprs); }
is_valid_gpr_or_zr() const201   bool is_valid_gpr_or_zr() const  { return is_valid_gpr() || (this == ZR); }
is_valid_gpr_or_sp() const202   bool is_valid_gpr_or_sp() const  { return is_valid_gpr() || (this == SP); }
203 #endif
204 };
205 
206 CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
207 
208 
209 // Use FloatRegister as shortcut
210 class FloatRegisterImpl;
211 typedef FloatRegisterImpl* FloatRegister;
212 
as_FloatRegister(int encoding)213 inline FloatRegister as_FloatRegister(int encoding) {
214   return (FloatRegister)(intptr_t)encoding;
215 }
216 
217 class FloatRegisterImpl : public AbstractRegisterImpl {
218  public:
219   enum {
220 #ifdef AARCH64
221     number_of_registers = 32
222 #else
223     number_of_registers = NOT_COMPILER2(32) COMPILER2_PRESENT(64)
224 #endif
225   };
226 
227   inline friend FloatRegister as_FloatRegister(int encoding);
228 
229   VMReg as_VMReg();
230 
encoding() const231   int   encoding() const          { assert(is_valid(), "invalid register"); return value(); }
is_valid() const232   bool  is_valid() const          { return 0 <= (intx)this && (intx)this < number_of_registers; }
successor() const233   FloatRegister successor() const { return as_FloatRegister(encoding() + 1); }
234 
235   const char* name() const;
236 
237 #ifndef AARCH64
hi_bits() const238   int hi_bits() const {
239     return (encoding() >> 1) & 0xf;
240   }
241 
lo_bit() const242   int lo_bit() const {
243     return encoding() & 1;
244   }
245 
hi_bit() const246   int hi_bit() const {
247     return encoding() >> 5;
248   }
249 #endif // !AARCH64
250 };
251 
252 CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg, (-1));
253 
254 #ifdef AARCH64
255 
256 CONSTANT_REGISTER_DECLARATION(FloatRegister, V0,     ( 0));
257 CONSTANT_REGISTER_DECLARATION(FloatRegister, V1,     ( 1));
258 CONSTANT_REGISTER_DECLARATION(FloatRegister, V2,     ( 2));
259 CONSTANT_REGISTER_DECLARATION(FloatRegister, V3,     ( 3));
260 CONSTANT_REGISTER_DECLARATION(FloatRegister, V4,     ( 4));
261 CONSTANT_REGISTER_DECLARATION(FloatRegister, V5,     ( 5));
262 CONSTANT_REGISTER_DECLARATION(FloatRegister, V6,     ( 6));
263 CONSTANT_REGISTER_DECLARATION(FloatRegister, V7,     ( 7));
264 CONSTANT_REGISTER_DECLARATION(FloatRegister, V8,     ( 8));
265 CONSTANT_REGISTER_DECLARATION(FloatRegister, V9,     ( 9));
266 CONSTANT_REGISTER_DECLARATION(FloatRegister, V10,    (10));
267 CONSTANT_REGISTER_DECLARATION(FloatRegister, V11,    (11));
268 CONSTANT_REGISTER_DECLARATION(FloatRegister, V12,    (12));
269 CONSTANT_REGISTER_DECLARATION(FloatRegister, V13,    (13));
270 CONSTANT_REGISTER_DECLARATION(FloatRegister, V14,    (14));
271 CONSTANT_REGISTER_DECLARATION(FloatRegister, V15,    (15));
272 CONSTANT_REGISTER_DECLARATION(FloatRegister, V16,    (16));
273 CONSTANT_REGISTER_DECLARATION(FloatRegister, V17,    (17));
274 CONSTANT_REGISTER_DECLARATION(FloatRegister, V18,    (18));
275 CONSTANT_REGISTER_DECLARATION(FloatRegister, V19,    (19));
276 CONSTANT_REGISTER_DECLARATION(FloatRegister, V20,    (20));
277 CONSTANT_REGISTER_DECLARATION(FloatRegister, V21,    (21));
278 CONSTANT_REGISTER_DECLARATION(FloatRegister, V22,    (22));
279 CONSTANT_REGISTER_DECLARATION(FloatRegister, V23,    (23));
280 CONSTANT_REGISTER_DECLARATION(FloatRegister, V24,    (24));
281 CONSTANT_REGISTER_DECLARATION(FloatRegister, V25,    (25));
282 CONSTANT_REGISTER_DECLARATION(FloatRegister, V26,    (26));
283 CONSTANT_REGISTER_DECLARATION(FloatRegister, V27,    (27));
284 CONSTANT_REGISTER_DECLARATION(FloatRegister, V28,    (28));
285 CONSTANT_REGISTER_DECLARATION(FloatRegister, V29,    (29));
286 CONSTANT_REGISTER_DECLARATION(FloatRegister, V30,    (30));
287 CONSTANT_REGISTER_DECLARATION(FloatRegister, V31,    (31));
288 
289 #define S0       V0
290 #define S1_reg   V1
291 #define Stemp    V31
292 
293 #define D0       V0
294 #define D1       V1
295 
296 #else // AARCH64
297 
298 /*
299  * S1-S6 are named with "_reg" suffix to avoid conflict with
300  * constants defined in sharedRuntimeTrig.cpp
301  */
302 CONSTANT_REGISTER_DECLARATION(FloatRegister, S0,     ( 0));
303 CONSTANT_REGISTER_DECLARATION(FloatRegister, S1_reg, ( 1));
304 CONSTANT_REGISTER_DECLARATION(FloatRegister, S2_reg, ( 2));
305 CONSTANT_REGISTER_DECLARATION(FloatRegister, S3_reg, ( 3));
306 CONSTANT_REGISTER_DECLARATION(FloatRegister, S4_reg, ( 4));
307 CONSTANT_REGISTER_DECLARATION(FloatRegister, S5_reg, ( 5));
308 CONSTANT_REGISTER_DECLARATION(FloatRegister, S6_reg, ( 6));
309 CONSTANT_REGISTER_DECLARATION(FloatRegister, S7,     ( 7));
310 CONSTANT_REGISTER_DECLARATION(FloatRegister, S8,     ( 8));
311 CONSTANT_REGISTER_DECLARATION(FloatRegister, S9,     ( 9));
312 CONSTANT_REGISTER_DECLARATION(FloatRegister, S10,    (10));
313 CONSTANT_REGISTER_DECLARATION(FloatRegister, S11,    (11));
314 CONSTANT_REGISTER_DECLARATION(FloatRegister, S12,    (12));
315 CONSTANT_REGISTER_DECLARATION(FloatRegister, S13,    (13));
316 CONSTANT_REGISTER_DECLARATION(FloatRegister, S14,    (14));
317 CONSTANT_REGISTER_DECLARATION(FloatRegister, S15,    (15));
318 CONSTANT_REGISTER_DECLARATION(FloatRegister, S16,    (16));
319 CONSTANT_REGISTER_DECLARATION(FloatRegister, S17,    (17));
320 CONSTANT_REGISTER_DECLARATION(FloatRegister, S18,    (18));
321 CONSTANT_REGISTER_DECLARATION(FloatRegister, S19,    (19));
322 CONSTANT_REGISTER_DECLARATION(FloatRegister, S20,    (20));
323 CONSTANT_REGISTER_DECLARATION(FloatRegister, S21,    (21));
324 CONSTANT_REGISTER_DECLARATION(FloatRegister, S22,    (22));
325 CONSTANT_REGISTER_DECLARATION(FloatRegister, S23,    (23));
326 CONSTANT_REGISTER_DECLARATION(FloatRegister, S24,    (24));
327 CONSTANT_REGISTER_DECLARATION(FloatRegister, S25,    (25));
328 CONSTANT_REGISTER_DECLARATION(FloatRegister, S26,    (26));
329 CONSTANT_REGISTER_DECLARATION(FloatRegister, S27,    (27));
330 CONSTANT_REGISTER_DECLARATION(FloatRegister, S28,    (28));
331 CONSTANT_REGISTER_DECLARATION(FloatRegister, S29,    (29));
332 CONSTANT_REGISTER_DECLARATION(FloatRegister, S30,    (30));
333 CONSTANT_REGISTER_DECLARATION(FloatRegister, S31,    (31));
334 CONSTANT_REGISTER_DECLARATION(FloatRegister, Stemp,  (30));
335 
336 CONSTANT_REGISTER_DECLARATION(FloatRegister, D0,     ( 0));
337 CONSTANT_REGISTER_DECLARATION(FloatRegister, D1,     ( 2));
338 CONSTANT_REGISTER_DECLARATION(FloatRegister, D2,     ( 4));
339 CONSTANT_REGISTER_DECLARATION(FloatRegister, D3,     ( 6));
340 CONSTANT_REGISTER_DECLARATION(FloatRegister, D4,     ( 8));
341 CONSTANT_REGISTER_DECLARATION(FloatRegister, D5,     ( 10));
342 CONSTANT_REGISTER_DECLARATION(FloatRegister, D6,     ( 12));
343 CONSTANT_REGISTER_DECLARATION(FloatRegister, D7,     ( 14));
344 CONSTANT_REGISTER_DECLARATION(FloatRegister, D8,     ( 16));
345 CONSTANT_REGISTER_DECLARATION(FloatRegister, D9,     ( 18));
346 CONSTANT_REGISTER_DECLARATION(FloatRegister, D10,    ( 20));
347 CONSTANT_REGISTER_DECLARATION(FloatRegister, D11,    ( 22));
348 CONSTANT_REGISTER_DECLARATION(FloatRegister, D12,    ( 24));
349 CONSTANT_REGISTER_DECLARATION(FloatRegister, D13,    ( 26));
350 CONSTANT_REGISTER_DECLARATION(FloatRegister, D14,    ( 28));
351 CONSTANT_REGISTER_DECLARATION(FloatRegister, D15,    (30));
352 CONSTANT_REGISTER_DECLARATION(FloatRegister, D16,    (32));
353 CONSTANT_REGISTER_DECLARATION(FloatRegister, D17,    (34));
354 CONSTANT_REGISTER_DECLARATION(FloatRegister, D18,    (36));
355 CONSTANT_REGISTER_DECLARATION(FloatRegister, D19,    (38));
356 CONSTANT_REGISTER_DECLARATION(FloatRegister, D20,    (40));
357 CONSTANT_REGISTER_DECLARATION(FloatRegister, D21,    (42));
358 CONSTANT_REGISTER_DECLARATION(FloatRegister, D22,    (44));
359 CONSTANT_REGISTER_DECLARATION(FloatRegister, D23,    (46));
360 CONSTANT_REGISTER_DECLARATION(FloatRegister, D24,    (48));
361 CONSTANT_REGISTER_DECLARATION(FloatRegister, D25,    (50));
362 CONSTANT_REGISTER_DECLARATION(FloatRegister, D26,    (52));
363 CONSTANT_REGISTER_DECLARATION(FloatRegister, D27,    (54));
364 CONSTANT_REGISTER_DECLARATION(FloatRegister, D28,    (56));
365 CONSTANT_REGISTER_DECLARATION(FloatRegister, D29,    (58));
366 CONSTANT_REGISTER_DECLARATION(FloatRegister, D30,    (60));
367 CONSTANT_REGISTER_DECLARATION(FloatRegister, D31,    (62));
368 
369 #endif // AARCH64
370 
371 class ConcreteRegisterImpl : public AbstractRegisterImpl {
372  public:
373   enum {
374     log_vmregs_per_word = LogBytesPerWord - LogBytesPerInt, // VMRegs are of 4-byte size
375 #ifdef COMPILER2
376     log_bytes_per_fpr  = AARCH64_ONLY(4) NOT_AARCH64(2), // quad vectors
377 #else
378     log_bytes_per_fpr  = AARCH64_ONLY(3) NOT_AARCH64(2), // double vectors
379 #endif
380     log_words_per_fpr  = log_bytes_per_fpr - LogBytesPerWord,
381     words_per_fpr      = 1 << log_words_per_fpr,
382     log_vmregs_per_fpr = log_bytes_per_fpr - LogBytesPerInt,
383     log_vmregs_per_gpr = log_vmregs_per_word,
384     vmregs_per_gpr = 1 << log_vmregs_per_gpr,
385     vmregs_per_fpr = 1 << log_vmregs_per_fpr,
386 
387     num_gpr  = RegisterImpl::number_of_registers << log_vmregs_per_gpr,
388     max_gpr0 = num_gpr,
389     num_fpr  = FloatRegisterImpl::number_of_registers << log_vmregs_per_fpr,
390     max_fpr0 = max_gpr0 + num_fpr,
391     number_of_registers = num_gpr + num_fpr +
392                           // TODO-AARCH64 revise
393                           1+1 // APSR and FPSCR so that c2's REG_COUNT <= ConcreteRegisterImpl::number_of_registers
394   };
395 
396   static const int max_gpr;
397   static const int max_fpr;
398 };
399 
400 // TODO-AARCH64 revise the following definitions
401 
402 class VFPSystemRegisterImpl;
403 typedef VFPSystemRegisterImpl* VFPSystemRegister;
404 class VFPSystemRegisterImpl : public AbstractRegisterImpl {
405  public:
encoding() const406   int   encoding() const          { return value(); }
407 };
408 
409 #define FPSID     ((VFPSystemRegister)0)
410 #define FPSCR     ((VFPSystemRegister)1)
411 #define MVFR0     ((VFPSystemRegister)0x6)
412 #define MVFR1     ((VFPSystemRegister)0x7)
413 
414 /*
415  * Register definitions shared across interpreter and compiler
416  */
417 #define Rexception_obj   AARCH64_ONLY(R19) NOT_AARCH64(R4)
418 #define Rexception_pc    AARCH64_ONLY(R20) NOT_AARCH64(R5)
419 
420 #ifdef AARCH64
421 #define Rheap_base       R27
422 #endif // AARCH64
423 
424 /*
425  * Interpreter register definitions common to C++ and template interpreters.
426  */
427 #ifdef AARCH64
428 #define Rlocals          R23
429 #define Rmethod          R26
430 #define Rthread          R28
431 #define Rtemp            R16
432 #define Rtemp2           R17
433 #else
434 #define Rlocals          R8
435 #define Rmethod          R9
436 #define Rthread          R10
437 #define Rtemp            R12
438 #endif // AARCH64
439 
440 // Interpreter calling conventions
441 
442 #define Rparams          AARCH64_ONLY(R8)  NOT_AARCH64(SP)
443 #define Rsender_sp       AARCH64_ONLY(R19) NOT_AARCH64(R4)
444 
445 // JSR292
446 //  Note: R5_mh is needed only during the call setup, including adapters
447 //  This does not seem to conflict with Rexception_pc
448 //  In case of issues, R3 might be OK but adapters calling the runtime would have to save it
449 #define R5_mh            R5 // MethodHandle register, used during the call setup
450 #define Rmh_SP_save      FP // for C1
451 
452 /*
453  * C++ Interpreter Register Defines
454  */
455 #define Rsave0   R4
456 #define Rsave1   R5
457 #define Rsave2   R6
458 #define Rstate   altFP_7_11 // R7 or R11
459 #define Ricklass R8
460 
461 /*
462  * TemplateTable Interpreter Register Usage
463  */
464 
465 // Temporary registers
466 #define R0_tmp                 R0
467 #define R1_tmp                 R1
468 #define R2_tmp                 R2
469 #define R3_tmp                 R3
470 #define R4_tmp                 R4
471 #define R5_tmp                 R5
472 #define R12_tmp                R12
473 #define LR_tmp                 LR
474 
475 #define S0_tmp                 S0
476 #define S1_tmp                 S1_reg
477 
478 #define D0_tmp                 D0
479 #define D1_tmp                 D1
480 
481 // Temporary registers saved across VM calls (according to C calling conventions)
482 #define Rtmp_save0             AARCH64_ONLY(R19) NOT_AARCH64(R4)
483 #define Rtmp_save1             AARCH64_ONLY(R20) NOT_AARCH64(R5)
484 
485 // Cached TOS value
486 #define R0_tos                 R0
487 
488 #ifndef AARCH64
489 #define R0_tos_lo              R0
490 #define R1_tos_hi              R1
491 #endif
492 
493 #define S0_tos                 S0
494 #define D0_tos                 D0
495 
496 // Dispatch table
497 #define RdispatchTable         AARCH64_ONLY(R22) NOT_AARCH64(R6)
498 
499 // Bytecode pointer
500 #define Rbcp                   AARCH64_ONLY(R24) NOT_AARCH64(altFP_7_11)
501 
502 // Pre-loaded next bytecode for the dispatch
503 #define R3_bytecode            R3
504 
505 // Conventions between bytecode templates and stubs
506 #define R2_ClassCastException_obj        R2
507 #define R4_ArrayIndexOutOfBounds_index   R4
508 
509 // Interpreter expression stack top
510 #define Rstack_top             AARCH64_ONLY(R25) NOT_AARCH64(SP)
511 
512 /*
513  * Linux 32-bit ARM C ABI Register calling conventions
514  *
515  *   REG         use                     callee/caller saved
516  *
517  *   R0         First argument reg            caller
518  *              result register
519  *   R1         Second argument reg           caller
520  *              result register
521  *   R2         Third argument reg            caller
522  *   R3         Fourth argument reg           caller
523  *
524  *   R4 - R8    Local variable registers      callee
525  *   R9
526  *   R10, R11   Local variable registers      callee
527  *
528  *   R12 (IP)   Scratch register used in inter-procedural calling
529  *   R13 (SP)   Stack Pointer                 callee
530  *   R14 (LR)   Link register
531  *   R15 (PC)   Program Counter
532  *
533  * TODO-AARCH64: document AArch64 ABI
534  *
535  */
536 #define c_rarg0  R0
537 #define c_rarg1  R1
538 #define c_rarg2  R2
539 #define c_rarg3  R3
540 
541 #ifdef AARCH64
542 #define c_rarg4  R4
543 #define c_rarg5  R5
544 #define c_rarg6  R6
545 #define c_rarg7  R7
546 #endif
547 
548 #ifdef AARCH64
549 #define GPR_PARAMS    8
550 #define FPR_PARAMS    8
551 #else
552 #define GPR_PARAMS    4
553 #endif
554 
555 
556 // Java ABI
557 // XXX Is this correct?
558 #define j_rarg0  c_rarg0
559 #define j_rarg1  c_rarg1
560 #define j_rarg2  c_rarg2
561 #define j_rarg3  c_rarg3
562 
563 #ifdef AARCH64
564 #define j_rarg4  c_rarg4
565 #define j_rarg5  c_rarg5
566 #define j_rarg6  c_rarg6
567 #define j_rarg7  c_rarg7
568 #endif
569 
570 #endif // CPU_ARM_VM_REGISTER_ARM_HPP
571