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