blob: a175706d2b6a40579142e984b5b92c5b38089b93 [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
buzbeeb046e162012-10-30 15:48:42 -0700149/* Regs not used for Mips */
150#define rLR INVALID_REG
151
buzbeee3acd072012-02-25 17:03:10 -0800152/* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
buzbee2cfc6392012-05-07 14:51:40 -0700153#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \
154 INVALID_SREG, INVALID_SREG}
jeffhao4f8f04a2012-10-02 18:10:35 -0700155#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0, \
156 INVALID_REG, INVALID_SREG, INVALID_SREG}
buzbee2cfc6392012-05-07 14:51:40 -0700157#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_RESULT0, \
158 r_RESULT1, INVALID_SREG, INVALID_SREG}
jeffhao4f8f04a2012-10-02 18:10:35 -0700159#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0,\
160 r_FRESULT1, INVALID_SREG, INVALID_SREG}
buzbeee3acd072012-02-25 17:03:10 -0800161
Elliott Hughes719ace42012-03-09 18:06:03 -0800162enum ResourceEncodingPos {
Bill Buzbeea114add2012-05-03 15:00:40 -0700163 kGPReg0 = 0,
164 kRegSP = 29,
165 kRegLR = 31,
166 kFPReg0 = 32, /* only 16 fp regs supported currently */
167 kFPRegEnd = 48,
168 kRegHI = kFPRegEnd,
169 kRegLO,
170 kRegPC,
171 kRegEnd = 51,
172 kCCode = kRegEnd,
173 kFPStatus, // FP status word
174 // The following four bits are for memory disambiguation
175 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
176 kLiteral, // 2 Literal pool (can be fully disambiguated)
177 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
178 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800179};
buzbeee3acd072012-02-25 17:03:10 -0800180
181#define ENCODE_REG_LIST(N) ((u8) N)
182#define ENCODE_REG_SP (1ULL << kRegSP)
183#define ENCODE_REG_LR (1ULL << kRegLR)
184#define ENCODE_REG_PC (1ULL << kRegPC)
185#define ENCODE_CCODE (1ULL << kCCode)
186#define ENCODE_FP_STATUS (1ULL << kFPStatus)
187
188/* Abstract memory locations */
189#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
190#define ENCODE_LITERAL (1ULL << kLiteral)
191#define ENCODE_HEAP_REF (1ULL << kHeapRef)
192#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
193
194#define ENCODE_ALL (~0ULL)
195#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
Bill Buzbeea114add2012-05-03 15:00:40 -0700196 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
buzbeee3acd072012-02-25 17:03:10 -0800197
198#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
199#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
200
buzbeee3acd072012-02-25 17:03:10 -0800201/*
buzbeee3acd072012-02-25 17:03:10 -0800202 * Annotate special-purpose core registers:
203 */
204
Elliott Hughes719ace42012-03-09 18:06:03 -0800205enum NativeRegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700206 r_ZERO = 0,
207 r_AT = 1,
208 r_V0 = 2,
209 r_V1 = 3,
210 r_A0 = 4,
211 r_A1 = 5,
212 r_A2 = 6,
213 r_A3 = 7,
214 r_T0 = 8,
215 r_T1 = 9,
216 r_T2 = 10,
217 r_T3 = 11,
218 r_T4 = 12,
219 r_T5 = 13,
220 r_T6 = 14,
221 r_T7 = 15,
222 r_S0 = 16,
223 r_S1 = 17,
224 r_S2 = 18,
225 r_S3 = 19,
226 r_S4 = 20,
227 r_S5 = 21,
228 r_S6 = 22,
229 r_S7 = 23,
230 r_T8 = 24,
231 r_T9 = 25,
232 r_K0 = 26,
233 r_K1 = 27,
234 r_GP = 28,
235 r_SP = 29,
236 r_FP = 30,
237 r_RA = 31,
buzbeee3acd072012-02-25 17:03:10 -0800238
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 r_F0 = 0 + FP_REG_OFFSET,
240 r_F1,
241 r_F2,
242 r_F3,
243 r_F4,
244 r_F5,
245 r_F6,
246 r_F7,
247 r_F8,
248 r_F9,
249 r_F10,
250 r_F11,
251 r_F12,
252 r_F13,
253 r_F14,
254 r_F15,
buzbeee3acd072012-02-25 17:03:10 -0800255#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700256 r_F16,
257 r_F17,
258 r_F18,
259 r_F19,
260 r_F20,
261 r_F21,
262 r_F22,
263 r_F23,
264 r_F24,
265 r_F25,
266 r_F26,
267 r_F27,
268 r_F28,
269 r_F29,
270 r_F30,
271 r_F31,
buzbeee3acd072012-02-25 17:03:10 -0800272#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 r_DF0 = r_F0 + FP_DOUBLE,
274 r_DF1 = r_F2 + FP_DOUBLE,
275 r_DF2 = r_F4 + FP_DOUBLE,
276 r_DF3 = r_F6 + FP_DOUBLE,
277 r_DF4 = r_F8 + FP_DOUBLE,
278 r_DF5 = r_F10 + FP_DOUBLE,
279 r_DF6 = r_F12 + FP_DOUBLE,
280 r_DF7 = r_F14 + FP_DOUBLE,
buzbeee3acd072012-02-25 17:03:10 -0800281#if 0 /* only 16 fp regs supported currently */
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 r_DF8 = r_F16 + FP_DOUBLE,
283 r_DF9 = r_F18 + FP_DOUBLE,
284 r_DF10 = r_F20 + FP_DOUBLE,
285 r_DF11 = r_F22 + FP_DOUBLE,
286 r_DF12 = r_F24 + FP_DOUBLE,
287 r_DF13 = r_F26 + FP_DOUBLE,
288 r_DF14 = r_F28 + FP_DOUBLE,
289 r_DF15 = r_F30 + FP_DOUBLE,
buzbeee3acd072012-02-25 17:03:10 -0800290#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 r_HI = EXTRA_REG_OFFSET,
292 r_LO,
293 r_PC,
Elliott Hughes719ace42012-03-09 18:06:03 -0800294};
buzbeee3acd072012-02-25 17:03:10 -0800295
buzbee5de34942012-03-01 14:51:57 -0800296/*
297 * Target-independent aliases
298 */
299
300#define rSUSPEND r_S0
301#define rSELF r_S1
302#define rSP r_SP
303#define rARG0 r_ARG0
304#define rARG1 r_ARG1
305#define rARG2 r_ARG2
306#define rARG3 r_ARG3
jeffhao30a33172012-10-22 18:16:22 -0700307#define rFARG0 r_FARG0
308#define rFARG1 r_FARG1
309#define rFARG2 r_FARG2
310#define rFARG3 r_FARG3
buzbee5de34942012-03-01 14:51:57 -0800311#define rRET0 r_RESULT0
312#define rRET1 r_RESULT1
jeffhaofa147e22012-10-12 17:03:32 -0700313#define rINVOKE_TGT r_T9
buzbeeb046e162012-10-30 15:48:42 -0700314#define rCOUNT INVALID_REG
buzbee5de34942012-03-01 14:51:57 -0800315
buzbeee3acd072012-02-25 17:03:10 -0800316/* Shift encodings */
Elliott Hughes719ace42012-03-09 18:06:03 -0800317enum MipsShiftEncodings {
Bill Buzbeea114add2012-05-03 15:00:40 -0700318 kMipsLsl = 0x0,
319 kMipsLsr = 0x1,
320 kMipsAsr = 0x2,
321 kMipsRor = 0x3
Elliott Hughes719ace42012-03-09 18:06:03 -0800322};
buzbeee3acd072012-02-25 17:03:10 -0800323
buzbeea2ebdd72012-03-04 14:57:06 -0800324// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist)
325#define kSYNC0 0x00
326#define kSYNC_WMB 0x04
327#define kSYNC_MB 0x01
328#define kSYNC_ACQUIRE 0x11
329#define kSYNC_RELEASE 0x12
330#define kSYNC_RMB 0x13
331
332// TODO: Use smaller hammer when appropriate for target CPU
333#define kST kSYNC0
334#define kSY kSYNC0
buzbeee3acd072012-02-25 17:03:10 -0800335
buzbee31a4a6f2012-02-28 15:36:15 -0800336#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
buzbeee3acd072012-02-25 17:03:10 -0800337
338/*
339 * The following enum defines the list of supported Thumb instructions by the
Ian Rogersde797832012-03-06 10:18:10 -0800340 * assembler. Their corresponding EncodingMap positions will be defined in
341 * Assemble.cc.
buzbeee3acd072012-02-25 17:03:10 -0800342 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800343enum MipsOpCode {
buzbeeb046e162012-10-30 15:48:42 -0700344 kMipsFirst = 0,
Bill Buzbeea114add2012-05-03 15:00:40 -0700345 kMips32BitData = kMipsFirst, /* data [31..0] */
346 kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
347 kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
348 kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
349 kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
350 kMipsB, /* b o [0001000000000000] o[15..0] */
351 kMipsBal, /* bal o [0000010000010001] o[15..0] */
352 /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
353 adding an instruction in this range may require updates */
354 kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
355 kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
356 kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
357 kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
358 kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
359 kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
360 kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
361 kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
362 kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
buzbeee3acd072012-02-25 17:03:10 -0800363#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700364 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 -0800365#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700366 kMipsJal, /* jal t [000011] t[25..0] */
367 kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
368 hint[10..6] [001001] */
369 kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
370 kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
371 kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
372 kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
373 kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
374 kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
375 kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
376 kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
377 kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
378 kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
379 kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
380 kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
381 kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
382 kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
383 kMipsNop, /* nop [00000000000000000000000000000000] */
384 kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
385 kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
386 kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
387 kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
388 kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800389#if __mips_isa_rev>=2
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
391 kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
buzbeee3acd072012-02-25 17:03:10 -0800392#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700393 kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
394 kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
395 kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
396 kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
397 kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
398 kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
399 kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
400 kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
401 kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
402 kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
403 kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
404 kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
405 kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
406 kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
buzbeee3acd072012-02-25 17:03:10 -0800407#ifdef __mips_hard_float
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
409 kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
410 kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
411 kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
412 kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
413 kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
414 kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
415 kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
416 kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
417 kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
418 kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
419 kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
420 kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
421 kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
422 kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
423 kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
424 kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
425 kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
426 kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
427 kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
428 kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
429 kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
buzbeee3acd072012-02-25 17:03:10 -0800430#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
432 kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
433 kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
434 kMipsCurrPC, /* jal to .+8 to materialize pc */
435 kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
436 kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
437 kMipsLast
Elliott Hughes719ace42012-03-09 18:06:03 -0800438};
buzbeee3acd072012-02-25 17:03:10 -0800439
440/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800441enum MipsOpFeatureFlags {
Bill Buzbeea114add2012-05-03 15:00:40 -0700442 kIsBranch = 0,
443 kRegDef0,
444 kRegDef1,
445 kRegDefSP,
446 kRegDefLR,
447 kRegDefList0,
448 kRegDefList1,
449 kRegUse0,
450 kRegUse1,
451 kRegUse2,
452 kRegUse3,
453 kRegUseSP,
454 kRegUsePC,
455 kRegUseList0,
456 kRegUseList1,
457 kNoOperand,
458 kIsUnaryOp,
459 kIsBinaryOp,
460 kIsTertiaryOp,
461 kIsQuadOp,
462 kIsIT,
463 kSetsCCodes,
464 kUsesCCodes,
465 kMemLoad,
466 kMemStore,
467 kPCRelFixup,
468 kRegUseLR,
Elliott Hughes719ace42012-03-09 18:06:03 -0800469};
buzbeee3acd072012-02-25 17:03:10 -0800470
471#define IS_LOAD (1 << kMemLoad)
472#define IS_STORE (1 << kMemStore)
473#define IS_BRANCH (1 << kIsBranch)
474#define REG_DEF0 (1 << kRegDef0)
475#define REG_DEF1 (1 << kRegDef1)
476#define REG_DEF_SP (1 << kRegDefSP)
477#define REG_DEF_LR (1 << kRegDefLR)
478#define REG_DEF_LIST0 (1 << kRegDefList0)
479#define REG_DEF_LIST1 (1 << kRegDefList1)
480#define REG_USE0 (1 << kRegUse0)
481#define REG_USE1 (1 << kRegUse1)
482#define REG_USE2 (1 << kRegUse2)
483#define REG_USE3 (1 << kRegUse3)
484#define REG_USE_SP (1 << kRegUseSP)
485#define REG_USE_PC (1 << kRegUsePC)
486#define REG_USE_LIST0 (1 << kRegUseList0)
487#define REG_USE_LIST1 (1 << kRegUseList1)
488#define NO_OPERAND (1 << kNoOperand)
489#define IS_UNARY_OP (1 << kIsUnaryOp)
490#define IS_BINARY_OP (1 << kIsBinaryOp)
491#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
492#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800493#define IS_QUIN_OP 0
buzbeee3acd072012-02-25 17:03:10 -0800494#define IS_IT (1 << kIsIT)
495#define SETS_CCODES (1 << kSetsCCodes)
496#define USES_CCODES (1 << kUsesCCodes)
buzbeec5159d52012-03-03 11:48:39 -0800497#define NEEDS_FIXUP (1 << kPCRelFixup)
498#define REG_USE_LR (1 << kRegUseLR)
buzbee5de34942012-03-01 14:51:57 -0800499
500/* attributes, included for compatibility */
501#define REG_DEF_FPCS_LIST0 (0)
502#define REG_DEF_FPCS_LIST2 (0)
503
buzbeee3acd072012-02-25 17:03:10 -0800504
505/* Common combo register usage patterns */
506#define REG_USE01 (REG_USE0 | REG_USE1)
507#define REG_USE02 (REG_USE0 | REG_USE2)
508#define REG_USE012 (REG_USE01 | REG_USE2)
509#define REG_USE12 (REG_USE1 | REG_USE2)
510#define REG_USE23 (REG_USE2 | REG_USE3)
511#define REG_DEF01 (REG_DEF0 | REG_DEF1)
512#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
513#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
514#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
515#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
516#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
517#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
518
519/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800520enum MipsEncodingKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 kFmtUnused,
522 kFmtBitBlt, /* Bit string using end/start */
523 kFmtDfp, /* Double FP reg */
524 kFmtSfp, /* Single FP reg */
525 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
Elliott Hughes719ace42012-03-09 18:06:03 -0800526};
buzbeee3acd072012-02-25 17:03:10 -0800527
Ian Rogerscad96062012-03-04 10:33:52 -0800528/* Struct used to define the snippet positions for each MIPS opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800529struct MipsEncodingMap {
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 u4 skeleton;
531 struct {
532 MipsEncodingKind kind;
533 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
534 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
535 } fieldLoc[4];
536 MipsOpCode opcode;
537 int flags;
538 const char *name;
539 const char* fmt;
540 int size; /* Size in bytes */
Elliott Hughes719ace42012-03-09 18:06:03 -0800541};
buzbeee3acd072012-02-25 17:03:10 -0800542
543/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800544enum MipsTargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800546};
buzbeee3acd072012-02-25 17:03:10 -0800547
548extern MipsEncodingMap EncodingMap[kMipsLast];
549
buzbeee3acd072012-02-25 17:03:10 -0800550#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
551#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
552#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
553
554} // namespace art
555
556#endif // ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_