blob: 96cd3d8bb546a16b659231b0bf165c883bf24541 [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
93// Offset to distingish the extra regs.
94#define MIPS_EXTRA_REG_OFFSET 128
95// Reg types.
96#define MIPS_REGTYPE(x) (x & (MIPS_FP_REG_OFFSET | MIPS_FP_DOUBLE))
97#define MIPS_FPREG(x) ((x & MIPS_FP_REG_OFFSET) == MIPS_FP_REG_OFFSET)
98#define MIPS_EXTRAREG(x) ((x & MIPS_EXTRA_REG_OFFSET) == MIPS_EXTRA_REG_OFFSET)
99#define MIPS_DOUBLEREG(x) ((x & MIPS_FP_DOUBLE) == MIPS_FP_DOUBLE)
100#define MIPS_SINGLEREG(x) (MIPS_FPREG(x) && !MIPS_DOUBLEREG(x))
101/*
102 * Note: the low register of a floating point pair is sufficient to
103 * create the name of a double, but require both names to be passed to
104 * allow for asserts to verify that the pair is consecutive if significant
105 * rework is done in this area. Also, it is a good reminder in the calling
106 * code that reg locations always describe doubles as a pair of singles.
107 */
Brian Carlstromb1eba212013-07-17 18:07:19 -0700108#define MIPS_S2D(x, y) ((x) | MIPS_FP_DOUBLE)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700109// Mask to strip off fp flags.
110#define MIPS_FP_REG_MASK (MIPS_FP_REG_OFFSET-1)
111
Brian Carlstrom7940e442013-07-12 13:46:57 -0700112#define LOWORD_OFFSET 0
113#define HIWORD_OFFSET 4
buzbee2700f7e2014-03-07 09:46:20 -0800114#define rARG0 rA0
115#define rs_rARG0 rs_rA0
116#define rARG1 rA1
117#define rs_rARG1 rs_rA1
118#define rARG2 rA2
119#define rs_rARG2 rs_rA2
120#define rARG3 rA3
121#define rs_rARG3 rs_rA3
122#define rRESULT0 rV0
123#define rs_rRESULT0 rs_rV0
124#define rRESULT1 rV1
125#define rs_rRESULT1 rs_rV1
Brian Carlstrom7940e442013-07-12 13:46:57 -0700126
buzbee2700f7e2014-03-07 09:46:20 -0800127#define rFARG0 rF12
128#define rs_rFARG0 rs_rF12
129#define rFARG1 rF13
130#define rs_rFARG1 rs_rF13
131#define rFARG2 rF14
132#define rs_rFARG2 rs_rF14
133#define rFARG3 rF15
134#define rs_rFARG3 rs_rF15
135#define rFRESULT0 rF0
136#define rs_rFRESULT0 rs_rF0
137#define rFRESULT1 rF1
138#define rs_rFRESULT1 rs_rF1
Brian Carlstrom7940e442013-07-12 13:46:57 -0700139
140// Regs not used for Mips.
buzbee2700f7e2014-03-07 09:46:20 -0800141#define rMIPS_LR RegStorage::kInvalidRegVal
142#define rMIPS_PC RegStorage::kInvalidRegVal
Brian Carlstrom7940e442013-07-12 13:46:57 -0700143
Brian Carlstrom7940e442013-07-12 13:46:57 -0700144enum MipsResourceEncodingPos {
145 kMipsGPReg0 = 0,
146 kMipsRegSP = 29,
147 kMipsRegLR = 31,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700148 kMipsFPReg0 = 32, // only 16 fp regs supported currently.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700149 kMipsFPRegEnd = 48,
150 kMipsRegHI = kMipsFPRegEnd,
151 kMipsRegLO,
152 kMipsRegPC,
153 kMipsRegEnd = 51,
154};
155
156#define ENCODE_MIPS_REG_LIST(N) (static_cast<uint64_t>(N))
157#define ENCODE_MIPS_REG_SP (1ULL << kMipsRegSP)
158#define ENCODE_MIPS_REG_LR (1ULL << kMipsRegLR)
159#define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC)
160
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
buzbee2700f7e2014-03-07 09:46:20 -0800251 rHI = MIPS_EXTRA_REG_OFFSET,
252 rLO,
253 rPC,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700254};
255
buzbee2700f7e2014-03-07 09:46:20 -0800256const RegStorage rs_rZERO(RegStorage::k32BitSolo, rZERO);
257const RegStorage rs_rAT(RegStorage::k32BitSolo, rAT);
258const RegStorage rs_rV0(RegStorage::k32BitSolo, rV0);
259const RegStorage rs_rV1(RegStorage::k32BitSolo, rV1);
260const RegStorage rs_rA0(RegStorage::k32BitSolo, rA0);
261const RegStorage rs_rA1(RegStorage::k32BitSolo, rA1);
262const RegStorage rs_rA2(RegStorage::k32BitSolo, rA2);
263const RegStorage rs_rA3(RegStorage::k32BitSolo, rA3);
264const RegStorage rs_rT0(RegStorage::k32BitSolo, rT0);
265const RegStorage rs_rT1(RegStorage::k32BitSolo, rT1);
266const RegStorage rs_rT2(RegStorage::k32BitSolo, rT2);
267const RegStorage rs_rT3(RegStorage::k32BitSolo, rT3);
268const RegStorage rs_rT4(RegStorage::k32BitSolo, rT4);
269const RegStorage rs_rT5(RegStorage::k32BitSolo, rT5);
270const RegStorage rs_rT6(RegStorage::k32BitSolo, rT6);
271const RegStorage rs_rT7(RegStorage::k32BitSolo, rT7);
272const RegStorage rs_rS0(RegStorage::k32BitSolo, rS0);
273const RegStorage rs_rS1(RegStorage::k32BitSolo, rS1);
274const RegStorage rs_rS2(RegStorage::k32BitSolo, rS2);
275const RegStorage rs_rS3(RegStorage::k32BitSolo, rS3);
276const RegStorage rs_rS4(RegStorage::k32BitSolo, rS4);
277const RegStorage rs_rS5(RegStorage::k32BitSolo, rS5);
278const RegStorage rs_rS6(RegStorage::k32BitSolo, rS6);
279const RegStorage rs_rS7(RegStorage::k32BitSolo, rS7);
280const RegStorage rs_rT8(RegStorage::k32BitSolo, rT8);
281const RegStorage rs_rT9(RegStorage::k32BitSolo, rT9);
282const RegStorage rs_rK0(RegStorage::k32BitSolo, rK0);
283const RegStorage rs_rK1(RegStorage::k32BitSolo, rK1);
284const RegStorage rs_rGP(RegStorage::k32BitSolo, rGP);
285const RegStorage rs_rSP(RegStorage::k32BitSolo, rSP);
286const RegStorage rs_rFP(RegStorage::k32BitSolo, rFP);
287const RegStorage rs_rRA(RegStorage::k32BitSolo, rRA);
288const RegStorage rs_rF12(RegStorage::k32BitSolo, rF12);
289const RegStorage rs_rF13(RegStorage::k32BitSolo, rF13);
290const RegStorage rs_rF14(RegStorage::k32BitSolo, rF14);
291const RegStorage rs_rF15(RegStorage::k32BitSolo, rF15);
292const RegStorage rs_rF0(RegStorage::k32BitSolo, rF0);
293const RegStorage rs_rF1(RegStorage::k32BitSolo, rF1);
294
295// TODO: reduce/eliminate use of these.
296#define rMIPS_SUSPEND rS0
297#define rs_rMIPS_SUSPEND rs_rS0
298#define rMIPS_SELF rS1
299#define rs_rMIPS_SELF rs_rS1
300#define rMIPS_SP rSP
301#define rs_rMIPS_SP rs_rSP
302#define rMIPS_ARG0 rARG0
303#define rs_rMIPS_ARG0 rs_rARG0
304#define rMIPS_ARG1 rARG1
305#define rs_rMIPS_ARG1 rs_rARG1
306#define rMIPS_ARG2 rARG2
307#define rs_rMIPS_ARG2 rs_rARG2
308#define rMIPS_ARG3 rARG3
309#define rs_rMIPS_ARG3 rs_rARG3
310#define rMIPS_FARG0 rFARG0
311#define rs_rMIPS_FARG0 rs_rFARG0
312#define rMIPS_FARG1 rFARG1
313#define rs_rMIPS_FARG1 rs_rFARG1
314#define rMIPS_FARG2 rFARG2
315#define rs_rMIPS_FARG2 rs_rFARG2
316#define rMIPS_FARG3 rFARG3
317#define rs_MIPS_FARG3 rs_rFARG3
318#define rMIPS_RET0 rRESULT0
319#define rs_MIPS_RET0 rs_rRESULT0
320#define rMIPS_RET1 rRESULT1
321#define rs_rMIPS_RET1 rs_rRESULT1
322#define rMIPS_INVOKE_TGT rT9
323#define rs_rMIPS_INVOKE_TGT rs_rT9
324#define rMIPS_COUNT RegStorage::kInvalidRegVal
Brian Carlstrom7940e442013-07-12 13:46:57 -0700325
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000326// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
327const RegLocation mips_loc_c_return
328 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800329 RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000330const RegLocation mips_loc_c_return_wide
331 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800332 RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000333const RegLocation mips_loc_c_return_float
334 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800335 RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000336const RegLocation mips_loc_c_return_double
337 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
buzbee2700f7e2014-03-07 09:46:20 -0800338 RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000339
Brian Carlstrom7940e442013-07-12 13:46:57 -0700340enum MipsShiftEncodings {
341 kMipsLsl = 0x0,
342 kMipsLsr = 0x1,
343 kMipsAsr = 0x2,
344 kMipsRor = 0x3
345};
346
347// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
348#define kSYNC0 0x00
349#define kSYNC_WMB 0x04
350#define kSYNC_MB 0x01
351#define kSYNC_ACQUIRE 0x11
352#define kSYNC_RELEASE 0x12
353#define kSYNC_RMB 0x13
354
355// TODO: Use smaller hammer when appropriate for target CPU.
356#define kST kSYNC0
357#define kSY kSYNC0
358
359/*
360 * The following enum defines the list of supported Thumb instructions by the
361 * assembler. Their corresponding EncodingMap positions will be defined in
362 * Assemble.cc.
363 */
364enum MipsOpCode {
365 kMipsFirst = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700366 kMips32BitData = kMipsFirst, // data [31..0].
367 kMipsAddiu, // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700368 kMipsAddu, // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
369 kMipsAnd, // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
370 kMipsAndi, // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
371 kMipsB, // b o [0001000000000000] o[15..0].
372 kMipsBal, // bal o [0000010000010001] o[15..0].
373 // NOTE: the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
374 // range may require updates.
375 kMipsBeq, // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
376 kMipsBeqz, // beqz s,o [000100] s[25..21] [00000] o[15..0].
377 kMipsBgez, // bgez s,o [000001] s[25..21] [00001] o[15..0].
378 kMipsBgtz, // bgtz s,o [000111] s[25..21] [00000] o[15..0].
379 kMipsBlez, // blez s,o [000110] s[25..21] [00000] o[15..0].
380 kMipsBltz, // bltz s,o [000001] s[25..21] [00000] o[15..0].
381 kMipsBnez, // bnez s,o [000101] s[25..21] [00000] o[15..0].
382 kMipsBne, // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
383 kMipsDiv, // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
Brian Carlstrom38f85e42013-07-18 14:45:22 -0700384#if __mips_isa_rev >= 2
Brian Carlstrom7940e442013-07-12 13:46:57 -0700385 kMipsExt, // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
386#endif
387 kMipsJal, // jal t [000011] t[25..0].
388 kMipsJalr, // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
389 kMipsJr, // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
390 kMipsLahi, // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
391 kMipsLalo, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
392 kMipsLui, // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
393 kMipsLb, // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
394 kMipsLbu, // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
395 kMipsLh, // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
396 kMipsLhu, // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
397 kMipsLw, // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
398 kMipsMfhi, // mfhi d [0000000000000000] d[15..11] [00000010000].
399 kMipsMflo, // mflo d [0000000000000000] d[15..11] [00000010010].
400 kMipsMove, // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
401 kMipsMovz, // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
402 kMipsMul, // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
403 kMipsNop, // nop [00000000000000000000000000000000].
404 kMipsNor, // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
405 kMipsOr, // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
406 kMipsOri, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
407 kMipsPref, // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
408 kMipsSb, // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
Brian Carlstrom38f85e42013-07-18 14:45:22 -0700409#if __mips_isa_rev >= 2
Brian Carlstrom7940e442013-07-12 13:46:57 -0700410 kMipsSeb, // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
411 kMipsSeh, // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
412#endif
413 kMipsSh, // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
414 kMipsSll, // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
415 kMipsSllv, // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
416 kMipsSlt, // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
417 kMipsSlti, // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
418 kMipsSltu, // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
419 kMipsSra, // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
420 kMipsSrav, // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
421 kMipsSrl, // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
422 kMipsSrlv, // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
423 kMipsSubu, // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
424 kMipsSw, // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
425 kMipsXor, // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
426 kMipsXori, // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700427 kMipsFadds, // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
428 kMipsFsubs, // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
429 kMipsFmuls, // mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
430 kMipsFdivs, // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
431 kMipsFaddd, // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
432 kMipsFsubd, // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
433 kMipsFmuld, // mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
434 kMipsFdivd, // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
435 kMipsFcvtsd, // cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
436 kMipsFcvtsw, // cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
437 kMipsFcvtds, // cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
438 kMipsFcvtdw, // cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
439 kMipsFcvtws, // cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
440 kMipsFcvtwd, // cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
441 kMipsFmovs, // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
442 kMipsFmovd, // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
443 kMipsFlwc1, // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
444 kMipsFldc1, // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
445 kMipsFswc1, // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
446 kMipsFsdc1, // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700447 kMipsMfc1, // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
448 kMipsMtc1, // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700449 kMipsDelta, // Psuedo for ori t, s, <label>-<label>.
450 kMipsDeltaHi, // Pseudo for lui t, high16(<label>-<label>).
451 kMipsDeltaLo, // Pseudo for ori t, s, low16(<label>-<label>).
Brian Carlstrom7940e442013-07-12 13:46:57 -0700452 kMipsCurrPC, // jal to .+8 to materialize pc.
453 kMipsSync, // sync kind [000000] [0000000000000000] s[10..6] [001111].
454 kMipsUndefined, // undefined [011001xxxxxxxxxxxxxxxx].
455 kMipsLast
456};
457
458// Instruction assembly field_loc kind.
459enum MipsEncodingKind {
460 kFmtUnused,
461 kFmtBitBlt, /* Bit string using end/start */
462 kFmtDfp, /* Double FP reg */
463 kFmtSfp, /* Single FP reg */
464 kFmtBlt5_2, /* Same 5-bit field to 2 locations */
465};
466
467// Struct used to define the snippet positions for each MIPS opcode.
468struct MipsEncodingMap {
469 uint32_t skeleton;
470 struct {
471 MipsEncodingKind kind;
472 int end; // end for kFmtBitBlt, 1-bit slice end for FP regs.
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700473 int start; // start for kFmtBitBlt, 4-bit slice end for FP regs.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700474 } field_loc[4];
475 MipsOpCode opcode;
476 uint64_t flags;
477 const char *name;
478 const char* fmt;
479 int size; // Note: size is in bytes.
480};
481
482extern MipsEncodingMap EncodingMap[kMipsLast];
483
484#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
485#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700486#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) // 2 offsets must fit.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700487
488} // namespace art
489
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700490#endif // ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_