blob: 4b7da557b3bc1e3b68cc8ab962c65319e7dd7e90 [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
jeffhaofc6a30e2012-10-18 18:24:15 -0700144#define r_FARG2 r_F14
145#define r_FARG3 r_F15
buzbeee3acd072012-02-25 17:03:10 -0800146#define r_FRESULT0 r_F0
147#define r_FRESULT1 r_F1
148
149/* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
buzbee2cfc6392012-05-07 14:51:40 -0700150#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \
151 INVALID_SREG, INVALID_SREG}
jeffhao4f8f04a2012-10-02 18:10:35 -0700152#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0, \
153 INVALID_REG, INVALID_SREG, INVALID_SREG}
buzbee2cfc6392012-05-07 14:51:40 -0700154#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_RESULT0, \
155 r_RESULT1, INVALID_SREG, INVALID_SREG}
jeffhao4f8f04a2012-10-02 18:10:35 -0700156#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0,\
157 r_FRESULT1, INVALID_SREG, INVALID_SREG}
buzbeee3acd072012-02-25 17:03:10 -0800158
Elliott Hughes719ace42012-03-09 18:06:03 -0800159enum ResourceEncodingPos {
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 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 | \
Bill Buzbeea114add2012-05-03 15:00:40 -0700193 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
buzbeee3acd072012-02-25 17:03:10 -0800194
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 {
Bill Buzbeea114add2012-05-03 15:00:40 -0700203 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,
buzbeee3acd072012-02-25 17:03:10 -0800235
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 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,
buzbeee3acd072012-02-25 17:03:10 -0800252#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 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,
buzbeee3acd072012-02-25 17:03:10 -0800269#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 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,
buzbeee3acd072012-02-25 17:03:10 -0800278#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 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,
buzbeee3acd072012-02-25 17:03:10 -0800287#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700288 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
jeffhao30a33172012-10-22 18:16:22 -0700304#define rFARG0 r_FARG0
305#define rFARG1 r_FARG1
306#define rFARG2 r_FARG2
307#define rFARG3 r_FARG3
buzbee5de34942012-03-01 14:51:57 -0800308#define rRET0 r_RESULT0
309#define rRET1 r_RESULT1
jeffhaofa147e22012-10-12 17:03:32 -0700310#define rINVOKE_TGT r_T9
buzbee5de34942012-03-01 14:51:57 -0800311
buzbeee3acd072012-02-25 17:03:10 -0800312/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800313enum MipsShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 kMipsLsl = 0x0,
315 kMipsLsr = 0x1,
316 kMipsAsr = 0x2,
317 kMipsRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800318};
buzbeee3acd072012-02-25 17:03:10 -0800319
buzbeea2ebdd72012-03-04 14:57:06 -0800320// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist)
321#define kSYNC0 0x00
322#define kSYNC_WMB 0x04
323#define kSYNC_MB 0x01
324#define kSYNC_ACQUIRE 0x11
325#define kSYNC_RELEASE 0x12
326#define kSYNC_RMB 0x13
327
328// TODO: Use smaller hammer when appropriate for target CPU
329#define kST kSYNC0
330#define kSY kSYNC0
buzbeee3acd072012-02-25 17:03:10 -0800331
buzbee31a4a6f2012-02-28 15:36:15 -0800332#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800333
334/*
335 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800336 * assembler. Their corresponding EncodingMap positions will be defined in
337 * Assemble.cc.
buzbeee3acd072012-02-25 17:03:10 -0800338 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800339enum MipsOpCode {
Bill Buzbeea5b30242012-09-28 07:19:44 -0700340 kPseudoExportedPC = -18,
buzbee8320f382012-09-11 16:29:42 -0700341 kPseudoSafepointPC = -17,
Bill Buzbeea114add2012-05-03 15:00:40 -0700342 kPseudoIntrinsicRetry = -16,
343 kPseudoSuspendTarget = -15,
344 kPseudoThrowTarget = -14,
345 kPseudoCaseLabel = -13,
346 kPseudoMethodEntry = -12,
347 kPseudoMethodExit = -11,
348 kPseudoBarrier = -10,
349 kPseudoExtended = -9,
350 kPseudoSSARep = -8,
351 kPseudoEntryBlock = -7,
352 kPseudoExitBlock = -6,
353 kPseudoTargetLabel = -5,
354 kPseudoDalvikByteCodeBoundary = -4,
355 kPseudoPseudoAlign4 = -3,
356 kPseudoEHBlockLabel = -2,
357 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800358
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 kMipsFirst,
360 kMips32BitData = kMipsFirst, /* data [31..0] */
361 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
362 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
363 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
364 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
365 kMipsB, /* b o [0001000000000000] o[15..0] */
366 kMipsBal, /* bal o [0000010000010001] o[15..0] */
367 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
368 adding an instruction in this range may require updates */
369 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
370 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
371 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
372 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
373 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
374 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
375 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
376 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
377 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
buzbeee3acd072012-02-25 17:03:10 -0800378#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700379 kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
buzbeee3acd072012-02-25 17:03:10 -0800380#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700381 kMipsJal, /* jal t [000011] t[25..0] */
382 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
383 hint[10..6] [001001] */
384 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
385 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
386 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
387 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
388 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
389 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
390 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
391 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
392 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
393 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
394 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
395 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
396 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
397 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
398 kMipsNop, /* nop [00000000000000000000000000000000] */
399 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
400 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
401 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
402 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
403 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800404#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
406 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
buzbeee3acd072012-02-25 17:03:10 -0800407#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
409 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
410 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
411 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
412 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
413 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
414 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
415 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
416 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
417 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
418 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
419 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
420 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
421 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800422#ifdef __mips_hard_float
Bill Buzbeea114add2012-05-03 15:00:40 -0700423 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
424 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
425 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
426 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
427 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
428 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
429 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
430 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
431 kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
432 kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
433 kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
434 kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
435 kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
436 kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
437 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
438 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
439 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
440 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
441 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
442 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
443 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
444 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
buzbeee3acd072012-02-25 17:03:10 -0800445#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700446 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
447 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
448 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
449 kMipsCurrPC, /* jal to .+8 to materialize pc */
450 kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
451 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
452 kMipsLast
Elliott Hughes719ace42012-03-09 18:06:03 -0800453};
buzbeee3acd072012-02-25 17:03:10 -0800454
455/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800456enum MipsOpFeatureFlags {
Bill Buzbeea114add2012-05-03 15:00:40 -0700457 kIsBranch = 0,
458 kRegDef0,
459 kRegDef1,
460 kRegDefSP,
461 kRegDefLR,
462 kRegDefList0,
463 kRegDefList1,
464 kRegUse0,
465 kRegUse1,
466 kRegUse2,
467 kRegUse3,
468 kRegUseSP,
469 kRegUsePC,
470 kRegUseList0,
471 kRegUseList1,
472 kNoOperand,
473 kIsUnaryOp,
474 kIsBinaryOp,
475 kIsTertiaryOp,
476 kIsQuadOp,
477 kIsIT,
478 kSetsCCodes,
479 kUsesCCodes,
480 kMemLoad,
481 kMemStore,
482 kPCRelFixup,
483 kRegUseLR,
Elliott Hughes719ace42012-03-09 18:06:03 -0800484};
buzbeee3acd072012-02-25 17:03:10 -0800485
486#define IS_LOAD (1 << kMemLoad)
487#define IS_STORE (1 << kMemStore)
488#define IS_BRANCH (1 << kIsBranch)
489#define REG_DEF0 (1 << kRegDef0)
490#define REG_DEF1 (1 << kRegDef1)
491#define REG_DEF_SP (1 << kRegDefSP)
492#define REG_DEF_LR (1 << kRegDefLR)
493#define REG_DEF_LIST0 (1 << kRegDefList0)
494#define REG_DEF_LIST1 (1 << kRegDefList1)
495#define REG_USE0 (1 << kRegUse0)
496#define REG_USE1 (1 << kRegUse1)
497#define REG_USE2 (1 << kRegUse2)
498#define REG_USE3 (1 << kRegUse3)
499#define REG_USE_SP (1 << kRegUseSP)
500#define REG_USE_PC (1 << kRegUsePC)
501#define REG_USE_LIST0 (1 << kRegUseList0)
502#define REG_USE_LIST1 (1 << kRegUseList1)
503#define NO_OPERAND (1 << kNoOperand)
504#define IS_UNARY_OP (1 << kIsUnaryOp)
505#define IS_BINARY_OP (1 << kIsBinaryOp)
506#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
507#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800508#define IS_QUIN_OP 0
buzbeee3acd072012-02-25 17:03:10 -0800509#define IS_IT (1 << kIsIT)
510#define SETS_CCODES (1 << kSetsCCodes)
511#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800512#define NEEDS_FIXUP (1 << kPCRelFixup)
513#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800514
515/* attributes, included for compatibility */
516#define REG_DEF_FPCS_LIST0 (0)
517#define REG_DEF_FPCS_LIST2 (0)
518
buzbeee3acd072012-02-25 17:03:10 -0800519
520/* Common combo register usage patterns */
521#define REG_USE01 (REG_USE0 | REG_USE1)
522#define REG_USE02 (REG_USE0 | REG_USE2)
523#define REG_USE012 (REG_USE01 | REG_USE2)
524#define REG_USE12 (REG_USE1 | REG_USE2)
525#define REG_USE23 (REG_USE2 | REG_USE3)
526#define REG_DEF01 (REG_DEF0 | REG_DEF1)
527#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
528#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
529#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
530#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
531#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
532#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
533
534/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800535enum MipsEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700536 kFmtUnused,
537 kFmtBitBlt, /* Bit string using end/start */
538 kFmtDfp, /* Double FP reg */
539 kFmtSfp, /* Single FP reg */
540 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
Elliott Hughes719ace42012-03-09 18:06:03 -0800541};
buzbeee3acd072012-02-25 17:03:10 -0800542
Ian Rogerscad96062012-03-04 10:33:52 -0800543/* Struct used to define the snippet positions for each MIPS opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800544struct MipsEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 u4 skeleton;
546 struct {
547 MipsEncodingKind kind;
548 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
549 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
550 } fieldLoc[4];
551 MipsOpCode opcode;
552 int flags;
553 const char *name;
554 const char* fmt;
555 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800556};
buzbeee3acd072012-02-25 17:03:10 -0800557
558/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800559enum MipsTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700560 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800561};
buzbeee3acd072012-02-25 17:03:10 -0800562
563extern MipsEncodingMap EncodingMap[kMipsLast];
564
buzbeee3acd072012-02-25 17:03:10 -0800565#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
566#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
567#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
568
569} // namespace art
570
571#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_