blob: 5852b31c56d293d96a9cb88e2e6cb35a3824a711 [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 {
Bill Buzbeea114add2012-05-03 15:00:40 -0700336 kPseudoIntrinsicRetry = -16,
337 kPseudoSuspendTarget = -15,
338 kPseudoThrowTarget = -14,
339 kPseudoCaseLabel = -13,
340 kPseudoMethodEntry = -12,
341 kPseudoMethodExit = -11,
342 kPseudoBarrier = -10,
343 kPseudoExtended = -9,
344 kPseudoSSARep = -8,
345 kPseudoEntryBlock = -7,
346 kPseudoExitBlock = -6,
347 kPseudoTargetLabel = -5,
348 kPseudoDalvikByteCodeBoundary = -4,
349 kPseudoPseudoAlign4 = -3,
350 kPseudoEHBlockLabel = -2,
351 kPseudoNormalBlockLabel = -1,
buzbeee3acd072012-02-25 17:03:10 -0800352
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 kMipsFirst,
354 kMips32BitData = kMipsFirst, /* data [31..0] */
355 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
356 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
357 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
358 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
359 kMipsB, /* b o [0001000000000000] o[15..0] */
360 kMipsBal, /* bal o [0000010000010001] o[15..0] */
361 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
362 adding an instruction in this range may require updates */
363 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
364 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
365 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
366 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
367 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
368 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
369 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
370 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
371 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
buzbeee3acd072012-02-25 17:03:10 -0800372#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700373 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 -0800374#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700375 kMipsJal, /* jal t [000011] t[25..0] */
376 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
377 hint[10..6] [001001] */
378 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
379 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
380 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
381 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
382 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
383 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
384 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
385 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
386 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
387 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
388 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
389 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
390 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
391 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
392 kMipsNop, /* nop [00000000000000000000000000000000] */
393 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
394 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
395 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
396 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
397 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800398#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700399 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
400 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
buzbeee3acd072012-02-25 17:03:10 -0800401#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
403 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
404 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
405 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
406 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
407 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
408 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
409 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
410 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
411 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
412 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
413 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
414 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
415 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800416#ifdef __mips_hard_float
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
418 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
419 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
420 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
421 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
422 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
423 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
424 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
425 kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
426 kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
427 kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
428 kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
429 kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
430 kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
431 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
432 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
433 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
434 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
435 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
436 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
437 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
438 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
buzbeee3acd072012-02-25 17:03:10 -0800439#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
441 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
442 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
443 kMipsCurrPC, /* jal to .+8 to materialize pc */
444 kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
445 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
446 kMipsLast
Elliott Hughes719ace42012-03-09 18:06:03 -0800447};
buzbeee3acd072012-02-25 17:03:10 -0800448
449/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800450enum MipsOpFeatureFlags {
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 kIsBranch = 0,
452 kRegDef0,
453 kRegDef1,
454 kRegDefSP,
455 kRegDefLR,
456 kRegDefList0,
457 kRegDefList1,
458 kRegUse0,
459 kRegUse1,
460 kRegUse2,
461 kRegUse3,
462 kRegUseSP,
463 kRegUsePC,
464 kRegUseList0,
465 kRegUseList1,
466 kNoOperand,
467 kIsUnaryOp,
468 kIsBinaryOp,
469 kIsTertiaryOp,
470 kIsQuadOp,
471 kIsIT,
472 kSetsCCodes,
473 kUsesCCodes,
474 kMemLoad,
475 kMemStore,
476 kPCRelFixup,
477 kRegUseLR,
Elliott Hughes719ace42012-03-09 18:06:03 -0800478};
buzbeee3acd072012-02-25 17:03:10 -0800479
480#define IS_LOAD (1 << kMemLoad)
481#define IS_STORE (1 << kMemStore)
482#define IS_BRANCH (1 << kIsBranch)
483#define REG_DEF0 (1 << kRegDef0)
484#define REG_DEF1 (1 << kRegDef1)
485#define REG_DEF_SP (1 << kRegDefSP)
486#define REG_DEF_LR (1 << kRegDefLR)
487#define REG_DEF_LIST0 (1 << kRegDefList0)
488#define REG_DEF_LIST1 (1 << kRegDefList1)
489#define REG_USE0 (1 << kRegUse0)
490#define REG_USE1 (1 << kRegUse1)
491#define REG_USE2 (1 << kRegUse2)
492#define REG_USE3 (1 << kRegUse3)
493#define REG_USE_SP (1 << kRegUseSP)
494#define REG_USE_PC (1 << kRegUsePC)
495#define REG_USE_LIST0 (1 << kRegUseList0)
496#define REG_USE_LIST1 (1 << kRegUseList1)
497#define NO_OPERAND (1 << kNoOperand)
498#define IS_UNARY_OP (1 << kIsUnaryOp)
499#define IS_BINARY_OP (1 << kIsBinaryOp)
500#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
501#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800502#define IS_QUIN_OP 0
buzbeee3acd072012-02-25 17:03:10 -0800503#define IS_IT (1 << kIsIT)
504#define SETS_CCODES (1 << kSetsCCodes)
505#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800506#define NEEDS_FIXUP (1 << kPCRelFixup)
507#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800508
509/* attributes, included for compatibility */
510#define REG_DEF_FPCS_LIST0 (0)
511#define REG_DEF_FPCS_LIST2 (0)
512
buzbeee3acd072012-02-25 17:03:10 -0800513
514/* Common combo register usage patterns */
515#define REG_USE01 (REG_USE0 | REG_USE1)
516#define REG_USE02 (REG_USE0 | REG_USE2)
517#define REG_USE012 (REG_USE01 | REG_USE2)
518#define REG_USE12 (REG_USE1 | REG_USE2)
519#define REG_USE23 (REG_USE2 | REG_USE3)
520#define REG_DEF01 (REG_DEF0 | REG_DEF1)
521#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
522#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
523#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
524#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
525#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
526#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
527
528/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800529enum MipsEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 kFmtUnused,
531 kFmtBitBlt, /* Bit string using end/start */
532 kFmtDfp, /* Double FP reg */
533 kFmtSfp, /* Single FP reg */
534 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
Elliott Hughes719ace42012-03-09 18:06:03 -0800535};
buzbeee3acd072012-02-25 17:03:10 -0800536
Ian Rogerscad96062012-03-04 10:33:52 -0800537/* Struct used to define the snippet positions for each MIPS opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800538struct MipsEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 u4 skeleton;
540 struct {
541 MipsEncodingKind kind;
542 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
543 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
544 } fieldLoc[4];
545 MipsOpCode opcode;
546 int flags;
547 const char *name;
548 const char* fmt;
549 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800550};
buzbeee3acd072012-02-25 17:03:10 -0800551
552/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800553enum MipsTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700554 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800555};
buzbeee3acd072012-02-25 17:03:10 -0800556
557extern MipsEncodingMap EncodingMap[kMipsLast];
558
buzbeee3acd072012-02-25 17:03:10 -0800559#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_