blob: 20fb6bf66c2bdfa6cb3bebea3995f974e87fa6f9 [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/*
Bill Buzbee9bc3df32009-07-30 10:52:29 -070024 * 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
Bill Buzbee270c1d62009-08-13 16:58:07 -070030 * r9 is reserved
Bill Buzbee9bc3df32009-07-30 10:52:29 -070031 * 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 *
Bill Buzbee270c1d62009-08-13 16:58:07 -070038 * 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 *
Bill Buzbee9bc3df32009-07-30 10:52:29 -070048 * For Thumb code use:
Bill Buzbee270c1d62009-08-13 16:58:07 -070049 * r0, r1, r2, r3 to hold operands/results
Bill Buzbee9bc3df32009-07-30 10:52:29 -070050 * r4, r7 for temps
51 *
52 * For Thumb2 code use:
Bill Buzbee270c1d62009-08-13 16:58:07 -070053 * 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
Bill Buzbee9bc3df32009-07-30 10:52:29 -070057 *
58 * When transitioning from code cache to interp:
59 * restore rIBASE
60 * restore rPC
Bill Buzbee270c1d62009-08-13 16:58:07 -070061 * restore r11?
Bill Buzbee89efc3d2009-07-28 11:22:22 -070062 */
Bill Buzbee9bc3df32009-07-30 10:52:29 -070063
64/* Offset to distingish FP regs */
65#define FP_REG_OFFSET 32
Bill Buzbee7ea0f642009-08-10 17:06:51 -070066/* 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))
Bill Buzbee9bc3df32009-07-30 10:52:29 -070073/* Mask to strip off fp flags */
74#define FP_REG_MASK (FP_REG_OFFSET-1)
Bill Buzbee270c1d62009-08-13 16:58:07 -070075/* non-existent Dalvik register */
76#define vNone (-1)
77/* non-existant physical register */
78#define rNone (-1)
Bill Buzbee9bc3df32009-07-30 10:52:29 -070079
Ben Chengdcf3e5d2009-09-11 13:42:05 -070080typedef enum ResourceEncodingPos {
81 kGPReg0 = 0,
82 kRegSP = 13,
83 kRegLR = 14,
84 kRegPC = 15,
85 kFPReg0 = 16,
86 kITBlock = 48,
87 kCCode = 49,
88 kFPStatus = 50,
89} ResourceEncodingPos;
90
91#define ENCODE_GP_REG(N) (1ULL << N)
92#define ENCODE_REG_LIST(N) ((u8) N)
93#define ENCODE_REG_SP (1ULL << kRegSP)
94#define ENCODE_REG_LR (1ULL << kRegLR)
95#define ENCODE_REG_PC (1ULL << kRegPC)
96#define ENCODE_SFP_REG(N) (1ULL << (N - FP_REG_OFFSET + kFPReg0))
97#define ENCODE_DFP_REG(N) (3ULL << (((N - FP_DOUBLE) << 1) + kFPReg0))
98#define ENCODE_IT_BLOCK (1ULL << kITBlock)
99#define ENCODE_CCODE (1ULL << kCCode)
100#define ENCODE_FP_STATUS (1ULL << kFPStatus)
101
Bill Buzbee270c1d62009-08-13 16:58:07 -0700102typedef enum OpSize {
103 WORD,
104 LONG,
105 SINGLE,
106 DOUBLE,
107 UNSIGNED_HALF,
108 SIGNED_HALF,
109 UNSIGNED_BYTE,
110 SIGNED_BYTE,
111} OpSize;
112
113typedef enum OpKind {
114 OP_MOV,
115 OP_MVN,
116 OP_CMP,
117 OP_LSL,
118 OP_LSR,
119 OP_ASR,
120 OP_ROR,
121 OP_NOT,
122 OP_AND,
123 OP_OR,
124 OP_XOR,
125 OP_NEG,
126 OP_ADD,
127 OP_ADC,
128 OP_SUB,
129 OP_SBC,
130 OP_RSUB,
131 OP_MUL,
132 OP_DIV,
133 OP_REM,
134 OP_BIC,
135 OP_CMN,
136 OP_TST,
137 OP_BKPT,
138 OP_BLX,
139 OP_PUSH,
140 OP_POP,
141 OP_2CHAR,
142 OP_2SHORT,
143 OP_2BYTE,
144 OP_COND_BR,
145 OP_UNCOND_BR,
146} OpKind;
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700147
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700148typedef enum NativeRegisterPool {
149 r0 = 0,
150 r1 = 1,
151 r2 = 2,
152 r3 = 3,
153 r4PC = 4,
154 rFP = 5,
155 rGLUE = 6,
156 r7 = 7,
157 r8 = 8,
158 r9 = 9,
159 r10 = 10,
160 r11 = 11,
161 r12 = 12,
162 r13 = 13,
163 rlr = 14,
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700164 rpc = 15,
165 fr0 = 0 + FP_REG_OFFSET,
166 fr1 = 1 + FP_REG_OFFSET,
167 fr2 = 2 + FP_REG_OFFSET,
168 fr3 = 3 + FP_REG_OFFSET,
169 fr4 = 4 + FP_REG_OFFSET,
170 fr5 = 5 + FP_REG_OFFSET,
171 fr6 = 6 + FP_REG_OFFSET,
172 fr7 = 7 + FP_REG_OFFSET,
173 fr8 = 8 + FP_REG_OFFSET,
174 fr9 = 9 + FP_REG_OFFSET,
175 fr10 = 10 + FP_REG_OFFSET,
176 fr11 = 11 + FP_REG_OFFSET,
177 fr12 = 12 + FP_REG_OFFSET,
178 fr13 = 13 + FP_REG_OFFSET,
179 fr14 = 14 + FP_REG_OFFSET,
180 fr15 = 15 + FP_REG_OFFSET,
181 fr16 = 16 + FP_REG_OFFSET,
182 fr17 = 17 + FP_REG_OFFSET,
183 fr18 = 18 + FP_REG_OFFSET,
184 fr19 = 19 + FP_REG_OFFSET,
185 fr20 = 20 + FP_REG_OFFSET,
186 fr21 = 21 + FP_REG_OFFSET,
187 fr22 = 22 + FP_REG_OFFSET,
188 fr23 = 23 + FP_REG_OFFSET,
189 fr24 = 24 + FP_REG_OFFSET,
190 fr25 = 25 + FP_REG_OFFSET,
191 fr26 = 26 + FP_REG_OFFSET,
192 fr27 = 27 + FP_REG_OFFSET,
193 fr28 = 28 + FP_REG_OFFSET,
194 fr29 = 29 + FP_REG_OFFSET,
195 fr30 = 30 + FP_REG_OFFSET,
196 fr31 = 31 + FP_REG_OFFSET,
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700197 dr0 = fr0 + FP_DOUBLE,
198 dr1 = fr2 + FP_DOUBLE,
199 dr2 = fr4 + FP_DOUBLE,
200 dr3 = fr6 + FP_DOUBLE,
201 dr4 = fr8 + FP_DOUBLE,
202 dr5 = fr10 + FP_DOUBLE,
203 dr6 = fr12 + FP_DOUBLE,
204 dr7 = fr14 + FP_DOUBLE,
205 dr8 = fr16 + FP_DOUBLE,
206 dr9 = fr18 + FP_DOUBLE,
207 dr10 = fr20 + FP_DOUBLE,
208 dr11 = fr22 + FP_DOUBLE,
209 dr12 = fr24 + FP_DOUBLE,
210 dr13 = fr26 + FP_DOUBLE,
211 dr14 = fr28 + FP_DOUBLE,
212 dr15 = fr30 + FP_DOUBLE,
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700213} NativeRegisterPool;
214
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700215/* Thumb condition encodings */
216typedef enum ArmConditionCode {
217 ARM_COND_EQ = 0x0, /* 0000 */
218 ARM_COND_NE = 0x1, /* 0001 */
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700219 ARM_COND_CS = 0x2, /* 0010 */
220 ARM_COND_CC = 0x3, /* 0011 */
221 ARM_COND_MI = 0x4, /* 0100 */
222 ARM_COND_PL = 0x5, /* 0101 */
223 ARM_COND_VS = 0x6, /* 0110 */
224 ARM_COND_VC = 0x7, /* 0111 */
225 ARM_COND_HI = 0x8, /* 1000 */
226 ARM_COND_LS = 0x9, /* 1001 */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700227 ARM_COND_GE = 0xa, /* 1010 */
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700228 ARM_COND_LT = 0xb, /* 1011 */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700229 ARM_COND_GT = 0xc, /* 1100 */
230 ARM_COND_LE = 0xd, /* 1101 */
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700231 ARM_COND_AL = 0xe, /* 1110 */
232 ARM_COND_NV = 0xf, /* 1111 */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700233} ArmConditionCode;
234
235#define isPseudoOpCode(opCode) ((int)(opCode) < 0)
236
237/*
238 * The following enum defines the list of supported Thumb instructions by the
239 * assembler. Their corresponding snippet positions will be defined in
240 * Assemble.c.
241 */
242typedef enum ArmOpCode {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700243 ARM_PSEUDO_IT_BOTTOM = -17,
Ben Cheng4238ec22009-08-24 16:32:22 -0700244 ARM_PSEUDO_EXTENDED_MIR = -16,
245 ARM_PSEUDO_SSA_REP = -15,
246 ARM_PSEUDO_ENTRY_BLOCK = -14,
247 ARM_PSEUDO_EXIT_BLOCK = -13,
Jeff Hao97319a82009-08-12 16:57:15 -0700248 ARM_PSEUDO_TARGET_LABEL = -12,
249 ARM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -11,
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700250 ARM_PSEUDO_CHAINING_CELL_HOT = -10,
251 ARM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
252 ARM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
253 ARM_PSEUDO_CHAINING_CELL_NORMAL = -7,
254 ARM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
255 ARM_PSEUDO_ALIGN4 = -5,
256 ARM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
257 ARM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
258 ARM_PSEUDO_EH_BLOCK_LABEL = -2,
259 ARM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
260 /************************************************************************/
261 ARM_16BIT_DATA, /* DATA [0] rd[15..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700262 THUMB_ADC_RR, /* adc [0100000101] rm[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700263 THUMB_ADD_RRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
264 THUMB_ADD_RI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
265 THUMB_ADD_RRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
266 THUMB_ADD_RR_LH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
267 THUMB_ADD_RR_HL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
268 THUMB_ADD_RR_HH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
269 THUMB_ADD_PC_REL, /* add(5) [10100] rd[10..8] imm_8[7..0] */
270 THUMB_ADD_SP_REL, /* add(6) [10101] rd[10..8] imm_8[7..0] */
271 THUMB_ADD_SPI7, /* add(7) [101100000] imm_7[6..0] */
272 THUMB_AND_RR, /* and [0100000000] rm[5..3] rd[2..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700273 THUMB_ASR_RRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
274 THUMB_ASR_RR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700275 THUMB_B_COND, /* b(1) [1101] cond[11..8] offset_8[7..0] */
276 THUMB_B_UNCOND, /* b(2) [11100] offset_11[10..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700277 THUMB_BIC_RR, /* bic [0100001110] rm[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700278 THUMB_BKPT, /* bkpt [10111110] imm_8[7..0] */
279 THUMB_BLX_1, /* blx(1) [111] H[10] offset_11[10..0] */
280 THUMB_BLX_2, /* blx(1) [111] H[01] offset_11[10..0] */
281 THUMB_BL_1, /* blx(1) [111] H[10] offset_11[10..0] */
282 THUMB_BL_2, /* blx(1) [111] H[11] offset_11[10..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700283 THUMB_BLX_R, /* blx(2) [010001111] rm[6..3] [000] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700284 THUMB_BX, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700285 THUMB_CMN_RR, /* cmn [0100001011] rm[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700286 THUMB_CMP_RI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
287 THUMB_CMP_RR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
288 THUMB_CMP_LH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
289 THUMB_CMP_HL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
290 THUMB_CMP_HH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700291 THUMB_EOR_RR, /* eor [0100000001] rm[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700292 THUMB_LDMIA, /* ldmia [11001] rn[10..8] reglist [7..0] */
293 THUMB_LDR_RRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
294 THUMB_LDR_RRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
295 THUMB_LDR_PC_REL, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
296 THUMB_LDR_SP_REL, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
297 THUMB_LDRB_RRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
298 THUMB_LDRB_RRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
299 THUMB_LDRH_RRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
300 THUMB_LDRH_RRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
301 THUMB_LDRSB_RRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
302 THUMB_LDRSH_RRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700303 THUMB_LSL_RRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
304 THUMB_LSL_RR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
305 THUMB_LSR_RRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
306 THUMB_LSR_RR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700307 THUMB_MOV_IMM, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
308 THUMB_MOV_RR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
309 THUMB_MOV_RR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
310 THUMB_MOV_RR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
311 THUMB_MOV_RR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
312 THUMB_MUL, /* mul [0100001101] rm[5..3] rd[2..0] */
313 THUMB_MVN, /* mvn [0100001111] rm[5..3] rd[2..0] */
314 THUMB_NEG, /* neg [0100001001] rm[5..3] rd[2..0] */
315 THUMB_ORR, /* orr [0100001100] rm[5..3] rd[2..0] */
316 THUMB_POP, /* pop [1011110] r[8..8] rl[7..0] */
317 THUMB_PUSH, /* push [1011010] r[8..8] rl[7..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700318 THUMB_ROR_RR, /* ror [0100000111] rs[5..3] rd[2..0] */
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700319 THUMB_SBC, /* sbc [0100000110] rm[5..3] rd[2..0] */
320 THUMB_STMIA, /* stmia [11000] rn[10..8] reglist [7.. 0] */
321 THUMB_STR_RRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
322 THUMB_STR_RRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
323 THUMB_STR_SP_REL, /* str(3) [10010] rd[10..8] imm_8[7..0] */
324 THUMB_STRB_RRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
325 THUMB_STRB_RRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
326 THUMB_STRH_RRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
327 THUMB_STRH_RRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
328 THUMB_SUB_RRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
329 THUMB_SUB_RI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
330 THUMB_SUB_RRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
331 THUMB_SUB_SPI7, /* sub(4) [101100001] imm_7[6..0] */
332 THUMB_SWI, /* swi [11011111] imm_8[7..0] */
333 THUMB_TST, /* tst [0100001000] rm[5..3] rn[2..0] */
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700334 THUMB2_VLDRS, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
335 [1010] imm_8[7..0] */
336 THUMB2_VLDRD, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
337 [1011] imm_8[7..0] */
338 THUMB2_VMULS, /* vmul vd, vn, vm [111011100010] rn[19..16]
339 rd[15-12] [10100000] rm[3..0] */
340 THUMB2_VMULD, /* vmul vd, vn, vm [111011100010] rn[19..16]
341 rd[15-12] [10110000] rm[3..0] */
342 THUMB2_VSTRS, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
343 [1010] imm_8[7..0] */
344 THUMB2_VSTRD, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
345 [1011] imm_8[7..0] */
346 THUMB2_VSUBS, /* vsub vd, vn, vm [111011100011] rn[19..16]
347 rd[15-12] [10100040] rm[3..0] */
348 THUMB2_VSUBD, /* vsub vd, vn, vm [111011100011] rn[19..16]
349 rd[15-12] [10110040] rm[3..0] */
350 THUMB2_VADDS, /* vadd vd, vn, vm [111011100011] rn[19..16]
351 rd[15-12] [10100000] rm[3..0] */
352 THUMB2_VADDD, /* vadd vd, vn, vm [111011100011] rn[19..16]
353 rd[15-12] [10110000] rm[3..0] */
354 THUMB2_VDIVS, /* vdiv vd, vn, vm [111011101000] rn[19..16]
355 rd[15-12] [10100000] rm[3..0] */
356 THUMB2_VDIVD, /* vdiv vd, vn, vm [111011101000] rn[19..16]
357 rd[15-12] [10110000] rm[3..0] */
358 THUMB2_VCVTIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
359 [10101100] vm[3..0] */
360 THUMB2_VCVTID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
361 [10111100] vm[3..0] */
362 THUMB2_VCVTFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
363 [10101100] vm[3..0] */
364 THUMB2_VCVTDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
365 [10111100] vm[3..0] */
366 THUMB2_VCVTFD, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
367 [10101100] vm[3..0] */
368 THUMB2_VCVTDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
369 [10111100] vm[3..0] */
Bill Buzbee9727c3d2009-08-01 11:32:36 -0700370 THUMB2_VSQRTS, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
371 [10101100] vm[3..0] */
372 THUMB2_VSQRTD, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
373 [10111100] vm[3..0] */
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700374 THUMB2_MOV_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00001001111]
375 imm3 rd[11..8] imm8 */
376 THUMB2_MOV_IMM16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
377 imm3 rd[11..8] imm8 */
378 THUMB2_STR_RRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
379 rn[19..16] rt[15..12] imm12[11..0] */
380 THUMB2_LDR_RRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
381 rn[19..16] rt[15..12] imm12[11..0] */
382 THUMB2_STR_RRI8_PREDEC, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
383 rn[19..16] rt[15..12] [1100] imm[7..0]*/
384 THUMB2_LDR_RRI8_PREDEC, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
385 rn[19..16] rt[15..12] [1100] imm[7..0]*/
Bill Buzbee270c1d62009-08-13 16:58:07 -0700386 THUMB2_CBNZ, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700387 rn[2..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700388 THUMB2_CBZ, /* cbn rd,<label> [101100] i [1] imm5[7..3]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700389 rn[2..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700390 THUMB2_ADD_RRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700391 [0] imm3[14..12] rd[11..8] imm8[7..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700392 THUMB2_MOV_RR, /* mov rd, rm [11101010010011110000] rd[11..8]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700393 [0000] rm[3..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700394 THUMB2_VMOVS, /* vmov.f32 vd, vm [111011101] D [110000]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700395 vd[15..12] 101001] M [0] vm[3..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700396 THUMB2_VMOVD, /* vmov.f64 vd, vm [111011101] D [110000]
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700397 vd[15..12] 101101] M [0] vm[3..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700398 THUMB2_LDMIA, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
399 THUMB2_STMIA, /* stmia [111010001000[ rn[19..16] mask[15..0] */
400 THUMB2_ADD_RRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
401 [0000] rm[3..0] */
402 THUMB2_SUB_RRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
403 [0000] rm[3..0] */
404 THUMB2_SBC_RRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
405 [0000] rm[3..0] */
406 THUMB2_CMP_RR, /* cmp [111010111011] rn[19..16] [0000] [1111]
407 [0000] rm[3..0] */
408 THUMB2_SUB_RRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
409 [0] imm3[14..12] rd[11..8] imm8[7..0] */
410 THUMB2_MVN_IMM_SHIFT, /* mov(T2) rd, #<const> [11110] i [00011011110]
411 imm3 rd[11..8] imm8 */
412 THUMB2_SEL, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
413 rm[3-0] */
414 THUMB2_UBFX, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
415 [0] imm3[14-12] rd[11-8] w[4-0] */
416 THUMB2_SBFX, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
417 [0] imm3[14-12] rd[11-8] w[4-0] */
418 THUMB2_LDR_RRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
419 rt[15-12] [000000] imm[5-4] rm[3-0] */
420 THUMB2_LDRH_RRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
421 rt[15-12] [000000] imm[5-4] rm[3-0] */
422 THUMB2_LDRSH_RRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
423 rt[15-12] [000000] imm[5-4] rm[3-0] */
424 THUMB2_LDRB_RRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
425 rt[15-12] [000000] imm[5-4] rm[3-0] */
426 THUMB2_LDRSB_RRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
427 rt[15-12] [000000] imm[5-4] rm[3-0] */
428 THUMB2_STR_RRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
429 rt[15-12] [000000] imm[5-4] rm[3-0] */
430 THUMB2_STRH_RRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
431 rt[15-12] [000000] imm[5-4] rm[3-0] */
432 THUMB2_STRB_RRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
433 rt[15-12] [000000] imm[5-4] rm[3-0] */
434 THUMB2_LDRH_RRI12, /* ldrh rt,[rn,#imm12] [111110001011]
435 rt[15..12] rn[19..16] imm12[11..0] */
436 THUMB2_LDRSH_RRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
437 rt[15..12] rn[19..16] imm12[11..0] */
438 THUMB2_LDRB_RRI12, /* ldrb rt,[rn,#imm12] [111110001001]
439 rt[15..12] rn[19..16] imm12[11..0] */
440 THUMB2_LDRSB_RRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
441 rt[15..12] rn[19..16] imm12[11..0] */
442 THUMB2_STRH_RRI12, /* strh rt,[rn,#imm12] [111110001010]
443 rt[15..12] rn[19..16] imm12[11..0] */
444 THUMB2_STRB_RRI12, /* strb rt,[rn,#imm12] [111110001000]
445 rt[15..12] rn[19..16] imm12[11..0] */
446 THUMB2_POP, /* pop [1110100010111101] list[15-0]*/
447 THUMB2_PUSH, /* push [1110100010101101] list[15-0]*/
448 THUMB2_CMP_RI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
449 imm3 [1111] imm8[7..0] */
450 THUMB2_ADC_RRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
451 [0000] rm[3..0] */
452 THUMB2_AND_RRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
453 [0000] rm[3..0] */
454 THUMB2_BIC_RRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
455 [0000] rm[3..0] */
456 THUMB2_CMN_RR, /* cmn [111010110001] rn[19..16] [0000] [1111]
457 [0000] rm[3..0] */
458 THUMB2_EOR_RRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
459 [0000] rm[3..0] */
460 THUMB2_MUL_RRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
461 [0000] rm[3..0] */
462 THUMB2_MVN_RR, /* mvn [11101010011011110] rd[11-8] [0000]
463 rm[3..0] */
464 THUMB2_RSUB_RRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
465 imm8[7..0] */
466 THUMB2_NEG_RR, /* actually rsub rd, rn, #0 */
467 THUMB2_ORR_RRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
468 [0000] rm[3..0] */
469 THUMB2_TST_RR, /* tst [111010100001] rn[19..16] [0000] [1111]
470 [0000] rm[3..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700471 THUMB2_LSL_RRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
Bill Buzbee270c1d62009-08-13 16:58:07 -0700472 [0000] rm[3..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700473 THUMB2_LSR_RRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
Bill Buzbee270c1d62009-08-13 16:58:07 -0700474 [0000] rm[3..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700475 THUMB2_ASR_RRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
Bill Buzbee270c1d62009-08-13 16:58:07 -0700476 [0000] rm[3..0] */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700477 THUMB2_ROR_RRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
Bill Buzbee270c1d62009-08-13 16:58:07 -0700478 [0000] rm[3..0] */
479 THUMB2_LSL_RRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
480 [00] rm[3..0] */
481 THUMB2_LSR_RRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
482 [01] rm[3..0] */
483 THUMB2_ASR_RRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
484 [10] rm[3..0] */
485 THUMB2_ROR_RRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
486 [11] rm[3..0] */
487 THUMB2_BIC_RRI8, /* bic [111100000010] rn[19..16] [0] imm3
488 rd[11..8] imm8 */
489 THUMB2_AND_RRI8, /* bic [111100000000] rn[19..16] [0] imm3
490 rd[11..8] imm8 */
491 THUMB2_ORR_RRI8, /* orr [111100000100] rn[19..16] [0] imm3
492 rd[11..8] imm8 */
493 THUMB2_EOR_RRI8, /* eor [111100001000] rn[19..16] [0] imm3
494 rd[11..8] imm8 */
495 THUMB2_ADD_RRI8, /* add [111100001000] rn[19..16] [0] imm3
496 rd[11..8] imm8 */
497 THUMB2_ADC_RRI8, /* adc [111100010101] rn[19..16] [0] imm3
498 rd[11..8] imm8 */
499 THUMB2_SUB_RRI8, /* sub [111100011011] rn[19..16] [0] imm3
500 rd[11..8] imm8 */
501 THUMB2_SBC_RRI8, /* sbc [111100010111] rn[19..16] [0] imm3
502 rd[11..8] imm8 */
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700503 THUMB2_IT, /* it [10111111] firstcond[7-4] mask[3-0] */
504 THUMB2_FMSTAT, /* fmstat [11101110111100011111101000010000] */
Bill Buzbee7fb2edd2009-08-31 10:25:55 -0700505 THUMB2_VCMPD, /* vcmp [111011101] D [11011] rd[15-12] [1011]
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700506 E [1] M [0] rm[3-0] */
Bill Buzbee7fb2edd2009-08-31 10:25:55 -0700507 THUMB2_VCMPS, /* vcmp [111011101] D [11010] rd[15-12] [1011]
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700508 E [1] M [0] rm[3-0] */
509 THUMB2_LDR_PC_REL12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
510 imm12[11-0] */
511 THUMB2_B_COND, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
512 J1 [0] J2 imm11[10..0] */
Bill Buzbee7fb2edd2009-08-31 10:25:55 -0700513 THUMB2_VMOVD_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
514 M [0] vm[3-0] */
515 THUMB2_VMOVS_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
516 M [0] vm[3-0] */
517 THUMB2_FMRS, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
518 N [0010000] */
519 THUMB2_FMSR, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
520 N [0010000] */
521 THUMB2_FMRRD, /* vmov [111011000100] rt2[19-16] rt[15-12]
522 [101100] M [1] vm[3-0] */
523 THUMB2_FMDRR, /* vmov [111011000101] rt2[19-16] rt[15-12]
524 [101100] M [1] vm[3-0] */
525
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700526 ARM_LAST,
527} ArmOpCode;
528
529/* Bit flags describing the behavior of each native opcode */
530typedef enum ArmOpFeatureFlags {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700531 kIsBranch = 0,
532 kRegDef0,
533 kRegDef1,
534 kRegDefSP,
535 kRegDefList0,
536 kRegDefList1,
537 kRegUse0,
538 kRegUse1,
539 kRegUse2,
540 kRegUseSP,
541 kRegUsePC,
542 kRegUseList0,
543 kRegUseList1,
544 kNoOperand,
545 kIsUnaryOp,
546 kIsBinaryOp,
547 kIsTertiaryOp,
548 kIsQuadOp,
549 kIsIT,
550 kSetsCCodes,
551 kUsesCCodes,
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700552} ArmOpFeatureFlags;
553
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700554#define IS_BRANCH (1 << kIsBranch)
555#define REG_DEF0 (1 << kRegDef0)
556#define REG_DEF1 (1 << kRegDef1)
557#define REG_DEF_SP (1 << kRegDefSP)
558#define REG_DEF_LIST0 (1 << kRegDefList0)
559#define REG_DEF_LIST1 (1 << kRegDefList1)
560#define REG_USE0 (1 << kRegUse0)
561#define REG_USE1 (1 << kRegUse1)
562#define REG_USE2 (1 << kRegUse2)
563#define REG_USE_PC (1 << kRegUsePC)
564#define REG_USE_SP (1 << kRegUseSP)
565#define REG_USE_LIST0 (1 << kRegUseList0)
566#define REG_USE_LIST1 (1 << kRegUseList1)
567#define NO_OPERAND (1 << kNoOperand)
568#define IS_UNARY_OP (1 << kIsUnaryOp)
569#define IS_BINARY_OP (1 << kIsBinaryOp)
570#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
571#define IS_QUAD_OP (1 << kIsQuadOp)
572#define IS_IT (1 << kIsIT)
573#define SETS_CCODES (1 << kSetsCCodes)
574#define USES_CCODES (1 << kUsesCCodes)
575
576/* Common combo register usage patterns */
577#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
578#define REG_DEF0_USE01 (REG_DEF0 | REG_USE0 | REG_USE1)
579#define REG_DEF0_USE12 (REG_DEF0 | REG_USE1 | REG_USE2)
580#define REG_USE01 (REG_USE0 | REG_USE1)
581#define REG_USE012 (REG_USE0 | REG_USE1 | REG_USE2)
582
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700583/* Instruction assembly fieldLoc kind */
584typedef enum ArmEncodingKind {
585 UNUSED,
586 BITBLT, /* Bit string using end/start */
587 DFP, /* Double FP reg */
588 SFP, /* Single FP reg */
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700589 MODIMM, /* Shifted 8-bit immediate using [26,14..12,7..0] */
590 IMM16, /* Zero-extended immediate using [26,19..16,14..12,7..0] */
591 IMM6, /* Encoded branch target using [9,7..3]0 */
592 IMM12, /* Zero-extended immediate using [26,14..12,7..0] */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700593 SHIFT, /* Shift descriptor, [14..12,7..4] */
594 LSB, /* least significant bit using [14..12][7..6] */
595 BWIDTH, /* bit-field width, encoded as width-1 */
596 SHIFT5, /* Shift count, [14..12,7..6] */
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700597 BROFFSET, /* Signed extended [26,11,13,21-16,10-0]:0 */
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700598} ArmEncodingKind;
599
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700600/* Struct used to define the snippet positions for each Thumb opcode */
601typedef struct ArmEncodingMap {
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700602 u4 skeleton;
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700603 struct {
Bill Buzbee9bc3df32009-07-30 10:52:29 -0700604 ArmEncodingKind kind;
605 int end; /* end for BITBLT, 1-bit slice end for FP regs */
606 int start; /* start for BITBLT, 4-bit slice end for FP regs */
Bill Buzbee270c1d62009-08-13 16:58:07 -0700607 } fieldLoc[4];
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700608 ArmOpCode opCode;
609 int flags;
610 char *name;
611 char* fmt;
612 int size;
613} ArmEncodingMap;
614
615extern ArmEncodingMap EncodingMap[ARM_LAST];
616
617/*
618 * Each instance of this struct holds a pseudo or real LIR instruction:
619 * - pesudo ones (eg labels and marks) and will be discarded by the assembler.
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700620 * - real ones will be assembled into Thumb instructions.
621 *
622 * Machine resources are encoded into a 64-bit vector, where the encodings are
623 * as following:
624 * - [ 0..15]: general purpose registers including PC, SP, and LR
625 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
626 * starts at bit 16
627 * - [48]: IT block
628 * - [49]: integer condition code
629 * - [50]: floatint-point status word
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700630 */
631typedef struct ArmLIR {
632 LIR generic;
633 ArmOpCode opCode;
Bill Buzbee270c1d62009-08-13 16:58:07 -0700634 int operands[4]; // [0..3] = [dest, src1, src2, extra]
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700635 bool isNop; // LIR is optimized away
636 int age; // default is 0, set lazily by the optimizer
637 int size; // 16-bit unit size (1 for thumb, 1 or 2 for thumb2)
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700638 u8 useMask; // Resource mask for use
639 u8 defMask; // Resource mask for def
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700640} ArmLIR;
641
642/* Chain cell for predicted method invocation */
643typedef struct PredictedChainingCell {
644 u4 branch; /* Branch to chained destination */
645 const ClassObject *clazz; /* key #1 for prediction */
646 const Method *method; /* key #2 to lookup native PC from dalvik PC */
647 u4 counter; /* counter to patch the chaining cell */
648} PredictedChainingCell;
649
650/* Init values when a predicted chain is initially assembled */
651#define PREDICTED_CHAIN_BX_PAIR_INIT 0
652#define PREDICTED_CHAIN_CLAZZ_INIT 0
653#define PREDICTED_CHAIN_METHOD_INIT 0
654#define PREDICTED_CHAIN_COUNTER_INIT 0
655
656/* Used when the callee is not compiled yet */
657#define PREDICTED_CHAIN_COUNTER_DELAY 16
658
659/* Rechain after this many mis-predictions have happened */
660#define PREDICTED_CHAIN_COUNTER_RECHAIN 1024
661
662/* Used if the resolved callee is a native method */
663#define PREDICTED_CHAIN_COUNTER_AVOID 0x7fffffff
664
665/* Utility macros to traverse the LIR/ArmLIR list */
666#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
667#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
668
669#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
670#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
671
672#define CHAIN_CELL_OFFSET_TAG 0xcdab
673
Bill Buzbee270c1d62009-08-13 16:58:07 -0700674ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc);
675
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700676#endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */