1 /*
2  *  MIPS32 emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <inttypes.h>
28 
29 #include "cpu.h"
30 #include "exec-all.h"
31 #include "disas.h"
32 #include "tcg-op.h"
33 #include "qemu-common.h"
34 
35 #include "helper.h"
36 #define GEN_HELPER 1
37 #include "helper.h"
38 
39 //#define MIPS_DEBUG_DISAS
40 //#define MIPS_DEBUG_SIGN_EXTENSIONS
41 
42 /* MIPS major opcodes */
43 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
44 
45 enum {
46     /* indirect opcode tables */
47     OPC_SPECIAL  = (0x00 << 26),
48     OPC_REGIMM   = (0x01 << 26),
49     OPC_CP0      = (0x10 << 26),
50     OPC_CP1      = (0x11 << 26),
51     OPC_CP2      = (0x12 << 26),
52     OPC_CP3      = (0x13 << 26),
53     OPC_SPECIAL2 = (0x1C << 26),
54     OPC_SPECIAL3 = (0x1F << 26),
55     /* arithmetic with immediate */
56     OPC_ADDI     = (0x08 << 26),
57     OPC_ADDIU    = (0x09 << 26),
58     OPC_SLTI     = (0x0A << 26),
59     OPC_SLTIU    = (0x0B << 26),
60     /* logic with immediate */
61     OPC_ANDI     = (0x0C << 26),
62     OPC_ORI      = (0x0D << 26),
63     OPC_XORI     = (0x0E << 26),
64     OPC_LUI      = (0x0F << 26),
65     /* arithmetic with immediate */
66     OPC_DADDI    = (0x18 << 26),
67     OPC_DADDIU   = (0x19 << 26),
68     /* Jump and branches */
69     OPC_J        = (0x02 << 26),
70     OPC_JAL      = (0x03 << 26),
71     OPC_JALS     = OPC_JAL | 0x5,
72     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
73     OPC_BEQL     = (0x14 << 26),
74     OPC_BNE      = (0x05 << 26),
75     OPC_BNEL     = (0x15 << 26),
76     OPC_BLEZ     = (0x06 << 26),
77     OPC_BLEZL    = (0x16 << 26),
78     OPC_BGTZ     = (0x07 << 26),
79     OPC_BGTZL    = (0x17 << 26),
80     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
81     OPC_JALXS    = OPC_JALX | 0x5,
82     /* Load and stores */
83     OPC_LDL      = (0x1A << 26),
84     OPC_LDR      = (0x1B << 26),
85     OPC_LB       = (0x20 << 26),
86     OPC_LH       = (0x21 << 26),
87     OPC_LWL      = (0x22 << 26),
88     OPC_LW       = (0x23 << 26),
89     OPC_LWPC     = OPC_LW | 0x5,
90     OPC_LBU      = (0x24 << 26),
91     OPC_LHU      = (0x25 << 26),
92     OPC_LWR      = (0x26 << 26),
93     OPC_LWU      = (0x27 << 26),
94     OPC_SB       = (0x28 << 26),
95     OPC_SH       = (0x29 << 26),
96     OPC_SWL      = (0x2A << 26),
97     OPC_SW       = (0x2B << 26),
98     OPC_SDL      = (0x2C << 26),
99     OPC_SDR      = (0x2D << 26),
100     OPC_SWR      = (0x2E << 26),
101     OPC_LL       = (0x30 << 26),
102     OPC_LLD      = (0x34 << 26),
103     OPC_LD       = (0x37 << 26),
104     OPC_LDPC     = OPC_LD | 0x5,
105     OPC_SC       = (0x38 << 26),
106     OPC_SCD      = (0x3C << 26),
107     OPC_SD       = (0x3F << 26),
108     /* Floating point load/store */
109     OPC_LWC1     = (0x31 << 26),
110     OPC_LWC2     = (0x32 << 26),
111     OPC_LDC1     = (0x35 << 26),
112     OPC_LDC2     = (0x36 << 26),
113     OPC_SWC1     = (0x39 << 26),
114     OPC_SWC2     = (0x3A << 26),
115     OPC_SDC1     = (0x3D << 26),
116     OPC_SDC2     = (0x3E << 26),
117     /* MDMX ASE specific */
118     OPC_MDMX     = (0x1E << 26),
119     /* Cache and prefetch */
120     OPC_CACHE    = (0x2F << 26),
121     OPC_PREF     = (0x33 << 26),
122     /* Reserved major opcode */
123     OPC_MAJOR3B_RESERVED = (0x3B << 26),
124 };
125 
126 /* MIPS special opcodes */
127 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
128 
129 enum {
130     /* Shifts */
131     OPC_SLL      = 0x00 | OPC_SPECIAL,
132     /* NOP is SLL r0, r0, 0   */
133     /* SSNOP is SLL r0, r0, 1 */
134     /* EHB is SLL r0, r0, 3 */
135     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
136     OPC_ROTR     = OPC_SRL | (1 << 21),
137     OPC_SRA      = 0x03 | OPC_SPECIAL,
138     OPC_SLLV     = 0x04 | OPC_SPECIAL,
139     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
140     OPC_ROTRV    = OPC_SRLV | (1 << 6),
141     OPC_SRAV     = 0x07 | OPC_SPECIAL,
142     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
143     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
144     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
145     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
146     OPC_DSLL     = 0x38 | OPC_SPECIAL,
147     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
148     OPC_DROTR    = OPC_DSRL | (1 << 21),
149     OPC_DSRA     = 0x3B | OPC_SPECIAL,
150     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
151     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
152     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
153     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
154     /* Multiplication / division */
155     OPC_MULT     = 0x18 | OPC_SPECIAL,
156     OPC_MULTU    = 0x19 | OPC_SPECIAL,
157     OPC_DIV      = 0x1A | OPC_SPECIAL,
158     OPC_DIVU     = 0x1B | OPC_SPECIAL,
159     OPC_DMULT    = 0x1C | OPC_SPECIAL,
160     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
161     OPC_DDIV     = 0x1E | OPC_SPECIAL,
162     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
163     /* 2 registers arithmetic / logic */
164     OPC_ADD      = 0x20 | OPC_SPECIAL,
165     OPC_ADDU     = 0x21 | OPC_SPECIAL,
166     OPC_SUB      = 0x22 | OPC_SPECIAL,
167     OPC_SUBU     = 0x23 | OPC_SPECIAL,
168     OPC_AND      = 0x24 | OPC_SPECIAL,
169     OPC_OR       = 0x25 | OPC_SPECIAL,
170     OPC_XOR      = 0x26 | OPC_SPECIAL,
171     OPC_NOR      = 0x27 | OPC_SPECIAL,
172     OPC_SLT      = 0x2A | OPC_SPECIAL,
173     OPC_SLTU     = 0x2B | OPC_SPECIAL,
174     OPC_DADD     = 0x2C | OPC_SPECIAL,
175     OPC_DADDU    = 0x2D | OPC_SPECIAL,
176     OPC_DSUB     = 0x2E | OPC_SPECIAL,
177     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
178     /* Jumps */
179     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
180     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
181     OPC_JALRC    = OPC_JALR | (0x5 << 6),
182     OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
183     /* Traps */
184     OPC_TGE      = 0x30 | OPC_SPECIAL,
185     OPC_TGEU     = 0x31 | OPC_SPECIAL,
186     OPC_TLT      = 0x32 | OPC_SPECIAL,
187     OPC_TLTU     = 0x33 | OPC_SPECIAL,
188     OPC_TEQ      = 0x34 | OPC_SPECIAL,
189     OPC_TNE      = 0x36 | OPC_SPECIAL,
190     /* HI / LO registers load & stores */
191     OPC_MFHI     = 0x10 | OPC_SPECIAL,
192     OPC_MTHI     = 0x11 | OPC_SPECIAL,
193     OPC_MFLO     = 0x12 | OPC_SPECIAL,
194     OPC_MTLO     = 0x13 | OPC_SPECIAL,
195     /* Conditional moves */
196     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197     OPC_MOVN     = 0x0B | OPC_SPECIAL,
198 
199     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200 
201     /* Special */
202     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
203     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204     OPC_BREAK    = 0x0D | OPC_SPECIAL,
205     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
206     OPC_SYNC     = 0x0F | OPC_SPECIAL,
207 
208     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215 };
216 
217 /* Multiplication variants of the vr54xx. */
218 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
219 
220 enum {
221     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
222     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
223     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
224     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
225     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
226     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
227     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
228     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
229     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
230     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
231     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
232     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
233     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
234     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
235 };
236 
237 /* REGIMM (rt field) opcodes */
238 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
239 
240 enum {
241     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
242     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
243     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
244     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
245     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
246     OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
247     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
248     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
249     OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
250     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
251     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
252     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
253     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
254     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
255     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
256     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
257     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
258 };
259 
260 /* Special2 opcodes */
261 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
262 
263 enum {
264     /* Multiply & xxx operations */
265     OPC_MADD     = 0x00 | OPC_SPECIAL2,
266     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
267     OPC_MUL      = 0x02 | OPC_SPECIAL2,
268     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
269     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
270     /* Loongson 2F */
271     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
272     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
273     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
274     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
275     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
276     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
277     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
278     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
279     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
280     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
281     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
282     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
283     /* Misc */
284     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
285     OPC_CLO      = 0x21 | OPC_SPECIAL2,
286     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
287     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
288     /* Special */
289     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
290 };
291 
292 /* Special3 opcodes */
293 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
294 
295 enum {
296     OPC_EXT      = 0x00 | OPC_SPECIAL3,
297     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
298     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
299     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
300     OPC_INS      = 0x04 | OPC_SPECIAL3,
301     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
302     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
303     OPC_DINS     = 0x07 | OPC_SPECIAL3,
304     OPC_FORK     = 0x08 | OPC_SPECIAL3,
305     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
306     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
307     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
308     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
309 
310     /* Loongson 2E */
311     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
312     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
313     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
314     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
315     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
316     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
317     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
318     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
319     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
320     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
321     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
322     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
323 };
324 
325 /* BSHFL opcodes */
326 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
327 
328 enum {
329     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
330     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
331     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
332 };
333 
334 /* DBSHFL opcodes */
335 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
336 
337 enum {
338     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
339     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
340 };
341 
342 /* Coprocessor 0 (rs field) */
343 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
344 
345 enum {
346     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
347     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
348     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
349     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
350     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
351     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
352     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
353     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
354     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
355     OPC_C0       = (0x10 << 21) | OPC_CP0,
356     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
357     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
358 };
359 
360 /* MFMC0 opcodes */
361 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
362 
363 enum {
364     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
366     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
367     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
368     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
369     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
370 };
371 
372 /* Coprocessor 0 (with rs == C0) */
373 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
374 
375 enum {
376     OPC_TLBR     = 0x01 | OPC_C0,
377     OPC_TLBWI    = 0x02 | OPC_C0,
378     OPC_TLBWR    = 0x06 | OPC_C0,
379     OPC_TLBP     = 0x08 | OPC_C0,
380     OPC_RFE      = 0x10 | OPC_C0,
381     OPC_ERET     = 0x18 | OPC_C0,
382     OPC_DERET    = 0x1F | OPC_C0,
383     OPC_WAIT     = 0x20 | OPC_C0,
384 };
385 
386 /* Coprocessor 1 (rs field) */
387 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
388 
389 /* Values for the fmt field in FP instructions */
390 enum {
391     /* 0 - 15 are reserved */
392     FMT_S = 16,          /* single fp */
393     FMT_D = 17,          /* double fp */
394     FMT_E = 18,          /* extended fp */
395     FMT_Q = 19,          /* quad fp */
396     FMT_W = 20,          /* 32-bit fixed */
397     FMT_L = 21,          /* 64-bit fixed */
398     FMT_PS = 22,         /* paired single fp */
399     /* 23 - 31 are reserved */
400 };
401 
402 enum {
403     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
404     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
405     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
406     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
407     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
408     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
409     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
410     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
411     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
412     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
413     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
414     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
415     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
416     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
417     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
418     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
419     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
420     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
421 };
422 
423 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
424 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
425 
426 enum {
427     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
428     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
429     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
430     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
431 };
432 
433 enum {
434     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
435     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
436 };
437 
438 enum {
439     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
440     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
441 };
442 
443 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
444 
445 enum {
446     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
447     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
448     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
449     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
450     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
451     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
452     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
453     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
454     OPC_BC2     = (0x08 << 21) | OPC_CP2,
455 };
456 
457 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
458 
459 enum {
460     OPC_LWXC1   = 0x00 | OPC_CP3,
461     OPC_LDXC1   = 0x01 | OPC_CP3,
462     OPC_LUXC1   = 0x05 | OPC_CP3,
463     OPC_SWXC1   = 0x08 | OPC_CP3,
464     OPC_SDXC1   = 0x09 | OPC_CP3,
465     OPC_SUXC1   = 0x0D | OPC_CP3,
466     OPC_PREFX   = 0x0F | OPC_CP3,
467     OPC_ALNV_PS = 0x1E | OPC_CP3,
468     OPC_MADD_S  = 0x20 | OPC_CP3,
469     OPC_MADD_D  = 0x21 | OPC_CP3,
470     OPC_MADD_PS = 0x26 | OPC_CP3,
471     OPC_MSUB_S  = 0x28 | OPC_CP3,
472     OPC_MSUB_D  = 0x29 | OPC_CP3,
473     OPC_MSUB_PS = 0x2E | OPC_CP3,
474     OPC_NMADD_S = 0x30 | OPC_CP3,
475     OPC_NMADD_D = 0x31 | OPC_CP3,
476     OPC_NMADD_PS= 0x36 | OPC_CP3,
477     OPC_NMSUB_S = 0x38 | OPC_CP3,
478     OPC_NMSUB_D = 0x39 | OPC_CP3,
479     OPC_NMSUB_PS= 0x3E | OPC_CP3,
480 };
481 
482 /* global register indices */
483 static TCGv_ptr cpu_env;
484 static TCGv cpu_gpr[32], cpu_PC;
485 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
486 static TCGv cpu_dspctrl, btarget, bcond;
487 static TCGv_i32 hflags;
488 static TCGv_i32 fpu_fcr0, fpu_fcr31;
489 
490 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
491 
492 #include "gen-icount.h"
493 
494 #define gen_helper_0i(name, arg) do {                             \
495     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
496     gen_helper_##name(helper_tmp);                                \
497     tcg_temp_free_i32(helper_tmp);                                \
498     } while(0)
499 
500 #define gen_helper_1i(name, arg1, arg2) do {                      \
501     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
502     gen_helper_##name(arg1, helper_tmp);                          \
503     tcg_temp_free_i32(helper_tmp);                                \
504     } while(0)
505 
506 #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
507     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
508     gen_helper_##name(arg1, arg2, helper_tmp);                    \
509     tcg_temp_free_i32(helper_tmp);                                \
510     } while(0)
511 
512 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
513     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
514     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
515     tcg_temp_free_i32(helper_tmp);                                \
516     } while(0)
517 
518 typedef struct DisasContext {
519     struct TranslationBlock *tb;
520     target_ulong pc, saved_pc;
521     uint32_t opcode;
522     int singlestep_enabled;
523     /* Routine used to access memory */
524     int mem_idx;
525     uint32_t hflags, saved_hflags;
526     int bstate;
527     target_ulong btarget;
528 } DisasContext;
529 
530 enum {
531     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
532                       * exception condition */
533     BS_STOP     = 1, /* We want to stop translation for any reason */
534     BS_BRANCH   = 2, /* We reached a branch condition     */
535     BS_EXCP     = 3, /* We reached an exception condition */
536 };
537 
538 static const char *regnames[] =
539     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
540       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
541       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
542       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
543 
544 static const char *regnames_HI[] =
545     { "HI0", "HI1", "HI2", "HI3", };
546 
547 static const char *regnames_LO[] =
548     { "LO0", "LO1", "LO2", "LO3", };
549 
550 static const char *regnames_ACX[] =
551     { "ACX0", "ACX1", "ACX2", "ACX3", };
552 
553 static const char *fregnames[] =
554     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
555       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
556       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
557       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
558 
559 #ifdef MIPS_DEBUG_DISAS
560 #define MIPS_DEBUG(fmt, ...)                         \
561         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
562                        TARGET_FMT_lx ": %08x " fmt "\n", \
563                        ctx->pc, ctx->opcode , ## __VA_ARGS__)
564 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
565 #else
566 #define MIPS_DEBUG(fmt, ...) do { } while(0)
567 #define LOG_DISAS(...) do { } while (0)
568 #endif
569 
570 #define MIPS_INVAL(op)                                                        \
571 do {                                                                          \
572     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
573                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
574 } while (0)
575 
576 /* General purpose registers moves. */
gen_load_gpr(TCGv t,int reg)577 static inline void gen_load_gpr (TCGv t, int reg)
578 {
579     if (reg == 0)
580         tcg_gen_movi_tl(t, 0);
581     else
582         tcg_gen_mov_tl(t, cpu_gpr[reg]);
583 }
584 
gen_store_gpr(TCGv t,int reg)585 static inline void gen_store_gpr (TCGv t, int reg)
586 {
587     if (reg != 0)
588         tcg_gen_mov_tl(cpu_gpr[reg], t);
589 }
590 
591 /* Moves to/from ACX register.  */
gen_load_ACX(TCGv t,int reg)592 static inline void gen_load_ACX (TCGv t, int reg)
593 {
594     tcg_gen_mov_tl(t, cpu_ACX[reg]);
595 }
596 
gen_store_ACX(TCGv t,int reg)597 static inline void gen_store_ACX (TCGv t, int reg)
598 {
599     tcg_gen_mov_tl(cpu_ACX[reg], t);
600 }
601 
602 /* Moves to/from shadow registers. */
gen_load_srsgpr(int from,int to)603 static inline void gen_load_srsgpr (int from, int to)
604 {
605     TCGv t0 = tcg_temp_new();
606 
607     if (from == 0)
608         tcg_gen_movi_tl(t0, 0);
609     else {
610         TCGv_i32 t2 = tcg_temp_new_i32();
611         TCGv_ptr addr = tcg_temp_new_ptr();
612 
613         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
614         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
615         tcg_gen_andi_i32(t2, t2, 0xf);
616         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
617         tcg_gen_ext_i32_ptr(addr, t2);
618         tcg_gen_add_ptr(addr, cpu_env, addr);
619 
620         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
621         tcg_temp_free_ptr(addr);
622         tcg_temp_free_i32(t2);
623     }
624     gen_store_gpr(t0, to);
625     tcg_temp_free(t0);
626 }
627 
gen_store_srsgpr(int from,int to)628 static inline void gen_store_srsgpr (int from, int to)
629 {
630     if (to != 0) {
631         TCGv t0 = tcg_temp_new();
632         TCGv_i32 t2 = tcg_temp_new_i32();
633         TCGv_ptr addr = tcg_temp_new_ptr();
634 
635         gen_load_gpr(t0, from);
636         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
637         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
638         tcg_gen_andi_i32(t2, t2, 0xf);
639         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
640         tcg_gen_ext_i32_ptr(addr, t2);
641         tcg_gen_add_ptr(addr, cpu_env, addr);
642 
643         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
644         tcg_temp_free_ptr(addr);
645         tcg_temp_free_i32(t2);
646         tcg_temp_free(t0);
647     }
648 }
649 
650 /* Floating point register moves. */
gen_load_fpr32(TCGv_i32 t,int reg)651 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
652 {
653     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
654 }
655 
gen_store_fpr32(TCGv_i32 t,int reg)656 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
657 {
658     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
659 }
660 
gen_load_fpr32h(TCGv_i32 t,int reg)661 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
662 {
663     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
664 }
665 
gen_store_fpr32h(TCGv_i32 t,int reg)666 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
667 {
668     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
669 }
670 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)671 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
672 {
673     if (ctx->hflags & MIPS_HFLAG_F64) {
674         tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
675     } else {
676         TCGv_i32 t0 = tcg_temp_new_i32();
677         TCGv_i32 t1 = tcg_temp_new_i32();
678         gen_load_fpr32(t0, reg & ~1);
679         gen_load_fpr32(t1, reg | 1);
680         tcg_gen_concat_i32_i64(t, t0, t1);
681         tcg_temp_free_i32(t0);
682         tcg_temp_free_i32(t1);
683     }
684 }
685 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)686 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
687 {
688     if (ctx->hflags & MIPS_HFLAG_F64) {
689         tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
690     } else {
691         TCGv_i64 t0 = tcg_temp_new_i64();
692         TCGv_i32 t1 = tcg_temp_new_i32();
693         tcg_gen_trunc_i64_i32(t1, t);
694         gen_store_fpr32(t1, reg & ~1);
695         tcg_gen_shri_i64(t0, t, 32);
696         tcg_gen_trunc_i64_i32(t1, t0);
697         gen_store_fpr32(t1, reg | 1);
698         tcg_temp_free_i32(t1);
699         tcg_temp_free_i64(t0);
700     }
701 }
702 
get_fp_bit(int cc)703 static inline int get_fp_bit (int cc)
704 {
705     if (cc)
706         return 24 + cc;
707     else
708         return 23;
709 }
710 
711 /* Tests */
gen_save_pc(target_ulong pc)712 static inline void gen_save_pc(target_ulong pc)
713 {
714     tcg_gen_movi_tl(cpu_PC, pc);
715 }
716 
save_cpu_state(DisasContext * ctx,int do_save_pc)717 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
718 {
719     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
720     if (do_save_pc && ctx->pc != ctx->saved_pc) {
721         gen_save_pc(ctx->pc);
722         ctx->saved_pc = ctx->pc;
723     }
724     if (ctx->hflags != ctx->saved_hflags) {
725         tcg_gen_movi_i32(hflags, ctx->hflags);
726         ctx->saved_hflags = ctx->hflags;
727         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
728         case MIPS_HFLAG_BR:
729             break;
730         case MIPS_HFLAG_BC:
731         case MIPS_HFLAG_BL:
732         case MIPS_HFLAG_B:
733             tcg_gen_movi_tl(btarget, ctx->btarget);
734             break;
735         }
736     }
737 }
738 
restore_cpu_state(CPUState * env,DisasContext * ctx)739 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
740 {
741     ctx->saved_hflags = ctx->hflags;
742     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
743     case MIPS_HFLAG_BR:
744         break;
745     case MIPS_HFLAG_BC:
746     case MIPS_HFLAG_BL:
747     case MIPS_HFLAG_B:
748         ctx->btarget = env->btarget;
749         break;
750     }
751 }
752 
753 static inline void
generate_exception_err(DisasContext * ctx,int excp,int err)754 generate_exception_err (DisasContext *ctx, int excp, int err)
755 {
756     TCGv_i32 texcp = tcg_const_i32(excp);
757     TCGv_i32 terr = tcg_const_i32(err);
758     save_cpu_state(ctx, 1);
759     gen_helper_raise_exception_err(texcp, terr);
760     tcg_temp_free_i32(terr);
761     tcg_temp_free_i32(texcp);
762 }
763 
764 static inline void
generate_exception(DisasContext * ctx,int excp)765 generate_exception (DisasContext *ctx, int excp)
766 {
767     save_cpu_state(ctx, 1);
768     gen_helper_0i(raise_exception, excp);
769 }
770 
771 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)772 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
773 {
774     tcg_gen_add_tl(ret, arg0, arg1);
775 
776 #if defined(TARGET_MIPS64)
777     /* For compatibility with 32-bit code, data reference in user mode
778        with Status_UX = 0 should be casted to 32-bit and sign extended.
779        See the MIPS64 PRA manual, section 4.10. */
780     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
781         !(ctx->hflags & MIPS_HFLAG_UX)) {
782         tcg_gen_ext32s_i64(ret, ret);
783     }
784 #endif
785 }
786 
check_cp0_enabled(DisasContext * ctx)787 static inline void check_cp0_enabled(DisasContext *ctx)
788 {
789     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
790         generate_exception_err(ctx, EXCP_CpU, 0);
791 }
792 
check_cp1_enabled(DisasContext * ctx)793 static inline void check_cp1_enabled(DisasContext *ctx)
794 {
795     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
796         generate_exception_err(ctx, EXCP_CpU, 1);
797 }
798 
799 /* Verify that the processor is running with COP1X instructions enabled.
800    This is associated with the nabla symbol in the MIPS32 and MIPS64
801    opcode tables.  */
802 
check_cop1x(DisasContext * ctx)803 static inline void check_cop1x(DisasContext *ctx)
804 {
805     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
806         generate_exception(ctx, EXCP_RI);
807 }
808 
809 /* Verify that the processor is running with 64-bit floating-point
810    operations enabled.  */
811 
check_cp1_64bitmode(DisasContext * ctx)812 static inline void check_cp1_64bitmode(DisasContext *ctx)
813 {
814     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
815         generate_exception(ctx, EXCP_RI);
816 }
817 
818 /*
819  * Verify if floating point register is valid; an operation is not defined
820  * if bit 0 of any register specification is set and the FR bit in the
821  * Status register equals zero, since the register numbers specify an
822  * even-odd pair of adjacent coprocessor general registers. When the FR bit
823  * in the Status register equals one, both even and odd register numbers
824  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
825  *
826  * Multiple 64 bit wide registers can be checked by calling
827  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
828  */
check_cp1_registers(DisasContext * ctx,int regs)829 static inline void check_cp1_registers(DisasContext *ctx, int regs)
830 {
831     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
832         generate_exception(ctx, EXCP_RI);
833 }
834 
835 /* This code generates a "reserved instruction" exception if the
836    CPU does not support the instruction set corresponding to flags. */
check_insn(CPUState * env,DisasContext * ctx,int flags)837 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
838 {
839     if (unlikely(!(env->insn_flags & flags)))
840         generate_exception(ctx, EXCP_RI);
841 }
842 
843 /* This code generates a "reserved instruction" exception if 64-bit
844    instructions are not enabled. */
check_mips_64(DisasContext * ctx)845 static inline void check_mips_64(DisasContext *ctx)
846 {
847     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
848         generate_exception(ctx, EXCP_RI);
849 }
850 
851 /* Define small wrappers for gen_load_fpr* so that we have a uniform
852    calling interface for 32 and 64-bit FPRs.  No sense in changing
853    all callers for gen_load_fpr32 when we need the CTX parameter for
854    this one use.  */
855 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
856 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
857 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
858 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
859                                                int ft, int fs, int cc)        \
860 {                                                                             \
861     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
862     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
863     switch (ifmt) {                                                           \
864     case FMT_PS:                                                              \
865         check_cp1_64bitmode(ctx);                                             \
866         break;                                                                \
867     case FMT_D:                                                               \
868         if (abs) {                                                            \
869             check_cop1x(ctx);                                                 \
870         }                                                                     \
871         check_cp1_registers(ctx, fs | ft);                                    \
872         break;                                                                \
873     case FMT_S:                                                               \
874         if (abs) {                                                            \
875             check_cop1x(ctx);                                                 \
876         }                                                                     \
877         break;                                                                \
878     }                                                                         \
879     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
880     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
881     switch (n) {                                                              \
882     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
883     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
884     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
885     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
886     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
887     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
888     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
889     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
890     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
891     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
892     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
893     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
894     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
895     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
896     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
897     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
898     default: abort();                                                         \
899     }                                                                         \
900     tcg_temp_free_i##bits (fp0);                                              \
901     tcg_temp_free_i##bits (fp1);                                              \
902 }
903 
904 FOP_CONDS(, 0, d, FMT_D, 64)
905 FOP_CONDS(abs, 1, d, FMT_D, 64)
906 FOP_CONDS(, 0, s, FMT_S, 32)
907 FOP_CONDS(abs, 1, s, FMT_S, 32)
908 FOP_CONDS(, 0, ps, FMT_PS, 64)
909 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
910 #undef FOP_CONDS
911 #undef gen_ldcmp_fpr32
912 #undef gen_ldcmp_fpr64
913 
914 /* load/store instructions. */
915 #define OP_LD(insn,fname)                                                 \
916 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
917 {                                                                         \
918     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
919 }
920 OP_LD(lb,ld8s);
921 OP_LD(lbu,ld8u);
922 OP_LD(lh,ld16s);
923 OP_LD(lhu,ld16u);
924 OP_LD(lw,ld32s);
925 #if defined(TARGET_MIPS64)
926 OP_LD(lwu,ld32u);
927 OP_LD(ld,ld64);
928 #endif
929 #undef OP_LD
930 
931 #define OP_ST(insn,fname)                                                  \
932 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
933 {                                                                          \
934     tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
935 }
936 OP_ST(sb,st8);
937 OP_ST(sh,st16);
938 OP_ST(sw,st32);
939 #if defined(TARGET_MIPS64)
940 OP_ST(sd,st64);
941 #endif
942 #undef OP_ST
943 
944 #ifdef CONFIG_USER_ONLY
945 #define OP_LD_ATOMIC(insn,fname)                                           \
946 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
947 {                                                                          \
948     TCGv t0 = tcg_temp_new();                                              \
949     tcg_gen_mov_tl(t0, arg1);                                              \
950     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
951     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
952     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
953     tcg_temp_free(t0);                                                     \
954 }
955 #else
956 #define OP_LD_ATOMIC(insn,fname)                                           \
957 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
958 {                                                                          \
959     gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
960 }
961 #endif
962 OP_LD_ATOMIC(ll,ld32s);
963 #if defined(TARGET_MIPS64)
964 OP_LD_ATOMIC(lld,ld64);
965 #endif
966 #undef OP_LD_ATOMIC
967 
968 #ifdef CONFIG_USER_ONLY
969 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
970 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
971 {                                                                            \
972     TCGv t0 = tcg_temp_new();                                                \
973     int l1 = gen_new_label();                                                \
974     int l2 = gen_new_label();                                                \
975                                                                              \
976     tcg_gen_andi_tl(t0, arg2, almask);                                       \
977     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
978     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
979     generate_exception(ctx, EXCP_AdES);                                      \
980     gen_set_label(l1);                                                       \
981     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
982     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
983     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
984     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
985     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
986     gen_helper_0i(raise_exception, EXCP_SC);                                 \
987     gen_set_label(l2);                                                       \
988     tcg_gen_movi_tl(t0, 0);                                                  \
989     gen_store_gpr(t0, rt);                                                   \
990     tcg_temp_free(t0);                                                       \
991 }
992 #else
993 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
994 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
995 {                                                                            \
996     TCGv t0 = tcg_temp_new();                                                \
997     gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
998     gen_store_gpr(t0, rt);                                                   \
999     tcg_temp_free(t0);                                                       \
1000 }
1001 #endif
1002 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1003 #if defined(TARGET_MIPS64)
1004 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1005 #endif
1006 #undef OP_ST_ATOMIC
1007 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int16_t offset)1008 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1009                                   int base, int16_t offset)
1010 {
1011     if (base == 0) {
1012         tcg_gen_movi_tl(addr, offset);
1013     } else if (offset == 0) {
1014         gen_load_gpr(addr, base);
1015     } else {
1016         tcg_gen_movi_tl(addr, offset);
1017         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1018     }
1019 }
1020 
pc_relative_pc(DisasContext * ctx)1021 static target_ulong pc_relative_pc (DisasContext *ctx)
1022 {
1023     target_ulong pc = ctx->pc;
1024 
1025     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1026         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1027 
1028         pc -= branch_bytes;
1029     }
1030 
1031     pc &= ~(target_ulong)3;
1032     return pc;
1033 }
1034 
1035 /* Load */
gen_ld(CPUState * env,DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)1036 static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1037                     int rt, int base, int16_t offset)
1038 {
1039     const char *opn = "ld";
1040     TCGv t0, t1;
1041 
1042     if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1043         /* Loongson CPU uses a load to zero register for prefetch.
1044            We emulate it as a NOP. On other CPU we must perform the
1045            actual memory access. */
1046         MIPS_DEBUG("NOP");
1047         return;
1048     }
1049 
1050     t0 = tcg_temp_new();
1051     t1 = tcg_temp_new();
1052     gen_base_offset_addr(ctx, t0, base, offset);
1053 
1054     switch (opc) {
1055 #if defined(TARGET_MIPS64)
1056     case OPC_LWU:
1057         save_cpu_state(ctx, 0);
1058         op_ld_lwu(t0, t0, ctx);
1059         gen_store_gpr(t0, rt);
1060         opn = "lwu";
1061         break;
1062     case OPC_LD:
1063         save_cpu_state(ctx, 0);
1064         op_ld_ld(t0, t0, ctx);
1065         gen_store_gpr(t0, rt);
1066         opn = "ld";
1067         break;
1068     case OPC_LLD:
1069         save_cpu_state(ctx, 1);
1070         op_ld_lld(t0, t0, ctx);
1071         gen_store_gpr(t0, rt);
1072         opn = "lld";
1073         break;
1074     case OPC_LDL:
1075         save_cpu_state(ctx, 1);
1076         gen_load_gpr(t1, rt);
1077         gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1078         gen_store_gpr(t1, rt);
1079         opn = "ldl";
1080         break;
1081     case OPC_LDR:
1082         save_cpu_state(ctx, 1);
1083         gen_load_gpr(t1, rt);
1084         gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1085         gen_store_gpr(t1, rt);
1086         opn = "ldr";
1087         break;
1088     case OPC_LDPC:
1089         save_cpu_state(ctx, 0);
1090         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1091         gen_op_addr_add(ctx, t0, t0, t1);
1092         op_ld_ld(t0, t0, ctx);
1093         gen_store_gpr(t0, rt);
1094         opn = "ldpc";
1095         break;
1096 #endif
1097     case OPC_LWPC:
1098         save_cpu_state(ctx, 0);
1099         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1100         gen_op_addr_add(ctx, t0, t0, t1);
1101         op_ld_lw(t0, t0, ctx);
1102         gen_store_gpr(t0, rt);
1103         opn = "lwpc";
1104         break;
1105     case OPC_LW:
1106         save_cpu_state(ctx, 0);
1107         op_ld_lw(t0, t0, ctx);
1108         gen_store_gpr(t0, rt);
1109         opn = "lw";
1110         break;
1111     case OPC_LH:
1112         save_cpu_state(ctx, 0);
1113         op_ld_lh(t0, t0, ctx);
1114         gen_store_gpr(t0, rt);
1115         opn = "lh";
1116         break;
1117     case OPC_LHU:
1118         save_cpu_state(ctx, 0);
1119         op_ld_lhu(t0, t0, ctx);
1120         gen_store_gpr(t0, rt);
1121         opn = "lhu";
1122         break;
1123     case OPC_LB:
1124         save_cpu_state(ctx, 0);
1125         op_ld_lb(t0, t0, ctx);
1126         gen_store_gpr(t0, rt);
1127         opn = "lb";
1128         break;
1129     case OPC_LBU:
1130         save_cpu_state(ctx, 0);
1131         op_ld_lbu(t0, t0, ctx);
1132         gen_store_gpr(t0, rt);
1133         opn = "lbu";
1134         break;
1135     case OPC_LWL:
1136         save_cpu_state(ctx, 1);
1137         gen_load_gpr(t1, rt);
1138         gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1139         gen_store_gpr(t1, rt);
1140         opn = "lwl";
1141         break;
1142     case OPC_LWR:
1143         save_cpu_state(ctx, 1);
1144         gen_load_gpr(t1, rt);
1145         gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1146         gen_store_gpr(t1, rt);
1147         opn = "lwr";
1148         break;
1149     case OPC_LL:
1150         save_cpu_state(ctx, 1);
1151         op_ld_ll(t0, t0, ctx);
1152         gen_store_gpr(t0, rt);
1153         opn = "ll";
1154         break;
1155     }
1156     (void)opn; /* avoid a compiler warning */
1157     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1158     tcg_temp_free(t0);
1159     tcg_temp_free(t1);
1160 }
1161 
1162 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)1163 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1164                     int base, int16_t offset)
1165 {
1166     const char *opn = "st";
1167     TCGv t0 = tcg_temp_new();
1168     TCGv t1 = tcg_temp_new();
1169 
1170     gen_base_offset_addr(ctx, t0, base, offset);
1171     gen_load_gpr(t1, rt);
1172     switch (opc) {
1173 #if defined(TARGET_MIPS64)
1174     case OPC_SD:
1175         save_cpu_state(ctx, 0);
1176         op_st_sd(t1, t0, ctx);
1177         opn = "sd";
1178         break;
1179     case OPC_SDL:
1180         save_cpu_state(ctx, 1);
1181         gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1182         opn = "sdl";
1183         break;
1184     case OPC_SDR:
1185         save_cpu_state(ctx, 1);
1186         gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1187         opn = "sdr";
1188         break;
1189 #endif
1190     case OPC_SW:
1191         save_cpu_state(ctx, 0);
1192         op_st_sw(t1, t0, ctx);
1193         opn = "sw";
1194         break;
1195     case OPC_SH:
1196         save_cpu_state(ctx, 0);
1197         op_st_sh(t1, t0, ctx);
1198         opn = "sh";
1199         break;
1200     case OPC_SB:
1201         save_cpu_state(ctx, 0);
1202         op_st_sb(t1, t0, ctx);
1203         opn = "sb";
1204         break;
1205     case OPC_SWL:
1206         save_cpu_state(ctx, 1);
1207         gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1208         opn = "swl";
1209         break;
1210     case OPC_SWR:
1211         save_cpu_state(ctx, 1);
1212         gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1213         opn = "swr";
1214         break;
1215     }
1216     (void)opn; /* avoid a compiler warning */
1217     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1218     tcg_temp_free(t0);
1219     tcg_temp_free(t1);
1220 }
1221 
1222 
1223 /* Store conditional */
gen_st_cond(DisasContext * ctx,uint32_t opc,int rt,int base,int16_t offset)1224 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1225                          int base, int16_t offset)
1226 {
1227     const char *opn = "st_cond";
1228     TCGv t0, t1;
1229 
1230     t0 = tcg_temp_local_new();
1231 
1232     gen_base_offset_addr(ctx, t0, base, offset);
1233     /* Don't do NOP if destination is zero: we must perform the actual
1234        memory access. */
1235 
1236     t1 = tcg_temp_local_new();
1237     gen_load_gpr(t1, rt);
1238     switch (opc) {
1239 #if defined(TARGET_MIPS64)
1240     case OPC_SCD:
1241         save_cpu_state(ctx, 1);
1242         op_st_scd(t1, t0, rt, ctx);
1243         opn = "scd";
1244         break;
1245 #endif
1246     case OPC_SC:
1247         save_cpu_state(ctx, 1);
1248         op_st_sc(t1, t0, rt, ctx);
1249         opn = "sc";
1250         break;
1251     }
1252     (void)opn; /* avoid a compiler warning */
1253     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1254     tcg_temp_free(t1);
1255     tcg_temp_free(t0);
1256 }
1257 
1258 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,int base,int16_t offset)1259 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1260                           int base, int16_t offset)
1261 {
1262     const char *opn = "flt_ldst";
1263     TCGv t0 = tcg_temp_new();
1264 
1265     gen_base_offset_addr(ctx, t0, base, offset);
1266     /* Don't do NOP if destination is zero: we must perform the actual
1267        memory access. */
1268     switch (opc) {
1269     case OPC_LWC1:
1270         {
1271             TCGv_i32 fp0 = tcg_temp_new_i32();
1272 
1273             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1274             tcg_gen_trunc_tl_i32(fp0, t0);
1275             gen_store_fpr32(fp0, ft);
1276             tcg_temp_free_i32(fp0);
1277         }
1278         opn = "lwc1";
1279         break;
1280     case OPC_SWC1:
1281         {
1282             TCGv_i32 fp0 = tcg_temp_new_i32();
1283             TCGv t1 = tcg_temp_new();
1284 
1285             gen_load_fpr32(fp0, ft);
1286             tcg_gen_extu_i32_tl(t1, fp0);
1287             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1288             tcg_temp_free(t1);
1289             tcg_temp_free_i32(fp0);
1290         }
1291         opn = "swc1";
1292         break;
1293     case OPC_LDC1:
1294         {
1295             TCGv_i64 fp0 = tcg_temp_new_i64();
1296 
1297             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1298             gen_store_fpr64(ctx, fp0, ft);
1299             tcg_temp_free_i64(fp0);
1300         }
1301         opn = "ldc1";
1302         break;
1303     case OPC_SDC1:
1304         {
1305             TCGv_i64 fp0 = tcg_temp_new_i64();
1306 
1307             gen_load_fpr64(ctx, fp0, ft);
1308             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1309             tcg_temp_free_i64(fp0);
1310         }
1311         opn = "sdc1";
1312         break;
1313     default:
1314         MIPS_INVAL(opn);
1315         generate_exception(ctx, EXCP_RI);
1316         goto out;
1317     }
1318     (void)opn; /* avoid a compiler warning */
1319     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1320  out:
1321     tcg_temp_free(t0);
1322 }
1323 
gen_cop1_ldst(CPUState * env,DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)1324 static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1325                           uint32_t op, int rt, int rs, int16_t imm)
1326 {
1327     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1328         check_cp1_enabled(ctx);
1329         gen_flt_ldst(ctx, op, rt, rs, imm);
1330     } else {
1331         generate_exception_err(ctx, EXCP_CpU, 1);
1332     }
1333 }
1334 
1335 /* Arithmetic with immediate operand */
gen_arith_imm(CPUState * env,DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)1336 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1337                            int rt, int rs, int16_t imm)
1338 {
1339     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1340     const char *opn = "imm arith";
1341 
1342     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1343         /* If no destination, treat it as a NOP.
1344            For addi, we must generate the overflow exception when needed. */
1345         MIPS_DEBUG("NOP");
1346         return;
1347     }
1348     switch (opc) {
1349     case OPC_ADDI:
1350         {
1351             TCGv t0 = tcg_temp_local_new();
1352             TCGv t1 = tcg_temp_new();
1353             TCGv t2 = tcg_temp_new();
1354             int l1 = gen_new_label();
1355 
1356             gen_load_gpr(t1, rs);
1357             tcg_gen_addi_tl(t0, t1, uimm);
1358             tcg_gen_ext32s_tl(t0, t0);
1359 
1360             tcg_gen_xori_tl(t1, t1, ~uimm);
1361             tcg_gen_xori_tl(t2, t0, uimm);
1362             tcg_gen_and_tl(t1, t1, t2);
1363             tcg_temp_free(t2);
1364             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1365             tcg_temp_free(t1);
1366             /* operands of same sign, result different sign */
1367             generate_exception(ctx, EXCP_OVERFLOW);
1368             gen_set_label(l1);
1369             tcg_gen_ext32s_tl(t0, t0);
1370             gen_store_gpr(t0, rt);
1371             tcg_temp_free(t0);
1372         }
1373         opn = "addi";
1374         break;
1375     case OPC_ADDIU:
1376         if (rs != 0) {
1377             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1378             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1379         } else {
1380             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1381         }
1382         opn = "addiu";
1383         break;
1384 #if defined(TARGET_MIPS64)
1385     case OPC_DADDI:
1386         {
1387             TCGv t0 = tcg_temp_local_new();
1388             TCGv t1 = tcg_temp_new();
1389             TCGv t2 = tcg_temp_new();
1390             int l1 = gen_new_label();
1391 
1392             gen_load_gpr(t1, rs);
1393             tcg_gen_addi_tl(t0, t1, uimm);
1394 
1395             tcg_gen_xori_tl(t1, t1, ~uimm);
1396             tcg_gen_xori_tl(t2, t0, uimm);
1397             tcg_gen_and_tl(t1, t1, t2);
1398             tcg_temp_free(t2);
1399             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1400             tcg_temp_free(t1);
1401             /* operands of same sign, result different sign */
1402             generate_exception(ctx, EXCP_OVERFLOW);
1403             gen_set_label(l1);
1404             gen_store_gpr(t0, rt);
1405             tcg_temp_free(t0);
1406         }
1407         opn = "daddi";
1408         break;
1409     case OPC_DADDIU:
1410         if (rs != 0) {
1411             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1412         } else {
1413             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1414         }
1415         opn = "daddiu";
1416         break;
1417 #endif
1418     }
1419     (void)opn; /* avoid a compiler warning */
1420     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1421 }
1422 
1423 /* Logic with immediate operand */
gen_logic_imm(CPUState * env,uint32_t opc,int rt,int rs,int16_t imm)1424 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1425 {
1426     target_ulong uimm;
1427     const char *opn = "imm logic";
1428 
1429     if (rt == 0) {
1430         /* If no destination, treat it as a NOP. */
1431         MIPS_DEBUG("NOP");
1432         return;
1433     }
1434     uimm = (uint16_t)imm;
1435     switch (opc) {
1436     case OPC_ANDI:
1437         if (likely(rs != 0))
1438             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1439         else
1440             tcg_gen_movi_tl(cpu_gpr[rt], 0);
1441         opn = "andi";
1442         break;
1443     case OPC_ORI:
1444         if (rs != 0)
1445             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1446         else
1447             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1448         opn = "ori";
1449         break;
1450     case OPC_XORI:
1451         if (likely(rs != 0))
1452             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1453         else
1454             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1455         opn = "xori";
1456         break;
1457     case OPC_LUI:
1458         tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1459         opn = "lui";
1460         break;
1461     }
1462     (void)opn; /* avoid a compiler warning */
1463     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1464 }
1465 
1466 /* Set on less than with immediate operand */
gen_slt_imm(CPUState * env,uint32_t opc,int rt,int rs,int16_t imm)1467 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1468 {
1469     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1470     const char *opn = "imm arith";
1471     TCGv t0;
1472 
1473     if (rt == 0) {
1474         /* If no destination, treat it as a NOP. */
1475         MIPS_DEBUG("NOP");
1476         return;
1477     }
1478     t0 = tcg_temp_new();
1479     gen_load_gpr(t0, rs);
1480     switch (opc) {
1481     case OPC_SLTI:
1482         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1483         opn = "slti";
1484         break;
1485     case OPC_SLTIU:
1486         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1487         opn = "sltiu";
1488         break;
1489     }
1490     (void)opn; /* avoid a compiler warning */
1491     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1492     tcg_temp_free(t0);
1493 }
1494 
1495 /* Shifts with immediate operand */
gen_shift_imm(CPUState * env,DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)1496 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1497                           int rt, int rs, int16_t imm)
1498 {
1499     target_ulong uimm = ((uint16_t)imm) & 0x1f;
1500     const char *opn = "imm shift";
1501     TCGv t0;
1502 
1503     if (rt == 0) {
1504         /* If no destination, treat it as a NOP. */
1505         MIPS_DEBUG("NOP");
1506         return;
1507     }
1508 
1509     t0 = tcg_temp_new();
1510     gen_load_gpr(t0, rs);
1511     switch (opc) {
1512     case OPC_SLL:
1513         tcg_gen_shli_tl(t0, t0, uimm);
1514         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1515         opn = "sll";
1516         break;
1517     case OPC_SRA:
1518         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1519         opn = "sra";
1520         break;
1521     case OPC_SRL:
1522         if (uimm != 0) {
1523             tcg_gen_ext32u_tl(t0, t0);
1524             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1525         } else {
1526             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1527         }
1528         opn = "srl";
1529         break;
1530     case OPC_ROTR:
1531         if (uimm != 0) {
1532             TCGv_i32 t1 = tcg_temp_new_i32();
1533 
1534             tcg_gen_trunc_tl_i32(t1, t0);
1535             tcg_gen_rotri_i32(t1, t1, uimm);
1536             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1537             tcg_temp_free_i32(t1);
1538         } else {
1539             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1540         }
1541         opn = "rotr";
1542         break;
1543 #if defined(TARGET_MIPS64)
1544     case OPC_DSLL:
1545         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1546         opn = "dsll";
1547         break;
1548     case OPC_DSRA:
1549         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1550         opn = "dsra";
1551         break;
1552     case OPC_DSRL:
1553         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1554         opn = "dsrl";
1555         break;
1556     case OPC_DROTR:
1557         if (uimm != 0) {
1558             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1559         } else {
1560             tcg_gen_mov_tl(cpu_gpr[rt], t0);
1561         }
1562         opn = "drotr";
1563         break;
1564     case OPC_DSLL32:
1565         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1566         opn = "dsll32";
1567         break;
1568     case OPC_DSRA32:
1569         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1570         opn = "dsra32";
1571         break;
1572     case OPC_DSRL32:
1573         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1574         opn = "dsrl32";
1575         break;
1576     case OPC_DROTR32:
1577         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1578         opn = "drotr32";
1579         break;
1580 #endif
1581     }
1582     (void)opn; /* avoid a compiler warning */
1583     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1584     tcg_temp_free(t0);
1585 }
1586 
1587 /* Arithmetic */
gen_arith(CPUState * env,DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)1588 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1589                        int rd, int rs, int rt)
1590 {
1591     const char *opn = "arith";
1592 
1593     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1594        && opc != OPC_DADD && opc != OPC_DSUB) {
1595         /* If no destination, treat it as a NOP.
1596            For add & sub, we must generate the overflow exception when needed. */
1597         MIPS_DEBUG("NOP");
1598         return;
1599     }
1600 
1601     switch (opc) {
1602     case OPC_ADD:
1603         {
1604             TCGv t0 = tcg_temp_local_new();
1605             TCGv t1 = tcg_temp_new();
1606             TCGv t2 = tcg_temp_new();
1607             int l1 = gen_new_label();
1608 
1609             gen_load_gpr(t1, rs);
1610             gen_load_gpr(t2, rt);
1611             tcg_gen_add_tl(t0, t1, t2);
1612             tcg_gen_ext32s_tl(t0, t0);
1613             tcg_gen_xor_tl(t1, t1, t2);
1614             tcg_gen_xor_tl(t2, t0, t2);
1615             tcg_gen_andc_tl(t1, t2, t1);
1616             tcg_temp_free(t2);
1617             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1618             tcg_temp_free(t1);
1619             /* operands of same sign, result different sign */
1620             generate_exception(ctx, EXCP_OVERFLOW);
1621             gen_set_label(l1);
1622             gen_store_gpr(t0, rd);
1623             tcg_temp_free(t0);
1624         }
1625         opn = "add";
1626         break;
1627     case OPC_ADDU:
1628         if (rs != 0 && rt != 0) {
1629             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1630             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1631         } else if (rs == 0 && rt != 0) {
1632             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1633         } else if (rs != 0 && rt == 0) {
1634             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1635         } else {
1636             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1637         }
1638         opn = "addu";
1639         break;
1640     case OPC_SUB:
1641         {
1642             TCGv t0 = tcg_temp_local_new();
1643             TCGv t1 = tcg_temp_new();
1644             TCGv t2 = tcg_temp_new();
1645             int l1 = gen_new_label();
1646 
1647             gen_load_gpr(t1, rs);
1648             gen_load_gpr(t2, rt);
1649             tcg_gen_sub_tl(t0, t1, t2);
1650             tcg_gen_ext32s_tl(t0, t0);
1651             tcg_gen_xor_tl(t2, t1, t2);
1652             tcg_gen_xor_tl(t1, t0, t1);
1653             tcg_gen_and_tl(t1, t1, t2);
1654             tcg_temp_free(t2);
1655             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1656             tcg_temp_free(t1);
1657             /* operands of different sign, first operand and result different sign */
1658             generate_exception(ctx, EXCP_OVERFLOW);
1659             gen_set_label(l1);
1660             gen_store_gpr(t0, rd);
1661             tcg_temp_free(t0);
1662         }
1663         opn = "sub";
1664         break;
1665     case OPC_SUBU:
1666         if (rs != 0 && rt != 0) {
1667             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1668             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1669         } else if (rs == 0 && rt != 0) {
1670             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1671             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1672         } else if (rs != 0 && rt == 0) {
1673             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1674         } else {
1675             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1676         }
1677         opn = "subu";
1678         break;
1679 #if defined(TARGET_MIPS64)
1680     case OPC_DADD:
1681         {
1682             TCGv t0 = tcg_temp_local_new();
1683             TCGv t1 = tcg_temp_new();
1684             TCGv t2 = tcg_temp_new();
1685             int l1 = gen_new_label();
1686 
1687             gen_load_gpr(t1, rs);
1688             gen_load_gpr(t2, rt);
1689             tcg_gen_add_tl(t0, t1, t2);
1690             tcg_gen_xor_tl(t1, t1, t2);
1691             tcg_gen_xor_tl(t2, t0, t2);
1692             tcg_gen_andc_tl(t1, t2, t1);
1693             tcg_temp_free(t2);
1694             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1695             tcg_temp_free(t1);
1696             /* operands of same sign, result different sign */
1697             generate_exception(ctx, EXCP_OVERFLOW);
1698             gen_set_label(l1);
1699             gen_store_gpr(t0, rd);
1700             tcg_temp_free(t0);
1701         }
1702         opn = "dadd";
1703         break;
1704     case OPC_DADDU:
1705         if (rs != 0 && rt != 0) {
1706             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1707         } else if (rs == 0 && rt != 0) {
1708             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1709         } else if (rs != 0 && rt == 0) {
1710             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1711         } else {
1712             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1713         }
1714         opn = "daddu";
1715         break;
1716     case OPC_DSUB:
1717         {
1718             TCGv t0 = tcg_temp_local_new();
1719             TCGv t1 = tcg_temp_new();
1720             TCGv t2 = tcg_temp_new();
1721             int l1 = gen_new_label();
1722 
1723             gen_load_gpr(t1, rs);
1724             gen_load_gpr(t2, rt);
1725             tcg_gen_sub_tl(t0, t1, t2);
1726             tcg_gen_xor_tl(t2, t1, t2);
1727             tcg_gen_xor_tl(t1, t0, t1);
1728             tcg_gen_and_tl(t1, t1, t2);
1729             tcg_temp_free(t2);
1730             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1731             tcg_temp_free(t1);
1732             /* operands of different sign, first operand and result different sign */
1733             generate_exception(ctx, EXCP_OVERFLOW);
1734             gen_set_label(l1);
1735             gen_store_gpr(t0, rd);
1736             tcg_temp_free(t0);
1737         }
1738         opn = "dsub";
1739         break;
1740     case OPC_DSUBU:
1741         if (rs != 0 && rt != 0) {
1742             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1743         } else if (rs == 0 && rt != 0) {
1744             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1745         } else if (rs != 0 && rt == 0) {
1746             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1747         } else {
1748             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1749         }
1750         opn = "dsubu";
1751         break;
1752 #endif
1753     case OPC_MUL:
1754         if (likely(rs != 0 && rt != 0)) {
1755             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1756             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1757         } else {
1758             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1759         }
1760         opn = "mul";
1761         break;
1762     }
1763     (void)opn; /* avoid a compiler warning */
1764     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1765 }
1766 
1767 /* Conditional move */
gen_cond_move(CPUState * env,uint32_t opc,int rd,int rs,int rt)1768 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1769 {
1770     const char *opn = "cond move";
1771     int l1;
1772 
1773     if (rd == 0) {
1774         /* If no destination, treat it as a NOP.
1775            For add & sub, we must generate the overflow exception when needed. */
1776         MIPS_DEBUG("NOP");
1777         return;
1778     }
1779 
1780     l1 = gen_new_label();
1781     switch (opc) {
1782     case OPC_MOVN:
1783         if (likely(rt != 0))
1784             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1785         else
1786             tcg_gen_br(l1);
1787         opn = "movn";
1788         break;
1789     case OPC_MOVZ:
1790         if (likely(rt != 0))
1791             tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1792         opn = "movz";
1793         break;
1794     }
1795     if (rs != 0)
1796         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1797     else
1798         tcg_gen_movi_tl(cpu_gpr[rd], 0);
1799     gen_set_label(l1);
1800 
1801     (void)opn; /* avoid a compiler warning */
1802     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1803 }
1804 
1805 /* Logic */
gen_logic(CPUState * env,uint32_t opc,int rd,int rs,int rt)1806 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1807 {
1808     const char *opn = "logic";
1809 
1810     if (rd == 0) {
1811         /* If no destination, treat it as a NOP. */
1812         MIPS_DEBUG("NOP");
1813         return;
1814     }
1815 
1816     switch (opc) {
1817     case OPC_AND:
1818         if (likely(rs != 0 && rt != 0)) {
1819             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820         } else {
1821             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1822         }
1823         opn = "and";
1824         break;
1825     case OPC_NOR:
1826         if (rs != 0 && rt != 0) {
1827             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1828         } else if (rs == 0 && rt != 0) {
1829             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1830         } else if (rs != 0 && rt == 0) {
1831             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1832         } else {
1833             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1834         }
1835         opn = "nor";
1836         break;
1837     case OPC_OR:
1838         if (likely(rs != 0 && rt != 0)) {
1839             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1840         } else if (rs == 0 && rt != 0) {
1841             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1842         } else if (rs != 0 && rt == 0) {
1843             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1844         } else {
1845             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1846         }
1847         opn = "or";
1848         break;
1849     case OPC_XOR:
1850         if (likely(rs != 0 && rt != 0)) {
1851             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1852         } else if (rs == 0 && rt != 0) {
1853             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1854         } else if (rs != 0 && rt == 0) {
1855             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1856         } else {
1857             tcg_gen_movi_tl(cpu_gpr[rd], 0);
1858         }
1859         opn = "xor";
1860         break;
1861     }
1862     (void)opn; /* avoid a compiler warning */
1863     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1864 }
1865 
1866 /* Set on lower than */
gen_slt(CPUState * env,uint32_t opc,int rd,int rs,int rt)1867 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1868 {
1869     const char *opn = "slt";
1870     TCGv t0, t1;
1871 
1872     if (rd == 0) {
1873         /* If no destination, treat it as a NOP. */
1874         MIPS_DEBUG("NOP");
1875         return;
1876     }
1877 
1878     t0 = tcg_temp_new();
1879     t1 = tcg_temp_new();
1880     gen_load_gpr(t0, rs);
1881     gen_load_gpr(t1, rt);
1882     switch (opc) {
1883     case OPC_SLT:
1884         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1885         opn = "slt";
1886         break;
1887     case OPC_SLTU:
1888         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1889         opn = "sltu";
1890         break;
1891     }
1892     (void)opn; /* avoid a compiler warning */
1893     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1894     tcg_temp_free(t0);
1895     tcg_temp_free(t1);
1896 }
1897 
1898 /* Shifts */
gen_shift(CPUState * env,DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)1899 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1900                        int rd, int rs, int rt)
1901 {
1902     const char *opn = "shifts";
1903     TCGv t0, t1;
1904 
1905     if (rd == 0) {
1906         /* If no destination, treat it as a NOP.
1907            For add & sub, we must generate the overflow exception when needed. */
1908         MIPS_DEBUG("NOP");
1909         return;
1910     }
1911 
1912     t0 = tcg_temp_new();
1913     t1 = tcg_temp_new();
1914     gen_load_gpr(t0, rs);
1915     gen_load_gpr(t1, rt);
1916     switch (opc) {
1917     case OPC_SLLV:
1918         tcg_gen_andi_tl(t0, t0, 0x1f);
1919         tcg_gen_shl_tl(t0, t1, t0);
1920         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1921         opn = "sllv";
1922         break;
1923     case OPC_SRAV:
1924         tcg_gen_andi_tl(t0, t0, 0x1f);
1925         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1926         opn = "srav";
1927         break;
1928     case OPC_SRLV:
1929         tcg_gen_ext32u_tl(t1, t1);
1930         tcg_gen_andi_tl(t0, t0, 0x1f);
1931         tcg_gen_shr_tl(t0, t1, t0);
1932         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1933         opn = "srlv";
1934         break;
1935     case OPC_ROTRV:
1936         {
1937             TCGv_i32 t2 = tcg_temp_new_i32();
1938             TCGv_i32 t3 = tcg_temp_new_i32();
1939 
1940             tcg_gen_trunc_tl_i32(t2, t0);
1941             tcg_gen_trunc_tl_i32(t3, t1);
1942             tcg_gen_andi_i32(t2, t2, 0x1f);
1943             tcg_gen_rotr_i32(t2, t3, t2);
1944             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1945             tcg_temp_free_i32(t2);
1946             tcg_temp_free_i32(t3);
1947             opn = "rotrv";
1948         }
1949         break;
1950 #if defined(TARGET_MIPS64)
1951     case OPC_DSLLV:
1952         tcg_gen_andi_tl(t0, t0, 0x3f);
1953         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1954         opn = "dsllv";
1955         break;
1956     case OPC_DSRAV:
1957         tcg_gen_andi_tl(t0, t0, 0x3f);
1958         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1959         opn = "dsrav";
1960         break;
1961     case OPC_DSRLV:
1962         tcg_gen_andi_tl(t0, t0, 0x3f);
1963         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1964         opn = "dsrlv";
1965         break;
1966     case OPC_DROTRV:
1967         tcg_gen_andi_tl(t0, t0, 0x3f);
1968         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1969         opn = "drotrv";
1970         break;
1971 #endif
1972     }
1973     (void)opn; /* avoid a compiler warning */
1974     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1975     tcg_temp_free(t0);
1976     tcg_temp_free(t1);
1977 }
1978 
1979 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int reg)1980 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1981 {
1982     const char *opn = "hilo";
1983 
1984     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1985         /* Treat as NOP. */
1986         MIPS_DEBUG("NOP");
1987         return;
1988     }
1989     switch (opc) {
1990     case OPC_MFHI:
1991         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1992         opn = "mfhi";
1993         break;
1994     case OPC_MFLO:
1995         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1996         opn = "mflo";
1997         break;
1998     case OPC_MTHI:
1999         if (reg != 0)
2000             tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2001         else
2002             tcg_gen_movi_tl(cpu_HI[0], 0);
2003         opn = "mthi";
2004         break;
2005     case OPC_MTLO:
2006         if (reg != 0)
2007             tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2008         else
2009             tcg_gen_movi_tl(cpu_LO[0], 0);
2010         opn = "mtlo";
2011         break;
2012     }
2013     (void)opn; /* avoid a compiler warning */
2014     MIPS_DEBUG("%s %s", opn, regnames[reg]);
2015 }
2016 
gen_muldiv(DisasContext * ctx,uint32_t opc,int rs,int rt)2017 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2018                         int rs, int rt)
2019 {
2020     const char *opn = "mul/div";
2021     TCGv t0, t1;
2022 
2023     switch (opc) {
2024     case OPC_DIV:
2025     case OPC_DIVU:
2026 #if defined(TARGET_MIPS64)
2027     case OPC_DDIV:
2028     case OPC_DDIVU:
2029 #endif
2030         t0 = tcg_temp_local_new();
2031         t1 = tcg_temp_local_new();
2032         break;
2033     default:
2034         t0 = tcg_temp_new();
2035         t1 = tcg_temp_new();
2036         break;
2037     }
2038 
2039     gen_load_gpr(t0, rs);
2040     gen_load_gpr(t1, rt);
2041     switch (opc) {
2042     case OPC_DIV:
2043         {
2044             int l1 = gen_new_label();
2045             int l2 = gen_new_label();
2046 
2047             tcg_gen_ext32s_tl(t0, t0);
2048             tcg_gen_ext32s_tl(t1, t1);
2049             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2050             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2051             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2052 
2053             tcg_gen_mov_tl(cpu_LO[0], t0);
2054             tcg_gen_movi_tl(cpu_HI[0], 0);
2055             tcg_gen_br(l1);
2056             gen_set_label(l2);
2057             tcg_gen_div_tl(cpu_LO[0], t0, t1);
2058             tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2059             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2060             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2061             gen_set_label(l1);
2062         }
2063         opn = "div";
2064         break;
2065     case OPC_DIVU:
2066         {
2067             int l1 = gen_new_label();
2068 
2069             tcg_gen_ext32u_tl(t0, t0);
2070             tcg_gen_ext32u_tl(t1, t1);
2071             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2072             tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2073             tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2074             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2075             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2076             gen_set_label(l1);
2077         }
2078         opn = "divu";
2079         break;
2080     case OPC_MULT:
2081         {
2082             TCGv_i64 t2 = tcg_temp_new_i64();
2083             TCGv_i64 t3 = tcg_temp_new_i64();
2084 
2085             tcg_gen_ext_tl_i64(t2, t0);
2086             tcg_gen_ext_tl_i64(t3, t1);
2087             tcg_gen_mul_i64(t2, t2, t3);
2088             tcg_temp_free_i64(t3);
2089             tcg_gen_trunc_i64_tl(t0, t2);
2090             tcg_gen_shri_i64(t2, t2, 32);
2091             tcg_gen_trunc_i64_tl(t1, t2);
2092             tcg_temp_free_i64(t2);
2093             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2094             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2095         }
2096         opn = "mult";
2097         break;
2098     case OPC_MULTU:
2099         {
2100             TCGv_i64 t2 = tcg_temp_new_i64();
2101             TCGv_i64 t3 = tcg_temp_new_i64();
2102 
2103             tcg_gen_ext32u_tl(t0, t0);
2104             tcg_gen_ext32u_tl(t1, t1);
2105             tcg_gen_extu_tl_i64(t2, t0);
2106             tcg_gen_extu_tl_i64(t3, t1);
2107             tcg_gen_mul_i64(t2, t2, t3);
2108             tcg_temp_free_i64(t3);
2109             tcg_gen_trunc_i64_tl(t0, t2);
2110             tcg_gen_shri_i64(t2, t2, 32);
2111             tcg_gen_trunc_i64_tl(t1, t2);
2112             tcg_temp_free_i64(t2);
2113             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2114             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2115         }
2116         opn = "multu";
2117         break;
2118 #if defined(TARGET_MIPS64)
2119     case OPC_DDIV:
2120         {
2121             int l1 = gen_new_label();
2122             int l2 = gen_new_label();
2123 
2124             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2125             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2126             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2127             tcg_gen_mov_tl(cpu_LO[0], t0);
2128             tcg_gen_movi_tl(cpu_HI[0], 0);
2129             tcg_gen_br(l1);
2130             gen_set_label(l2);
2131             tcg_gen_div_i64(cpu_LO[0], t0, t1);
2132             tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2133             gen_set_label(l1);
2134         }
2135         opn = "ddiv";
2136         break;
2137     case OPC_DDIVU:
2138         {
2139             int l1 = gen_new_label();
2140 
2141             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2142             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2143             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2144             gen_set_label(l1);
2145         }
2146         opn = "ddivu";
2147         break;
2148     case OPC_DMULT:
2149         gen_helper_dmult(t0, t1);
2150         opn = "dmult";
2151         break;
2152     case OPC_DMULTU:
2153         gen_helper_dmultu(t0, t1);
2154         opn = "dmultu";
2155         break;
2156 #endif
2157     case OPC_MADD:
2158         {
2159             TCGv_i64 t2 = tcg_temp_new_i64();
2160             TCGv_i64 t3 = tcg_temp_new_i64();
2161 
2162             tcg_gen_ext_tl_i64(t2, t0);
2163             tcg_gen_ext_tl_i64(t3, t1);
2164             tcg_gen_mul_i64(t2, t2, t3);
2165             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2166             tcg_gen_add_i64(t2, t2, t3);
2167             tcg_temp_free_i64(t3);
2168             tcg_gen_trunc_i64_tl(t0, t2);
2169             tcg_gen_shri_i64(t2, t2, 32);
2170             tcg_gen_trunc_i64_tl(t1, t2);
2171             tcg_temp_free_i64(t2);
2172             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2173             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2174         }
2175         opn = "madd";
2176         break;
2177     case OPC_MADDU:
2178        {
2179             TCGv_i64 t2 = tcg_temp_new_i64();
2180             TCGv_i64 t3 = tcg_temp_new_i64();
2181 
2182             tcg_gen_ext32u_tl(t0, t0);
2183             tcg_gen_ext32u_tl(t1, t1);
2184             tcg_gen_extu_tl_i64(t2, t0);
2185             tcg_gen_extu_tl_i64(t3, t1);
2186             tcg_gen_mul_i64(t2, t2, t3);
2187             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2188             tcg_gen_add_i64(t2, t2, t3);
2189             tcg_temp_free_i64(t3);
2190             tcg_gen_trunc_i64_tl(t0, t2);
2191             tcg_gen_shri_i64(t2, t2, 32);
2192             tcg_gen_trunc_i64_tl(t1, t2);
2193             tcg_temp_free_i64(t2);
2194             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2195             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2196         }
2197         opn = "maddu";
2198         break;
2199     case OPC_MSUB:
2200         {
2201             TCGv_i64 t2 = tcg_temp_new_i64();
2202             TCGv_i64 t3 = tcg_temp_new_i64();
2203 
2204             tcg_gen_ext_tl_i64(t2, t0);
2205             tcg_gen_ext_tl_i64(t3, t1);
2206             tcg_gen_mul_i64(t2, t2, t3);
2207             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2208             tcg_gen_sub_i64(t2, t3, t2);
2209             tcg_temp_free_i64(t3);
2210             tcg_gen_trunc_i64_tl(t0, t2);
2211             tcg_gen_shri_i64(t2, t2, 32);
2212             tcg_gen_trunc_i64_tl(t1, t2);
2213             tcg_temp_free_i64(t2);
2214             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2215             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2216         }
2217         opn = "msub";
2218         break;
2219     case OPC_MSUBU:
2220         {
2221             TCGv_i64 t2 = tcg_temp_new_i64();
2222             TCGv_i64 t3 = tcg_temp_new_i64();
2223 
2224             tcg_gen_ext32u_tl(t0, t0);
2225             tcg_gen_ext32u_tl(t1, t1);
2226             tcg_gen_extu_tl_i64(t2, t0);
2227             tcg_gen_extu_tl_i64(t3, t1);
2228             tcg_gen_mul_i64(t2, t2, t3);
2229             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2230             tcg_gen_sub_i64(t2, t3, t2);
2231             tcg_temp_free_i64(t3);
2232             tcg_gen_trunc_i64_tl(t0, t2);
2233             tcg_gen_shri_i64(t2, t2, 32);
2234             tcg_gen_trunc_i64_tl(t1, t2);
2235             tcg_temp_free_i64(t2);
2236             tcg_gen_ext32s_tl(cpu_LO[0], t0);
2237             tcg_gen_ext32s_tl(cpu_HI[0], t1);
2238         }
2239         opn = "msubu";
2240         break;
2241     default:
2242         MIPS_INVAL(opn);
2243         generate_exception(ctx, EXCP_RI);
2244         goto out;
2245     }
2246     (void)opn; /* avoid a compiler warning */
2247     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2248  out:
2249     tcg_temp_free(t0);
2250     tcg_temp_free(t1);
2251 }
2252 
gen_mul_vr54xx(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2253 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2254                             int rd, int rs, int rt)
2255 {
2256     const char *opn = "mul vr54xx";
2257     TCGv t0 = tcg_temp_new();
2258     TCGv t1 = tcg_temp_new();
2259 
2260     gen_load_gpr(t0, rs);
2261     gen_load_gpr(t1, rt);
2262 
2263     switch (opc) {
2264     case OPC_VR54XX_MULS:
2265         gen_helper_muls(t0, t0, t1);
2266         opn = "muls";
2267         break;
2268     case OPC_VR54XX_MULSU:
2269         gen_helper_mulsu(t0, t0, t1);
2270         opn = "mulsu";
2271         break;
2272     case OPC_VR54XX_MACC:
2273         gen_helper_macc(t0, t0, t1);
2274         opn = "macc";
2275         break;
2276     case OPC_VR54XX_MACCU:
2277         gen_helper_maccu(t0, t0, t1);
2278         opn = "maccu";
2279         break;
2280     case OPC_VR54XX_MSAC:
2281         gen_helper_msac(t0, t0, t1);
2282         opn = "msac";
2283         break;
2284     case OPC_VR54XX_MSACU:
2285         gen_helper_msacu(t0, t0, t1);
2286         opn = "msacu";
2287         break;
2288     case OPC_VR54XX_MULHI:
2289         gen_helper_mulhi(t0, t0, t1);
2290         opn = "mulhi";
2291         break;
2292     case OPC_VR54XX_MULHIU:
2293         gen_helper_mulhiu(t0, t0, t1);
2294         opn = "mulhiu";
2295         break;
2296     case OPC_VR54XX_MULSHI:
2297         gen_helper_mulshi(t0, t0, t1);
2298         opn = "mulshi";
2299         break;
2300     case OPC_VR54XX_MULSHIU:
2301         gen_helper_mulshiu(t0, t0, t1);
2302         opn = "mulshiu";
2303         break;
2304     case OPC_VR54XX_MACCHI:
2305         gen_helper_macchi(t0, t0, t1);
2306         opn = "macchi";
2307         break;
2308     case OPC_VR54XX_MACCHIU:
2309         gen_helper_macchiu(t0, t0, t1);
2310         opn = "macchiu";
2311         break;
2312     case OPC_VR54XX_MSACHI:
2313         gen_helper_msachi(t0, t0, t1);
2314         opn = "msachi";
2315         break;
2316     case OPC_VR54XX_MSACHIU:
2317         gen_helper_msachiu(t0, t0, t1);
2318         opn = "msachiu";
2319         break;
2320     default:
2321         MIPS_INVAL("mul vr54xx");
2322         generate_exception(ctx, EXCP_RI);
2323         goto out;
2324     }
2325     gen_store_gpr(t0, rd);
2326     (void)opn; /* avoid a compiler warning */
2327     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2328 
2329  out:
2330     tcg_temp_free(t0);
2331     tcg_temp_free(t1);
2332 }
2333 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)2334 static void gen_cl (DisasContext *ctx, uint32_t opc,
2335                     int rd, int rs)
2336 {
2337     const char *opn = "CLx";
2338     TCGv t0;
2339 
2340     if (rd == 0) {
2341         /* Treat as NOP. */
2342         MIPS_DEBUG("NOP");
2343         return;
2344     }
2345     t0 = tcg_temp_new();
2346     gen_load_gpr(t0, rs);
2347     switch (opc) {
2348     case OPC_CLO:
2349         gen_helper_clo(cpu_gpr[rd], t0);
2350         opn = "clo";
2351         break;
2352     case OPC_CLZ:
2353         gen_helper_clz(cpu_gpr[rd], t0);
2354         opn = "clz";
2355         break;
2356 #if defined(TARGET_MIPS64)
2357     case OPC_DCLO:
2358         gen_helper_dclo(cpu_gpr[rd], t0);
2359         opn = "dclo";
2360         break;
2361     case OPC_DCLZ:
2362         gen_helper_dclz(cpu_gpr[rd], t0);
2363         opn = "dclz";
2364         break;
2365 #endif
2366     }
2367     (void)opn; /* avoid a compiler warning */
2368     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2369     tcg_temp_free(t0);
2370 }
2371 
2372 /* Godson integer instructions */
gen_loongson_integer(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2373 static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2374                                 int rd, int rs, int rt)
2375 {
2376     const char *opn = "loongson";
2377     TCGv t0, t1;
2378 
2379     if (rd == 0) {
2380         /* Treat as NOP. */
2381         MIPS_DEBUG("NOP");
2382         return;
2383     }
2384 
2385     switch (opc) {
2386     case OPC_MULT_G_2E:
2387     case OPC_MULT_G_2F:
2388     case OPC_MULTU_G_2E:
2389     case OPC_MULTU_G_2F:
2390 #if defined(TARGET_MIPS64)
2391     case OPC_DMULT_G_2E:
2392     case OPC_DMULT_G_2F:
2393     case OPC_DMULTU_G_2E:
2394     case OPC_DMULTU_G_2F:
2395 #endif
2396         t0 = tcg_temp_new();
2397         t1 = tcg_temp_new();
2398         break;
2399     default:
2400         t0 = tcg_temp_local_new();
2401         t1 = tcg_temp_local_new();
2402         break;
2403     }
2404 
2405     gen_load_gpr(t0, rs);
2406     gen_load_gpr(t1, rt);
2407 
2408     switch (opc) {
2409     case OPC_MULT_G_2E:
2410     case OPC_MULT_G_2F:
2411         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2412         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2413         opn = "mult.g";
2414         break;
2415     case OPC_MULTU_G_2E:
2416     case OPC_MULTU_G_2F:
2417         tcg_gen_ext32u_tl(t0, t0);
2418         tcg_gen_ext32u_tl(t1, t1);
2419         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2420         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2421         opn = "multu.g";
2422         break;
2423     case OPC_DIV_G_2E:
2424     case OPC_DIV_G_2F:
2425         {
2426             int l1 = gen_new_label();
2427             int l2 = gen_new_label();
2428             int l3 = gen_new_label();
2429             tcg_gen_ext32s_tl(t0, t0);
2430             tcg_gen_ext32s_tl(t1, t1);
2431             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2432             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2433             tcg_gen_br(l3);
2434             gen_set_label(l1);
2435             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2436             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2437             tcg_gen_mov_tl(cpu_gpr[rd], t0);
2438             tcg_gen_br(l3);
2439             gen_set_label(l2);
2440             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2441             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2442             gen_set_label(l3);
2443         }
2444         opn = "div.g";
2445         break;
2446     case OPC_DIVU_G_2E:
2447     case OPC_DIVU_G_2F:
2448         {
2449             int l1 = gen_new_label();
2450             int l2 = gen_new_label();
2451             tcg_gen_ext32u_tl(t0, t0);
2452             tcg_gen_ext32u_tl(t1, t1);
2453             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2454             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2455             tcg_gen_br(l2);
2456             gen_set_label(l1);
2457             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2458             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2459             gen_set_label(l2);
2460         }
2461         opn = "divu.g";
2462         break;
2463     case OPC_MOD_G_2E:
2464     case OPC_MOD_G_2F:
2465         {
2466             int l1 = gen_new_label();
2467             int l2 = gen_new_label();
2468             int l3 = gen_new_label();
2469             tcg_gen_ext32u_tl(t0, t0);
2470             tcg_gen_ext32u_tl(t1, t1);
2471             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2472             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2473             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2474             gen_set_label(l1);
2475             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2476             tcg_gen_br(l3);
2477             gen_set_label(l2);
2478             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2479             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2480             gen_set_label(l3);
2481         }
2482         opn = "mod.g";
2483         break;
2484     case OPC_MODU_G_2E:
2485     case OPC_MODU_G_2F:
2486         {
2487             int l1 = gen_new_label();
2488             int l2 = gen_new_label();
2489             tcg_gen_ext32u_tl(t0, t0);
2490             tcg_gen_ext32u_tl(t1, t1);
2491             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2492             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2493             tcg_gen_br(l2);
2494             gen_set_label(l1);
2495             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2496             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2497             gen_set_label(l2);
2498         }
2499         opn = "modu.g";
2500         break;
2501 #if defined(TARGET_MIPS64)
2502     case OPC_DMULT_G_2E:
2503     case OPC_DMULT_G_2F:
2504         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2505         opn = "dmult.g";
2506         break;
2507     case OPC_DMULTU_G_2E:
2508     case OPC_DMULTU_G_2F:
2509         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2510         opn = "dmultu.g";
2511         break;
2512     case OPC_DDIV_G_2E:
2513     case OPC_DDIV_G_2F:
2514         {
2515             int l1 = gen_new_label();
2516             int l2 = gen_new_label();
2517             int l3 = gen_new_label();
2518             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2519             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2520             tcg_gen_br(l3);
2521             gen_set_label(l1);
2522             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2523             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2524             tcg_gen_mov_tl(cpu_gpr[rd], t0);
2525             tcg_gen_br(l3);
2526             gen_set_label(l2);
2527             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2528             gen_set_label(l3);
2529         }
2530         opn = "ddiv.g";
2531         break;
2532     case OPC_DDIVU_G_2E:
2533     case OPC_DDIVU_G_2F:
2534         {
2535             int l1 = gen_new_label();
2536             int l2 = gen_new_label();
2537             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2538             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2539             tcg_gen_br(l2);
2540             gen_set_label(l1);
2541             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2542             gen_set_label(l2);
2543         }
2544         opn = "ddivu.g";
2545         break;
2546     case OPC_DMOD_G_2E:
2547     case OPC_DMOD_G_2F:
2548         {
2549             int l1 = gen_new_label();
2550             int l2 = gen_new_label();
2551             int l3 = gen_new_label();
2552             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2553             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2554             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2555             gen_set_label(l1);
2556             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2557             tcg_gen_br(l3);
2558             gen_set_label(l2);
2559             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2560             gen_set_label(l3);
2561         }
2562         opn = "dmod.g";
2563         break;
2564     case OPC_DMODU_G_2E:
2565     case OPC_DMODU_G_2F:
2566         {
2567             int l1 = gen_new_label();
2568             int l2 = gen_new_label();
2569             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2570             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2571             tcg_gen_br(l2);
2572             gen_set_label(l1);
2573             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2574             gen_set_label(l2);
2575         }
2576         opn = "dmodu.g";
2577         break;
2578 #endif
2579     }
2580 
2581     (void)opn; /* avoid a compiler warning */
2582     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2583     tcg_temp_free(t0);
2584     tcg_temp_free(t1);
2585 }
2586 
2587 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm)2588 static void gen_trap (DisasContext *ctx, uint32_t opc,
2589                       int rs, int rt, int16_t imm)
2590 {
2591     int cond;
2592     TCGv t0 = tcg_temp_new();
2593     TCGv t1 = tcg_temp_new();
2594 
2595     cond = 0;
2596     /* Load needed operands */
2597     switch (opc) {
2598     case OPC_TEQ:
2599     case OPC_TGE:
2600     case OPC_TGEU:
2601     case OPC_TLT:
2602     case OPC_TLTU:
2603     case OPC_TNE:
2604         /* Compare two registers */
2605         if (rs != rt) {
2606             gen_load_gpr(t0, rs);
2607             gen_load_gpr(t1, rt);
2608             cond = 1;
2609         }
2610         break;
2611     case OPC_TEQI:
2612     case OPC_TGEI:
2613     case OPC_TGEIU:
2614     case OPC_TLTI:
2615     case OPC_TLTIU:
2616     case OPC_TNEI:
2617         /* Compare register to immediate */
2618         if (rs != 0 || imm != 0) {
2619             gen_load_gpr(t0, rs);
2620             tcg_gen_movi_tl(t1, (int32_t)imm);
2621             cond = 1;
2622         }
2623         break;
2624     }
2625     if (cond == 0) {
2626         switch (opc) {
2627         case OPC_TEQ:   /* rs == rs */
2628         case OPC_TEQI:  /* r0 == 0  */
2629         case OPC_TGE:   /* rs >= rs */
2630         case OPC_TGEI:  /* r0 >= 0  */
2631         case OPC_TGEU:  /* rs >= rs unsigned */
2632         case OPC_TGEIU: /* r0 >= 0  unsigned */
2633             /* Always trap */
2634             generate_exception(ctx, EXCP_TRAP);
2635             break;
2636         case OPC_TLT:   /* rs < rs           */
2637         case OPC_TLTI:  /* r0 < 0            */
2638         case OPC_TLTU:  /* rs < rs unsigned  */
2639         case OPC_TLTIU: /* r0 < 0  unsigned  */
2640         case OPC_TNE:   /* rs != rs          */
2641         case OPC_TNEI:  /* r0 != 0           */
2642             /* Never trap: treat as NOP. */
2643             break;
2644         }
2645     } else {
2646         int l1 = gen_new_label();
2647 
2648         switch (opc) {
2649         case OPC_TEQ:
2650         case OPC_TEQI:
2651             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2652             break;
2653         case OPC_TGE:
2654         case OPC_TGEI:
2655             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2656             break;
2657         case OPC_TGEU:
2658         case OPC_TGEIU:
2659             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2660             break;
2661         case OPC_TLT:
2662         case OPC_TLTI:
2663             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2664             break;
2665         case OPC_TLTU:
2666         case OPC_TLTIU:
2667             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2668             break;
2669         case OPC_TNE:
2670         case OPC_TNEI:
2671             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2672             break;
2673         }
2674         generate_exception(ctx, EXCP_TRAP);
2675         gen_set_label(l1);
2676     }
2677     tcg_temp_free(t0);
2678     tcg_temp_free(t1);
2679 }
2680 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)2681 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2682 {
2683     TranslationBlock *tb;
2684     tb = ctx->tb;
2685     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2686         likely(!ctx->singlestep_enabled)) {
2687         tcg_gen_goto_tb(n);
2688         gen_save_pc(dest);
2689         tcg_gen_exit_tb((long)tb + n);
2690     } else {
2691         gen_save_pc(dest);
2692         if (ctx->singlestep_enabled) {
2693             save_cpu_state(ctx, 0);
2694             gen_helper_0i(raise_exception, EXCP_DEBUG);
2695         }
2696         tcg_gen_exit_tb(0);
2697     }
2698 }
2699 
2700 /* Branches (before delay slot) */
gen_compute_branch(DisasContext * ctx,uint32_t opc,int insn_bytes,int rs,int rt,int32_t offset)2701 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2702                                 int insn_bytes,
2703                                 int rs, int rt, int32_t offset)
2704 {
2705     target_ulong btgt = -1;
2706     int blink = 0;
2707     int bcond_compute = 0;
2708     TCGv t0 = tcg_temp_new();
2709     TCGv t1 = tcg_temp_new();
2710 
2711     if (ctx->hflags & MIPS_HFLAG_BMASK) {
2712 #ifdef MIPS_DEBUG_DISAS
2713         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2714 #endif
2715         generate_exception(ctx, EXCP_RI);
2716         goto out;
2717     }
2718 
2719     /* Load needed operands */
2720     switch (opc) {
2721     case OPC_BEQ:
2722     case OPC_BEQL:
2723     case OPC_BNE:
2724     case OPC_BNEL:
2725         /* Compare two registers */
2726         if (rs != rt) {
2727             gen_load_gpr(t0, rs);
2728             gen_load_gpr(t1, rt);
2729             bcond_compute = 1;
2730         }
2731         btgt = ctx->pc + insn_bytes + offset;
2732         break;
2733     case OPC_BGEZ:
2734     case OPC_BGEZAL:
2735     case OPC_BGEZALS:
2736     case OPC_BGEZALL:
2737     case OPC_BGEZL:
2738     case OPC_BGTZ:
2739     case OPC_BGTZL:
2740     case OPC_BLEZ:
2741     case OPC_BLEZL:
2742     case OPC_BLTZ:
2743     case OPC_BLTZAL:
2744     case OPC_BLTZALS:
2745     case OPC_BLTZALL:
2746     case OPC_BLTZL:
2747         /* Compare to zero */
2748         if (rs != 0) {
2749             gen_load_gpr(t0, rs);
2750             bcond_compute = 1;
2751         }
2752         btgt = ctx->pc + insn_bytes + offset;
2753         break;
2754     case OPC_J:
2755     case OPC_JAL:
2756     case OPC_JALX:
2757     case OPC_JALS:
2758     case OPC_JALXS:
2759         /* Jump to immediate */
2760         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2761         break;
2762     case OPC_JR:
2763     case OPC_JALR:
2764     case OPC_JALRC:
2765     case OPC_JALRS:
2766         /* Jump to register */
2767         if (offset != 0 && offset != 16) {
2768             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2769                others are reserved. */
2770             MIPS_INVAL("jump hint");
2771             generate_exception(ctx, EXCP_RI);
2772             goto out;
2773         }
2774         gen_load_gpr(btarget, rs);
2775         break;
2776     default:
2777         MIPS_INVAL("branch/jump");
2778         generate_exception(ctx, EXCP_RI);
2779         goto out;
2780     }
2781     if (bcond_compute == 0) {
2782         /* No condition to be computed */
2783         switch (opc) {
2784         case OPC_BEQ:     /* rx == rx        */
2785         case OPC_BEQL:    /* rx == rx likely */
2786         case OPC_BGEZ:    /* 0 >= 0          */
2787         case OPC_BGEZL:   /* 0 >= 0 likely   */
2788         case OPC_BLEZ:    /* 0 <= 0          */
2789         case OPC_BLEZL:   /* 0 <= 0 likely   */
2790             /* Always take */
2791             ctx->hflags |= MIPS_HFLAG_B;
2792             MIPS_DEBUG("balways");
2793             break;
2794         case OPC_BGEZALS:
2795         case OPC_BGEZAL:  /* 0 >= 0          */
2796         case OPC_BGEZALL: /* 0 >= 0 likely   */
2797             ctx->hflags |= (