1 /*
2 ** Definitions for MIPS CPUs.
3 ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
4 */
5 
6 #ifndef _LJ_TARGET_MIPS_H
7 #define _LJ_TARGET_MIPS_H
8 
9 /* -- Registers IDs ------------------------------------------------------- */
10 
11 #define GPRDEF(_) \
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)
16 #define FPRDEF(_) \
17   _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
18   _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
19   _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
20   _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
21 #define VRIDDEF(_)
22 
23 #define RIDENUM(name)	RID_##name,
24 
25 enum {
26   GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
27   FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
28   RID_MAX,
29   RID_ZERO = RID_R0,
30   RID_TMP = RID_RA,
31 
32   /* Calling conventions. */
33   RID_RET = RID_R2,
34 #if LJ_LE
35   RID_RETHI = RID_R3,
36   RID_RETLO = RID_R2,
37 #else
38   RID_RETHI = RID_R2,
39   RID_RETLO = RID_R3,
40 #endif
41   RID_FPRET = RID_F0,
42   RID_CFUNCADDR = RID_R25,
43 
44   /* These definitions must match with the *.dasc file(s): */
45   RID_BASE = RID_R16,		/* Interpreter BASE. */
46   RID_LPC = RID_R18,		/* Interpreter PC. */
47   RID_DISPATCH = RID_R19,	/* Interpreter DISPATCH table. */
48   RID_LREG = RID_R20,		/* Interpreter L. */
49   RID_JGL = RID_R30,		/* On-trace: global_State + 32768. */
50 
51   /* Register ranges [min, max) and number of registers. */
52   RID_MIN_GPR = RID_R0,
53   RID_MAX_GPR = RID_RA+1,
54   RID_MIN_FPR = RID_F0,
55   RID_MAX_FPR = RID_F31+1,
56   RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
57   RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR	/* Only even regs are used. */
58 };
59 
60 #define RID_NUM_KREF		RID_NUM_GPR
61 #define RID_MIN_KREF		RID_R0
62 
63 /* -- Register sets ------------------------------------------------------- */
64 
65 /* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2 and JGL. */
66 #define RSET_FIXED \
67   (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\
68    RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL))
69 #define RSET_GPR	(RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
70 #define RSET_FPR \
71   (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
72    RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
73    RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\
74    RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30))
75 #define RSET_ALL	(RSET_GPR|RSET_FPR)
76 #define RSET_INIT	RSET_ALL
77 
78 #define RSET_SCRATCH_GPR \
79   (RSET_RANGE(RID_R1, RID_R15+1)|\
80    RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_R28))
81 #define RSET_SCRATCH_FPR \
82   (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
83    RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
84    RID2RSET(RID_F16)|RID2RSET(RID_F18))
85 #define RSET_SCRATCH		(RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
86 #define REGARG_FIRSTGPR		RID_R4
87 #define REGARG_LASTGPR		RID_R7
88 #define REGARG_NUMGPR		4
89 #define REGARG_FIRSTFPR		RID_F12
90 #define REGARG_LASTFPR		RID_F14
91 #define REGARG_NUMFPR		2
92 
93 /* -- Spill slots --------------------------------------------------------- */
94 
95 /* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
96 **
97 ** SPS_FIXED: Available fixed spill slots in interpreter frame.
98 ** This definition must match with the *.dasc file(s).
99 **
100 ** SPS_FIRST: First spill slot for general use.
101 */
102 #define SPS_FIXED	5
103 #define SPS_FIRST	4
104 
105 #define SPOFS_TMP	0
106 
107 #define sps_scale(slot)		(4 * (int32_t)(slot))
108 #define sps_align(slot)		(((slot) - SPS_FIXED + 1) & ~1)
109 
110 /* -- Exit state ---------------------------------------------------------- */
111 
112 /* This definition must match with the *.dasc file(s). */
113 typedef struct {
114   lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
115   int32_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
116   int32_t spill[256];		/* Spill slots. */
117 } ExitState;
118 
119 /* Highest exit + 1 indicates stack check. */
120 #define EXITSTATE_CHECKEXIT	1
121 
122 /* Return the address of a per-trace exit stub. */
exitstub_trace_addr_(uint32_t * p)123 static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p)
124 {
125   while (*p == 0x00000000) p++;  /* Skip MIPSI_NOP. */
126   return p;
127 }
128 /* Avoid dependence on lj_jit.h if only including lj_target.h. */
129 #define exitstub_trace_addr(T, exitno) \
130   exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode))
131 
132 /* -- Instructions -------------------------------------------------------- */
133 
134 /* Instruction fields. */
135 #define MIPSF_S(r)	((r) << 21)
136 #define MIPSF_T(r)	((r) << 16)
137 #define MIPSF_D(r)	((r) << 11)
138 #define MIPSF_R(r)	((r) << 21)
139 #define MIPSF_H(r)	((r) << 16)
140 #define MIPSF_G(r)	((r) << 11)
141 #define MIPSF_F(r)	((r) << 6)
142 #define MIPSF_A(n)	((n) << 6)
143 #define MIPSF_M(n)	((n) << 11)
144 
145 typedef enum MIPSIns {
146   /* Integer instructions. */
147   MIPSI_MOVE = 0x00000021,
148   MIPSI_NOP = 0x00000000,
149 
150   MIPSI_LI = 0x24000000,
151   MIPSI_LU = 0x34000000,
152   MIPSI_LUI = 0x3c000000,
153 
154   MIPSI_ADDIU = 0x24000000,
155   MIPSI_ANDI = 0x30000000,
156   MIPSI_ORI = 0x34000000,
157   MIPSI_XORI = 0x38000000,
158   MIPSI_SLTI = 0x28000000,
159   MIPSI_SLTIU = 0x2c000000,
160 
161   MIPSI_ADDU = 0x00000021,
162   MIPSI_SUBU = 0x00000023,
163   MIPSI_MUL = 0x70000002,
164   MIPSI_AND = 0x00000024,
165   MIPSI_OR = 0x00000025,
166   MIPSI_XOR = 0x00000026,
167   MIPSI_NOR = 0x00000027,
168   MIPSI_SLT = 0x0000002a,
169   MIPSI_SLTU = 0x0000002b,
170   MIPSI_MOVZ = 0x0000000a,
171   MIPSI_MOVN = 0x0000000b,
172 
173   MIPSI_SLL = 0x00000000,
174   MIPSI_SRL = 0x00000002,
175   MIPSI_SRA = 0x00000003,
176   MIPSI_ROTR = 0x00200002,	/* MIPS32R2 */
177   MIPSI_SLLV = 0x00000004,
178   MIPSI_SRLV = 0x00000006,
179   MIPSI_SRAV = 0x00000007,
180   MIPSI_ROTRV = 0x00000046,	/* MIPS32R2 */
181 
182   MIPSI_SEB = 0x7c000420,	/* MIPS32R2 */
183   MIPSI_SEH = 0x7c000620,	/* MIPS32R2 */
184   MIPSI_WSBH = 0x7c0000a0,	/* MIPS32R2 */
185 
186   MIPSI_B = 0x10000000,
187   MIPSI_J = 0x08000000,
188   MIPSI_JAL = 0x0c000000,
189   MIPSI_JR = 0x00000008,
190   MIPSI_JALR = 0x0000f809,
191 
192   MIPSI_BEQ = 0x10000000,
193   MIPSI_BNE = 0x14000000,
194   MIPSI_BLEZ = 0x18000000,
195   MIPSI_BGTZ = 0x1c000000,
196   MIPSI_BLTZ = 0x04000000,
197   MIPSI_BGEZ = 0x04010000,
198 
199   /* Load/store instructions. */
200   MIPSI_LW = 0x8c000000,
201   MIPSI_SW = 0xac000000,
202   MIPSI_LB = 0x80000000,
203   MIPSI_SB = 0xa0000000,
204   MIPSI_LH = 0x84000000,
205   MIPSI_SH = 0xa4000000,
206   MIPSI_LBU = 0x90000000,
207   MIPSI_LHU = 0x94000000,
208   MIPSI_LWC1 = 0xc4000000,
209   MIPSI_SWC1 = 0xe4000000,
210   MIPSI_LDC1 = 0xd4000000,
211   MIPSI_SDC1 = 0xf4000000,
212 
213   /* FP instructions. */
214   MIPSI_MOV_S = 0x46000006,
215   MIPSI_MOV_D = 0x46200006,
216   MIPSI_MOVT_D = 0x46210011,
217   MIPSI_MOVF_D = 0x46200011,
218 
219   MIPSI_ABS_D = 0x46200005,
220   MIPSI_NEG_D = 0x46200007,
221 
222   MIPSI_ADD_D = 0x46200000,
223   MIPSI_SUB_D = 0x46200001,
224   MIPSI_MUL_D = 0x46200002,
225   MIPSI_DIV_D = 0x46200003,
226   MIPSI_SQRT_D = 0x46200004,
227 
228   MIPSI_ADD_S = 0x46000000,
229   MIPSI_SUB_S = 0x46000001,
230 
231   MIPSI_CVT_D_S = 0x46000021,
232   MIPSI_CVT_W_S = 0x46000024,
233   MIPSI_CVT_S_D = 0x46200020,
234   MIPSI_CVT_W_D = 0x46200024,
235   MIPSI_CVT_S_W = 0x46800020,
236   MIPSI_CVT_D_W = 0x46800021,
237 
238   MIPSI_TRUNC_W_S = 0x4600000d,
239   MIPSI_TRUNC_W_D = 0x4620000d,
240   MIPSI_FLOOR_W_S = 0x4600000f,
241   MIPSI_FLOOR_W_D = 0x4620000f,
242 
243   MIPSI_MFC1 = 0x44000000,
244   MIPSI_MTC1 = 0x44800000,
245 
246   MIPSI_BC1F = 0x45000000,
247   MIPSI_BC1T = 0x45010000,
248 
249   MIPSI_C_EQ_D = 0x46200032,
250   MIPSI_C_OLT_D = 0x46200034,
251   MIPSI_C_ULT_D = 0x46200035,
252   MIPSI_C_OLE_D = 0x46200036,
253   MIPSI_C_ULE_D = 0x46200037,
254 
255 } MIPSIns;
256 
257 #endif
258