1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_ 18 #define DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_ 19 20 #include "Dalvik.h" 21 #include "compiler/CompilerInternals.h" 22 23 /* 24 * zero is always the value 0 25 * at is scratch for Jit (normally used as temp reg by assembler) 26 * v0, v1 are scratch for Jit (normally hold subroutine return values) 27 * a0-a3 are scratch for Jit (normally hold subroutine arguments) 28 * t0-t7 are scratch for Jit 29 * t8 is scratch for Jit 30 * t9 is scratch for Jit (normally used for function calls) 31 * s0 (rFP) is reserved [holds Dalvik frame pointer] 32 * s1 (rSELF) is reserved [holds current &Thread] 33 * s2 (rINST) is scratch for Jit 34 * s3 (rIBASE) is scratch for Jit 35 * s4-s7 are scratch for Jit 36 * k0, k1 are reserved for use by interrupt handlers 37 * gp is reserved for global pointer 38 * sp is reserved 39 * s8 is scratch for Jit 40 * ra is scratch for Jit (normally holds the return addr) 41 * 42 * Preserved across C calls: s0-s8 43 * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra 44 * 45 * Floating pointer registers 46 * NOTE: there are 32 fp registers (16 df pairs), but current Jit code 47 * only support 16 fp registers (8 df pairs). 48 * f0-f15 49 * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15} 50 * 51 * f0-f15 (df0-df7) trashed across C calls 52 * 53 * For mips32 code use: 54 * a0-a3 to hold operands 55 * v0-v1 to hold results 56 * t0-t9 for temps 57 * 58 * All jump/branch instructions have a delay slot after it. 59 * 60 */ 61 62 /* Offset to distingish FP regs */ 63 #define FP_REG_OFFSET 32 64 /* Offset to distinguish DP FP regs */ 65 #define FP_DOUBLE 64 66 /* Offset to distingish the extra regs */ 67 #define EXTRA_REG_OFFSET 128 68 /* Reg types */ 69 #define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE)) 70 #define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET) 71 #define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET) 72 #define LOWREG(x) ((x & 0x1f) == x) 73 #define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE) 74 #define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x)) 75 /* 76 * Note: the low register of a floating point pair is sufficient to 77 * create the name of a double, but require both names to be passed to 78 * allow for asserts to verify that the pair is consecutive if significant 79 * rework is done in this area. Also, it is a good reminder in the calling 80 * code that reg locations always describe doubles as a pair of singles. 81 */ 82 #define S2D(x,y) ((x) | FP_DOUBLE) 83 /* Mask to strip off fp flags */ 84 #define FP_REG_MASK (FP_REG_OFFSET-1) 85 /* non-existent Dalvik register */ 86 #define vNone (-1) 87 /* non-existant physical register */ 88 #define rNone (-1) 89 90 #ifdef HAVE_LITTLE_ENDIAN 91 #define LOWORD_OFFSET 0 92 #define HIWORD_OFFSET 4 93 #define r_ARG0 r_A0 94 #define r_ARG1 r_A1 95 #define r_ARG2 r_A2 96 #define r_ARG3 r_A3 97 #define r_RESULT0 r_V0 98 #define r_RESULT1 r_V1 99 #else 100 #define LOWORD_OFFSET 4 101 #define HIWORD_OFFSET 0 102 #define r_ARG0 r_A1 103 #define r_ARG1 r_A0 104 #define r_ARG2 r_A3 105 #define r_ARG3 r_A2 106 #define r_RESULT0 r_V1 107 #define r_RESULT1 r_V0 108 #endif 109 110 /* These are the same for both big and little endian. */ 111 #define r_FARG0 r_F12 112 #define r_FARG1 r_F13 113 #define r_FRESULT0 r_F0 114 #define r_FRESULT1 r_F1 115 116 /* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */ 117 #define LOC_C_RETURN {kLocPhysReg, 0, 0, r_V0, 0, -1} 118 #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r_RESULT0, r_RESULT1, -1} 119 #define LOC_C_RETURN_ALT {kLocPhysReg, 0, 1, r_F0, 0, -1} 120 #define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 1, r_FRESULT0, r_FRESULT1, -1} 121 /* RegisterLocation templates for interpState->retVal; */ 122 #define LOC_DALVIK_RETURN_VAL {kLocRetval, 0, 0, 0, 0, -1} 123 #define LOC_DALVIK_RETURN_VAL_WIDE {kLocRetval, 1, 0, 0, 0, -1} 124 125 /* 126 * Data structure tracking the mapping between a Dalvik register (pair) and a 127 * native register (pair). The idea is to reuse the previously loaded value 128 * if possible, otherwise to keep the value in a native register as long as 129 * possible. 130 */ 131 typedef struct RegisterInfo { 132 int reg; // Reg number 133 bool inUse; // Has it been allocated? 134 bool pair; // Part of a register pair? 135 int partner; // If pair, other reg of pair 136 bool live; // Is there an associated SSA name? 137 bool dirty; // If live, is it dirty? 138 int sReg; // Name of live value 139 struct LIR *defStart; // Starting inst in last def sequence 140 struct LIR *defEnd; // Ending inst in last def sequence 141 } RegisterInfo; 142 143 typedef struct RegisterPool { 144 BitVector *nullCheckedRegs; // Track which registers have been null-checked 145 int numCoreTemps; 146 RegisterInfo *coreTemps; 147 int nextCoreTemp; 148 int numFPTemps; 149 RegisterInfo *FPTemps; 150 int nextFPTemp; 151 } RegisterPool; 152 153 typedef enum ResourceEncodingPos { 154 kGPReg0 = 0, 155 kRegSP = 29, 156 kRegLR = 31, 157 kFPReg0 = 32, /* only 16 fp regs supported currently */ 158 kFPRegEnd = 48, 159 kRegHI = kFPRegEnd, 160 kRegLO, 161 kRegPC, 162 kRegEnd = 51, 163 kCCode = kRegEnd, 164 kFPStatus, // FP status word 165 // The following four bits are for memory disambiguation 166 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) 167 kLiteral, // 2 Literal pool (can be fully disambiguated) 168 kHeapRef, // 3 Somewhere on the heap (alias with any other heap) 169 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) 170 } ResourceEncodingPos; 171 172 #define ENCODE_REG_LIST(N) ((u8) N) 173 #define ENCODE_REG_SP (1ULL << kRegSP) 174 #define ENCODE_REG_LR (1ULL << kRegLR) 175 #define ENCODE_REG_PC (1ULL << kRegPC) 176 #define ENCODE_CCODE (1ULL << kCCode) 177 #define ENCODE_FP_STATUS (1ULL << kFPStatus) 178 179 /* Abstract memory locations */ 180 #define ENCODE_DALVIK_REG (1ULL << kDalvikReg) 181 #define ENCODE_LITERAL (1ULL << kLiteral) 182 #define ENCODE_HEAP_REF (1ULL << kHeapRef) 183 #define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias) 184 185 #define ENCODE_ALL (~0ULL) 186 #define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ 187 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) 188 189 #define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) 190 #define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) 191 192 typedef enum OpSize { 193 kWord, 194 kLong, 195 kSingle, 196 kDouble, 197 kUnsignedHalf, 198 kSignedHalf, 199 kUnsignedByte, 200 kSignedByte, 201 } OpSize; 202 203 typedef enum OpKind { 204 kOpMov, 205 kOpMvn, 206 kOpCmp, 207 kOpLsl, 208 kOpLsr, 209 kOpAsr, 210 kOpRor, 211 kOpNot, 212 kOpAnd, 213 kOpOr, 214 kOpXor, 215 kOpNeg, 216 kOpAdd, 217 kOpAdc, 218 kOpSub, 219 kOpSbc, 220 kOpRsub, 221 kOpMul, 222 kOpDiv, 223 kOpRem, 224 kOpBic, 225 kOpCmn, 226 kOpTst, 227 kOpBkpt, 228 kOpBlx, 229 kOpPush, 230 kOpPop, 231 kOp2Char, 232 kOp2Short, 233 kOp2Byte, 234 kOpCondBr, 235 kOpUncondBr, 236 } OpKind; 237 238 /* 239 * Annotate special-purpose core registers: 240 * 241 * rPC, rFP, and rSELF are for architecture-independent code to use. 242 */ 243 typedef enum NativeRegisterPool { 244 r_ZERO = 0, 245 r_AT = 1, 246 r_V0 = 2, 247 r_V1 = 3, 248 r_A0 = 4, 249 r_A1 = 5, 250 r_A2 = 6, 251 r_A3 = 7, 252 r_T0 = 8, 253 r_T1 = 9, 254 r_T2 = 10, 255 r_T3 = 11, 256 r_T4 = 12, 257 r_T5 = 13, 258 r_T6 = 14, 259 r_T7 = 15, 260 r_S0 = 16, 261 r_S1 = 17, 262 r_S2 = 18, 263 r_S3 = 19, 264 r_S4 = 20, 265 r_S5 = 21, 266 r_S6 = 22, 267 r_S7 = 23, 268 r_T8 = 24, 269 r_T9 = 25, 270 r_K0 = 26, 271 r_K1 = 27, 272 r_GP = 28, 273 r_SP = 29, 274 r_FP = 30, 275 r_RA = 31, 276 277 r_F0 = 0 + FP_REG_OFFSET, 278 r_F1, 279 r_F2, 280 r_F3, 281 r_F4, 282 r_F5, 283 r_F6, 284 r_F7, 285 r_F8, 286 r_F9, 287 r_F10, 288 r_F11, 289 r_F12, 290 r_F13, 291 r_F14, 292 r_F15, 293 #if 0 /* only 16 fp regs supported currently */ 294 r_F16, 295 r_F17, 296 r_F18, 297 r_F19, 298 r_F20, 299 r_F21, 300 r_F22, 301 r_F23, 302 r_F24, 303 r_F25, 304 r_F26, 305 r_F27, 306 r_F28, 307 r_F29, 308 r_F30, 309 r_F31, 310 #endif 311 r_DF0 = r_F0 + FP_DOUBLE, 312 r_DF1 = r_F2 + FP_DOUBLE, 313 r_DF2 = r_F4 + FP_DOUBLE, 314 r_DF3 = r_F6 + FP_DOUBLE, 315 r_DF4 = r_F8 + FP_DOUBLE, 316 r_DF5 = r_F10 + FP_DOUBLE, 317 r_DF6 = r_F12 + FP_DOUBLE, 318 r_DF7 = r_F14 + FP_DOUBLE, 319 #if 0 /* only 16 fp regs supported currently */ 320 r_DF8 = r_F16 + FP_DOUBLE, 321 r_DF9 = r_F18 + FP_DOUBLE, 322 r_DF10 = r_F20 + FP_DOUBLE, 323 r_DF11 = r_F22 + FP_DOUBLE, 324 r_DF12 = r_F24 + FP_DOUBLE, 325 r_DF13 = r_F26 + FP_DOUBLE, 326 r_DF14 = r_F28 + FP_DOUBLE, 327 r_DF15 = r_F30 + FP_DOUBLE, 328 #endif 329 r_HI = EXTRA_REG_OFFSET, 330 r_LO, 331 r_PC, 332 } NativeRegisterPool; 333 334 335 /* must match gp offset used mterp/mips files */ 336 #define STACK_OFFSET_GP 84 337 338 /* MIPSTODO: properly remap arm regs (dPC, dFP, dGLUE) and remove these mappings */ 339 #define r4PC r_S0 340 #define rFP r_S1 341 #define rSELF r_S2 342 #define rINST r_S4 343 344 /* Shift encodings */ 345 typedef enum MipsShiftEncodings { 346 kMipsLsl = 0x0, 347 kMipsLsr = 0x1, 348 kMipsAsr = 0x2, 349 kMipsRor = 0x3 350 } MipsShiftEncodings; 351 352 /* condition encodings */ 353 typedef enum MipsConditionCode { 354 kMipsCondEq = 0x0, /* 0000 */ 355 kMipsCondNe = 0x1, /* 0001 */ 356 kMipsCondCs = 0x2, /* 0010 */ 357 kMipsCondCc = 0x3, /* 0011 */ 358 kMipsCondMi = 0x4, /* 0100 */ 359 kMipsCondPl = 0x5, /* 0101 */ 360 kMipsCondVs = 0x6, /* 0110 */ 361 kMipsCondVc = 0x7, /* 0111 */ 362 kMipsCondHi = 0x8, /* 1000 */ 363 kMipsCondLs = 0x9, /* 1001 */ 364 kMipsCondGe = 0xa, /* 1010 */ 365 kMipsCondLt = 0xb, /* 1011 */ 366 kMipsCondGt = 0xc, /* 1100 */ 367 kMipsCondLe = 0xd, /* 1101 */ 368 kMipsCondAl = 0xe, /* 1110 */ 369 kMipsCondNv = 0xf, /* 1111 */ 370 } MipsConditionCode; 371 372 #define isPseudoOpCode(opCode) ((int)(opCode) < 0) 373 374 /* 375 * The following enum defines the list of supported Thumb instructions by the 376 * assembler. Their corresponding snippet positions will be defined in 377 * Assemble.c. 378 */ 379 typedef enum MipsOpCode { 380 kMipsChainingCellBottom = -18, 381 kMipsPseudoBarrier = -17, 382 kMipsPseudoExtended = -16, 383 kMipsPseudoSSARep = -15, 384 kMipsPseudoEntryBlock = -14, 385 kMipsPseudoExitBlock = -13, 386 kMipsPseudoTargetLabel = -12, 387 kMipsPseudoChainingCellBackwardBranch = -11, 388 kMipsPseudoChainingCellHot = -10, 389 kMipsPseudoChainingCellInvokePredicted = -9, 390 kMipsPseudoChainingCellInvokeSingleton = -8, 391 kMipsPseudoChainingCellNormal = -7, 392 kMipsPseudoDalvikByteCodeBoundary = -6, 393 kMipsPseudoPseudoAlign4 = -5, 394 kMipsPseudoPCReconstructionCell = -4, 395 kMipsPseudoPCReconstructionBlockLabel = -3, 396 kMipsPseudoEHBlockLabel = -2, 397 kMipsPseudoNormalBlockLabel = -1, 398 399 kMipsFirst, 400 kMips32BitData = kMipsFirst, /* data [31..0] */ 401 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ 402 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */ 403 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */ 404 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */ 405 kMipsB, /* b o [0001000000000000] o[15..0] */ 406 kMipsBal, /* bal o [0000010000010001] o[15..0] */ 407 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so 408 adding an instruction in this range may require updates */ 409 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */ 410 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */ 411 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */ 412 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */ 413 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */ 414 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */ 415 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */ 416 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */ 417 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */ 418 #if __mips_isa_rev>=2 419 kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */ 420 #endif 421 kMipsJal, /* jal t [000011] t[25..0] */ 422 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11] 423 hint[10..6] [001001] */ 424 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */ 425 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */ 426 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */ 427 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */ 428 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */ 429 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */ 430 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */ 431 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */ 432 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */ 433 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */ 434 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */ 435 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */ 436 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */ 437 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */ 438 kMipsNop, /* nop [00000000000000000000000000000000] */ 439 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */ 440 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */ 441 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ 442 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */ 443 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */ 444 #if __mips_isa_rev>=2 445 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */ 446 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */ 447 #endif 448 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */ 449 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */ 450 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */ 451 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */ 452 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */ 453 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */ 454 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */ 455 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */ 456 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */ 457 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */ 458 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */ 459 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */ 460 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */ 461 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */ 462 #ifdef __mips_hard_float 463 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */ 464 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */ 465 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */ 466 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */ 467 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */ 468 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */ 469 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */ 470 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */ 471 kMipsFcvtsd, /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */ 472 kMipsFcvtsw, /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */ 473 kMipsFcvtds, /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */ 474 kMipsFcvtdw, /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */ 475 kMipsFcvtws, /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */ 476 kMipsFcvtwd, /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */ 477 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */ 478 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */ 479 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */ 480 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */ 481 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */ 482 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */ 483 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */ 484 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */ 485 #endif 486 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */ 487 kMipsLast 488 } MipsOpCode; 489 490 /* Bit flags describing the behavior of each native opcode */ 491 typedef enum MipsOpFeatureFlags { 492 kIsBranch = 0, 493 kRegDef0, 494 kRegDef1, 495 kRegDefSP, 496 kRegDefLR, 497 kRegDefList0, 498 kRegDefList1, 499 kRegUse0, 500 kRegUse1, 501 kRegUse2, 502 kRegUse3, 503 kRegUseSP, 504 kRegUsePC, 505 kRegUseList0, 506 kRegUseList1, 507 kNoOperand, 508 kIsUnaryOp, 509 kIsBinaryOp, 510 kIsTertiaryOp, 511 kIsQuadOp, 512 kIsIT, 513 kSetsCCodes, 514 kUsesCCodes, 515 kMemLoad, 516 kMemStore, 517 } MipsOpFeatureFlags; 518 519 #define IS_LOAD (1 << kMemLoad) 520 #define IS_STORE (1 << kMemStore) 521 #define IS_BRANCH (1 << kIsBranch) 522 #define REG_DEF0 (1 << kRegDef0) 523 #define REG_DEF1 (1 << kRegDef1) 524 #define REG_DEF_SP (1 << kRegDefSP) 525 #define REG_DEF_LR (1 << kRegDefLR) 526 #define REG_DEF_LIST0 (1 << kRegDefList0) 527 #define REG_DEF_LIST1 (1 << kRegDefList1) 528 #define REG_USE0 (1 << kRegUse0) 529 #define REG_USE1 (1 << kRegUse1) 530 #define REG_USE2 (1 << kRegUse2) 531 #define REG_USE3 (1 << kRegUse3) 532 #define REG_USE_SP (1 << kRegUseSP) 533 #define REG_USE_PC (1 << kRegUsePC) 534 #define REG_USE_LIST0 (1 << kRegUseList0) 535 #define REG_USE_LIST1 (1 << kRegUseList1) 536 #define NO_OPERAND (1 << kNoOperand) 537 #define IS_UNARY_OP (1 << kIsUnaryOp) 538 #define IS_BINARY_OP (1 << kIsBinaryOp) 539 #define IS_TERTIARY_OP (1 << kIsTertiaryOp) 540 #define IS_QUAD_OP (1 << kIsQuadOp) 541 #define IS_IT (1 << kIsIT) 542 #define SETS_CCODES (1 << kSetsCCodes) 543 #define USES_CCODES (1 << kUsesCCodes) 544 545 /* Common combo register usage patterns */ 546 #define REG_USE01 (REG_USE0 | REG_USE1) 547 #define REG_USE02 (REG_USE0 | REG_USE2) 548 #define REG_USE012 (REG_USE01 | REG_USE2) 549 #define REG_USE12 (REG_USE1 | REG_USE2) 550 #define REG_USE23 (REG_USE2 | REG_USE3) 551 #define REG_DEF01 (REG_DEF0 | REG_DEF1) 552 #define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) 553 #define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) 554 #define REG_DEF0_USE2 (REG_DEF0 | REG_USE2) 555 #define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) 556 #define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) 557 #define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) 558 559 /* Instruction assembly fieldLoc kind */ 560 typedef enum MipsEncodingKind { 561 kFmtUnused, 562 kFmtBitBlt, /* Bit string using end/start */ 563 kFmtDfp, /* Double FP reg */ 564 kFmtSfp, /* Single FP reg */ 565 } MipsEncodingKind; 566 567 /* Struct used to define the snippet positions for each Thumb opcode */ 568 typedef struct MipsEncodingMap { 569 u4 skeleton; 570 struct { 571 MipsEncodingKind kind; 572 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */ 573 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */ 574 } fieldLoc[4]; 575 MipsOpCode opcode; 576 int flags; 577 const char *name; 578 const char* fmt; 579 int size; 580 } MipsEncodingMap; 581 582 /* Keys for target-specific scheduling and other optimization hints */ 583 typedef enum MipsTargetOptHints { 584 kMaxHoistDistance, 585 } MipsTargetOptHints; 586 587 extern MipsEncodingMap EncodingMap[kMipsLast]; 588 589 /* 590 * Each instance of this struct holds a pseudo or real LIR instruction: 591 * - pseudo ones (eg labels and marks) and will be discarded by the assembler. 592 * - real ones will be assembled into Thumb instructions. 593 * 594 * Machine resources are encoded into a 64-bit vector, where the encodings are 595 * as following: 596 * - [ 0..15]: general purpose registers including PC, SP, and LR 597 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0 598 * starts at bit 16 599 * - [48]: IT block 600 * - [49]: integer condition code 601 * - [50]: floatint-point status word 602 */ 603 typedef struct MipsLIR { 604 LIR generic; 605 MipsOpCode opcode; 606 int operands[4]; // [0..3] = [dest, src1, src2, extra] 607 struct { 608 bool isNop:1; // LIR is optimized away 609 bool insertWrapper:1; // insert branch to emulate memory accesses 610 unsigned int age:4; // default is 0, set lazily by the optimizer 611 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2) 612 unsigned int unused:23; 613 } flags; 614 int aliasInfo; // For Dalvik register access & litpool disambiguation 615 u8 useMask; // Resource mask for use 616 u8 defMask; // Resource mask for def 617 } MipsLIR; 618 619 /* Init values when a predicted chain is initially assembled */ 620 /* E7FE is branch to self */ 621 #define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe 622 #define PREDICTED_CHAIN_DELAY_SLOT_INIT 0 623 #define PREDICTED_CHAIN_CLAZZ_INIT 0 624 #define PREDICTED_CHAIN_METHOD_INIT 0 625 #define PREDICTED_CHAIN_COUNTER_INIT 0 626 627 /* Utility macros to traverse the LIR/MipsLIR list */ 628 #define NEXT_LIR(lir) ((MipsLIR *) lir->generic.next) 629 #define PREV_LIR(lir) ((MipsLIR *) lir->generic.prev) 630 631 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next 632 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev 633 634 #define CHAIN_CELL_OFFSET_TAG 0xcdabcdabL 635 636 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535)) 637 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766)) 638 #define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */ 639 640 #define CHAIN_CELL_NORMAL_SIZE 16 641 #define CHAIN_CELL_PREDICTED_SIZE 20 642 643 644 #endif // DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_ 645