blob: c78cd8dc1cd75580da7d495cd1b5dc4e1799a7e4 [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) */
buzbee2cfc6392012-05-07 14:51:40 -0700148#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \
149 INVALID_SREG, INVALID_SREG}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700150#define LOC_C_RETURN_FLOAT LOC_C_RETURN
jeffhao7fbee072012-08-24 17:56:54 -0700151#define LOC_C_RETURN_ALT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_V1, \
buzbee2cfc6392012-05-07 14:51:40 -0700152 INVALID_REG, INVALID_SREG, INVALID_SREG}
153#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_RESULT0, \
154 r_RESULT1, INVALID_SREG, INVALID_SREG}
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700155#define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE
buzbee2cfc6392012-05-07 14:51:40 -0700156#define LOC_C_RETURN_WIDE_ALT {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
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 {
Bill Buzbeea114add2012-05-03 15:00:40 -0700310 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 {
buzbee8320f382012-09-11 16:29:42 -0700336 kPseudoSafepointPC = -17,
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 kPseudoIntrinsicRetry = -16,
338 kPseudoSuspendTarget = -15,
339 kPseudoThrowTarget = -14,
340 kPseudoCaseLabel = -13,
341 kPseudoMethodEntry = -12,
342 kPseudoMethodExit = -11,
343 kPseudoBarrier = -10,
344 kPseudoExtended = -9,
345 kPseudoSSARep = -8,
346 kPseudoEntryBlock = -7,
347 kPseudoExitBlock = -6,
348 kPseudoTargetLabel = -5,
349 kPseudoDalvikByteCodeBoundary = -4,
350 kPseudoPseudoAlign4 = -3,
351 kPseudoEHBlockLabel = -2,
352 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800353
Bill Buzbeea114add2012-05-03 15:00:40 -0700354 kMipsFirst,
355 kMips32BitData = kMipsFirst, /* data [31..0] */
356 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
357 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
358 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
359 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
360 kMipsB, /* b o [0001000000000000] o[15..0] */
361 kMipsBal, /* bal o [0000010000010001] o[15..0] */
362 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
363 adding an instruction in this range may require updates */
364 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
365 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
366 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
367 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
368 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
369 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
370 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
371 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
372 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
buzbeee3acd072012-02-25 17:03:10 -0800373#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 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 -0800375#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 kMipsJal, /* jal t [000011] t[25..0] */
377 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
378 hint[10..6] [001001] */
379 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
380 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
381 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
382 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
383 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
384 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
385 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
386 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
387 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
388 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
389 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
390 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
391 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
392 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
393 kMipsNop, /* nop [00000000000000000000000000000000] */
394 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
395 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
396 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
397 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
398 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800399#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700400 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
401 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
buzbeee3acd072012-02-25 17:03:10 -0800402#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
404 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
405 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
406 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
407 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
408 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
409 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
410 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
411 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
412 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
413 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
414 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
415 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
416 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800417#ifdef __mips_hard_float
Bill Buzbeea114add2012-05-03 15:00:40 -0700418 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
419 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
420 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
421 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
422 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
423 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
424 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
425 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
426 kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
427 kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
428 kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
429 kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
430 kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
431 kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
432 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
433 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
434 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
435 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
436 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
437 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
438 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
439 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
buzbeee3acd072012-02-25 17:03:10 -0800440#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700441 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
442 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
443 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
444 kMipsCurrPC, /* jal to .+8 to materialize pc */
445 kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
446 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
447 kMipsLast
Elliott Hughes719ace42012-03-09 18:06:03 -0800448};
buzbeee3acd072012-02-25 17:03:10 -0800449
450/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800451enum MipsOpFeatureFlags {
Bill Buzbeea114add2012-05-03 15:00:40 -0700452 kIsBranch = 0,
453 kRegDef0,
454 kRegDef1,
455 kRegDefSP,
456 kRegDefLR,
457 kRegDefList0,
458 kRegDefList1,
459 kRegUse0,
460 kRegUse1,
461 kRegUse2,
462 kRegUse3,
463 kRegUseSP,
464 kRegUsePC,
465 kRegUseList0,
466 kRegUseList1,
467 kNoOperand,
468 kIsUnaryOp,
469 kIsBinaryOp,
470 kIsTertiaryOp,
471 kIsQuadOp,
472 kIsIT,
473 kSetsCCodes,
474 kUsesCCodes,
475 kMemLoad,
476 kMemStore,
477 kPCRelFixup,
478 kRegUseLR,
Elliott Hughes719ace42012-03-09 18:06:03 -0800479};
buzbeee3acd072012-02-25 17:03:10 -0800480
481#define IS_LOAD (1 << kMemLoad)
482#define IS_STORE (1 << kMemStore)
483#define IS_BRANCH (1 << kIsBranch)
484#define REG_DEF0 (1 << kRegDef0)
485#define REG_DEF1 (1 << kRegDef1)
486#define REG_DEF_SP (1 << kRegDefSP)
487#define REG_DEF_LR (1 << kRegDefLR)
488#define REG_DEF_LIST0 (1 << kRegDefList0)
489#define REG_DEF_LIST1 (1 << kRegDefList1)
490#define REG_USE0 (1 << kRegUse0)
491#define REG_USE1 (1 << kRegUse1)
492#define REG_USE2 (1 << kRegUse2)
493#define REG_USE3 (1 << kRegUse3)
494#define REG_USE_SP (1 << kRegUseSP)
495#define REG_USE_PC (1 << kRegUsePC)
496#define REG_USE_LIST0 (1 << kRegUseList0)
497#define REG_USE_LIST1 (1 << kRegUseList1)
498#define NO_OPERAND (1 << kNoOperand)
499#define IS_UNARY_OP (1 << kIsUnaryOp)
500#define IS_BINARY_OP (1 << kIsBinaryOp)
501#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
502#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800503#define IS_QUIN_OP 0
buzbeee3acd072012-02-25 17:03:10 -0800504#define IS_IT (1 << kIsIT)
505#define SETS_CCODES (1 << kSetsCCodes)
506#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800507#define NEEDS_FIXUP (1 << kPCRelFixup)
508#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800509
510/* attributes, included for compatibility */
511#define REG_DEF_FPCS_LIST0 (0)
512#define REG_DEF_FPCS_LIST2 (0)
513
buzbeee3acd072012-02-25 17:03:10 -0800514
515/* Common combo register usage patterns */
516#define REG_USE01 (REG_USE0 | REG_USE1)
517#define REG_USE02 (REG_USE0 | REG_USE2)
518#define REG_USE012 (REG_USE01 | REG_USE2)
519#define REG_USE12 (REG_USE1 | REG_USE2)
520#define REG_USE23 (REG_USE2 | REG_USE3)
521#define REG_DEF01 (REG_DEF0 | REG_DEF1)
522#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
523#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
524#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
525#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
526#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
527#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
528
529/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800530enum MipsEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700531 kFmtUnused,
532 kFmtBitBlt, /* Bit string using end/start */
533 kFmtDfp, /* Double FP reg */
534 kFmtSfp, /* Single FP reg */
535 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
Elliott Hughes719ace42012-03-09 18:06:03 -0800536};
buzbeee3acd072012-02-25 17:03:10 -0800537
Ian Rogerscad96062012-03-04 10:33:52 -0800538/* Struct used to define the snippet positions for each MIPS opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800539struct MipsEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 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;
550 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800551};
buzbeee3acd072012-02-25 17:03:10 -0800552
553/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800554enum MipsTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800556};
buzbeee3acd072012-02-25 17:03:10 -0800557
558extern MipsEncodingMap EncodingMap[kMipsLast];
559
buzbeee3acd072012-02-25 17:03:10 -0800560#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
561#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
562#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
563
564} // namespace art
565
566#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_