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_ARM_ARMLIR_H_ 18 #define DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H_ 19 20 #include "Dalvik.h" 21 #include "compiler/CompilerInternals.h" 22 23 /* 24 * r0, r1, r2, r3 are always scratch 25 * r4 (rPC) is scratch for Jit, but most be restored when resuming interp 26 * r5 (rFP) is reserved [holds Dalvik frame pointer] 27 * r6 (rSELF) is reserved [holds current &Thread] 28 * r7 (rINST) is scratch for Jit 29 * r8 (rIBASE) is scratch for Jit, but must be restored when resuming interp 30 * r9 is reserved 31 * r10 is always scratch 32 * r11 (fp) used by gcc unless -fomit-frame-pointer set [available for jit?] 33 * r12 is always scratch 34 * r13 (sp) is reserved 35 * r14 (lr) is scratch for Jit 36 * r15 (pc) is reserved 37 * 38 * Preserved across C calls: r4, r5, r6, r7, r8, r10, r11 39 * Trashed across C calls: r0, r1, r2, r3, r12, r14 40 * 41 * Floating pointer registers 42 * s0-s31 43 * d0-d15, where d0={s0,s1}, d1={s2,s3}, ... , d15={s30,s31} 44 * 45 * s16-s31 (d8-d15) preserved across C calls 46 * s0-s15 (d0-d7) trashed across C calls 47 * 48 * For Thumb code use: 49 * r0, r1, r2, r3 to hold operands/results 50 * r4, r7 for temps 51 * 52 * For Thumb2 code use: 53 * r0, r1, r2, r3, r8, r9, r10, r11, r12, r14 for operands/results 54 * r4, r7 for temps 55 * s16-s31/d8-d15 for operands/results 56 * s0-s15/d0-d7 for temps 57 * 58 * When transitioning from code cache to interp: 59 * restore rIBASE 60 * restore rPC 61 * restore r11? 62 */ 63 64 /* Offset to distingish FP regs */ 65 #define FP_REG_OFFSET 32 66 /* Offset to distinguish DP FP regs */ 67 #define FP_DOUBLE 64 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 LOWREG(x) ((x & 0x7) == x) 72 #define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE) 73 #define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x)) 74 /* 75 * Note: the low register of a floating point pair is sufficient to 76 * create the name of a double, but require both names to be passed to 77 * allow for asserts to verify that the pair is consecutive if significant 78 * rework is done in this area. Also, it is a good reminder in the calling 79 * code that reg locations always describe doubles as a pair of singles. 80 */ 81 #define S2D(x,y) ((x) | FP_DOUBLE) 82 /* Mask to strip off fp flags */ 83 #define FP_REG_MASK (FP_REG_OFFSET-1) 84 /* non-existent Dalvik register */ 85 #define vNone (-1) 86 /* non-existant physical register */ 87 #define rNone (-1) 88 89 /* RegisterLocation templates return values (r0, or r0/r1) */ 90 #define LOC_C_RETURN {kLocPhysReg, 0, 0, r0, 0, -1} 91 #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r0, r1, -1} 92 /* RegisterLocation templates for interpState->retVal; */ 93 #define LOC_DALVIK_RETURN_VAL {kLocRetval, 0, 0, 0, 0, -1} 94 #define LOC_DALVIK_RETURN_VAL_WIDE {kLocRetval, 1, 0, 0, 0, -1} 95 96 /* 97 * Data structure tracking the mapping between a Dalvik register (pair) and a 98 * native register (pair). The idea is to reuse the previously loaded value 99 * if possible, otherwise to keep the value in a native register as long as 100 * possible. 101 */ 102 typedef struct RegisterInfo { 103 int reg; // Reg number 104 bool inUse; // Has it been allocated? 105 bool pair; // Part of a register pair? 106 int partner; // If pair, other reg of pair 107 bool live; // Is there an associated SSA name? 108 bool dirty; // If live, is it dirty? 109 int sReg; // Name of live value 110 struct LIR *defStart; // Starting inst in last def sequence 111 struct LIR *defEnd; // Ending inst in last def sequence 112 } RegisterInfo; 113 114 typedef struct RegisterPool { 115 BitVector *nullCheckedRegs; // Track which registers have been null-checked 116 int numCoreTemps; 117 RegisterInfo *coreTemps; 118 int nextCoreTemp; 119 int numFPTemps; 120 RegisterInfo *FPTemps; 121 int nextFPTemp; 122 } RegisterPool; 123 124 typedef enum ResourceEncodingPos { 125 kGPReg0 = 0, 126 kRegSP = 13, 127 kRegLR = 14, 128 kRegPC = 15, 129 kFPReg0 = 16, 130 kRegEnd = 48, 131 kCCode = kRegEnd, 132 kFPStatus, // FP status word 133 // The following four bits are for memory disambiguation 134 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) 135 kLiteral, // 2 Literal pool (can be fully disambiguated) 136 kHeapRef, // 3 Somewhere on the heap (alias with any other heap) 137 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) 138 } ResourceEncodingPos; 139 140 #define ENCODE_REG_LIST(N) ((u8) N) 141 #define ENCODE_REG_SP (1ULL << kRegSP) 142 #define ENCODE_REG_LR (1ULL << kRegLR) 143 #define ENCODE_REG_PC (1ULL << kRegPC) 144 #define ENCODE_CCODE (1ULL << kCCode) 145 #define ENCODE_FP_STATUS (1ULL << kFPStatus) 146 147 /* Abstract memory locations */ 148 #define ENCODE_DALVIK_REG (1ULL << kDalvikReg) 149 #define ENCODE_LITERAL (1ULL << kLiteral) 150 #define ENCODE_HEAP_REF (1ULL << kHeapRef) 151 #define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias) 152 153 #define ENCODE_ALL (~0ULL) 154 #define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ 155 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) 156 157 #define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) 158 #define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) 159 160 typedef enum OpSize { 161 kWord, 162 kLong, 163 kSingle, 164 kDouble, 165 kUnsignedHalf, 166 kSignedHalf, 167 kUnsignedByte, 168 kSignedByte, 169 } OpSize; 170 171 typedef enum OpKind { 172 kOpMov, 173 kOpMvn, 174 kOpCmp, 175 kOpLsl, 176 kOpLsr, 177 kOpAsr, 178 kOpRor, 179 kOpNot, 180 kOpAnd, 181 kOpOr, 182 kOpXor, 183 kOpNeg, 184 kOpAdd, 185 kOpAdc, 186 kOpSub, 187 kOpSbc, 188 kOpRsub, 189 kOpMul, 190 kOpDiv, 191 kOpRem, 192 kOpBic, 193 kOpCmn, 194 kOpTst, 195 kOpBkpt, 196 kOpBlx, 197 kOpPush, 198 kOpPop, 199 kOp2Char, 200 kOp2Short, 201 kOp2Byte, 202 kOpCondBr, 203 kOpUncondBr, 204 } OpKind; 205 206 /* 207 * Annotate special-purpose core registers: 208 * - VM: r4PC, r5FP, and r6SELF 209 * - ARM architecture: r13sp, r14lr, and r15pc 210 * 211 * rPC, rFP, and rSELF are for architecture-independent code to use. 212 */ 213 typedef enum NativeRegisterPool { 214 r0 = 0, 215 r1 = 1, 216 r2 = 2, 217 r3 = 3, 218 rPC = 4, 219 r4PC = rPC, 220 rFP = 5, 221 r5FP = rFP, 222 rSELF = 6, 223 r6SELF = rSELF, 224 r7 = 7, 225 r8 = 8, 226 r9 = 9, 227 r10 = 10, 228 r11 = 11, 229 r12 = 12, 230 r13sp = 13, 231 r14lr = 14, 232 r15pc = 15, 233 fr0 = 0 + FP_REG_OFFSET, 234 fr1 = 1 + FP_REG_OFFSET, 235 fr2 = 2 + FP_REG_OFFSET, 236 fr3 = 3 + FP_REG_OFFSET, 237 fr4 = 4 + FP_REG_OFFSET, 238 fr5 = 5 + FP_REG_OFFSET, 239 fr6 = 6 + FP_REG_OFFSET, 240 fr7 = 7 + FP_REG_OFFSET, 241 fr8 = 8 + FP_REG_OFFSET, 242 fr9 = 9 + FP_REG_OFFSET, 243 fr10 = 10 + FP_REG_OFFSET, 244 fr11 = 11 + FP_REG_OFFSET, 245 fr12 = 12 + FP_REG_OFFSET, 246 fr13 = 13 + FP_REG_OFFSET, 247 fr14 = 14 + FP_REG_OFFSET, 248 fr15 = 15 + FP_REG_OFFSET, 249 fr16 = 16 + FP_REG_OFFSET, 250 fr17 = 17 + FP_REG_OFFSET, 251 fr18 = 18 + FP_REG_OFFSET, 252 fr19 = 19 + FP_REG_OFFSET, 253 fr20 = 20 + FP_REG_OFFSET, 254 fr21 = 21 + FP_REG_OFFSET, 255 fr22 = 22 + FP_REG_OFFSET, 256 fr23 = 23 + FP_REG_OFFSET, 257 fr24 = 24 + FP_REG_OFFSET, 258 fr25 = 25 + FP_REG_OFFSET, 259 fr26 = 26 + FP_REG_OFFSET, 260 fr27 = 27 + FP_REG_OFFSET, 261 fr28 = 28 + FP_REG_OFFSET, 262 fr29 = 29 + FP_REG_OFFSET, 263 fr30 = 30 + FP_REG_OFFSET, 264 fr31 = 31 + FP_REG_OFFSET, 265 dr0 = fr0 + FP_DOUBLE, 266 dr1 = fr2 + FP_DOUBLE, 267 dr2 = fr4 + FP_DOUBLE, 268 dr3 = fr6 + FP_DOUBLE, 269 dr4 = fr8 + FP_DOUBLE, 270 dr5 = fr10 + FP_DOUBLE, 271 dr6 = fr12 + FP_DOUBLE, 272 dr7 = fr14 + FP_DOUBLE, 273 dr8 = fr16 + FP_DOUBLE, 274 dr9 = fr18 + FP_DOUBLE, 275 dr10 = fr20 + FP_DOUBLE, 276 dr11 = fr22 + FP_DOUBLE, 277 dr12 = fr24 + FP_DOUBLE, 278 dr13 = fr26 + FP_DOUBLE, 279 dr14 = fr28 + FP_DOUBLE, 280 dr15 = fr30 + FP_DOUBLE, 281 } NativeRegisterPool; 282 283 /* Shift encodings */ 284 typedef enum ArmShiftEncodings { 285 kArmLsl = 0x0, 286 kArmLsr = 0x1, 287 kArmAsr = 0x2, 288 kArmRor = 0x3 289 } ArmShiftEncodings; 290 291 /* Thumb condition encodings */ 292 typedef enum ArmConditionCode { 293 kArmCondEq = 0x0, /* 0000 */ 294 kArmCondNe = 0x1, /* 0001 */ 295 kArmCondCs = 0x2, /* 0010 */ 296 kArmCondCc = 0x3, /* 0011 */ 297 kArmCondMi = 0x4, /* 0100 */ 298 kArmCondPl = 0x5, /* 0101 */ 299 kArmCondVs = 0x6, /* 0110 */ 300 kArmCondVc = 0x7, /* 0111 */ 301 kArmCondHi = 0x8, /* 1000 */ 302 kArmCondLs = 0x9, /* 1001 */ 303 kArmCondGe = 0xa, /* 1010 */ 304 kArmCondLt = 0xb, /* 1011 */ 305 kArmCondGt = 0xc, /* 1100 */ 306 kArmCondLe = 0xd, /* 1101 */ 307 kArmCondAl = 0xe, /* 1110 */ 308 kArmCondNv = 0xf, /* 1111 */ 309 } ArmConditionCode; 310 311 #define isPseudoOpcode(opcode) ((int)(opcode) < 0) 312 313 /* 314 * The following enum defines the list of supported Thumb instructions by the 315 * assembler. Their corresponding snippet positions will be defined in 316 * Assemble.c. 317 */ 318 typedef enum ArmOpcode { 319 kArmChainingCellBottom = -18, 320 kArmPseudoBarrier = -17, 321 kArmPseudoExtended = -16, 322 kArmPseudoSSARep = -15, 323 kArmPseudoEntryBlock = -14, 324 kArmPseudoExitBlock = -13, 325 kArmPseudoTargetLabel = -12, 326 kArmPseudoChainingCellBackwardBranch = -11, 327 kArmPseudoChainingCellHot = -10, 328 kArmPseudoChainingCellInvokePredicted = -9, 329 kArmPseudoChainingCellInvokeSingleton = -8, 330 kArmPseudoChainingCellNormal = -7, 331 kArmPseudoDalvikByteCodeBoundary = -6, 332 kArmPseudoPseudoAlign4 = -5, 333 kArmPseudoPCReconstructionCell = -4, 334 kArmPseudoPCReconstructionBlockLabel = -3, 335 kArmPseudoEHBlockLabel = -2, 336 kArmPseudoNormalBlockLabel = -1, 337 /************************************************************************/ 338 kArm16BitData, /* DATA [0] rd[15..0] */ 339 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */ 340 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/ 341 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */ 342 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */ 343 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */ 344 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */ 345 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */ 346 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */ 347 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */ 348 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */ 349 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */ 350 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */ 351 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */ 352 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */ 353 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */ 354 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */ 355 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */ 356 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */ 357 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */ 358 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */ 359 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */ 360 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */ 361 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */ 362 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */ 363 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */ 364 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */ 365 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */ 366 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */ 367 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */ 368 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */ 369 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */ 370 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */ 371 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */ 372 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */ 373 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */ 374 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */ 375 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */ 376 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */ 377 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */ 378 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */ 379 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */ 380 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */ 381 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */ 382 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */ 383 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */ 384 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */ 385 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */ 386 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */ 387 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */ 388 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */ 389 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */ 390 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */ 391 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */ 392 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */ 393 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */ 394 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */ 395 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */ 396 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */ 397 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */ 398 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */ 399 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */ 400 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */ 401 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */ 402 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */ 403 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */ 404 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */ 405 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/ 406 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */ 407 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */ 408 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */ 409 kThumbSwi, /* swi [11011111] imm_8[7..0] */ 410 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */ 411 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12] 412 [1010] imm_8[7..0] */ 413 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12] 414 [1011] imm_8[7..0] */ 415 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16] 416 rd[15-12] [10100000] rm[3..0] */ 417 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16] 418 rd[15-12] [10110000] rm[3..0] */ 419 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12] 420 [1010] imm_8[7..0] */ 421 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12] 422 [1011] imm_8[7..0] */ 423 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16] 424 rd[15-12] [10100040] rm[3..0] */ 425 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16] 426 rd[15-12] [10110040] rm[3..0] */ 427 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16] 428 rd[15-12] [10100000] rm[3..0] */ 429 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16] 430 rd[15-12] [10110000] rm[3..0] */ 431 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16] 432 rd[15-12] [10100000] rm[3..0] */ 433 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16] 434 rd[15-12] [10110000] rm[3..0] */ 435 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12] 436 [10101100] vm[3..0] */ 437 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12] 438 [10111100] vm[3..0] */ 439 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] 440 [10101100] vm[3..0] */ 441 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] 442 [10111100] vm[3..0] */ 443 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12] 444 [10101100] vm[3..0] */ 445 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12] 446 [10111100] vm[3..0] */ 447 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12] 448 [10101100] vm[3..0] */ 449 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12] 450 [10111100] vm[3..0] */ 451 kThumb2MovImmShift, /* mov(T2) rd, #<const> [11110] i [00001001111] 452 imm3 rd[11..8] imm8 */ 453 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0] 454 imm3 rd[11..8] imm8 */ 455 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100] 456 rn[19..16] rt[15..12] imm12[11..0] */ 457 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100] 458 rn[19..16] rt[15..12] imm12[11..0] */ 459 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100] 460 rn[19..16] rt[15..12] [1100] imm[7..0]*/ 461 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101] 462 rn[19..16] rt[15..12] [1100] imm[7..0]*/ 463 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3] 464 rn[2..0] */ 465 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3] 466 rn[2..0] */ 467 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16] 468 [0] imm3[14..12] rd[11..8] imm8[7..0] */ 469 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8] 470 [0000] rm[3..0] */ 471 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000] 472 vd[15..12] 101001] M [0] vm[3..0] */ 473 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000] 474 vd[15..12] 101101] M [0] vm[3..0] */ 475 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */ 476 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */ 477 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8] 478 [0000] rm[3..0] */ 479 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8] 480 [0000] rm[3..0] */ 481 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8] 482 [0000] rm[3..0] */ 483 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111] 484 [0000] rm[3..0] */ 485 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16] 486 [0] imm3[14..12] rd[11..8] imm8[7..0] */ 487 kThumb2MvnImmShift, /* mov(T2) rd, #<const> [11110] i [00011011110] 488 imm3 rd[11..8] imm8 */ 489 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8] 490 rm[3-0] */ 491 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16] 492 [0] imm3[14-12] rd[11-8] w[4-0] */ 493 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16] 494 [0] imm3[14-12] rd[11-8] w[4-0] */ 495 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 496 rt[15-12] [000000] imm[5-4] rm[3-0] */ 497 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 498 rt[15-12] [000000] imm[5-4] rm[3-0] */ 499 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 500 rt[15-12] [000000] imm[5-4] rm[3-0] */ 501 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 502 rt[15-12] [000000] imm[5-4] rm[3-0] */ 503 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 504 rt[15-12] [000000] imm[5-4] rm[3-0] */ 505 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16] 506 rt[15-12] [000000] imm[5-4] rm[3-0] */ 507 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16] 508 rt[15-12] [000000] imm[5-4] rm[3-0] */ 509 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16] 510 rt[15-12] [000000] imm[5-4] rm[3-0] */ 511 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011] 512 rt[15..12] rn[19..16] imm12[11..0] */ 513 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011] 514 rt[15..12] rn[19..16] imm12[11..0] */ 515 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001] 516 rt[15..12] rn[19..16] imm12[11..0] */ 517 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001] 518 rt[15..12] rn[19..16] imm12[11..0] */ 519 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010] 520 rt[15..12] rn[19..16] imm12[11..0] */ 521 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000] 522 rt[15..12] rn[19..16] imm12[11..0] */ 523 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/ 524 kThumb2Push, /* push [1110100100101101] list[15-0]*/ 525 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0] 526 imm3 [1111] imm8[7..0] */ 527 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8] 528 [0000] rm[3..0] */ 529 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8] 530 [0000] rm[3..0] */ 531 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8] 532 [0000] rm[3..0] */ 533 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111] 534 [0000] rm[3..0] */ 535 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8] 536 [0000] rm[3..0] */ 537 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8] 538 [0000] rm[3..0] */ 539 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000] 540 rm[3..0] */ 541 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8] 542 imm8[7..0] */ 543 kThumb2NegRR, /* actually rsub rd, rn, #0 */ 544 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8] 545 [0000] rm[3..0] */ 546 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111] 547 [0000] rm[3..0] */ 548 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8] 549 [0000] rm[3..0] */ 550 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8] 551 [0000] rm[3..0] */ 552 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8] 553 [0000] rm[3..0] */ 554 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8] 555 [0000] rm[3..0] */ 556 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8] 557 [00] rm[3..0] */ 558 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8] 559 [01] rm[3..0] */ 560 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8] 561 [10] rm[3..0] */ 562 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8] 563 [11] rm[3..0] */ 564 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3 565 rd[11..8] imm8 */ 566 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3 567 rd[11..8] imm8 */ 568 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3 569 rd[11..8] imm8 */ 570 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3 571 rd[11..8] imm8 */ 572 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3 573 rd[11..8] imm8 */ 574 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3 575 rd[11..8] imm8 */ 576 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3 577 rd[11..8] imm8 */ 578 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3 579 rd[11..8] imm8 */ 580 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */ 581 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */ 582 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011] 583 E [1] M [0] rm[3-0] */ 584 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011] 585 E [1] M [0] rm[3-0] */ 586 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12] 587 imm12[11-0] */ 588 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10] 589 J1 [0] J2 imm11[10..0] */ 590 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101] 591 M [0] vm[3-0] */ 592 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001] 593 M [0] vm[3-0] */ 594 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010] 595 N [0010000] */ 596 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010] 597 N [0010000] */ 598 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12] 599 [101100] M [1] vm[3-0] */ 600 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12] 601 [101100] M [1] vm[3-0] */ 602 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12] 603 [1011110] M [0] vm[3-0] */ 604 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12] 605 [1010110] M [0] vm[3-0] */ 606 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12] 607 [1011110] M [0] vm[3-0] */ 608 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12] 609 [1010110] M [0] vm[3-0] */ 610 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12] 611 [10100000] imm4l[3-0] */ 612 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12] 613 [10110000] imm4l[3-0] */ 614 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4] 615 [0000] rm[3-0] */ 616 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12] 617 rdhi[11-8] [0000] rm[3-0] */ 618 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111] 619 imm8[7-0] */ 620 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8] 621 imm8[7-0] */ 622 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */ 623 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12] 624 rd[11-8] imm2[7-6] [0] msb[4-0] */ 625 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12] 626 rd[11-8] imm2[7-6] [0] msb[4-0] */ 627 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */ 628 kThumb2LdrPcReln12, /* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12] 629 imm12[11-0] */ 630 kThumbUndefined, /* undefined [11011110xxxxxxxx] */ 631 kArmLast, 632 } ArmOpcode; 633 634 /* DMB option encodings */ 635 typedef enum ArmOpDmbOptions { 636 kSY = 0xf, 637 kST = 0xe, 638 kISH = 0xb, 639 kISHST = 0xa, 640 kNSH = 0x7, 641 kNSHST = 0x6 642 } ArmOpDmbOptions; 643 644 /* Bit flags describing the behavior of each native opcode */ 645 typedef enum ArmOpFeatureFlags { 646 kIsBranch = 0, 647 kRegDef0, 648 kRegDef1, 649 kRegDefSP, 650 kRegDefLR, 651 kRegDefList0, 652 kRegDefList1, 653 kRegUse0, 654 kRegUse1, 655 kRegUse2, 656 kRegUse3, 657 kRegUseSP, 658 kRegUsePC, 659 kRegUseList0, 660 kRegUseList1, 661 kNoOperand, 662 kIsUnaryOp, 663 kIsBinaryOp, 664 kIsTertiaryOp, 665 kIsQuadOp, 666 kIsIT, 667 kSetsCCodes, 668 kUsesCCodes, 669 kMemLoad, 670 kMemStore, 671 } ArmOpFeatureFlags; 672 673 #define IS_LOAD (1 << kMemLoad) 674 #define IS_STORE (1 << kMemStore) 675 #define IS_BRANCH (1 << kIsBranch) 676 #define REG_DEF0 (1 << kRegDef0) 677 #define REG_DEF1 (1 << kRegDef1) 678 #define REG_DEF_SP (1 << kRegDefSP) 679 #define REG_DEF_LR (1 << kRegDefLR) 680 #define REG_DEF_LIST0 (1 << kRegDefList0) 681 #define REG_DEF_LIST1 (1 << kRegDefList1) 682 #define REG_USE0 (1 << kRegUse0) 683 #define REG_USE1 (1 << kRegUse1) 684 #define REG_USE2 (1 << kRegUse2) 685 #define REG_USE3 (1 << kRegUse3) 686 #define REG_USE_SP (1 << kRegUseSP) 687 #define REG_USE_PC (1 << kRegUsePC) 688 #define REG_USE_LIST0 (1 << kRegUseList0) 689 #define REG_USE_LIST1 (1 << kRegUseList1) 690 #define NO_OPERAND (1 << kNoOperand) 691 #define IS_UNARY_OP (1 << kIsUnaryOp) 692 #define IS_BINARY_OP (1 << kIsBinaryOp) 693 #define IS_TERTIARY_OP (1 << kIsTertiaryOp) 694 #define IS_QUAD_OP (1 << kIsQuadOp) 695 #define IS_IT (1 << kIsIT) 696 #define SETS_CCODES (1 << kSetsCCodes) 697 #define USES_CCODES (1 << kUsesCCodes) 698 699 /* Common combo register usage patterns */ 700 #define REG_USE01 (REG_USE0 | REG_USE1) 701 #define REG_USE012 (REG_USE01 | REG_USE2) 702 #define REG_USE12 (REG_USE1 | REG_USE2) 703 #define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) 704 #define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) 705 #define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) 706 #define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) 707 #define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) 708 709 /* Instruction assembly fieldLoc kind */ 710 typedef enum ArmEncodingKind { 711 kFmtUnused, 712 kFmtBitBlt, /* Bit string using end/start */ 713 kFmtDfp, /* Double FP reg */ 714 kFmtSfp, /* Single FP reg */ 715 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */ 716 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */ 717 kFmtImm6, /* Encoded branch target using [9,7..3]0 */ 718 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */ 719 kFmtShift, /* Shift descriptor, [14..12,7..4] */ 720 kFmtLsb, /* least significant bit using [14..12][7..6] */ 721 kFmtBWidth, /* bit-field width, encoded as width-1 */ 722 kFmtShift5, /* Shift count, [14..12,7..6] */ 723 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */ 724 kFmtFPImm, /* Encoded floating point immediate */ 725 } ArmEncodingKind; 726 727 /* Struct used to define the snippet positions for each Thumb opcode */ 728 typedef struct ArmEncodingMap { 729 u4 skeleton; 730 struct { 731 ArmEncodingKind kind; 732 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */ 733 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */ 734 } fieldLoc[4]; 735 ArmOpcode opcode; 736 int flags; 737 const char* name; 738 const char* fmt; 739 int size; 740 } ArmEncodingMap; 741 742 /* Keys for target-specific scheduling and other optimization hints */ 743 typedef enum ArmTargetOptHints { 744 kMaxHoistDistance, 745 } ArmTargetOptHints; 746 747 extern ArmEncodingMap EncodingMap[kArmLast]; 748 749 /* 750 * Each instance of this struct holds a pseudo or real LIR instruction: 751 * - pseudo ones (eg labels and marks) and will be discarded by the assembler. 752 * - real ones will be assembled into Thumb instructions. 753 * 754 * Machine resources are encoded into a 64-bit vector, where the encodings are 755 * as following: 756 * - [ 0..15]: general purpose registers including PC, SP, and LR 757 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0 758 * starts at bit 16 759 * - [48]: IT block 760 * - [49]: integer condition code 761 * - [50]: floatint-point status word 762 */ 763 typedef struct ArmLIR { 764 LIR generic; 765 ArmOpcode opcode; 766 int operands[4]; // [0..3] = [dest, src1, src2, extra] 767 struct { 768 bool isNop:1; // LIR is optimized away 769 bool insertWrapper:1; // insert branch to emulate memory accesses 770 unsigned int age:4; // default is 0, set lazily by the optimizer 771 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2) 772 unsigned int unused:23; 773 } flags; 774 int aliasInfo; // For Dalvik register & litpool disambiguation 775 u8 useMask; // Resource mask for use 776 u8 defMask; // Resource mask for def 777 } ArmLIR; 778 779 /* Init values when a predicted chain is initially assembled */ 780 /* E7FE is branch to self */ 781 #define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe 782 783 /* Utility macros to traverse the LIR/ArmLIR list */ 784 #define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next) 785 #define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev) 786 787 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next 788 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev 789 790 #define CHAIN_CELL_OFFSET_TAG 0xcdab 791 792 #define CHAIN_CELL_NORMAL_SIZE 12 793 #define CHAIN_CELL_PREDICTED_SIZE 16 794 795 #endif // DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H_ 796