xref: /php-src/ext/opcache/jit/ir/ir_aarch64.h (revision 4630f77e)
1 /*
2  * IR - Lightweight JIT Compilation Framework
3  * (Aarch64 CPU specific definitions)
4  * Copyright (C) 2022 Zend by Perforce.
5  * Authors: Dmitry Stogov <dmitry@php.net>
6  */
7 
8 #ifndef IR_AARCH64_H
9 #define IR_AARCH64_H
10 
11 #define IR_GP_REGS(_) \
12 	_(X0,    x0,  w0) \
13 	_(X1,    x1,  w1) \
14 	_(X2,    x2,  w2) \
15 	_(X3,    x3,  w3) \
16 	_(X4,    x4,  w4) \
17 	_(X5,    x5,  w5) \
18 	_(X6,    x6,  w6) \
19 	_(X7,    x7,  w7) \
20 	_(X8,    x8,  w8) \
21 	_(X9,    x9,  w9) \
22 	_(X10,  x10,  w10) \
23 	_(X11,  x11,  w11) \
24 	_(X12,  x12,  w12) \
25 	_(X13,  x13,  w13) \
26 	_(X14,  x14,  w14) \
27 	_(X15,  x15,  w15) \
28 	_(X16,  x16,  w16) \
29 	_(X17,  x17,  w17) \
30 	_(X18,  x18,  w18) \
31 	_(X19,  x19,  w19) \
32 	_(X20,  x20,  w20) \
33 	_(X21,  x21,  w21) \
34 	_(X22,  x22,  w22) \
35 	_(X23,  x23,  w23) \
36 	_(X24,  x24,  w24) \
37 	_(X25,  x25,  w25) \
38 	_(X26,  x26,  w26) \
39 	_(X27,  x27,  w27) \
40 	_(X28,  x28,  w28) \
41 	_(X29,  x29,  w29) \
42 	_(X30,  x30,  w30) \
43 	_(X31,  x31,  w31) \
44 
45 # define IR_FP_REGS(_) \
46 	_(V0,   d0,   s0,   h0,   b0) \
47 	_(V1,   d1,   s1,   h1,   b1) \
48 	_(V2,   d2,   s2,   h2,   b2) \
49 	_(V3,   d3,   s3,   h3,   b3) \
50 	_(V4,   d4,   s4,   h4,   b4) \
51 	_(V5,   d5,   s5,   h5,   b5) \
52 	_(V6,   d6,   s6,   h6,   b6) \
53 	_(V7,   d7,   s7,   h7,   b7) \
54 	_(V8,   d8,   s8,   h8,   b8) \
55 	_(V9,   d9,   s9,   h9,   b9) \
56 	_(V10,  d10,  s10,  h10,  b10) \
57 	_(V11,  d11,  s11,  h11,  b11) \
58 	_(V12,  d12,  s12,  h12,  b12) \
59 	_(V13,  d13,  s13,  h13,  b13) \
60 	_(V14,  d14,  s14,  h14,  b14) \
61 	_(V15,  d15,  s15,  h15,  b15) \
62 	_(V16,  d16,  s16,  h16,  b16) \
63 	_(V17,  d17,  s17,  h17,  b17) \
64 	_(V18,  d18,  s18,  h18,  b18) \
65 	_(V19,  d19,  s19,  h19,  b19) \
66 	_(V20,  d20,  s20,  h20,  b20) \
67 	_(V21,  d21,  s21,  h21,  b21) \
68 	_(V22,  d22,  s22,  h22,  b22) \
69 	_(V23,  d23,  s23,  h23,  b23) \
70 	_(V24,  d24,  s24,  h24,  b24) \
71 	_(V25,  d25,  s25,  h25,  b25) \
72 	_(V26,  d26,  s26,  h26,  b26) \
73 	_(V27,  d27,  s27,  h27,  b27) \
74 	_(V28,  d28,  s28,  h28,  b28) \
75 	_(V29,  d29,  s29,  h29,  b29) \
76 	_(V30,  d30,  s30,  h30,  b30) \
77 	_(V31,  d31,  s31,  h31,  b31) \
78 
79 #define IR_GP_REG_ENUM(code, name64, name32) \
80 	IR_REG_ ## code,
81 
82 #define IR_FP_REG_ENUM(code, name64, name32, name16, name8) \
83 	IR_REG_ ## code,
84 
85 enum _ir_reg {
86 	_IR_REG_NONE = -1,
87 	IR_GP_REGS(IR_GP_REG_ENUM)
88 	IR_FP_REGS(IR_FP_REG_ENUM)
89 	IR_REG_NUM,
90 };
91 
92 #define IR_REG_GP_FIRST IR_REG_X0
93 #define IR_REG_FP_FIRST IR_REG_V0
94 #define IR_REG_GP_LAST  (IR_REG_FP_FIRST - 1)
95 #define IR_REG_FP_LAST  (IR_REG_NUM - 1)
96 #define IR_REG_SCRATCH  (IR_REG_NUM)        /* special name for regset */
97 #define IR_REG_ALL      (IR_REG_NUM + 1)    /* special name for regset */
98 
99 #define IR_REGSET_64BIT 1
100 
101 #define IR_REG_INT_TMP  IR_REG_X17 /* reserved temporary register used by code-generator */
102 
103 #define IR_REG_STACK_POINTER \
104 	IR_REG_X31
105 #define IR_REG_FRAME_POINTER \
106 	IR_REG_X29
107 
108 #if defined(__linux__)
109 #define IR_REGSET_FIXED \
110 	(IR_REGSET(IR_REG_INT_TMP) | IR_REGSET_INTERVAL(IR_REG_X29, IR_REG_X31))
111 #else
112 #define IR_REGSET_FIXED \
113 	(IR_REGSET(IR_REG_INT_TMP) | IR_REGSET_INTERVAL(IR_REG_X29, IR_REG_X31) \
114 	| IR_REGSET(IR_REG_X18)) /* Other platforms reserve x18 register */
115 #endif
116 
117 #define IR_REGSET_GP \
118 	IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_GP_FIRST, IR_REG_GP_LAST), IR_REGSET_FIXED)
119 #define IR_REGSET_FP \
120 	IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_FP_FIRST, IR_REG_FP_LAST), IR_REGSET_FIXED)
121 
122 #define IR_REG_IP0 IR_REG_X16
123 #define IR_REG_IP1 IR_REG_X17
124 #define IR_REG_PR  IR_REG_X18
125 #define IR_REG_LR  IR_REG_X30
126 #define IR_REG_ZR  IR_REG_X31
127 
128 /* Calling Convention */
129 #define IR_REG_INT_RET1 IR_REG_X0
130 #define IR_REG_FP_RET1  IR_REG_V0
131 #define IR_REG_INT_ARGS 8
132 #define IR_REG_FP_ARGS  8
133 #define IR_REG_INT_ARG1 IR_REG_X0
134 #define IR_REG_INT_ARG2 IR_REG_X1
135 #define IR_REG_INT_ARG3 IR_REG_X2
136 #define IR_REG_INT_ARG4 IR_REG_X3
137 #define IR_REG_INT_ARG5 IR_REG_X4
138 #define IR_REG_INT_ARG6 IR_REG_X5
139 #define IR_REG_INT_ARG7 IR_REG_X6
140 #define IR_REG_INT_ARG8 IR_REG_X7
141 #define IR_REG_FP_ARG1  IR_REG_V0
142 #define IR_REG_FP_ARG2  IR_REG_V1
143 #define IR_REG_FP_ARG3  IR_REG_V2
144 #define IR_REG_FP_ARG4  IR_REG_V3
145 #define IR_REG_FP_ARG5  IR_REG_V4
146 #define IR_REG_FP_ARG6  IR_REG_V5
147 #define IR_REG_FP_ARG7  IR_REG_V6
148 #define IR_REG_FP_ARG8  IR_REG_V7
149 #define IR_MAX_REG_ARGS 16
150 #define IR_SHADOW_ARGS  0
151 
152 # define IR_REGSET_SCRATCH \
153 	(IR_REGSET_INTERVAL(IR_REG_X0, IR_REG_X18) \
154 	| IR_REGSET_INTERVAL(IR_REG_V0, IR_REG_V7) \
155 	| IR_REGSET_INTERVAL(IR_REG_V16, IR_REG_V31))
156 
157 # define IR_REGSET_PRESERVED \
158 	(IR_REGSET_INTERVAL(IR_REG_X19, IR_REG_X30) \
159 	| IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15))
160 
161 #ifndef __APPLE__
162 typedef struct _ir_va_list {
163 	void    *stack;
164 	void    *gr_top;
165 	void    *vr_top;
166 	int32_t  gr_offset;
167 	int32_t  vr_offset;
168 } ir_va_list;
169 #endif
170 
171 typedef struct _ir_tmp_reg {
172 	union {
173 		uint8_t num;
174 		int8_t  reg;
175 	};
176 	uint8_t     type;
177 	uint8_t     start;
178 	uint8_t     end;
179 } ir_tmp_reg;
180 
181 struct _ir_target_constraints {
182 	int8_t      def_reg;
183 	uint8_t     tmps_count;
184 	uint8_t     hints_count;
185 	ir_tmp_reg  tmp_regs[3];
186 	int8_t      hints[IR_MAX_REG_ARGS + 3];
187 };
188 
189 #endif /* IR_AARCH64_H */
190