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