2 ** Definitions for ARM CPUs.
3 ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
6 #ifndef _LJ_TARGET_ARM_H
7 #define _LJ_TARGET_ARM_H
9 /* -- Registers IDs ------------------------------------------------------- */
12 _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
13 _(R8) _(R9) _(R10) _(R11) _(R12) _(SP) _(LR) _(PC)
18 _(D0) _(D1) _(D2) _(D3) _(D4) _(D5) _(D6) _(D7) \
19 _(D8) _(D9) _(D10) _(D11) _(D12) _(D13) _(D14) _(D15)
23 #define RIDENUM(name) RID_##name,
26 GPRDEF(RIDENUM
) /* General-purpose registers (GPRs). */
27 FPRDEF(RIDENUM
) /* Floating-point registers (FPRs). */
31 /* Calling conventions. */
41 /* These definitions must match with the *.dasc file(s): */
42 RID_BASE
= RID_R9
, /* Interpreter BASE. */
43 RID_LPC
= RID_R6
, /* Interpreter PC. */
44 RID_DISPATCH
= RID_R7
, /* Interpreter DISPATCH table. */
45 RID_LREG
= RID_R8
, /* Interpreter L. */
47 /* Register ranges [min, max) and number of registers. */
49 RID_MAX_GPR
= RID_PC
+1,
50 RID_MIN_FPR
= RID_MAX_GPR
,
52 RID_MAX_FPR
= RID_MIN_FPR
,
54 RID_MAX_FPR
= RID_D15
+1,
56 RID_NUM_GPR
= RID_MAX_GPR
- RID_MIN_GPR
,
57 RID_NUM_FPR
= RID_MAX_FPR
- RID_MIN_FPR
60 #define RID_NUM_KREF RID_NUM_GPR
61 #define RID_MIN_KREF RID_R0
63 /* -- Register sets ------------------------------------------------------- */
65 /* Make use of all registers, except sp, lr and pc. */
66 #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_R12+1))
67 #define RSET_GPREVEN \
68 (RID2RSET(RID_R0)|RID2RSET(RID_R2)|RID2RSET(RID_R4)|RID2RSET(RID_R6)| \
69 RID2RSET(RID_R8)|RID2RSET(RID_R10))
71 (RID2RSET(RID_R1)|RID2RSET(RID_R3)|RID2RSET(RID_R5)|RID2RSET(RID_R7)| \
72 RID2RSET(RID_R9)|RID2RSET(RID_R11))
76 #define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
78 #define RSET_ALL (RSET_GPR|RSET_FPR)
79 #define RSET_INIT RSET_ALL
81 /* ABI-specific register sets. lr is an implicit scratch register. */
82 #define RSET_SCRATCH_GPR_ (RSET_RANGE(RID_R0, RID_R3+1)|RID2RSET(RID_R12))
84 #define RSET_SCRATCH_GPR (RSET_SCRATCH_GPR_|RID2RSET(RID_R9))
86 #define RSET_SCRATCH_GPR RSET_SCRATCH_GPR_
89 #define RSET_SCRATCH_FPR 0
91 #define RSET_SCRATCH_FPR (RSET_RANGE(RID_D0, RID_D7+1))
93 #define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
94 #define REGARG_FIRSTGPR RID_R0
95 #define REGARG_LASTGPR RID_R3
96 #define REGARG_NUMGPR 4
98 #define REGARG_FIRSTFPR 0
99 #define REGARG_LASTFPR 0
100 #define REGARG_NUMFPR 0
102 #define REGARG_FIRSTFPR RID_D0
103 #define REGARG_LASTFPR RID_D7
104 #define REGARG_NUMFPR 8
107 /* -- Spill slots --------------------------------------------------------- */
109 /* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
111 ** SPS_FIXED: Available fixed spill slots in interpreter frame.
112 ** This definition must match with the *.dasc file(s).
114 ** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
121 #define sps_scale(slot) (4 * (int32_t)(slot))
122 #define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
124 /* -- Exit state ---------------------------------------------------------- */
126 /* This definition must match with the *.dasc file(s). */
129 lua_Number fpr
[RID_NUM_FPR
]; /* Floating-point registers. */
131 int32_t gpr
[RID_NUM_GPR
]; /* General-purpose registers. */
132 int32_t spill
[256]; /* Spill slots. */
135 /* PC after instruction that caused an exit. Used to find the trace number. */
136 #define EXITSTATE_PCREG RID_PC
137 /* Highest exit + 1 indicates stack check. */
138 #define EXITSTATE_CHECKEXIT 1
140 #define EXITSTUB_SPACING 4
141 #define EXITSTUBS_PER_GROUP 32
143 /* -- Instructions -------------------------------------------------------- */
145 /* Instruction fields. */
146 #define ARMF_CC(ai, cc) (((ai) ^ ARMI_CCAL) | ((cc) << 28))
147 #define ARMF_N(r) ((r) << 16)
148 #define ARMF_D(r) ((r) << 12)
149 #define ARMF_S(r) ((r) << 8)
150 #define ARMF_M(r) (r)
151 #define ARMF_SH(sh, n) (((sh) << 5) | ((n) << 7))
152 #define ARMF_RSH(sh, r) (0x10 | ((sh) << 5) | ARMF_S(r))
154 typedef enum ARMIns
{
155 ARMI_CCAL
= 0xe0000000,
156 ARMI_S
= 0x000100000,
157 ARMI_K12
= 0x02000000,
158 ARMI_KNEG
= 0x00200000,
159 ARMI_LS_W
= 0x00200000,
160 ARMI_LS_U
= 0x00800000,
161 ARMI_LS_P
= 0x01000000,
162 ARMI_LS_R
= 0x02000000,
163 ARMI_LSX_I
= 0x00400000,
165 ARMI_AND
= 0xe0000000,
166 ARMI_EOR
= 0xe0200000,
167 ARMI_SUB
= 0xe0400000,
168 ARMI_RSB
= 0xe0600000,
169 ARMI_ADD
= 0xe0800000,
170 ARMI_ADC
= 0xe0a00000,
171 ARMI_SBC
= 0xe0c00000,
172 ARMI_RSC
= 0xe0e00000,
173 ARMI_TST
= 0xe1100000,
174 ARMI_TEQ
= 0xe1300000,
175 ARMI_CMP
= 0xe1500000,
176 ARMI_CMN
= 0xe1700000,
177 ARMI_ORR
= 0xe1800000,
178 ARMI_MOV
= 0xe1a00000,
179 ARMI_BIC
= 0xe1c00000,
180 ARMI_MVN
= 0xe1e00000,
182 ARMI_NOP
= 0xe1a00000,
184 ARMI_MUL
= 0xe0000090,
185 ARMI_SMULL
= 0xe0c00090,
187 ARMI_LDR
= 0xe4100000,
188 ARMI_LDRB
= 0xe4500000,
189 ARMI_LDRH
= 0xe01000b0,
190 ARMI_LDRSB
= 0xe01000d0,
191 ARMI_LDRSH
= 0xe01000f0,
192 ARMI_LDRD
= 0xe00000d0,
193 ARMI_STR
= 0xe4000000,
194 ARMI_STRB
= 0xe4400000,
195 ARMI_STRH
= 0xe00000b0,
196 ARMI_STRD
= 0xe00000f0,
197 ARMI_PUSH
= 0xe92d0000,
200 ARMI_BL
= 0xeb000000,
201 ARMI_BLX
= 0xfa000000,
202 ARMI_BLXr
= 0xe12fff30,
205 ARMI_REV
= 0xe6bf0f30,
206 ARMI_SXTB
= 0xe6af0070,
207 ARMI_SXTH
= 0xe6bf0070,
208 ARMI_UXTB
= 0xe6ef0070,
209 ARMI_UXTH
= 0xe6ff0070,
212 ARMI_MOVW
= 0xe3000000,
213 ARMI_MOVT
= 0xe3400000,
216 ARMI_VMOV_D
= 0xeeb00b40,
217 ARMI_VMOV_S
= 0xeeb00a40,
218 ARMI_VMOVI_D
= 0xeeb00b00,
220 ARMI_VMOV_R_S
= 0xee100a10,
221 ARMI_VMOV_S_R
= 0xee000a10,
222 ARMI_VMOV_RR_D
= 0xec500b10,
223 ARMI_VMOV_D_RR
= 0xec400b10,
225 ARMI_VADD_D
= 0xee300b00,
226 ARMI_VSUB_D
= 0xee300b40,
227 ARMI_VMUL_D
= 0xee200b00,
228 ARMI_VMLA_D
= 0xee000b00,
229 ARMI_VMLS_D
= 0xee000b40,
230 ARMI_VNMLS_D
= 0xee100b00,
231 ARMI_VDIV_D
= 0xee800b00,
233 ARMI_VABS_D
= 0xeeb00bc0,
234 ARMI_VNEG_D
= 0xeeb10b40,
235 ARMI_VSQRT_D
= 0xeeb10bc0,
237 ARMI_VCMP_D
= 0xeeb40b40,
238 ARMI_VCMPZ_D
= 0xeeb50b40,
240 ARMI_VMRS
= 0xeef1fa10,
242 ARMI_VCVT_S32_F32
= 0xeebd0ac0,
243 ARMI_VCVT_S32_F64
= 0xeebd0bc0,
244 ARMI_VCVT_U32_F32
= 0xeebc0ac0,
245 ARMI_VCVT_U32_F64
= 0xeebc0bc0,
246 ARMI_VCVTR_S32_F32
= 0xeebd0a40,
247 ARMI_VCVTR_S32_F64
= 0xeebd0b40,
248 ARMI_VCVTR_U32_F32
= 0xeebc0a40,
249 ARMI_VCVTR_U32_F64
= 0xeebc0b40,
250 ARMI_VCVT_F32_S32
= 0xeeb80ac0,
251 ARMI_VCVT_F64_S32
= 0xeeb80bc0,
252 ARMI_VCVT_F32_U32
= 0xeeb80a40,
253 ARMI_VCVT_F64_U32
= 0xeeb80b40,
254 ARMI_VCVT_F32_F64
= 0xeeb70bc0,
255 ARMI_VCVT_F64_F32
= 0xeeb70ac0,
257 ARMI_VLDR_S
= 0xed100a00,
258 ARMI_VLDR_D
= 0xed100b00,
259 ARMI_VSTR_S
= 0xed000a00,
260 ARMI_VSTR_D
= 0xed000b00,
263 typedef enum ARMShift
{
264 ARMSH_LSL
, ARMSH_LSR
, ARMSH_ASR
, ARMSH_ROR
267 /* ARM condition codes. */
269 CC_EQ
, CC_NE
, CC_CS
, CC_CC
, CC_MI
, CC_PL
, CC_VS
, CC_VC
,
270 CC_HI
, CC_LS
, CC_GE
, CC_LT
, CC_GT
, CC_LE
, CC_AL
,
271 CC_HS
= CC_CS
, CC_LO
= CC_CC