blob: 407ad793c05d3f820664e316f5dd886fe8ef807b [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) */
buzbee2cfc6392012-05-07 14:51:40 -0700128#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
129 INVALID_SREG, INVALID_SREG}
130#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1, \
131 INVALID_SREG, INVALID_SREG}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700132#define LOC_C_RETURN_FLOAT LOC_C_RETURN
133#define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE
buzbee67bf8852011-08-17 17:51:35 -0700134
Elliott Hughes719ace42012-03-09 18:06:03 -0800135enum ResourceEncodingPos {
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 kGPReg0 = 0,
137 kRegSP = 13,
138 kRegLR = 14,
139 kRegPC = 15,
140 kFPReg0 = 16,
141 kFPReg16 = 32,
142 kRegEnd = 48,
143 kCCode = kRegEnd,
144 kFPStatus, // FP status word
145 // The following four bits are for memory disambiguation
146 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
147 kLiteral, // 2 Literal pool (can be fully disambiguated)
148 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
149 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800150};
buzbee67bf8852011-08-17 17:51:35 -0700151
152#define ENCODE_REG_LIST(N) ((u8) N)
153#define ENCODE_REG_SP (1ULL << kRegSP)
154#define ENCODE_REG_LR (1ULL << kRegLR)
155#define ENCODE_REG_PC (1ULL << kRegPC)
156#define ENCODE_CCODE (1ULL << kCCode)
157#define ENCODE_FP_STATUS (1ULL << kFPStatus)
158#define ENCODE_REG_FPCS_LIST(N) ((u8)N << kFPReg16)
159
160/* Abstract memory locations */
161#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
162#define ENCODE_LITERAL (1ULL << kLiteral)
163#define ENCODE_HEAP_REF (1ULL << kHeapRef)
164#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
165
166#define ENCODE_ALL (~0ULL)
167#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
Bill Buzbeea114add2012-05-03 15:00:40 -0700168 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
buzbee67bf8852011-08-17 17:51:35 -0700169
170#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
171#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
172
buzbee67bf8852011-08-17 17:51:35 -0700173/*
174 * Annotate special-purpose core registers:
buzbee67bf8852011-08-17 17:51:35 -0700175 * - ARM architecture: r13sp, r14lr, and r15pc
176 *
177 * rPC, rFP, and rSELF are for architecture-independent code to use.
178 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800179enum NativeRegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 r0 = 0,
181 r1 = 1,
182 r2 = 2,
183 r3 = 3,
184 rSUSPEND = 4,
185 r5 = 5,
186 r6 = 6,
187 r7 = 7,
188 r8 = 8,
189 rSELF = 9,
190 r10 = 10,
191 r11 = 11,
192 r12 = 12,
193 r13sp = 13,
194 rSP = 13,
195 r14lr = 14,
196 rLR = 14,
197 r15pc = 15,
198 rPC = 15,
199 fr0 = 0 + FP_REG_OFFSET,
200 fr1 = 1 + FP_REG_OFFSET,
201 fr2 = 2 + FP_REG_OFFSET,
202 fr3 = 3 + FP_REG_OFFSET,
203 fr4 = 4 + FP_REG_OFFSET,
204 fr5 = 5 + FP_REG_OFFSET,
205 fr6 = 6 + FP_REG_OFFSET,
206 fr7 = 7 + FP_REG_OFFSET,
207 fr8 = 8 + FP_REG_OFFSET,
208 fr9 = 9 + FP_REG_OFFSET,
209 fr10 = 10 + FP_REG_OFFSET,
210 fr11 = 11 + FP_REG_OFFSET,
211 fr12 = 12 + FP_REG_OFFSET,
212 fr13 = 13 + FP_REG_OFFSET,
213 fr14 = 14 + FP_REG_OFFSET,
214 fr15 = 15 + FP_REG_OFFSET,
215 fr16 = 16 + FP_REG_OFFSET,
216 fr17 = 17 + FP_REG_OFFSET,
217 fr18 = 18 + FP_REG_OFFSET,
218 fr19 = 19 + FP_REG_OFFSET,
219 fr20 = 20 + FP_REG_OFFSET,
220 fr21 = 21 + FP_REG_OFFSET,
221 fr22 = 22 + FP_REG_OFFSET,
222 fr23 = 23 + FP_REG_OFFSET,
223 fr24 = 24 + FP_REG_OFFSET,
224 fr25 = 25 + FP_REG_OFFSET,
225 fr26 = 26 + FP_REG_OFFSET,
226 fr27 = 27 + FP_REG_OFFSET,
227 fr28 = 28 + FP_REG_OFFSET,
228 fr29 = 29 + FP_REG_OFFSET,
229 fr30 = 30 + FP_REG_OFFSET,
230 fr31 = 31 + FP_REG_OFFSET,
231 dr0 = fr0 + FP_DOUBLE,
232 dr1 = fr2 + FP_DOUBLE,
233 dr2 = fr4 + FP_DOUBLE,
234 dr3 = fr6 + FP_DOUBLE,
235 dr4 = fr8 + FP_DOUBLE,
236 dr5 = fr10 + FP_DOUBLE,
237 dr6 = fr12 + FP_DOUBLE,
238 dr7 = fr14 + FP_DOUBLE,
239 dr8 = fr16 + FP_DOUBLE,
240 dr9 = fr18 + FP_DOUBLE,
241 dr10 = fr20 + FP_DOUBLE,
242 dr11 = fr22 + FP_DOUBLE,
243 dr12 = fr24 + FP_DOUBLE,
244 dr13 = fr26 + FP_DOUBLE,
245 dr14 = fr28 + FP_DOUBLE,
246 dr15 = fr30 + FP_DOUBLE,
Elliott Hughes719ace42012-03-09 18:06:03 -0800247};
buzbee67bf8852011-08-17 17:51:35 -0700248
buzbee31a4a6f2012-02-28 15:36:15 -0800249/* Target-independent aliases */
250#define rARG0 r0
251#define rARG1 r1
252#define rARG2 r2
253#define rARG3 r3
jeffhao30a33172012-10-22 18:16:22 -0700254#define rFARG0 r0
255#define rFARG1 r1
256#define rFARG2 r2
257#define rFARG3 r3
buzbee31a4a6f2012-02-28 15:36:15 -0800258#define rRET0 r0
259#define rRET1 r1
buzbee0398c422012-03-02 15:22:47 -0800260#define rINVOKE_TGT rLR
buzbeeb046e162012-10-30 15:48:42 -0700261#define rCOUNT INVALID_REG
buzbee31a4a6f2012-02-28 15:36:15 -0800262
buzbee67bf8852011-08-17 17:51:35 -0700263/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800264enum ArmShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700265 kArmLsl = 0x0,
266 kArmLsr = 0x1,
267 kArmAsr = 0x2,
268 kArmRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800269};
buzbee67bf8852011-08-17 17:51:35 -0700270
buzbee67bf8852011-08-17 17:51:35 -0700271#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
272
273/*
274 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800275 * assembler. Their corresponding EncodingMap positions will be defined in
276 * Assemble.cc.
buzbee67bf8852011-08-17 17:51:35 -0700277 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800278enum ArmOpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 /************************************************************************/
buzbeeb046e162012-10-30 15:48:42 -0700280 kArmFirst = 0,
281 kArm16BitData = kArmFirst, /* DATA [0] rd[15..0] */
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
283 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
284 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
285 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
286 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
287 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
288 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
289 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
290 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
291 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
292 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
293 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
294 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
295 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
296 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
297 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
298 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
299 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
300 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
301 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
302 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
303 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
304 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
305 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
306 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
307 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
308 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
309 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
310 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
311 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
312 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
313 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
314 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
315 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
316 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
317 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
318 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
319 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
320 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
321 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
322 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
323 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
324 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
325 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
326 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
327 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
328 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
329 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
330 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
331 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
332 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
333 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
334 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
335 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
336 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
337 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
338 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
339 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
340 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
341 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
342 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
343 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
344 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
345 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
346 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
347 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
348 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
349 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
350 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
351 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
352 kThumbSwi, /* swi [11011111] imm_8[7..0] */
353 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
354 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
355 [1010] imm_8[7..0] */
356 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
357 [1011] imm_8[7..0] */
358 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
359 rd[15-12] [10100000] rm[3..0] */
360 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
361 rd[15-12] [10110000] rm[3..0] */
362 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
363 [1010] imm_8[7..0] */
364 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
365 [1011] imm_8[7..0] */
366 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
367 rd[15-12] [10100040] rm[3..0] */
368 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
369 rd[15-12] [10110040] rm[3..0] */
370 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
371 rd[15-12] [10100000] rm[3..0] */
372 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
373 rd[15-12] [10110000] rm[3..0] */
374 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
375 rd[15-12] [10100000] rm[3..0] */
376 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
377 rd[15-12] [10110000] rm[3..0] */
378 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
379 [10101100] vm[3..0] */
380 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
381 [10111100] vm[3..0] */
382 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
383 [10101100] vm[3..0] */
384 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
385 [10111100] vm[3..0] */
386 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
387 [10101100] vm[3..0] */
388 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
389 [10111100] vm[3..0] */
390 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
391 [10101100] vm[3..0] */
392 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
393 [10111100] vm[3..0] */
394 kThumb2MovImmShift,/* mov(T2) rd, #<const> [11110] i [00001001111]
395 imm3 rd[11..8] imm8 */
396 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
397 imm3 rd[11..8] imm8 */
398 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
399 rn[19..16] rt[15..12] imm12[11..0] */
400 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
401 rn[19..16] rt[15..12] imm12[11..0] */
402 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
403 rn[19..16] rt[15..12] [1100] imm[7..0]*/
404 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
405 rn[19..16] rt[15..12] [1100] imm[7..0]*/
406 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
407 rn[2..0] */
408 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
409 rn[2..0] */
410 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
411 [0] imm3[14..12] rd[11..8] imm8[7..0] */
412 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
413 [0000] rm[3..0] */
414 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
415 vd[15..12] 101001] M [0] vm[3..0] */
416 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
417 vd[15..12] 101101] M [0] vm[3..0] */
418 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
419 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
420 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
421 [0000] rm[3..0] */
422 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
423 [0000] rm[3..0] */
424 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
425 [0000] rm[3..0] */
426 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
427 [0000] rm[3..0] */
428 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
429 [0] imm3[14..12] rd[11..8] imm8[7..0] */
430 kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110]
431 imm3 rd[11..8] imm8 */
432 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
433 rm[3-0] */
434 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
435 [0] imm3[14-12] rd[11-8] w[4-0] */
436 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
437 [0] imm3[14-12] rd[11-8] w[4-0] */
438 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
439 rt[15-12] [000000] imm[5-4] rm[3-0] */
440 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
441 rt[15-12] [000000] imm[5-4] rm[3-0] */
442 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
443 rt[15-12] [000000] imm[5-4] rm[3-0] */
444 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
445 rt[15-12] [000000] imm[5-4] rm[3-0] */
446 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
447 rt[15-12] [000000] imm[5-4] rm[3-0] */
448 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
449 rt[15-12] [000000] imm[5-4] rm[3-0] */
450 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
451 rt[15-12] [000000] imm[5-4] rm[3-0] */
452 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
453 rt[15-12] [000000] imm[5-4] rm[3-0] */
454 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
455 rt[15..12] rn[19..16] imm12[11..0] */
456 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
457 rt[15..12] rn[19..16] imm12[11..0] */
458 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
459 rt[15..12] rn[19..16] imm12[11..0] */
460 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
461 rt[15..12] rn[19..16] imm12[11..0] */
462 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
463 rt[15..12] rn[19..16] imm12[11..0] */
464 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
465 rt[15..12] rn[19..16] imm12[11..0] */
466 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
467 kThumb2Push, /* push [1110100100101101] list[15-0]*/
468 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
469 imm3 [1111] imm8[7..0] */
470 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
471 [0000] rm[3..0] */
472 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
473 [0000] rm[3..0] */
474 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
475 [0000] rm[3..0] */
476 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
477 [0000] rm[3..0] */
478 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
479 [0000] rm[3..0] */
480 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
481 [0000] rm[3..0] */
482 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
483 rm[3..0] */
484 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
485 imm8[7..0] */
486 kThumb2NegRR, /* actually rsub rd, rn, #0 */
487 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
488 [0000] rm[3..0] */
489 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
490 [0000] rm[3..0] */
491 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
492 [0000] rm[3..0] */
493 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
494 [0000] rm[3..0] */
495 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
496 [0000] rm[3..0] */
497 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
498 [0000] rm[3..0] */
499 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
500 [00] rm[3..0] */
501 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
502 [01] rm[3..0] */
503 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
504 [10] rm[3..0] */
505 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
506 [11] rm[3..0] */
507 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
508 rd[11..8] imm8 */
509 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
510 rd[11..8] imm8 */
511 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
512 rd[11..8] imm8 */
513 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
514 rd[11..8] imm8 */
515 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
516 rd[11..8] imm8 */
517 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
518 rd[11..8] imm8 */
519 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
520 rd[11..8] imm8 */
521 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
522 rd[11..8] imm8 */
523 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
524 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
525 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
526 E [1] M [0] rm[3-0] */
527 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
528 E [1] M [0] rm[3-0] */
529 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
530 imm12[11-0] */
531 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
532 J1 [0] J2 imm11[10..0] */
533 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
534 M [0] vm[3-0] */
535 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
536 M [0] vm[3-0] */
537 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
538 N [0010000] */
539 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
540 N [0010000] */
541 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
542 [101100] M [1] vm[3-0] */
543 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
544 [101100] M [1] vm[3-0] */
545 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
546 [1011110] M [0] vm[3-0] */
547 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
548 [1010110] M [0] vm[3-0] */
549 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
550 [1011110] M [0] vm[3-0] */
551 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
552 [1010110] M [0] vm[3-0] */
553 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
554 [10100000] imm4l[3-0] */
555 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
556 [10110000] imm4l[3-0] */
557 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
558 [0000] rm[3-0] */
559 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
560 rdhi[11-8] [0000] rm[3-0] */
561 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
562 imm8[7-0] */
563 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
564 imm8[7-0] */
565 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
566 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
567 rd[11-8] imm2[7-6] [0] msb[4-0] */
568 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
569 rd[11-8] imm2[7-6] [0] msb[4-0] */
570 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
571 kThumb2LdrPcReln12,/* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
572 imm12[11-0] */
573 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
574 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
575 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
576 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
577 kThumb2Vldms, /* vldms rd, <list> */
578 kThumb2Vstms, /* vstms rd, <list> */
579 kThumb2BUncond, /* b <label> */
580 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
581 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
582 kThumb2Adr, /* Special purpose encoding of ADR for switch tables */
583 kThumb2MovImm16LST,/* Special purpose version for switch table use */
584 kThumb2MovImm16HST,/* Special purpose version for switch table use */
585 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
586 kThumb2SubsRRI12, /* setflags encoding */
587 kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
588 [0000] rm[3..0] */
589 kThumb2Push1, /* t3 encoding of push */
590 kThumb2Pop1, /* t3 encoding of pop */
591 kThumb2RsubRRR, /* rsb [111010111101] rn[19..16] [0000] rd[11..8]
592 [0000] rm[3..0] */
593 kThumb2Smull, /* smull [111110111000] rn[19-16], rdlo[15-12]
594 rdhi[11-8] [0000] rm[3-0] */
595 kArmLast,
Elliott Hughes719ace42012-03-09 18:06:03 -0800596};
buzbee67bf8852011-08-17 17:51:35 -0700597
598/* DMB option encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800599enum ArmOpDmbOptions {
Bill Buzbeea114add2012-05-03 15:00:40 -0700600 kSY = 0xf,
601 kST = 0xe,
602 kISH = 0xb,
603 kISHST = 0xa,
604 kNSH = 0x7,
605 kNSHST = 0x6
Elliott Hughes719ace42012-03-09 18:06:03 -0800606};
buzbee67bf8852011-08-17 17:51:35 -0700607
608/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800609enum ArmOpFeatureFlags {
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 kIsBranch = 0,
611 kRegDef0,
612 kRegDef1,
613 kRegDefSP,
614 kRegDefLR,
615 kRegDefList0,
616 kRegDefList1,
617 kRegDefFPCSList0,
618 kRegDefFPCSList2,
619 kRegDefList2,
620 kRegUse0,
621 kRegUse1,
622 kRegUse2,
623 kRegUse3,
624 kRegUseSP,
625 kRegUsePC,
626 kRegUseList0,
627 kRegUseList1,
628 kRegUseFPCSList0,
629 kRegUseFPCSList2,
630 kNoOperand,
631 kIsUnaryOp,
632 kIsBinaryOp,
633 kIsTertiaryOp,
634 kIsQuadOp,
635 kIsIT,
636 kSetsCCodes,
637 kUsesCCodes,
638 kMemLoad,
639 kMemStore,
640 kPCRelFixup,
Elliott Hughes719ace42012-03-09 18:06:03 -0800641};
buzbee67bf8852011-08-17 17:51:35 -0700642
643#define IS_LOAD (1 << kMemLoad)
644#define IS_STORE (1 << kMemStore)
645#define IS_BRANCH (1 << kIsBranch)
646#define REG_DEF0 (1 << kRegDef0)
647#define REG_DEF1 (1 << kRegDef1)
648#define REG_DEF_SP (1 << kRegDefSP)
649#define REG_DEF_LR (1 << kRegDefLR)
650#define REG_DEF_LIST0 (1 << kRegDefList0)
651#define REG_DEF_LIST1 (1 << kRegDefList1)
652#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
653#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
654#define REG_USE0 (1 << kRegUse0)
655#define REG_USE1 (1 << kRegUse1)
656#define REG_USE2 (1 << kRegUse2)
657#define REG_USE3 (1 << kRegUse3)
658#define REG_USE_SP (1 << kRegUseSP)
659#define REG_USE_PC (1 << kRegUsePC)
660#define REG_USE_LIST0 (1 << kRegUseList0)
661#define REG_USE_LIST1 (1 << kRegUseList1)
662#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
663#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
664#define NO_OPERAND (1 << kNoOperand)
665#define IS_UNARY_OP (1 << kIsUnaryOp)
666#define IS_BINARY_OP (1 << kIsBinaryOp)
667#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
668#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800669#define IS_QUIN_OP 0
buzbee67bf8852011-08-17 17:51:35 -0700670#define IS_IT (1 << kIsIT)
671#define SETS_CCODES (1 << kSetsCCodes)
672#define USES_CCODES (1 << kUsesCCodes)
buzbee5abfa3e2012-01-31 17:01:43 -0800673#define NEEDS_FIXUP (1 << kPCRelFixup)
buzbee67bf8852011-08-17 17:51:35 -0700674
675/* Common combo register usage patterns */
676#define REG_USE01 (REG_USE0 | REG_USE1)
677#define REG_USE012 (REG_USE01 | REG_USE2)
678#define REG_USE12 (REG_USE1 | REG_USE2)
679#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
680#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
681#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
682#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
683#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
684
685/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800686enum ArmEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700687 kFmtUnused,
688 kFmtBitBlt, /* Bit string using end/start */
689 kFmtDfp, /* Double FP reg */
690 kFmtSfp, /* Single FP reg */
691 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
692 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
693 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
694 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
695 kFmtShift, /* Shift descriptor, [14..12,7..4] */
696 kFmtLsb, /* least significant bit using [14..12][7..6] */
697 kFmtBWidth, /* bit-field width, encoded as width-1 */
698 kFmtShift5, /* Shift count, [14..12,7..6] */
699 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
700 kFmtFPImm, /* Encoded floating point immediate */
701 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
Elliott Hughes719ace42012-03-09 18:06:03 -0800702};
buzbee67bf8852011-08-17 17:51:35 -0700703
704/* Struct used to define the snippet positions for each Thumb opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800705struct ArmEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700706 u4 skeleton;
707 struct {
708 ArmEncodingKind kind;
709 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
710 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
711 } fieldLoc[4];
712 ArmOpcode opcode;
713 int flags;
714 const char* name;
715 const char* fmt;
716 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800717};
buzbee67bf8852011-08-17 17:51:35 -0700718
719/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800720enum ArmTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700721 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800722};
buzbee67bf8852011-08-17 17:51:35 -0700723
buzbeeba938cb2012-02-03 14:47:55 -0800724extern const ArmEncodingMap EncodingMap[kArmLast];
buzbee67bf8852011-08-17 17:51:35 -0700725
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800726} // namespace art
727
buzbee67bf8852011-08-17 17:51:35 -0700728#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_