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