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 
23 namespace 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 
116 enum 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 
143 enum 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 
346 constexpr RegStorage rs_rZERO(RegStorage::kValid | rZERO);
347 constexpr RegStorage rs_rAT(RegStorage::kValid | rAT);
348 constexpr RegStorage rs_rV0(RegStorage::kValid | rV0);
349 constexpr RegStorage rs_rV1(RegStorage::kValid | rV1);
350 constexpr RegStorage rs_rA0(RegStorage::kValid | rA0);
351 constexpr RegStorage rs_rA1(RegStorage::kValid | rA1);
352 constexpr RegStorage rs_rA2(RegStorage::kValid | rA2);
353 constexpr RegStorage rs_rA3(RegStorage::kValid | rA3);
354 constexpr RegStorage rs_rT0_32(RegStorage::kValid | rT0_32);
355 constexpr RegStorage rs_rA4 = rs_rT0_32;
356 constexpr RegStorage rs_rT1_32(RegStorage::kValid | rT1_32);
357 constexpr RegStorage rs_rA5 = rs_rT1_32;
358 constexpr RegStorage rs_rT2_32(RegStorage::kValid | rT2_32);
359 constexpr RegStorage rs_rA6 = rs_rT2_32;
360 constexpr RegStorage rs_rT3_32(RegStorage::kValid | rT3_32);
361 constexpr RegStorage rs_rA7 = rs_rT3_32;
362 constexpr RegStorage rs_rT4_32(RegStorage::kValid | rT4_32);
363 constexpr RegStorage rs_rT0 = rs_rT4_32;
364 constexpr RegStorage rs_rT5_32(RegStorage::kValid | rT5_32);
365 constexpr RegStorage rs_rT1 = rs_rT5_32;
366 constexpr RegStorage rs_rT6_32(RegStorage::kValid | rT6_32);
367 constexpr RegStorage rs_rT2 = rs_rT6_32;
368 constexpr RegStorage rs_rT7_32(RegStorage::kValid | rT7_32);
369 constexpr RegStorage rs_rT3 = rs_rT7_32;
370 constexpr RegStorage rs_rS0(RegStorage::kValid | rS0);
371 constexpr RegStorage rs_rS1(RegStorage::kValid | rS1);
372 constexpr RegStorage rs_rS2(RegStorage::kValid | rS2);
373 constexpr RegStorage rs_rS3(RegStorage::kValid | rS3);
374 constexpr RegStorage rs_rS4(RegStorage::kValid | rS4);
375 constexpr RegStorage rs_rS5(RegStorage::kValid | rS5);
376 constexpr RegStorage rs_rS6(RegStorage::kValid | rS6);
377 constexpr RegStorage rs_rS7(RegStorage::kValid | rS7);
378 constexpr RegStorage rs_rT8(RegStorage::kValid | rT8);
379 constexpr RegStorage rs_rT9(RegStorage::kValid | rT9);
380 constexpr RegStorage rs_rK0(RegStorage::kValid | rK0);
381 constexpr RegStorage rs_rK1(RegStorage::kValid | rK1);
382 constexpr RegStorage rs_rGP(RegStorage::kValid | rGP);
383 constexpr RegStorage rs_rSP(RegStorage::kValid | rSP);
384 constexpr RegStorage rs_rFP(RegStorage::kValid | rFP);
385 constexpr RegStorage rs_rRA(RegStorage::kValid | rRA);
386 
387 constexpr RegStorage rs_rZEROd(RegStorage::kValid | rZEROd);
388 constexpr RegStorage rs_rATd(RegStorage::kValid | rATd);
389 constexpr RegStorage rs_rV0d(RegStorage::kValid | rV0d);
390 constexpr RegStorage rs_rV1d(RegStorage::kValid | rV1d);
391 constexpr RegStorage rs_rA0d(RegStorage::kValid | rA0d);
392 constexpr RegStorage rs_rA1d(RegStorage::kValid | rA1d);
393 constexpr RegStorage rs_rA2d(RegStorage::kValid | rA2d);
394 constexpr RegStorage rs_rA3d(RegStorage::kValid | rA3d);
395 constexpr RegStorage rs_rA4d(RegStorage::kValid | rA4d);
396 constexpr RegStorage rs_rA5d(RegStorage::kValid | rA5d);
397 constexpr RegStorage rs_rA6d(RegStorage::kValid | rA6d);
398 constexpr RegStorage rs_rA7d(RegStorage::kValid | rA7d);
399 constexpr RegStorage rs_rT0d(RegStorage::kValid | rT0d);
400 constexpr RegStorage rs_rT1d(RegStorage::kValid | rT1d);
401 constexpr RegStorage rs_rT2d(RegStorage::kValid | rT2d);
402 constexpr RegStorage rs_rT3d(RegStorage::kValid | rT3d);
403 constexpr RegStorage rs_rS0d(RegStorage::kValid | rS0d);
404 constexpr RegStorage rs_rS1d(RegStorage::kValid | rS1d);
405 constexpr RegStorage rs_rS2d(RegStorage::kValid | rS2d);
406 constexpr RegStorage rs_rS3d(RegStorage::kValid | rS3d);
407 constexpr RegStorage rs_rS4d(RegStorage::kValid | rS4d);
408 constexpr RegStorage rs_rS5d(RegStorage::kValid | rS5d);
409 constexpr RegStorage rs_rS6d(RegStorage::kValid | rS6d);
410 constexpr RegStorage rs_rS7d(RegStorage::kValid | rS7d);
411 constexpr RegStorage rs_rT8d(RegStorage::kValid | rT8d);
412 constexpr RegStorage rs_rT9d(RegStorage::kValid | rT9d);
413 constexpr RegStorage rs_rK0d(RegStorage::kValid | rK0d);
414 constexpr RegStorage rs_rK1d(RegStorage::kValid | rK1d);
415 constexpr RegStorage rs_rGPd(RegStorage::kValid | rGPd);
416 constexpr RegStorage rs_rSPd(RegStorage::kValid | rSPd);
417 constexpr RegStorage rs_rFPd(RegStorage::kValid | rFPd);
418 constexpr RegStorage rs_rRAd(RegStorage::kValid | rRAd);
419 
420 constexpr RegStorage rs_rF0(RegStorage::kValid | rF0);
421 constexpr RegStorage rs_rF1(RegStorage::kValid | rF1);
422 constexpr RegStorage rs_rF2(RegStorage::kValid | rF2);
423 constexpr RegStorage rs_rF3(RegStorage::kValid | rF3);
424 constexpr RegStorage rs_rF4(RegStorage::kValid | rF4);
425 constexpr RegStorage rs_rF5(RegStorage::kValid | rF5);
426 constexpr RegStorage rs_rF6(RegStorage::kValid | rF6);
427 constexpr RegStorage rs_rF7(RegStorage::kValid | rF7);
428 constexpr RegStorage rs_rF8(RegStorage::kValid | rF8);
429 constexpr RegStorage rs_rF9(RegStorage::kValid | rF9);
430 constexpr RegStorage rs_rF10(RegStorage::kValid | rF10);
431 constexpr RegStorage rs_rF11(RegStorage::kValid | rF11);
432 constexpr RegStorage rs_rF12(RegStorage::kValid | rF12);
433 constexpr RegStorage rs_rF13(RegStorage::kValid | rF13);
434 constexpr RegStorage rs_rF14(RegStorage::kValid | rF14);
435 constexpr RegStorage rs_rF15(RegStorage::kValid | rF15);
436 
437 constexpr RegStorage rs_rF16(RegStorage::kValid | rF16);
438 constexpr RegStorage rs_rF17(RegStorage::kValid | rF17);
439 constexpr RegStorage rs_rF18(RegStorage::kValid | rF18);
440 constexpr RegStorage rs_rF19(RegStorage::kValid | rF19);
441 constexpr RegStorage rs_rF20(RegStorage::kValid | rF20);
442 constexpr RegStorage rs_rF21(RegStorage::kValid | rF21);
443 constexpr RegStorage rs_rF22(RegStorage::kValid | rF22);
444 constexpr RegStorage rs_rF23(RegStorage::kValid | rF23);
445 constexpr RegStorage rs_rF24(RegStorage::kValid | rF24);
446 constexpr RegStorage rs_rF25(RegStorage::kValid | rF25);
447 constexpr RegStorage rs_rF26(RegStorage::kValid | rF26);
448 constexpr RegStorage rs_rF27(RegStorage::kValid | rF27);
449 constexpr RegStorage rs_rF28(RegStorage::kValid | rF28);
450 constexpr RegStorage rs_rF29(RegStorage::kValid | rF29);
451 constexpr RegStorage rs_rF30(RegStorage::kValid | rF30);
452 constexpr RegStorage rs_rF31(RegStorage::kValid | rF31);
453 
454 constexpr RegStorage rs_rD0_fr0(RegStorage::kValid | rD0_fr0);
455 constexpr RegStorage rs_rD1_fr0(RegStorage::kValid | rD1_fr0);
456 constexpr RegStorage rs_rD2_fr0(RegStorage::kValid | rD2_fr0);
457 constexpr RegStorage rs_rD3_fr0(RegStorage::kValid | rD3_fr0);
458 constexpr RegStorage rs_rD4_fr0(RegStorage::kValid | rD4_fr0);
459 constexpr RegStorage rs_rD5_fr0(RegStorage::kValid | rD5_fr0);
460 constexpr RegStorage rs_rD6_fr0(RegStorage::kValid | rD6_fr0);
461 constexpr RegStorage rs_rD7_fr0(RegStorage::kValid | rD7_fr0);
462 
463 constexpr RegStorage rs_rD0_fr1(RegStorage::kValid | rD0_fr1);
464 constexpr RegStorage rs_rD1_fr1(RegStorage::kValid | rD1_fr1);
465 constexpr RegStorage rs_rD2_fr1(RegStorage::kValid | rD2_fr1);
466 constexpr RegStorage rs_rD3_fr1(RegStorage::kValid | rD3_fr1);
467 constexpr RegStorage rs_rD4_fr1(RegStorage::kValid | rD4_fr1);
468 constexpr RegStorage rs_rD5_fr1(RegStorage::kValid | rD5_fr1);
469 constexpr RegStorage rs_rD6_fr1(RegStorage::kValid | rD6_fr1);
470 constexpr RegStorage rs_rD7_fr1(RegStorage::kValid | rD7_fr1);
471 
472 constexpr RegStorage rs_rD0(RegStorage::kValid | rD0);
473 constexpr RegStorage rs_rD1(RegStorage::kValid | rD1);
474 constexpr RegStorage rs_rD2(RegStorage::kValid | rD2);
475 constexpr RegStorage rs_rD3(RegStorage::kValid | rD3);
476 constexpr RegStorage rs_rD4(RegStorage::kValid | rD4);
477 constexpr RegStorage rs_rD5(RegStorage::kValid | rD5);
478 constexpr RegStorage rs_rD6(RegStorage::kValid | rD6);
479 constexpr RegStorage rs_rD7(RegStorage::kValid | rD7);
480 constexpr RegStorage rs_rD8(RegStorage::kValid | rD8);
481 constexpr RegStorage rs_rD9(RegStorage::kValid | rD9);
482 constexpr RegStorage rs_rD10(RegStorage::kValid | rD10);
483 constexpr RegStorage rs_rD11(RegStorage::kValid | rD11);
484 constexpr RegStorage rs_rD12(RegStorage::kValid | rD12);
485 constexpr RegStorage rs_rD13(RegStorage::kValid | rD13);
486 constexpr RegStorage rs_rD14(RegStorage::kValid | rD14);
487 constexpr RegStorage rs_rD15(RegStorage::kValid | rD15);
488 constexpr RegStorage rs_rD16(RegStorage::kValid | rD16);
489 constexpr RegStorage rs_rD17(RegStorage::kValid | rD17);
490 constexpr RegStorage rs_rD18(RegStorage::kValid | rD18);
491 constexpr RegStorage rs_rD19(RegStorage::kValid | rD19);
492 constexpr RegStorage rs_rD20(RegStorage::kValid | rD20);
493 constexpr RegStorage rs_rD21(RegStorage::kValid | rD21);
494 constexpr RegStorage rs_rD22(RegStorage::kValid | rD22);
495 constexpr RegStorage rs_rD23(RegStorage::kValid | rD23);
496 constexpr RegStorage rs_rD24(RegStorage::kValid | rD24);
497 constexpr RegStorage rs_rD25(RegStorage::kValid | rD25);
498 constexpr RegStorage rs_rD26(RegStorage::kValid | rD26);
499 constexpr RegStorage rs_rD27(RegStorage::kValid | rD27);
500 constexpr RegStorage rs_rD28(RegStorage::kValid | rD28);
501 constexpr RegStorage rs_rD29(RegStorage::kValid | rD29);
502 constexpr RegStorage rs_rD30(RegStorage::kValid | rD30);
503 constexpr RegStorage rs_rD31(RegStorage::kValid | rD31);
504 
505 // RegisterLocation templates return values (r_V0, or r_V0/r_V1).
506 const RegLocation mips_loc_c_return
507     {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
508      RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
509 const 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};
512 const 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};
515 const 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};
518 const 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
522 const 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};
525 const 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};
528 const 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 
532 enum 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  */
556 enum 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 };
685 std::ostream& operator<<(std::ostream& os, const MipsOpCode& rhs);
686 
687 // Instruction assembly field_loc kind.
688 enum 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 };
695 std::ostream& operator<<(std::ostream& os, const MipsEncodingKind& rhs);
696 
697 // Struct used to define the snippet positions for each MIPS opcode.
698 struct 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 
712 extern 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