blob: a068502972d273c75bc17459e90a10d70c9716ca [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
buzbeeefc63692012-11-14 16:31:52 -080020#include "../../dalvik.h"
21#include "../../compiler_internals.h"
buzbee67bf8852011-08-17 17:51:35 -070022
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
buzbeef0504cd2012-11-13 16:31:10 -080033 * r4 : (rARM_SUSPEND) 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)
buzbeef0504cd2012-11-13 16:31:10 -080038 * r9 : (rARM_SELF) is reserved (pointer to thread-local storage)
buzbee67bf8852011-08-17 17:51:35 -070039 * 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 */
buzbeef0504cd2012-11-13 16:31:10 -080098#define ARM_FP_REG_OFFSET 32
buzbee67bf8852011-08-17 17:51:35 -070099/* Offset to distinguish DP FP regs */
buzbeef0504cd2012-11-13 16:31:10 -0800100#define ARM_FP_DOUBLE 64
buzbeebbaf8942011-10-02 13:08:29 -0700101/* First FP callee save */
buzbeef0504cd2012-11-13 16:31:10 -0800102#define ARM_FP_CALLEE_SAVE_BASE 16
buzbee67bf8852011-08-17 17:51:35 -0700103/* Reg types */
buzbeef0504cd2012-11-13 16:31:10 -0800104#define ARM_REGTYPE(x) (x & (ARM_FP_REG_OFFSET | ARM_FP_DOUBLE))
105#define ARM_FPREG(x) ((x & ARM_FP_REG_OFFSET) == ARM_FP_REG_OFFSET)
106#define ARM_LOWREG(x) ((x & 0x7) == x)
107#define ARM_DOUBLEREG(x) ((x & ARM_FP_DOUBLE) == ARM_FP_DOUBLE)
108#define ARM_SINGLEREG(x) (ARM_FPREG(x) && !ARM_DOUBLEREG(x))
buzbee67bf8852011-08-17 17:51:35 -0700109/*
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 */
buzbeef0504cd2012-11-13 16:31:10 -0800116#define ARM_S2D(x,y) ((x) | ARM_FP_DOUBLE)
buzbee67bf8852011-08-17 17:51:35 -0700117/* Mask to strip off fp flags */
buzbeef0504cd2012-11-13 16:31:10 -0800118#define ARM_FP_REG_MASK (ARM_FP_REG_OFFSET-1)
buzbee67bf8852011-08-17 17:51:35 -0700119
120/* RegisterLocation templates return values (r0, or r0/r1) */
buzbeef0504cd2012-11-13 16:31:10 -0800121#define ARM_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
122 INVALID_SREG, INVALID_SREG}
123#define ARM_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1, \
124 INVALID_SREG, INVALID_SREG}
125#define ARM_LOC_C_RETURN_FLOAT ARM_LOC_C_RETURN
126#define ARM_LOC_C_RETURN_DOUBLE ARM_LOC_C_RETURN_WIDE
buzbee67bf8852011-08-17 17:51:35 -0700127
buzbeeec137432012-11-13 12:13:16 -0800128enum ArmResourceEncodingPos {
129 kArmGPReg0 = 0,
130 kArmRegSP = 13,
131 kArmRegLR = 14,
132 kArmRegPC = 15,
133 kArmFPReg0 = 16,
134 kArmFPReg16 = 32,
135 kArmRegEnd = 48,
Elliott Hughes719ace42012-03-09 18:06:03 -0800136};
buzbee67bf8852011-08-17 17:51:35 -0700137
buzbeeec137432012-11-13 12:13:16 -0800138#define ENCODE_ARM_REG_LIST(N) ((u8) N)
139#define ENCODE_ARM_REG_SP (1ULL << kArmRegSP)
140#define ENCODE_ARM_REG_LR (1ULL << kArmRegLR)
141#define ENCODE_ARM_REG_PC (1ULL << kArmRegPC)
142#define ENCODE_ARM_REG_FPCS_LIST(N) ((u8)N << kArmFPReg16)
buzbee67bf8852011-08-17 17:51:35 -0700143
buzbeef0504cd2012-11-13 16:31:10 -0800144enum ArmNativeRegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700145 r0 = 0,
146 r1 = 1,
147 r2 = 2,
148 r3 = 3,
buzbeef0504cd2012-11-13 16:31:10 -0800149 rARM_SUSPEND = 4,
Bill Buzbeea114add2012-05-03 15:00:40 -0700150 r5 = 5,
151 r6 = 6,
152 r7 = 7,
153 r8 = 8,
buzbeef0504cd2012-11-13 16:31:10 -0800154 rARM_SELF = 9,
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 r10 = 10,
156 r11 = 11,
157 r12 = 12,
158 r13sp = 13,
buzbeef0504cd2012-11-13 16:31:10 -0800159 rARM_SP = 13,
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 r14lr = 14,
buzbeef0504cd2012-11-13 16:31:10 -0800161 rARM_LR = 14,
Bill Buzbeea114add2012-05-03 15:00:40 -0700162 r15pc = 15,
buzbeef0504cd2012-11-13 16:31:10 -0800163 rARM_PC = 15,
164 fr0 = 0 + ARM_FP_REG_OFFSET,
165 fr1 = 1 + ARM_FP_REG_OFFSET,
166 fr2 = 2 + ARM_FP_REG_OFFSET,
167 fr3 = 3 + ARM_FP_REG_OFFSET,
168 fr4 = 4 + ARM_FP_REG_OFFSET,
169 fr5 = 5 + ARM_FP_REG_OFFSET,
170 fr6 = 6 + ARM_FP_REG_OFFSET,
171 fr7 = 7 + ARM_FP_REG_OFFSET,
172 fr8 = 8 + ARM_FP_REG_OFFSET,
173 fr9 = 9 + ARM_FP_REG_OFFSET,
174 fr10 = 10 + ARM_FP_REG_OFFSET,
175 fr11 = 11 + ARM_FP_REG_OFFSET,
176 fr12 = 12 + ARM_FP_REG_OFFSET,
177 fr13 = 13 + ARM_FP_REG_OFFSET,
178 fr14 = 14 + ARM_FP_REG_OFFSET,
179 fr15 = 15 + ARM_FP_REG_OFFSET,
180 fr16 = 16 + ARM_FP_REG_OFFSET,
181 fr17 = 17 + ARM_FP_REG_OFFSET,
182 fr18 = 18 + ARM_FP_REG_OFFSET,
183 fr19 = 19 + ARM_FP_REG_OFFSET,
184 fr20 = 20 + ARM_FP_REG_OFFSET,
185 fr21 = 21 + ARM_FP_REG_OFFSET,
186 fr22 = 22 + ARM_FP_REG_OFFSET,
187 fr23 = 23 + ARM_FP_REG_OFFSET,
188 fr24 = 24 + ARM_FP_REG_OFFSET,
189 fr25 = 25 + ARM_FP_REG_OFFSET,
190 fr26 = 26 + ARM_FP_REG_OFFSET,
191 fr27 = 27 + ARM_FP_REG_OFFSET,
192 fr28 = 28 + ARM_FP_REG_OFFSET,
193 fr29 = 29 + ARM_FP_REG_OFFSET,
194 fr30 = 30 + ARM_FP_REG_OFFSET,
195 fr31 = 31 + ARM_FP_REG_OFFSET,
196 dr0 = fr0 + ARM_FP_DOUBLE,
197 dr1 = fr2 + ARM_FP_DOUBLE,
198 dr2 = fr4 + ARM_FP_DOUBLE,
199 dr3 = fr6 + ARM_FP_DOUBLE,
200 dr4 = fr8 + ARM_FP_DOUBLE,
201 dr5 = fr10 + ARM_FP_DOUBLE,
202 dr6 = fr12 + ARM_FP_DOUBLE,
203 dr7 = fr14 + ARM_FP_DOUBLE,
204 dr8 = fr16 + ARM_FP_DOUBLE,
205 dr9 = fr18 + ARM_FP_DOUBLE,
206 dr10 = fr20 + ARM_FP_DOUBLE,
207 dr11 = fr22 + ARM_FP_DOUBLE,
208 dr12 = fr24 + ARM_FP_DOUBLE,
209 dr13 = fr26 + ARM_FP_DOUBLE,
210 dr14 = fr28 + ARM_FP_DOUBLE,
211 dr15 = fr30 + ARM_FP_DOUBLE,
Elliott Hughes719ace42012-03-09 18:06:03 -0800212};
buzbee67bf8852011-08-17 17:51:35 -0700213
buzbee31a4a6f2012-02-28 15:36:15 -0800214/* Target-independent aliases */
buzbeef0504cd2012-11-13 16:31:10 -0800215#define rARM_ARG0 r0
216#define rARM_ARG1 r1
217#define rARM_ARG2 r2
218#define rARM_ARG3 r3
219#define rARM_FARG0 r0
220#define rARM_FARG1 r1
221#define rARM_FARG2 r2
222#define rARM_FARG3 r3
223#define rARM_RET0 r0
224#define rARM_RET1 r1
225#define rARM_INVOKE_TGT rARM_LR
226#define rARM_COUNT INVALID_REG
buzbee31a4a6f2012-02-28 15:36:15 -0800227
buzbee67bf8852011-08-17 17:51:35 -0700228/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800229enum ArmShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700230 kArmLsl = 0x0,
231 kArmLsr = 0x1,
232 kArmAsr = 0x2,
233 kArmRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800234};
buzbee67bf8852011-08-17 17:51:35 -0700235
buzbee67bf8852011-08-17 17:51:35 -0700236#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
237
238/*
239 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800240 * assembler. Their corresponding EncodingMap positions will be defined in
241 * Assemble.cc.
buzbee67bf8852011-08-17 17:51:35 -0700242 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800243enum ArmOpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 /************************************************************************/
buzbeeb046e162012-10-30 15:48:42 -0700245 kArmFirst = 0,
246 kArm16BitData = kArmFirst, /* DATA [0] rd[15..0] */
Bill Buzbeea114add2012-05-03 15:00:40 -0700247 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
248 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
249 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
250 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
251 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
252 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
253 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
254 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
255 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
256 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
257 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
258 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
259 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
260 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
261 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
262 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
263 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
264 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
265 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
266 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
267 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
268 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
269 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
270 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
271 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
272 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
273 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
274 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
275 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
276 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
277 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
278 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
279 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
280 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
281 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
282 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
283 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
284 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
285 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
286 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
287 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
288 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
289 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
290 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
291 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
292 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
293 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
294 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
295 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
296 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
297 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
298 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
299 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
300 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
301 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
302 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
303 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
304 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
305 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
306 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
307 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
308 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
309 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
310 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
311 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
312 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
313 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
314 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
315 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
316 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
317 kThumbSwi, /* swi [11011111] imm_8[7..0] */
318 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
319 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
320 [1010] imm_8[7..0] */
321 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
322 [1011] imm_8[7..0] */
323 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
324 rd[15-12] [10100000] rm[3..0] */
325 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
326 rd[15-12] [10110000] rm[3..0] */
327 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
328 [1010] imm_8[7..0] */
329 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
330 [1011] imm_8[7..0] */
331 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
332 rd[15-12] [10100040] rm[3..0] */
333 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
334 rd[15-12] [10110040] rm[3..0] */
335 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
336 rd[15-12] [10100000] rm[3..0] */
337 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
338 rd[15-12] [10110000] rm[3..0] */
339 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
340 rd[15-12] [10100000] rm[3..0] */
341 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
342 rd[15-12] [10110000] rm[3..0] */
343 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
344 [10101100] vm[3..0] */
345 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
346 [10111100] vm[3..0] */
347 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
348 [10101100] vm[3..0] */
349 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
350 [10111100] vm[3..0] */
351 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
352 [10101100] vm[3..0] */
353 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
354 [10111100] vm[3..0] */
355 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
356 [10101100] vm[3..0] */
357 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
358 [10111100] vm[3..0] */
359 kThumb2MovImmShift,/* mov(T2) rd, #<const> [11110] i [00001001111]
360 imm3 rd[11..8] imm8 */
361 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
362 imm3 rd[11..8] imm8 */
363 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
364 rn[19..16] rt[15..12] imm12[11..0] */
365 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
366 rn[19..16] rt[15..12] imm12[11..0] */
367 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
368 rn[19..16] rt[15..12] [1100] imm[7..0]*/
369 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
370 rn[19..16] rt[15..12] [1100] imm[7..0]*/
371 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
372 rn[2..0] */
373 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
374 rn[2..0] */
375 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
376 [0] imm3[14..12] rd[11..8] imm8[7..0] */
377 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
378 [0000] rm[3..0] */
379 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
380 vd[15..12] 101001] M [0] vm[3..0] */
381 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
382 vd[15..12] 101101] M [0] vm[3..0] */
383 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
384 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
385 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
386 [0000] rm[3..0] */
387 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
388 [0000] rm[3..0] */
389 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
390 [0000] rm[3..0] */
391 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
392 [0000] rm[3..0] */
393 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
394 [0] imm3[14..12] rd[11..8] imm8[7..0] */
395 kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110]
396 imm3 rd[11..8] imm8 */
397 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
398 rm[3-0] */
399 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
400 [0] imm3[14-12] rd[11-8] w[4-0] */
401 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
402 [0] imm3[14-12] rd[11-8] w[4-0] */
403 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
404 rt[15-12] [000000] imm[5-4] rm[3-0] */
405 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
406 rt[15-12] [000000] imm[5-4] rm[3-0] */
407 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
408 rt[15-12] [000000] imm[5-4] rm[3-0] */
409 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
410 rt[15-12] [000000] imm[5-4] rm[3-0] */
411 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
412 rt[15-12] [000000] imm[5-4] rm[3-0] */
413 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
414 rt[15-12] [000000] imm[5-4] rm[3-0] */
415 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
416 rt[15-12] [000000] imm[5-4] rm[3-0] */
417 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
418 rt[15-12] [000000] imm[5-4] rm[3-0] */
419 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
420 rt[15..12] rn[19..16] imm12[11..0] */
421 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
422 rt[15..12] rn[19..16] imm12[11..0] */
423 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
424 rt[15..12] rn[19..16] imm12[11..0] */
425 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
426 rt[15..12] rn[19..16] imm12[11..0] */
427 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
428 rt[15..12] rn[19..16] imm12[11..0] */
429 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
430 rt[15..12] rn[19..16] imm12[11..0] */
431 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
432 kThumb2Push, /* push [1110100100101101] list[15-0]*/
433 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
434 imm3 [1111] imm8[7..0] */
435 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
436 [0000] rm[3..0] */
437 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
438 [0000] rm[3..0] */
439 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
440 [0000] rm[3..0] */
441 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
442 [0000] rm[3..0] */
443 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
444 [0000] rm[3..0] */
445 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
446 [0000] rm[3..0] */
447 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
448 rm[3..0] */
449 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
450 imm8[7..0] */
451 kThumb2NegRR, /* actually rsub rd, rn, #0 */
452 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
453 [0000] rm[3..0] */
454 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
455 [0000] rm[3..0] */
456 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
457 [0000] rm[3..0] */
458 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
459 [0000] rm[3..0] */
460 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
461 [0000] rm[3..0] */
462 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
463 [0000] rm[3..0] */
464 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
465 [00] rm[3..0] */
466 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
467 [01] rm[3..0] */
468 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
469 [10] rm[3..0] */
470 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
471 [11] rm[3..0] */
472 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
473 rd[11..8] imm8 */
474 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
475 rd[11..8] imm8 */
476 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
477 rd[11..8] imm8 */
478 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
479 rd[11..8] imm8 */
480 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
481 rd[11..8] imm8 */
482 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
483 rd[11..8] imm8 */
484 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
485 rd[11..8] imm8 */
486 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
487 rd[11..8] imm8 */
488 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
489 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
490 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
491 E [1] M [0] rm[3-0] */
492 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
493 E [1] M [0] rm[3-0] */
494 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
495 imm12[11-0] */
496 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
497 J1 [0] J2 imm11[10..0] */
498 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
499 M [0] vm[3-0] */
500 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
501 M [0] vm[3-0] */
502 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
503 N [0010000] */
504 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
505 N [0010000] */
506 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
507 [101100] M [1] vm[3-0] */
508 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
509 [101100] M [1] vm[3-0] */
510 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
511 [1011110] M [0] vm[3-0] */
512 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
513 [1010110] M [0] vm[3-0] */
514 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
515 [1011110] M [0] vm[3-0] */
516 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
517 [1010110] M [0] vm[3-0] */
518 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
519 [10100000] imm4l[3-0] */
520 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
521 [10110000] imm4l[3-0] */
522 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
523 [0000] rm[3-0] */
524 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
525 rdhi[11-8] [0000] rm[3-0] */
526 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
527 imm8[7-0] */
528 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
529 imm8[7-0] */
530 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
531 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
532 rd[11-8] imm2[7-6] [0] msb[4-0] */
533 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
534 rd[11-8] imm2[7-6] [0] msb[4-0] */
535 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
536 kThumb2LdrPcReln12,/* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
537 imm12[11-0] */
538 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
539 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
540 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
541 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
542 kThumb2Vldms, /* vldms rd, <list> */
543 kThumb2Vstms, /* vstms rd, <list> */
544 kThumb2BUncond, /* b <label> */
545 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
546 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
547 kThumb2Adr, /* Special purpose encoding of ADR for switch tables */
548 kThumb2MovImm16LST,/* Special purpose version for switch table use */
549 kThumb2MovImm16HST,/* Special purpose version for switch table use */
550 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
551 kThumb2SubsRRI12, /* setflags encoding */
552 kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
553 [0000] rm[3..0] */
554 kThumb2Push1, /* t3 encoding of push */
555 kThumb2Pop1, /* t3 encoding of pop */
556 kThumb2RsubRRR, /* rsb [111010111101] rn[19..16] [0000] rd[11..8]
557 [0000] rm[3..0] */
558 kThumb2Smull, /* smull [111110111000] rn[19-16], rdlo[15-12]
559 rdhi[11-8] [0000] rm[3-0] */
560 kArmLast,
Elliott Hughes719ace42012-03-09 18:06:03 -0800561};
buzbee67bf8852011-08-17 17:51:35 -0700562
563/* DMB option encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800564enum ArmOpDmbOptions {
Bill Buzbeea114add2012-05-03 15:00:40 -0700565 kSY = 0xf,
566 kST = 0xe,
567 kISH = 0xb,
568 kISHST = 0xa,
569 kNSH = 0x7,
570 kNSHST = 0x6
Elliott Hughes719ace42012-03-09 18:06:03 -0800571};
buzbee67bf8852011-08-17 17:51:35 -0700572
573/* Bit flags describing the behavior of each native opcode */
buzbee67bf8852011-08-17 17:51:35 -0700574/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800575enum ArmEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700576 kFmtUnused,
577 kFmtBitBlt, /* Bit string using end/start */
578 kFmtDfp, /* Double FP reg */
579 kFmtSfp, /* Single FP reg */
580 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
581 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
582 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
583 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
584 kFmtShift, /* Shift descriptor, [14..12,7..4] */
585 kFmtLsb, /* least significant bit using [14..12][7..6] */
586 kFmtBWidth, /* bit-field width, encoded as width-1 */
587 kFmtShift5, /* Shift count, [14..12,7..6] */
588 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
589 kFmtFPImm, /* Encoded floating point immediate */
590 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
Elliott Hughes719ace42012-03-09 18:06:03 -0800591};
buzbee67bf8852011-08-17 17:51:35 -0700592
593/* Struct used to define the snippet positions for each Thumb opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800594struct ArmEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 u4 skeleton;
596 struct {
597 ArmEncodingKind kind;
598 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
599 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
600 } fieldLoc[4];
601 ArmOpcode opcode;
buzbeeec137432012-11-13 12:13:16 -0800602 uint64_t flags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700603 const char* name;
604 const char* fmt;
605 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800606};
buzbee67bf8852011-08-17 17:51:35 -0700607
608/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800609enum ArmTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800611};
buzbee67bf8852011-08-17 17:51:35 -0700612
buzbeeba938cb2012-02-03 14:47:55 -0800613extern const ArmEncodingMap EncodingMap[kArmLast];
buzbee67bf8852011-08-17 17:51:35 -0700614
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800615} // namespace art
616
buzbee67bf8852011-08-17 17:51:35 -0700617#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_