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