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