blob: 05082ed8d89f1f323408ae5b66b738ee9d839599 [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
buzbee67bf8852011-08-17 17:51:35 -070025/*
26 * Runtime register usage conventions.
27 *
28 * r0-r3: Argument registers in both Dalvik and C/C++ conventions.
29 * However, for Dalvik->Dalvik calls we'll pass the target's Method*
30 * pointer in r0 as a hidden arg0. Otherwise used as codegen scratch
31 * registers.
32 * r0-r1: As in C/C++ r0 is 32-bit return register and r0/r1 is 64-bit
buzbee44b412b2012-02-04 08:50:53 -080033 * r4 : (rSUSPEND) is reserved (suspend check/debugger assist)
buzbee67bf8852011-08-17 17:51:35 -070034 * r5 : Callee save (promotion target)
35 * r6 : Callee save (promotion target)
36 * r7 : Callee save (promotion target)
37 * r8 : Callee save (promotion target)
38 * r9 : (rSELF) is reserved (pointer to thread-local storage)
39 * r10 : Callee save (promotion target)
40 * r11 : Callee save (promotion target)
41 * r12 : Scratch, may be trashed by linkage stubs
42 * r13 : (sp) is reserved
43 * r14 : (lr) is reserved
44 * r15 : (pc) is reserved
45 *
46 * 5 core temps that codegen can use (r0, r1, r2, r3, r12)
47 * 7 core registers that can be used for promotion
48 *
49 * Floating pointer registers
50 * s0-s31
51 * d0-d15, where d0={s0,s1}, d1={s2,s3}, ... , d15={s30,s31}
52 *
53 * s16-s31 (d8-d15) preserved across C calls
54 * s0-s15 (d0-d7) trashed across C calls
55 *
56 * s0-s15/d0-d7 used as codegen temp/scratch
57 * s16-s31/d8-d31 can be used for promotion.
58 *
59 * Calling convention
60 * o On a call to a Dalvik method, pass target's Method* in r0
61 * o r1-r3 will be used for up to the first 3 words of arguments
62 * o Arguments past the first 3 words will be placed in appropriate
63 * out slots by the caller.
64 * o If a 64-bit argument would span the register/memory argument
65 * boundary, it will instead be fully passed in the frame.
66 * o Maintain a 16-byte stack alignment
67 *
68 * Stack frame diagram (stack grows down, higher addresses at top):
69 *
70 * +------------------------+
71 * | IN[ins-1] | {Note: resides in caller's frame}
72 * | . |
73 * | IN[0] |
74 * | caller's Method* |
75 * +========================+ {Note: start of callee's frame}
76 * | spill region | {variable sized - will include lr if non-leaf.}
77 * +------------------------+
78 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
79 * +------------------------+
80 * | V[locals-1] |
81 * | V[locals-2] |
82 * | . |
83 * | . |
84 * | V[1] |
85 * | V[0] |
86 * +------------------------+
87 * | 0 to 3 words padding |
88 * +------------------------+
89 * | OUT[outs-1] |
90 * | OUT[outs-2] |
91 * | . |
92 * | OUT[0] |
93 * | curMethod* | <<== sp w/ 16-byte alignment
94 * +========================+
95 */
96
97/* Offset to distingish FP regs */
98#define FP_REG_OFFSET 32
99/* Offset to distinguish DP FP regs */
100#define FP_DOUBLE 64
buzbeebbaf8942011-10-02 13:08:29 -0700101/* First FP callee save */
102#define FP_CALLEE_SAVE_BASE 16
buzbee67bf8852011-08-17 17:51:35 -0700103/* Reg types */
104#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
105#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
106#define LOWREG(x) ((x & 0x7) == x)
107#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
108#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
109/*
110 * Note: the low register of a floating point pair is sufficient to
111 * create the name of a double, but require both names to be passed to
112 * allow for asserts to verify that the pair is consecutive if significant
113 * rework is done in this area. Also, it is a good reminder in the calling
114 * code that reg locations always describe doubles as a pair of singles.
115 */
116#define S2D(x,y) ((x) | FP_DOUBLE)
117/* Mask to strip off fp flags */
118#define FP_REG_MASK (FP_REG_OFFSET-1)
119/* non-existent Dalvik register */
120#define vNone (-1)
121/* non-existant physical register */
122#define rNone (-1)
123
124/* RegisterLocation templates return values (r0, or r0/r1) */
buzbee2cfc6392012-05-07 14:51:40 -0700125#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
126 INVALID_SREG, INVALID_SREG}
127#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1, \
128 INVALID_SREG, INVALID_SREG}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700129#define LOC_C_RETURN_FLOAT LOC_C_RETURN
130#define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE
buzbee67bf8852011-08-17 17:51:35 -0700131
buzbee07131ca2012-11-07 16:13:14 -0800132enum ArmResourceEncodingPos {
133 kArmGPReg0 = 0,
134 kArmRegSP = 13,
135 kArmRegLR = 14,
136 kArmRegPC = 15,
137 kArmFPReg0 = 16,
138 kArmFPReg16 = 32,
139 kArmRegEnd = 48,
Elliott Hughes719ace42012-03-09 18:06:03 -0800140};
buzbee67bf8852011-08-17 17:51:35 -0700141
buzbee07131ca2012-11-07 16:13:14 -0800142#define ENCODE_ARM_REG_LIST(N) ((u8) N)
143#define ENCODE_ARM_REG_SP (1ULL << kArmRegSP)
144#define ENCODE_ARM_REG_LR (1ULL << kArmRegLR)
145#define ENCODE_ARM_REG_PC (1ULL << kArmRegPC)
146#define ENCODE_ARM_REG_FPCS_LIST(N) ((u8)N << kArmFPReg16)
buzbee67bf8852011-08-17 17:51:35 -0700147
buzbee67bf8852011-08-17 17:51:35 -0700148/*
149 * Annotate special-purpose core registers:
buzbee67bf8852011-08-17 17:51:35 -0700150 * - ARM architecture: r13sp, r14lr, and r15pc
151 *
152 * rPC, rFP, and rSELF are for architecture-independent code to use.
153 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800154enum NativeRegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 r0 = 0,
156 r1 = 1,
157 r2 = 2,
158 r3 = 3,
159 rSUSPEND = 4,
160 r5 = 5,
161 r6 = 6,
162 r7 = 7,
163 r8 = 8,
164 rSELF = 9,
165 r10 = 10,
166 r11 = 11,
167 r12 = 12,
168 r13sp = 13,
169 rSP = 13,
170 r14lr = 14,
171 rLR = 14,
172 r15pc = 15,
173 rPC = 15,
174 fr0 = 0 + FP_REG_OFFSET,
175 fr1 = 1 + FP_REG_OFFSET,
176 fr2 = 2 + FP_REG_OFFSET,
177 fr3 = 3 + FP_REG_OFFSET,
178 fr4 = 4 + FP_REG_OFFSET,
179 fr5 = 5 + FP_REG_OFFSET,
180 fr6 = 6 + FP_REG_OFFSET,
181 fr7 = 7 + FP_REG_OFFSET,
182 fr8 = 8 + FP_REG_OFFSET,
183 fr9 = 9 + FP_REG_OFFSET,
184 fr10 = 10 + FP_REG_OFFSET,
185 fr11 = 11 + FP_REG_OFFSET,
186 fr12 = 12 + FP_REG_OFFSET,
187 fr13 = 13 + FP_REG_OFFSET,
188 fr14 = 14 + FP_REG_OFFSET,
189 fr15 = 15 + FP_REG_OFFSET,
190 fr16 = 16 + FP_REG_OFFSET,
191 fr17 = 17 + FP_REG_OFFSET,
192 fr18 = 18 + FP_REG_OFFSET,
193 fr19 = 19 + FP_REG_OFFSET,
194 fr20 = 20 + FP_REG_OFFSET,
195 fr21 = 21 + FP_REG_OFFSET,
196 fr22 = 22 + FP_REG_OFFSET,
197 fr23 = 23 + FP_REG_OFFSET,
198 fr24 = 24 + FP_REG_OFFSET,
199 fr25 = 25 + FP_REG_OFFSET,
200 fr26 = 26 + FP_REG_OFFSET,
201 fr27 = 27 + FP_REG_OFFSET,
202 fr28 = 28 + FP_REG_OFFSET,
203 fr29 = 29 + FP_REG_OFFSET,
204 fr30 = 30 + FP_REG_OFFSET,
205 fr31 = 31 + FP_REG_OFFSET,
206 dr0 = fr0 + FP_DOUBLE,
207 dr1 = fr2 + FP_DOUBLE,
208 dr2 = fr4 + FP_DOUBLE,
209 dr3 = fr6 + FP_DOUBLE,
210 dr4 = fr8 + FP_DOUBLE,
211 dr5 = fr10 + FP_DOUBLE,
212 dr6 = fr12 + FP_DOUBLE,
213 dr7 = fr14 + FP_DOUBLE,
214 dr8 = fr16 + FP_DOUBLE,
215 dr9 = fr18 + FP_DOUBLE,
216 dr10 = fr20 + FP_DOUBLE,
217 dr11 = fr22 + FP_DOUBLE,
218 dr12 = fr24 + FP_DOUBLE,
219 dr13 = fr26 + FP_DOUBLE,
220 dr14 = fr28 + FP_DOUBLE,
221 dr15 = fr30 + FP_DOUBLE,
Elliott Hughes719ace42012-03-09 18:06:03 -0800222};
buzbee67bf8852011-08-17 17:51:35 -0700223
buzbee31a4a6f2012-02-28 15:36:15 -0800224/* Target-independent aliases */
225#define rARG0 r0
226#define rARG1 r1
227#define rARG2 r2
228#define rARG3 r3
jeffhao30a33172012-10-22 18:16:22 -0700229#define rFARG0 r0
230#define rFARG1 r1
231#define rFARG2 r2
232#define rFARG3 r3
buzbee31a4a6f2012-02-28 15:36:15 -0800233#define rRET0 r0
234#define rRET1 r1
buzbee0398c422012-03-02 15:22:47 -0800235#define rINVOKE_TGT rLR
buzbeeb046e162012-10-30 15:48:42 -0700236#define rCOUNT INVALID_REG
buzbee31a4a6f2012-02-28 15:36:15 -0800237
buzbee67bf8852011-08-17 17:51:35 -0700238/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800239enum ArmShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700240 kArmLsl = 0x0,
241 kArmLsr = 0x1,
242 kArmAsr = 0x2,
243 kArmRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800244};
buzbee67bf8852011-08-17 17:51:35 -0700245
buzbee67bf8852011-08-17 17:51:35 -0700246#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
247
248/*
249 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800250 * assembler. Their corresponding EncodingMap positions will be defined in
251 * Assemble.cc.
buzbee67bf8852011-08-17 17:51:35 -0700252 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800253enum ArmOpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700254 /************************************************************************/
buzbeeb046e162012-10-30 15:48:42 -0700255 kArmFirst = 0,
256 kArm16BitData = kArmFirst, /* DATA [0] rd[15..0] */
Bill Buzbeea114add2012-05-03 15:00:40 -0700257 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
258 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
259 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
260 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
261 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
262 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
263 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
264 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
265 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
266 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
267 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
268 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
269 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
270 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
271 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
272 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
273 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
274 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
275 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
276 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
277 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
278 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
279 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
280 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
281 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
282 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
283 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
284 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
285 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
286 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
287 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
288 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
289 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
290 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
291 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
292 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
293 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
294 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
295 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
296 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
297 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
298 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
299 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
300 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
301 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
302 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
303 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
304 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
305 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
306 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
307 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
308 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
309 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
310 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
311 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
312 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
313 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
314 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
315 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
316 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
317 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
318 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
319 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
320 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
321 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
322 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
323 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
324 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
325 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
326 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
327 kThumbSwi, /* swi [11011111] imm_8[7..0] */
328 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
329 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
330 [1010] imm_8[7..0] */
331 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
332 [1011] imm_8[7..0] */
333 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
334 rd[15-12] [10100000] rm[3..0] */
335 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
336 rd[15-12] [10110000] rm[3..0] */
337 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
338 [1010] imm_8[7..0] */
339 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
340 [1011] imm_8[7..0] */
341 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
342 rd[15-12] [10100040] rm[3..0] */
343 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
344 rd[15-12] [10110040] rm[3..0] */
345 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
346 rd[15-12] [10100000] rm[3..0] */
347 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
348 rd[15-12] [10110000] rm[3..0] */
349 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
350 rd[15-12] [10100000] rm[3..0] */
351 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
352 rd[15-12] [10110000] rm[3..0] */
353 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
354 [10101100] vm[3..0] */
355 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
356 [10111100] vm[3..0] */
357 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
358 [10101100] vm[3..0] */
359 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
360 [10111100] vm[3..0] */
361 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
362 [10101100] vm[3..0] */
363 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
364 [10111100] vm[3..0] */
365 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
366 [10101100] vm[3..0] */
367 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
368 [10111100] vm[3..0] */
369 kThumb2MovImmShift,/* mov(T2) rd, #<const> [11110] i [00001001111]
370 imm3 rd[11..8] imm8 */
371 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
372 imm3 rd[11..8] imm8 */
373 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
374 rn[19..16] rt[15..12] imm12[11..0] */
375 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
376 rn[19..16] rt[15..12] imm12[11..0] */
377 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
378 rn[19..16] rt[15..12] [1100] imm[7..0]*/
379 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
380 rn[19..16] rt[15..12] [1100] imm[7..0]*/
381 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
382 rn[2..0] */
383 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
384 rn[2..0] */
385 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
386 [0] imm3[14..12] rd[11..8] imm8[7..0] */
387 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
388 [0000] rm[3..0] */
389 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
390 vd[15..12] 101001] M [0] vm[3..0] */
391 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
392 vd[15..12] 101101] M [0] vm[3..0] */
393 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
394 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
395 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
396 [0000] rm[3..0] */
397 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
398 [0000] rm[3..0] */
399 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
400 [0000] rm[3..0] */
401 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
402 [0000] rm[3..0] */
403 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
404 [0] imm3[14..12] rd[11..8] imm8[7..0] */
405 kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110]
406 imm3 rd[11..8] imm8 */
407 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
408 rm[3-0] */
409 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
410 [0] imm3[14-12] rd[11-8] w[4-0] */
411 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
412 [0] imm3[14-12] rd[11-8] w[4-0] */
413 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
414 rt[15-12] [000000] imm[5-4] rm[3-0] */
415 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
416 rt[15-12] [000000] imm[5-4] rm[3-0] */
417 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
418 rt[15-12] [000000] imm[5-4] rm[3-0] */
419 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
420 rt[15-12] [000000] imm[5-4] rm[3-0] */
421 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
422 rt[15-12] [000000] imm[5-4] rm[3-0] */
423 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
424 rt[15-12] [000000] imm[5-4] rm[3-0] */
425 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
426 rt[15-12] [000000] imm[5-4] rm[3-0] */
427 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
428 rt[15-12] [000000] imm[5-4] rm[3-0] */
429 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
430 rt[15..12] rn[19..16] imm12[11..0] */
431 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
432 rt[15..12] rn[19..16] imm12[11..0] */
433 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
434 rt[15..12] rn[19..16] imm12[11..0] */
435 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
436 rt[15..12] rn[19..16] imm12[11..0] */
437 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
438 rt[15..12] rn[19..16] imm12[11..0] */
439 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
440 rt[15..12] rn[19..16] imm12[11..0] */
441 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
442 kThumb2Push, /* push [1110100100101101] list[15-0]*/
443 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
444 imm3 [1111] imm8[7..0] */
445 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
446 [0000] rm[3..0] */
447 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
448 [0000] rm[3..0] */
449 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
450 [0000] rm[3..0] */
451 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
452 [0000] rm[3..0] */
453 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
454 [0000] rm[3..0] */
455 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
456 [0000] rm[3..0] */
457 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
458 rm[3..0] */
459 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
460 imm8[7..0] */
461 kThumb2NegRR, /* actually rsub rd, rn, #0 */
462 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
463 [0000] rm[3..0] */
464 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
465 [0000] rm[3..0] */
466 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
467 [0000] rm[3..0] */
468 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
469 [0000] rm[3..0] */
470 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
471 [0000] rm[3..0] */
472 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
473 [0000] rm[3..0] */
474 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
475 [00] rm[3..0] */
476 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
477 [01] rm[3..0] */
478 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
479 [10] rm[3..0] */
480 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
481 [11] rm[3..0] */
482 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
483 rd[11..8] imm8 */
484 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
485 rd[11..8] imm8 */
486 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
487 rd[11..8] imm8 */
488 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
489 rd[11..8] imm8 */
490 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
491 rd[11..8] imm8 */
492 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
493 rd[11..8] imm8 */
494 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
495 rd[11..8] imm8 */
496 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
497 rd[11..8] imm8 */
498 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
499 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
500 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
501 E [1] M [0] rm[3-0] */
502 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
503 E [1] M [0] rm[3-0] */
504 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
505 imm12[11-0] */
506 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
507 J1 [0] J2 imm11[10..0] */
508 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
509 M [0] vm[3-0] */
510 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
511 M [0] vm[3-0] */
512 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
513 N [0010000] */
514 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
515 N [0010000] */
516 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
517 [101100] M [1] vm[3-0] */
518 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
519 [101100] M [1] vm[3-0] */
520 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
521 [1011110] M [0] vm[3-0] */
522 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
523 [1010110] M [0] vm[3-0] */
524 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
525 [1011110] M [0] vm[3-0] */
526 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
527 [1010110] M [0] vm[3-0] */
528 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
529 [10100000] imm4l[3-0] */
530 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
531 [10110000] imm4l[3-0] */
532 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
533 [0000] rm[3-0] */
534 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
535 rdhi[11-8] [0000] rm[3-0] */
536 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
537 imm8[7-0] */
538 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
539 imm8[7-0] */
540 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
541 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
542 rd[11-8] imm2[7-6] [0] msb[4-0] */
543 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
544 rd[11-8] imm2[7-6] [0] msb[4-0] */
545 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
546 kThumb2LdrPcReln12,/* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
547 imm12[11-0] */
548 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
549 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
550 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
551 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
552 kThumb2Vldms, /* vldms rd, <list> */
553 kThumb2Vstms, /* vstms rd, <list> */
554 kThumb2BUncond, /* b <label> */
555 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
556 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
557 kThumb2Adr, /* Special purpose encoding of ADR for switch tables */
558 kThumb2MovImm16LST,/* Special purpose version for switch table use */
559 kThumb2MovImm16HST,/* Special purpose version for switch table use */
560 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
561 kThumb2SubsRRI12, /* setflags encoding */
562 kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
563 [0000] rm[3..0] */
564 kThumb2Push1, /* t3 encoding of push */
565 kThumb2Pop1, /* t3 encoding of pop */
566 kThumb2RsubRRR, /* rsb [111010111101] rn[19..16] [0000] rd[11..8]
567 [0000] rm[3..0] */
568 kThumb2Smull, /* smull [111110111000] rn[19-16], rdlo[15-12]
569 rdhi[11-8] [0000] rm[3-0] */
570 kArmLast,
Elliott Hughes719ace42012-03-09 18:06:03 -0800571};
buzbee67bf8852011-08-17 17:51:35 -0700572
573/* DMB option encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800574enum ArmOpDmbOptions {
Bill Buzbeea114add2012-05-03 15:00:40 -0700575 kSY = 0xf,
576 kST = 0xe,
577 kISH = 0xb,
578 kISHST = 0xa,
579 kNSH = 0x7,
580 kNSHST = 0x6
Elliott Hughes719ace42012-03-09 18:06:03 -0800581};
buzbee67bf8852011-08-17 17:51:35 -0700582
583/* Bit flags describing the behavior of each native opcode */
buzbee67bf8852011-08-17 17:51:35 -0700584/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800585enum ArmEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 kFmtUnused,
587 kFmtBitBlt, /* Bit string using end/start */
588 kFmtDfp, /* Double FP reg */
589 kFmtSfp, /* Single FP reg */
590 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
591 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
592 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
593 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
594 kFmtShift, /* Shift descriptor, [14..12,7..4] */
595 kFmtLsb, /* least significant bit using [14..12][7..6] */
596 kFmtBWidth, /* bit-field width, encoded as width-1 */
597 kFmtShift5, /* Shift count, [14..12,7..6] */
598 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
599 kFmtFPImm, /* Encoded floating point immediate */
600 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
Elliott Hughes719ace42012-03-09 18:06:03 -0800601};
buzbee67bf8852011-08-17 17:51:35 -0700602
603/* Struct used to define the snippet positions for each Thumb opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800604struct ArmEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700605 u4 skeleton;
606 struct {
607 ArmEncodingKind kind;
608 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
609 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
610 } fieldLoc[4];
611 ArmOpcode opcode;
buzbee07131ca2012-11-07 16:13:14 -0800612 uint64_t flags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700613 const char* name;
614 const char* fmt;
615 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800616};
buzbee67bf8852011-08-17 17:51:35 -0700617
618/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800619enum ArmTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700620 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800621};
buzbee67bf8852011-08-17 17:51:35 -0700622
buzbeeba938cb2012-02-03 14:47:55 -0800623extern const ArmEncodingMap EncodingMap[kArmLast];
buzbee67bf8852011-08-17 17:51:35 -0700624
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800625} // namespace art
626
buzbee67bf8852011-08-17 17:51:35 -0700627#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_