2 ** Definitions for MIPS CPUs.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
6 #ifndef _LJ_TARGET_MIPS_H
7 #define _LJ_TARGET_MIPS_H
9 /* -- Registers IDs ------------------------------------------------------- */
12 _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
13 _(R8) _(R9) _(R10) _(R11) _(R12) _(R13) _(R14) _(R15) \
14 _(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \
15 _(R24) _(R25) _(SYS1) _(SYS2) _(R28) _(SP) _(R30) _(RA)
20 _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
21 _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
22 _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
23 _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
27 #define RIDENUM(name) RID_##name,
30 GPRDEF(RIDENUM
) /* General-purpose registers (GPRs). */
31 FPRDEF(RIDENUM
) /* Floating-point registers (FPRs). */
37 /* Calling conventions. */
51 RID_CFUNCADDR
= RID_R25
,
53 /* These definitions must match with the *.dasc file(s): */
54 RID_BASE
= RID_R16
, /* Interpreter BASE. */
55 RID_LPC
= RID_R18
, /* Interpreter PC. */
56 RID_DISPATCH
= RID_R19
, /* Interpreter DISPATCH table. */
57 RID_LREG
= RID_R20
, /* Interpreter L. */
58 RID_JGL
= RID_R30
, /* On-trace: global_State + 32768. */
60 /* Register ranges [min, max) and number of registers. */
62 RID_MAX_GPR
= RID_RA
+1,
63 RID_MIN_FPR
= RID_MAX_GPR
,
65 RID_MAX_FPR
= RID_MIN_FPR
,
67 RID_MAX_FPR
= RID_F31
+1,
69 RID_NUM_GPR
= RID_MAX_GPR
- RID_MIN_GPR
,
70 RID_NUM_FPR
= RID_MAX_FPR
- RID_MIN_FPR
/* Only even regs are used. */
73 #define RID_NUM_KREF RID_NUM_GPR
74 #define RID_MIN_KREF RID_R0
76 /* -- Register sets ------------------------------------------------------- */
78 /* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2, JGL and GP. */
80 (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\
81 RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)|RID2RSET(RID_GP))
82 #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
88 (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
89 RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
90 RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\
91 RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30))
93 #define RSET_FPR RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR)
96 #define RSET_ALL (RSET_GPR|RSET_FPR)
97 #define RSET_INIT RSET_ALL
99 #define RSET_SCRATCH_GPR \
100 (RSET_RANGE(RID_R1, RID_R15+1)|\
101 RID2RSET(RID_R24)|RID2RSET(RID_R25))
103 #define RSET_SCRATCH_FPR 0
106 #define RSET_SCRATCH_FPR \
107 (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
108 RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
109 RID2RSET(RID_F16)|RID2RSET(RID_F18))
111 #define RSET_SCRATCH_FPR RSET_RANGE(RID_F0, RID_F24)
114 #define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
115 #define REGARG_FIRSTGPR RID_R4
117 #define REGARG_LASTGPR RID_R7
118 #define REGARG_NUMGPR 4
120 #define REGARG_LASTGPR RID_R11
121 #define REGARG_NUMGPR 8
124 #define REGARG_FIRSTFPR 0
125 #define REGARG_LASTFPR 0
126 #define REGARG_NUMFPR 0
128 #define REGARG_FIRSTFPR RID_F12
130 #define REGARG_LASTFPR RID_F14
131 #define REGARG_NUMFPR 2
133 #define REGARG_LASTFPR RID_F19
134 #define REGARG_NUMFPR 8
138 /* -- Spill slots --------------------------------------------------------- */
140 /* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
142 ** SPS_FIXED: Available fixed spill slots in interpreter frame.
143 ** This definition must match with the *.dasc file(s).
145 ** SPS_FIRST: First spill slot for general use.
156 #define sps_scale(slot) (4 * (int32_t)(slot))
157 #define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
159 /* -- Exit state ---------------------------------------------------------- */
161 /* This definition must match with the *.dasc file(s). */
164 lua_Number fpr
[RID_NUM_FPR
]; /* Floating-point registers. */
166 intptr_t gpr
[RID_NUM_GPR
]; /* General-purpose registers. */
167 int32_t spill
[256]; /* Spill slots. */
170 /* Highest exit + 1 indicates stack check. */
171 #define EXITSTATE_CHECKEXIT 1
173 /* Return the address of a per-trace exit stub. */
174 static LJ_AINLINE
uint32_t *exitstub_trace_addr_(uint32_t *p
)
176 while (*p
== 0x00000000) p
++; /* Skip MIPSI_NOP. */
179 /* Avoid dependence on lj_jit.h if only including lj_target.h. */
180 #define exitstub_trace_addr(T, exitno) \
181 exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode))
183 /* -- Instructions -------------------------------------------------------- */
185 /* Instruction fields. */
186 #define MIPSF_S(r) ((r) << 21)
187 #define MIPSF_T(r) ((r) << 16)
188 #define MIPSF_D(r) ((r) << 11)
189 #define MIPSF_R(r) ((r) << 21)
190 #define MIPSF_H(r) ((r) << 16)
191 #define MIPSF_G(r) ((r) << 11)
192 #define MIPSF_F(r) ((r) << 6)
193 #define MIPSF_A(n) ((n) << 6)
194 #define MIPSF_M(n) ((n) << 11)
195 #define MIPSF_L(n) ((n) << 6)
197 typedef enum MIPSIns
{
201 /* Integer instructions. */
202 MIPSI_MOVE
= 0x00000025,
203 MIPSI_NOP
= 0x00000000,
205 MIPSI_LI
= 0x24000000,
206 MIPSI_LU
= 0x34000000,
207 MIPSI_LUI
= 0x3c000000,
209 MIPSI_AND
= 0x00000024,
210 MIPSI_ANDI
= 0x30000000,
211 MIPSI_OR
= 0x00000025,
212 MIPSI_ORI
= 0x34000000,
213 MIPSI_XOR
= 0x00000026,
214 MIPSI_XORI
= 0x38000000,
215 MIPSI_NOR
= 0x00000027,
217 MIPSI_SLT
= 0x0000002a,
218 MIPSI_SLTU
= 0x0000002b,
219 MIPSI_SLTI
= 0x28000000,
220 MIPSI_SLTIU
= 0x2c000000,
222 MIPSI_ADDU
= 0x00000021,
223 MIPSI_ADDIU
= 0x24000000,
224 MIPSI_SUB
= 0x00000022,
225 MIPSI_SUBU
= 0x00000023,
227 #if !LJ_TARGET_MIPSR6
228 MIPSI_MUL
= 0x70000002,
229 MIPSI_DIV
= 0x0000001a,
230 MIPSI_DIVU
= 0x0000001b,
232 MIPSI_MOVZ
= 0x0000000a,
233 MIPSI_MOVN
= 0x0000000b,
234 MIPSI_MFHI
= 0x00000010,
235 MIPSI_MFLO
= 0x00000012,
236 MIPSI_MULT
= 0x00000018,
238 MIPSI_MUL
= 0x00000098,
239 MIPSI_MUH
= 0x000000d8,
240 MIPSI_DIV
= 0x0000009a,
241 MIPSI_DIVU
= 0x0000009b,
243 MIPSI_SELEQZ
= 0x00000035,
244 MIPSI_SELNEZ
= 0x00000037,
247 MIPSI_SLL
= 0x00000000,
248 MIPSI_SRL
= 0x00000002,
249 MIPSI_SRA
= 0x00000003,
250 MIPSI_ROTR
= 0x00200002, /* MIPSXXR2 */
251 MIPSI_DROTR
= 0x0020003a,
252 MIPSI_DROTR32
= 0x0020003e,
253 MIPSI_SLLV
= 0x00000004,
254 MIPSI_SRLV
= 0x00000006,
255 MIPSI_SRAV
= 0x00000007,
256 MIPSI_ROTRV
= 0x00000046, /* MIPSXXR2 */
257 MIPSI_DROTRV
= 0x00000056,
259 MIPSI_INS
= 0x7c000004, /* MIPSXXR2 */
261 MIPSI_SEB
= 0x7c000420, /* MIPSXXR2 */
262 MIPSI_SEH
= 0x7c000620, /* MIPSXXR2 */
263 MIPSI_WSBH
= 0x7c0000a0, /* MIPSXXR2 */
264 MIPSI_DSBH
= 0x7c0000a4,
266 MIPSI_B
= 0x10000000,
267 MIPSI_J
= 0x08000000,
268 MIPSI_JAL
= 0x0c000000,
269 #if !LJ_TARGET_MIPSR6
270 MIPSI_JALX
= 0x74000000,
271 MIPSI_JR
= 0x00000008,
273 MIPSI_JR
= 0x00000009,
274 MIPSI_BALC
= 0xe8000000,
276 MIPSI_JALR
= 0x0000f809,
278 MIPSI_BEQ
= 0x10000000,
279 MIPSI_BNE
= 0x14000000,
280 MIPSI_BLEZ
= 0x18000000,
281 MIPSI_BGTZ
= 0x1c000000,
282 MIPSI_BLTZ
= 0x04000000,
283 MIPSI_BGEZ
= 0x04010000,
285 /* Load/store instructions. */
286 MIPSI_LW
= 0x8c000000,
287 MIPSI_LD
= 0xdc000000,
288 MIPSI_SW
= 0xac000000,
289 MIPSI_SD
= 0xfc000000,
290 MIPSI_LB
= 0x80000000,
291 MIPSI_SB
= 0xa0000000,
292 MIPSI_LH
= 0x84000000,
293 MIPSI_SH
= 0xa4000000,
294 MIPSI_LBU
= 0x90000000,
295 MIPSI_LHU
= 0x94000000,
296 MIPSI_LWC1
= 0xc4000000,
297 MIPSI_SWC1
= 0xe4000000,
298 MIPSI_LDC1
= 0xd4000000,
299 MIPSI_SDC1
= 0xf4000000,
301 /* MIPS64 instructions. */
302 MIPSI_DADD
= 0x0000002c,
303 MIPSI_DADDU
= 0x0000002d,
304 MIPSI_DADDIU
= 0x64000000,
305 MIPSI_DSUB
= 0x0000002e,
306 MIPSI_DSUBU
= 0x0000002f,
307 #if !LJ_TARGET_MIPSR6
308 MIPSI_DDIV
= 0x0000001e,
309 MIPSI_DDIVU
= 0x0000001f,
310 MIPSI_DMULT
= 0x0000001c,
311 MIPSI_DMULTU
= 0x0000001d,
313 MIPSI_DDIV
= 0x0000009e,
314 MIPSI_DMOD
= 0x000000de,
315 MIPSI_DDIVU
= 0x0000009f,
316 MIPSI_DMODU
= 0x000000df,
317 MIPSI_DMUL
= 0x0000009c,
318 MIPSI_DMUH
= 0x000000dc,
321 MIPSI_DSLL
= 0x00000038,
322 MIPSI_DSRL
= 0x0000003a,
323 MIPSI_DSLLV
= 0x00000014,
324 MIPSI_DSRLV
= 0x00000016,
325 MIPSI_DSRA
= 0x0000003b,
326 MIPSI_DSRAV
= 0x00000017,
327 MIPSI_DSRA32
= 0x0000003f,
328 MIPSI_DSLL32
= 0x0000003c,
329 MIPSI_DSRL32
= 0x0000003e,
330 MIPSI_DSHD
= 0x7c000164,
332 MIPSI_AADDU
= LJ_32
? MIPSI_ADDU
: MIPSI_DADDU
,
333 MIPSI_AADDIU
= LJ_32
? MIPSI_ADDIU
: MIPSI_DADDIU
,
334 MIPSI_ASUBU
= LJ_32
? MIPSI_SUBU
: MIPSI_DSUBU
,
335 MIPSI_AL
= LJ_32
? MIPSI_LW
: MIPSI_LD
,
336 MIPSI_AS
= LJ_32
? MIPSI_SW
: MIPSI_SD
,
338 MIPSI_LSA
= 0x00000005,
339 MIPSI_DLSA
= 0x00000015,
340 MIPSI_ALSA
= LJ_32
? MIPSI_LSA
: MIPSI_DLSA
,
343 /* Extract/insert instructions. */
344 MIPSI_DEXTM
= 0x7c000001,
345 MIPSI_DEXTU
= 0x7c000002,
346 MIPSI_DEXT
= 0x7c000003,
347 MIPSI_DINSM
= 0x7c000005,
348 MIPSI_DINSU
= 0x7c000006,
349 MIPSI_DINS
= 0x7c000007,
351 MIPSI_FLOOR_D
= 0x4620000b,
353 /* FP instructions. */
354 MIPSI_MOV_S
= 0x46000006,
355 MIPSI_MOV_D
= 0x46200006,
356 #if !LJ_TARGET_MIPSR6
357 MIPSI_MOVT_D
= 0x46210011,
358 MIPSI_MOVF_D
= 0x46200011,
360 MIPSI_MIN_D
= 0x4620001C,
361 MIPSI_MAX_D
= 0x4620001E,
362 MIPSI_SEL_D
= 0x46200010,
365 MIPSI_ABS_D
= 0x46200005,
366 MIPSI_NEG_D
= 0x46200007,
368 MIPSI_ADD_D
= 0x46200000,
369 MIPSI_SUB_D
= 0x46200001,
370 MIPSI_MUL_D
= 0x46200002,
371 MIPSI_DIV_D
= 0x46200003,
372 MIPSI_SQRT_D
= 0x46200004,
374 MIPSI_ADD_S
= 0x46000000,
375 MIPSI_SUB_S
= 0x46000001,
377 MIPSI_CVT_D_S
= 0x46000021,
378 MIPSI_CVT_W_S
= 0x46000024,
379 MIPSI_CVT_S_D
= 0x46200020,
380 MIPSI_CVT_W_D
= 0x46200024,
381 MIPSI_CVT_S_W
= 0x46800020,
382 MIPSI_CVT_D_W
= 0x46800021,
383 MIPSI_CVT_S_L
= 0x46a00020,
384 MIPSI_CVT_D_L
= 0x46a00021,
386 MIPSI_TRUNC_W_S
= 0x4600000d,
387 MIPSI_TRUNC_W_D
= 0x4620000d,
388 MIPSI_TRUNC_L_S
= 0x46000009,
389 MIPSI_TRUNC_L_D
= 0x46200009,
390 MIPSI_FLOOR_W_S
= 0x4600000f,
391 MIPSI_FLOOR_W_D
= 0x4620000f,
393 MIPSI_MFC1
= 0x44000000,
394 MIPSI_MTC1
= 0x44800000,
395 MIPSI_DMTC1
= 0x44a00000,
396 MIPSI_DMFC1
= 0x44200000,
398 #if !LJ_TARGET_MIPSR6
399 MIPSI_BC1F
= 0x45000000,
400 MIPSI_BC1T
= 0x45010000,
401 MIPSI_C_EQ_D
= 0x46200032,
402 MIPSI_C_OLT_S
= 0x46000034,
403 MIPSI_C_OLT_D
= 0x46200034,
404 MIPSI_C_ULT_D
= 0x46200035,
405 MIPSI_C_OLE_D
= 0x46200036,
406 MIPSI_C_ULE_D
= 0x46200037,
408 MIPSI_BC1EQZ
= 0x45200000,
409 MIPSI_BC1NEZ
= 0x45a00000,
410 MIPSI_CMP_EQ_D
= 0x46a00002,
411 MIPSI_CMP_LT_S
= 0x46800004,
412 MIPSI_CMP_LT_D
= 0x46a00004,