1/*
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_DEX_QUICK_MIPS_MIPS_LIR_H_
18#define ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
19
20#include "dex/reg_location.h"
21#include "dex/reg_storage.h"
22
23namespace art {
24
25/*
26 * Runtime register conventions.
27 *
28 *          mips32            | mips64
29 * $0:      zero is always the value 0
30 * $1:      at is scratch (normally used as temp reg by assembler)
31 * $2,$3:   v0, v1 are scratch (normally hold subroutine return values)
32 * $4-$7:   a0-a3 are scratch (normally hold subroutine arguments)
33 * $8-$11:  t0-t3 are scratch | a4-a7 are scratch (normally hold subroutine arguments)
34 * $12-$15: t4-t7 are scratch | t0-t3 are scratch
35 * $16:     s0 (rSUSPEND) is reserved [holds suspend-check counter]
36 * $17:     s1 (rSELF) is reserved [holds current &Thread]
37 * $18-$23: s2-s7 are callee save (promotion target)
38 * $24:     t8 is scratch
39 * $25:     t9 is scratch (normally used for function calls)
40 * $26,$27: k0, k1 are reserved for use by interrupt handlers
41 * $28:     gp is reserved for global pointer
42 * $29:     sp is reserved
43 * $30:     s8 is callee save (promotion target)
44 * $31:     ra is scratch (normally holds the return addr)
45 *
46 * Preserved across C calls: s0-s8
47 * Trashed across C calls (mips32): at, v0-v1, a0-a3, t0-t9, gp, ra
48 * Trashed across C calls (mips64): at, v0-v1, a0-a7, t0-t3, t8, t9, gp, ra
49 *
50 * Floating pointer registers (mips32)
51 * NOTE: there are 32 fp registers (16 df pairs), but currently
52 *       only support 16 fp registers (8 df pairs).
53 * f0-f15
54 * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
55 *
56 * f0-f15 (df0-df7) trashed across C calls
57 *
58 * Floating pointer registers (mips64)
59 * NOTE: there are 32 fp registers.
60 * f0-f31
61 *
62 * For mips32 code use:
63 *      a0-a3 to hold operands
64 *      v0-v1 to hold results
65 *      t0-t9 for temps
66 *
67 * For mips64 code use:
68 *      a0-a7 to hold operands
69 *      v0-v1 to hold results
70 *      t0-t3, t8-t9 for temps
71 *
72 * All jump/branch instructions have a delay slot after it.
73 *
74 * Stack frame diagram (stack grows down, higher addresses at top):
75 *
76 * +------------------------+
77 * | IN[ins-1]              |  {Note: resides in caller's frame}
78 * |       .                |
79 * | IN[0]                  |
80 * | caller's Method*       |
81 * +========================+  {Note: start of callee's frame}
82 * | spill region           |  {variable sized - will include lr if non-leaf.}
83 * +------------------------+
84 * | ...filler word...      |  {Note: used as 2nd word of V[locals-1] if long]
85 * +------------------------+
86 * | V[locals-1]            |
87 * | V[locals-2]            |
88 * |      .                 |
89 * |      .                 |
90 * | V[1]                   |
91 * | V[0]                   |
92 * +------------------------+
93 * |  0 to 3 words padding  |
94 * +------------------------+
95 * | OUT[outs-1]            |
96 * | OUT[outs-2]            |
97 * |       .                |
98 * | OUT[0]                 |
99 * | cur_method*            | <<== sp w/ 16-byte alignment
100 * +========================+
101 */
102
103
104#define LOWORD_OFFSET 0
105#define HIWORD_OFFSET 4
106
107#define rFARG0 rF12
108#define rs_rFARG0 rs_rF12
109#define rFARG1 rF13
110#define rs_rFARG1 rs_rF13
111#define rFARG2 rF14
112#define rs_rFARG2 rs_rF14
113#define rFARG3 rF15
114#define rs_rFARG3 rs_rF15
115
116enum MipsResourceEncodingPos {
117  kMipsGPReg0   = 0,
118  kMipsRegSP    = 29,
119  kMipsRegLR    = 31,
120  kMipsFPReg0   = 32,  // only 16 fp regs supported currently.
121  kMipsFPRegEnd   = 48,
122  kMipsRegHI    = kMipsFPRegEnd,
123  kMipsRegLO,
124  kMipsRegPC,
125  kMipsRegEnd   = 51,
126  // Mips64 related:
127  kMips64FPRegEnd = 64,
128  kMips64RegPC    = kMips64FPRegEnd,
129  kMips64RegEnd   = 65,
130};
131
132#define ENCODE_MIPS_REG_LIST(N)      (static_cast<uint64_t>(N))
133#define ENCODE_MIPS_REG_SP           (1ULL << kMipsRegSP)
134#define ENCODE_MIPS_REG_LR           (1ULL << kMipsRegLR)
135#define ENCODE_MIPS_REG_PC           (1ULL << kMipsRegPC)
136#define ENCODE_MIPS_REG_HI           (1ULL << kMipsRegHI)
137#define ENCODE_MIPS_REG_LO           (1ULL << kMipsRegLO)
138
139// Set FR_BIT to 0
140// This bit determines how the CPU access FP registers.
141#define FR_BIT   0
142
143enum MipsNativeRegisterPool {  // private marker to avoid generate-operator-out.py from processing.
144  rZERO  = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  0,
145  rZEROd = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  0,
146  rAT    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  1,
147  rATd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  1,
148  rV0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  2,
149  rV0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  2,
150  rV1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  3,
151  rV1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  3,
152  rA0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  4,
153  rA0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  4,
154  rA1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  5,
155  rA1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  5,
156  rA2    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  6,
157  rA2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  6,
158  rA3    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  7,
159  rA3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  7,
160  rT0_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  8,
161  rA4    = rT0_32,
162  rA4d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  8,
163  rT1_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  9,
164  rA5    = rT1_32,
165  rA5d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  9,
166  rT2_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
167  rA6    = rT2_32,
168  rA6d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
169  rT3_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
170  rA7    = rT3_32,
171  rA7d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
172  rT4_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
173  rT0    = rT4_32,
174  rT0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
175  rT5_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
176  rT1    = rT5_32,
177  rT1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
178  rT6_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
179  rT2    = rT6_32,
180  rT2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
181  rT7_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
182  rT3    = rT7_32,
183  rT3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
184  rS0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
185  rS0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 16,
186  rS1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 17,
187  rS1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 17,
188  rS2    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 18,
189  rS2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 18,
190  rS3    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 19,
191  rS3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 19,
192  rS4    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 20,
193  rS4d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 20,
194  rS5    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 21,
195  rS5d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 21,
196  rS6    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 22,
197  rS6d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 22,
198  rS7    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 23,
199  rS7d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 23,
200  rT8    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 24,
201  rT8d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 24,
202  rT9    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 25,
203  rT9d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 25,
204  rK0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 26,
205  rK0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 26,
206  rK1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 27,
207  rK1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 27,
208  rGP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 28,
209  rGPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 28,
210  rSP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 29,
211  rSPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 29,
212  rFP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 30,
213  rFPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 30,
214  rRA    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 31,
215  rRAd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 31,
216
217  rF0  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  0,
218  rF1  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  1,
219  rF2  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  2,
220  rF3  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  3,
221  rF4  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  4,
222  rF5  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  5,
223  rF6  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  6,
224  rF7  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  7,
225  rF8  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  8,
226  rF9  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  9,
227  rF10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
228  rF11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
229  rF12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
230  rF13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
231  rF14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
232  rF15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
233
234  rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
235  rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
236  rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
237  rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
238  rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
239  rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
240  rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
241  rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
242  rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
243  rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
244  rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
245  rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
246  rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
247  rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
248  rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
249  rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
250
251#if 0
252  /*
253   * TODO: The shared resource mask doesn't have enough bit positions to describe all
254   * MIPS registers.  Expand it and enable use of fp registers 16 through 31.
255   */
256  rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
257  rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
258  rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
259  rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
260  rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
261  rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
262  rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
263  rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
264  rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
265  rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
266  rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
267  rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
268  rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
269  rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
270  rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
271  rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
272#endif
273  // Double precision registers where the FPU is in 32-bit mode.
274  rD0_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
275  rD1_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
276  rD2_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
277  rD3_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
278  rD4_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
279  rD5_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
280  rD6_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
281  rD7_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
282#if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
283  rD8_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
284  rD9_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
285  rD10_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
286  rD11_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
287  rD12_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
288  rD13_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
289  rD14_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
290  rD15_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
291#endif
292  // Double precision registers where the FPU is in 64-bit mode.
293  rD0_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
294  rD1_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
295  rD2_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
296  rD3_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
297  rD4_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
298  rD5_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
299  rD6_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
300  rD7_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
301#if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
302  rD8_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
303  rD9_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
304  rD10_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
305  rD11_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
306  rD12_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
307  rD13_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
308  rD14_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
309  rD15_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
310#endif
311
312  rD0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
313  rD1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  1,
314  rD2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
315  rD3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  3,
316  rD4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
317  rD5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  5,
318  rD6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
319  rD7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  7,
320  rD8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
321  rD9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  9,
322  rD10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
323  rD11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
324  rD12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
325  rD13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
326  rD14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
327  rD15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
328  rD16 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
329  rD17 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 17,
330  rD18 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
331  rD19 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 19,
332  rD20 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
333  rD21 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 21,
334  rD22 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
335  rD23 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 23,
336  rD24 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
337  rD25 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 25,
338  rD26 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
339  rD27 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 27,
340  rD28 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
341  rD29 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 29,
342  rD30 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
343  rD31 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 31,
344};
345
346constexpr RegStorage rs_rZERO(RegStorage::kValid | rZERO);
347constexpr RegStorage rs_rAT(RegStorage::kValid | rAT);
348constexpr RegStorage rs_rV0(RegStorage::kValid | rV0);
349constexpr RegStorage rs_rV1(RegStorage::kValid | rV1);
350constexpr RegStorage rs_rA0(RegStorage::kValid | rA0);
351constexpr RegStorage rs_rA1(RegStorage::kValid | rA1);
352constexpr RegStorage rs_rA2(RegStorage::kValid | rA2);
353constexpr RegStorage rs_rA3(RegStorage::kValid | rA3);
354constexpr RegStorage rs_rT0_32(RegStorage::kValid | rT0_32);
355constexpr RegStorage rs_rA4 = rs_rT0_32;
356constexpr RegStorage rs_rT1_32(RegStorage::kValid | rT1_32);
357constexpr RegStorage rs_rA5 = rs_rT1_32;
358constexpr RegStorage rs_rT2_32(RegStorage::kValid | rT2_32);
359constexpr RegStorage rs_rA6 = rs_rT2_32;
360constexpr RegStorage rs_rT3_32(RegStorage::kValid | rT3_32);
361constexpr RegStorage rs_rA7 = rs_rT3_32;
362constexpr RegStorage rs_rT4_32(RegStorage::kValid | rT4_32);
363constexpr RegStorage rs_rT0 = rs_rT4_32;
364constexpr RegStorage rs_rT5_32(RegStorage::kValid | rT5_32);
365constexpr RegStorage rs_rT1 = rs_rT5_32;
366constexpr RegStorage rs_rT6_32(RegStorage::kValid | rT6_32);
367constexpr RegStorage rs_rT2 = rs_rT6_32;
368constexpr RegStorage rs_rT7_32(RegStorage::kValid | rT7_32);
369constexpr RegStorage rs_rT3 = rs_rT7_32;
370constexpr RegStorage rs_rS0(RegStorage::kValid | rS0);
371constexpr RegStorage rs_rS1(RegStorage::kValid | rS1);
372constexpr RegStorage rs_rS2(RegStorage::kValid | rS2);
373constexpr RegStorage rs_rS3(RegStorage::kValid | rS3);
374constexpr RegStorage rs_rS4(RegStorage::kValid | rS4);
375constexpr RegStorage rs_rS5(RegStorage::kValid | rS5);
376constexpr RegStorage rs_rS6(RegStorage::kValid | rS6);
377constexpr RegStorage rs_rS7(RegStorage::kValid | rS7);
378constexpr RegStorage rs_rT8(RegStorage::kValid | rT8);
379constexpr RegStorage rs_rT9(RegStorage::kValid | rT9);
380constexpr RegStorage rs_rK0(RegStorage::kValid | rK0);
381constexpr RegStorage rs_rK1(RegStorage::kValid | rK1);
382constexpr RegStorage rs_rGP(RegStorage::kValid | rGP);
383constexpr RegStorage rs_rSP(RegStorage::kValid | rSP);
384constexpr RegStorage rs_rFP(RegStorage::kValid | rFP);
385constexpr RegStorage rs_rRA(RegStorage::kValid | rRA);
386
387constexpr RegStorage rs_rZEROd(RegStorage::kValid | rZEROd);
388constexpr RegStorage rs_rATd(RegStorage::kValid | rATd);
389constexpr RegStorage rs_rV0d(RegStorage::kValid | rV0d);
390constexpr RegStorage rs_rV1d(RegStorage::kValid | rV1d);
391constexpr RegStorage rs_rA0d(RegStorage::kValid | rA0d);
392constexpr RegStorage rs_rA1d(RegStorage::kValid | rA1d);
393constexpr RegStorage rs_rA2d(RegStorage::kValid | rA2d);
394constexpr RegStorage rs_rA3d(RegStorage::kValid | rA3d);
395constexpr RegStorage rs_rA4d(RegStorage::kValid | rA4d);
396constexpr RegStorage rs_rA5d(RegStorage::kValid | rA5d);
397constexpr RegStorage rs_rA6d(RegStorage::kValid | rA6d);
398constexpr RegStorage rs_rA7d(RegStorage::kValid | rA7d);
399constexpr RegStorage rs_rT0d(RegStorage::kValid | rT0d);
400constexpr RegStorage rs_rT1d(RegStorage::kValid | rT1d);
401constexpr RegStorage rs_rT2d(RegStorage::kValid | rT2d);
402constexpr RegStorage rs_rT3d(RegStorage::kValid | rT3d);
403constexpr RegStorage rs_rS0d(RegStorage::kValid | rS0d);
404constexpr RegStorage rs_rS1d(RegStorage::kValid | rS1d);
405constexpr RegStorage rs_rS2d(RegStorage::kValid | rS2d);
406constexpr RegStorage rs_rS3d(RegStorage::kValid | rS3d);
407constexpr RegStorage rs_rS4d(RegStorage::kValid | rS4d);
408constexpr RegStorage rs_rS5d(RegStorage::kValid | rS5d);
409constexpr RegStorage rs_rS6d(RegStorage::kValid | rS6d);
410constexpr RegStorage rs_rS7d(RegStorage::kValid | rS7d);
411constexpr RegStorage rs_rT8d(RegStorage::kValid | rT8d);
412constexpr RegStorage rs_rT9d(RegStorage::kValid | rT9d);
413constexpr RegStorage rs_rK0d(RegStorage::kValid | rK0d);
414constexpr RegStorage rs_rK1d(RegStorage::kValid | rK1d);
415constexpr RegStorage rs_rGPd(RegStorage::kValid | rGPd);
416constexpr RegStorage rs_rSPd(RegStorage::kValid | rSPd);
417constexpr RegStorage rs_rFPd(RegStorage::kValid | rFPd);
418constexpr RegStorage rs_rRAd(RegStorage::kValid | rRAd);
419
420constexpr RegStorage rs_rF0(RegStorage::kValid | rF0);
421constexpr RegStorage rs_rF1(RegStorage::kValid | rF1);
422constexpr RegStorage rs_rF2(RegStorage::kValid | rF2);
423constexpr RegStorage rs_rF3(RegStorage::kValid | rF3);
424constexpr RegStorage rs_rF4(RegStorage::kValid | rF4);
425constexpr RegStorage rs_rF5(RegStorage::kValid | rF5);
426constexpr RegStorage rs_rF6(RegStorage::kValid | rF6);
427constexpr RegStorage rs_rF7(RegStorage::kValid | rF7);
428constexpr RegStorage rs_rF8(RegStorage::kValid | rF8);
429constexpr RegStorage rs_rF9(RegStorage::kValid | rF9);
430constexpr RegStorage rs_rF10(RegStorage::kValid | rF10);
431constexpr RegStorage rs_rF11(RegStorage::kValid | rF11);
432constexpr RegStorage rs_rF12(RegStorage::kValid | rF12);
433constexpr RegStorage rs_rF13(RegStorage::kValid | rF13);
434constexpr RegStorage rs_rF14(RegStorage::kValid | rF14);
435constexpr RegStorage rs_rF15(RegStorage::kValid | rF15);
436
437constexpr RegStorage rs_rF16(RegStorage::kValid | rF16);
438constexpr RegStorage rs_rF17(RegStorage::kValid | rF17);
439constexpr RegStorage rs_rF18(RegStorage::kValid | rF18);
440constexpr RegStorage rs_rF19(RegStorage::kValid | rF19);
441constexpr RegStorage rs_rF20(RegStorage::kValid | rF20);
442constexpr RegStorage rs_rF21(RegStorage::kValid | rF21);
443constexpr RegStorage rs_rF22(RegStorage::kValid | rF22);
444constexpr RegStorage rs_rF23(RegStorage::kValid | rF23);
445constexpr RegStorage rs_rF24(RegStorage::kValid | rF24);
446constexpr RegStorage rs_rF25(RegStorage::kValid | rF25);
447constexpr RegStorage rs_rF26(RegStorage::kValid | rF26);
448constexpr RegStorage rs_rF27(RegStorage::kValid | rF27);
449constexpr RegStorage rs_rF28(RegStorage::kValid | rF28);
450constexpr RegStorage rs_rF29(RegStorage::kValid | rF29);
451constexpr RegStorage rs_rF30(RegStorage::kValid | rF30);
452constexpr RegStorage rs_rF31(RegStorage::kValid | rF31);
453
454constexpr RegStorage rs_rD0_fr0(RegStorage::kValid | rD0_fr0);
455constexpr RegStorage rs_rD1_fr0(RegStorage::kValid | rD1_fr0);
456constexpr RegStorage rs_rD2_fr0(RegStorage::kValid | rD2_fr0);
457constexpr RegStorage rs_rD3_fr0(RegStorage::kValid | rD3_fr0);
458constexpr RegStorage rs_rD4_fr0(RegStorage::kValid | rD4_fr0);
459constexpr RegStorage rs_rD5_fr0(RegStorage::kValid | rD5_fr0);
460constexpr RegStorage rs_rD6_fr0(RegStorage::kValid | rD6_fr0);
461constexpr RegStorage rs_rD7_fr0(RegStorage::kValid | rD7_fr0);
462
463constexpr RegStorage rs_rD0_fr1(RegStorage::kValid | rD0_fr1);
464constexpr RegStorage rs_rD1_fr1(RegStorage::kValid | rD1_fr1);
465constexpr RegStorage rs_rD2_fr1(RegStorage::kValid | rD2_fr1);
466constexpr RegStorage rs_rD3_fr1(RegStorage::kValid | rD3_fr1);
467constexpr RegStorage rs_rD4_fr1(RegStorage::kValid | rD4_fr1);
468constexpr RegStorage rs_rD5_fr1(RegStorage::kValid | rD5_fr1);
469constexpr RegStorage rs_rD6_fr1(RegStorage::kValid | rD6_fr1);
470constexpr RegStorage rs_rD7_fr1(RegStorage::kValid | rD7_fr1);
471
472constexpr RegStorage rs_rD0(RegStorage::kValid | rD0);
473constexpr RegStorage rs_rD1(RegStorage::kValid | rD1);
474constexpr RegStorage rs_rD2(RegStorage::kValid | rD2);
475constexpr RegStorage rs_rD3(RegStorage::kValid | rD3);
476constexpr RegStorage rs_rD4(RegStorage::kValid | rD4);
477constexpr RegStorage rs_rD5(RegStorage::kValid | rD5);
478constexpr RegStorage rs_rD6(RegStorage::kValid | rD6);
479constexpr RegStorage rs_rD7(RegStorage::kValid | rD7);
480constexpr RegStorage rs_rD8(RegStorage::kValid | rD8);
481constexpr RegStorage rs_rD9(RegStorage::kValid | rD9);
482constexpr RegStorage rs_rD10(RegStorage::kValid | rD10);
483constexpr RegStorage rs_rD11(RegStorage::kValid | rD11);
484constexpr RegStorage rs_rD12(RegStorage::kValid | rD12);
485constexpr RegStorage rs_rD13(RegStorage::kValid | rD13);
486constexpr RegStorage rs_rD14(RegStorage::kValid | rD14);
487constexpr RegStorage rs_rD15(RegStorage::kValid | rD15);
488constexpr RegStorage rs_rD16(RegStorage::kValid | rD16);
489constexpr RegStorage rs_rD17(RegStorage::kValid | rD17);
490constexpr RegStorage rs_rD18(RegStorage::kValid | rD18);
491constexpr RegStorage rs_rD19(RegStorage::kValid | rD19);
492constexpr RegStorage rs_rD20(RegStorage::kValid | rD20);
493constexpr RegStorage rs_rD21(RegStorage::kValid | rD21);
494constexpr RegStorage rs_rD22(RegStorage::kValid | rD22);
495constexpr RegStorage rs_rD23(RegStorage::kValid | rD23);
496constexpr RegStorage rs_rD24(RegStorage::kValid | rD24);
497constexpr RegStorage rs_rD25(RegStorage::kValid | rD25);
498constexpr RegStorage rs_rD26(RegStorage::kValid | rD26);
499constexpr RegStorage rs_rD27(RegStorage::kValid | rD27);
500constexpr RegStorage rs_rD28(RegStorage::kValid | rD28);
501constexpr RegStorage rs_rD29(RegStorage::kValid | rD29);
502constexpr RegStorage rs_rD30(RegStorage::kValid | rD30);
503constexpr RegStorage rs_rD31(RegStorage::kValid | rD31);
504
505// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
506const RegLocation mips_loc_c_return
507    {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
508     RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
509const RegLocation mips64_loc_c_return_ref
510    {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
511     RegStorage(RegStorage::k64BitSolo, rV0d), INVALID_SREG, INVALID_SREG};
512const RegLocation mips_loc_c_return_wide
513    {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
514     RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
515const RegLocation mips64_loc_c_return_wide
516    {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
517     RegStorage(RegStorage::k64BitSolo, rV0d), INVALID_SREG, INVALID_SREG};
518const RegLocation mips_loc_c_return_float
519    {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
520     RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
521// FIXME: move MIPS to k64Bitsolo for doubles
522const RegLocation mips_loc_c_return_double_fr0
523    {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
524     RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
525const RegLocation mips_loc_c_return_double_fr1
526    {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
527     RegStorage(RegStorage::k64BitSolo, rF0), INVALID_SREG, INVALID_SREG};
528const RegLocation mips64_loc_c_return_double
529    {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
530     RegStorage(RegStorage::k64BitSolo, rD0), INVALID_SREG, INVALID_SREG};
531
532enum MipsShiftEncodings {
533  kMipsLsl = 0x0,
534  kMipsLsr = 0x1,
535  kMipsAsr = 0x2,
536  kMipsRor = 0x3
537};
538
539// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
540#define kSYNC0        0x00
541#define kSYNC_WMB     0x04
542#define kSYNC_MB      0x01
543#define kSYNC_ACQUIRE 0x11
544#define kSYNC_RELEASE 0x12
545#define kSYNC_RMB     0x13
546
547// TODO: Use smaller hammer when appropriate for target CPU.
548#define kST kSYNC0
549#define kSY kSYNC0
550
551/*
552 * The following enum defines the list of supported mips instructions by the
553 * assembler. Their corresponding EncodingMap positions will be defined in
554 * assemble_mips.cc.
555 */
556enum MipsOpCode {
557  kMipsFirst = 0,
558  // The following are common mips32r2, mips32r6 and mips64r6 instructions.
559  kMips32BitData = kMipsFirst,  // data [31..0].
560  kMipsAddiu,      // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
561  kMipsAddu,       // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
562  kMipsAnd,        // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
563  kMipsAndi,       // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
564  kMipsB,          // b o   [0001000000000000] o[15..0].
565  kMipsBal,        // bal o [0000010000010001] o[15..0].
566  // NOTE : the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
567  // range may require updates.
568  kMipsBeq,        // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
569  kMipsBeqz,       // beqz s,o [000100] s[25..21] [00000] o[15..0].
570  kMipsBgez,       // bgez s,o [000001] s[25..21] [00001] o[15..0].
571  kMipsBgtz,       // bgtz s,o [000111] s[25..21] [00000] o[15..0].
572  kMipsBlez,       // blez s,o [000110] s[25..21] [00000] o[15..0].
573  kMipsBltz,       // bltz s,o [000001] s[25..21] [00000] o[15..0].
574  kMipsBnez,       // bnez s,o [000101] s[25..21] [00000] o[15..0].
575  kMipsBne,        // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
576  kMipsExt,        // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
577  kMipsFaddd,      // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
578  kMipsFadds,      // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
579  kMipsFsubd,      // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
580  kMipsFsubs,      // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
581  kMipsFdivd,      // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
582  kMipsFdivs,      // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
583  kMipsFmuld,      // mul.d d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
584  kMipsFmuls,      // mul.s d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
585  kMipsFcvtsd,     // cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
586  kMipsFcvtsw,     // cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
587  kMipsFcvtds,     // cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
588  kMipsFcvtdw,     // cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
589  kMipsFcvtwd,     // cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
590  kMipsFcvtws,     // cvt.w.s d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
591  kMipsFmovd,      // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
592  kMipsFmovs,      // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
593  kMipsFnegd,      // neg.d d,s [01000110001] [00000] s[15..11] d[10..6] [000111].
594  kMipsFnegs,      // neg.s d,s [01000110000] [00000] s[15..11] d[10..6] [000111].
595  kMipsFldc1,      // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
596  kMipsFlwc1,      // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
597  kMipsFsdc1,      // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
598  kMipsFswc1,      // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
599  kMipsJal,        // jal t [000011] t[25..0].
600  kMipsJalr,       // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
601  kMipsJr,         // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
602  kMipsLahi,       // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
603  kMipsLalo,       // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
604  kMipsLui,        // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
605  kMipsLb,         // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
606  kMipsLbu,        // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
607  kMipsLh,         // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
608  kMipsLhu,        // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
609  kMipsLw,         // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
610  kMipsMove,       // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
611  kMipsMfc1,       // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
612  kMipsMtc1,       // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
613  kMipsMfhc1,      // mfhc1 t,s [01000100011] t[20..16] s[15..11] [00000000000].
614  kMipsMthc1,      // mthc1 t,s [01000100111] t[20..16] s[15..11] [00000000000].
615  kMipsNop,        // nop [00000000000000000000000000000000].
616  kMipsNor,        // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
617  kMipsOr,         // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
618  kMipsOri,        // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
619  kMipsPref,       // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
620  kMipsSb,         // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
621  kMipsSeb,        // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
622  kMipsSeh,        // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
623  kMipsSh,         // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
624  kMipsSll,        // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
625  kMipsSllv,       // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
626  kMipsSlt,        // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
627  kMipsSlti,       // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
628  kMipsSltu,       // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
629  kMipsSra,        // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
630  kMipsSrav,       // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
631  kMipsSrl,        // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
632  kMipsSrlv,       // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
633  kMipsSubu,       // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
634  kMipsSw,         // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
635  kMipsSync,       // sync kind [000000] [0000000000000000] s[10..6] [001111].
636  kMipsXor,        // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
637  kMipsXori,       // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
638
639  // The following are mips32r2 instructions.
640  kMipsR2Div,      // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
641  kMipsR2Mul,      // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
642  kMipsR2Mfhi,     // mfhi d [0000000000000000] d[15..11] [00000010000].
643  kMipsR2Mflo,     // mflo d [0000000000000000] d[15..11] [00000010010].
644  kMipsR2Movz,     // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
645
646  // The following are mips32r6 and mips64r6 instructions.
647  kMipsR6Div,      // div d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011010].
648  kMipsR6Mod,      // mod d,s,t [000000] s[25..21] t[20..16] d[15..11] [00011011010].
649  kMipsR6Mul,      // mul d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011000].
650
651  // The following are mips64r6 instructions.
652  kMips64Daddiu,   // daddiu t,s,imm16 [011001] s[25..21] t[20..16] imm16[15..11].
653  kMips64Daddu,    // daddu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101101].
654  kMips64Dahi,     // dahi s,imm16 [000001] s[25..21] [00110] imm16[15..11].
655  kMips64Dati,     // dati s,imm16 [000001] s[25..21] [11110] imm16[15..11].
656  kMips64Daui,     // daui t,s,imm16 [011101] s[25..21] t[20..16] imm16[15..11].
657  kMips64Ddiv,     // ddiv  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011110].
658  kMips64Dmod,     // dmod  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00011011110].
659  kMips64Dmul,     // dmul  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011100].
660  kMips64Dmfc1,    // dmfc1 t,s [01000100001] t[20..16] s[15..11] [00000000000].
661  kMips64Dmtc1,    // dmtc1 t,s [01000100101] t[20..16] s[15..11] [00000000000].
662  kMips64Drotr32,  // drotr32 d,t,a [00000000001] t[20..16] d[15..11] a[10..6] [111110].
663  kMips64Dsll,     // dsll    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111000].
664  kMips64Dsll32,   // dsll32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111100].
665  kMips64Dsrl,     // dsrl    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111010].
666  kMips64Dsrl32,   // dsrl32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111110].
667  kMips64Dsra,     // dsra    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111011].
668  kMips64Dsra32,   // dsra32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111111].
669  kMips64Dsllv,    // dsllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010100].
670  kMips64Dsrlv,    // dsrlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010110].
671  kMips64Dsrav,    // dsrav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010111].
672  kMips64Dsubu,    // dsubu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101111].
673  kMips64Ld,       // ld  t,o(b) [110111] b[25..21] t[20..16] o[15..0].
674  kMips64Lwu,      // lwu t,o(b) [100111] b[25..21] t[20..16] o[15..0].
675  kMips64Sd,       // sd t,o(b) [111111] b[25..21] t[20..16] o[15..0].
676
677  // The following are pseudoinstructions.
678  kMipsDelta,      // Psuedo for ori t, s, <label>-<label>.
679  kMipsDeltaHi,    // Pseudo for lui t, high16(<label>-<label>).
680  kMipsDeltaLo,    // Pseudo for ori t, s, low16(<label>-<label>).
681  kMipsCurrPC,     // jal to .+8 to materialize pc.
682  kMipsUndefined,  // undefined [011001xxxxxxxxxxxxxxxx].
683  kMipsLast
684};
685std::ostream& operator<<(std::ostream& os, const MipsOpCode& rhs);
686
687// Instruction assembly field_loc kind.
688enum MipsEncodingKind {
689  kFmtUnused,
690  kFmtBitBlt,    // Bit string using end/start.
691  kFmtDfp,       // Double FP reg.
692  kFmtSfp,       // Single FP reg.
693  kFmtBlt5_2,    // Same 5-bit field to 2 locations.
694};
695std::ostream& operator<<(std::ostream& os, const MipsEncodingKind& rhs);
696
697// Struct used to define the snippet positions for each MIPS opcode.
698struct MipsEncodingMap {
699  uint32_t skeleton;
700  struct {
701    MipsEncodingKind kind;
702    int end;   // end for kFmtBitBlt, 1-bit slice end for FP regs.
703    int start;  // start for kFmtBitBlt, 4-bit slice end for FP regs.
704  } field_loc[4];
705  MipsOpCode opcode;
706  uint64_t flags;
707  const char *name;
708  const char* fmt;
709  int size;   // Note: size is in bytes.
710};
711
712extern MipsEncodingMap EncodingMap[kMipsLast];
713
714#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
715#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
716#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763))  // 2 offsets must fit.
717
718}  // namespace art
719
720#endif  // ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
721