• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 always scratch
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  * For Thumb code use:
39  *       r0, r1, r2, r3 to hold operands/results via scoreboard
40  *       r4, r7 for temps
41  *
42  * For Thumb2 code use:
43  *       r0, r1, r2, r3, r8, r9, r10, r11 for operands/results via scoreboard
44  *       r4, r7, r14 for temps
45  *
46  * When transitioning from code cache to interp:
47  *       restore rIBASE
48  *       restore rPC
49  *       restore r11 (fp)?
50  *
51  * Double precision values are stored in consecutive single precision registers
52  * such that dr0 -> (sr0,sr1), dr1 -> (sr2,sr3) ... dr16 -> (sr30,sr31)
53  */
54 
55 /* Offset to distingish FP regs */
56 #define FP_REG_OFFSET 32
57 /* Offset to distinguish DP FP regs */
58 #define FP_DOUBLE 64
59 /* Reg types */
60 #define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
61 #define LOWREG(x) ((x & 0x7) == x)
62 #define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
63 #define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
64 /* Mask to strip off fp flags */
65 #define FP_REG_MASK (FP_REG_OFFSET-1)
66 /* Mask to convert high reg to low for Thumb */
67 #define THUMB_REG_MASK 0x7
68 
69 
70 typedef enum NativeRegisterPool {
71     r0 = 0,
72     r1 = 1,
73     r2 = 2,
74     r3 = 3,
75     r4PC = 4,
76     rFP = 5,
77     rGLUE = 6,
78     r7 = 7,
79     r8 = 8,
80     r9 = 9,
81     r10 = 10,
82     r11 = 11,
83     r12 = 12,
84     r13 = 13,
85     rlr = 14,
86     rpc = 15,
87     fr0  =  0 + FP_REG_OFFSET,
88     fr1  =  1 + FP_REG_OFFSET,
89     fr2  =  2 + FP_REG_OFFSET,
90     fr3  =  3 + FP_REG_OFFSET,
91     fr4  =  4 + FP_REG_OFFSET,
92     fr5  =  5 + FP_REG_OFFSET,
93     fr6  =  6 + FP_REG_OFFSET,
94     fr7  =  7 + FP_REG_OFFSET,
95     fr8  =  8 + FP_REG_OFFSET,
96     fr9  =  9 + FP_REG_OFFSET,
97     fr10 = 10 + FP_REG_OFFSET,
98     fr11 = 11 + FP_REG_OFFSET,
99     fr12 = 12 + FP_REG_OFFSET,
100     fr13 = 13 + FP_REG_OFFSET,
101     fr14 = 14 + FP_REG_OFFSET,
102     fr15 = 15 + FP_REG_OFFSET,
103     fr16 = 16 + FP_REG_OFFSET,
104     fr17 = 17 + FP_REG_OFFSET,
105     fr18 = 18 + FP_REG_OFFSET,
106     fr19 = 19 + FP_REG_OFFSET,
107     fr20 = 20 + FP_REG_OFFSET,
108     fr21 = 21 + FP_REG_OFFSET,
109     fr22 = 22 + FP_REG_OFFSET,
110     fr23 = 23 + FP_REG_OFFSET,
111     fr24 = 24 + FP_REG_OFFSET,
112     fr25 = 25 + FP_REG_OFFSET,
113     fr26 = 26 + FP_REG_OFFSET,
114     fr27 = 27 + FP_REG_OFFSET,
115     fr28 = 28 + FP_REG_OFFSET,
116     fr29 = 29 + FP_REG_OFFSET,
117     fr30 = 30 + FP_REG_OFFSET,
118     fr31 = 31 + FP_REG_OFFSET,
119     dr0 = fr0 + FP_DOUBLE,
120     dr1 = fr2 + FP_DOUBLE,
121     dr2 = fr4 + FP_DOUBLE,
122     dr3 = fr6 + FP_DOUBLE,
123     dr4 = fr8 + FP_DOUBLE,
124     dr5 = fr10 + FP_DOUBLE,
125     dr6 = fr12 + FP_DOUBLE,
126     dr7 = fr14 + FP_DOUBLE,
127     dr8 = fr16 + FP_DOUBLE,
128     dr9 = fr18 + FP_DOUBLE,
129     dr10 = fr20 + FP_DOUBLE,
130     dr11 = fr22 + FP_DOUBLE,
131     dr12 = fr24 + FP_DOUBLE,
132     dr13 = fr26 + FP_DOUBLE,
133     dr14 = fr28 + FP_DOUBLE,
134     dr15 = fr30 + FP_DOUBLE,
135 } NativeRegisterPool;
136 
137 /* Thumb condition encodings */
138 typedef enum ArmConditionCode {
139     ARM_COND_EQ = 0x0,    /* 0000 */
140     ARM_COND_NE = 0x1,    /* 0001 */
141     ARM_COND_LT = 0xb,    /* 1011 */
142     ARM_COND_GE = 0xa,    /* 1010 */
143     ARM_COND_GT = 0xc,    /* 1100 */
144     ARM_COND_LE = 0xd,    /* 1101 */
145     ARM_COND_CS = 0x2,    /* 0010 */
146     ARM_COND_MI = 0x4,    /* 0100 */
147 } ArmConditionCode;
148 
149 #define isPseudoOpCode(opCode) ((int)(opCode) < 0)
150 
151 /*
152  * The following enum defines the list of supported Thumb instructions by the
153  * assembler. Their corresponding snippet positions will be defined in
154  * Assemble.c.
155  */
156 typedef enum ArmOpCode {
157     ARM_PSEUDO_TARGET_LABEL = -11,
158     ARM_PSEUDO_CHAINING_CELL_HOT = -10,
159     ARM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
160     ARM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
161     ARM_PSEUDO_CHAINING_CELL_NORMAL = -7,
162     ARM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
163     ARM_PSEUDO_ALIGN4 = -5,
164     ARM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
165     ARM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
166     ARM_PSEUDO_EH_BLOCK_LABEL = -2,
167     ARM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
168     /************************************************************************/
169     ARM_16BIT_DATA,       /* DATA   [0] rd[15..0] */
170     THUMB_ADC,            /* adc     [0100000101] rm[5..3] rd[2..0] */
171     THUMB_ADD_RRI3,       /* add(1)  [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
172     THUMB_ADD_RI8,        /* add(2)  [00110] rd[10..8] imm_8[7..0] */
173     THUMB_ADD_RRR,        /* add(3)  [0001100] rm[8..6] rn[5..3] rd[2..0] */
174     THUMB_ADD_RR_LH,      /* add(4)  [01000100] H12[01] rm[5..3] rd[2..0] */
175     THUMB_ADD_RR_HL,      /* add(4)  [01001000] H12[10] rm[5..3] rd[2..0] */
176     THUMB_ADD_RR_HH,      /* add(4)  [01001100] H12[11] rm[5..3] rd[2..0] */
177     THUMB_ADD_PC_REL,     /* add(5)  [10100] rd[10..8] imm_8[7..0] */
178     THUMB_ADD_SP_REL,     /* add(6)  [10101] rd[10..8] imm_8[7..0] */
179     THUMB_ADD_SPI7,       /* add(7)  [101100000] imm_7[6..0] */
180     THUMB_AND_RR,         /* and     [0100000000] rm[5..3] rd[2..0] */
181     THUMB_ASR,            /* asr(1)  [00010] imm_5[10..6] rm[5..3] rd[2..0] */
182     THUMB_ASRV,           /* asr(2)  [0100000100] rs[5..3] rd[2..0] */
183     THUMB_B_COND,         /* b(1)    [1101] cond[11..8] offset_8[7..0] */
184     THUMB_B_UNCOND,       /* b(2)    [11100] offset_11[10..0] */
185     THUMB_BIC,            /* bic     [0100001110] rm[5..3] rd[2..0] */
186     THUMB_BKPT,           /* bkpt    [10111110] imm_8[7..0] */
187     THUMB_BLX_1,          /* blx(1)  [111] H[10] offset_11[10..0] */
188     THUMB_BLX_2,          /* blx(1)  [111] H[01] offset_11[10..0] */
189     THUMB_BL_1,           /* blx(1)  [111] H[10] offset_11[10..0] */
190     THUMB_BL_2,           /* blx(1)  [111] H[11] offset_11[10..0] */
191     THUMB_BLX_R,          /* blx(2)  [010001111] H2[6..6] rm[5..3] SBZ[000] */
192     THUMB_BX,             /* bx      [010001110] H2[6..6] rm[5..3] SBZ[000] */
193     THUMB_CMN,            /* cmn     [0100001011] rm[5..3] rd[2..0] */
194     THUMB_CMP_RI8,        /* cmp(1)  [00101] rn[10..8] imm_8[7..0] */
195     THUMB_CMP_RR,         /* cmp(2)  [0100001010] rm[5..3] rd[2..0] */
196     THUMB_CMP_LH,         /* cmp(3)  [01000101] H12[01] rm[5..3] rd[2..0] */
197     THUMB_CMP_HL,         /* cmp(3)  [01000110] H12[10] rm[5..3] rd[2..0] */
198     THUMB_CMP_HH,         /* cmp(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
199     THUMB_EOR,            /* eor     [0100000001] rm[5..3] rd[2..0] */
200     THUMB_LDMIA,          /* ldmia   [11001] rn[10..8] reglist [7..0] */
201     THUMB_LDR_RRI5,       /* ldr(1)  [01101] imm_5[10..6] rn[5..3] rd[2..0] */
202     THUMB_LDR_RRR,        /* ldr(2)  [0101100] rm[8..6] rn[5..3] rd[2..0] */
203     THUMB_LDR_PC_REL,     /* ldr(3)  [01001] rd[10..8] imm_8[7..0] */
204     THUMB_LDR_SP_REL,     /* ldr(4)  [10011] rd[10..8] imm_8[7..0] */
205     THUMB_LDRB_RRI5,      /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
206     THUMB_LDRB_RRR,       /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
207     THUMB_LDRH_RRI5,      /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
208     THUMB_LDRH_RRR,       /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
209     THUMB_LDRSB_RRR,      /* ldrsb   [0101011] rm[8..6] rn[5..3] rd[2..0] */
210     THUMB_LDRSH_RRR,      /* ldrsh   [0101111] rm[8..6] rn[5..3] rd[2..0] */
211     THUMB_LSL,            /* lsl(1)  [00000] imm_5[10..6] rm[5..3] rd[2..0] */
212     THUMB_LSLV,           /* lsl(2)  [0100000010] rs[5..3] rd[2..0] */
213     THUMB_LSR,            /* lsr(1)  [00001] imm_5[10..6] rm[5..3] rd[2..0] */
214     THUMB_LSRV,           /* lsr(2)  [0100000011] rs[5..3] rd[2..0] */
215     THUMB_MOV_IMM,        /* mov(1)  [00100] rd[10..8] imm_8[7..0] */
216     THUMB_MOV_RR,         /* mov(2)  [0001110000] rn[5..3] rd[2..0] */
217     THUMB_MOV_RR_H2H,     /* mov(3)  [01000111] H12[11] rm[5..3] rd[2..0] */
218     THUMB_MOV_RR_H2L,     /* mov(3)  [01000110] H12[01] rm[5..3] rd[2..0] */
219     THUMB_MOV_RR_L2H,     /* mov(3)  [01000101] H12[10] rm[5..3] rd[2..0] */
220     THUMB_MUL,            /* mul     [0100001101] rm[5..3] rd[2..0] */
221     THUMB_MVN,            /* mvn     [0100001111] rm[5..3] rd[2..0] */
222     THUMB_NEG,            /* neg     [0100001001] rm[5..3] rd[2..0] */
223     THUMB_ORR,            /* orr     [0100001100] rm[5..3] rd[2..0] */
224     THUMB_POP,            /* pop     [1011110] r[8..8] rl[7..0] */
225     THUMB_PUSH,           /* push    [1011010] r[8..8] rl[7..0] */
226     THUMB_ROR,            /* ror     [0100000111] rs[5..3] rd[2..0] */
227     THUMB_SBC,            /* sbc     [0100000110] rm[5..3] rd[2..0] */
228     THUMB_STMIA,          /* stmia   [11000] rn[10..8] reglist [7.. 0] */
229     THUMB_STR_RRI5,       /* str(1)  [01100] imm_5[10..6] rn[5..3] rd[2..0] */
230     THUMB_STR_RRR,        /* str(2)  [0101000] rm[8..6] rn[5..3] rd[2..0] */
231     THUMB_STR_SP_REL,     /* str(3)  [10010] rd[10..8] imm_8[7..0] */
232     THUMB_STRB_RRI5,      /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
233     THUMB_STRB_RRR,       /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
234     THUMB_STRH_RRI5,      /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
235     THUMB_STRH_RRR,       /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
236     THUMB_SUB_RRI3,       /* sub(1)  [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
237     THUMB_SUB_RI8,        /* sub(2)  [00111] rd[10..8] imm_8[7..0] */
238     THUMB_SUB_RRR,        /* sub(3)  [0001101] rm[8..6] rn[5..3] rd[2..0] */
239     THUMB_SUB_SPI7,       /* sub(4)  [101100001] imm_7[6..0] */
240     THUMB_SWI,            /* swi     [11011111] imm_8[7..0] */
241     THUMB_TST,            /* tst     [0100001000] rm[5..3] rn[2..0] */
242     THUMB2_VLDRS,         /* vldr low  sx [111011011001] rn[19..16] rd[15-12]
243                                        [1010] imm_8[7..0] */
244     THUMB2_VLDRD,         /* vldr low  dx [111011011001] rn[19..16] rd[15-12]
245                                        [1011] imm_8[7..0] */
246     THUMB2_VMULS,         /* vmul vd, vn, vm [111011100010] rn[19..16]
247                                        rd[15-12] [10100000] rm[3..0] */
248     THUMB2_VMULD,         /* vmul vd, vn, vm [111011100010] rn[19..16]
249                                        rd[15-12] [10110000] rm[3..0] */
250     THUMB2_VSTRS,         /* vstr low  sx [111011011000] rn[19..16] rd[15-12]
251                                        [1010] imm_8[7..0] */
252     THUMB2_VSTRD,         /* vstr low  dx [111011011000] rn[19..16] rd[15-12]
253                                        [1011] imm_8[7..0] */
254     THUMB2_VSUBS,         /* vsub vd, vn, vm [111011100011] rn[19..16]
255                                        rd[15-12] [10100040] rm[3..0] */
256     THUMB2_VSUBD,         /* vsub vd, vn, vm [111011100011] rn[19..16]
257                                        rd[15-12] [10110040] rm[3..0] */
258     THUMB2_VADDS,         /* vadd vd, vn, vm [111011100011] rn[19..16]
259                                        rd[15-12] [10100000] rm[3..0] */
260     THUMB2_VADDD,         /* vadd vd, vn, vm [111011100011] rn[19..16]
261                                        rd[15-12] [10110000] rm[3..0] */
262     THUMB2_VDIVS,         /* vdiv vd, vn, vm [111011101000] rn[19..16]
263                                        rd[15-12] [10100000] rm[3..0] */
264     THUMB2_VDIVD,         /* vdiv vd, vn, vm [111011101000] rn[19..16]
265                                        rd[15-12] [10110000] rm[3..0] */
266     THUMB2_VCVTIF,        /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
267                                        [10101100] vm[3..0] */
268     THUMB2_VCVTID,        /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
269                                        [10111100] vm[3..0] */
270     THUMB2_VCVTFI,        /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
271                                        [10101100] vm[3..0] */
272     THUMB2_VCVTDI,        /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
273                                        [10111100] vm[3..0] */
274     THUMB2_VCVTFD,        /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
275                                        [10101100] vm[3..0] */
276     THUMB2_VCVTDF,        /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
277                                        [10111100] vm[3..0] */
278     THUMB2_VSQRTS,        /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
279                                        [10101100] vm[3..0] */
280     THUMB2_VSQRTD,        /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
281                                        [10111100] vm[3..0] */
282     THUMB2_MOV_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00001001111]
283                                        imm3 rd[11..8] imm8 */
284     THUMB2_MOV_IMM16,     /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
285                                        imm3 rd[11..8] imm8 */
286     THUMB2_STR_RRI12,     /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
287                                        rn[19..16] rt[15..12] imm12[11..0] */
288     THUMB2_LDR_RRI12,     /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
289                                        rn[19..16] rt[15..12] imm12[11..0] */
290     THUMB2_STR_RRI8_PREDEC, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
291                                        rn[19..16] rt[15..12] [1100] imm[7..0]*/
292     THUMB2_LDR_RRI8_PREDEC, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
293                                        rn[19..16] rt[15..12] [1100] imm[7..0]*/
294     THUMB2_CBNZ,            /* cbnz rd,<label> [101110] i [1] imm5[7..3]
295                                        rn[2..0] */
296     THUMB2_CBZ,             /* cbn rd,<label> [101100] i [1] imm5[7..3]
297                                        rn[2..0] */
298     THUMB2_ADD_RRI12,       /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
299                                        [0] imm3[14..12] rd[11..8] imm8[7..0] */
300     THUMB2_MOV_RR,          /* mov rd, rm [11101010010011110000] rd[11..8]
301                                        [0000] rm[3..0] */
302     THUMB2_VMOVS,           /* vmov.f32 vd, vm [111011101] D [110000]
303                                        vd[15..12] 101001] M [0] vm[3..0] */
304     THUMB2_VMOVD,           /* vmov.f64 vd, vm [111011101] D [110000]
305                                        vd[15..12] 101101] M [0] vm[3..0] */
306     ARM_LAST,
307 } ArmOpCode;
308 
309 /* Bit flags describing the behavior of each native opcode */
310 typedef enum ArmOpFeatureFlags {
311     IS_BRANCH =           1 << 1,
312     CLOBBER_DEST =        1 << 2,
313     CLOBBER_SRC1 =        1 << 3,
314     NO_OPERAND =          1 << 4,
315     IS_UNARY_OP =         1 << 5,
316     IS_BINARY_OP =        1 << 6,
317     IS_TERTIARY_OP =      1 << 7,
318 } ArmOpFeatureFlags;
319 
320 /* Instruction assembly fieldLoc kind */
321 typedef enum ArmEncodingKind {
322     UNUSED,
323     BITBLT,        /* Bit string using end/start */
324     DFP,           /* Double FP reg */
325     SFP,           /* Single FP reg */
326     MODIMM,        /* Shifted 8-bit immediate using [26,14..12,7..0] */
327     IMM16,         /* Zero-extended immediate using [26,19..16,14..12,7..0] */
328     IMM6,          /* Encoded branch target using [9,7..3]0 */
329     IMM12,         /* Zero-extended immediate using [26,14..12,7..0] */
330 } ArmEncodingKind;
331 
332 /* Struct used to define the snippet positions for each Thumb opcode */
333 typedef struct ArmEncodingMap {
334     u4 skeleton;
335     struct {
336         ArmEncodingKind kind;
337         int end;   /* end for BITBLT, 1-bit slice end for FP regs */
338         int start; /* start for BITBLT, 4-bit slice end for FP regs */
339     } fieldLoc[3];
340     ArmOpCode opCode;
341     int flags;
342     char *name;
343     char* fmt;
344     int size;
345 } ArmEncodingMap;
346 
347 extern ArmEncodingMap EncodingMap[ARM_LAST];
348 
349 /*
350  * Each instance of this struct holds a pseudo or real LIR instruction:
351  * - pesudo ones (eg labels and marks) and will be discarded by the assembler.
352  * - real ones will e assembled into Thumb instructions.
353  */
354 typedef struct ArmLIR {
355     LIR generic;
356     ArmOpCode opCode;
357     int operands[3];    // [0..2] = [dest, src1, src2]
358     bool isNop;         // LIR is optimized away
359     int age;            // default is 0, set lazily by the optimizer
360     int size;           // 16-bit unit size (1 for thumb, 1 or 2 for thumb2)
361 } ArmLIR;
362 
363 /* Chain cell for predicted method invocation */
364 typedef struct PredictedChainingCell {
365     u4 branch;                  /* Branch to chained destination */
366     const ClassObject *clazz;   /* key #1 for prediction */
367     const Method *method;       /* key #2 to lookup native PC from dalvik PC */
368     u4 counter;                 /* counter to patch the chaining cell */
369 } PredictedChainingCell;
370 
371 /* Init values when a predicted chain is initially assembled */
372 #define PREDICTED_CHAIN_BX_PAIR_INIT     0
373 #define PREDICTED_CHAIN_CLAZZ_INIT       0
374 #define PREDICTED_CHAIN_METHOD_INIT      0
375 #define PREDICTED_CHAIN_COUNTER_INIT     0
376 
377 /* Used when the callee is not compiled yet */
378 #define PREDICTED_CHAIN_COUNTER_DELAY    16
379 
380 /* Rechain after this many mis-predictions have happened */
381 #define PREDICTED_CHAIN_COUNTER_RECHAIN  1024
382 
383 /* Used if the resolved callee is a native method */
384 #define PREDICTED_CHAIN_COUNTER_AVOID    0x7fffffff
385 
386 /* Utility macros to traverse the LIR/ArmLIR list */
387 #define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
388 #define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
389 
390 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next
391 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev
392 
393 #define CHAIN_CELL_OFFSET_TAG   0xcdab
394 
395 #endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */
396