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