blob: 5e5147a96b47a046179d81c4954da92803367522 [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}
jeffhao4f8f04a2012-10-02 18:10:35 -0700150#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0, \
151 INVALID_REG, INVALID_SREG, INVALID_SREG}
buzbee2cfc6392012-05-07 14:51:40 -0700152#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_RESULT0, \
153 r_RESULT1, INVALID_SREG, INVALID_SREG}
jeffhao4f8f04a2012-10-02 18:10:35 -0700154#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0,\
155 r_FRESULT1, INVALID_SREG, INVALID_SREG}
buzbeee3acd072012-02-25 17:03:10 -0800156
Elliott Hughes719ace42012-03-09 18:06:03 -0800157enum ResourceEncodingPos {
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 kGPReg0 = 0,
159 kRegSP = 29,
160 kRegLR = 31,
161 kFPReg0 = 32, /* only 16 fp regs supported currently */
162 kFPRegEnd = 48,
163 kRegHI = kFPRegEnd,
164 kRegLO,
165 kRegPC,
166 kRegEnd = 51,
167 kCCode = kRegEnd,
168 kFPStatus, // FP status word
169 // The following four bits are for memory disambiguation
170 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
171 kLiteral, // 2 Literal pool (can be fully disambiguated)
172 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
173 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800174};
buzbeee3acd072012-02-25 17:03:10 -0800175
176#define ENCODE_REG_LIST(N) ((u8) N)
177#define ENCODE_REG_SP (1ULL << kRegSP)
178#define ENCODE_REG_LR (1ULL << kRegLR)
179#define ENCODE_REG_PC (1ULL << kRegPC)
180#define ENCODE_CCODE (1ULL << kCCode)
181#define ENCODE_FP_STATUS (1ULL << kFPStatus)
182
183/* Abstract memory locations */
184#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
185#define ENCODE_LITERAL (1ULL << kLiteral)
186#define ENCODE_HEAP_REF (1ULL << kHeapRef)
187#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
188
189#define ENCODE_ALL (~0ULL)
190#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
Bill Buzbeea114add2012-05-03 15:00:40 -0700191 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
buzbeee3acd072012-02-25 17:03:10 -0800192
193#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
194#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
195
buzbeee3acd072012-02-25 17:03:10 -0800196/*
buzbeee3acd072012-02-25 17:03:10 -0800197 * Annotate special-purpose core registers:
198 */
199
Elliott Hughes719ace42012-03-09 18:06:03 -0800200enum NativeRegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700201 r_ZERO = 0,
202 r_AT = 1,
203 r_V0 = 2,
204 r_V1 = 3,
205 r_A0 = 4,
206 r_A1 = 5,
207 r_A2 = 6,
208 r_A3 = 7,
209 r_T0 = 8,
210 r_T1 = 9,
211 r_T2 = 10,
212 r_T3 = 11,
213 r_T4 = 12,
214 r_T5 = 13,
215 r_T6 = 14,
216 r_T7 = 15,
217 r_S0 = 16,
218 r_S1 = 17,
219 r_S2 = 18,
220 r_S3 = 19,
221 r_S4 = 20,
222 r_S5 = 21,
223 r_S6 = 22,
224 r_S7 = 23,
225 r_T8 = 24,
226 r_T9 = 25,
227 r_K0 = 26,
228 r_K1 = 27,
229 r_GP = 28,
230 r_SP = 29,
231 r_FP = 30,
232 r_RA = 31,
buzbeee3acd072012-02-25 17:03:10 -0800233
Bill Buzbeea114add2012-05-03 15:00:40 -0700234 r_F0 = 0 + FP_REG_OFFSET,
235 r_F1,
236 r_F2,
237 r_F3,
238 r_F4,
239 r_F5,
240 r_F6,
241 r_F7,
242 r_F8,
243 r_F9,
244 r_F10,
245 r_F11,
246 r_F12,
247 r_F13,
248 r_F14,
249 r_F15,
buzbeee3acd072012-02-25 17:03:10 -0800250#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 r_F16,
252 r_F17,
253 r_F18,
254 r_F19,
255 r_F20,
256 r_F21,
257 r_F22,
258 r_F23,
259 r_F24,
260 r_F25,
261 r_F26,
262 r_F27,
263 r_F28,
264 r_F29,
265 r_F30,
266 r_F31,
buzbeee3acd072012-02-25 17:03:10 -0800267#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 r_DF0 = r_F0 + FP_DOUBLE,
269 r_DF1 = r_F2 + FP_DOUBLE,
270 r_DF2 = r_F4 + FP_DOUBLE,
271 r_DF3 = r_F6 + FP_DOUBLE,
272 r_DF4 = r_F8 + FP_DOUBLE,
273 r_DF5 = r_F10 + FP_DOUBLE,
274 r_DF6 = r_F12 + FP_DOUBLE,
275 r_DF7 = r_F14 + FP_DOUBLE,
buzbeee3acd072012-02-25 17:03:10 -0800276#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700277 r_DF8 = r_F16 + FP_DOUBLE,
278 r_DF9 = r_F18 + FP_DOUBLE,
279 r_DF10 = r_F20 + FP_DOUBLE,
280 r_DF11 = r_F22 + FP_DOUBLE,
281 r_DF12 = r_F24 + FP_DOUBLE,
282 r_DF13 = r_F26 + FP_DOUBLE,
283 r_DF14 = r_F28 + FP_DOUBLE,
284 r_DF15 = r_F30 + FP_DOUBLE,
buzbeee3acd072012-02-25 17:03:10 -0800285#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700286 r_HI = EXTRA_REG_OFFSET,
287 r_LO,
288 r_PC,
Elliott Hughes719ace42012-03-09 18:06:03 -0800289};
buzbeee3acd072012-02-25 17:03:10 -0800290
buzbee5de34942012-03-01 14:51:57 -0800291/*
292 * Target-independent aliases
293 */
294
295#define rSUSPEND r_S0
296#define rSELF r_S1
297#define rSP r_SP
298#define rARG0 r_ARG0
299#define rARG1 r_ARG1
300#define rARG2 r_ARG2
301#define rARG3 r_ARG3
302#define rRET0 r_RESULT0
303#define rRET1 r_RESULT1
jeffhaofa147e22012-10-12 17:03:32 -0700304#define rINVOKE_TGT r_T9
buzbee5de34942012-03-01 14:51:57 -0800305
buzbeee3acd072012-02-25 17:03:10 -0800306/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800307enum MipsShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 kMipsLsl = 0x0,
309 kMipsLsr = 0x1,
310 kMipsAsr = 0x2,
311 kMipsRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800312};
buzbeee3acd072012-02-25 17:03:10 -0800313
buzbeea2ebdd72012-03-04 14:57:06 -0800314// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist)
315#define kSYNC0 0x00
316#define kSYNC_WMB 0x04
317#define kSYNC_MB 0x01
318#define kSYNC_ACQUIRE 0x11
319#define kSYNC_RELEASE 0x12
320#define kSYNC_RMB 0x13
321
322// TODO: Use smaller hammer when appropriate for target CPU
323#define kST kSYNC0
324#define kSY kSYNC0
buzbeee3acd072012-02-25 17:03:10 -0800325
buzbee31a4a6f2012-02-28 15:36:15 -0800326#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800327
328/*
329 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800330 * assembler. Their corresponding EncodingMap positions will be defined in
331 * Assemble.cc.
buzbeee3acd072012-02-25 17:03:10 -0800332 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800333enum MipsOpCode {
Bill Buzbeea5b30242012-09-28 07:19:44 -0700334 kPseudoExportedPC = -18,
buzbee8320f382012-09-11 16:29:42 -0700335 kPseudoSafepointPC = -17,
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_