blob: 5c8fc345e7e37d217128dd2431bae9904b81c8f3 [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}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700150#define LOC_C_RETURN_FLOAT LOC_C_RETURN
buzbeee3acd072012-02-25 17:03:10 -0800151#define LOC_C_RETURN_ALT {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_F0, INVALID_REG, \
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700152 INVALID_SREG}
buzbee5de34942012-03-01 14:51:57 -0800153#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_RESULT0, r_RESULT1,\
buzbeee3acd072012-02-25 17:03:10 -0800154 INVALID_SREG}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700155#define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE
buzbee5de34942012-03-01 14:51:57 -0800156#define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_FRESULT0,\
157 r_FRESULT1, INVALID_SREG}
buzbeee3acd072012-02-25 17:03:10 -0800158
Elliott Hughes719ace42012-03-09 18:06:03 -0800159enum ResourceEncodingPos {
buzbeee3acd072012-02-25 17:03:10 -0800160 kGPReg0 = 0,
161 kRegSP = 29,
162 kRegLR = 31,
163 kFPReg0 = 32, /* only 16 fp regs supported currently */
164 kFPRegEnd = 48,
165 kRegHI = kFPRegEnd,
166 kRegLO,
167 kRegPC,
168 kRegEnd = 51,
169 kCCode = kRegEnd,
170 kFPStatus, // FP status word
171 // The following four bits are for memory disambiguation
172 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
173 kLiteral, // 2 Literal pool (can be fully disambiguated)
174 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
175 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800176};
buzbeee3acd072012-02-25 17:03:10 -0800177
178#define ENCODE_REG_LIST(N) ((u8) N)
179#define ENCODE_REG_SP (1ULL << kRegSP)
180#define ENCODE_REG_LR (1ULL << kRegLR)
181#define ENCODE_REG_PC (1ULL << kRegPC)
182#define ENCODE_CCODE (1ULL << kCCode)
183#define ENCODE_FP_STATUS (1ULL << kFPStatus)
184
185/* Abstract memory locations */
186#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
187#define ENCODE_LITERAL (1ULL << kLiteral)
188#define ENCODE_HEAP_REF (1ULL << kHeapRef)
189#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
190
191#define ENCODE_ALL (~0ULL)
192#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
193 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
194
195#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
196#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
197
buzbeee3acd072012-02-25 17:03:10 -0800198/*
buzbeee3acd072012-02-25 17:03:10 -0800199 * Annotate special-purpose core registers:
200 */
201
Elliott Hughes719ace42012-03-09 18:06:03 -0800202enum NativeRegisterPool {
buzbeee3acd072012-02-25 17:03:10 -0800203 r_ZERO = 0,
204 r_AT = 1,
205 r_V0 = 2,
206 r_V1 = 3,
207 r_A0 = 4,
208 r_A1 = 5,
209 r_A2 = 6,
210 r_A3 = 7,
211 r_T0 = 8,
212 r_T1 = 9,
213 r_T2 = 10,
214 r_T3 = 11,
215 r_T4 = 12,
216 r_T5 = 13,
217 r_T6 = 14,
218 r_T7 = 15,
219 r_S0 = 16,
220 r_S1 = 17,
221 r_S2 = 18,
222 r_S3 = 19,
223 r_S4 = 20,
224 r_S5 = 21,
225 r_S6 = 22,
226 r_S7 = 23,
227 r_T8 = 24,
228 r_T9 = 25,
229 r_K0 = 26,
230 r_K1 = 27,
231 r_GP = 28,
232 r_SP = 29,
233 r_FP = 30,
234 r_RA = 31,
235
236 r_F0 = 0 + FP_REG_OFFSET,
237 r_F1,
238 r_F2,
239 r_F3,
240 r_F4,
241 r_F5,
242 r_F6,
243 r_F7,
244 r_F8,
245 r_F9,
246 r_F10,
247 r_F11,
248 r_F12,
249 r_F13,
250 r_F14,
251 r_F15,
252#if 0 /* only 16 fp regs supported currently */
253 r_F16,
254 r_F17,
255 r_F18,
256 r_F19,
257 r_F20,
258 r_F21,
259 r_F22,
260 r_F23,
261 r_F24,
262 r_F25,
263 r_F26,
264 r_F27,
265 r_F28,
266 r_F29,
267 r_F30,
268 r_F31,
269#endif
270 r_DF0 = r_F0 + FP_DOUBLE,
271 r_DF1 = r_F2 + FP_DOUBLE,
272 r_DF2 = r_F4 + FP_DOUBLE,
273 r_DF3 = r_F6 + FP_DOUBLE,
274 r_DF4 = r_F8 + FP_DOUBLE,
275 r_DF5 = r_F10 + FP_DOUBLE,
276 r_DF6 = r_F12 + FP_DOUBLE,
277 r_DF7 = r_F14 + FP_DOUBLE,
278#if 0 /* only 16 fp regs supported currently */
279 r_DF8 = r_F16 + FP_DOUBLE,
280 r_DF9 = r_F18 + FP_DOUBLE,
281 r_DF10 = r_F20 + FP_DOUBLE,
282 r_DF11 = r_F22 + FP_DOUBLE,
283 r_DF12 = r_F24 + FP_DOUBLE,
284 r_DF13 = r_F26 + FP_DOUBLE,
285 r_DF14 = r_F28 + FP_DOUBLE,
286 r_DF15 = r_F30 + FP_DOUBLE,
287#endif
288 r_HI = EXTRA_REG_OFFSET,
289 r_LO,
290 r_PC,
Elliott Hughes719ace42012-03-09 18:06:03 -0800291};
buzbeee3acd072012-02-25 17:03:10 -0800292
buzbee5de34942012-03-01 14:51:57 -0800293/*
294 * Target-independent aliases
295 */
296
297#define rSUSPEND r_S0
298#define rSELF r_S1
299#define rSP r_SP
300#define rARG0 r_ARG0
301#define rARG1 r_ARG1
302#define rARG2 r_ARG2
303#define rARG3 r_ARG3
304#define rRET0 r_RESULT0
305#define rRET1 r_RESULT1
buzbee0398c422012-03-02 15:22:47 -0800306#define rINVOKE_TGT r_V0
buzbee5de34942012-03-01 14:51:57 -0800307
buzbeee3acd072012-02-25 17:03:10 -0800308/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800309enum MipsShiftEncodings {
buzbeee3acd072012-02-25 17:03:10 -0800310 kMipsLsl = 0x0,
311 kMipsLsr = 0x1,
312 kMipsAsr = 0x2,
313 kMipsRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800314};
buzbeee3acd072012-02-25 17:03:10 -0800315
buzbeea2ebdd72012-03-04 14:57:06 -0800316// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist)
317#define kSYNC0 0x00
318#define kSYNC_WMB 0x04
319#define kSYNC_MB 0x01
320#define kSYNC_ACQUIRE 0x11
321#define kSYNC_RELEASE 0x12
322#define kSYNC_RMB 0x13
323
324// TODO: Use smaller hammer when appropriate for target CPU
325#define kST kSYNC0
326#define kSY kSYNC0
buzbeee3acd072012-02-25 17:03:10 -0800327
buzbee31a4a6f2012-02-28 15:36:15 -0800328#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800329
330/*
331 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800332 * assembler. Their corresponding EncodingMap positions will be defined in
333 * Assemble.cc.
buzbeee3acd072012-02-25 17:03:10 -0800334 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800335enum MipsOpCode {
buzbee31a4a6f2012-02-28 15:36:15 -0800336 kPseudoSuspendTarget = -15,
337 kPseudoThrowTarget = -14,
338 kPseudoCaseLabel = -13,
339 kPseudoMethodEntry = -12,
340 kPseudoMethodExit = -11,
341 kPseudoBarrier = -10,
342 kPseudoExtended = -9,
343 kPseudoSSARep = -8,
344 kPseudoEntryBlock = -7,
345 kPseudoExitBlock = -6,
346 kPseudoTargetLabel = -5,
347 kPseudoDalvikByteCodeBoundary = -4,
348 kPseudoPseudoAlign4 = -3,
349 kPseudoEHBlockLabel = -2,
350 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800351
352 kMipsFirst,
353 kMips32BitData = kMipsFirst, /* data [31..0] */
354 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
355 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
356 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
357 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
358 kMipsB, /* b o [0001000000000000] o[15..0] */
359 kMipsBal, /* bal o [0000010000010001] o[15..0] */
360 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
361 adding an instruction in this range may require updates */
362 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
363 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
364 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
365 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
366 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
367 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
368 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
369 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
370 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
371#if __mips_isa_rev>=2
372 kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
373#endif
374 kMipsJal, /* jal t [000011] t[25..0] */
375 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
376 hint[10..6] [001001] */
377 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
378 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
379 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
380 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
381 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
382 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
383 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
384 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
385 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
386 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
387 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
388 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
389 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
390 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
391 kMipsNop, /* nop [00000000000000000000000000000000] */
392 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
393 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
394 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
395 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
396 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
397#if __mips_isa_rev>=2
398 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
399 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
400#endif
401 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
402 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
403 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
404 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
405 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
406 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
407 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
408 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
409 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
410 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
411 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
412 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
413 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
414 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
415#ifdef __mips_hard_float
416 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
417 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
418 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
419 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
420 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
421 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
422 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
423 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
424 kMipsFcvtsd, /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
425 kMipsFcvtsw, /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
426 kMipsFcvtds, /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
427 kMipsFcvtdw, /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
428 kMipsFcvtws, /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
429 kMipsFcvtwd, /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
430 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
431 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
432 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
433 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
434 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
435 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
436 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
437 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
438#endif
buzbeec5159d52012-03-03 11:48:39 -0800439 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
440 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
441 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
442 kMipsCurrPC, /* jal to .+8 to materialize pc */
buzbeea2ebdd72012-03-04 14:57:06 -0800443 kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
buzbeee3acd072012-02-25 17:03:10 -0800444 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
445 kMipsLast
Elliott Hughes719ace42012-03-09 18:06:03 -0800446};
buzbeee3acd072012-02-25 17:03:10 -0800447
448/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800449enum MipsOpFeatureFlags {
buzbeee3acd072012-02-25 17:03:10 -0800450 kIsBranch = 0,
451 kRegDef0,
452 kRegDef1,
453 kRegDefSP,
454 kRegDefLR,
455 kRegDefList0,
456 kRegDefList1,
457 kRegUse0,
458 kRegUse1,
459 kRegUse2,
460 kRegUse3,
461 kRegUseSP,
462 kRegUsePC,
463 kRegUseList0,
464 kRegUseList1,
465 kNoOperand,
466 kIsUnaryOp,
467 kIsBinaryOp,
468 kIsTertiaryOp,
469 kIsQuadOp,
470 kIsIT,
471 kSetsCCodes,
472 kUsesCCodes,
473 kMemLoad,
474 kMemStore,
buzbee5de34942012-03-01 14:51:57 -0800475 kPCRelFixup,
buzbeec5159d52012-03-03 11:48:39 -0800476 kRegUseLR,
Elliott Hughes719ace42012-03-09 18:06:03 -0800477};
buzbeee3acd072012-02-25 17:03:10 -0800478
479#define IS_LOAD (1 << kMemLoad)
480#define IS_STORE (1 << kMemStore)
481#define IS_BRANCH (1 << kIsBranch)
482#define REG_DEF0 (1 << kRegDef0)
483#define REG_DEF1 (1 << kRegDef1)
484#define REG_DEF_SP (1 << kRegDefSP)
485#define REG_DEF_LR (1 << kRegDefLR)
486#define REG_DEF_LIST0 (1 << kRegDefList0)
487#define REG_DEF_LIST1 (1 << kRegDefList1)
488#define REG_USE0 (1 << kRegUse0)
489#define REG_USE1 (1 << kRegUse1)
490#define REG_USE2 (1 << kRegUse2)
491#define REG_USE3 (1 << kRegUse3)
492#define REG_USE_SP (1 << kRegUseSP)
493#define REG_USE_PC (1 << kRegUsePC)
494#define REG_USE_LIST0 (1 << kRegUseList0)
495#define REG_USE_LIST1 (1 << kRegUseList1)
496#define NO_OPERAND (1 << kNoOperand)
497#define IS_UNARY_OP (1 << kIsUnaryOp)
498#define IS_BINARY_OP (1 << kIsBinaryOp)
499#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
500#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800501#define IS_QUIN_OP 0
buzbeee3acd072012-02-25 17:03:10 -0800502#define IS_IT (1 << kIsIT)
503#define SETS_CCODES (1 << kSetsCCodes)
504#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800505#define NEEDS_FIXUP (1 << kPCRelFixup)
506#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800507
508/* attributes, included for compatibility */
509#define REG_DEF_FPCS_LIST0 (0)
510#define REG_DEF_FPCS_LIST2 (0)
511
buzbeee3acd072012-02-25 17:03:10 -0800512
513/* Common combo register usage patterns */
514#define REG_USE01 (REG_USE0 | REG_USE1)
515#define REG_USE02 (REG_USE0 | REG_USE2)
516#define REG_USE012 (REG_USE01 | REG_USE2)
517#define REG_USE12 (REG_USE1 | REG_USE2)
518#define REG_USE23 (REG_USE2 | REG_USE3)
519#define REG_DEF01 (REG_DEF0 | REG_DEF1)
520#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
521#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
522#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
523#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
524#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
525#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
526
527/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800528enum MipsEncodingKind {
buzbeee3acd072012-02-25 17:03:10 -0800529 kFmtUnused,
530 kFmtBitBlt, /* Bit string using end/start */
531 kFmtDfp, /* Double FP reg */
532 kFmtSfp, /* Single FP reg */
buzbeec5159d52012-03-03 11:48:39 -0800533 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
Elliott Hughes719ace42012-03-09 18:06:03 -0800534};
buzbeee3acd072012-02-25 17:03:10 -0800535
Ian Rogerscad96062012-03-04 10:33:52 -0800536/* Struct used to define the snippet positions for each MIPS opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800537struct MipsEncodingMap {
buzbeee3acd072012-02-25 17:03:10 -0800538 u4 skeleton;
539 struct {
540 MipsEncodingKind kind;
541 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
542 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
543 } fieldLoc[4];
544 MipsOpCode opcode;
545 int flags;
546 const char *name;
547 const char* fmt;
buzbee71ac9942012-03-01 17:23:10 -0800548 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800549};
buzbeee3acd072012-02-25 17:03:10 -0800550
551/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800552enum MipsTargetOptHints {
buzbeee3acd072012-02-25 17:03:10 -0800553 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800554};
buzbeee3acd072012-02-25 17:03:10 -0800555
556extern MipsEncodingMap EncodingMap[kMipsLast];
557
buzbeee3acd072012-02-25 17:03:10 -0800558
559#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
560#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
561#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
562
563} // namespace art
564
565#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_