blob: 9baa3c008380a0d22981ee879ffd46467260ed37 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2012 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_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
18#define ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
19
20#include "../../Dalvik.h"
21#include "../../CompilerInternals.h"
22
23namespace art {
24
25// Set to 1 to measure cost of suspend check
26#define NO_SUSPEND 0
27
28/*
29 * Runtime register conventions.
30 *
31 * zero is always the value 0
32 * at is scratch (normally used as temp reg by assembler)
33 * v0, v1 are scratch (normally hold subroutine return values)
34 * a0-a3 are scratch (normally hold subroutine arguments)
35 * t0-t8 are scratch
36 * t9 is scratch (normally used for function calls)
37 * s0 (rSUSPEND) is reserved [holds suspend-check counter]
38 * s1 (rSELF) is reserved [holds current &Thread]
39 * s2-s7 are callee save (promotion target)
40 * k0, k1 are reserved for use by interrupt handlers
41 * gp is reserved for global pointer
42 * sp is reserved
43 * s8 is callee save (promotion target)
44 * ra is scratch (normally holds the return addr)
45 *
46 * Preserved across C calls: s0-s8
47 * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra
48 *
49 * Floating pointer registers
50 * NOTE: there are 32 fp registers (16 df pairs), but currently
51 * only support 16 fp registers (8 df pairs).
52 * f0-f15
53 * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
54 *
55 * f0-f15 (df0-df7) trashed across C calls
56 *
57 * For mips32 code use:
58 * a0-a3 to hold operands
59 * v0-v1 to hold results
60 * t0-t9 for temps
61 *
62 * All jump/branch instructions have a delay slot after it.
63 *
64 * Stack frame diagram (stack grows down, higher addresses at top):
65 *
66 * +------------------------+
67 * | IN[ins-1] | {Note: resides in caller's frame}
68 * | . |
69 * | IN[0] |
70 * | caller's Method* |
71 * +========================+ {Note: start of callee's frame}
72 * | spill region | {variable sized - will include lr if non-leaf.}
73 * +------------------------+
74 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
75 * +------------------------+
76 * | V[locals-1] |
77 * | V[locals-2] |
78 * | . |
79 * | . |
80 * | V[1] |
81 * | V[0] |
82 * +------------------------+
83 * | 0 to 3 words padding |
84 * +------------------------+
85 * | OUT[outs-1] |
86 * | OUT[outs-2] |
87 * | . |
88 * | OUT[0] |
89 * | curMethod* | <<== sp w/ 16-byte alignment
90 * +========================+
91 */
92
93/* Offset to distingish FP regs */
94#define FP_REG_OFFSET 32
95/* Offset to distinguish DP FP regs */
96#define FP_DOUBLE 64
97/* Offset to distingish the extra regs */
98#define EXTRA_REG_OFFSET 128
99/* Reg types */
100#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
101#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
102#define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
103#define LOWREG(x) ((x & 0x1f) == x)
104#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
105#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
106/*
107 * Note: the low register of a floating point pair is sufficient to
108 * create the name of a double, but require both names to be passed to
109 * allow for asserts to verify that the pair is consecutive if significant
110 * rework is done in this area. Also, it is a good reminder in the calling
111 * code that reg locations always describe doubles as a pair of singles.
112 */
113#define S2D(x,y) ((x) | FP_DOUBLE)
114/* Mask to strip off fp flags */
115#define FP_REG_MASK (FP_REG_OFFSET-1)
116/* non-existent Dalvik register */
117#define vNone (-1)
118/* non-existant physical register */
119#define rNone (-1)
120
121#ifdef HAVE_LITTLE_ENDIAN
122#define LOWORD_OFFSET 0
123#define HIWORD_OFFSET 4
124#define r_ARG0 r_A0
125#define r_ARG1 r_A1
126#define r_ARG2 r_A2
127#define r_ARG3 r_A3
128#define r_RESULT0 r_V0
129#define r_RESULT1 r_V1
130#else
131#define LOWORD_OFFSET 4
132#define HIWORD_OFFSET 0
133#define r_ARG0 r_A1
134#define r_ARG1 r_A0
135#define r_ARG2 r_A3
136#define r_ARG3 r_A2
137#define r_RESULT0 r_V1
138#define r_RESULT1 r_V0
139#endif
140
141/* These are the same for both big and little endian. */
142#define r_FARG0 r_F12
143#define r_FARG1 r_F13
144#define r_FRESULT0 r_F0
145#define r_FRESULT1 r_F1
146
147/* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
148#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \
149 INVALID_SREG}
150#define LOC_C_RETURN_ALT {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_F0, INVALID_REG, \
151 INVALID_SREG}
buzbee5de34942012-03-01 14:51:57 -0800152#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_RESULT0, r_RESULT1,\
buzbeee3acd072012-02-25 17:03:10 -0800153 INVALID_SREG}
buzbee5de34942012-03-01 14:51:57 -0800154#define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_FRESULT0,\
155 r_FRESULT1, INVALID_SREG}
buzbeee3acd072012-02-25 17:03:10 -0800156
157typedef enum ResourceEncodingPos {
158 kGPReg0 = 0,
159 kRegSP = 29,
160 kRegLR = 31,
161 kFPReg0 = 32, /* only 16 fp regs supported currently */
162 kFPRegEnd = 48,
163 kRegHI = kFPRegEnd,
164 kRegLO,
165 kRegPC,
166 kRegEnd = 51,
167 kCCode = kRegEnd,
168 kFPStatus, // FP status word
169 // The following four bits are for memory disambiguation
170 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
171 kLiteral, // 2 Literal pool (can be fully disambiguated)
172 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
173 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
174} ResourceEncodingPos;
175
176#define ENCODE_REG_LIST(N) ((u8) N)
177#define ENCODE_REG_SP (1ULL << kRegSP)
178#define ENCODE_REG_LR (1ULL << kRegLR)
179#define ENCODE_REG_PC (1ULL << kRegPC)
180#define ENCODE_CCODE (1ULL << kCCode)
181#define ENCODE_FP_STATUS (1ULL << kFPStatus)
182
183/* Abstract memory locations */
184#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
185#define ENCODE_LITERAL (1ULL << kLiteral)
186#define ENCODE_HEAP_REF (1ULL << kHeapRef)
187#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
188
189#define ENCODE_ALL (~0ULL)
190#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
191 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
192
193#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
194#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
195
buzbeee3acd072012-02-25 17:03:10 -0800196/*
buzbeee3acd072012-02-25 17:03:10 -0800197 * Annotate special-purpose core registers:
198 */
199
200typedef enum NativeRegisterPool {
201 r_ZERO = 0,
202 r_AT = 1,
203 r_V0 = 2,
204 r_V1 = 3,
205 r_A0 = 4,
206 r_A1 = 5,
207 r_A2 = 6,
208 r_A3 = 7,
209 r_T0 = 8,
210 r_T1 = 9,
211 r_T2 = 10,
212 r_T3 = 11,
213 r_T4 = 12,
214 r_T5 = 13,
215 r_T6 = 14,
216 r_T7 = 15,
217 r_S0 = 16,
218 r_S1 = 17,
219 r_S2 = 18,
220 r_S3 = 19,
221 r_S4 = 20,
222 r_S5 = 21,
223 r_S6 = 22,
224 r_S7 = 23,
225 r_T8 = 24,
226 r_T9 = 25,
227 r_K0 = 26,
228 r_K1 = 27,
229 r_GP = 28,
230 r_SP = 29,
231 r_FP = 30,
232 r_RA = 31,
233
234 r_F0 = 0 + FP_REG_OFFSET,
235 r_F1,
236 r_F2,
237 r_F3,
238 r_F4,
239 r_F5,
240 r_F6,
241 r_F7,
242 r_F8,
243 r_F9,
244 r_F10,
245 r_F11,
246 r_F12,
247 r_F13,
248 r_F14,
249 r_F15,
250#if 0 /* only 16 fp regs supported currently */
251 r_F16,
252 r_F17,
253 r_F18,
254 r_F19,
255 r_F20,
256 r_F21,
257 r_F22,
258 r_F23,
259 r_F24,
260 r_F25,
261 r_F26,
262 r_F27,
263 r_F28,
264 r_F29,
265 r_F30,
266 r_F31,
267#endif
268 r_DF0 = r_F0 + FP_DOUBLE,
269 r_DF1 = r_F2 + FP_DOUBLE,
270 r_DF2 = r_F4 + FP_DOUBLE,
271 r_DF3 = r_F6 + FP_DOUBLE,
272 r_DF4 = r_F8 + FP_DOUBLE,
273 r_DF5 = r_F10 + FP_DOUBLE,
274 r_DF6 = r_F12 + FP_DOUBLE,
275 r_DF7 = r_F14 + FP_DOUBLE,
276#if 0 /* only 16 fp regs supported currently */
277 r_DF8 = r_F16 + FP_DOUBLE,
278 r_DF9 = r_F18 + FP_DOUBLE,
279 r_DF10 = r_F20 + FP_DOUBLE,
280 r_DF11 = r_F22 + FP_DOUBLE,
281 r_DF12 = r_F24 + FP_DOUBLE,
282 r_DF13 = r_F26 + FP_DOUBLE,
283 r_DF14 = r_F28 + FP_DOUBLE,
284 r_DF15 = r_F30 + FP_DOUBLE,
285#endif
286 r_HI = EXTRA_REG_OFFSET,
287 r_LO,
288 r_PC,
289} NativeRegisterPool;
290
buzbee5de34942012-03-01 14:51:57 -0800291/*
292 * Target-independent aliases
293 */
294
295#define rSUSPEND r_S0
296#define rSELF r_S1
297#define rSP r_SP
298#define rARG0 r_ARG0
299#define rARG1 r_ARG1
300#define rARG2 r_ARG2
301#define rARG3 r_ARG3
302#define rRET0 r_RESULT0
303#define rRET1 r_RESULT1
304#define rLINK r_RA
305
buzbeee3acd072012-02-25 17:03:10 -0800306/* Shift encodings */
307typedef enum MipsShiftEncodings {
308 kMipsLsl = 0x0,
309 kMipsLsr = 0x1,
310 kMipsAsr = 0x2,
311 kMipsRor = 0x3
312} MipsShiftEncodings;
313
314/* condition encodings */
315typedef enum MipsConditionCode {
316 kMipsCondEq = 0x0, /* 0000 */
317 kMipsCondNe = 0x1, /* 0001 */
318 kMipsCondCs = 0x2, /* 0010 */
319 kMipsCondCc = 0x3, /* 0011 */
320 kMipsCondMi = 0x4, /* 0100 */
321 kMipsCondPl = 0x5, /* 0101 */
322 kMipsCondVs = 0x6, /* 0110 */
323 kMipsCondVc = 0x7, /* 0111 */
324 kMipsCondHi = 0x8, /* 1000 */
325 kMipsCondLs = 0x9, /* 1001 */
326 kMipsCondGe = 0xa, /* 1010 */
327 kMipsCondLt = 0xb, /* 1011 */
328 kMipsCondGt = 0xc, /* 1100 */
329 kMipsCondLe = 0xd, /* 1101 */
330 kMipsCondAl = 0xe, /* 1110 */
331 kMipsCondNv = 0xf, /* 1111 */
332} MipsConditionCode;
333
buzbee5de34942012-03-01 14:51:57 -0800334// FIXME: Need support for barriers. Adding these defines to allow compile
335#define kST 0
336#define kSY 1
buzbeee3acd072012-02-25 17:03:10 -0800337
buzbee31a4a6f2012-02-28 15:36:15 -0800338#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800339
340/*
341 * The following enum defines the list of supported Thumb instructions by the
342 * assembler. Their corresponding snippet positions will be defined in
343 * Assemble.c.
344 */
345typedef enum MipsOpCode {
buzbee31a4a6f2012-02-28 15:36:15 -0800346 kPseudoSuspendTarget = -15,
347 kPseudoThrowTarget = -14,
348 kPseudoCaseLabel = -13,
349 kPseudoMethodEntry = -12,
350 kPseudoMethodExit = -11,
351 kPseudoBarrier = -10,
352 kPseudoExtended = -9,
353 kPseudoSSARep = -8,
354 kPseudoEntryBlock = -7,
355 kPseudoExitBlock = -6,
356 kPseudoTargetLabel = -5,
357 kPseudoDalvikByteCodeBoundary = -4,
358 kPseudoPseudoAlign4 = -3,
359 kPseudoEHBlockLabel = -2,
360 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800361
362 kMipsFirst,
363 kMips32BitData = kMipsFirst, /* data [31..0] */
364 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
365 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
366 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
367 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
368 kMipsB, /* b o [0001000000000000] o[15..0] */
369 kMipsBal, /* bal o [0000010000010001] o[15..0] */
370 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
371 adding an instruction in this range may require updates */
372 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
373 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
374 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
375 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
376 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
377 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
378 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
379 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
380 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
381#if __mips_isa_rev>=2
382 kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
383#endif
384 kMipsJal, /* jal t [000011] t[25..0] */
385 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
386 hint[10..6] [001001] */
387 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
388 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
389 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
390 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
391 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
392 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
393 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
394 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
395 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
396 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
397 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
398 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
399 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
400 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
401 kMipsNop, /* nop [00000000000000000000000000000000] */
402 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
403 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
404 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
405 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
406 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
407#if __mips_isa_rev>=2
408 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
409 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
410#endif
411 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
412 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
413 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
414 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
415 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
416 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
417 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
418 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
419 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
420 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
421 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
422 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
423 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
424 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
425#ifdef __mips_hard_float
426 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
427 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
428 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
429 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
430 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
431 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
432 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
433 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
434 kMipsFcvtsd, /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
435 kMipsFcvtsw, /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
436 kMipsFcvtds, /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
437 kMipsFcvtdw, /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
438 kMipsFcvtws, /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
439 kMipsFcvtwd, /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
440 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
441 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
442 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
443 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
444 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
445 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
446 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
447 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
448#endif
449 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
450 kMipsLast
451} MipsOpCode;
452
453/* Bit flags describing the behavior of each native opcode */
454typedef enum MipsOpFeatureFlags {
455 kIsBranch = 0,
456 kRegDef0,
457 kRegDef1,
458 kRegDefSP,
459 kRegDefLR,
460 kRegDefList0,
461 kRegDefList1,
462 kRegUse0,
463 kRegUse1,
464 kRegUse2,
465 kRegUse3,
466 kRegUseSP,
467 kRegUsePC,
468 kRegUseList0,
469 kRegUseList1,
470 kNoOperand,
471 kIsUnaryOp,
472 kIsBinaryOp,
473 kIsTertiaryOp,
474 kIsQuadOp,
475 kIsIT,
476 kSetsCCodes,
477 kUsesCCodes,
478 kMemLoad,
479 kMemStore,
buzbee5de34942012-03-01 14:51:57 -0800480 kPCRelFixup,
481// FIXME: add NEEDS_FIXUP to instruction attributes
buzbeee3acd072012-02-25 17:03:10 -0800482} MipsOpFeatureFlags;
483
484#define IS_LOAD (1 << kMemLoad)
485#define IS_STORE (1 << kMemStore)
486#define IS_BRANCH (1 << kIsBranch)
487#define REG_DEF0 (1 << kRegDef0)
488#define REG_DEF1 (1 << kRegDef1)
489#define REG_DEF_SP (1 << kRegDefSP)
490#define REG_DEF_LR (1 << kRegDefLR)
491#define REG_DEF_LIST0 (1 << kRegDefList0)
492#define REG_DEF_LIST1 (1 << kRegDefList1)
493#define REG_USE0 (1 << kRegUse0)
494#define REG_USE1 (1 << kRegUse1)
495#define REG_USE2 (1 << kRegUse2)
496#define REG_USE3 (1 << kRegUse3)
497#define REG_USE_SP (1 << kRegUseSP)
498#define REG_USE_PC (1 << kRegUsePC)
499#define REG_USE_LIST0 (1 << kRegUseList0)
500#define REG_USE_LIST1 (1 << kRegUseList1)
501#define NO_OPERAND (1 << kNoOperand)
502#define IS_UNARY_OP (1 << kIsUnaryOp)
503#define IS_BINARY_OP (1 << kIsBinaryOp)
504#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
505#define IS_QUAD_OP (1 << kIsQuadOp)
506#define IS_IT (1 << kIsIT)
507#define SETS_CCODES (1 << kSetsCCodes)
508#define USES_CCODES (1 << kUsesCCodes)
buzbee5de34942012-03-01 14:51:57 -0800509#define NEEDS_FIXUP (1 << kPCRelFixup)
510
511/* attributes, included for compatibility */
512#define REG_DEF_FPCS_LIST0 (0)
513#define REG_DEF_FPCS_LIST2 (0)
514
buzbeee3acd072012-02-25 17:03:10 -0800515
516/* Common combo register usage patterns */
517#define REG_USE01 (REG_USE0 | REG_USE1)
518#define REG_USE02 (REG_USE0 | REG_USE2)
519#define REG_USE012 (REG_USE01 | REG_USE2)
520#define REG_USE12 (REG_USE1 | REG_USE2)
521#define REG_USE23 (REG_USE2 | REG_USE3)
522#define REG_DEF01 (REG_DEF0 | REG_DEF1)
523#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
524#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
525#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
526#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
527#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
528#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
529
530/* Instruction assembly fieldLoc kind */
531typedef enum MipsEncodingKind {
532 kFmtUnused,
533 kFmtBitBlt, /* Bit string using end/start */
534 kFmtDfp, /* Double FP reg */
535 kFmtSfp, /* Single FP reg */
536} MipsEncodingKind;
537
538/* Struct used to define the snippet positions for each Thumb opcode */
539typedef struct MipsEncodingMap {
540 u4 skeleton;
541 struct {
542 MipsEncodingKind kind;
543 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
544 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
545 } fieldLoc[4];
546 MipsOpCode opcode;
547 int flags;
548 const char *name;
549 const char* fmt;
buzbee71ac9942012-03-01 17:23:10 -0800550 int size; /* Size in bytes */
buzbeee3acd072012-02-25 17:03:10 -0800551} MipsEncodingMap;
552
553/* Keys for target-specific scheduling and other optimization hints */
554typedef enum MipsTargetOptHints {
555 kMaxHoistDistance,
556} MipsTargetOptHints;
557
558extern MipsEncodingMap EncodingMap[kMipsLast];
559
buzbeee3acd072012-02-25 17:03:10 -0800560
561#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
562#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
563#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
564
565} // namespace art
566
567#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_