blob: 5034623c2b795ad0b98a131ae0e0f5f638c33a79 [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
buzbee0398c422012-03-02 15:22:47 -0800304#define rINVOKE_TGT r_V0
buzbee5de34942012-03-01 14:51:57 -0800305
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
buzbee5de34942012-03-01 14:51:57 -0800314// FIXME: Need support for barriers. Adding these defines to allow compile
315#define kST 0
316#define kSY 1
buzbeee3acd072012-02-25 17:03:10 -0800317
buzbee31a4a6f2012-02-28 15:36:15 -0800318#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800319
320/*
321 * The following enum defines the list of supported Thumb instructions by the
322 * assembler. Their corresponding snippet positions will be defined in
323 * Assemble.c.
324 */
325typedef enum MipsOpCode {
buzbee31a4a6f2012-02-28 15:36:15 -0800326 kPseudoSuspendTarget = -15,
327 kPseudoThrowTarget = -14,
328 kPseudoCaseLabel = -13,
329 kPseudoMethodEntry = -12,
330 kPseudoMethodExit = -11,
331 kPseudoBarrier = -10,
332 kPseudoExtended = -9,
333 kPseudoSSARep = -8,
334 kPseudoEntryBlock = -7,
335 kPseudoExitBlock = -6,
336 kPseudoTargetLabel = -5,
337 kPseudoDalvikByteCodeBoundary = -4,
338 kPseudoPseudoAlign4 = -3,
339 kPseudoEHBlockLabel = -2,
340 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800341
342 kMipsFirst,
343 kMips32BitData = kMipsFirst, /* data [31..0] */
344 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
345 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
346 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
347 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
348 kMipsB, /* b o [0001000000000000] o[15..0] */
349 kMipsBal, /* bal o [0000010000010001] o[15..0] */
350 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
351 adding an instruction in this range may require updates */
352 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
353 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
354 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
355 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
356 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
357 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
358 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
359 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
360 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
361#if __mips_isa_rev>=2
362 kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
363#endif
364 kMipsJal, /* jal t [000011] t[25..0] */
365 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
366 hint[10..6] [001001] */
367 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
368 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
369 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
370 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
371 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
372 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
373 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
374 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
375 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
376 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
377 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
378 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
379 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
380 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
381 kMipsNop, /* nop [00000000000000000000000000000000] */
382 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
383 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
384 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
385 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
386 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
387#if __mips_isa_rev>=2
388 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
389 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
390#endif
391 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
392 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
393 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
394 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
395 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
396 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
397 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
398 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
399 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
400 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
401 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
402 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
403 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
404 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
405#ifdef __mips_hard_float
406 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
407 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
408 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
409 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
410 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
411 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
412 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
413 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
414 kMipsFcvtsd, /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
415 kMipsFcvtsw, /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
416 kMipsFcvtds, /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
417 kMipsFcvtdw, /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
418 kMipsFcvtws, /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
419 kMipsFcvtwd, /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
420 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
421 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
422 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
423 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
424 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
425 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
426 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
427 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
428#endif
buzbeec5159d52012-03-03 11:48:39 -0800429 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
430 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
431 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
432 kMipsCurrPC, /* jal to .+8 to materialize pc */
buzbeee3acd072012-02-25 17:03:10 -0800433 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
434 kMipsLast
435} MipsOpCode;
436
437/* Bit flags describing the behavior of each native opcode */
438typedef enum MipsOpFeatureFlags {
439 kIsBranch = 0,
440 kRegDef0,
441 kRegDef1,
442 kRegDefSP,
443 kRegDefLR,
444 kRegDefList0,
445 kRegDefList1,
446 kRegUse0,
447 kRegUse1,
448 kRegUse2,
449 kRegUse3,
450 kRegUseSP,
451 kRegUsePC,
452 kRegUseList0,
453 kRegUseList1,
454 kNoOperand,
455 kIsUnaryOp,
456 kIsBinaryOp,
457 kIsTertiaryOp,
458 kIsQuadOp,
459 kIsIT,
460 kSetsCCodes,
461 kUsesCCodes,
462 kMemLoad,
463 kMemStore,
buzbee5de34942012-03-01 14:51:57 -0800464 kPCRelFixup,
buzbeec5159d52012-03-03 11:48:39 -0800465 kRegUseLR,
buzbee5de34942012-03-01 14:51:57 -0800466// FIXME: add NEEDS_FIXUP to instruction attributes
buzbeee3acd072012-02-25 17:03:10 -0800467} MipsOpFeatureFlags;
468
469#define IS_LOAD (1 << kMemLoad)
470#define IS_STORE (1 << kMemStore)
471#define IS_BRANCH (1 << kIsBranch)
472#define REG_DEF0 (1 << kRegDef0)
473#define REG_DEF1 (1 << kRegDef1)
474#define REG_DEF_SP (1 << kRegDefSP)
475#define REG_DEF_LR (1 << kRegDefLR)
476#define REG_DEF_LIST0 (1 << kRegDefList0)
477#define REG_DEF_LIST1 (1 << kRegDefList1)
478#define REG_USE0 (1 << kRegUse0)
479#define REG_USE1 (1 << kRegUse1)
480#define REG_USE2 (1 << kRegUse2)
481#define REG_USE3 (1 << kRegUse3)
482#define REG_USE_SP (1 << kRegUseSP)
483#define REG_USE_PC (1 << kRegUsePC)
484#define REG_USE_LIST0 (1 << kRegUseList0)
485#define REG_USE_LIST1 (1 << kRegUseList1)
486#define NO_OPERAND (1 << kNoOperand)
487#define IS_UNARY_OP (1 << kIsUnaryOp)
488#define IS_BINARY_OP (1 << kIsBinaryOp)
489#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
490#define IS_QUAD_OP (1 << kIsQuadOp)
491#define IS_IT (1 << kIsIT)
492#define SETS_CCODES (1 << kSetsCCodes)
493#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800494#define NEEDS_FIXUP (1 << kPCRelFixup)
495#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800496
497/* attributes, included for compatibility */
498#define REG_DEF_FPCS_LIST0 (0)
499#define REG_DEF_FPCS_LIST2 (0)
500
buzbeee3acd072012-02-25 17:03:10 -0800501
502/* Common combo register usage patterns */
503#define REG_USE01 (REG_USE0 | REG_USE1)
504#define REG_USE02 (REG_USE0 | REG_USE2)
505#define REG_USE012 (REG_USE01 | REG_USE2)
506#define REG_USE12 (REG_USE1 | REG_USE2)
507#define REG_USE23 (REG_USE2 | REG_USE3)
508#define REG_DEF01 (REG_DEF0 | REG_DEF1)
509#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
510#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
511#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
512#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
513#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
514#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
515
516/* Instruction assembly fieldLoc kind */
517typedef enum MipsEncodingKind {
518 kFmtUnused,
519 kFmtBitBlt, /* Bit string using end/start */
520 kFmtDfp, /* Double FP reg */
521 kFmtSfp, /* Single FP reg */
buzbeec5159d52012-03-03 11:48:39 -0800522 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
buzbeee3acd072012-02-25 17:03:10 -0800523} MipsEncodingKind;
524
525/* Struct used to define the snippet positions for each Thumb opcode */
526typedef struct MipsEncodingMap {
527 u4 skeleton;
528 struct {
529 MipsEncodingKind kind;
530 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
531 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
532 } fieldLoc[4];
533 MipsOpCode opcode;
534 int flags;
535 const char *name;
536 const char* fmt;
buzbee71ac9942012-03-01 17:23:10 -0800537 int size; /* Size in bytes */
buzbeee3acd072012-02-25 17:03:10 -0800538} MipsEncodingMap;
539
540/* Keys for target-specific scheduling and other optimization hints */
541typedef enum MipsTargetOptHints {
542 kMaxHoistDistance,
543} MipsTargetOptHints;
544
545extern MipsEncodingMap EncodingMap[kMipsLast];
546
buzbeee3acd072012-02-25 17:03:10 -0800547
548#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
549#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
550#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
551
552} // namespace art
553
554#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_