blob: 81e7346db61d178783b283c0a939283827ae5e44 [file] [log] [blame]
Bill Buzbee89efc3d2009-07-28 11:22:22 -07001/*
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, and r7 are always scratch
25 * r4PC is scratch if used solely in the compiled land. Otherwise it holds the
26 * Dalvik PC.
27 * rFP holds the current frame pointer
28 * rGLUE holds &InterpState
29 */
30typedef enum NativeRegisterPool {
31 r0 = 0,
32 r1 = 1,
33 r2 = 2,
34 r3 = 3,
35 r4PC = 4,
36 rFP = 5,
37 rGLUE = 6,
38 r7 = 7,
39 r8 = 8,
40 r9 = 9,
41 r10 = 10,
42 r11 = 11,
43 r12 = 12,
44 r13 = 13,
45 rlr = 14,
46 rpc = 15
47} NativeRegisterPool;
48
49/* Mask to convert high reg to low for Thumb */
50#define THUMB_REG_MASK 0x7
51
52/* Thumb condition encodings */
53typedef enum ArmConditionCode {
54 ARM_COND_EQ = 0x0, /* 0000 */
55 ARM_COND_NE = 0x1, /* 0001 */
56 ARM_COND_LT = 0xb, /* 1011 */
57 ARM_COND_GE = 0xa, /* 1010 */
58 ARM_COND_GT = 0xc, /* 1100 */
59 ARM_COND_LE = 0xd, /* 1101 */
60 ARM_COND_CS = 0x2, /* 0010 */
61 ARM_COND_MI = 0x4, /* 0100 */
62} ArmConditionCode;
63
64#define isPseudoOpCode(opCode) ((int)(opCode) < 0)
65
66/*
67 * The following enum defines the list of supported Thumb instructions by the
68 * assembler. Their corresponding snippet positions will be defined in
69 * Assemble.c.
70 */
71typedef enum ArmOpCode {
72 ARM_PSEUDO_TARGET_LABEL = -11,
73 ARM_PSEUDO_CHAINING_CELL_HOT = -10,
74 ARM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
75 ARM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
76 ARM_PSEUDO_CHAINING_CELL_NORMAL = -7,
77 ARM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
78 ARM_PSEUDO_ALIGN4 = -5,
79 ARM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
80 ARM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
81 ARM_PSEUDO_EH_BLOCK_LABEL = -2,
82 ARM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
83 /************************************************************************/
84 ARM_16BIT_DATA, /* DATA [0] rd[15..0] */
85 THUMB_ADC, /* adc [0100000101] rm[5..3] rd[2..0] */
86 THUMB_ADD_RRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
87 THUMB_ADD_RI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
88 THUMB_ADD_RRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
89 THUMB_ADD_RR_LH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
90 THUMB_ADD_RR_HL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
91 THUMB_ADD_RR_HH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
92 THUMB_ADD_PC_REL, /* add(5) [10100] rd[10..8] imm_8[7..0] */
93 THUMB_ADD_SP_REL, /* add(6) [10101] rd[10..8] imm_8[7..0] */
94 THUMB_ADD_SPI7, /* add(7) [101100000] imm_7[6..0] */
95 THUMB_AND_RR, /* and [0100000000] rm[5..3] rd[2..0] */
96 THUMB_ASR, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
97 THUMB_ASRV, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
98 THUMB_B_COND, /* b(1) [1101] cond[11..8] offset_8[7..0] */
99 THUMB_B_UNCOND, /* b(2) [11100] offset_11[10..0] */
100 THUMB_BIC, /* bic [0100001110] rm[5..3] rd[2..0] */
101 THUMB_BKPT, /* bkpt [10111110] imm_8[7..0] */
102 THUMB_BLX_1, /* blx(1) [111] H[10] offset_11[10..0] */
103 THUMB_BLX_2, /* blx(1) [111] H[01] offset_11[10..0] */
104 THUMB_BL_1, /* blx(1) [111] H[10] offset_11[10..0] */
105 THUMB_BL_2, /* blx(1) [111] H[11] offset_11[10..0] */
106 THUMB_BLX_R, /* blx(2) [010001111] H2[6..6] rm[5..3] SBZ[000] */
107 THUMB_BX, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
108 THUMB_CMN, /* cmn [0100001011] rm[5..3] rd[2..0] */
109 THUMB_CMP_RI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
110 THUMB_CMP_RR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
111 THUMB_CMP_LH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
112 THUMB_CMP_HL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
113 THUMB_CMP_HH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
114 THUMB_EOR, /* eor [0100000001] rm[5..3] rd[2..0] */
115 THUMB_LDMIA, /* ldmia [11001] rn[10..8] reglist [7..0] */
116 THUMB_LDR_RRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
117 THUMB_LDR_RRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
118 THUMB_LDR_PC_REL, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
119 THUMB_LDR_SP_REL, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
120 THUMB_LDRB_RRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
121 THUMB_LDRB_RRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
122 THUMB_LDRH_RRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
123 THUMB_LDRH_RRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
124 THUMB_LDRSB_RRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
125 THUMB_LDRSH_RRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
126 THUMB_LSL, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
127 THUMB_LSLV, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
128 THUMB_LSR, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
129 THUMB_LSRV, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
130 THUMB_MOV_IMM, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
131 THUMB_MOV_RR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
132 THUMB_MOV_RR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
133 THUMB_MOV_RR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
134 THUMB_MOV_RR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
135 THUMB_MUL, /* mul [0100001101] rm[5..3] rd[2..0] */
136 THUMB_MVN, /* mvn [0100001111] rm[5..3] rd[2..0] */
137 THUMB_NEG, /* neg [0100001001] rm[5..3] rd[2..0] */
138 THUMB_ORR, /* orr [0100001100] rm[5..3] rd[2..0] */
139 THUMB_POP, /* pop [1011110] r[8..8] rl[7..0] */
140 THUMB_PUSH, /* push [1011010] r[8..8] rl[7..0] */
141 THUMB_ROR, /* ror [0100000111] rs[5..3] rd[2..0] */
142 THUMB_SBC, /* sbc [0100000110] rm[5..3] rd[2..0] */
143 THUMB_STMIA, /* stmia [11000] rn[10..8] reglist [7.. 0] */
144 THUMB_STR_RRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
145 THUMB_STR_RRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
146 THUMB_STR_SP_REL, /* str(3) [10010] rd[10..8] imm_8[7..0] */
147 THUMB_STRB_RRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
148 THUMB_STRB_RRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
149 THUMB_STRH_RRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
150 THUMB_STRH_RRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
151 THUMB_SUB_RRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
152 THUMB_SUB_RI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
153 THUMB_SUB_RRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
154 THUMB_SUB_SPI7, /* sub(4) [101100001] imm_7[6..0] */
155 THUMB_SWI, /* swi [11011111] imm_8[7..0] */
156 THUMB_TST, /* tst [0100001000] rm[5..3] rn[2..0] */
157 ARM_LAST,
158} ArmOpCode;
159
160/* Bit flags describing the behavior of each native opcode */
161typedef enum ArmOpFeatureFlags {
162 IS_BRANCH = 1 << 1,
163 CLOBBER_DEST = 1 << 2,
164 CLOBBER_SRC1 = 1 << 3,
165 NO_OPERAND = 1 << 4,
166 IS_UNARY_OP = 1 << 5,
167 IS_BINARY_OP = 1 << 6,
168 IS_TERTIARY_OP = 1 << 7,
169} ArmOpFeatureFlags;
170
171/* Struct used to define the snippet positions for each Thumb opcode */
172typedef struct ArmEncodingMap {
173 short skeleton;
174 struct {
175 int end;
176 int start;
177 } fieldLoc[3];
178 ArmOpCode opCode;
179 int flags;
180 char *name;
181 char* fmt;
182 int size;
183} ArmEncodingMap;
184
185extern ArmEncodingMap EncodingMap[ARM_LAST];
186
187/*
188 * Each instance of this struct holds a pseudo or real LIR instruction:
189 * - pesudo ones (eg labels and marks) and will be discarded by the assembler.
190 * - real ones will e assembled into Thumb instructions.
191 */
192typedef struct ArmLIR {
193 LIR generic;
194 ArmOpCode opCode;
195 int operands[3]; // [0..2] = [dest, src1, src2]
196 bool isNop; // LIR is optimized away
197 int age; // default is 0, set lazily by the optimizer
198 int size; // 16-bit unit size (1 for thumb, 1 or 2 for thumb2)
199} ArmLIR;
200
201/* Chain cell for predicted method invocation */
202typedef struct PredictedChainingCell {
203 u4 branch; /* Branch to chained destination */
204 const ClassObject *clazz; /* key #1 for prediction */
205 const Method *method; /* key #2 to lookup native PC from dalvik PC */
206 u4 counter; /* counter to patch the chaining cell */
207} PredictedChainingCell;
208
209/* Init values when a predicted chain is initially assembled */
210#define PREDICTED_CHAIN_BX_PAIR_INIT 0
211#define PREDICTED_CHAIN_CLAZZ_INIT 0
212#define PREDICTED_CHAIN_METHOD_INIT 0
213#define PREDICTED_CHAIN_COUNTER_INIT 0
214
215/* Used when the callee is not compiled yet */
216#define PREDICTED_CHAIN_COUNTER_DELAY 16
217
218/* Rechain after this many mis-predictions have happened */
219#define PREDICTED_CHAIN_COUNTER_RECHAIN 1024
220
221/* Used if the resolved callee is a native method */
222#define PREDICTED_CHAIN_COUNTER_AVOID 0x7fffffff
223
224/* Utility macros to traverse the LIR/ArmLIR list */
225#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
226#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
227
228#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
229#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
230
231#define CHAIN_CELL_OFFSET_TAG 0xcdab
232
233#endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */