blob: bc85dd85e015b8270e5122593fce67ddb7ed2f20 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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#ifndef ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
18#define ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
19
20#include "../../Dalvik.h"
21#include "../../CompilerInternals.h"
22
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080023namespace art {
24
buzbeec0ecd652011-09-25 18:11:54 -070025// Set to 1 to measure cost of suspend check
26#define NO_SUSPEND 0
27
buzbee67bf8852011-08-17 17:51:35 -070028/*
29 * Runtime register usage conventions.
30 *
31 * r0-r3: Argument registers in both Dalvik and C/C++ conventions.
32 * However, for Dalvik->Dalvik calls we'll pass the target's Method*
33 * pointer in r0 as a hidden arg0. Otherwise used as codegen scratch
34 * registers.
35 * r0-r1: As in C/C++ r0 is 32-bit return register and r0/r1 is 64-bit
buzbee44b412b2012-02-04 08:50:53 -080036 * r4 : (rSUSPEND) is reserved (suspend check/debugger assist)
buzbee67bf8852011-08-17 17:51:35 -070037 * r5 : Callee save (promotion target)
38 * r6 : Callee save (promotion target)
39 * r7 : Callee save (promotion target)
40 * r8 : Callee save (promotion target)
41 * r9 : (rSELF) is reserved (pointer to thread-local storage)
42 * r10 : Callee save (promotion target)
43 * r11 : Callee save (promotion target)
44 * r12 : Scratch, may be trashed by linkage stubs
45 * r13 : (sp) is reserved
46 * r14 : (lr) is reserved
47 * r15 : (pc) is reserved
48 *
49 * 5 core temps that codegen can use (r0, r1, r2, r3, r12)
50 * 7 core registers that can be used for promotion
51 *
52 * Floating pointer registers
53 * s0-s31
54 * d0-d15, where d0={s0,s1}, d1={s2,s3}, ... , d15={s30,s31}
55 *
56 * s16-s31 (d8-d15) preserved across C calls
57 * s0-s15 (d0-d7) trashed across C calls
58 *
59 * s0-s15/d0-d7 used as codegen temp/scratch
60 * s16-s31/d8-d31 can be used for promotion.
61 *
62 * Calling convention
63 * o On a call to a Dalvik method, pass target's Method* in r0
64 * o r1-r3 will be used for up to the first 3 words of arguments
65 * o Arguments past the first 3 words will be placed in appropriate
66 * out slots by the caller.
67 * o If a 64-bit argument would span the register/memory argument
68 * boundary, it will instead be fully passed in the frame.
69 * o Maintain a 16-byte stack alignment
70 *
71 * Stack frame diagram (stack grows down, higher addresses at top):
72 *
73 * +------------------------+
74 * | IN[ins-1] | {Note: resides in caller's frame}
75 * | . |
76 * | IN[0] |
77 * | caller's Method* |
78 * +========================+ {Note: start of callee's frame}
79 * | spill region | {variable sized - will include lr if non-leaf.}
80 * +------------------------+
81 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
82 * +------------------------+
83 * | V[locals-1] |
84 * | V[locals-2] |
85 * | . |
86 * | . |
87 * | V[1] |
88 * | V[0] |
89 * +------------------------+
90 * | 0 to 3 words padding |
91 * +------------------------+
92 * | OUT[outs-1] |
93 * | OUT[outs-2] |
94 * | . |
95 * | OUT[0] |
96 * | curMethod* | <<== sp w/ 16-byte alignment
97 * +========================+
98 */
99
100/* Offset to distingish FP regs */
101#define FP_REG_OFFSET 32
102/* Offset to distinguish DP FP regs */
103#define FP_DOUBLE 64
buzbeebbaf8942011-10-02 13:08:29 -0700104/* First FP callee save */
105#define FP_CALLEE_SAVE_BASE 16
buzbee67bf8852011-08-17 17:51:35 -0700106/* Reg types */
107#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
108#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
109#define LOWREG(x) ((x & 0x7) == x)
110#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
111#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
112/*
113 * Note: the low register of a floating point pair is sufficient to
114 * create the name of a double, but require both names to be passed to
115 * allow for asserts to verify that the pair is consecutive if significant
116 * rework is done in this area. Also, it is a good reminder in the calling
117 * code that reg locations always describe doubles as a pair of singles.
118 */
119#define S2D(x,y) ((x) | FP_DOUBLE)
120/* Mask to strip off fp flags */
121#define FP_REG_MASK (FP_REG_OFFSET-1)
122/* non-existent Dalvik register */
123#define vNone (-1)
124/* non-existant physical register */
125#define rNone (-1)
126
127/* RegisterLocation templates return values (r0, or r0/r1) */
buzbeee3acd072012-02-25 17:03:10 -0800128#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
129 INVALID_SREG}
buzbee67bc2362011-10-11 18:08:40 -0700130#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r0, r1, INVALID_SREG}
buzbee67bf8852011-08-17 17:51:35 -0700131
132typedef enum ResourceEncodingPos {
133 kGPReg0 = 0,
134 kRegSP = 13,
135 kRegLR = 14,
136 kRegPC = 15,
137 kFPReg0 = 16,
138 kFPReg16 = 32,
139 kRegEnd = 48,
140 kCCode = kRegEnd,
141 kFPStatus, // FP status word
142 // The following four bits are for memory disambiguation
143 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
144 kLiteral, // 2 Literal pool (can be fully disambiguated)
145 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
146 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
147} ResourceEncodingPos;
148
149#define ENCODE_REG_LIST(N) ((u8) N)
150#define ENCODE_REG_SP (1ULL << kRegSP)
151#define ENCODE_REG_LR (1ULL << kRegLR)
152#define ENCODE_REG_PC (1ULL << kRegPC)
153#define ENCODE_CCODE (1ULL << kCCode)
154#define ENCODE_FP_STATUS (1ULL << kFPStatus)
155#define ENCODE_REG_FPCS_LIST(N) ((u8)N << kFPReg16)
156
157/* Abstract memory locations */
158#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
159#define ENCODE_LITERAL (1ULL << kLiteral)
160#define ENCODE_HEAP_REF (1ULL << kHeapRef)
161#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
162
163#define ENCODE_ALL (~0ULL)
164#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
165 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
166
167#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
168#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
169
buzbee67bf8852011-08-17 17:51:35 -0700170/*
171 * Annotate special-purpose core registers:
buzbeec1f45042011-09-21 16:03:19 -0700172 * - VM: r6SELF
buzbee67bf8852011-08-17 17:51:35 -0700173 * - ARM architecture: r13sp, r14lr, and r15pc
174 *
175 * rPC, rFP, and rSELF are for architecture-independent code to use.
176 */
177typedef enum NativeRegisterPool {
178 r0 = 0,
179 r1 = 1,
180 r2 = 2,
181 r3 = 3,
buzbeec1f45042011-09-21 16:03:19 -0700182 rSUSPEND = 4,
buzbee67bf8852011-08-17 17:51:35 -0700183 r5 = 5,
184 r6 = 6,
185 r7 = 7,
186 r8 = 8,
187 rSELF = 9,
188 r10 = 10,
189 r11 = 11,
190 r12 = 12,
191 r13sp = 13,
192 rSP = 13,
193 r14lr = 14,
194 rLR = 14,
195 r15pc = 15,
196 rPC = 15,
197 fr0 = 0 + FP_REG_OFFSET,
198 fr1 = 1 + FP_REG_OFFSET,
199 fr2 = 2 + FP_REG_OFFSET,
200 fr3 = 3 + FP_REG_OFFSET,
201 fr4 = 4 + FP_REG_OFFSET,
202 fr5 = 5 + FP_REG_OFFSET,
203 fr6 = 6 + FP_REG_OFFSET,
204 fr7 = 7 + FP_REG_OFFSET,
205 fr8 = 8 + FP_REG_OFFSET,
206 fr9 = 9 + FP_REG_OFFSET,
207 fr10 = 10 + FP_REG_OFFSET,
208 fr11 = 11 + FP_REG_OFFSET,
209 fr12 = 12 + FP_REG_OFFSET,
210 fr13 = 13 + FP_REG_OFFSET,
211 fr14 = 14 + FP_REG_OFFSET,
212 fr15 = 15 + FP_REG_OFFSET,
213 fr16 = 16 + FP_REG_OFFSET,
214 fr17 = 17 + FP_REG_OFFSET,
215 fr18 = 18 + FP_REG_OFFSET,
216 fr19 = 19 + FP_REG_OFFSET,
217 fr20 = 20 + FP_REG_OFFSET,
218 fr21 = 21 + FP_REG_OFFSET,
219 fr22 = 22 + FP_REG_OFFSET,
220 fr23 = 23 + FP_REG_OFFSET,
221 fr24 = 24 + FP_REG_OFFSET,
222 fr25 = 25 + FP_REG_OFFSET,
223 fr26 = 26 + FP_REG_OFFSET,
224 fr27 = 27 + FP_REG_OFFSET,
225 fr28 = 28 + FP_REG_OFFSET,
226 fr29 = 29 + FP_REG_OFFSET,
227 fr30 = 30 + FP_REG_OFFSET,
228 fr31 = 31 + FP_REG_OFFSET,
229 dr0 = fr0 + FP_DOUBLE,
230 dr1 = fr2 + FP_DOUBLE,
231 dr2 = fr4 + FP_DOUBLE,
232 dr3 = fr6 + FP_DOUBLE,
233 dr4 = fr8 + FP_DOUBLE,
234 dr5 = fr10 + FP_DOUBLE,
235 dr6 = fr12 + FP_DOUBLE,
236 dr7 = fr14 + FP_DOUBLE,
237 dr8 = fr16 + FP_DOUBLE,
238 dr9 = fr18 + FP_DOUBLE,
239 dr10 = fr20 + FP_DOUBLE,
240 dr11 = fr22 + FP_DOUBLE,
241 dr12 = fr24 + FP_DOUBLE,
242 dr13 = fr26 + FP_DOUBLE,
243 dr14 = fr28 + FP_DOUBLE,
244 dr15 = fr30 + FP_DOUBLE,
245} NativeRegisterPool;
246
buzbee31a4a6f2012-02-28 15:36:15 -0800247/* Target-independent aliases */
248#define rARG0 r0
249#define rARG1 r1
250#define rARG2 r2
251#define rARG3 r3
252#define rRET0 r0
253#define rRET1 r1
buzbee0398c422012-03-02 15:22:47 -0800254#define rINVOKE_TGT rLR
buzbee31a4a6f2012-02-28 15:36:15 -0800255
buzbee67bf8852011-08-17 17:51:35 -0700256/* Shift encodings */
257typedef enum ArmShiftEncodings {
258 kArmLsl = 0x0,
259 kArmLsr = 0x1,
260 kArmAsr = 0x2,
261 kArmRor = 0x3
262} ArmShiftEncodings;
263
264/* Thumb condition encodings */
265typedef enum ArmConditionCode {
266 kArmCondEq = 0x0, /* 0000 */
267 kArmCondNe = 0x1, /* 0001 */
268 kArmCondCs = 0x2, /* 0010 */
269 kArmCondCc = 0x3, /* 0011 */
270 kArmCondMi = 0x4, /* 0100 */
271 kArmCondPl = 0x5, /* 0101 */
272 kArmCondVs = 0x6, /* 0110 */
273 kArmCondVc = 0x7, /* 0111 */
274 kArmCondHi = 0x8, /* 1000 */
275 kArmCondLs = 0x9, /* 1001 */
276 kArmCondGe = 0xa, /* 1010 */
277 kArmCondLt = 0xb, /* 1011 */
278 kArmCondGt = 0xc, /* 1100 */
279 kArmCondLe = 0xd, /* 1101 */
280 kArmCondAl = 0xe, /* 1110 */
281 kArmCondNv = 0xf, /* 1111 */
282} ArmConditionCode;
283
284#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
285
286/*
287 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800288 * assembler. Their corresponding EncodingMap positions will be defined in
289 * Assemble.cc.
buzbee67bf8852011-08-17 17:51:35 -0700290 */
291typedef enum ArmOpcode {
buzbee31a4a6f2012-02-28 15:36:15 -0800292 kPseudoSuspendTarget = -15,
293 kPseudoThrowTarget = -14,
294 kPseudoCaseLabel = -13,
295 kPseudoMethodEntry = -12,
296 kPseudoMethodExit = -11,
297 kPseudoBarrier = -10,
298 kPseudoExtended = -9,
299 kPseudoSSARep = -8,
300 kPseudoEntryBlock = -7,
301 kPseudoExitBlock = -6,
302 kPseudoTargetLabel = -5,
303 kPseudoDalvikByteCodeBoundary = -4,
304 kPseudoPseudoAlign4 = -3,
305 kPseudoEHBlockLabel = -2,
306 kPseudoNormalBlockLabel = -1,
buzbee67bf8852011-08-17 17:51:35 -0700307 /************************************************************************/
308 kArm16BitData, /* DATA [0] rd[15..0] */
309 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
310 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
311 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
312 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
313 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
314 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
315 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
316 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
317 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
318 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
319 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
320 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
321 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
322 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
323 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
324 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
325 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
326 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
327 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
328 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
329 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
330 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
331 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
332 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
333 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
334 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
335 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
336 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
337 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
338 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
339 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
340 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
341 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
342 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
343 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
344 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
345 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
346 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
347 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
348 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
349 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
350 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
351 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
352 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
353 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
354 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
355 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
356 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
357 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
358 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
359 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
360 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
361 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
362 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
363 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
364 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
365 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
366 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
367 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
368 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
369 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
370 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
371 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
372 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
373 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
374 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
375 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
376 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
377 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
378 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
379 kThumbSwi, /* swi [11011111] imm_8[7..0] */
380 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
381 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
382 [1010] imm_8[7..0] */
383 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
384 [1011] imm_8[7..0] */
385 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
386 rd[15-12] [10100000] rm[3..0] */
387 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
388 rd[15-12] [10110000] rm[3..0] */
389 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
390 [1010] imm_8[7..0] */
391 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
392 [1011] imm_8[7..0] */
393 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
394 rd[15-12] [10100040] rm[3..0] */
395 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
396 rd[15-12] [10110040] rm[3..0] */
397 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
398 rd[15-12] [10100000] rm[3..0] */
399 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
400 rd[15-12] [10110000] rm[3..0] */
401 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
402 rd[15-12] [10100000] rm[3..0] */
403 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
404 rd[15-12] [10110000] rm[3..0] */
405 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
406 [10101100] vm[3..0] */
407 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
408 [10111100] vm[3..0] */
409 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
410 [10101100] vm[3..0] */
411 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
412 [10111100] vm[3..0] */
413 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
414 [10101100] vm[3..0] */
415 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
416 [10111100] vm[3..0] */
417 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
418 [10101100] vm[3..0] */
419 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
420 [10111100] vm[3..0] */
421 kThumb2MovImmShift, /* mov(T2) rd, #<const> [11110] i [00001001111]
422 imm3 rd[11..8] imm8 */
423 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
424 imm3 rd[11..8] imm8 */
425 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
426 rn[19..16] rt[15..12] imm12[11..0] */
427 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
428 rn[19..16] rt[15..12] imm12[11..0] */
429 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
430 rn[19..16] rt[15..12] [1100] imm[7..0]*/
431 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
432 rn[19..16] rt[15..12] [1100] imm[7..0]*/
433 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
434 rn[2..0] */
435 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
436 rn[2..0] */
437 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
438 [0] imm3[14..12] rd[11..8] imm8[7..0] */
439 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
440 [0000] rm[3..0] */
441 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
442 vd[15..12] 101001] M [0] vm[3..0] */
443 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
444 vd[15..12] 101101] M [0] vm[3..0] */
445 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
446 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
447 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
448 [0000] rm[3..0] */
449 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
450 [0000] rm[3..0] */
451 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
452 [0000] rm[3..0] */
453 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
454 [0000] rm[3..0] */
455 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
456 [0] imm3[14..12] rd[11..8] imm8[7..0] */
buzbee58f92742011-10-01 11:22:17 -0700457 kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110]
buzbee67bf8852011-08-17 17:51:35 -0700458 imm3 rd[11..8] imm8 */
459 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
460 rm[3-0] */
461 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
462 [0] imm3[14-12] rd[11-8] w[4-0] */
463 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
464 [0] imm3[14-12] rd[11-8] w[4-0] */
465 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
466 rt[15-12] [000000] imm[5-4] rm[3-0] */
467 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
468 rt[15-12] [000000] imm[5-4] rm[3-0] */
469 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
470 rt[15-12] [000000] imm[5-4] rm[3-0] */
471 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
472 rt[15-12] [000000] imm[5-4] rm[3-0] */
473 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
474 rt[15-12] [000000] imm[5-4] rm[3-0] */
475 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
476 rt[15-12] [000000] imm[5-4] rm[3-0] */
477 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
478 rt[15-12] [000000] imm[5-4] rm[3-0] */
479 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
480 rt[15-12] [000000] imm[5-4] rm[3-0] */
481 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
482 rt[15..12] rn[19..16] imm12[11..0] */
483 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
484 rt[15..12] rn[19..16] imm12[11..0] */
485 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
486 rt[15..12] rn[19..16] imm12[11..0] */
487 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
488 rt[15..12] rn[19..16] imm12[11..0] */
489 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
490 rt[15..12] rn[19..16] imm12[11..0] */
491 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
492 rt[15..12] rn[19..16] imm12[11..0] */
493 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
494 kThumb2Push, /* push [1110100100101101] list[15-0]*/
495 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
496 imm3 [1111] imm8[7..0] */
497 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
498 [0000] rm[3..0] */
499 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
500 [0000] rm[3..0] */
501 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
502 [0000] rm[3..0] */
503 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
504 [0000] rm[3..0] */
505 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
506 [0000] rm[3..0] */
507 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
508 [0000] rm[3..0] */
509 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
510 rm[3..0] */
511 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
512 imm8[7..0] */
513 kThumb2NegRR, /* actually rsub rd, rn, #0 */
514 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
515 [0000] rm[3..0] */
516 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
517 [0000] rm[3..0] */
518 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
519 [0000] rm[3..0] */
520 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
521 [0000] rm[3..0] */
522 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
523 [0000] rm[3..0] */
524 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
525 [0000] rm[3..0] */
526 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
527 [00] rm[3..0] */
528 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
529 [01] rm[3..0] */
530 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
531 [10] rm[3..0] */
532 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
533 [11] rm[3..0] */
534 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
535 rd[11..8] imm8 */
536 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
537 rd[11..8] imm8 */
538 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
539 rd[11..8] imm8 */
540 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
541 rd[11..8] imm8 */
542 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
543 rd[11..8] imm8 */
544 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
545 rd[11..8] imm8 */
546 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
547 rd[11..8] imm8 */
548 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
549 rd[11..8] imm8 */
550 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
551 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
552 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
553 E [1] M [0] rm[3-0] */
554 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
555 E [1] M [0] rm[3-0] */
556 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
557 imm12[11-0] */
558 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
559 J1 [0] J2 imm11[10..0] */
560 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
561 M [0] vm[3-0] */
562 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
563 M [0] vm[3-0] */
564 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
565 N [0010000] */
566 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
567 N [0010000] */
568 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
569 [101100] M [1] vm[3-0] */
570 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
571 [101100] M [1] vm[3-0] */
572 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
573 [1011110] M [0] vm[3-0] */
574 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
575 [1010110] M [0] vm[3-0] */
576 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
577 [1011110] M [0] vm[3-0] */
578 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
579 [1010110] M [0] vm[3-0] */
580 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
581 [10100000] imm4l[3-0] */
582 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
583 [10110000] imm4l[3-0] */
584 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
585 [0000] rm[3-0] */
586 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
587 rdhi[11-8] [0000] rm[3-0] */
588 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
589 imm8[7-0] */
590 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
591 imm8[7-0] */
592 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
593 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
594 rd[11-8] imm2[7-6] [0] msb[4-0] */
595 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
596 rd[11-8] imm2[7-6] [0] msb[4-0] */
597 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
598 kThumb2LdrPcReln12, /* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
599 imm12[11-0] */
600 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
601 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
602 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
603 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
604 kThumb2Vldms, /* vldms rd, <list> */
605 kThumb2Vstms, /* vstms rd, <list> */
606 kThumb2BUncond, /* b <label> */
607 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
608 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
buzbee03fa2632011-09-20 17:10:57 -0700609 kThumb2Adr, /* Special purpose encoding of ADR for switch tables */
buzbee67bf8852011-08-17 17:51:35 -0700610 kThumb2MovImm16LST, /* Special purpose version for switch table use */
611 kThumb2MovImm16HST, /* Special purpose version for switch table use */
612 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
613 kThumb2SubsRRI12, /* setflags encoding */
buzbee58f92742011-10-01 11:22:17 -0700614 kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
615 [0000] rm[3..0] */
buzbeee7070802011-10-09 17:56:06 -0700616 kThumb2Push1, /* t3 encoding of push */
617 kThumb2Pop1, /* t3 encoding of pop */
buzbee67bf8852011-08-17 17:51:35 -0700618 kArmLast,
619} ArmOpcode;
620
621/* DMB option encodings */
622typedef enum ArmOpDmbOptions {
623 kSY = 0xf,
624 kST = 0xe,
625 kISH = 0xb,
626 kISHST = 0xa,
627 kNSH = 0x7,
628 kNSHST = 0x6
629} ArmOpDmbOptions;
630
631/* Bit flags describing the behavior of each native opcode */
632typedef enum ArmOpFeatureFlags {
633 kIsBranch = 0,
634 kRegDef0,
635 kRegDef1,
636 kRegDefSP,
637 kRegDefLR,
638 kRegDefList0,
639 kRegDefList1,
640 kRegDefFPCSList0,
641 kRegDefFPCSList2,
642 kRegDefList2,
643 kRegUse0,
644 kRegUse1,
645 kRegUse2,
646 kRegUse3,
647 kRegUseSP,
648 kRegUsePC,
649 kRegUseList0,
650 kRegUseList1,
651 kRegUseFPCSList0,
652 kRegUseFPCSList2,
653 kNoOperand,
654 kIsUnaryOp,
655 kIsBinaryOp,
656 kIsTertiaryOp,
657 kIsQuadOp,
658 kIsIT,
659 kSetsCCodes,
660 kUsesCCodes,
661 kMemLoad,
662 kMemStore,
buzbee5abfa3e2012-01-31 17:01:43 -0800663 kPCRelFixup,
buzbee67bf8852011-08-17 17:51:35 -0700664} ArmOpFeatureFlags;
665
666#define IS_LOAD (1 << kMemLoad)
667#define IS_STORE (1 << kMemStore)
668#define IS_BRANCH (1 << kIsBranch)
669#define REG_DEF0 (1 << kRegDef0)
670#define REG_DEF1 (1 << kRegDef1)
671#define REG_DEF_SP (1 << kRegDefSP)
672#define REG_DEF_LR (1 << kRegDefLR)
673#define REG_DEF_LIST0 (1 << kRegDefList0)
674#define REG_DEF_LIST1 (1 << kRegDefList1)
675#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
676#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
677#define REG_USE0 (1 << kRegUse0)
678#define REG_USE1 (1 << kRegUse1)
679#define REG_USE2 (1 << kRegUse2)
680#define REG_USE3 (1 << kRegUse3)
681#define REG_USE_SP (1 << kRegUseSP)
682#define REG_USE_PC (1 << kRegUsePC)
683#define REG_USE_LIST0 (1 << kRegUseList0)
684#define REG_USE_LIST1 (1 << kRegUseList1)
685#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
686#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
687#define NO_OPERAND (1 << kNoOperand)
688#define IS_UNARY_OP (1 << kIsUnaryOp)
689#define IS_BINARY_OP (1 << kIsBinaryOp)
690#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
691#define IS_QUAD_OP (1 << kIsQuadOp)
692#define IS_IT (1 << kIsIT)
693#define SETS_CCODES (1 << kSetsCCodes)
694#define USES_CCODES (1 << kUsesCCodes)
buzbee5abfa3e2012-01-31 17:01:43 -0800695#define NEEDS_FIXUP (1 << kPCRelFixup)
buzbee67bf8852011-08-17 17:51:35 -0700696
697/* Common combo register usage patterns */
698#define REG_USE01 (REG_USE0 | REG_USE1)
699#define REG_USE012 (REG_USE01 | REG_USE2)
700#define REG_USE12 (REG_USE1 | REG_USE2)
701#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
702#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
703#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
704#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
705#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
706
707/* Instruction assembly fieldLoc kind */
708typedef enum ArmEncodingKind {
709 kFmtUnused,
710 kFmtBitBlt, /* Bit string using end/start */
711 kFmtDfp, /* Double FP reg */
712 kFmtSfp, /* Single FP reg */
713 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
714 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
715 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
716 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
717 kFmtShift, /* Shift descriptor, [14..12,7..4] */
718 kFmtLsb, /* least significant bit using [14..12][7..6] */
719 kFmtBWidth, /* bit-field width, encoded as width-1 */
720 kFmtShift5, /* Shift count, [14..12,7..6] */
721 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
722 kFmtFPImm, /* Encoded floating point immediate */
723 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
724} ArmEncodingKind;
725
726/* Struct used to define the snippet positions for each Thumb opcode */
727typedef struct ArmEncodingMap {
728 u4 skeleton;
729 struct {
730 ArmEncodingKind kind;
731 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
732 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
733 } fieldLoc[4];
734 ArmOpcode opcode;
735 int flags;
736 const char* name;
737 const char* fmt;
buzbee71ac9942012-03-01 17:23:10 -0800738 int size; /* Size in bytes */
buzbee67bf8852011-08-17 17:51:35 -0700739} ArmEncodingMap;
740
741/* Keys for target-specific scheduling and other optimization hints */
742typedef enum ArmTargetOptHints {
743 kMaxHoistDistance,
744} ArmTargetOptHints;
745
buzbeeba938cb2012-02-03 14:47:55 -0800746extern const ArmEncodingMap EncodingMap[kArmLast];
buzbee67bf8852011-08-17 17:51:35 -0700747
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800748} // namespace art
749
buzbee67bf8852011-08-17 17:51:35 -0700750#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_