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