ArmLIR.h revision 270c1d64a192341be842f46734054c692bac061e
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_LT = 0xb,    /* 1011 */
200    ARM_COND_GE = 0xa,    /* 1010 */
201    ARM_COND_GT = 0xc,    /* 1100 */
202    ARM_COND_LE = 0xd,    /* 1101 */
203    ARM_COND_CS = 0x2,    /* 0010 */
204    ARM_COND_MI = 0x4,    /* 0100 */
205} ArmConditionCode;
206
207#define isPseudoOpCode(opCode) ((int)(opCode) < 0)
208
209/*
210 * The following enum defines the list of supported Thumb instructions by the
211 * assembler. Their corresponding snippet positions will be defined in
212 * Assemble.c.
213 */
214typedef enum ArmOpCode {
215    ARM_PSEUDO_TARGET_LABEL = -12,
216    ARM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -11,
217    ARM_PSEUDO_CHAINING_CELL_HOT = -10,
218    ARM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
219    ARM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
220    ARM_PSEUDO_CHAINING_CELL_NORMAL = -7,
221    ARM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
222    ARM_PSEUDO_ALIGN4 = -5,
223    ARM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
224    ARM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
225    ARM_PSEUDO_EH_BLOCK_LABEL = -2,
226    ARM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
227    /************************************************************************/
228    ARM_16BIT_DATA,       /* DATA   [0] rd[15..0] */
229    THUMB_ADC,            /* adc     [0100000101] rm[5..3] rd[2..0] */
230    THUMB_ADD_RRI3,       /* add(1)  [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
231    THUMB_ADD_RI8,        /* add(2)  [00110] rd[10..8] imm_8[7..0] */
232    THUMB_ADD_RRR,        /* add(3)  [0001100] rm[8..6] rn[5..3] rd[2..0] */
233    THUMB_ADD_RR_LH,      /* add(4)  [01000100] H12[01] rm[5..3] rd[2..0] */
234    THUMB_ADD_RR_HL,      /* add(4)  [01001000] H12[10] rm[5..3] rd[2..0] */
235    THUMB_ADD_RR_HH,      /* add(4)  [01001100] H12[11] rm[5..3] rd[2..0] */
236    THUMB_ADD_PC_REL,     /* add(5)  [10100] rd[10..8] imm_8[7..0] */
237    THUMB_ADD_SP_REL,     /* add(6)  [10101] rd[10..8] imm_8[7..0] */
238    THUMB_ADD_SPI7,       /* add(7)  [101100000] imm_7[6..0] */
239    THUMB_AND_RR,         /* and     [0100000000] rm[5..3] rd[2..0] */
240    THUMB_ASR,            /* asr(1)  [00010] imm_5[10..6] rm[5..3] rd[2..0] */
241    THUMB_ASRV,           /* asr(2)  [0100000100] rs[5..3] rd[2..0] */
242    THUMB_B_COND,         /* b(1)    [1101] cond[11..8] offset_8[7..0] */
243    THUMB_B_UNCOND,       /* b(2)    [11100] offset_11[10..0] */
244    THUMB_BIC,            /* bic     [0100001110] rm[5..3] rd[2..0] */
245    THUMB_BKPT,           /* bkpt    [10111110] imm_8[7..0] */
246    THUMB_BLX_1,          /* blx(1)  [111] H[10] offset_11[10..0] */
247    THUMB_BLX_2,          /* blx(1)  [111] H[01] offset_11[10..0] */
248    THUMB_BL_1,           /* blx(1)  [111] H[10] offset_11[10..0] */
249    THUMB_BL_2,           /* blx(1)  [111] H[11] offset_11[10..0] */
250    THUMB_BLX_R,          /* blx(2)  [010001111] rm[6..3] [000] */
251    THUMB_BX,             /* bx      [010001110] H2[6..6] rm[5..3] SBZ[000] */
252    THUMB_CMN,            /* cmn     [0100001011] rm[5..3] rd[2..0] */
253    THUMB_CMP_RI8,        /* cmp(1)  [00101] rn[10..8] imm_8[7..0] */
254    THUMB_CMP_RR,         /* cmp(2)  [0100001010] rm[5..3] rd[2..0] */
255    THUMB_CMP_LH,         /* cmp(3)  [01000101] H12[01] rm[5..3] rd[2..0] */
256    THUMB_CMP_HL,         /* cmp(3)  [01000110] H12[10] rm[5..3] rd[2..0] */
257    THUMB_CMP_HH,         /* cmp(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
258    THUMB_EOR,            /* eor     [0100000001] rm[5..3] rd[2..0] */
259    THUMB_LDMIA,          /* ldmia   [11001] rn[10..8] reglist [7..0] */
260    THUMB_LDR_RRI5,       /* ldr(1)  [01101] imm_5[10..6] rn[5..3] rd[2..0] */
261    THUMB_LDR_RRR,        /* ldr(2)  [0101100] rm[8..6] rn[5..3] rd[2..0] */
262    THUMB_LDR_PC_REL,     /* ldr(3)  [01001] rd[10..8] imm_8[7..0] */
263    THUMB_LDR_SP_REL,     /* ldr(4)  [10011] rd[10..8] imm_8[7..0] */
264    THUMB_LDRB_RRI5,      /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
265    THUMB_LDRB_RRR,       /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
266    THUMB_LDRH_RRI5,      /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
267    THUMB_LDRH_RRR,       /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
268    THUMB_LDRSB_RRR,      /* ldrsb   [0101011] rm[8..6] rn[5..3] rd[2..0] */
269    THUMB_LDRSH_RRR,      /* ldrsh   [0101111] rm[8..6] rn[5..3] rd[2..0] */
270    THUMB_LSL,            /* lsl(1)  [00000] imm_5[10..6] rm[5..3] rd[2..0] */
271    THUMB_LSLV,           /* lsl(2)  [0100000010] rs[5..3] rd[2..0] */
272    THUMB_LSR,            /* lsr(1)  [00001] imm_5[10..6] rm[5..3] rd[2..0] */
273    THUMB_LSRV,           /* lsr(2)  [0100000011] rs[5..3] rd[2..0] */
274    THUMB_MOV_IMM,        /* mov(1)  [00100] rd[10..8] imm_8[7..0] */
275    THUMB_MOV_RR,         /* mov(2)  [0001110000] rn[5..3] rd[2..0] */
276    THUMB_MOV_RR_H2H,     /* mov(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
277    THUMB_MOV_RR_H2L,     /* mov(3)  [01000110] H12[01] rm[5..3] rd[2..0] */
278    THUMB_MOV_RR_L2H,     /* mov(3)  [01000101] H12[10] rm[5..3] rd[2..0] */
279    THUMB_MUL,            /* mul     [0100001101] rm[5..3] rd[2..0] */
280    THUMB_MVN,            /* mvn     [0100001111] rm[5..3] rd[2..0] */
281    THUMB_NEG,            /* neg     [0100001001] rm[5..3] rd[2..0] */
282    THUMB_ORR,            /* orr     [0100001100] rm[5..3] rd[2..0] */
283    THUMB_POP,            /* pop     [1011110] r[8..8] rl[7..0] */
284    THUMB_PUSH,           /* push    [1011010] r[8..8] rl[7..0] */
285    THUMB_RORV,           /* ror     [0100000111] rs[5..3] rd[2..0] */
286    THUMB_SBC,            /* sbc     [0100000110] rm[5..3] rd[2..0] */
287    THUMB_STMIA,          /* stmia   [11000] rn[10..8] reglist [7.. 0] */
288    THUMB_STR_RRI5,       /* str(1)  [01100] imm_5[10..6] rn[5..3] rd[2..0] */
289    THUMB_STR_RRR,        /* str(2)  [0101000] rm[8..6] rn[5..3] rd[2..0] */
290    THUMB_STR_SP_REL,     /* str(3)  [10010] rd[10..8] imm_8[7..0] */
291    THUMB_STRB_RRI5,      /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
292    THUMB_STRB_RRR,       /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
293    THUMB_STRH_RRI5,      /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
294    THUMB_STRH_RRR,       /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
295    THUMB_SUB_RRI3,       /* sub(1)  [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
296    THUMB_SUB_RI8,        /* sub(2)  [00111] rd[10..8] imm_8[7..0] */
297    THUMB_SUB_RRR,        /* sub(3)  [0001101] rm[8..6] rn[5..3] rd[2..0] */
298    THUMB_SUB_SPI7,       /* sub(4)  [101100001] imm_7[6..0] */
299    THUMB_SWI,            /* swi     [11011111] imm_8[7..0] */
300    THUMB_TST,            /* tst     [0100001000] rm[5..3] rn[2..0] */
301    THUMB2_VLDRS,         /* vldr low  sx [111011011001] rn[19..16] rd[15-12]
302                                       [1010] imm_8[7..0] */
303    THUMB2_VLDRD,         /* vldr low  dx [111011011001] rn[19..16] rd[15-12]
304                                       [1011] imm_8[7..0] */
305    THUMB2_VMULS,         /* vmul vd, vn, vm [111011100010] rn[19..16]
306                                       rd[15-12] [10100000] rm[3..0] */
307    THUMB2_VMULD,         /* vmul vd, vn, vm [111011100010] rn[19..16]
308                                       rd[15-12] [10110000] rm[3..0] */
309    THUMB2_VSTRS,         /* vstr low  sx [111011011000] rn[19..16] rd[15-12]
310                                       [1010] imm_8[7..0] */
311    THUMB2_VSTRD,         /* vstr low  dx [111011011000] rn[19..16] rd[15-12]
312                                       [1011] imm_8[7..0] */
313    THUMB2_VSUBS,         /* vsub vd, vn, vm [111011100011] rn[19..16]
314                                       rd[15-12] [10100040] rm[3..0] */
315    THUMB2_VSUBD,         /* vsub vd, vn, vm [111011100011] rn[19..16]
316                                       rd[15-12] [10110040] rm[3..0] */
317    THUMB2_VADDS,         /* vadd vd, vn, vm [111011100011] rn[19..16]
318                                       rd[15-12] [10100000] rm[3..0] */
319    THUMB2_VADDD,         /* vadd vd, vn, vm [111011100011] rn[19..16]
320                                       rd[15-12] [10110000] rm[3..0] */
321    THUMB2_VDIVS,         /* vdiv vd, vn, vm [111011101000] rn[19..16]
322                                       rd[15-12] [10100000] rm[3..0] */
323    THUMB2_VDIVD,         /* vdiv vd, vn, vm [111011101000] rn[19..16]
324                                       rd[15-12] [10110000] rm[3..0] */
325    THUMB2_VCVTIF,        /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
326                                       [10101100] vm[3..0] */
327    THUMB2_VCVTID,        /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
328                                       [10111100] vm[3..0] */
329    THUMB2_VCVTFI,        /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
330                                       [10101100] vm[3..0] */
331    THUMB2_VCVTDI,        /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
332                                       [10111100] vm[3..0] */
333    THUMB2_VCVTFD,        /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
334                                       [10101100] vm[3..0] */
335    THUMB2_VCVTDF,        /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
336                                       [10111100] vm[3..0] */
337    THUMB2_VSQRTS,        /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
338                                       [10101100] vm[3..0] */
339    THUMB2_VSQRTD,        /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
340                                       [10111100] vm[3..0] */
341    THUMB2_MOV_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00001001111]
342                                       imm3 rd[11..8] imm8 */
343    THUMB2_MOV_IMM16,     /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
344                                       imm3 rd[11..8] imm8 */
345    THUMB2_STR_RRI12,     /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
346                                       rn[19..16] rt[15..12] imm12[11..0] */
347    THUMB2_LDR_RRI12,     /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
348                                       rn[19..16] rt[15..12] imm12[11..0] */
349    THUMB2_STR_RRI8_PREDEC, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
350                                       rn[19..16] rt[15..12] [1100] imm[7..0]*/
351    THUMB2_LDR_RRI8_PREDEC, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
352                                       rn[19..16] rt[15..12] [1100] imm[7..0]*/
353    THUMB2_CBNZ,          /* cbnz rd,<label> [101110] i [1] imm5[7..3]
354                                       rn[2..0] */
355    THUMB2_CBZ,           /* cbn rd,<label> [101100] i [1] imm5[7..3]
356                                       rn[2..0] */
357    THUMB2_ADD_RRI12,     /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
358                                       [0] imm3[14..12] rd[11..8] imm8[7..0] */
359    THUMB2_MOV_RR,        /* mov rd, rm [11101010010011110000] rd[11..8]
360                                       [0000] rm[3..0] */
361    THUMB2_VMOVS,         /* vmov.f32 vd, vm [111011101] D [110000]
362                                       vd[15..12] 101001] M [0] vm[3..0] */
363    THUMB2_VMOVD,         /* vmov.f64 vd, vm [111011101] D [110000]
364                                       vd[15..12] 101101] M [0] vm[3..0] */
365    THUMB2_LDMIA,         /* ldmia  [111010001001[ rn[19..16] mask[15..0] */
366    THUMB2_STMIA,         /* stmia  [111010001000[ rn[19..16] mask[15..0] */
367    THUMB2_ADD_RRR,       /* add [111010110000] rn[19..16] [0000] rd[11..8]
368                                   [0000] rm[3..0] */
369    THUMB2_SUB_RRR,       /* sub [111010111010] rn[19..16] [0000] rd[11..8]
370                                   [0000] rm[3..0] */
371    THUMB2_SBC_RRR,       /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
372                                   [0000] rm[3..0] */
373    THUMB2_CMP_RR,        /* cmp [111010111011] rn[19..16] [0000] [1111]
374                                   [0000] rm[3..0] */
375    THUMB2_SUB_RRI12,     /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
376                                       [0] imm3[14..12] rd[11..8] imm8[7..0] */
377    THUMB2_MVN_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00011011110]
378                                       imm3 rd[11..8] imm8 */
379    THUMB2_SEL,           /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
380                                       rm[3-0] */
381    THUMB2_UBFX,          /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
382                                       [0] imm3[14-12] rd[11-8] w[4-0] */
383    THUMB2_SBFX,          /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
384                                       [0] imm3[14-12] rd[11-8] w[4-0] */
385    THUMB2_LDR_RRR,       /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
386                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
387    THUMB2_LDRH_RRR,      /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
388                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
389    THUMB2_LDRSH_RRR,     /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
390                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
391    THUMB2_LDRB_RRR,      /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
392                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
393    THUMB2_LDRSB_RRR,     /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
394                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
395    THUMB2_STR_RRR,       /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
396                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
397    THUMB2_STRH_RRR,      /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
398                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
399    THUMB2_STRB_RRR,      /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
400                                       rt[15-12] [000000] imm[5-4] rm[3-0] */
401    THUMB2_LDRH_RRI12,    /* ldrh rt,[rn,#imm12] [111110001011]
402                                       rt[15..12] rn[19..16] imm12[11..0] */
403    THUMB2_LDRSH_RRI12,   /* ldrsh rt,[rn,#imm12] [111110011011]
404                                       rt[15..12] rn[19..16] imm12[11..0] */
405    THUMB2_LDRB_RRI12,    /* ldrb rt,[rn,#imm12] [111110001001]
406                                       rt[15..12] rn[19..16] imm12[11..0] */
407    THUMB2_LDRSB_RRI12,   /* ldrsb rt,[rn,#imm12] [111110011001]
408                                       rt[15..12] rn[19..16] imm12[11..0] */
409    THUMB2_STRH_RRI12,    /* strh rt,[rn,#imm12] [111110001010]
410                                       rt[15..12] rn[19..16] imm12[11..0] */
411    THUMB2_STRB_RRI12,    /* strb rt,[rn,#imm12] [111110001000]
412                                       rt[15..12] rn[19..16] imm12[11..0] */
413    THUMB2_POP,           /* pop     [1110100010111101] list[15-0]*/
414    THUMB2_PUSH,          /* push    [1110100010101101] list[15-0]*/
415    THUMB2_CMP_RI8,       /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
416                                       imm3 [1111] imm8[7..0] */
417    THUMB2_ADC_RRR,       /* adc [111010110101] rn[19..16] [0000] rd[11..8]
418                                   [0000] rm[3..0] */
419    THUMB2_AND_RRR,       /* and [111010100000] rn[19..16] [0000] rd[11..8]
420                                   [0000] rm[3..0] */
421    THUMB2_BIC_RRR,       /* bic [111010100010] rn[19..16] [0000] rd[11..8]
422                                   [0000] rm[3..0] */
423    THUMB2_CMN_RR,        /* cmn [111010110001] rn[19..16] [0000] [1111]
424                                   [0000] rm[3..0] */
425    THUMB2_EOR_RRR,       /* eor [111010101000] rn[19..16] [0000] rd[11..8]
426                                   [0000] rm[3..0] */
427    THUMB2_MUL_RRR,       /* mul [111110110000] rn[19..16] [1111] rd[11..8]
428                                   [0000] rm[3..0] */
429    THUMB2_MVN_RR,        /* mvn [11101010011011110] rd[11-8] [0000]
430                                   rm[3..0] */
431    THUMB2_RSUB_RRI8,     /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
432                                   imm8[7..0] */
433    THUMB2_NEG_RR,        /* actually rsub rd, rn, #0 */
434    THUMB2_ORR_RRR,       /* orr [111010100100] rn[19..16] [0000] rd[11..8]
435                                   [0000] rm[3..0] */
436    THUMB2_TST_RR,        /* tst [111010100001] rn[19..16] [0000] [1111]
437                                   [0000] rm[3..0] */
438    THUMB2_LSLV_RRR,      /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
439                                   [0000] rm[3..0] */
440    THUMB2_LSRV_RRR,      /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
441                                   [0000] rm[3..0] */
442    THUMB2_ASRV_RRR,      /* asr [111110100100] rn[19..16] [1111] rd[11..8]
443                                   [0000] rm[3..0] */
444    THUMB2_RORV_RRR,      /* ror [111110100110] rn[19..16] [1111] rd[11..8]
445                                   [0000] rm[3..0] */
446    THUMB2_LSL_RRI5,      /* lsl [11101010010011110] imm[14.12] rd[11..8]
447                                   [00] rm[3..0] */
448    THUMB2_LSR_RRI5,      /* lsr [11101010010011110] imm[14.12] rd[11..8]
449                                   [01] rm[3..0] */
450    THUMB2_ASR_RRI5,      /* asr [11101010010011110] imm[14.12] rd[11..8]
451                                   [10] rm[3..0] */
452    THUMB2_ROR_RRI5,      /* ror [11101010010011110] imm[14.12] rd[11..8]
453                                   [11] rm[3..0] */
454    THUMB2_BIC_RRI8,      /* bic [111100000010] rn[19..16] [0] imm3
455                                   rd[11..8] imm8 */
456    THUMB2_AND_RRI8,      /* bic [111100000000] rn[19..16] [0] imm3
457                                   rd[11..8] imm8 */
458    THUMB2_ORR_RRI8,      /* orr [111100000100] rn[19..16] [0] imm3
459                                   rd[11..8] imm8 */
460    THUMB2_EOR_RRI8,      /* eor [111100001000] rn[19..16] [0] imm3
461                                   rd[11..8] imm8 */
462    THUMB2_ADD_RRI8,      /* add [111100001000] rn[19..16] [0] imm3
463                                   rd[11..8] imm8 */
464    THUMB2_ADC_RRI8,      /* adc [111100010101] rn[19..16] [0] imm3
465                                   rd[11..8] imm8 */
466    THUMB2_SUB_RRI8,      /* sub [111100011011] rn[19..16] [0] imm3
467                                   rd[11..8] imm8 */
468    THUMB2_SBC_RRI8,      /* sbc [111100010111] rn[19..16] [0] imm3
469                                   rd[11..8] imm8 */
470    ARM_LAST,
471} ArmOpCode;
472
473/* Bit flags describing the behavior of each native opcode */
474typedef enum ArmOpFeatureFlags {
475    IS_BRANCH =           1 << 1,
476    CLOBBER_DEST =        1 << 2,
477    CLOBBER_SRC1 =        1 << 3,
478    NO_OPERAND =          1 << 4,
479    IS_UNARY_OP =         1 << 5,
480    IS_BINARY_OP =        1 << 6,
481    IS_TERTIARY_OP =      1 << 7,
482    IS_QUAD_OP =          1 << 8,
483    SETS_CCODES =         1 << 9,
484    USES_CCODES =         1 << 10,
485} ArmOpFeatureFlags;
486
487/* Instruction assembly fieldLoc kind */
488typedef enum ArmEncodingKind {
489    UNUSED,
490    BITBLT,        /* Bit string using end/start */
491    DFP,           /* Double FP reg */
492    SFP,           /* Single FP reg */
493    MODIMM,        /* Shifted 8-bit immediate using [26,14..12,7..0] */
494    IMM16,         /* Zero-extended immediate using [26,19..16,14..12,7..0] */
495    IMM6,          /* Encoded branch target using [9,7..3]0 */
496    IMM12,         /* Zero-extended immediate using [26,14..12,7..0] */
497    SHIFT,         /* Shift descriptor, [14..12,7..4] */
498    LSB,           /* least significant bit using [14..12][7..6] */
499    BWIDTH,        /* bit-field width, encoded as width-1 */
500    SHIFT5,        /* Shift count, [14..12,7..6] */
501} ArmEncodingKind;
502
503/* Struct used to define the snippet positions for each Thumb opcode */
504typedef struct ArmEncodingMap {
505    u4 skeleton;
506    struct {
507        ArmEncodingKind kind;
508        int end;   /* end for BITBLT, 1-bit slice end for FP regs */
509        int start; /* start for BITBLT, 4-bit slice end for FP regs */
510    } fieldLoc[4];
511    ArmOpCode opCode;
512    int flags;
513    char *name;
514    char* fmt;
515    int size;
516} ArmEncodingMap;
517
518extern ArmEncodingMap EncodingMap[ARM_LAST];
519
520/*
521 * Each instance of this struct holds a pseudo or real LIR instruction:
522 * - pesudo ones (eg labels and marks) and will be discarded by the assembler.
523 * - real ones will e assembled into Thumb instructions.
524 */
525typedef struct ArmLIR {
526    LIR generic;
527    ArmOpCode opCode;
528    int operands[4];    // [0..3] = [dest, src1, src2, extra]
529    bool isNop;         // LIR is optimized away
530    int age;            // default is 0, set lazily by the optimizer
531    int size;           // 16-bit unit size (1 for thumb, 1 or 2 for thumb2)
532} ArmLIR;
533
534/* Chain cell for predicted method invocation */
535typedef struct PredictedChainingCell {
536    u4 branch;                  /* Branch to chained destination */
537    const ClassObject *clazz;   /* key #1 for prediction */
538    const Method *method;       /* key #2 to lookup native PC from dalvik PC */
539    u4 counter;                 /* counter to patch the chaining cell */
540} PredictedChainingCell;
541
542/* Init values when a predicted chain is initially assembled */
543#define PREDICTED_CHAIN_BX_PAIR_INIT     0
544#define PREDICTED_CHAIN_CLAZZ_INIT       0
545#define PREDICTED_CHAIN_METHOD_INIT      0
546#define PREDICTED_CHAIN_COUNTER_INIT     0
547
548/* Used when the callee is not compiled yet */
549#define PREDICTED_CHAIN_COUNTER_DELAY    16
550
551/* Rechain after this many mis-predictions have happened */
552#define PREDICTED_CHAIN_COUNTER_RECHAIN  1024
553
554/* Used if the resolved callee is a native method */
555#define PREDICTED_CHAIN_COUNTER_AVOID    0x7fffffff
556
557/* Utility macros to traverse the LIR/ArmLIR list */
558#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
559#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
560
561#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
562#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
563
564#define CHAIN_CELL_OFFSET_TAG   0xcdab
565
566ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc);
567
568#endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */
569