ArmLIR.h revision d7d426a1d746f70edeaeccf77886f3ad8298e28c
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/* Mask to strip off fp flags */ 75#define FP_REG_MASK (FP_REG_OFFSET-1) 76/* non-existent Dalvik register */ 77#define vNone (-1) 78/* non-existant physical register */ 79#define rNone (-1) 80 81typedef enum ResourceEncodingPos { 82 kGPReg0 = 0, 83 kRegSP = 13, 84 kRegLR = 14, 85 kRegPC = 15, 86 kFPReg0 = 16, 87 kRegEnd = 48, 88 kCCode = kRegEnd, 89 kFPStatus, 90 kDalvikReg, 91} ResourceEncodingPos; 92 93#define ENCODE_REG_LIST(N) ((u8) N) 94#define ENCODE_REG_SP (1ULL << kRegSP) 95#define ENCODE_REG_LR (1ULL << kRegLR) 96#define ENCODE_REG_PC (1ULL << kRegPC) 97#define ENCODE_CCODE (1ULL << kCCode) 98#define ENCODE_FP_STATUS (1ULL << kFPStatus) 99#define ENCODE_DALVIK_REG (1ULL << kDalvikReg) 100#define ENCODE_ALL (~0ULL) 101 102#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) 103#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) 104 105typedef enum OpSize { 106 WORD, 107 LONG, 108 SINGLE, 109 DOUBLE, 110 UNSIGNED_HALF, 111 SIGNED_HALF, 112 UNSIGNED_BYTE, 113 SIGNED_BYTE, 114} OpSize; 115 116typedef enum OpKind { 117 OP_MOV, 118 OP_MVN, 119 OP_CMP, 120 OP_LSL, 121 OP_LSR, 122 OP_ASR, 123 OP_ROR, 124 OP_NOT, 125 OP_AND, 126 OP_OR, 127 OP_XOR, 128 OP_NEG, 129 OP_ADD, 130 OP_ADC, 131 OP_SUB, 132 OP_SBC, 133 OP_RSUB, 134 OP_MUL, 135 OP_DIV, 136 OP_REM, 137 OP_BIC, 138 OP_CMN, 139 OP_TST, 140 OP_BKPT, 141 OP_BLX, 142 OP_PUSH, 143 OP_POP, 144 OP_2CHAR, 145 OP_2SHORT, 146 OP_2BYTE, 147 OP_COND_BR, 148 OP_UNCOND_BR, 149} OpKind; 150 151typedef enum NativeRegisterPool { 152 r0 = 0, 153 r1 = 1, 154 r2 = 2, 155 r3 = 3, 156 r4PC = 4, 157 rFP = 5, 158 rGLUE = 6, 159 r7 = 7, 160 r8 = 8, 161 r9 = 9, 162 r10 = 10, 163 r11 = 11, 164 r12 = 12, 165 r13 = 13, 166 rlr = 14, 167 rpc = 15, 168 fr0 = 0 + FP_REG_OFFSET, 169 fr1 = 1 + FP_REG_OFFSET, 170 fr2 = 2 + FP_REG_OFFSET, 171 fr3 = 3 + FP_REG_OFFSET, 172 fr4 = 4 + FP_REG_OFFSET, 173 fr5 = 5 + FP_REG_OFFSET, 174 fr6 = 6 + FP_REG_OFFSET, 175 fr7 = 7 + FP_REG_OFFSET, 176 fr8 = 8 + FP_REG_OFFSET, 177 fr9 = 9 + FP_REG_OFFSET, 178 fr10 = 10 + FP_REG_OFFSET, 179 fr11 = 11 + FP_REG_OFFSET, 180 fr12 = 12 + FP_REG_OFFSET, 181 fr13 = 13 + FP_REG_OFFSET, 182 fr14 = 14 + FP_REG_OFFSET, 183 fr15 = 15 + FP_REG_OFFSET, 184 fr16 = 16 + FP_REG_OFFSET, 185 fr17 = 17 + FP_REG_OFFSET, 186 fr18 = 18 + FP_REG_OFFSET, 187 fr19 = 19 + FP_REG_OFFSET, 188 fr20 = 20 + FP_REG_OFFSET, 189 fr21 = 21 + FP_REG_OFFSET, 190 fr22 = 22 + FP_REG_OFFSET, 191 fr23 = 23 + FP_REG_OFFSET, 192 fr24 = 24 + FP_REG_OFFSET, 193 fr25 = 25 + FP_REG_OFFSET, 194 fr26 = 26 + FP_REG_OFFSET, 195 fr27 = 27 + FP_REG_OFFSET, 196 fr28 = 28 + FP_REG_OFFSET, 197 fr29 = 29 + FP_REG_OFFSET, 198 fr30 = 30 + FP_REG_OFFSET, 199 fr31 = 31 + FP_REG_OFFSET, 200 dr0 = fr0 + FP_DOUBLE, 201 dr1 = fr2 + FP_DOUBLE, 202 dr2 = fr4 + FP_DOUBLE, 203 dr3 = fr6 + FP_DOUBLE, 204 dr4 = fr8 + FP_DOUBLE, 205 dr5 = fr10 + FP_DOUBLE, 206 dr6 = fr12 + FP_DOUBLE, 207 dr7 = fr14 + FP_DOUBLE, 208 dr8 = fr16 + FP_DOUBLE, 209 dr9 = fr18 + FP_DOUBLE, 210 dr10 = fr20 + FP_DOUBLE, 211 dr11 = fr22 + FP_DOUBLE, 212 dr12 = fr24 + FP_DOUBLE, 213 dr13 = fr26 + FP_DOUBLE, 214 dr14 = fr28 + FP_DOUBLE, 215 dr15 = fr30 + FP_DOUBLE, 216} NativeRegisterPool; 217 218/* Thumb condition encodings */ 219typedef enum ArmConditionCode { 220 ARM_COND_EQ = 0x0, /* 0000 */ 221 ARM_COND_NE = 0x1, /* 0001 */ 222 ARM_COND_CS = 0x2, /* 0010 */ 223 ARM_COND_CC = 0x3, /* 0011 */ 224 ARM_COND_MI = 0x4, /* 0100 */ 225 ARM_COND_PL = 0x5, /* 0101 */ 226 ARM_COND_VS = 0x6, /* 0110 */ 227 ARM_COND_VC = 0x7, /* 0111 */ 228 ARM_COND_HI = 0x8, /* 1000 */ 229 ARM_COND_LS = 0x9, /* 1001 */ 230 ARM_COND_GE = 0xa, /* 1010 */ 231 ARM_COND_LT = 0xb, /* 1011 */ 232 ARM_COND_GT = 0xc, /* 1100 */ 233 ARM_COND_LE = 0xd, /* 1101 */ 234 ARM_COND_AL = 0xe, /* 1110 */ 235 ARM_COND_NV = 0xf, /* 1111 */ 236} ArmConditionCode; 237 238#define isPseudoOpCode(opCode) ((int)(opCode) < 0) 239 240/* 241 * The following enum defines the list of supported Thumb instructions by the 242 * assembler. Their corresponding snippet positions will be defined in 243 * Assemble.c. 244 */ 245typedef enum ArmOpCode { 246 ARM_PSEUDO_BARRIER = -17, 247 ARM_PSEUDO_EXTENDED_MIR = -16, 248 ARM_PSEUDO_SSA_REP = -15, 249 ARM_PSEUDO_ENTRY_BLOCK = -14, 250 ARM_PSEUDO_EXIT_BLOCK = -13, 251 ARM_PSEUDO_TARGET_LABEL = -12, 252 ARM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -11, 253 ARM_PSEUDO_CHAINING_CELL_HOT = -10, 254 ARM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9, 255 ARM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8, 256 ARM_PSEUDO_CHAINING_CELL_NORMAL = -7, 257 ARM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6, 258 ARM_PSEUDO_ALIGN4 = -5, 259 ARM_PSEUDO_PC_RECONSTRUCTION_CELL = -4, 260 ARM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3, 261 ARM_PSEUDO_EH_BLOCK_LABEL = -2, 262 ARM_PSEUDO_NORMAL_BLOCK_LABEL = -1, 263 /************************************************************************/ 264 ARM_16BIT_DATA, /* DATA [0] rd[15..0] */ 265 THUMB_ADC_RR, /* adc [0100000101] rm[5..3] rd[2..0] */ 266 THUMB_ADD_RRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/ 267 THUMB_ADD_RI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */ 268 THUMB_ADD_RRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */ 269 THUMB_ADD_RR_LH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */ 270 THUMB_ADD_RR_HL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */ 271 THUMB_ADD_RR_HH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */ 272 THUMB_ADD_PC_REL, /* add(5) [10100] rd[10..8] imm_8[7..0] */ 273 THUMB_ADD_SP_REL, /* add(6) [10101] rd[10..8] imm_8[7..0] */ 274 THUMB_ADD_SPI7, /* add(7) [101100000] imm_7[6..0] */ 275 THUMB_AND_RR, /* and [0100000000] rm[5..3] rd[2..0] */ 276 THUMB_ASR_RRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */ 277 THUMB_ASR_RR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */ 278 THUMB_B_COND, /* b(1) [1101] cond[11..8] offset_8[7..0] */ 279 THUMB_B_UNCOND, /* b(2) [11100] offset_11[10..0] */ 280 THUMB_BIC_RR, /* bic [0100001110] rm[5..3] rd[2..0] */ 281 THUMB_BKPT, /* bkpt [10111110] imm_8[7..0] */ 282 THUMB_BLX_1, /* blx(1) [111] H[10] offset_11[10..0] */ 283 THUMB_BLX_2, /* blx(1) [111] H[01] offset_11[10..0] */ 284 THUMB_BL_1, /* blx(1) [111] H[10] offset_11[10..0] */ 285 THUMB_BL_2, /* blx(1) [111] H[11] offset_11[10..0] */ 286 THUMB_BLX_R, /* blx(2) [010001111] rm[6..3] [000] */ 287 THUMB_BX, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */ 288 THUMB_CMN_RR, /* cmn [0100001011] rm[5..3] rd[2..0] */ 289 THUMB_CMP_RI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */ 290 THUMB_CMP_RR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */ 291 THUMB_CMP_LH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */ 292 THUMB_CMP_HL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */ 293 THUMB_CMP_HH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */ 294 THUMB_EOR_RR, /* eor [0100000001] rm[5..3] rd[2..0] */ 295 THUMB_LDMIA, /* ldmia [11001] rn[10..8] reglist [7..0] */ 296 THUMB_LDR_RRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */ 297 THUMB_LDR_RRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */ 298 THUMB_LDR_PC_REL, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */ 299 THUMB_LDR_SP_REL, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */ 300 THUMB_LDRB_RRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */ 301 THUMB_LDRB_RRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */ 302 THUMB_LDRH_RRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */ 303 THUMB_LDRH_RRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */ 304 THUMB_LDRSB_RRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */ 305 THUMB_LDRSH_RRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */ 306 THUMB_LSL_RRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */ 307 THUMB_LSL_RR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */ 308 THUMB_LSR_RRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */ 309 THUMB_LSR_RR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */ 310 THUMB_MOV_IMM, /* mov(1) [00100] rd[10..8] imm_8[7..0] */ 311 THUMB_MOV_RR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */ 312 THUMB_MOV_RR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */ 313 THUMB_MOV_RR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */ 314 THUMB_MOV_RR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */ 315 THUMB_MUL, /* mul [0100001101] rm[5..3] rd[2..0] */ 316 THUMB_MVN, /* mvn [0100001111] rm[5..3] rd[2..0] */ 317 THUMB_NEG, /* neg [0100001001] rm[5..3] rd[2..0] */ 318 THUMB_ORR, /* orr [0100001100] rm[5..3] rd[2..0] */ 319 THUMB_POP, /* pop [1011110] r[8..8] rl[7..0] */ 320 THUMB_PUSH, /* push [1011010] r[8..8] rl[7..0] */ 321 THUMB_ROR_RR, /* ror [0100000111] rs[5..3] rd[2..0] */ 322 THUMB_SBC, /* sbc [0100000110] rm[5..3] rd[2..0] */ 323 THUMB_STMIA, /* stmia [11000] rn[10..8] reglist [7.. 0] */ 324 THUMB_STR_RRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */ 325 THUMB_STR_RRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */ 326 THUMB_STR_SP_REL, /* str(3) [10010] rd[10..8] imm_8[7..0] */ 327 THUMB_STRB_RRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */ 328 THUMB_STRB_RRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */ 329 THUMB_STRH_RRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */ 330 THUMB_STRH_RRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */ 331 THUMB_SUB_RRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/ 332 THUMB_SUB_RI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */ 333 THUMB_SUB_RRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */ 334 THUMB_SUB_SPI7, /* sub(4) [101100001] imm_7[6..0] */ 335 THUMB_SWI, /* swi [11011111] imm_8[7..0] */ 336 THUMB_TST, /* tst [0100001000] rm[5..3] rn[2..0] */ 337 THUMB2_VLDRS, /* vldr low sx [111011011001] rn[19..16] rd[15-12] 338 [1010] imm_8[7..0] */ 339 THUMB2_VLDRD, /* vldr low dx [111011011001] rn[19..16] rd[15-12] 340 [1011] imm_8[7..0] */ 341 THUMB2_VMULS, /* vmul vd, vn, vm [111011100010] rn[19..16] 342 rd[15-12] [10100000] rm[3..0] */ 343 THUMB2_VMULD, /* vmul vd, vn, vm [111011100010] rn[19..16] 344 rd[15-12] [10110000] rm[3..0] */ 345 THUMB2_VSTRS, /* vstr low sx [111011011000] rn[19..16] rd[15-12] 346 [1010] imm_8[7..0] */ 347 THUMB2_VSTRD, /* vstr low dx [111011011000] rn[19..16] rd[15-12] 348 [1011] imm_8[7..0] */ 349 THUMB2_VSUBS, /* vsub vd, vn, vm [111011100011] rn[19..16] 350 rd[15-12] [10100040] rm[3..0] */ 351 THUMB2_VSUBD, /* vsub vd, vn, vm [111011100011] rn[19..16] 352 rd[15-12] [10110040] rm[3..0] */ 353 THUMB2_VADDS, /* vadd vd, vn, vm [111011100011] rn[19..16] 354 rd[15-12] [10100000] rm[3..0] */ 355 THUMB2_VADDD, /* vadd vd, vn, vm [111011100011] rn[19..16] 356 rd[15-12] [10110000] rm[3..0] */ 357 THUMB2_VDIVS, /* vdiv vd, vn, vm [111011101000] rn[19..16] 358 rd[15-12] [10100000] rm[3..0] */ 359 THUMB2_VDIVD, /* vdiv vd, vn, vm [111011101000] rn[19..16] 360 rd[15-12] [10110000] rm[3..0] */ 361 THUMB2_VCVTIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12] 362 [10101100] vm[3..0] */ 363 THUMB2_VCVTID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12] 364 [10111100] vm[3..0] */ 365 THUMB2_VCVTFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] 366 [10101100] vm[3..0] */ 367 THUMB2_VCVTDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12] 368 [10111100] vm[3..0] */ 369 THUMB2_VCVTFD, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12] 370 [10101100] vm[3..0] */ 371 THUMB2_VCVTDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12] 372 [10111100] vm[3..0] */ 373 THUMB2_VSQRTS, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12] 374 [10101100] vm[3..0] */ 375 THUMB2_VSQRTD, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12] 376 [10111100] vm[3..0] */ 377 THUMB2_MOV_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00001001111] 378 imm3 rd[11..8] imm8 */ 379 THUMB2_MOV_IMM16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0] 380 imm3 rd[11..8] imm8 */ 381 THUMB2_STR_RRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100] 382 rn[19..16] rt[15..12] imm12[11..0] */ 383 THUMB2_LDR_RRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100] 384 rn[19..16] rt[15..12] imm12[11..0] */ 385 THUMB2_STR_RRI8_PREDEC, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100] 386 rn[19..16] rt[15..12] [1100] imm[7..0]*/ 387 THUMB2_LDR_RRI8_PREDEC, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101] 388 rn[19..16] rt[15..12] [1100] imm[7..0]*/ 389 THUMB2_CBNZ, /* cbnz rd,<label> [101110] i [1] imm5[7..3] 390 rn[2..0] */ 391 THUMB2_CBZ, /* cbn rd,<label> [101100] i [1] imm5[7..3] 392 rn[2..0] */ 393 THUMB2_ADD_RRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16] 394 [0] imm3[14..12] rd[11..8] imm8[7..0] */ 395 THUMB2_MOV_RR, /* mov rd, rm [11101010010011110000] rd[11..8] 396 [0000] rm[3..0] */ 397 THUMB2_VMOVS, /* vmov.f32 vd, vm [111011101] D [110000] 398 vd[15..12] 101001] M [0] vm[3..0] */ 399 THUMB2_VMOVD, /* vmov.f64 vd, vm [111011101] D [110000] 400 vd[15..12] 101101] M [0] vm[3..0] */ 401 THUMB2_LDMIA, /* ldmia [111010001001[ rn[19..16] mask[15..0] */ 402 THUMB2_STMIA, /* stmia [111010001000[ rn[19..16] mask[15..0] */ 403 THUMB2_ADD_RRR, /* add [111010110000] rn[19..16] [0000] rd[11..8] 404 [0000] rm[3..0] */ 405 THUMB2_SUB_RRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8] 406 [0000] rm[3..0] */ 407 THUMB2_SBC_RRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8] 408 [0000] rm[3..0] */ 409 THUMB2_CMP_RR, /* cmp [111010111011] rn[19..16] [0000] [1111] 410 [0000] rm[3..0] */ 411 THUMB2_SUB_RRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16] 412 [0] imm3[14..12] rd[11..8] imm8[7..0] */ 413 THUMB2_MVN_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00011011110] 414 imm3 rd[11..8] imm8 */ 415 THUMB2_SEL, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8] 416 rm[3-0] */ 417 THUMB2_UBFX, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16] 418 [0] imm3[14-12] rd[11-8] w[4-0] */ 419 THUMB2_SBFX, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16] 420 [0] imm3[14-12] rd[11-8] w[4-0] */ 421 THUMB2_LDR_RRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 422 rt[15-12] [000000] imm[5-4] rm[3-0] */ 423 THUMB2_LDRH_RRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 424 rt[15-12] [000000] imm[5-4] rm[3-0] */ 425 THUMB2_LDRSH_RRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 426 rt[15-12] [000000] imm[5-4] rm[3-0] */ 427 THUMB2_LDRB_RRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 428 rt[15-12] [000000] imm[5-4] rm[3-0] */ 429 THUMB2_LDRSB_RRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16] 430 rt[15-12] [000000] imm[5-4] rm[3-0] */ 431 THUMB2_STR_RRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16] 432 rt[15-12] [000000] imm[5-4] rm[3-0] */ 433 THUMB2_STRH_RRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16] 434 rt[15-12] [000000] imm[5-4] rm[3-0] */ 435 THUMB2_STRB_RRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16] 436 rt[15-12] [000000] imm[5-4] rm[3-0] */ 437 THUMB2_LDRH_RRI12, /* ldrh rt,[rn,#imm12] [111110001011] 438 rt[15..12] rn[19..16] imm12[11..0] */ 439 THUMB2_LDRSH_RRI12, /* ldrsh rt,[rn,#imm12] [111110011011] 440 rt[15..12] rn[19..16] imm12[11..0] */ 441 THUMB2_LDRB_RRI12, /* ldrb rt,[rn,#imm12] [111110001001] 442 rt[15..12] rn[19..16] imm12[11..0] */ 443 THUMB2_LDRSB_RRI12, /* ldrsb rt,[rn,#imm12] [111110011001] 444 rt[15..12] rn[19..16] imm12[11..0] */ 445 THUMB2_STRH_RRI12, /* strh rt,[rn,#imm12] [111110001010] 446 rt[15..12] rn[19..16] imm12[11..0] */ 447 THUMB2_STRB_RRI12, /* strb rt,[rn,#imm12] [111110001000] 448 rt[15..12] rn[19..16] imm12[11..0] */ 449 THUMB2_POP, /* pop [1110100010111101] list[15-0]*/ 450 THUMB2_PUSH, /* push [1110100010101101] list[15-0]*/ 451 THUMB2_CMP_RI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0] 452 imm3 [1111] imm8[7..0] */ 453 THUMB2_ADC_RRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8] 454 [0000] rm[3..0] */ 455 THUMB2_AND_RRR, /* and [111010100000] rn[19..16] [0000] rd[11..8] 456 [0000] rm[3..0] */ 457 THUMB2_BIC_RRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8] 458 [0000] rm[3..0] */ 459 THUMB2_CMN_RR, /* cmn [111010110001] rn[19..16] [0000] [1111] 460 [0000] rm[3..0] */ 461 THUMB2_EOR_RRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8] 462 [0000] rm[3..0] */ 463 THUMB2_MUL_RRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8] 464 [0000] rm[3..0] */ 465 THUMB2_MVN_RR, /* mvn [11101010011011110] rd[11-8] [0000] 466 rm[3..0] */ 467 THUMB2_RSUB_RRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8] 468 imm8[7..0] */ 469 THUMB2_NEG_RR, /* actually rsub rd, rn, #0 */ 470 THUMB2_ORR_RRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8] 471 [0000] rm[3..0] */ 472 THUMB2_TST_RR, /* tst [111010100001] rn[19..16] [0000] [1111] 473 [0000] rm[3..0] */ 474 THUMB2_LSL_RRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8] 475 [0000] rm[3..0] */ 476 THUMB2_LSR_RRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8] 477 [0000] rm[3..0] */ 478 THUMB2_ASR_RRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8] 479 [0000] rm[3..0] */ 480 THUMB2_ROR_RRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8] 481 [0000] rm[3..0] */ 482 THUMB2_LSL_RRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8] 483 [00] rm[3..0] */ 484 THUMB2_LSR_RRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8] 485 [01] rm[3..0] */ 486 THUMB2_ASR_RRI5, /* asr [11101010010011110] imm[14.12] rd[11..8] 487 [10] rm[3..0] */ 488 THUMB2_ROR_RRI5, /* ror [11101010010011110] imm[14.12] rd[11..8] 489 [11] rm[3..0] */ 490 THUMB2_BIC_RRI8, /* bic [111100000010] rn[19..16] [0] imm3 491 rd[11..8] imm8 */ 492 THUMB2_AND_RRI8, /* bic [111100000000] rn[19..16] [0] imm3 493 rd[11..8] imm8 */ 494 THUMB2_ORR_RRI8, /* orr [111100000100] rn[19..16] [0] imm3 495 rd[11..8] imm8 */ 496 THUMB2_EOR_RRI8, /* eor [111100001000] rn[19..16] [0] imm3 497 rd[11..8] imm8 */ 498 THUMB2_ADD_RRI8, /* add [111100001000] rn[19..16] [0] imm3 499 rd[11..8] imm8 */ 500 THUMB2_ADC_RRI8, /* adc [111100010101] rn[19..16] [0] imm3 501 rd[11..8] imm8 */ 502 THUMB2_SUB_RRI8, /* sub [111100011011] rn[19..16] [0] imm3 503 rd[11..8] imm8 */ 504 THUMB2_SBC_RRI8, /* sbc [111100010111] rn[19..16] [0] imm3 505 rd[11..8] imm8 */ 506 THUMB2_IT, /* it [10111111] firstcond[7-4] mask[3-0] */ 507 THUMB2_FMSTAT, /* fmstat [11101110111100011111101000010000] */ 508 THUMB2_VCMPD, /* vcmp [111011101] D [11011] rd[15-12] [1011] 509 E [1] M [0] rm[3-0] */ 510 THUMB2_VCMPS, /* vcmp [111011101] D [11010] rd[15-12] [1011] 511 E [1] M [0] rm[3-0] */ 512 THUMB2_LDR_PC_REL12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12] 513 imm12[11-0] */ 514 THUMB2_B_COND, /* b<c> [1110] S cond[25-22] imm6[21-16] [10] 515 J1 [0] J2 imm11[10..0] */ 516 THUMB2_VMOVD_RR, /* vmov [111011101] D [110000] vd[15-12 [101101] 517 M [0] vm[3-0] */ 518 THUMB2_VMOVS_RR, /* vmov [111011101] D [110000] vd[15-12 [101001] 519 M [0] vm[3-0] */ 520 THUMB2_FMRS, /* vmov [111011100000] vn[19-16] rt[15-12] [1010] 521 N [0010000] */ 522 THUMB2_FMSR, /* vmov [111011100001] vn[19-16] rt[15-12] [1010] 523 N [0010000] */ 524 THUMB2_FMRRD, /* vmov [111011000100] rt2[19-16] rt[15-12] 525 [101100] M [1] vm[3-0] */ 526 THUMB2_FMDRR, /* vmov [111011000101] rt2[19-16] rt[15-12] 527 [101100] M [1] vm[3-0] */ 528 529 ARM_LAST, 530} ArmOpCode; 531 532/* Bit flags describing the behavior of each native opcode */ 533typedef enum ArmOpFeatureFlags { 534 kIsBranch = 0, 535 kRegDef0, 536 kRegDef1, 537 kRegDefSP, 538 kRegDefLR, 539 kRegDefList0, 540 kRegDefList1, 541 kRegUse0, 542 kRegUse1, 543 kRegUse2, 544 kRegUseSP, 545 kRegUsePC, 546 kRegUseList0, 547 kRegUseList1, 548 kNoOperand, 549 kIsUnaryOp, 550 kIsBinaryOp, 551 kIsTertiaryOp, 552 kIsQuadOp, 553 kIsIT, 554 kSetsCCodes, 555 kUsesCCodes, 556} ArmOpFeatureFlags; 557 558#define IS_BRANCH (1 << kIsBranch) 559#define REG_DEF0 (1 << kRegDef0) 560#define REG_DEF1 (1 << kRegDef1) 561#define REG_DEF_SP (1 << kRegDefSP) 562#define REG_DEF_LR (1 << kRegDefLR) 563#define REG_DEF_LIST0 (1 << kRegDefList0) 564#define REG_DEF_LIST1 (1 << kRegDefList1) 565#define REG_USE0 (1 << kRegUse0) 566#define REG_USE1 (1 << kRegUse1) 567#define REG_USE2 (1 << kRegUse2) 568#define REG_USE_SP (1 << kRegUseSP) 569#define REG_USE_PC (1 << kRegUsePC) 570#define REG_USE_LIST0 (1 << kRegUseList0) 571#define REG_USE_LIST1 (1 << kRegUseList1) 572#define NO_OPERAND (1 << kNoOperand) 573#define IS_UNARY_OP (1 << kIsUnaryOp) 574#define IS_BINARY_OP (1 << kIsBinaryOp) 575#define IS_TERTIARY_OP (1 << kIsTertiaryOp) 576#define IS_QUAD_OP (1 << kIsQuadOp) 577#define IS_IT (1 << kIsIT) 578#define SETS_CCODES (1 << kSetsCCodes) 579#define USES_CCODES (1 << kUsesCCodes) 580 581/* Common combo register usage patterns */ 582#define REG_USE01 (REG_USE0 | REG_USE1) 583#define REG_USE012 (REG_USE01 | REG_USE2) 584#define REG_USE12 (REG_USE1 | REG_USE2) 585#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0) 586#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1) 587#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01) 588#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12) 589#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2) 590 591/* Instruction assembly fieldLoc kind */ 592typedef enum ArmEncodingKind { 593 UNUSED, 594 BITBLT, /* Bit string using end/start */ 595 DFP, /* Double FP reg */ 596 SFP, /* Single FP reg */ 597 MODIMM, /* Shifted 8-bit immediate using [26,14..12,7..0] */ 598 IMM16, /* Zero-extended immediate using [26,19..16,14..12,7..0] */ 599 IMM6, /* Encoded branch target using [9,7..3]0 */ 600 IMM12, /* Zero-extended immediate using [26,14..12,7..0] */ 601 SHIFT, /* Shift descriptor, [14..12,7..4] */ 602 LSB, /* least significant bit using [14..12][7..6] */ 603 BWIDTH, /* bit-field width, encoded as width-1 */ 604 SHIFT5, /* Shift count, [14..12,7..6] */ 605 BROFFSET, /* Signed extended [26,11,13,21-16,10-0]:0 */ 606} ArmEncodingKind; 607 608/* Struct used to define the snippet positions for each Thumb opcode */ 609typedef struct ArmEncodingMap { 610 u4 skeleton; 611 struct { 612 ArmEncodingKind kind; 613 int end; /* end for BITBLT, 1-bit slice end for FP regs */ 614 int start; /* start for BITBLT, 4-bit slice end for FP regs */ 615 } fieldLoc[4]; 616 ArmOpCode opCode; 617 int flags; 618 char *name; 619 char* fmt; 620 int size; 621} ArmEncodingMap; 622 623extern ArmEncodingMap EncodingMap[ARM_LAST]; 624 625/* 626 * Each instance of this struct holds a pseudo or real LIR instruction: 627 * - pesudo ones (eg labels and marks) and will be discarded by the assembler. 628 * - real ones will be assembled into Thumb instructions. 629 * 630 * Machine resources are encoded into a 64-bit vector, where the encodings are 631 * as following: 632 * - [ 0..15]: general purpose registers including PC, SP, and LR 633 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0 634 * starts at bit 16 635 * - [48]: IT block 636 * - [49]: integer condition code 637 * - [50]: floatint-point status word 638 */ 639typedef struct ArmLIR { 640 LIR generic; 641 ArmOpCode opCode; 642 int operands[4]; // [0..3] = [dest, src1, src2, extra] 643 bool isNop; // LIR is optimized away 644 int age; // default is 0, set lazily by the optimizer 645 int size; // 16-bit unit size (1 for thumb, 1 or 2 for thumb2) 646 int aliasInfo; // For Dalvik register access disambiguation 647 u8 useMask; // Resource mask for use 648 u8 defMask; // Resource mask for def 649} ArmLIR; 650 651/* Chain cell for predicted method invocation */ 652typedef struct PredictedChainingCell { 653 u4 branch; /* Branch to chained destination */ 654 const ClassObject *clazz; /* key #1 for prediction */ 655 const Method *method; /* key #2 to lookup native PC from dalvik PC */ 656 u4 counter; /* counter to patch the chaining cell */ 657} PredictedChainingCell; 658 659/* Init values when a predicted chain is initially assembled */ 660#define PREDICTED_CHAIN_BX_PAIR_INIT 0 661#define PREDICTED_CHAIN_CLAZZ_INIT 0 662#define PREDICTED_CHAIN_METHOD_INIT 0 663#define PREDICTED_CHAIN_COUNTER_INIT 0 664 665/* Used when the callee is not compiled yet */ 666#define PREDICTED_CHAIN_COUNTER_DELAY 16 667 668/* Rechain after this many mis-predictions have happened */ 669#define PREDICTED_CHAIN_COUNTER_RECHAIN 1024 670 671/* Used if the resolved callee is a native method */ 672#define PREDICTED_CHAIN_COUNTER_AVOID 0x7fffffff 673 674/* Utility macros to traverse the LIR/ArmLIR list */ 675#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next) 676#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev) 677 678#define NEXT_LIR_LVALUE(lir) (lir)->generic.next 679#define PREV_LIR_LVALUE(lir) (lir)->generic.prev 680 681#define CHAIN_CELL_OFFSET_TAG 0xcdab 682 683ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc); 684 685#endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */ 686