blob: c5150eec31f70008e606e9de458c977d96c08235 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
18#define ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
Brian Carlstrom7940e442013-07-12 13:46:57 -070019
20#include "dex/compiler_internals.h"
21
22namespace art {
23
24/*
25 * Runtime register conventions.
26 *
27 * zero is always the value 0
28 * at is scratch (normally used as temp reg by assembler)
29 * v0, v1 are scratch (normally hold subroutine return values)
30 * a0-a3 are scratch (normally hold subroutine arguments)
31 * t0-t8 are scratch
32 * t9 is scratch (normally used for function calls)
33 * s0 (rMIPS_SUSPEND) is reserved [holds suspend-check counter]
34 * s1 (rMIPS_SELF) is reserved [holds current &Thread]
35 * s2-s7 are callee save (promotion target)
36 * k0, k1 are reserved for use by interrupt handlers
37 * gp is reserved for global pointer
38 * sp is reserved
39 * s8 is callee save (promotion target)
40 * ra is scratch (normally holds the return addr)
41 *
42 * Preserved across C calls: s0-s8
43 * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra
44 *
45 * Floating pointer registers
46 * NOTE: there are 32 fp registers (16 df pairs), but currently
47 * only support 16 fp registers (8 df pairs).
48 * f0-f15
49 * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
50 *
51 * f0-f15 (df0-df7) trashed across C calls
52 *
53 * For mips32 code use:
54 * a0-a3 to hold operands
55 * v0-v1 to hold results
56 * t0-t9 for temps
57 *
58 * All jump/branch instructions have a delay slot after it.
59 *
60 * Stack frame diagram (stack grows down, higher addresses at top):
61 *
62 * +------------------------+
63 * | IN[ins-1] | {Note: resides in caller's frame}
64 * | . |
65 * | IN[0] |
66 * | caller's Method* |
67 * +========================+ {Note: start of callee's frame}
68 * | spill region | {variable sized - will include lr if non-leaf.}
69 * +------------------------+
70 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
71 * +------------------------+
72 * | V[locals-1] |
73 * | V[locals-2] |
74 * | . |
75 * | . |
76 * | V[1] |
77 * | V[0] |
78 * +------------------------+
79 * | 0 to 3 words padding |
80 * +------------------------+
81 * | OUT[outs-1] |
82 * | OUT[outs-2] |
83 * | . |
84 * | OUT[0] |
85 * | cur_method* | <<== sp w/ 16-byte alignment
86 * +========================+
87 */
88
89// Offset to distingish FP regs.
90#define MIPS_FP_REG_OFFSET 32
91// Offset to distinguish DP FP regs.
92#define MIPS_FP_DOUBLE 64
Brian Carlstrom7940e442013-07-12 13:46:57 -070093// Reg types.
94#define MIPS_REGTYPE(x) (x & (MIPS_FP_REG_OFFSET | MIPS_FP_DOUBLE))
95#define MIPS_FPREG(x) ((x & MIPS_FP_REG_OFFSET) == MIPS_FP_REG_OFFSET)
Brian Carlstrom7940e442013-07-12 13:46:57 -070096#define MIPS_DOUBLEREG(x) ((x & MIPS_FP_DOUBLE) == MIPS_FP_DOUBLE)
97#define MIPS_SINGLEREG(x) (MIPS_FPREG(x) && !MIPS_DOUBLEREG(x))
buzbee9da5c102014-03-28 12:59:18 -070098// FIXME: out of date comment.
Brian Carlstrom7940e442013-07-12 13:46:57 -070099/*
100 * Note: the low register of a floating point pair is sufficient to
101 * create the name of a double, but require both names to be passed to
102 * allow for asserts to verify that the pair is consecutive if significant
103 * rework is done in this area. Also, it is a good reminder in the calling
104 * code that reg locations always describe doubles as a pair of singles.
105 */
Brian Carlstromb1eba212013-07-17 18:07:19 -0700106#define MIPS_S2D(x, y) ((x) | MIPS_FP_DOUBLE)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700107// Mask to strip off fp flags.
108#define MIPS_FP_REG_MASK (MIPS_FP_REG_OFFSET-1)
109
Brian Carlstrom7940e442013-07-12 13:46:57 -0700110#define LOWORD_OFFSET 0
111#define HIWORD_OFFSET 4
buzbee2700f7e2014-03-07 09:46:20 -0800112#define rARG0 rA0
113#define rs_rARG0 rs_rA0
114#define rARG1 rA1
115#define rs_rARG1 rs_rA1
116#define rARG2 rA2
117#define rs_rARG2 rs_rA2
118#define rARG3 rA3
119#define rs_rARG3 rs_rA3
120#define rRESULT0 rV0
121#define rs_rRESULT0 rs_rV0
122#define rRESULT1 rV1
123#define rs_rRESULT1 rs_rV1
Brian Carlstrom7940e442013-07-12 13:46:57 -0700124
buzbee2700f7e2014-03-07 09:46:20 -0800125#define rFARG0 rF12
126#define rs_rFARG0 rs_rF12
127#define rFARG1 rF13
128#define rs_rFARG1 rs_rF13
129#define rFARG2 rF14
130#define rs_rFARG2 rs_rF14
131#define rFARG3 rF15
132#define rs_rFARG3 rs_rF15
133#define rFRESULT0 rF0
134#define rs_rFRESULT0 rs_rF0
135#define rFRESULT1 rF1
136#define rs_rFRESULT1 rs_rF1
Brian Carlstrom7940e442013-07-12 13:46:57 -0700137
138// Regs not used for Mips.
buzbee2700f7e2014-03-07 09:46:20 -0800139#define rMIPS_LR RegStorage::kInvalidRegVal
140#define rMIPS_PC RegStorage::kInvalidRegVal
Brian Carlstrom7940e442013-07-12 13:46:57 -0700141
Brian Carlstrom7940e442013-07-12 13:46:57 -0700142enum MipsResourceEncodingPos {
143 kMipsGPReg0 = 0,
144 kMipsRegSP = 29,
145 kMipsRegLR = 31,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700146 kMipsFPReg0 = 32, // only 16 fp regs supported currently.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700147 kMipsFPRegEnd = 48,
148 kMipsRegHI = kMipsFPRegEnd,
149 kMipsRegLO,
150 kMipsRegPC,
151 kMipsRegEnd = 51,
152};
153
154#define ENCODE_MIPS_REG_LIST(N) (static_cast<uint64_t>(N))
155#define ENCODE_MIPS_REG_SP (1ULL << kMipsRegSP)
156#define ENCODE_MIPS_REG_LR (1ULL << kMipsRegLR)
157#define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC)
buzbee9da5c102014-03-28 12:59:18 -0700158#define ENCODE_MIPS_REG_HI (1ULL << kMipsRegHI)
159#define ENCODE_MIPS_REG_LO (1ULL << kMipsRegLO)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700160
161enum MipsNativeRegisterPool {
buzbee2700f7e2014-03-07 09:46:20 -0800162 rZERO = 0,
163 rAT = 1,
164 rV0 = 2,
165 rV1 = 3,
166 rA0 = 4,
167 rA1 = 5,
168 rA2 = 6,
169 rA3 = 7,
170 rT0 = 8,
171 rT1 = 9,
172 rT2 = 10,
173 rT3 = 11,
174 rT4 = 12,
175 rT5 = 13,
176 rT6 = 14,
177 rT7 = 15,
178 rS0 = 16,
179 rS1 = 17,
180 rS2 = 18,
181 rS3 = 19,
182 rS4 = 20,
183 rS5 = 21,
184 rS6 = 22,
185 rS7 = 23,
186 rT8 = 24,
187 rT9 = 25,
188 rK0 = 26,
189 rK1 = 27,
190 rGP = 28,
191 rSP = 29,
192 rFP = 30,
193 rRA = 31,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700194
buzbee2700f7e2014-03-07 09:46:20 -0800195 rF0 = 0 + MIPS_FP_REG_OFFSET,
196 rF1,
197 rF2,
198 rF3,
199 rF4,
200 rF5,
201 rF6,
202 rF7,
203 rF8,
204 rF9,
205 rF10,
206 rF11,
207 rF12,
208 rF13,
209 rF14,
210 rF15,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700211#if 0
212 /*
213 * TODO: The shared resource mask doesn't have enough bit positions to describe all
214 * MIPS registers. Expand it and enable use of fp registers 16 through 31.
215 */
buzbee2700f7e2014-03-07 09:46:20 -0800216 rF16,
217 rF17,
218 rF18,
219 rF19,
220 rF20,
221 rF21,
222 rF22,
223 rF23,
224 rF24,
225 rF25,
226 rF26,
227 rF27,
228 rF28,
229 rF29,
230 rF30,
231 rF31,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700232#endif
buzbee2700f7e2014-03-07 09:46:20 -0800233 rDF0 = rF0 + MIPS_FP_DOUBLE,
234 rDF1 = rF2 + MIPS_FP_DOUBLE,
235 rDF2 = rF4 + MIPS_FP_DOUBLE,
236 rDF3 = rF6 + MIPS_FP_DOUBLE,
237 rDF4 = rF8 + MIPS_FP_DOUBLE,
238 rDF5 = rF10 + MIPS_FP_DOUBLE,
239 rDF6 = rF12 + MIPS_FP_DOUBLE,
240 rDF7 = rF14 + MIPS_FP_DOUBLE,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700241#if 0 // TODO: expand resource mask to enable use of all MIPS fp registers.
buzbee2700f7e2014-03-07 09:46:20 -0800242 rDF8 = rF16 + MIPS_FP_DOUBLE,
243 rDF9 = rF18 + MIPS_FP_DOUBLE,
244 rDF10 = rF20 + MIPS_FP_DOUBLE,
245 rDF11 = rF22 + MIPS_FP_DOUBLE,
246 rDF12 = rF24 + MIPS_FP_DOUBLE,
247 rDF13 = rF26 + MIPS_FP_DOUBLE,
248 rDF14 = rF28 + MIPS_FP_DOUBLE,
249 rDF15 = rF30 + MIPS_FP_DOUBLE,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700250#endif
Brian Carlstrom7940e442013-07-12 13:46:57 -0700251};
252
buzbee2700f7e2014-03-07 09:46:20 -0800253const RegStorage rs_rZERO(RegStorage::k32BitSolo, rZERO);
254const RegStorage rs_rAT(RegStorage::k32BitSolo, rAT);
255const RegStorage rs_rV0(RegStorage::k32BitSolo, rV0);
256const RegStorage rs_rV1(RegStorage::k32BitSolo, rV1);
257const RegStorage rs_rA0(RegStorage::k32BitSolo, rA0);
258const RegStorage rs_rA1(RegStorage::k32BitSolo, rA1);
259const RegStorage rs_rA2(RegStorage::k32BitSolo, rA2);
260const RegStorage rs_rA3(RegStorage::k32BitSolo, rA3);
261const RegStorage rs_rT0(RegStorage::k32BitSolo, rT0);
262const RegStorage rs_rT1(RegStorage::k32BitSolo, rT1);
263const RegStorage rs_rT2(RegStorage::k32BitSolo, rT2);
264const RegStorage rs_rT3(RegStorage::k32BitSolo, rT3);
265const RegStorage rs_rT4(RegStorage::k32BitSolo, rT4);
266const RegStorage rs_rT5(RegStorage::k32BitSolo, rT5);
267const RegStorage rs_rT6(RegStorage::k32BitSolo, rT6);
268const RegStorage rs_rT7(RegStorage::k32BitSolo, rT7);
269const RegStorage rs_rS0(RegStorage::k32BitSolo, rS0);
270const RegStorage rs_rS1(RegStorage::k32BitSolo, rS1);
271const RegStorage rs_rS2(RegStorage::k32BitSolo, rS2);
272const RegStorage rs_rS3(RegStorage::k32BitSolo, rS3);
273const RegStorage rs_rS4(RegStorage::k32BitSolo, rS4);
274const RegStorage rs_rS5(RegStorage::k32BitSolo, rS5);
275const RegStorage rs_rS6(RegStorage::k32BitSolo, rS6);
276const RegStorage rs_rS7(RegStorage::k32BitSolo, rS7);
277const RegStorage rs_rT8(RegStorage::k32BitSolo, rT8);
278const RegStorage rs_rT9(RegStorage::k32BitSolo, rT9);
279const RegStorage rs_rK0(RegStorage::k32BitSolo, rK0);
280const RegStorage rs_rK1(RegStorage::k32BitSolo, rK1);
281const RegStorage rs_rGP(RegStorage::k32BitSolo, rGP);
282const RegStorage rs_rSP(RegStorage::k32BitSolo, rSP);
283const RegStorage rs_rFP(RegStorage::k32BitSolo, rFP);
284const RegStorage rs_rRA(RegStorage::k32BitSolo, rRA);
285const RegStorage rs_rF12(RegStorage::k32BitSolo, rF12);
286const RegStorage rs_rF13(RegStorage::k32BitSolo, rF13);
287const RegStorage rs_rF14(RegStorage::k32BitSolo, rF14);
288const RegStorage rs_rF15(RegStorage::k32BitSolo, rF15);
289const RegStorage rs_rF0(RegStorage::k32BitSolo, rF0);
290const RegStorage rs_rF1(RegStorage::k32BitSolo, rF1);
291
292// TODO: reduce/eliminate use of these.
293#define rMIPS_SUSPEND rS0
294#define rs_rMIPS_SUSPEND rs_rS0
295#define rMIPS_SELF rS1
296#define rs_rMIPS_SELF rs_rS1
297#define rMIPS_SP rSP
298#define rs_rMIPS_SP rs_rSP
299#define rMIPS_ARG0 rARG0
300#define rs_rMIPS_ARG0 rs_rARG0
301#define rMIPS_ARG1 rARG1
302#define rs_rMIPS_ARG1 rs_rARG1
303#define rMIPS_ARG2 rARG2
304#define rs_rMIPS_ARG2 rs_rARG2
305#define rMIPS_ARG3 rARG3
306#define rs_rMIPS_ARG3 rs_rARG3
307#define rMIPS_FARG0 rFARG0
308#define rs_rMIPS_FARG0 rs_rFARG0
309#define rMIPS_FARG1 rFARG1
310#define rs_rMIPS_FARG1 rs_rFARG1
311#define rMIPS_FARG2 rFARG2
312#define rs_rMIPS_FARG2 rs_rFARG2
313#define rMIPS_FARG3 rFARG3
314#define rs_MIPS_FARG3 rs_rFARG3
315#define rMIPS_RET0 rRESULT0
316#define rs_MIPS_RET0 rs_rRESULT0
317#define rMIPS_RET1 rRESULT1
318#define rs_rMIPS_RET1 rs_rRESULT1
319#define rMIPS_INVOKE_TGT rT9
320#define rs_rMIPS_INVOKE_TGT rs_rT9
321#define rMIPS_COUNT RegStorage::kInvalidRegVal
Brian Carlstrom7940e442013-07-12 13:46:57 -0700322
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000323// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
324const RegLocation mips_loc_c_return
325 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800326 RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000327const RegLocation mips_loc_c_return_wide
328 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800329 RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000330const RegLocation mips_loc_c_return_float
331 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800332 RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000333const RegLocation mips_loc_c_return_double
334 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800335 RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000336
Brian Carlstrom7940e442013-07-12 13:46:57 -0700337enum MipsShiftEncodings {
338 kMipsLsl = 0x0,
339 kMipsLsr = 0x1,
340 kMipsAsr = 0x2,
341 kMipsRor = 0x3
342};
343
344// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
345#define kSYNC0 0x00
346#define kSYNC_WMB 0x04
347#define kSYNC_MB 0x01
348#define kSYNC_ACQUIRE 0x11
349#define kSYNC_RELEASE 0x12
350#define kSYNC_RMB 0x13
351
352// TODO: Use smaller hammer when appropriate for target CPU.
353#define kST kSYNC0
354#define kSY kSYNC0
355
356/*
357 * The following enum defines the list of supported Thumb instructions by the
358 * assembler. Their corresponding EncodingMap positions will be defined in
359 * Assemble.cc.
360 */
361enum MipsOpCode {
362 kMipsFirst = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700363 kMips32BitData = kMipsFirst, // data [31..0].
364 kMipsAddiu, // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700365 kMipsAddu, // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
366 kMipsAnd, // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
367 kMipsAndi, // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
368 kMipsB, // b o [0001000000000000] o[15..0].
369 kMipsBal, // bal o [0000010000010001] o[15..0].
370 // NOTE: the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
371 // range may require updates.
372 kMipsBeq, // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
373 kMipsBeqz, // beqz s,o [000100] s[25..21] [00000] o[15..0].
374 kMipsBgez, // bgez s,o [000001] s[25..21] [00001] o[15..0].
375 kMipsBgtz, // bgtz s,o [000111] s[25..21] [00000] o[15..0].
376 kMipsBlez, // blez s,o [000110] s[25..21] [00000] o[15..0].
377 kMipsBltz, // bltz s,o [000001] s[25..21] [00000] o[15..0].
378 kMipsBnez, // bnez s,o [000101] s[25..21] [00000] o[15..0].
379 kMipsBne, // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
380 kMipsDiv, // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
Brian Carlstrom38f85e42013-07-18 14:45:22 -0700381#if __mips_isa_rev >= 2
Brian Carlstrom7940e442013-07-12 13:46:57 -0700382 kMipsExt, // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
383#endif
384 kMipsJal, // jal t [000011] t[25..0].
385 kMipsJalr, // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
386 kMipsJr, // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
387 kMipsLahi, // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
388 kMipsLalo, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
389 kMipsLui, // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
390 kMipsLb, // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
391 kMipsLbu, // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
392 kMipsLh, // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
393 kMipsLhu, // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
394 kMipsLw, // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
395 kMipsMfhi, // mfhi d [0000000000000000] d[15..11] [00000010000].
396 kMipsMflo, // mflo d [0000000000000000] d[15..11] [00000010010].
397 kMipsMove, // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
398 kMipsMovz, // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
399 kMipsMul, // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
400 kMipsNop, // nop [00000000000000000000000000000000].
401 kMipsNor, // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
402 kMipsOr, // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
403 kMipsOri, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
404 kMipsPref, // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
405 kMipsSb, // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
Brian Carlstrom38f85e42013-07-18 14:45:22 -0700406#if __mips_isa_rev >= 2
Brian Carlstrom7940e442013-07-12 13:46:57 -0700407 kMipsSeb, // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
408 kMipsSeh, // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
409#endif
410 kMipsSh, // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
411 kMipsSll, // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
412 kMipsSllv, // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
413 kMipsSlt, // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
414 kMipsSlti, // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
415 kMipsSltu, // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
416 kMipsSra, // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
417 kMipsSrav, // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
418 kMipsSrl, // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
419 kMipsSrlv, // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
420 kMipsSubu, // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
421 kMipsSw, // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
422 kMipsXor, // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
423 kMipsXori, // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700424 kMipsFadds, // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
425 kMipsFsubs, // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
426 kMipsFmuls, // mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
427 kMipsFdivs, // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
428 kMipsFaddd, // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
429 kMipsFsubd, // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
430 kMipsFmuld, // mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
431 kMipsFdivd, // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
432 kMipsFcvtsd, // cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
433 kMipsFcvtsw, // cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
434 kMipsFcvtds, // cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
435 kMipsFcvtdw, // cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
436 kMipsFcvtws, // cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
437 kMipsFcvtwd, // cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
438 kMipsFmovs, // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
439 kMipsFmovd, // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
440 kMipsFlwc1, // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
441 kMipsFldc1, // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
442 kMipsFswc1, // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
443 kMipsFsdc1, // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700444 kMipsMfc1, // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
445 kMipsMtc1, // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700446 kMipsDelta, // Psuedo for ori t, s, <label>-<label>.
447 kMipsDeltaHi, // Pseudo for lui t, high16(<label>-<label>).
448 kMipsDeltaLo, // Pseudo for ori t, s, low16(<label>-<label>).
Brian Carlstrom7940e442013-07-12 13:46:57 -0700449 kMipsCurrPC, // jal to .+8 to materialize pc.
450 kMipsSync, // sync kind [000000] [0000000000000000] s[10..6] [001111].
451 kMipsUndefined, // undefined [011001xxxxxxxxxxxxxxxx].
452 kMipsLast
453};
454
455// Instruction assembly field_loc kind.
456enum MipsEncodingKind {
457 kFmtUnused,
458 kFmtBitBlt, /* Bit string using end/start */
459 kFmtDfp, /* Double FP reg */
460 kFmtSfp, /* Single FP reg */
461 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
462};
463
464// Struct used to define the snippet positions for each MIPS opcode.
465struct MipsEncodingMap {
466 uint32_t skeleton;
467 struct {
468 MipsEncodingKind kind;
469 int end; // end for kFmtBitBlt, 1-bit slice end for FP regs.
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700470 int start; // start for kFmtBitBlt, 4-bit slice end for FP regs.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700471 } field_loc[4];
472 MipsOpCode opcode;
473 uint64_t flags;
474 const char *name;
475 const char* fmt;
476 int size; // Note: size is in bytes.
477};
478
479extern MipsEncodingMap EncodingMap[kMipsLast];
480
481#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
482#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700483#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) // 2 offsets must fit.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700484
485} // namespace art
486
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700487#endif // ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_