Statistics
| Branch: | Revision:

root / target-mips / translate.c @ b53371ed

History | View | Annotate | Download (475.2 kB)

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
 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22
 */
23

    
24
#include "cpu.h"
25
#include "disas.h"
26
#include "tcg-op.h"
27

    
28
#include "helper.h"
29
#define GEN_HELPER 1
30
#include "helper.h"
31

    
32
#define MIPS_DEBUG_DISAS 0
33
//#define MIPS_DEBUG_SIGN_EXTENSIONS
34

    
35
/* MIPS major opcodes */
36
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
37

    
38
enum {
39
    /* indirect opcode tables */
40
    OPC_SPECIAL  = (0x00 << 26),
41
    OPC_REGIMM   = (0x01 << 26),
42
    OPC_CP0      = (0x10 << 26),
43
    OPC_CP1      = (0x11 << 26),
44
    OPC_CP2      = (0x12 << 26),
45
    OPC_CP3      = (0x13 << 26),
46
    OPC_SPECIAL2 = (0x1C << 26),
47
    OPC_SPECIAL3 = (0x1F << 26),
48
    /* arithmetic with immediate */
49
    OPC_ADDI     = (0x08 << 26),
50
    OPC_ADDIU    = (0x09 << 26),
51
    OPC_SLTI     = (0x0A << 26),
52
    OPC_SLTIU    = (0x0B << 26),
53
    /* logic with immediate */
54
    OPC_ANDI     = (0x0C << 26),
55
    OPC_ORI      = (0x0D << 26),
56
    OPC_XORI     = (0x0E << 26),
57
    OPC_LUI      = (0x0F << 26),
58
    /* arithmetic with immediate */
59
    OPC_DADDI    = (0x18 << 26),
60
    OPC_DADDIU   = (0x19 << 26),
61
    /* Jump and branches */
62
    OPC_J        = (0x02 << 26),
63
    OPC_JAL      = (0x03 << 26),
64
    OPC_JALS     = OPC_JAL | 0x5,
65
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
66
    OPC_BEQL     = (0x14 << 26),
67
    OPC_BNE      = (0x05 << 26),
68
    OPC_BNEL     = (0x15 << 26),
69
    OPC_BLEZ     = (0x06 << 26),
70
    OPC_BLEZL    = (0x16 << 26),
71
    OPC_BGTZ     = (0x07 << 26),
72
    OPC_BGTZL    = (0x17 << 26),
73
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
74
    OPC_JALXS    = OPC_JALX | 0x5,
75
    /* Load and stores */
76
    OPC_LDL      = (0x1A << 26),
77
    OPC_LDR      = (0x1B << 26),
78
    OPC_LB       = (0x20 << 26),
79
    OPC_LH       = (0x21 << 26),
80
    OPC_LWL      = (0x22 << 26),
81
    OPC_LW       = (0x23 << 26),
82
    OPC_LWPC     = OPC_LW | 0x5,
83
    OPC_LBU      = (0x24 << 26),
84
    OPC_LHU      = (0x25 << 26),
85
    OPC_LWR      = (0x26 << 26),
86
    OPC_LWU      = (0x27 << 26),
87
    OPC_SB       = (0x28 << 26),
88
    OPC_SH       = (0x29 << 26),
89
    OPC_SWL      = (0x2A << 26),
90
    OPC_SW       = (0x2B << 26),
91
    OPC_SDL      = (0x2C << 26),
92
    OPC_SDR      = (0x2D << 26),
93
    OPC_SWR      = (0x2E << 26),
94
    OPC_LL       = (0x30 << 26),
95
    OPC_LLD      = (0x34 << 26),
96
    OPC_LD       = (0x37 << 26),
97
    OPC_LDPC     = OPC_LD | 0x5,
98
    OPC_SC       = (0x38 << 26),
99
    OPC_SCD      = (0x3C << 26),
100
    OPC_SD       = (0x3F << 26),
101
    /* Floating point load/store */
102
    OPC_LWC1     = (0x31 << 26),
103
    OPC_LWC2     = (0x32 << 26),
104
    OPC_LDC1     = (0x35 << 26),
105
    OPC_LDC2     = (0x36 << 26),
106
    OPC_SWC1     = (0x39 << 26),
107
    OPC_SWC2     = (0x3A << 26),
108
    OPC_SDC1     = (0x3D << 26),
109
    OPC_SDC2     = (0x3E << 26),
110
    /* MDMX ASE specific */
111
    OPC_MDMX     = (0x1E << 26),
112
    /* Cache and prefetch */
113
    OPC_CACHE    = (0x2F << 26),
114
    OPC_PREF     = (0x33 << 26),
115
    /* Reserved major opcode */
116
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
117
};
118

    
119
/* MIPS special opcodes */
120
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
121

    
122
enum {
123
    /* Shifts */
124
    OPC_SLL      = 0x00 | OPC_SPECIAL,
125
    /* NOP is SLL r0, r0, 0   */
126
    /* SSNOP is SLL r0, r0, 1 */
127
    /* EHB is SLL r0, r0, 3 */
128
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
129
    OPC_ROTR     = OPC_SRL | (1 << 21),
130
    OPC_SRA      = 0x03 | OPC_SPECIAL,
131
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
132
    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
133
    OPC_ROTRV    = OPC_SRLV | (1 << 6),
134
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
135
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
136
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
137
    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
138
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
139
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
140
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
141
    OPC_DROTR    = OPC_DSRL | (1 << 21),
142
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
143
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
144
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145
    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
146
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
147
    /* Multiplication / division */
148
    OPC_MULT     = 0x18 | OPC_SPECIAL,
149
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
150
    OPC_DIV      = 0x1A | OPC_SPECIAL,
151
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
152
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
153
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
154
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
155
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
156
    /* 2 registers arithmetic / logic */
157
    OPC_ADD      = 0x20 | OPC_SPECIAL,
158
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
159
    OPC_SUB      = 0x22 | OPC_SPECIAL,
160
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
161
    OPC_AND      = 0x24 | OPC_SPECIAL,
162
    OPC_OR       = 0x25 | OPC_SPECIAL,
163
    OPC_XOR      = 0x26 | OPC_SPECIAL,
164
    OPC_NOR      = 0x27 | OPC_SPECIAL,
165
    OPC_SLT      = 0x2A | OPC_SPECIAL,
166
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
167
    OPC_DADD     = 0x2C | OPC_SPECIAL,
168
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
169
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
170
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
171
    /* Jumps */
172
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174
    OPC_JALRC    = OPC_JALR | (0x5 << 6),
175
    OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
176
    /* Traps */
177
    OPC_TGE      = 0x30 | OPC_SPECIAL,
178
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
179
    OPC_TLT      = 0x32 | OPC_SPECIAL,
180
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
181
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
182
    OPC_TNE      = 0x36 | OPC_SPECIAL,
183
    /* HI / LO registers load & stores */
184
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
185
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
186
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
187
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
188
    /* Conditional moves */
189
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
190
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
191

    
192
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
193

    
194
    /* Special */
195
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
196
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
197
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
198
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
199
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
200

    
201
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208
};
209

    
210
/* Multiplication variants of the vr54xx. */
211
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
212

    
213
enum {
214
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
215
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
216
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
217
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
218
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
219
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
220
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
221
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
222
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
223
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
225
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
227
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228
};
229

    
230
/* REGIMM (rt field) opcodes */
231
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232

    
233
enum {
234
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
235
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
236
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
237
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
238
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
239
    OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
240
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
241
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
242
    OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
243
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
244
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
245
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
246
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
247
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
248
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
249
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
250
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
251
};
252

    
253
/* Special2 opcodes */
254
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
255

    
256
enum {
257
    /* Multiply & xxx operations */
258
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
259
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
260
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
261
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
262
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
263
    /* Loongson 2F */
264
    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
265
    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
266
    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
267
    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268
    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
269
    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
270
    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
271
    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
272
    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
273
    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
274
    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
275
    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
276
    /* Misc */
277
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
278
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
279
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
280
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
281
    /* Special */
282
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
283
};
284

    
285
/* Special3 opcodes */
286
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
287

    
288
enum {
289
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
290
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
291
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
292
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
293
    OPC_INS      = 0x04 | OPC_SPECIAL3,
294
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
295
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
296
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
297
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
298
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
299
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
300
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
301
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
302

    
303
    /* Loongson 2E */
304
    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
305
    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
306
    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
307
    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
308
    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
309
    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310
    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
311
    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
312
    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
313
    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
314
    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
315
    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
316

    
317
    /* MIPS DSP Load */
318
    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
319
    /* MIPS DSP Arithmetic */
320
    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
321
#if defined(TARGET_MIPS64)
322
    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
323
#endif
324
    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
325
#if defined(TARGET_MIPS64)
326
    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
327
#endif
328
    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
329
    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
330
    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
331
#if defined(TARGET_MIPS64)
332
    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
333
#endif
334
    /* MIPS DSP GPR-Based Shift Sub-class */
335
    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
336
#if defined(TARGET_MIPS64)
337
    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
338
#endif
339
    /* MIPS DSP Multiply Sub-class insns */
340
    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
341
    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
342
    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
343
#if defined(TARGET_MIPS64)
344
    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
345
#endif
346
    /* DSP Bit/Manipulation Sub-class */
347
    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
348
#if defined(TARGET_MIPS64)
349
    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
350
#endif
351
    /* MIPS DSP Compare-Pick Sub-class */
352
    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
353
#if defined(TARGET_MIPS64)
354
    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
355
#endif
356
    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
357
    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
358
#if defined(TARGET_MIPS64)
359
    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
360
#endif
361
};
362

    
363
/* BSHFL opcodes */
364
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
365

    
366
enum {
367
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
368
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
369
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
370
};
371

    
372
/* DBSHFL opcodes */
373
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
374

    
375
enum {
376
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
377
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
378
};
379

    
380
/* MIPS DSP REGIMM opcodes */
381
enum {
382
    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
383
#if defined(TARGET_MIPS64)
384
    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
385
#endif
386
};
387

    
388
#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
389
/* MIPS DSP Load */
390
enum {
391
    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
392
    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
393
    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
394
#if defined(TARGET_MIPS64)
395
    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
396
#endif
397
};
398

    
399
#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
400
enum {
401
    /* MIPS DSP Arithmetic Sub-class */
402
    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
403
    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
404
    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
405
    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
406
    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
407
    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
408
    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
409
    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
410
    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
411
    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
412
    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
413
    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
414
    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
415
    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
416
    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
417
    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
418
    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
419
    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
420
    /* MIPS DSP Multiply Sub-class insns */
421
    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
422
    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
423
    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
424
    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
425
    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
426
    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
427
};
428

    
429
#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
430
#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
431
enum {
432
    /* MIPS DSP Arithmetic Sub-class */
433
    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
434
    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
435
    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
436
    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
437
    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
438
    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
439
    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
440
    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
441
    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
442
    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
443
    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
444
    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
445
    /* MIPS DSP Multiply Sub-class insns */
446
    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
447
    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
448
    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
449
    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
450
};
451

    
452
#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
453
enum {
454
    /* MIPS DSP Arithmetic Sub-class */
455
    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
456
    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
457
    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
458
    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
459
    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
460
    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
461
    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
462
    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
463
    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
464
    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
465
    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
466
    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
467
    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
468
    /* DSP Bit/Manipulation Sub-class */
469
    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
470
    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
471
    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
472
    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
473
    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
474
};
475

    
476
#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
477
enum {
478
    /* MIPS DSP Arithmetic Sub-class */
479
    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
480
    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
481
    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
482
    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
483
    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
484
    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
485
    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
486
    /* DSP Compare-Pick Sub-class */
487
    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
488
    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
489
    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
490
    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
491
    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
492
    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
493
    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
494
    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
495
    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
496
    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
497
    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
498
    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
499
    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
500
    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
501
    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
502
};
503

    
504
#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505
enum {
506
    /* MIPS DSP GPR-Based Shift Sub-class */
507
    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
508
    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
509
    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
510
    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
511
    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
512
    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
513
    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
514
    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
515
    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
516
    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
517
    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
518
    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
519
    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
520
    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
521
    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
522
    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
523
    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
524
    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
525
    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
526
    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
527
    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
528
    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
529
};
530

    
531
#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532
enum {
533
    /* MIPS DSP Multiply Sub-class insns */
534
    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
535
    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
536
    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
537
    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
538
    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
539
    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
540
    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
541
    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
542
    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
543
    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
544
    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
545
    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
546
    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
547
    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
548
    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
549
    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
550
    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
551
    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
552
    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
553
    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
554
    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
555
    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
556
};
557

    
558
#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
559
enum {
560
    /* DSP Bit/Manipulation Sub-class */
561
    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
562
};
563

    
564
#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
565
enum {
566
    /* MIPS DSP Compare-Pick Sub-class */
567
    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
568
    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
569
    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
570
};
571

    
572
#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
573
enum {
574
    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
575
    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
576
    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
577
    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
578
    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
579
    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
580
    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
581
    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
582
    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
583
    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
584
    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
585
    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
586
    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
587
    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
588
    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
589
    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
590
    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
591
    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
592
};
593

    
594

    
595

    
596
#if defined(TARGET_MIPS64)
597
#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
598
enum {
599
    /* MIPS DSP Arithmetic Sub-class */
600
    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
601
    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
602
    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
603
    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
604
    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
605
    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
606
    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
607
    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
608
    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
609
    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
610
    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
611
    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
612
    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
613
    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
614
    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
615
    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
616
    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
617
    /* DSP Bit/Manipulation Sub-class */
618
    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
619
    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
620
    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
621
    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
622
    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
623
    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
624
};
625
#endif
626

    
627
#if defined(TARGET_MIPS64)
628
#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
629
enum {
630
    /* MIPS DSP Multiply Sub-class insns */
631
    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
632
    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
633
    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
634
    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
635
    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
636
    /* MIPS DSP Arithmetic Sub-class */
637
    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
638
    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
639
    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
640
    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
641
    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
642
    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
643
    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
644
    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
645
    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
646
    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
647
    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
648
    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
649
    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
650
    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
651
    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
652
    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
653
    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
654
    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
655
    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
656
    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
657
    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
658
};
659
#endif
660

    
661
#if defined(TARGET_MIPS64)
662
#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663
enum {
664
    /* DSP Compare-Pick Sub-class */
665
    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
666
    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
667
    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
668
    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
669
    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
670
    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
671
    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
672
    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
673
    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
674
    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
675
    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
676
    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
677
    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
678
    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
679
    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
680
    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
681
    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
682
    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
683
    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
684
    /* MIPS DSP Arithmetic Sub-class */
685
    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
686
    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
687
    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
688
    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
689
    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
690
    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
691
    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
692
    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
693
};
694
#endif
695

    
696
#if defined(TARGET_MIPS64)
697
#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
698
enum {
699
    /* DSP Compare-Pick Sub-class */
700
    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
701
    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
702
    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
703
    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
704
};
705
#endif
706

    
707
#if defined(TARGET_MIPS64)
708
#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
709
enum {
710
    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
711
    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
712
    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
713
    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
714
    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
715
    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
716
    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
717
    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
718
    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
719
    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
720
    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
721
    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
722
    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
723
    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
724
    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
725
    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
726
    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
727
    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
728
    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
729
    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
730
    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
731
    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
732
};
733

    
734
#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
735
enum {
736
    /* DSP Bit/Manipulation Sub-class */
737
    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
738
};
739
#endif
740

    
741
#if defined(TARGET_MIPS64)
742
#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
743
enum {
744
    /* MIPS DSP Multiply Sub-class insns */
745
    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
746
    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
747
    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
748
    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
749
    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
750
    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
751
    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
752
    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
753
    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
754
    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
755
    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
756
    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
757
    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
758
    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
759
    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
760
    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
761
    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
762
    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
763
    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
764
    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
765
    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
766
    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
767
    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
768
    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
769
    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
770
    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
771
};
772
#endif
773

    
774
#if defined(TARGET_MIPS64)
775
#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776
enum {
777
    /* MIPS DSP GPR-Based Shift Sub-class */
778
    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
779
    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
780
    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
781
    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
782
    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
783
    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
784
    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
785
    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
786
    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
787
    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
788
    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
789
    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
790
    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
791
    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
792
    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
793
    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
794
    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
795
    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
796
    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
797
    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
798
    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
799
    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
800
    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
801
    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
802
    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
803
    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
804
};
805
#endif
806

    
807
/* Coprocessor 0 (rs field) */
808
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
809

    
810
enum {
811
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
812
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
813
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
814
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
815
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
816
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
817
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
818
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
819
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
820
    OPC_C0       = (0x10 << 21) | OPC_CP0,
821
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
822
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
823
};
824

    
825
/* MFMC0 opcodes */
826
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
827

    
828
enum {
829
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
830
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
831
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
832
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
833
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
834
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
835
};
836

    
837
/* Coprocessor 0 (with rs == C0) */
838
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
839

    
840
enum {
841
    OPC_TLBR     = 0x01 | OPC_C0,
842
    OPC_TLBWI    = 0x02 | OPC_C0,
843
    OPC_TLBWR    = 0x06 | OPC_C0,
844
    OPC_TLBP     = 0x08 | OPC_C0,
845
    OPC_RFE      = 0x10 | OPC_C0,
846
    OPC_ERET     = 0x18 | OPC_C0,
847
    OPC_DERET    = 0x1F | OPC_C0,
848
    OPC_WAIT     = 0x20 | OPC_C0,
849
};
850

    
851
/* Coprocessor 1 (rs field) */
852
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
853

    
854
/* Values for the fmt field in FP instructions */
855
enum {
856
    /* 0 - 15 are reserved */
857
    FMT_S = 16,          /* single fp */
858
    FMT_D = 17,          /* double fp */
859
    FMT_E = 18,          /* extended fp */
860
    FMT_Q = 19,          /* quad fp */
861
    FMT_W = 20,          /* 32-bit fixed */
862
    FMT_L = 21,          /* 64-bit fixed */
863
    FMT_PS = 22,         /* paired single fp */
864
    /* 23 - 31 are reserved */
865
};
866

    
867
enum {
868
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
869
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
870
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
871
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
872
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
873
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
874
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
875
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
876
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
877
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
878
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
879
    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
880
    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
881
    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
882
    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
883
    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
884
    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
885
    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
886
};
887

    
888
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
889
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
890

    
891
enum {
892
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
893
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
894
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
895
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
896
};
897

    
898
enum {
899
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
900
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
901
};
902

    
903
enum {
904
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
905
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
906
};
907

    
908
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
909

    
910
enum {
911
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
912
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
913
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
914
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
915
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
916
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
917
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
918
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
919
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
920
};
921

    
922
#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
923

    
924
enum {
925
    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
926
    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
927
    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
928
    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
929
    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
930
    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
931
    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
932
    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
933

    
934
    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
935
    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
936
    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
937
    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
938
    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
939
    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
940
    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
941
    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
942

    
943
    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
944
    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
945
    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
946
    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
947
    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
948
    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
949
    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
950
    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
951

    
952
    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
953
    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
954
    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
955
    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
956
    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
957
    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
958
    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
959
    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
960

    
961
    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
962
    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
963
    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
964
    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
965
    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
966
    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
967

    
968
    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
969
    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
970
    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
971
    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
972
    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
973
    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
974

    
975
    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
976
    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
977
    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
978
    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
979
    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
980
    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
981

    
982
    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
983
    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
984
    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
985
    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
986
    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
987
    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
988

    
989
    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
990
    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
991
    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
992
    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
993
    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
994
    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
995

    
996
    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
997
    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
998
    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
999
    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1000
    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1001
    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1002

    
1003
    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1004
    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1005
    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1006
    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1007
    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1008
    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1009

    
1010
    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1011
    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1012
    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1013
    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1014
    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1015
    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1016
};
1017

    
1018

    
1019
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1020

    
1021
enum {
1022
    OPC_LWXC1   = 0x00 | OPC_CP3,
1023
    OPC_LDXC1   = 0x01 | OPC_CP3,
1024
    OPC_LUXC1   = 0x05 | OPC_CP3,
1025
    OPC_SWXC1   = 0x08 | OPC_CP3,
1026
    OPC_SDXC1   = 0x09 | OPC_CP3,
1027
    OPC_SUXC1   = 0x0D | OPC_CP3,
1028
    OPC_PREFX   = 0x0F | OPC_CP3,
1029
    OPC_ALNV_PS = 0x1E | OPC_CP3,
1030
    OPC_MADD_S  = 0x20 | OPC_CP3,
1031
    OPC_MADD_D  = 0x21 | OPC_CP3,
1032
    OPC_MADD_PS = 0x26 | OPC_CP3,
1033
    OPC_MSUB_S  = 0x28 | OPC_CP3,
1034
    OPC_MSUB_D  = 0x29 | OPC_CP3,
1035
    OPC_MSUB_PS = 0x2E | OPC_CP3,
1036
    OPC_NMADD_S = 0x30 | OPC_CP3,
1037
    OPC_NMADD_D = 0x31 | OPC_CP3,
1038
    OPC_NMADD_PS= 0x36 | OPC_CP3,
1039
    OPC_NMSUB_S = 0x38 | OPC_CP3,
1040
    OPC_NMSUB_D = 0x39 | OPC_CP3,
1041
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1042
};
1043

    
1044
/* global register indices */
1045
static TCGv_ptr cpu_env;
1046
static TCGv cpu_gpr[32], cpu_PC;
1047
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1048
static TCGv cpu_dspctrl, btarget, bcond;
1049
static TCGv_i32 hflags;
1050
static TCGv_i32 fpu_fcr0, fpu_fcr31;
1051
static TCGv_i64 fpu_f64[32];
1052

    
1053
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1054

    
1055
#include "gen-icount.h"
1056

    
1057
#define gen_helper_0e0i(name, arg) do {                           \
1058
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1059
    gen_helper_##name(cpu_env, helper_tmp);                       \
1060
    tcg_temp_free_i32(helper_tmp);                                \
1061
    } while(0)
1062

    
1063
#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1064
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1065
    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1066
    tcg_temp_free_i32(helper_tmp);                                \
1067
    } while(0)
1068

    
1069
#define gen_helper_1e0i(name, ret, arg1) do {                     \
1070
    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1071
    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1072
    tcg_temp_free_i32(helper_tmp);                                \
1073
    } while(0)
1074

    
1075
#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1076
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1077
    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1078
    tcg_temp_free_i32(helper_tmp);                                \
1079
    } while(0)
1080

    
1081
#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1082
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1083
    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1084
    tcg_temp_free_i32(helper_tmp);                                \
1085
    } while(0)
1086

    
1087
#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1088
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1089
    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1090
    tcg_temp_free_i32(helper_tmp);                                \
1091
    } while(0)
1092

    
1093
#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1094
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1095
    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1096
    tcg_temp_free_i32(helper_tmp);                                \
1097
    } while(0)
1098

    
1099
typedef struct DisasContext {
1100
    struct TranslationBlock *tb;
1101
    target_ulong pc, saved_pc;
1102
    uint32_t opcode;
1103
    int singlestep_enabled;
1104
    /* Routine used to access memory */
1105
    int mem_idx;
1106
    uint32_t hflags, saved_hflags;
1107
    int bstate;
1108
    target_ulong btarget;
1109
} DisasContext;
1110

    
1111
enum {
1112
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1113
                      * exception condition */
1114
    BS_STOP     = 1, /* We want to stop translation for any reason */
1115
    BS_BRANCH   = 2, /* We reached a branch condition     */
1116
    BS_EXCP     = 3, /* We reached an exception condition */
1117
};
1118

    
1119
static const char * const regnames[] = {
1120
    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1121
    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1122
    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1123
    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1124
};
1125

    
1126
static const char * const regnames_HI[] = {
1127
    "HI0", "HI1", "HI2", "HI3",
1128
};
1129

    
1130
static const char * const regnames_LO[] = {
1131
    "LO0", "LO1", "LO2", "LO3",
1132
};
1133

    
1134
static const char * const regnames_ACX[] = {
1135
    "ACX0", "ACX1", "ACX2", "ACX3",
1136
};
1137

    
1138
static const char * const fregnames[] = {
1139
    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1140
    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1141
    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1142
    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1143
};
1144

    
1145
#define MIPS_DEBUG(fmt, ...)                                                  \
1146
    do {                                                                      \
1147
        if (MIPS_DEBUG_DISAS) {                                               \
1148
            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1149
                          TARGET_FMT_lx ": %08x " fmt "\n",                   \
1150
                          ctx->pc, ctx->opcode , ## __VA_ARGS__);             \
1151
        }                                                                     \
1152
    } while (0)
1153

    
1154
#define LOG_DISAS(...)                                                        \
1155
    do {                                                                      \
1156
        if (MIPS_DEBUG_DISAS) {                                               \
1157
            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1158
        }                                                                     \
1159
    } while (0)
1160

    
1161
#define MIPS_INVAL(op)                                                        \
1162
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
1163
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1164

    
1165
/* General purpose registers moves. */
1166
static inline void gen_load_gpr (TCGv t, int reg)
1167
{
1168
    if (reg == 0)
1169
        tcg_gen_movi_tl(t, 0);
1170
    else
1171
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1172
}
1173

    
1174
static inline void gen_store_gpr (TCGv t, int reg)
1175
{
1176
    if (reg != 0)
1177
        tcg_gen_mov_tl(cpu_gpr[reg], t);
1178
}
1179

    
1180
/* Moves to/from ACX register.  */
1181
static inline void gen_load_ACX (TCGv t, int reg)
1182
{
1183
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
1184
}
1185

    
1186
static inline void gen_store_ACX (TCGv t, int reg)
1187
{
1188
    tcg_gen_mov_tl(cpu_ACX[reg], t);
1189
}
1190

    
1191
/* Moves to/from shadow registers. */
1192
static inline void gen_load_srsgpr (int from, int to)
1193
{
1194
    TCGv t0 = tcg_temp_new();
1195

    
1196
    if (from == 0)
1197
        tcg_gen_movi_tl(t0, 0);
1198
    else {
1199
        TCGv_i32 t2 = tcg_temp_new_i32();
1200
        TCGv_ptr addr = tcg_temp_new_ptr();
1201

    
1202
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1203
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1204
        tcg_gen_andi_i32(t2, t2, 0xf);
1205
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1206
        tcg_gen_ext_i32_ptr(addr, t2);
1207
        tcg_gen_add_ptr(addr, cpu_env, addr);
1208

    
1209
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1210
        tcg_temp_free_ptr(addr);
1211
        tcg_temp_free_i32(t2);
1212
    }
1213
    gen_store_gpr(t0, to);
1214
    tcg_temp_free(t0);
1215
}
1216

    
1217
static inline void gen_store_srsgpr (int from, int to)
1218
{
1219
    if (to != 0) {
1220
        TCGv t0 = tcg_temp_new();
1221
        TCGv_i32 t2 = tcg_temp_new_i32();
1222
        TCGv_ptr addr = tcg_temp_new_ptr();
1223

    
1224
        gen_load_gpr(t0, from);
1225
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1226
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1227
        tcg_gen_andi_i32(t2, t2, 0xf);
1228
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1229
        tcg_gen_ext_i32_ptr(addr, t2);
1230
        tcg_gen_add_ptr(addr, cpu_env, addr);
1231

    
1232
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1233
        tcg_temp_free_ptr(addr);
1234
        tcg_temp_free_i32(t2);
1235
        tcg_temp_free(t0);
1236
    }
1237
}
1238

    
1239
/* Floating point register moves. */
1240
static void gen_load_fpr32(TCGv_i32 t, int reg)
1241
{
1242
    tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1243
}
1244

    
1245
static void gen_store_fpr32(TCGv_i32 t, int reg)
1246
{
1247
    TCGv_i64 t64 = tcg_temp_new_i64();
1248
    tcg_gen_extu_i32_i64(t64, t);
1249
    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1250
    tcg_temp_free_i64(t64);
1251
}
1252

    
1253
static void gen_load_fpr32h(TCGv_i32 t, int reg)
1254
{
1255
    TCGv_i64 t64 = tcg_temp_new_i64();
1256
    tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1257
    tcg_gen_trunc_i64_i32(t, t64);
1258
    tcg_temp_free_i64(t64);
1259
}
1260

    
1261
static void gen_store_fpr32h(TCGv_i32 t, int reg)
1262
{
1263
    TCGv_i64 t64 = tcg_temp_new_i64();
1264
    tcg_gen_extu_i32_i64(t64, t);
1265
    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1266
    tcg_temp_free_i64(t64);
1267
}
1268

    
1269
static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1270
{
1271
    if (ctx->hflags & MIPS_HFLAG_F64) {
1272
        tcg_gen_mov_i64(t, fpu_f64[reg]);
1273
    } else {
1274
        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1275
    }
1276
}
1277

    
1278
static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1279
{
1280
    if (ctx->hflags & MIPS_HFLAG_F64) {
1281
        tcg_gen_mov_i64(fpu_f64[reg], t);
1282
    } else {
1283
        TCGv_i64 t0;
1284
        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1285
        t0 = tcg_temp_new_i64();
1286
        tcg_gen_shri_i64(t0, t, 32);
1287
        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1288
        tcg_temp_free_i64(t0);
1289
    }
1290
}
1291

    
1292
static inline int get_fp_bit (int cc)
1293
{
1294
    if (cc)
1295
        return 24 + cc;
1296
    else
1297
        return 23;
1298
}
1299

    
1300
/* Tests */
1301
static inline void gen_save_pc(target_ulong pc)
1302
{
1303
    tcg_gen_movi_tl(cpu_PC, pc);
1304
}
1305

    
1306
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1307
{
1308
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1309
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1310
        gen_save_pc(ctx->pc);
1311
        ctx->saved_pc = ctx->pc;
1312
    }
1313
    if (ctx->hflags != ctx->saved_hflags) {
1314
        tcg_gen_movi_i32(hflags, ctx->hflags);
1315
        ctx->saved_hflags = ctx->hflags;
1316
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1317
        case MIPS_HFLAG_BR:
1318
            break;
1319
        case MIPS_HFLAG_BC:
1320
        case MIPS_HFLAG_BL:
1321
        case MIPS_HFLAG_B:
1322
            tcg_gen_movi_tl(btarget, ctx->btarget);
1323
            break;
1324
        }
1325
    }
1326
}
1327

    
1328
static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1329
{
1330
    ctx->saved_hflags = ctx->hflags;
1331
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1332
    case MIPS_HFLAG_BR:
1333
        break;
1334
    case MIPS_HFLAG_BC:
1335
    case MIPS_HFLAG_BL:
1336
    case MIPS_HFLAG_B:
1337
        ctx->btarget = env->btarget;
1338
        break;
1339
    }
1340
}
1341

    
1342
static inline void
1343
generate_exception_err (DisasContext *ctx, int excp, int err)
1344
{
1345
    TCGv_i32 texcp = tcg_const_i32(excp);
1346
    TCGv_i32 terr = tcg_const_i32(err);
1347
    save_cpu_state(ctx, 1);
1348
    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1349
    tcg_temp_free_i32(terr);
1350
    tcg_temp_free_i32(texcp);
1351
}
1352

    
1353
static inline void
1354
generate_exception (DisasContext *ctx, int excp)
1355
{
1356
    save_cpu_state(ctx, 1);
1357
    gen_helper_0e0i(raise_exception, excp);
1358
}
1359

    
1360
/* Addresses computation */
1361
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1362
{
1363
    tcg_gen_add_tl(ret, arg0, arg1);
1364

    
1365
#if defined(TARGET_MIPS64)
1366
    /* For compatibility with 32-bit code, data reference in user mode
1367
       with Status_UX = 0 should be casted to 32-bit and sign extended.
1368
       See the MIPS64 PRA manual, section 4.10. */
1369
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1370
        !(ctx->hflags & MIPS_HFLAG_UX)) {
1371
        tcg_gen_ext32s_i64(ret, ret);
1372
    }
1373
#endif
1374
}
1375

    
1376
static inline void check_cp0_enabled(DisasContext *ctx)
1377
{
1378
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1379
        generate_exception_err(ctx, EXCP_CpU, 0);
1380
}
1381

    
1382
static inline void check_cp1_enabled(DisasContext *ctx)
1383
{
1384
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1385
        generate_exception_err(ctx, EXCP_CpU, 1);
1386
}
1387

    
1388
/* Verify that the processor is running with COP1X instructions enabled.
1389
   This is associated with the nabla symbol in the MIPS32 and MIPS64
1390
   opcode tables.  */
1391

    
1392
static inline void check_cop1x(DisasContext *ctx)
1393
{
1394
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1395
        generate_exception(ctx, EXCP_RI);
1396
}
1397

    
1398
/* Verify that the processor is running with 64-bit floating-point
1399
   operations enabled.  */
1400

    
1401
static inline void check_cp1_64bitmode(DisasContext *ctx)
1402
{
1403
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1404
        generate_exception(ctx, EXCP_RI);
1405
}
1406

    
1407
/*
1408
 * Verify if floating point register is valid; an operation is not defined
1409
 * if bit 0 of any register specification is set and the FR bit in the
1410
 * Status register equals zero, since the register numbers specify an
1411
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1412
 * in the Status register equals one, both even and odd register numbers
1413
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1414
 *
1415
 * Multiple 64 bit wide registers can be checked by calling
1416
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1417
 */
1418
static inline void check_cp1_registers(DisasContext *ctx, int regs)
1419
{
1420
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1421
        generate_exception(ctx, EXCP_RI);
1422
}
1423

    
1424
/* Verify that the processor is running with DSP instructions enabled.
1425
   This is enabled by CP0 Status register MX(24) bit.
1426
 */
1427

    
1428
static inline void check_dsp(DisasContext *ctx)
1429
{
1430
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1431
        generate_exception(ctx, EXCP_DSPDIS);
1432
    }
1433
}
1434

    
1435
static inline void check_dspr2(DisasContext *ctx)
1436
{
1437
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1438
        generate_exception(ctx, EXCP_DSPDIS);
1439
    }
1440
}
1441

    
1442
/* This code generates a "reserved instruction" exception if the
1443
   CPU does not support the instruction set corresponding to flags. */
1444
static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1445
{
1446
    if (unlikely(!(env->insn_flags & flags)))
1447
        generate_exception(ctx, EXCP_RI);
1448
}
1449

    
1450
/* This code generates a "reserved instruction" exception if 64-bit
1451
   instructions are not enabled. */
1452
static inline void check_mips_64(DisasContext *ctx)
1453
{
1454
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1455
        generate_exception(ctx, EXCP_RI);
1456
}
1457

    
1458
/* Define small wrappers for gen_load_fpr* so that we have a uniform
1459
   calling interface for 32 and 64-bit FPRs.  No sense in changing
1460
   all callers for gen_load_fpr32 when we need the CTX parameter for
1461
   this one use.  */
1462
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1463
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1464
#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1465
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1466
                                               int ft, int fs, int cc)        \
1467
{                                                                             \
1468
    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1469
    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1470
    switch (ifmt) {                                                           \
1471
    case FMT_PS:                                                              \
1472
        check_cp1_64bitmode(ctx);                                             \
1473
        break;                                                                \
1474
    case FMT_D:                                                               \
1475
        if (abs) {                                                            \
1476
            check_cop1x(ctx);                                                 \
1477
        }                                                                     \
1478
        check_cp1_registers(ctx, fs | ft);                                    \
1479
        break;                                                                \
1480
    case FMT_S:                                                               \
1481
        if (abs) {                                                            \
1482
            check_cop1x(ctx);                                                 \
1483
        }                                                                     \
1484
        break;                                                                \
1485
    }                                                                         \
1486
    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1487
    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1488
    switch (n) {                                                              \
1489
    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1490
    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1491
    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1492
    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1493
    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1494
    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1495
    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1496
    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1497
    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1498
    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1499
    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1500
    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1501
    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1502
    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1503
    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1504
    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1505
    default: abort();                                                         \
1506
    }                                                                         \
1507
    tcg_temp_free_i##bits (fp0);                                              \
1508
    tcg_temp_free_i##bits (fp1);                                              \
1509
}
1510

    
1511
FOP_CONDS(, 0, d, FMT_D, 64)
1512
FOP_CONDS(abs, 1, d, FMT_D, 64)
1513
FOP_CONDS(, 0, s, FMT_S, 32)
1514
FOP_CONDS(abs, 1, s, FMT_S, 32)
1515
FOP_CONDS(, 0, ps, FMT_PS, 64)
1516
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1517
#undef FOP_CONDS
1518
#undef gen_ldcmp_fpr32
1519
#undef gen_ldcmp_fpr64
1520

    
1521
/* load/store instructions. */
1522
#define OP_LD(insn,fname)                                                 \
1523
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
1524
{                                                                         \
1525
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
1526
}
1527
OP_LD(lb,ld8s);
1528
OP_LD(lbu,ld8u);
1529
OP_LD(lh,ld16s);
1530
OP_LD(lhu,ld16u);
1531
OP_LD(lw,ld32s);
1532
#if defined(TARGET_MIPS64)
1533
OP_LD(lwu,ld32u);
1534
OP_LD(ld,ld64);
1535
#endif
1536
#undef OP_LD
1537

    
1538
#define OP_ST(insn,fname)                                                  \
1539
static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
1540
{                                                                          \
1541
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
1542
}
1543
OP_ST(sb,st8);
1544
OP_ST(sh,st16);
1545
OP_ST(sw,st32);
1546
#if defined(TARGET_MIPS64)
1547
OP_ST(sd,st64);
1548
#endif
1549
#undef OP_ST
1550

    
1551
#ifdef CONFIG_USER_ONLY
1552
#define OP_LD_ATOMIC(insn,fname)                                           \
1553
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1554
{                                                                          \
1555
    TCGv t0 = tcg_temp_new();                                              \
1556
    tcg_gen_mov_tl(t0, arg1);                                              \
1557
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1558
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
1559
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
1560
    tcg_temp_free(t0);                                                     \
1561
}
1562
#else
1563
#define OP_LD_ATOMIC(insn,fname)                                           \
1564
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1565
{                                                                          \
1566
    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
1567
}
1568
#endif
1569
OP_LD_ATOMIC(ll,ld32s);
1570
#if defined(TARGET_MIPS64)
1571
OP_LD_ATOMIC(lld,ld64);
1572
#endif
1573
#undef OP_LD_ATOMIC
1574

    
1575
#ifdef CONFIG_USER_ONLY
1576
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1577
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1578
{                                                                            \
1579
    TCGv t0 = tcg_temp_new();                                                \
1580
    int l1 = gen_new_label();                                                \
1581
    int l2 = gen_new_label();                                                \
1582
                                                                             \
1583
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
1584
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
1585
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
1586
    generate_exception(ctx, EXCP_AdES);                                      \
1587
    gen_set_label(l1);                                                       \
1588
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
1589
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
1590
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
1591
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
1592
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
1593
    gen_helper_0e0i(raise_exception, EXCP_SC);                               \
1594
    gen_set_label(l2);                                                       \
1595
    tcg_gen_movi_tl(t0, 0);                                                  \
1596
    gen_store_gpr(t0, rt);                                                   \
1597
    tcg_temp_free(t0);                                                       \
1598
}
1599
#else
1600
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1601
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1602
{                                                                            \
1603
    TCGv t0 = tcg_temp_new();                                                \
1604
    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
1605
    gen_store_gpr(t0, rt);                                                   \
1606
    tcg_temp_free(t0);                                                       \
1607
}
1608
#endif
1609
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1610
#if defined(TARGET_MIPS64)
1611
OP_ST_ATOMIC(scd,st64,ld64,0x7);
1612
#endif
1613
#undef OP_ST_ATOMIC
1614

    
1615
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1616
                                  int base, int16_t offset)
1617
{
1618
    if (base == 0) {
1619
        tcg_gen_movi_tl(addr, offset);
1620
    } else if (offset == 0) {
1621
        gen_load_gpr(addr, base);
1622
    } else {
1623
        tcg_gen_movi_tl(addr, offset);
1624
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1625
    }
1626
}
1627

    
1628
static target_ulong pc_relative_pc (DisasContext *ctx)
1629
{
1630
    target_ulong pc = ctx->pc;
1631

    
1632
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1633
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1634

    
1635
        pc -= branch_bytes;
1636
    }
1637

    
1638
    pc &= ~(target_ulong)3;
1639
    return pc;
1640
}
1641

    
1642
/* Load */
1643
static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1644
                    int rt, int base, int16_t offset)
1645
{
1646
    const char *opn = "ld";
1647
    TCGv t0, t1;
1648

    
1649
    if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1650
        /* Loongson CPU uses a load to zero register for prefetch.
1651
           We emulate it as a NOP. On other CPU we must perform the
1652
           actual memory access. */
1653
        MIPS_DEBUG("NOP");
1654
        return;
1655
    }
1656

    
1657
    t0 = tcg_temp_new();
1658
    t1 = tcg_temp_new();
1659
    gen_base_offset_addr(ctx, t0, base, offset);
1660

    
1661
    switch (opc) {
1662
#if defined(TARGET_MIPS64)
1663
    case OPC_LWU:
1664
        save_cpu_state(ctx, 0);
1665
        op_ld_lwu(t0, t0, ctx);
1666
        gen_store_gpr(t0, rt);
1667
        opn = "lwu";
1668
        break;
1669
    case OPC_LD:
1670
        save_cpu_state(ctx, 0);
1671
        op_ld_ld(t0, t0, ctx);
1672
        gen_store_gpr(t0, rt);
1673
        opn = "ld";
1674
        break;
1675
    case OPC_LLD:
1676
        save_cpu_state(ctx, 1);
1677
        op_ld_lld(t0, t0, ctx);
1678
        gen_store_gpr(t0, rt);
1679
        opn = "lld";
1680
        break;
1681
    case OPC_LDL:
1682
        save_cpu_state(ctx, 1);
1683
        gen_load_gpr(t1, rt);
1684
        gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1685
        gen_store_gpr(t1, rt);
1686
        opn = "ldl";
1687
        break;
1688
    case OPC_LDR:
1689
        save_cpu_state(ctx, 1);
1690
        gen_load_gpr(t1, rt);
1691
        gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1692
        gen_store_gpr(t1, rt);
1693
        opn = "ldr";
1694
        break;
1695
    case OPC_LDPC:
1696
        save_cpu_state(ctx, 0);
1697
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1698
        gen_op_addr_add(ctx, t0, t0, t1);
1699
        op_ld_ld(t0, t0, ctx);
1700
        gen_store_gpr(t0, rt);
1701
        opn = "ldpc";
1702
        break;
1703
#endif
1704
    case OPC_LWPC:
1705
        save_cpu_state(ctx, 0);
1706
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1707
        gen_op_addr_add(ctx, t0, t0, t1);
1708
        op_ld_lw(t0, t0, ctx);
1709
        gen_store_gpr(t0, rt);
1710
        opn = "lwpc";
1711
        break;
1712
    case OPC_LW:
1713
        save_cpu_state(ctx, 0);
1714
        op_ld_lw(t0, t0, ctx);
1715
        gen_store_gpr(t0, rt);
1716
        opn = "lw";
1717
        break;
1718
    case OPC_LH:
1719
        save_cpu_state(ctx, 0);
1720
        op_ld_lh(t0, t0, ctx);
1721
        gen_store_gpr(t0, rt);
1722
        opn = "lh";
1723
        break;
1724
    case OPC_LHU:
1725
        save_cpu_state(ctx, 0);
1726
        op_ld_lhu(t0, t0, ctx);
1727
        gen_store_gpr(t0, rt);
1728
        opn = "lhu";
1729
        break;
1730
    case OPC_LB:
1731
        save_cpu_state(ctx, 0);
1732
        op_ld_lb(t0, t0, ctx);
1733
        gen_store_gpr(t0, rt);
1734
        opn = "lb";
1735
        break;
1736
    case OPC_LBU:
1737
        save_cpu_state(ctx, 0);
1738
        op_ld_lbu(t0, t0, ctx);
1739
        gen_store_gpr(t0, rt);
1740
        opn = "lbu";
1741
        break;
1742
    case OPC_LWL:
1743
        save_cpu_state(ctx, 1);
1744
        gen_load_gpr(t1, rt);
1745
        gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1746
        gen_store_gpr(t1, rt);
1747
        opn = "lwl";
1748
        break;
1749
    case OPC_LWR:
1750
        save_cpu_state(ctx, 1);
1751
        gen_load_gpr(t1, rt);
1752
        gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1753
        gen_store_gpr(t1, rt);
1754
        opn = "lwr";
1755
        break;
1756
    case OPC_LL:
1757
        save_cpu_state(ctx, 1);
1758
        op_ld_ll(t0, t0, ctx);
1759
        gen_store_gpr(t0, rt);
1760
        opn = "ll";
1761
        break;
1762
    }
1763
    (void)opn; /* avoid a compiler warning */
1764
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1765
    tcg_temp_free(t0);
1766
    tcg_temp_free(t1);
1767
}
1768

    
1769
/* Store */
1770
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1771
                    int base, int16_t offset)
1772
{
1773
    const char *opn = "st";
1774
    TCGv t0 = tcg_temp_new();
1775
    TCGv t1 = tcg_temp_new();
1776

    
1777
    gen_base_offset_addr(ctx, t0, base, offset);
1778
    gen_load_gpr(t1, rt);
1779
    switch (opc) {
1780
#if defined(TARGET_MIPS64)
1781
    case OPC_SD:
1782
        save_cpu_state(ctx, 0);
1783
        op_st_sd(t1, t0, ctx);
1784
        opn = "sd";
1785
        break;
1786
    case OPC_SDL:
1787
        save_cpu_state(ctx, 1);
1788
        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1789
        opn = "sdl";
1790
        break;
1791
    case OPC_SDR:
1792
        save_cpu_state(ctx, 1);
1793
        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1794
        opn = "sdr";
1795
        break;
1796
#endif
1797
    case OPC_SW:
1798
        save_cpu_state(ctx, 0);
1799
        op_st_sw(t1, t0, ctx);
1800
        opn = "sw";
1801
        break;
1802
    case OPC_SH:
1803
        save_cpu_state(ctx, 0);
1804
        op_st_sh(t1, t0, ctx);
1805
        opn = "sh";
1806
        break;
1807
    case OPC_SB:
1808
        save_cpu_state(ctx, 0);
1809
        op_st_sb(t1, t0, ctx);
1810
        opn = "sb";
1811
        break;
1812
    case OPC_SWL:
1813
        save_cpu_state(ctx, 1);
1814
        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1815
        opn = "swl";
1816
        break;
1817
    case OPC_SWR:
1818
        save_cpu_state(ctx, 1);
1819
        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1820
        opn = "swr";
1821
        break;
1822
    }
1823
    (void)opn; /* avoid a compiler warning */
1824
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1825
    tcg_temp_free(t0);
1826
    tcg_temp_free(t1);
1827
}
1828

    
1829

    
1830
/* Store conditional */
1831
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1832
                         int base, int16_t offset)
1833
{
1834
    const char *opn = "st_cond";
1835
    TCGv t0, t1;
1836

    
1837
    t0 = tcg_temp_local_new();
1838

    
1839
    gen_base_offset_addr(ctx, t0, base, offset);
1840
    /* Don't do NOP if destination is zero: we must perform the actual
1841
       memory access. */
1842

    
1843
    t1 = tcg_temp_local_new();
1844
    gen_load_gpr(t1, rt);
1845
    switch (opc) {
1846
#if defined(TARGET_MIPS64)
1847
    case OPC_SCD:
1848
        save_cpu_state(ctx, 1);
1849
        op_st_scd(t1, t0, rt, ctx);
1850
        opn = "scd";
1851
        break;
1852
#endif
1853
    case OPC_SC:
1854
        save_cpu_state(ctx, 1);
1855
        op_st_sc(t1, t0, rt, ctx);
1856
        opn = "sc";
1857
        break;
1858
    }
1859
    (void)opn; /* avoid a compiler warning */
1860
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1861
    tcg_temp_free(t1);
1862
    tcg_temp_free(t0);
1863
}
1864

    
1865
/* Load and store */
1866
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1867
                          int base, int16_t offset)
1868
{
1869
    const char *opn = "flt_ldst";
1870
    TCGv t0 = tcg_temp_new();
1871

    
1872
    gen_base_offset_addr(ctx, t0, base, offset);
1873
    /* Don't do NOP if destination is zero: we must perform the actual
1874
       memory access. */
1875
    switch (opc) {
1876
    case OPC_LWC1:
1877
        {
1878
            TCGv_i32 fp0 = tcg_temp_new_i32();
1879

    
1880
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1881
            tcg_gen_trunc_tl_i32(fp0, t0);
1882
            gen_store_fpr32(fp0, ft);
1883
            tcg_temp_free_i32(fp0);
1884
        }
1885
        opn = "lwc1";
1886
        break;
1887
    case OPC_SWC1:
1888
        {
1889
            TCGv_i32 fp0 = tcg_temp_new_i32();
1890
            TCGv t1 = tcg_temp_new();
1891

    
1892
            gen_load_fpr32(fp0, ft);
1893
            tcg_gen_extu_i32_tl(t1, fp0);
1894
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1895
            tcg_temp_free(t1);
1896
            tcg_temp_free_i32(fp0);
1897
        }
1898
        opn = "swc1";
1899
        break;
1900
    case OPC_LDC1:
1901
        {
1902
            TCGv_i64 fp0 = tcg_temp_new_i64();
1903

    
1904
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1905
            gen_store_fpr64(ctx, fp0, ft);
1906
            tcg_temp_free_i64(fp0);
1907
        }
1908
        opn = "ldc1";
1909
        break;
1910
    case OPC_SDC1:
1911
        {
1912
            TCGv_i64 fp0 = tcg_temp_new_i64();
1913

    
1914
            gen_load_fpr64(ctx, fp0, ft);
1915
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1916
            tcg_temp_free_i64(fp0);
1917
        }
1918
        opn = "sdc1";
1919
        break;
1920
    default:
1921
        MIPS_INVAL(opn);
1922
        generate_exception(ctx, EXCP_RI);
1923
        goto out;
1924
    }
1925
    (void)opn; /* avoid a compiler warning */
1926
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1927
 out:
1928
    tcg_temp_free(t0);
1929
}
1930

    
1931
static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1932
                          uint32_t op, int rt, int rs, int16_t imm)
1933
{
1934
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1935
        check_cp1_enabled(ctx);
1936
        gen_flt_ldst(ctx, op, rt, rs, imm);
1937
    } else {
1938
        generate_exception_err(ctx, EXCP_CpU, 1);
1939
    }
1940
}
1941

    
1942
/* Arithmetic with immediate operand */
1943
static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1944
                           int rt, int rs, int16_t imm)
1945
{
1946
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1947
    const char *opn = "imm arith";
1948

    
1949
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1950
        /* If no destination, treat it as a NOP.
1951
           For addi, we must generate the overflow exception when needed. */
1952
        MIPS_DEBUG("NOP");
1953
        return;
1954
    }
1955
    switch (opc) {
1956
    case OPC_ADDI:
1957
        {
1958
            TCGv t0 = tcg_temp_local_new();
1959
            TCGv t1 = tcg_temp_new();
1960
            TCGv t2 = tcg_temp_new();
1961
            int l1 = gen_new_label();
1962

    
1963
            gen_load_gpr(t1, rs);
1964
            tcg_gen_addi_tl(t0, t1, uimm);
1965
            tcg_gen_ext32s_tl(t0, t0);
1966

    
1967
            tcg_gen_xori_tl(t1, t1, ~uimm);
1968
            tcg_gen_xori_tl(t2, t0, uimm);
1969
            tcg_gen_and_tl(t1, t1, t2);
1970
            tcg_temp_free(t2);
1971
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1972
            tcg_temp_free(t1);
1973
            /* operands of same sign, result different sign */
1974
            generate_exception(ctx, EXCP_OVERFLOW);
1975
            gen_set_label(l1);
1976
            tcg_gen_ext32s_tl(t0, t0);
1977
            gen_store_gpr(t0, rt);
1978
            tcg_temp_free(t0);
1979
        }
1980
        opn = "addi";
1981
        break;
1982
    case OPC_ADDIU:
1983
        if (rs != 0) {
1984
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1985
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1986
        } else {
1987
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1988
        }
1989
        opn = "addiu";
1990
        break;
1991
#if defined(TARGET_MIPS64)
1992
    case OPC_DADDI:
1993
        {
1994
            TCGv t0 = tcg_temp_local_new();
1995
            TCGv t1 = tcg_temp_new();
1996
            TCGv t2 = tcg_temp_new();
1997
            int l1 = gen_new_label();
1998

    
1999
            gen_load_gpr(t1, rs);
2000
            tcg_gen_addi_tl(t0, t1, uimm);
2001

    
2002
            tcg_gen_xori_tl(t1, t1, ~uimm);
2003
            tcg_gen_xori_tl(t2, t0, uimm);
2004
            tcg_gen_and_tl(t1, t1, t2);
2005
            tcg_temp_free(t2);
2006
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2007
            tcg_temp_free(t1);
2008
            /* operands of same sign, result different sign */
2009
            generate_exception(ctx, EXCP_OVERFLOW);
2010
            gen_set_label(l1);
2011
            gen_store_gpr(t0, rt);
2012
            tcg_temp_free(t0);
2013
        }
2014
        opn = "daddi";
2015
        break;
2016
    case OPC_DADDIU:
2017
        if (rs != 0) {
2018
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2019
        } else {
2020
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2021
        }
2022
        opn = "daddiu";
2023
        break;
2024
#endif
2025
    }
2026
    (void)opn; /* avoid a compiler warning */
2027
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2028
}
2029

    
2030
/* Logic with immediate operand */
2031
static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2032
                          int rt, int rs, int16_t imm)
2033
{
2034
    target_ulong uimm;
2035
    const char *opn = "imm logic";
2036

    
2037
    if (rt == 0) {
2038
        /* If no destination, treat it as a NOP. */
2039
        MIPS_DEBUG("NOP");
2040
        return;
2041
    }
2042
    uimm = (uint16_t)imm;
2043
    switch (opc) {
2044
    case OPC_ANDI:
2045
        if (likely(rs != 0))
2046
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2047
        else
2048
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2049
        opn = "andi";
2050
        break;
2051
    case OPC_ORI:
2052
        if (rs != 0)
2053
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054
        else
2055
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2056
        opn = "ori";
2057
        break;
2058
    case OPC_XORI:
2059
        if (likely(rs != 0))
2060
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2061
        else
2062
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2063
        opn = "xori";
2064
        break;
2065
    case OPC_LUI:
2066
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2067
        opn = "lui";
2068
        break;
2069
    }
2070
    (void)opn; /* avoid a compiler warning */
2071
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2072
}
2073

    
2074
/* Set on less than with immediate operand */
2075
static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2076
                        int rt, int rs, int16_t imm)
2077
{
2078
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2079
    const char *opn = "imm arith";
2080
    TCGv t0;
2081

    
2082
    if (rt == 0) {
2083
        /* If no destination, treat it as a NOP. */
2084
        MIPS_DEBUG("NOP");
2085
        return;
2086
    }
2087
    t0 = tcg_temp_new();
2088
    gen_load_gpr(t0, rs);
2089
    switch (opc) {
2090
    case OPC_SLTI:
2091
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2092
        opn = "slti";
2093
        break;
2094
    case OPC_SLTIU:
2095
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2096
        opn = "sltiu";
2097
        break;
2098
    }
2099
    (void)opn; /* avoid a compiler warning */
2100
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2101
    tcg_temp_free(t0);
2102
}
2103

    
2104
/* Shifts with immediate operand */
2105
static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2106
                          int rt, int rs, int16_t imm)
2107
{
2108
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2109
    const char *opn = "imm shift";
2110
    TCGv t0;
2111

    
2112
    if (rt == 0) {
2113
        /* If no destination, treat it as a NOP. */
2114
        MIPS_DEBUG("NOP");
2115
        return;
2116
    }
2117

    
2118
    t0 = tcg_temp_new();
2119
    gen_load_gpr(t0, rs);
2120
    switch (opc) {
2121
    case OPC_SLL:
2122
        tcg_gen_shli_tl(t0, t0, uimm);
2123
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2124
        opn = "sll";
2125
        break;
2126
    case OPC_SRA:
2127
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2128
        opn = "sra";
2129
        break;
2130
    case OPC_SRL:
2131
        if (uimm != 0) {
2132
            tcg_gen_ext32u_tl(t0, t0);
2133
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2134
        } else {
2135
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2136
        }
2137
        opn = "srl";
2138
        break;
2139
    case OPC_ROTR:
2140
        if (uimm != 0) {
2141
            TCGv_i32 t1 = tcg_temp_new_i32();
2142

    
2143
            tcg_gen_trunc_tl_i32(t1, t0);
2144
            tcg_gen_rotri_i32(t1, t1, uimm);
2145
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2146
            tcg_temp_free_i32(t1);
2147
        } else {
2148
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2149
        }
2150
        opn = "rotr";
2151
        break;
2152
#if defined(TARGET_MIPS64)
2153
    case OPC_DSLL:
2154
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2155
        opn = "dsll";
2156
        break;
2157
    case OPC_DSRA:
2158
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2159
        opn = "dsra";
2160
        break;
2161
    case OPC_DSRL:
2162
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2163
        opn = "dsrl";
2164
        break;
2165
    case OPC_DROTR:
2166
        if (uimm != 0) {
2167
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2168
        } else {
2169
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2170
        }
2171
        opn = "drotr";
2172
        break;
2173
    case OPC_DSLL32:
2174
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2175
        opn = "dsll32";
2176
        break;
2177
    case OPC_DSRA32:
2178
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2179
        opn = "dsra32";
2180
        break;
2181
    case OPC_DSRL32:
2182
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2183
        opn = "dsrl32";
2184
        break;
2185
    case OPC_DROTR32:
2186
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2187
        opn = "drotr32";
2188
        break;
2189
#endif
2190
    }
2191
    (void)opn; /* avoid a compiler warning */
2192
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2193
    tcg_temp_free(t0);
2194
}
2195

    
2196
/* Arithmetic */
2197
static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2198
                       int rd, int rs, int rt)
2199
{
2200
    const char *opn = "arith";
2201

    
2202
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2203
       && opc != OPC_DADD && opc != OPC_DSUB) {
2204
        /* If no destination, treat it as a NOP.
2205
           For add & sub, we must generate the overflow exception when needed. */
2206
        MIPS_DEBUG("NOP");
2207
        return;
2208
    }
2209

    
2210
    switch (opc) {
2211
    case OPC_ADD:
2212
        {
2213
            TCGv t0 = tcg_temp_local_new();
2214
            TCGv t1 = tcg_temp_new();
2215
            TCGv t2 = tcg_temp_new();
2216
            int l1 = gen_new_label();
2217

    
2218
            gen_load_gpr(t1, rs);
2219
            gen_load_gpr(t2, rt);
2220
            tcg_gen_add_tl(t0, t1, t2);
2221
            tcg_gen_ext32s_tl(t0, t0);
2222
            tcg_gen_xor_tl(t1, t1, t2);
2223
            tcg_gen_xor_tl(t2, t0, t2);
2224
            tcg_gen_andc_tl(t1, t2, t1);
2225
            tcg_temp_free(t2);
2226
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2227
            tcg_temp_free(t1);
2228
            /* operands of same sign, result different sign */
2229
            generate_exception(ctx, EXCP_OVERFLOW);
2230
            gen_set_label(l1);
2231
            gen_store_gpr(t0, rd);
2232
            tcg_temp_free(t0);
2233
        }
2234
        opn = "add";
2235
        break;
2236
    case OPC_ADDU:
2237
        if (rs != 0 && rt != 0) {
2238
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2239
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2240
        } else if (rs == 0 && rt != 0) {
2241
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2242
        } else if (rs != 0 && rt == 0) {
2243
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2244
        } else {
2245
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2246
        }
2247
        opn = "addu";
2248
        break;
2249
    case OPC_SUB:
2250
        {
2251
            TCGv t0 = tcg_temp_local_new();
2252
            TCGv t1 = tcg_temp_new();
2253
            TCGv t2 = tcg_temp_new();
2254
            int l1 = gen_new_label();
2255

    
2256
            gen_load_gpr(t1, rs);
2257
            gen_load_gpr(t2, rt);
2258
            tcg_gen_sub_tl(t0, t1, t2);
2259
            tcg_gen_ext32s_tl(t0, t0);
2260
            tcg_gen_xor_tl(t2, t1, t2);
2261
            tcg_gen_xor_tl(t1, t0, t1);
2262
            tcg_gen_and_tl(t1, t1, t2);
2263
            tcg_temp_free(t2);
2264
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2265
            tcg_temp_free(t1);
2266
            /* operands of different sign, first operand and result different sign */
2267
            generate_exception(ctx, EXCP_OVERFLOW);
2268
            gen_set_label(l1);
2269
            gen_store_gpr(t0, rd);
2270
            tcg_temp_free(t0);
2271
        }
2272
        opn = "sub";
2273
        break;
2274
    case OPC_SUBU:
2275
        if (rs != 0 && rt != 0) {
2276
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2277
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2278
        } else if (rs == 0 && rt != 0) {
2279
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2280
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2281
        } else if (rs != 0 && rt == 0) {
2282
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2283
        } else {
2284
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2285
        }
2286
        opn = "subu";
2287
        break;
2288
#if defined(TARGET_MIPS64)
2289
    case OPC_DADD:
2290
        {
2291
            TCGv t0 = tcg_temp_local_new();
2292
            TCGv t1 = tcg_temp_new();
2293
            TCGv t2 = tcg_temp_new();
2294
            int l1 = gen_new_label();
2295

    
2296
            gen_load_gpr(t1, rs);
2297
            gen_load_gpr(t2, rt);
2298
            tcg_gen_add_tl(t0, t1, t2);
2299
            tcg_gen_xor_tl(t1, t1, t2);
2300
            tcg_gen_xor_tl(t2, t0, t2);
2301
            tcg_gen_andc_tl(t1, t2, t1);
2302
            tcg_temp_free(t2);
2303
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2304
            tcg_temp_free(t1);
2305
            /* operands of same sign, result different sign */
2306
            generate_exception(ctx, EXCP_OVERFLOW);
2307
            gen_set_label(l1);
2308
            gen_store_gpr(t0, rd);
2309
            tcg_temp_free(t0);
2310
        }
2311
        opn = "dadd";
2312
        break;
2313
    case OPC_DADDU:
2314
        if (rs != 0 && rt != 0) {
2315
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2316
        } else if (rs == 0 && rt != 0) {
2317
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2318
        } else if (rs != 0 && rt == 0) {
2319
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2320
        } else {
2321
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2322
        }
2323
        opn = "daddu";
2324
        break;
2325
    case OPC_DSUB:
2326
        {
2327
            TCGv t0 = tcg_temp_local_new();
2328
            TCGv t1 = tcg_temp_new();
2329
            TCGv t2 = tcg_temp_new();
2330
            int l1 = gen_new_label();
2331

    
2332
            gen_load_gpr(t1, rs);
2333
            gen_load_gpr(t2, rt);
2334
            tcg_gen_sub_tl(t0, t1, t2);
2335
            tcg_gen_xor_tl(t2, t1, t2);
2336
            tcg_gen_xor_tl(t1, t0, t1);
2337
            tcg_gen_and_tl(t1, t1, t2);
2338
            tcg_temp_free(t2);
2339
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2340
            tcg_temp_free(t1);
2341
            /* operands of different sign, first operand and result different sign */
2342
            generate_exception(ctx, EXCP_OVERFLOW);
2343
            gen_set_label(l1);
2344
            gen_store_gpr(t0, rd);
2345
            tcg_temp_free(t0);
2346
        }
2347
        opn = "dsub";
2348
        break;
2349
    case OPC_DSUBU:
2350
        if (rs != 0 && rt != 0) {
2351
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2352
        } else if (rs == 0 && rt != 0) {
2353
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2354
        } else if (rs != 0 && rt == 0) {
2355
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2356
        } else {
2357
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2358
        }
2359
        opn = "dsubu";
2360
        break;
2361
#endif
2362
    case OPC_MUL:
2363
        if (likely(rs != 0 && rt != 0)) {
2364
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2365
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2366
        } else {
2367
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2368
        }
2369
        opn = "mul";
2370
        break;
2371
    }
2372
    (void)opn; /* avoid a compiler warning */
2373
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2374
}
2375

    
2376
/* Conditional move */
2377
static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2378
                          int rd, int rs, int rt)
2379
{
2380
    const char *opn = "cond move";
2381
    int l1;
2382

    
2383
    if (rd == 0) {
2384
        /* If no destination, treat it as a NOP.
2385
           For add & sub, we must generate the overflow exception when needed. */
2386
        MIPS_DEBUG("NOP");
2387
        return;
2388
    }
2389

    
2390
    l1 = gen_new_label();
2391
    switch (opc) {
2392
    case OPC_MOVN:
2393
        if (likely(rt != 0))
2394
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2395
        else
2396
            tcg_gen_br(l1);
2397
        opn = "movn";
2398
        break;
2399
    case OPC_MOVZ:
2400
        if (likely(rt != 0))
2401
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2402
        opn = "movz";
2403
        break;
2404
    }
2405
    if (rs != 0)
2406
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2407
    else
2408
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
2409
    gen_set_label(l1);
2410

    
2411
    (void)opn; /* avoid a compiler warning */
2412
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2413
}
2414

    
2415
/* Logic */
2416
static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2417
                      int rd, int rs, int rt)
2418
{
2419
    const char *opn = "logic";
2420

    
2421
    if (rd == 0) {
2422
        /* If no destination, treat it as a NOP. */
2423
        MIPS_DEBUG("NOP");
2424
        return;
2425
    }
2426

    
2427
    switch (opc) {
2428
    case OPC_AND:
2429
        if (likely(rs != 0 && rt != 0)) {
2430
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431
        } else {
2432
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2433
        }
2434
        opn = "and";
2435
        break;
2436
    case OPC_NOR:
2437
        if (rs != 0 && rt != 0) {
2438
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2439
        } else if (rs == 0 && rt != 0) {
2440
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2441
        } else if (rs != 0 && rt == 0) {
2442
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2443
        } else {
2444
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2445
        }
2446
        opn = "nor";
2447
        break;
2448
    case OPC_OR:
2449
        if (likely(rs != 0 && rt != 0)) {
2450
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2451
        } else if (rs == 0 && rt != 0) {
2452
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2453
        } else if (rs != 0 && rt == 0) {
2454
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2455
        } else {
2456
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2457
        }
2458
        opn = "or";
2459
        break;
2460
    case OPC_XOR:
2461
        if (likely(rs != 0 && rt != 0)) {
2462
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2463
        } else if (rs == 0 && rt != 0) {
2464
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2465
        } else if (rs != 0 && rt == 0) {
2466
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2467
        } else {
2468
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2469
        }
2470
        opn = "xor";
2471
        break;
2472
    }
2473
    (void)opn; /* avoid a compiler warning */
2474
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2475
}
2476

    
2477
/* Set on lower than */
2478
static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2479
                    int rd, int rs, int rt)
2480
{
2481
    const char *opn = "slt";
2482
    TCGv t0, t1;
2483

    
2484
    if (rd == 0) {
2485
        /* If no destination, treat it as a NOP. */
2486
        MIPS_DEBUG("NOP");
2487
        return;
2488
    }
2489

    
2490
    t0 = tcg_temp_new();
2491
    t1 = tcg_temp_new();
2492
    gen_load_gpr(t0, rs);
2493
    gen_load_gpr(t1, rt);
2494
    switch (opc) {
2495
    case OPC_SLT:
2496
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2497
        opn = "slt";
2498
        break;
2499
    case OPC_SLTU:
2500
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2501
        opn = "sltu";
2502
        break;
2503
    }
2504
    (void)opn; /* avoid a compiler warning */
2505
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2506
    tcg_temp_free(t0);
2507
    tcg_temp_free(t1);
2508
}
2509

    
2510
/* Shifts */
2511
static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2512
                       int rd, int rs, int rt)
2513
{
2514
    const char *opn = "shifts";
2515
    TCGv t0, t1;
2516

    
2517
    if (rd == 0) {
2518
        /* If no destination, treat it as a NOP.
2519
           For add & sub, we must generate the overflow exception when needed. */
2520
        MIPS_DEBUG("NOP");
2521
        return;
2522
    }
2523

    
2524
    t0 = tcg_temp_new();
2525
    t1 = tcg_temp_new();
2526
    gen_load_gpr(t0, rs);
2527
    gen_load_gpr(t1, rt);
2528
    switch (opc) {
2529
    case OPC_SLLV:
2530
        tcg_gen_andi_tl(t0, t0, 0x1f);
2531
        tcg_gen_shl_tl(t0, t1, t0);
2532
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2533
        opn = "sllv";
2534
        break;
2535
    case OPC_SRAV:
2536
        tcg_gen_andi_tl(t0, t0, 0x1f);
2537
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2538
        opn = "srav";
2539
        break;
2540
    case OPC_SRLV:
2541
        tcg_gen_ext32u_tl(t1, t1);
2542
        tcg_gen_andi_tl(t0, t0, 0x1f);
2543
        tcg_gen_shr_tl(t0, t1, t0);
2544
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2545
        opn = "srlv";
2546
        break;
2547
    case OPC_ROTRV:
2548
        {
2549
            TCGv_i32 t2 = tcg_temp_new_i32();
2550
            TCGv_i32 t3 = tcg_temp_new_i32();
2551

    
2552
            tcg_gen_trunc_tl_i32(t2, t0);
2553
            tcg_gen_trunc_tl_i32(t3, t1);
2554
            tcg_gen_andi_i32(t2, t2, 0x1f);
2555
            tcg_gen_rotr_i32(t2, t3, t2);
2556
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2557
            tcg_temp_free_i32(t2);
2558
            tcg_temp_free_i32(t3);
2559
            opn = "rotrv";
2560
        }
2561
        break;
2562
#if defined(TARGET_MIPS64)
2563
    case OPC_DSLLV:
2564
        tcg_gen_andi_tl(t0, t0, 0x3f);
2565
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2566
        opn = "dsllv";
2567
        break;
2568
    case OPC_DSRAV:
2569
        tcg_gen_andi_tl(t0, t0, 0x3f);
2570
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2571
        opn = "dsrav";
2572
        break;
2573
    case OPC_DSRLV:
2574
        tcg_gen_andi_tl(t0, t0, 0x3f);
2575
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2576
        opn = "dsrlv";
2577
        break;
2578
    case OPC_DROTRV:
2579
        tcg_gen_andi_tl(t0, t0, 0x3f);
2580
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2581
        opn = "drotrv";
2582
        break;
2583
#endif
2584
    }
2585
    (void)opn; /* avoid a compiler warning */
2586
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2587
    tcg_temp_free(t0);
2588
    tcg_temp_free(t1);
2589
}
2590

    
2591
/* Arithmetic on HI/LO registers */
2592
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2593
{
2594
    const char *opn = "hilo";
2595
    unsigned int acc;
2596

    
2597
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2598
        /* Treat as NOP. */
2599
        MIPS_DEBUG("NOP");
2600
        return;
2601
    }
2602

    
2603
    if (opc == OPC_MFHI || opc == OPC_MFLO) {
2604
        acc = ((ctx->opcode) >> 21) & 0x03;
2605
    } else {
2606
        acc = ((ctx->opcode) >> 11) & 0x03;
2607
    }
2608

    
2609
    if (acc != 0) {
2610
        check_dsp(ctx);
2611
    }
2612

    
2613
    switch (opc) {
2614
    case OPC_MFHI:
2615
#if defined(TARGET_MIPS64)
2616
        if (acc != 0) {
2617
            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2618
        } else
2619
#endif
2620
        {
2621
            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2622
        }
2623
        opn = "mfhi";
2624
        break;
2625
    case OPC_MFLO:
2626
#if defined(TARGET_MIPS64)
2627
        if (acc != 0) {
2628
            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2629
        } else
2630
#endif
2631
        {
2632
            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2633
        }
2634
        opn = "mflo";
2635
        break;
2636
    case OPC_MTHI:
2637
        if (reg != 0) {
2638
#if defined(TARGET_MIPS64)
2639
            if (acc != 0) {
2640
                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2641
            } else
2642
#endif
2643
            {
2644
                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2645
            }
2646
        } else {
2647
            tcg_gen_movi_tl(cpu_HI[acc], 0);
2648
        }
2649
        opn = "mthi";
2650
        break;
2651
    case OPC_MTLO:
2652
        if (reg != 0) {
2653
#if defined(TARGET_MIPS64)
2654
            if (acc != 0) {
2655
                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2656
            } else
2657
#endif
2658
            {
2659
                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2660
            }
2661
        } else {
2662
            tcg_gen_movi_tl(cpu_LO[acc], 0);
2663
        }
2664
        opn = "mtlo";
2665
        break;
2666
    }
2667
    (void)opn; /* avoid a compiler warning */
2668
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2669
}
2670

    
2671
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2672
                        int rs, int rt)
2673
{
2674
    const char *opn = "mul/div";
2675
    TCGv t0, t1;
2676
    unsigned int acc;
2677

    
2678
    switch (opc) {
2679
    case OPC_DIV:
2680
    case OPC_DIVU:
2681
#if defined(TARGET_MIPS64)
2682
    case OPC_DDIV:
2683
    case OPC_DDIVU:
2684
#endif
2685
        t0 = tcg_temp_local_new();
2686
        t1 = tcg_temp_local_new();
2687
        break;
2688
    default:
2689
        t0 = tcg_temp_new();
2690
        t1 = tcg_temp_new();
2691
        break;
2692
    }
2693

    
2694
    gen_load_gpr(t0, rs);
2695
    gen_load_gpr(t1, rt);
2696
    switch (opc) {
2697
    case OPC_DIV:
2698
        {
2699
            int l1 = gen_new_label();
2700
            int l2 = gen_new_label();
2701

    
2702
            tcg_gen_ext32s_tl(t0, t0);
2703
            tcg_gen_ext32s_tl(t1, t1);
2704
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2705
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2706
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2707

    
2708
            tcg_gen_mov_tl(cpu_LO[0], t0);
2709
            tcg_gen_movi_tl(cpu_HI[0], 0);
2710
            tcg_gen_br(l1);
2711
            gen_set_label(l2);
2712
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2713
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2714
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2715
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2716
            gen_set_label(l1);
2717
        }
2718
        opn = "div";
2719
        break;
2720
    case OPC_DIVU:
2721
        {
2722
            int l1 = gen_new_label();
2723

    
2724
            tcg_gen_ext32u_tl(t0, t0);
2725
            tcg_gen_ext32u_tl(t1, t1);
2726
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2727
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2728
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2729
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2730
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2731
            gen_set_label(l1);
2732
        }
2733
        opn = "divu";
2734
        break;
2735
    case OPC_MULT:
2736
        {
2737
            TCGv_i64 t2 = tcg_temp_new_i64();
2738
            TCGv_i64 t3 = tcg_temp_new_i64();
2739
            acc = ((ctx->opcode) >> 11) & 0x03;
2740
            if (acc != 0) {
2741
                check_dsp(ctx);
2742
            }
2743

    
2744
            tcg_gen_ext_tl_i64(t2, t0);
2745
            tcg_gen_ext_tl_i64(t3, t1);
2746
            tcg_gen_mul_i64(t2, t2, t3);
2747
            tcg_temp_free_i64(t3);
2748
            tcg_gen_trunc_i64_tl(t0, t2);
2749
            tcg_gen_shri_i64(t2, t2, 32);
2750
            tcg_gen_trunc_i64_tl(t1, t2);
2751
            tcg_temp_free_i64(t2);
2752
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2753
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2754
        }
2755
        opn = "mult";
2756
        break;
2757
    case OPC_MULTU:
2758
        {
2759
            TCGv_i64 t2 = tcg_temp_new_i64();
2760
            TCGv_i64 t3 = tcg_temp_new_i64();
2761
            acc = ((ctx->opcode) >> 11) & 0x03;
2762
            if (acc != 0) {
2763
                check_dsp(ctx);
2764
            }
2765

    
2766
            tcg_gen_ext32u_tl(t0, t0);
2767
            tcg_gen_ext32u_tl(t1, t1);
2768
            tcg_gen_extu_tl_i64(t2, t0);
2769
            tcg_gen_extu_tl_i64(t3, t1);
2770
            tcg_gen_mul_i64(t2, t2, t3);
2771
            tcg_temp_free_i64(t3);
2772
            tcg_gen_trunc_i64_tl(t0, t2);
2773
            tcg_gen_shri_i64(t2, t2, 32);
2774
            tcg_gen_trunc_i64_tl(t1, t2);
2775
            tcg_temp_free_i64(t2);
2776
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2777
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2778
        }
2779
        opn = "multu";
2780
        break;
2781
#if defined(TARGET_MIPS64)
2782
    case OPC_DDIV:
2783
        {
2784
            int l1 = gen_new_label();
2785
            int l2 = gen_new_label();
2786

    
2787
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2788
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2789
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2790
            tcg_gen_mov_tl(cpu_LO[0], t0);
2791
            tcg_gen_movi_tl(cpu_HI[0], 0);
2792
            tcg_gen_br(l1);
2793
            gen_set_label(l2);
2794
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2795
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2796
            gen_set_label(l1);
2797
        }
2798
        opn = "ddiv";
2799
        break;
2800
    case OPC_DDIVU:
2801
        {
2802
            int l1 = gen_new_label();
2803

    
2804
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2805
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2806
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2807
            gen_set_label(l1);
2808
        }
2809
        opn = "ddivu";
2810
        break;
2811
    case OPC_DMULT:
2812
        gen_helper_dmult(cpu_env, t0, t1);
2813
        opn = "dmult";
2814
        break;
2815
    case OPC_DMULTU:
2816
        gen_helper_dmultu(cpu_env, t0, t1);
2817
        opn = "dmultu";
2818
        break;
2819
#endif
2820
    case OPC_MADD:
2821
        {
2822
            TCGv_i64 t2 = tcg_temp_new_i64();
2823
            TCGv_i64 t3 = tcg_temp_new_i64();
2824
            acc = ((ctx->opcode) >> 11) & 0x03;
2825
            if (acc != 0) {
2826
                check_dsp(ctx);
2827
            }
2828

    
2829
            tcg_gen_ext_tl_i64(t2, t0);
2830
            tcg_gen_ext_tl_i64(t3, t1);
2831
            tcg_gen_mul_i64(t2, t2, t3);
2832
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2833
            tcg_gen_add_i64(t2, t2, t3);
2834
            tcg_temp_free_i64(t3);
2835
            tcg_gen_trunc_i64_tl(t0, t2);
2836
            tcg_gen_shri_i64(t2, t2, 32);
2837
            tcg_gen_trunc_i64_tl(t1, t2);
2838
            tcg_temp_free_i64(t2);
2839
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2840
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2841
        }
2842
        opn = "madd";
2843
        break;
2844
    case OPC_MADDU:
2845
        {
2846
            TCGv_i64 t2 = tcg_temp_new_i64();
2847
            TCGv_i64 t3 = tcg_temp_new_i64();
2848
            acc = ((ctx->opcode) >> 11) & 0x03;
2849
            if (acc != 0) {
2850
                check_dsp(ctx);
2851
            }
2852

    
2853
            tcg_gen_ext32u_tl(t0, t0);
2854
            tcg_gen_ext32u_tl(t1, t1);
2855
            tcg_gen_extu_tl_i64(t2, t0);
2856
            tcg_gen_extu_tl_i64(t3, t1);
2857
            tcg_gen_mul_i64(t2, t2, t3);
2858
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2859
            tcg_gen_add_i64(t2, t2, t3);
2860
            tcg_temp_free_i64(t3);
2861
            tcg_gen_trunc_i64_tl(t0, t2);
2862
            tcg_gen_shri_i64(t2, t2, 32);
2863
            tcg_gen_trunc_i64_tl(t1, t2);
2864
            tcg_temp_free_i64(t2);
2865
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2866
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2867
        }
2868
        opn = "maddu";
2869
        break;
2870
    case OPC_MSUB:
2871
        {
2872
            TCGv_i64 t2 = tcg_temp_new_i64();
2873
            TCGv_i64 t3 = tcg_temp_new_i64();
2874
            acc = ((ctx->opcode) >> 11) & 0x03;
2875
            if (acc != 0) {
2876
                check_dsp(ctx);
2877
            }
2878

    
2879
            tcg_gen_ext_tl_i64(t2, t0);
2880
            tcg_gen_ext_tl_i64(t3, t1);
2881
            tcg_gen_mul_i64(t2, t2, t3);
2882
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2883
            tcg_gen_sub_i64(t2, t3, t2);
2884
            tcg_temp_free_i64(t3);
2885
            tcg_gen_trunc_i64_tl(t0, t2);
2886
            tcg_gen_shri_i64(t2, t2, 32);
2887
            tcg_gen_trunc_i64_tl(t1, t2);
2888
            tcg_temp_free_i64(t2);
2889
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2890
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2891
        }
2892
        opn = "msub";
2893
        break;
2894
    case OPC_MSUBU:
2895
        {
2896
            TCGv_i64 t2 = tcg_temp_new_i64();
2897
            TCGv_i64 t3 = tcg_temp_new_i64();
2898
            acc = ((ctx->opcode) >> 11) & 0x03;
2899
            if (acc != 0) {
2900
                check_dsp(ctx);
2901
            }
2902

    
2903
            tcg_gen_ext32u_tl(t0, t0);
2904
            tcg_gen_ext32u_tl(t1, t1);
2905
            tcg_gen_extu_tl_i64(t2, t0);
2906
            tcg_gen_extu_tl_i64(t3, t1);
2907
            tcg_gen_mul_i64(t2, t2, t3);
2908
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2909
            tcg_gen_sub_i64(t2, t3, t2);
2910
            tcg_temp_free_i64(t3);
2911
            tcg_gen_trunc_i64_tl(t0, t2);
2912
            tcg_gen_shri_i64(t2, t2, 32);
2913
            tcg_gen_trunc_i64_tl(t1, t2);
2914
            tcg_temp_free_i64(t2);
2915
            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2916
            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2917
        }
2918
        opn = "msubu";
2919
        break;
2920
    default:
2921
        MIPS_INVAL(opn);
2922
        generate_exception(ctx, EXCP_RI);
2923
        goto out;
2924
    }
2925
    (void)opn; /* avoid a compiler warning */
2926
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2927
 out:
2928
    tcg_temp_free(t0);
2929
    tcg_temp_free(t1);
2930
}
2931

    
2932
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2933
                            int rd, int rs, int rt)
2934
{
2935
    const char *opn = "mul vr54xx";
2936
    TCGv t0 = tcg_temp_new();
2937
    TCGv t1 = tcg_temp_new();
2938

    
2939
    gen_load_gpr(t0, rs);
2940
    gen_load_gpr(t1, rt);
2941

    
2942
    switch (opc) {
2943
    case OPC_VR54XX_MULS:
2944
        gen_helper_muls(t0, cpu_env, t0, t1);
2945
        opn = "muls";
2946
        break;
2947
    case OPC_VR54XX_MULSU:
2948
        gen_helper_mulsu(t0, cpu_env, t0, t1);
2949
        opn = "mulsu";
2950
        break;
2951
    case OPC_VR54XX_MACC:
2952
        gen_helper_macc(t0, cpu_env, t0, t1);
2953
        opn = "macc";
2954
        break;
2955
    case OPC_VR54XX_MACCU:
2956
        gen_helper_maccu(t0, cpu_env, t0, t1);
2957
        opn = "maccu";
2958
        break;
2959
    case OPC_VR54XX_MSAC:
2960
        gen_helper_msac(t0, cpu_env, t0, t1);
2961
        opn = "msac";
2962
        break;
2963
    case OPC_VR54XX_MSACU:
2964
        gen_helper_msacu(t0, cpu_env, t0, t1);
2965
        opn = "msacu";
2966
        break;
2967
    case OPC_VR54XX_MULHI:
2968
        gen_helper_mulhi(t0, cpu_env, t0, t1);
2969
        opn = "mulhi";
2970
        break;
2971
    case OPC_VR54XX_MULHIU:
2972
        gen_helper_mulhiu(t0, cpu_env, t0, t1);
2973
        opn = "mulhiu";
2974
        break;
2975
    case OPC_VR54XX_MULSHI:
2976
        gen_helper_mulshi(t0, cpu_env, t0, t1);
2977
        opn = "mulshi";
2978
        break;
2979
    case OPC_VR54XX_MULSHIU:
2980
        gen_helper_mulshiu(t0, cpu_env, t0, t1);
2981
        opn = "mulshiu";
2982
        break;
2983
    case OPC_VR54XX_MACCHI:
2984
        gen_helper_macchi(t0, cpu_env, t0, t1);
2985
        opn = "macchi";
2986
        break;
2987
    case OPC_VR54XX_MACCHIU:
2988
        gen_helper_macchiu(t0, cpu_env, t0, t1);
2989
        opn = "macchiu";
2990
        break;
2991
    case OPC_VR54XX_MSACHI:
2992
        gen_helper_msachi(t0, cpu_env, t0, t1);
2993
        opn = "msachi";
2994
        break;
2995
    case OPC_VR54XX_MSACHIU:
2996
        gen_helper_msachiu(t0, cpu_env, t0, t1);
2997
        opn = "msachiu";
2998
        break;
2999
    default:
3000
        MIPS_INVAL("mul vr54xx");
3001
        generate_exception(ctx, EXCP_RI);
3002
        goto out;
3003
    }
3004
    gen_store_gpr(t0, rd);
3005
    (void)opn; /* avoid a compiler warning */
3006
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3007

    
3008
 out:
3009
    tcg_temp_free(t0);
3010
    tcg_temp_free(t1);
3011
}
3012

    
3013
static void gen_cl (DisasContext *ctx, uint32_t opc,
3014
                    int rd, int rs)
3015
{
3016
    const char *opn = "CLx";
3017
    TCGv t0;
3018

    
3019
    if (rd == 0) {
3020
        /* Treat as NOP. */
3021
        MIPS_DEBUG("NOP");
3022
        return;
3023
    }
3024
    t0 = tcg_temp_new();
3025
    gen_load_gpr(t0, rs);
3026
    switch (opc) {
3027
    case OPC_CLO:
3028
        gen_helper_clo(cpu_gpr[rd], t0);
3029
        opn = "clo";
3030
        break;
3031
    case OPC_CLZ:
3032
        gen_helper_clz(cpu_gpr[rd], t0);
3033
        opn = "clz";
3034
        break;
3035
#if defined(TARGET_MIPS64)
3036
    case OPC_DCLO:
3037
        gen_helper_dclo(cpu_gpr[rd], t0);
3038
        opn = "dclo";
3039
        break;
3040
    case OPC_DCLZ:
3041
        gen_helper_dclz(cpu_gpr[rd], t0);
3042
        opn = "dclz";
3043
        break;
3044
#endif
3045
    }
3046
    (void)opn; /* avoid a compiler warning */
3047
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3048
    tcg_temp_free(t0);
3049
}
3050

    
3051
/* Godson integer instructions */
3052
static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3053
                                 int rd, int rs, int rt)
3054
{
3055
    const char *opn = "loongson";
3056
    TCGv t0, t1;
3057

    
3058
    if (rd == 0) {
3059
        /* Treat as NOP. */
3060
        MIPS_DEBUG("NOP");
3061
        return;
3062
    }
3063

    
3064
    switch (opc) {
3065
    case OPC_MULT_G_2E:
3066
    case OPC_MULT_G_2F:
3067
    case OPC_MULTU_G_2E:
3068
    case OPC_MULTU_G_2F:
3069
#if defined(TARGET_MIPS64)
3070
    case OPC_DMULT_G_2E:
3071
    case OPC_DMULT_G_2F:
3072
    case OPC_DMULTU_G_2E:
3073
    case OPC_DMULTU_G_2F:
3074
#endif
3075
        t0 = tcg_temp_new();
3076
        t1 = tcg_temp_new();
3077
        break;
3078
    default:
3079
        t0 = tcg_temp_local_new();
3080
        t1 = tcg_temp_local_new();
3081
        break;
3082
    }
3083

    
3084
    gen_load_gpr(t0, rs);
3085
    gen_load_gpr(t1, rt);
3086

    
3087
    switch (opc) {
3088
    case OPC_MULT_G_2E:
3089
    case OPC_MULT_G_2F:
3090
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3091
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3092
        opn = "mult.g";
3093
        break;
3094
    case OPC_MULTU_G_2E:
3095
    case OPC_MULTU_G_2F:
3096
        tcg_gen_ext32u_tl(t0, t0);
3097
        tcg_gen_ext32u_tl(t1, t1);
3098
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3099
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3100
        opn = "multu.g";
3101
        break;
3102
    case OPC_DIV_G_2E:
3103
    case OPC_DIV_G_2F:
3104
        {
3105
            int l1 = gen_new_label();
3106
            int l2 = gen_new_label();
3107
            int l3 = gen_new_label();
3108
            tcg_gen_ext32s_tl(t0, t0);
3109
            tcg_gen_ext32s_tl(t1, t1);
3110
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3111
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3112
            tcg_gen_br(l3);
3113
            gen_set_label(l1);
3114
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3115
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3116
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3117
            tcg_gen_br(l3);
3118
            gen_set_label(l2);
3119
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3120
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3121
            gen_set_label(l3);
3122
        }
3123
        opn = "div.g";
3124
        break;
3125
    case OPC_DIVU_G_2E:
3126
    case OPC_DIVU_G_2F:
3127
        {
3128
            int l1 = gen_new_label();
3129
            int l2 = gen_new_label();
3130
            tcg_gen_ext32u_tl(t0, t0);
3131
            tcg_gen_ext32u_tl(t1, t1);
3132
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3133
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3134
            tcg_gen_br(l2);
3135
            gen_set_label(l1);
3136
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3137
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3138
            gen_set_label(l2);
3139
        }
3140
        opn = "divu.g";
3141
        break;
3142
    case OPC_MOD_G_2E:
3143
    case OPC_MOD_G_2F:
3144
        {
3145
            int l1 = gen_new_label();
3146
            int l2 = gen_new_label();
3147
            int l3 = gen_new_label();
3148
            tcg_gen_ext32u_tl(t0, t0);
3149
            tcg_gen_ext32u_tl(t1, t1);
3150
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3151
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3152
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3153
            gen_set_label(l1);
3154
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3155
            tcg_gen_br(l3);
3156
            gen_set_label(l2);
3157
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3158
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3159
            gen_set_label(l3);
3160
        }
3161
        opn = "mod.g";
3162
        break;
3163
    case OPC_MODU_G_2E:
3164
    case OPC_MODU_G_2F:
3165
        {
3166
            int l1 = gen_new_label();
3167
            int l2 = gen_new_label();
3168
            tcg_gen_ext32u_tl(t0, t0);
3169
            tcg_gen_ext32u_tl(t1, t1);
3170
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3171
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172
            tcg_gen_br(l2);
3173
            gen_set_label(l1);
3174
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3175
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3176
            gen_set_label(l2);
3177
        }
3178
        opn = "modu.g";
3179
        break;
3180
#if defined(TARGET_MIPS64)
3181
    case OPC_DMULT_G_2E:
3182
    case OPC_DMULT_G_2F:
3183
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3184
        opn = "dmult.g";
3185
        break;
3186
    case OPC_DMULTU_G_2E:
3187
    case OPC_DMULTU_G_2F:
3188
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3189
        opn = "dmultu.g";
3190
        break;
3191
    case OPC_DDIV_G_2E:
3192
    case OPC_DDIV_G_2F:
3193
        {
3194
            int l1 = gen_new_label();
3195
            int l2 = gen_new_label();
3196
            int l3 = gen_new_label();
3197
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3199
            tcg_gen_br(l3);
3200
            gen_set_label(l1);
3201
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3202
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3203
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3204
            tcg_gen_br(l3);
3205
            gen_set_label(l2);
3206
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3207
            gen_set_label(l3);
3208
        }
3209
        opn = "ddiv.g";
3210
        break;
3211
    case OPC_DDIVU_G_2E:
3212
    case OPC_DDIVU_G_2F:
3213
        {
3214
            int l1 = gen_new_label();
3215
            int l2 = gen_new_label();
3216
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3217
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3218
            tcg_gen_br(l2);
3219
            gen_set_label(l1);
3220
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3221
            gen_set_label(l2);
3222
        }
3223
        opn = "ddivu.g";
3224
        break;
3225
    case OPC_DMOD_G_2E:
3226
    case OPC_DMOD_G_2F:
3227
        {
3228
            int l1 = gen_new_label();
3229
            int l2 = gen_new_label();
3230
            int l3 = gen_new_label();
3231
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3232
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3233
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3234
            gen_set_label(l1);
3235
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3236
            tcg_gen_br(l3);
3237
            gen_set_label(l2);
3238
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3239
            gen_set_label(l3);
3240
        }
3241
        opn = "dmod.g";
3242
        break;
3243
    case OPC_DMODU_G_2E:
3244
    case OPC_DMODU_G_2F:
3245
        {
3246
            int l1 = gen_new_label();
3247
            int l2 = gen_new_label();
3248
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3249
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3250
            tcg_gen_br(l2);
3251
            gen_set_label(l1);
3252
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3253
            gen_set_label(l2);
3254
        }
3255
        opn = "dmodu.g";
3256
        break;
3257
#endif
3258
    }
3259

    
3260
    (void)opn; /* avoid a compiler warning */
3261
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3262
    tcg_temp_free(t0);
3263
    tcg_temp_free(t1);
3264
}
3265

    
3266
/* Loongson multimedia instructions */
3267
static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3268
{
3269
    const char *opn = "loongson_cp2";
3270
    uint32_t opc, shift_max;
3271
    TCGv_i64 t0, t1;
3272

    
3273
    opc = MASK_LMI(ctx->opcode);
3274
    switch (opc) {
3275
    case OPC_ADD_CP2:
3276
    case OPC_SUB_CP2:
3277
    case OPC_DADD_CP2:
3278
    case OPC_DSUB_CP2:
3279
        t0 = tcg_temp_local_new_i64();
3280
        t1 = tcg_temp_local_new_i64();
3281
        break;
3282
    default:
3283
        t0 = tcg_temp_new_i64();
3284
        t1 = tcg_temp_new_i64();
3285
        break;
3286
    }
3287

    
3288
    gen_load_fpr64(ctx, t0, rs);
3289
    gen_load_fpr64(ctx, t1, rt);
3290

    
3291
#define LMI_HELPER(UP, LO) \
3292
    case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3293
#define LMI_HELPER_1(UP, LO) \
3294
    case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3295
#define LMI_DIRECT(UP, LO, OP) \
3296
    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3297

    
3298
    switch (opc) {
3299
    LMI_HELPER(PADDSH, paddsh);
3300
    LMI_HELPER(PADDUSH, paddush);
3301
    LMI_HELPER(PADDH, paddh);
3302
    LMI_HELPER(PADDW, paddw);
3303
    LMI_HELPER(PADDSB, paddsb);
3304
    LMI_HELPER(PADDUSB, paddusb);
3305
    LMI_HELPER(PADDB, paddb);
3306

    
3307
    LMI_HELPER(PSUBSH, psubsh);
3308
    LMI_HELPER(PSUBUSH, psubush);
3309
    LMI_HELPER(PSUBH, psubh);
3310
    LMI_HELPER(PSUBW, psubw);
3311
    LMI_HELPER(PSUBSB, psubsb);
3312
    LMI_HELPER(PSUBUSB, psubusb);
3313
    LMI_HELPER(PSUBB, psubb);
3314

    
3315
    LMI_HELPER(PSHUFH, pshufh);
3316
    LMI_HELPER(PACKSSWH, packsswh);
3317
    LMI_HELPER(PACKSSHB, packsshb);
3318
    LMI_HELPER(PACKUSHB, packushb);
3319

    
3320
    LMI_HELPER(PUNPCKLHW, punpcklhw);
3321
    LMI_HELPER(PUNPCKHHW, punpckhhw);
3322
    LMI_HELPER(PUNPCKLBH, punpcklbh);
3323
    LMI_HELPER(PUNPCKHBH, punpckhbh);
3324
    LMI_HELPER(PUNPCKLWD, punpcklwd);
3325
    LMI_HELPER(PUNPCKHWD, punpckhwd);
3326

    
3327
    LMI_HELPER(PAVGH, pavgh);
3328
    LMI_HELPER(PAVGB, pavgb);
3329
    LMI_HELPER(PMAXSH, pmaxsh);
3330
    LMI_HELPER(PMINSH, pminsh);
3331
    LMI_HELPER(PMAXUB, pmaxub);
3332
    LMI_HELPER(PMINUB, pminub);
3333

    
3334
    LMI_HELPER(PCMPEQW, pcmpeqw);
3335
    LMI_HELPER(PCMPGTW, pcmpgtw);
3336
    LMI_HELPER(PCMPEQH, pcmpeqh);
3337
    LMI_HELPER(PCMPGTH, pcmpgth);
3338
    LMI_HELPER(PCMPEQB, pcmpeqb);
3339
    LMI_HELPER(PCMPGTB, pcmpgtb);
3340

    
3341
    LMI_HELPER(PSLLW, psllw);
3342
    LMI_HELPER(PSLLH, psllh);
3343
    LMI_HELPER(PSRLW, psrlw);
3344
    LMI_HELPER(PSRLH, psrlh);
3345
    LMI_HELPER(PSRAW, psraw);
3346
    LMI_HELPER(PSRAH, psrah);
3347

    
3348
    LMI_HELPER(PMULLH, pmullh);
3349
    LMI_HELPER(PMULHH, pmulhh);
3350
    LMI_HELPER(PMULHUH, pmulhuh);
3351
    LMI_HELPER(PMADDHW, pmaddhw);
3352

    
3353
    LMI_HELPER(PASUBUB, pasubub);
3354
    LMI_HELPER_1(BIADD, biadd);
3355
    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3356

    
3357
    LMI_DIRECT(PADDD, paddd, add);
3358
    LMI_DIRECT(PSUBD, psubd, sub);
3359
    LMI_DIRECT(XOR_CP2, xor, xor);
3360
    LMI_DIRECT(NOR_CP2, nor, nor);
3361
    LMI_DIRECT(AND_CP2, and, and);
3362
    LMI_DIRECT(PANDN, pandn, andc);
3363
    LMI_DIRECT(OR, or, or);
3364

    
3365
    case OPC_PINSRH_0:
3366
        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3367
        opn = "pinsrh_0";
3368
        break;
3369
    case OPC_PINSRH_1:
3370
        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3371
        opn = "pinsrh_1";
3372
        break;
3373
    case OPC_PINSRH_2:
3374
        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3375
        opn = "pinsrh_2";
3376
        break;
3377
    case OPC_PINSRH_3:
3378
        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3379
        opn = "pinsrh_3";
3380
        break;
3381

    
3382
    case OPC_PEXTRH:
3383
        tcg_gen_andi_i64(t1, t1, 3);
3384
        tcg_gen_shli_i64(t1, t1, 4);
3385
        tcg_gen_shr_i64(t0, t0, t1);
3386
        tcg_gen_ext16u_i64(t0, t0);
3387
        opn = "pextrh";
3388
        break;
3389

    
3390
    case OPC_ADDU_CP2:
3391
        tcg_gen_add_i64(t0, t0, t1);
3392
        tcg_gen_ext32s_i64(t0, t0);
3393
        opn = "addu";
3394
        break;
3395
    case OPC_SUBU_CP2:
3396
        tcg_gen_sub_i64(t0, t0, t1);
3397
        tcg_gen_ext32s_i64(t0, t0);
3398
        opn = "addu";
3399
        break;
3400

    
3401
    case OPC_SLL_CP2:
3402
        opn = "sll";
3403
        shift_max = 32;
3404
        goto do_shift;
3405
    case OPC_SRL_CP2:
3406
        opn = "srl";
3407
        shift_max = 32;
3408
        goto do_shift;
3409
    case OPC_SRA_CP2:
3410
        opn = "sra";
3411
        shift_max = 32;
3412
        goto do_shift;
3413
    case OPC_DSLL_CP2:
3414
        opn = "dsll";
3415
        shift_max = 64;
3416
        goto do_shift;
3417
    case OPC_DSRL_CP2:
3418
        opn = "dsrl";
3419
        shift_max = 64;
3420
        goto do_shift;
3421
    case OPC_DSRA_CP2:
3422
        opn = "dsra";
3423
        shift_max = 64;
3424
        goto do_shift;
3425
    do_shift:
3426
        /* Make sure shift count isn't TCG undefined behaviour.  */
3427
        tcg_gen_andi_i64(t1, t1, shift_max - 1);
3428

    
3429
        switch (opc) {
3430
        case OPC_SLL_CP2:
3431
        case OPC_DSLL_CP2:
3432
            tcg_gen_shl_i64(t0, t0, t1);
3433
            break;
3434
        case OPC_SRA_CP2:
3435
        case OPC_DSRA_CP2:
3436
            /* Since SRA is UndefinedResult without sign-extended inputs,
3437
               we can treat SRA and DSRA the same.  */
3438
            tcg_gen_sar_i64(t0, t0, t1);
3439
            break;
3440
        case OPC_SRL_CP2:
3441
            /* We want to shift in zeros for SRL; zero-extend first.  */
3442
            tcg_gen_ext32u_i64(t0, t0);
3443
            /* FALLTHRU */
3444
        case OPC_DSRL_CP2:
3445
            tcg_gen_shr_i64(t0, t0, t1);
3446
            break;
3447
        }
3448

    
3449
        if (shift_max == 32) {
3450
            tcg_gen_ext32s_i64(t0, t0);
3451
        }
3452

    
3453
        /* Shifts larger than MAX produce zero.  */
3454
        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3455
        tcg_gen_neg_i64(t1, t1);
3456
        tcg_gen_and_i64(t0, t0, t1);
3457
        break;
3458

    
3459
    case OPC_ADD_CP2:
3460
    case OPC_DADD_CP2:
3461
        {
3462
            TCGv_i64 t2 = tcg_temp_new_i64();
3463
            int lab = gen_new_label();
3464

    
3465
            tcg_gen_mov_i64(t2, t0);
3466
            tcg_gen_add_i64(t0, t1, t2);
3467
            if (opc == OPC_ADD_CP2) {
3468
                tcg_gen_ext32s_i64(t0, t0);
3469
            }
3470
            tcg_gen_xor_i64(t1, t1, t2);
3471
            tcg_gen_xor_i64(t2, t2, t0);
3472
            tcg_gen_andc_i64(t1, t2, t1);
3473
            tcg_temp_free_i64(t2);
3474
            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3475
            generate_exception(ctx, EXCP_OVERFLOW);
3476
            gen_set_label(lab);
3477

    
3478
            opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3479
            break;
3480
        }
3481

    
3482
    case OPC_SUB_CP2:
3483
    case OPC_DSUB_CP2:
3484
        {
3485
            TCGv_i64 t2 = tcg_temp_new_i64();
3486
            int lab = gen_new_label();
3487

    
3488
            tcg_gen_mov_i64(t2, t0);
3489
            tcg_gen_sub_i64(t0, t1, t2);
3490
            if (opc == OPC_SUB_CP2) {
3491
                tcg_gen_ext32s_i64(t0, t0);
3492
            }
3493
            tcg_gen_xor_i64(t1, t1, t2);
3494
            tcg_gen_xor_i64(t2, t2, t0);
3495
            tcg_gen_and_i64(t1, t1, t2);
3496
            tcg_temp_free_i64(t2);
3497
            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3498
            generate_exception(ctx, EXCP_OVERFLOW);
3499
            gen_set_label(lab);
3500

    
3501
            opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3502
            break;
3503
        }
3504

    
3505
    case OPC_PMULUW:
3506
        tcg_gen_ext32u_i64(t0, t0);
3507
        tcg_gen_ext32u_i64(t1, t1);
3508
        tcg_gen_mul_i64(t0, t0, t1);
3509
        opn = "pmuluw";
3510
        break;
3511

    
3512
    case OPC_SEQU_CP2:
3513
    case OPC_SEQ_CP2:
3514
    case OPC_SLTU_CP2:
3515
    case OPC_SLT_CP2:
3516
    case OPC_SLEU_CP2:
3517
    case OPC_SLE_CP2:
3518
        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
3519
           FD field is the CC field?  */
3520
    default:
3521
        MIPS_INVAL(opn);
3522
        generate_exception(ctx, EXCP_RI);
3523
        return;
3524
    }
3525

    
3526
#undef LMI_HELPER
3527
#undef LMI_DIRECT
3528

    
3529
    gen_store_fpr64(ctx, t0, rd);
3530

    
3531
    (void)opn; /* avoid a compiler warning */
3532
    MIPS_DEBUG("%s %s, %s, %s", opn,
3533
               fregnames[rd], fregnames[rs], fregnames[rt]);
3534
    tcg_temp_free_i64(t0);
3535
    tcg_temp_free_i64(t1);
3536
}
3537

    
3538
/* Traps */
3539
static void gen_trap (DisasContext *ctx, uint32_t opc,
3540
                      int rs, int rt, int16_t imm)
3541
{
3542
    int cond;
3543
    TCGv t0 = tcg_temp_new();
3544
    TCGv t1 = tcg_temp_new();
3545

    
3546
    cond = 0;
3547
    /* Load needed operands */
3548
    switch (opc) {
3549
    case OPC_TEQ:
3550
    case OPC_TGE:
3551
    case OPC_TGEU:
3552
    case OPC_TLT:
3553
    case OPC_TLTU:
3554
    case OPC_TNE:
3555
        /* Compare two registers */
3556
        if (rs != rt) {
3557
            gen_load_gpr(t0, rs);
3558
            gen_load_gpr(t1, rt);
3559
            cond = 1;
3560
        }
3561
        break;
3562
    case OPC_TEQI:
3563
    case OPC_TGEI:
3564
    case OPC_TGEIU:
3565
    case OPC_TLTI:
3566
    case OPC_TLTIU:
3567
    case OPC_TNEI:
3568
        /* Compare register to immediate */
3569
        if (rs != 0 || imm != 0) {
3570
            gen_load_gpr(t0, rs);
3571
            tcg_gen_movi_tl(t1, (int32_t)imm);
3572
            cond = 1;
3573
        }
3574
        break;
3575
    }
3576
    if (cond == 0) {
3577
        switch (opc) {
3578
        case OPC_TEQ:   /* rs == rs */
3579
        case OPC_TEQI:  /* r0 == 0  */
3580
        case OPC_TGE:   /* rs >= rs */
3581
        case OPC_TGEI:  /* r0 >= 0  */
3582
        case OPC_TGEU:  /* rs >= rs unsigned */
3583
        case OPC_TGEIU: /* r0 >= 0  unsigned */
3584
            /* Always trap */
3585
            generate_exception(ctx, EXCP_TRAP);
3586
            break;
3587
        case OPC_TLT:   /* rs < rs           */
3588
        case OPC_TLTI:  /* r0 < 0            */
3589
        case OPC_TLTU:  /* rs < rs unsigned  */
3590
        case OPC_TLTIU: /* r0 < 0  unsigned  */
3591
        case OPC_TNE:   /* rs != rs          */
3592
        case OPC_TNEI:  /* r0 != 0           */
3593
            /* Never trap: treat as NOP. */
3594
            break;
3595
        }
3596
    } else {
3597
        int l1 = gen_new_label();
3598

    
3599
        switch (opc) {
3600
        case OPC_TEQ:
3601
        case OPC_TEQI:
3602
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3603
            break;
3604
        case OPC_TGE:
3605
        case OPC_TGEI:
3606
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3607
            break;
3608
        case OPC_TGEU:
3609
        case OPC_TGEIU:
3610
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3611
            break;
3612
        case OPC_TLT:
3613
        case OPC_TLTI:
3614
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3615
            break;
3616
        case OPC_TLTU:
3617
        case OPC_TLTIU:
3618
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3619
            break;
3620
        case OPC_TNE:
3621
        case OPC_TNEI:
3622
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3623
            break;
3624
        }
3625
        generate_exception(ctx, EXCP_TRAP);
3626
        gen_set_label(l1);
3627
    }
3628
    tcg_temp_free(t0);
3629
    tcg_temp_free(t1);
3630
}
3631

    
3632
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3633
{
3634
    TranslationBlock *tb;
3635
    tb = ctx->tb;
3636
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3637
        likely(!ctx->singlestep_enabled)) {
3638
        tcg_gen_goto_tb(n);
3639
        gen_save_pc(dest);
3640
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3641
    } else {
3642
        gen_save_pc(dest);
3643
        if (ctx->singlestep_enabled) {
3644
            save_cpu_state(ctx, 0);
3645
            gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3646
        }
3647
        tcg_gen_exit_tb(0);
3648
    }
3649
}
3650

    
3651
/* Branches (before delay slot) */
3652
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3653
                                int insn_bytes,
3654
                                int rs, int rt, int32_t offset)
3655
{
3656
    target_ulong btgt = -1;
3657
    int blink = 0;
3658
    int bcond_compute = 0;
3659
    TCGv t0 = tcg_temp_new();
3660
    TCGv t1 = tcg_temp_new();
3661

    
3662
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3663
#ifdef MIPS_DEBUG_DISAS
3664
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3665
#endif
3666
        generate_exception(ctx, EXCP_RI);
3667
        goto out;
3668
    }
3669

    
3670
    /* Load needed operands */
3671
    switch (opc) {
3672
    case OPC_BEQ:
3673
    case OPC_BEQL:
3674
    case OPC_BNE:
3675
    case OPC_BNEL:
3676
        /* Compare two registers */
3677
        if (rs != rt) {
3678
            gen_load_gpr(t0, rs);
3679
            gen_load_gpr(t1, rt);
3680
            bcond_compute = 1;
3681
        }
3682
        btgt = ctx->pc + insn_bytes + offset;
3683
        break;
3684
    case OPC_BGEZ:
3685
    case OPC_BGEZAL:
3686
    case OPC_BGEZALS:
3687
    case OPC_BGEZALL:
3688
    case OPC_BGEZL:
3689
    case OPC_BGTZ:
3690
    case OPC_BGTZL:
3691
    case OPC_BLEZ:
3692
    case OPC_BLEZL:
3693
    case OPC_BLTZ:
3694
    case OPC_BLTZAL:
3695
    case OPC_BLTZALS:
3696
    case OPC_BLTZALL:
3697
    case OPC_BLTZL:
3698
        /* Compare to zero */
3699
        if (rs != 0) {
3700
            gen_load_gpr(t0, rs);
3701
            bcond_compute = 1;
3702
        }
3703
        btgt = ctx->pc + insn_bytes + offset;
3704
        break;
3705
    case OPC_BPOSGE32:
3706
#if defined(TARGET_MIPS64)
3707
    case OPC_BPOSGE64:
3708
        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3709
#else
3710
        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3711
#endif
3712
        bcond_compute = 1;
3713
        btgt = ctx->pc + insn_bytes + offset;
3714
        break;
3715
    case OPC_J:
3716
    case OPC_JAL:
3717
    case OPC_JALX:
3718
    case OPC_JALS:
3719
    case OPC_JALXS:
3720
        /* Jump to immediate */
3721
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3722
        break;
3723
    case OPC_JR:
3724
    case OPC_JALR:
3725
    case OPC_JALRC:
3726
    case OPC_JALRS:
3727
        /* Jump to register */
3728
        if (offset != 0 && offset != 16) {
3729
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3730
               others are reserved. */
3731
            MIPS_INVAL("jump hint");
3732
            generate_exception(ctx, EXCP_RI);
3733
            goto out;
3734
        }
3735
        gen_load_gpr(btarget, rs);
3736
        break;
3737
    default:
3738
        MIPS_INVAL("branch/jump");
3739
        generate_exception(ctx, EXCP_RI);
3740
        goto out;
3741
    }
3742
    if (bcond_compute == 0) {
3743
        /* No condition to be computed */
3744
        switch (opc) {
3745
        case OPC_BEQ:     /* rx == rx        */
3746
        case OPC_BEQL:    /* rx == rx likely */
3747
        case OPC_BGEZ:    /* 0 >= 0          */
3748
        case OPC_BGEZL:   /* 0 >= 0 likely   */
3749
        case OPC_BLEZ:    /* 0 <= 0          */
3750
        case OPC_BLEZL:   /* 0 <= 0 likely   */
3751
            /* Always take */
3752
            ctx->hflags |= MIPS_HFLAG_B;
3753
            MIPS_DEBUG("balways");
3754
            break;
3755
        case OPC_BGEZALS:
3756
        case OPC_BGEZAL:  /* 0 >= 0          */
3757
        case OPC_BGEZALL: /* 0 >= 0 likely   */
3758
            ctx->hflags |= (opc == OPC_BGEZALS
3759
                            ? MIPS_HFLAG_BDS16
3760
                            : MIPS_HFLAG_BDS32);
3761
            /* Always take and link */
3762
            blink = 31;
3763
            ctx->hflags |= MIPS_HFLAG_B;
3764
            MIPS_DEBUG("balways and link");
3765
            break;
3766
        case OPC_BNE:     /* rx != rx        */
3767
        case OPC_BGTZ:    /* 0 > 0           */
3768
        case OPC_BLTZ:    /* 0 < 0           */
3769
            /* Treat as NOP. */
3770
            MIPS_DEBUG("bnever (NOP)");
3771
            goto out;
3772
        case OPC_BLTZALS:
3773
        case OPC_BLTZAL:  /* 0 < 0           */
3774
            ctx->hflags |= (opc == OPC_BLTZALS
3775
                            ? MIPS_HFLAG_BDS16
3776
                            : MIPS_HFLAG_BDS32);
3777
            /* Handle as an unconditional branch to get correct delay
3778
               slot checking.  */
3779
            blink = 31;
3780
            btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3781
            ctx->hflags |= MIPS_HFLAG_B;
3782
            MIPS_DEBUG("bnever and link");
3783
            break;
3784
        case OPC_BLTZALL: /* 0 < 0 likely */
3785
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3786
            /* Skip the instruction in the delay slot */
3787
            MIPS_DEBUG("bnever, link and skip");
3788
            ctx->pc += 4;
3789
            goto out;
3790
        case OPC_BNEL:    /* rx != rx likely */
3791
        case OPC_BGTZL:   /* 0 > 0 likely */
3792
        case OPC_BLTZL:   /* 0 < 0 likely */
3793
            /* Skip the instruction in the delay slot */
3794
            MIPS_DEBUG("bnever and skip");
3795
            ctx->pc += 4;
3796
            goto out;
3797
        case OPC_J:
3798
            ctx->hflags |= MIPS_HFLAG_B;
3799
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3800
            break;
3801
        case OPC_JALXS:
3802
        case OPC_JALX:
3803
            ctx->hflags |= MIPS_HFLAG_BX;
3804
            /* Fallthrough */
3805
        case OPC_JALS:
3806
        case OPC_JAL:
3807
            blink = 31;
3808
            ctx->hflags |= MIPS_HFLAG_B;
3809
            ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3810
                            ? MIPS_HFLAG_BDS16
3811
                            : MIPS_HFLAG_BDS32);
3812
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3813
            break;
3814
        case OPC_JR:
3815
            ctx->hflags |= MIPS_HFLAG_BR;
3816
            if (insn_bytes == 4)
3817
                ctx->hflags |= MIPS_HFLAG_BDS32;
3818
            MIPS_DEBUG("jr %s", regnames[rs]);
3819
            break;
3820
        case OPC_JALRS:
3821
        case OPC_JALR:
3822
        case OPC_JALRC:
3823
            blink = rt;
3824
            ctx->hflags |= MIPS_HFLAG_BR;
3825
            ctx->hflags |= (opc == OPC_JALRS
3826
                            ? MIPS_HFLAG_BDS16
3827
                            : MIPS_HFLAG_BDS32);
3828
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3829
            break;
3830
        default:
3831
            MIPS_INVAL("branch/jump");
3832
            generate_exception(ctx, EXCP_RI);
3833
            goto out;
3834
        }
3835
    } else {
3836
        switch (opc) {
3837
        case OPC_BEQ:
3838
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3839
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3840
                       regnames[rs], regnames[rt], btgt);
3841
            goto not_likely;
3842
        case OPC_BEQL:
3843
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3844
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3845
                       regnames[rs], regnames[rt], btgt);
3846
            goto likely;
3847
        case OPC_BNE:
3848
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3849
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3850
                       regnames[rs], regnames[rt], btgt);
3851
            goto not_likely;
3852
        case OPC_BNEL:
3853
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3854
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3855
                       regnames[rs], regnames[rt], btgt);
3856
            goto likely;
3857
        case OPC_BGEZ:
3858
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3859
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860
            goto not_likely;
3861
        case OPC_BGEZL:
3862
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3863
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864
            goto likely;
3865
        case OPC_BGEZALS:
3866
        case OPC_BGEZAL:
3867
            ctx->hflags |= (opc == OPC_BGEZALS
3868
                            ? MIPS_HFLAG_BDS16
3869
                            : MIPS_HFLAG_BDS32);
3870
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3871
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872
            blink = 31;
3873
            goto not_likely;
3874
        case OPC_BGEZALL:
3875
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3876
            blink = 31;
3877
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3878
            goto likely;
3879
        case OPC_BGTZ:
3880
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3881
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3882
            goto not_likely;
3883
        case OPC_BGTZL:
3884
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3885
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3886
            goto likely;
3887
        case OPC_BLEZ:
3888
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3889
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3890
            goto not_likely;
3891
        case OPC_BLEZL:
3892
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3893
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3894
            goto likely;
3895
        case OPC_BLTZ:
3896
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3897
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3898
            goto not_likely;
3899
        case OPC_BLTZL:
3900
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3901
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3902
            goto likely;
3903
        case OPC_BPOSGE32:
3904
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3905
            MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3906
            goto not_likely;
3907
#if defined(TARGET_MIPS64)
3908
        case OPC_BPOSGE64:
3909
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3910
            MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3911
            goto not_likely;
3912
#endif
3913
        case OPC_BLTZALS:
3914
        case OPC_BLTZAL:
3915
            ctx->hflags |= (opc == OPC_BLTZALS
3916
                            ? MIPS_HFLAG_BDS16
3917
                            : MIPS_HFLAG_BDS32);
3918
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3919
            blink = 31;
3920
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3921
        not_likely:
3922
            ctx->hflags |= MIPS_HFLAG_BC;
3923
            break;
3924
        case OPC_BLTZALL:
3925
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3926
            blink = 31;
3927
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3928
        likely:
3929
            ctx->hflags |= MIPS_HFLAG_BL;
3930
            break;
3931
        default:
3932
            MIPS_INVAL("conditional branch/jump");
3933
            generate_exception(ctx, EXCP_RI);
3934
            goto out;
3935
        }
3936
    }
3937
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3938
               blink, ctx->hflags, btgt);
3939

    
3940
    ctx->btarget = btgt;
3941
    if (blink > 0) {
3942
        int post_delay = insn_bytes;
3943
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3944

    
3945
        if (opc != OPC_JALRC)
3946
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3947

    
3948
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3949
    }
3950

    
3951
 out:
3952
    if (insn_bytes == 2)
3953
        ctx->hflags |= MIPS_HFLAG_B16;
3954
    tcg_temp_free(t0);
3955
    tcg_temp_free(t1);
3956
}
3957

    
3958
/* special3 bitfield operations */
3959
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3960
                        int rs, int lsb, int msb)
3961
{
3962
    TCGv t0 = tcg_temp_new();
3963
    TCGv t1 = tcg_temp_new();
3964
    target_ulong mask;
3965

    
3966
    gen_load_gpr(t1, rs);
3967
    switch (opc) {
3968
    case OPC_EXT:
3969
        if (lsb + msb > 31)
3970
            goto fail;
3971
        tcg_gen_shri_tl(t0, t1, lsb);
3972
        if (msb != 31) {
3973
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3974
        } else {
3975
            tcg_gen_ext32s_tl(t0, t0);
3976
        }
3977
        break;
3978
#if defined(TARGET_MIPS64)
3979
    case OPC_DEXTM:
3980
        tcg_gen_shri_tl(t0, t1, lsb);
3981
        if (msb != 31) {
3982
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3983
        }
3984
        break;
3985
    case OPC_DEXTU:
3986
        tcg_gen_shri_tl(t0, t1, lsb + 32);
3987
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3988
        break;
3989
    case OPC_DEXT:
3990
        tcg_gen_shri_tl(t0, t1, lsb);
3991
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3992
        break;
3993
#endif
3994
    case OPC_INS:
3995
        if (lsb > msb)
3996
            goto fail;
3997
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3998
        gen_load_gpr(t0, rt);
3999
        tcg_gen_andi_tl(t0, t0, ~mask);
4000
        tcg_gen_shli_tl(t1, t1, lsb);
4001
        tcg_gen_andi_tl(t1, t1, mask);
4002
        tcg_gen_or_tl(t0, t0, t1);
4003
        tcg_gen_ext32s_tl(t0, t0);
4004
        break;
4005
#if defined(TARGET_MIPS64)
4006
    case OPC_DINSM:
4007
        if (lsb > msb)
4008
            goto fail;
4009
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
4010
        gen_load_gpr(t0, rt);
4011
        tcg_gen_andi_tl(t0, t0, ~mask);
4012
        tcg_gen_shli_tl(t1, t1, lsb);
4013
        tcg_gen_andi_tl(t1, t1, mask);
4014
        tcg_gen_or_tl(t0, t0, t1);
4015
        break;
4016
    case OPC_DINSU:
4017
        if (lsb > msb)
4018
            goto fail;
4019
        mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
4020
        gen_load_gpr(t0, rt);
4021
        tcg_gen_andi_tl(t0, t0, ~mask);
4022
        tcg_gen_shli_tl(t1, t1, lsb + 32);
4023
        tcg_gen_andi_tl(t1, t1, mask);
4024
        tcg_gen_or_tl(t0, t0, t1);
4025
        break;
4026
    case OPC_DINS:
4027
        if (lsb > msb)
4028
            goto fail;
4029
        gen_load_gpr(t0, rt);
4030
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4031
        gen_load_gpr(t0, rt);
4032
        tcg_gen_andi_tl(t0, t0, ~mask);
4033
        tcg_gen_shli_tl(t1, t1, lsb);
4034
        tcg_gen_andi_tl(t1, t1, mask);
4035
        tcg_gen_or_tl(t0, t0, t1);
4036
        break;
4037
#endif
4038
    default:
4039
fail:
4040
        MIPS_INVAL("bitops");
4041
        generate_exception(ctx, EXCP_RI);
4042
        tcg_temp_free(t0);
4043
        tcg_temp_free(t1);
4044
        return;
4045
    }
4046
    gen_store_gpr(t0, rt);
4047
    tcg_temp_free(t0);
4048
    tcg_temp_free(t1);
4049
}
4050

    
4051
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4052
{
4053
    TCGv t0;
4054

    
4055
    if (rd == 0) {
4056
        /* If no destination, treat it as a NOP. */
4057
        MIPS_DEBUG("NOP");
4058
        return;
4059
    }
4060

    
4061
    t0 = tcg_temp_new();
4062
    gen_load_gpr(t0, rt);
4063
    switch (op2) {
4064
    case OPC_WSBH:
4065
        {
4066
            TCGv t1 = tcg_temp_new();
4067

    
4068
            tcg_gen_shri_tl(t1, t0, 8);
4069
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4070
            tcg_gen_shli_tl(t0, t0, 8);
4071
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4072
            tcg_gen_or_tl(t0, t0, t1);
4073
            tcg_temp_free(t1);
4074
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4075
        }
4076
        break;
4077
    case OPC_SEB:
4078
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4079
        break;
4080
    case OPC_SEH:
4081
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4082
        break;
4083
#if defined(TARGET_MIPS64)
4084
    case OPC_DSBH:
4085
        {
4086
            TCGv t1 = tcg_temp_new();
4087

    
4088
            tcg_gen_shri_tl(t1, t0, 8);
4089
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4090
            tcg_gen_shli_tl(t0, t0, 8);
4091
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4092
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4093
            tcg_temp_free(t1);
4094
        }
4095
        break;
4096
    case OPC_DSHD:
4097
        {
4098
            TCGv t1 = tcg_temp_new();
4099

    
4100
            tcg_gen_shri_tl(t1, t0, 16);
4101
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4102
            tcg_gen_shli_tl(t0, t0, 16);
4103
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4104
            tcg_gen_or_tl(t0, t0, t1);
4105
            tcg_gen_shri_tl(t1, t0, 32);
4106
            tcg_gen_shli_tl(t0, t0, 32);
4107
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4108
            tcg_temp_free(t1);
4109
        }
4110
        break;
4111
#endif
4112
    default:
4113
        MIPS_INVAL("bsfhl");
4114
        generate_exception(ctx, EXCP_RI);
4115
        tcg_temp_free(t0);
4116
        return;
4117
    }
4118
    tcg_temp_free(t0);
4119
}
4120

    
4121
#ifndef CONFIG_USER_ONLY
4122
/* CP0 (MMU and control) */
4123
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4124
{
4125
    TCGv_i32 t0 = tcg_temp_new_i32();
4126

    
4127
    tcg_gen_ld_i32(t0, cpu_env, off);
4128
    tcg_gen_ext_i32_tl(arg, t0);
4129
    tcg_temp_free_i32(t0);
4130
}
4131

    
4132
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4133
{
4134
    tcg_gen_ld_tl(arg, cpu_env, off);
4135
    tcg_gen_ext32s_tl(arg, arg);
4136
}
4137

    
4138
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4139
{
4140
    TCGv_i32 t0 = tcg_temp_new_i32();
4141

    
4142
    tcg_gen_trunc_tl_i32(t0, arg);
4143
    tcg_gen_st_i32(t0, cpu_env, off);
4144
    tcg_temp_free_i32(t0);
4145
}
4146

    
4147
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4148
{
4149
    tcg_gen_ext32s_tl(arg, arg);
4150
    tcg_gen_st_tl(arg, cpu_env, off);
4151
}
4152

    
4153
static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4154
{
4155
    const char *rn = "invalid";
4156

    
4157
    if (sel != 0)
4158
        check_insn(env, ctx, ISA_MIPS32);
4159

    
4160
    switch (reg) {
4161
    case 0:
4162
        switch (sel) {
4163
        case 0:
4164
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4165
            rn = "Index";
4166
            break;
4167
        case 1:
4168
            check_insn(env, ctx, ASE_MT);
4169
            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4170
            rn = "MVPControl";
4171
            break;
4172
        case 2:
4173
            check_insn(env, ctx, ASE_MT);
4174
            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4175
            rn = "MVPConf0";
4176
            break;
4177
        case 3:
4178
            check_insn(env, ctx, ASE_MT);
4179
            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4180
            rn = "MVPConf1";
4181
            break;
4182
        default:
4183
            goto die;
4184
        }
4185
        break;
4186
    case 1:
4187
        switch (sel) {
4188
        case 0:
4189
            gen_helper_mfc0_random(arg, cpu_env);
4190
            rn = "Random";
4191
            break;
4192
        case 1:
4193
            check_insn(env, ctx, ASE_MT);
4194
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4195
            rn = "VPEControl";
4196
            break;
4197
        case 2:
4198
            check_insn(env, ctx, ASE_MT);
4199
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4200
            rn = "VPEConf0";
4201
            break;
4202
        case 3:
4203
            check_insn(env, ctx, ASE_MT);
4204
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4205
            rn = "VPEConf1";
4206
            break;
4207
        case 4:
4208
            check_insn(env, ctx, ASE_MT);
4209
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4210
            rn = "YQMask";
4211
            break;
4212
        case 5:
4213
            check_insn(env, ctx, ASE_MT);
4214
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4215
            rn = "VPESchedule";
4216
            break;
4217
        case 6:
4218
            check_insn(env, ctx, ASE_MT);
4219
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4220
            rn = "VPEScheFBack";
4221
            break;
4222
        case 7:
4223
            check_insn(env, ctx, ASE_MT);
4224
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4225
            rn = "VPEOpt";
4226
            break;
4227
        default:
4228
            goto die;
4229
        }
4230
        break;
4231
    case 2:
4232
        switch (sel) {
4233
        case 0:
4234
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4235
            tcg_gen_ext32s_tl(arg, arg);
4236
            rn = "EntryLo0";
4237
            break;
4238
        case 1:
4239
            check_insn(env, ctx, ASE_MT);
4240
            gen_helper_mfc0_tcstatus(arg, cpu_env);
4241
            rn = "TCStatus";
4242
            break;
4243
        case 2:
4244
            check_insn(env, ctx, ASE_MT);
4245
            gen_helper_mfc0_tcbind(arg, cpu_env);
4246
            rn = "TCBind";
4247
            break;
4248
        case 3:
4249
            check_insn(env, ctx, ASE_MT);
4250
            gen_helper_mfc0_tcrestart(arg, cpu_env);
4251
            rn = "TCRestart";
4252
            break;
4253
        case 4:
4254
            check_insn(env, ctx, ASE_MT);
4255
            gen_helper_mfc0_tchalt(arg, cpu_env);
4256
            rn = "TCHalt";
4257
            break;
4258
        case 5:
4259
            check_insn(env, ctx, ASE_MT);
4260
            gen_helper_mfc0_tccontext(arg, cpu_env);
4261
            rn = "TCContext";
4262
            break;
4263
        case 6:
4264
            check_insn(env, ctx, ASE_MT);
4265
            gen_helper_mfc0_tcschedule(arg, cpu_env);
4266
            rn = "TCSchedule";
4267
            break;
4268
        case 7:
4269
            check_insn(env, ctx, ASE_MT);
4270
            gen_helper_mfc0_tcschefback(arg, cpu_env);
4271
            rn = "TCScheFBack";
4272
            break;
4273
        default:
4274
            goto die;
4275
        }
4276
        break;
4277
    case 3:
4278
        switch (sel) {
4279
        case 0:
4280
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4281
            tcg_gen_ext32s_tl(arg, arg);
4282
            rn = "EntryLo1";
4283
            break;
4284
        default:
4285
            goto die;
4286
        }
4287
        break;
4288
    case 4:
4289
        switch (sel) {
4290
        case 0:
4291
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4292
            tcg_gen_ext32s_tl(arg, arg);
4293
            rn = "Context";
4294
            break;
4295
        case 1:
4296
//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4297
            rn = "ContextConfig";
4298
//            break;
4299
        default:
4300
            goto die;
4301
        }
4302
        break;
4303
    case 5:
4304
        switch (sel) {
4305
        case 0:
4306
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4307
            rn = "PageMask";
4308
            break;
4309
        case 1:
4310
            check_insn(env, ctx, ISA_MIPS32R2);
4311
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4312
            rn = "PageGrain";
4313
            break;
4314
        default:
4315
            goto die;
4316
        }
4317
        break;
4318
    case 6:
4319
        switch (sel) {
4320
        case 0:
4321
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4322
            rn = "Wired";
4323
            break;
4324
        case 1:
4325
            check_insn(env, ctx, ISA_MIPS32R2);
4326
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4327
            rn = "SRSConf0";
4328
            break;
4329
        case 2:
4330
            check_insn(env, ctx, ISA_MIPS32R2);
4331
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4332
            rn = "SRSConf1";
4333
            break;
4334
        case 3:
4335
            check_insn(env, ctx, ISA_MIPS32R2);
4336
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4337
            rn = "SRSConf2";
4338
            break;
4339
        case 4:
4340
            check_insn(env, ctx, ISA_MIPS32R2);
4341
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4342
            rn = "SRSConf3";
4343
            break;
4344
        case 5:
4345
            check_insn(env, ctx, ISA_MIPS32R2);
4346
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4347
            rn = "SRSConf4";
4348
            break;
4349
        default:
4350
            goto die;
4351
        }
4352
        break;
4353
    case 7:
4354
        switch (sel) {
4355
        case 0:
4356
            check_insn(env, ctx, ISA_MIPS32R2);
4357
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4358
            rn = "HWREna";
4359
            break;
4360
        default:
4361
            goto die;
4362
        }
4363
        break;
4364
    case 8:
4365
        switch (sel) {
4366
        case 0:
4367
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4368
            tcg_gen_ext32s_tl(arg, arg);
4369
            rn = "BadVAddr";
4370
            break;
4371
        default:
4372
            goto die;
4373
       }
4374
        break;
4375
    case 9:
4376
        switch (sel) {
4377
        case 0:
4378
            /* Mark as an IO operation because we read the time.  */
4379
            if (use_icount)
4380
                gen_io_start();
4381
            gen_helper_mfc0_count(arg, cpu_env);
4382
            if (use_icount) {
4383
                gen_io_end();
4384
            }
4385
            /* Break the TB to be able to take timer interrupts immediately
4386
               after reading count.  */
4387
            ctx->bstate = BS_STOP;
4388
            rn = "Count";
4389
            break;
4390
        /* 6,7 are implementation dependent */
4391
        default:
4392
            goto die;
4393
        }
4394
        break;
4395
    case 10:
4396
        switch (sel) {
4397
        case 0:
4398
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4399
            tcg_gen_ext32s_tl(arg, arg);
4400
            rn = "EntryHi";
4401
            break;
4402
        default:
4403
            goto die;
4404
        }
4405
        break;
4406
    case 11:
4407
        switch (sel) {
4408
        case 0:
4409
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4410
            rn = "Compare";
4411
            break;
4412
        /* 6,7 are implementation dependent */
4413
        default:
4414
            goto die;
4415
        }
4416
        break;
4417
    case 12:
4418
        switch (sel) {
4419
        case 0:
4420
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4421
            rn = "Status";
4422
            break;
4423
        case 1:
4424
            check_insn(env, ctx, ISA_MIPS32R2);
4425
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4426
            rn = "IntCtl";
4427
            break;
4428
        case 2:
4429
            check_insn(env, ctx, ISA_MIPS32R2);
4430
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4431
            rn = "SRSCtl";
4432
            break;
4433
        case 3:
4434
            check_insn(env, ctx, ISA_MIPS32R2);
4435
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4436
            rn = "SRSMap";
4437
            break;
4438
        default:
4439
            goto die;
4440
       }
4441
        break;
4442
    case 13:
4443
        switch (sel) {
4444
        case 0:
4445
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4446
            rn = "Cause";
4447
            break;
4448
        default:
4449
            goto die;
4450
       }
4451
        break;
4452
    case 14:
4453
        switch (sel) {
4454
        case 0:
4455
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4456
            tcg_gen_ext32s_tl(arg, arg);
4457
            rn = "EPC";
4458
            break;
4459
        default:
4460
            goto die;
4461
        }
4462
        break;
4463
    case 15:
4464
        switch (sel) {
4465
        case 0:
4466
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4467
            rn = "PRid";
4468
            break;
4469
        case 1:
4470
            check_insn(env, ctx, ISA_MIPS32R2);
4471
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4472
            rn = "EBase";
4473
            break;
4474
        default:
4475
            goto die;
4476
       }
4477
        break;
4478
    case 16:
4479
        switch (sel) {
4480
        case 0:
4481
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4482
            rn = "Config";
4483
            break;
4484
        case 1:
4485
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4486
            rn = "Config1";
4487
            break;
4488
        case 2:
4489
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4490
            rn = "Config2";
4491
            break;
4492
        case 3:
4493
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4494
            rn = "Config3";
4495
            break;
4496
        /* 4,5 are reserved */
4497
        /* 6,7 are implementation dependent */
4498
        case 6:
4499
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4500
            rn = "Config6";
4501
            break;
4502
        case 7:
4503
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4504
            rn = "Config7";
4505
            break;
4506
        default:
4507
            goto die;
4508
        }
4509
        break;
4510
    case 17:
4511
        switch (sel) {
4512
        case 0:
4513
            gen_helper_mfc0_lladdr(arg, cpu_env);
4514
            rn = "LLAddr";
4515
            break;
4516
        default:
4517
            goto die;
4518
        }
4519
        break;
4520
    case 18:
4521
        switch (sel) {
4522
        case 0 ... 7:
4523
            gen_helper_1e0i(mfc0_watchlo, arg, sel);
4524
            rn = "WatchLo";
4525
            break;
4526
        default:
4527
            goto die;
4528
        }
4529
        break;
4530
    case 19:
4531
        switch (sel) {
4532
        case 0 ...7:
4533
            gen_helper_1e0i(mfc0_watchhi, arg, sel);
4534
            rn = "WatchHi";
4535
            break;
4536
        default:
4537
            goto die;
4538
        }
4539
        break;
4540
    case 20:
4541
        switch (sel) {
4542
        case 0:
4543
#if defined(TARGET_MIPS64)
4544
            check_insn(env, ctx, ISA_MIPS3);
4545
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4546
            tcg_gen_ext32s_tl(arg, arg);
4547
            rn = "XContext";
4548
            break;
4549
#endif
4550
        default:
4551
            goto die;
4552
        }
4553
        break;
4554
    case 21:
4555
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4556
        switch (sel) {
4557
        case 0:
4558
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4559
            rn = "Framemask";
4560
            break;
4561
        default:
4562
            goto die;
4563
        }
4564
        break;
4565
    case 22:
4566
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4567
        rn = "'Diagnostic"; /* implementation dependent */
4568
        break;
4569
    case 23:
4570
        switch (sel) {
4571
        case 0:
4572
            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4573
            rn = "Debug";
4574
            break;
4575
        case 1:
4576
//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4577
            rn = "TraceControl";
4578
//            break;
4579
        case 2:
4580
//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4581
            rn = "TraceControl2";
4582
//            break;
4583
        case 3:
4584
//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4585
            rn = "UserTraceData";
4586
//            break;
4587
        case 4:
4588
//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4589
            rn = "TraceBPC";
4590
//            break;
4591
        default:
4592
            goto die;
4593
        }
4594
        break;
4595
    case 24:
4596
        switch (sel) {
4597
        case 0:
4598
            /* EJTAG support */
4599
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4600
            tcg_gen_ext32s_tl(arg, arg);
4601
            rn = "DEPC";
4602
            break;
4603
        default:
4604
            goto die;
4605
        }
4606
        break;
4607
    case 25:
4608
        switch (sel) {
4609
        case 0:
4610
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4611
            rn = "Performance0";
4612
            break;
4613
        case 1:
4614
//            gen_helper_mfc0_performance1(arg);
4615
            rn = "Performance1";
4616
//            break;
4617
        case 2:
4618
//            gen_helper_mfc0_performance2(arg);
4619
            rn = "Performance2";
4620
//            break;
4621
        case 3:
4622
//            gen_helper_mfc0_performance3(arg);
4623
            rn = "Performance3";
4624
//            break;
4625
        case 4:
4626
//            gen_helper_mfc0_performance4(arg);
4627
            rn = "Performance4";
4628
//            break;
4629
        case 5:
4630
//            gen_helper_mfc0_performance5(arg);
4631
            rn = "Performance5";
4632
//            break;
4633
        case 6:
4634
//            gen_helper_mfc0_performance6(arg);
4635
            rn = "Performance6";
4636
//            break;
4637
        case 7:
4638
//            gen_helper_mfc0_performance7(arg);
4639
            rn = "Performance7";
4640
//            break;
4641
        default:
4642
            goto die;
4643
        }
4644
        break;
4645
    case 26:
4646
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4647
        rn = "ECC";
4648
        break;
4649
    case 27:
4650
        switch (sel) {
4651
        case 0 ... 3:
4652
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4653
            rn = "CacheErr";
4654
            break;
4655
        default:
4656
            goto die;
4657
        }
4658
        break;
4659
    case 28:
4660
        switch (sel) {
4661
        case 0:
4662
        case 2:
4663
        case 4:
4664
        case 6:
4665
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4666
            rn = "TagLo";
4667
            break;
4668
        case 1:
4669
        case 3:
4670
        case 5:
4671
        case 7:
4672
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4673
            rn = "DataLo";
4674
            break;
4675
        default:
4676
            goto die;
4677
        }
4678
        break;
4679
    case 29:
4680
        switch (sel) {
4681
        case 0:
4682
        case 2:
4683
        case 4:
4684
        case 6:
4685
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4686
            rn = "TagHi";
4687
            break;
4688
        case 1:
4689
        case 3:
4690
        case 5:
4691
        case 7:
4692
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4693
            rn = "DataHi";
4694
            break;
4695
        default:
4696
            goto die;
4697
        }
4698
        break;
4699
    case 30:
4700
        switch (sel) {
4701
        case 0:
4702
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4703
            tcg_gen_ext32s_tl(arg, arg);
4704
            rn = "ErrorEPC";
4705
            break;
4706
        default:
4707
            goto die;
4708
        }
4709
        break;
4710
    case 31:
4711
        switch (sel) {
4712
        case 0:
4713
            /* EJTAG support */
4714
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4715
            rn = "DESAVE";
4716
            break;
4717
        default:
4718
            goto die;
4719
        }
4720
        break;
4721
    default:
4722
       goto die;
4723
    }
4724
    (void)rn; /* avoid a compiler warning */
4725
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4726
    return;
4727

    
4728
die:
4729
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4730
    generate_exception(ctx, EXCP_RI);
4731
}
4732

    
4733
static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4734
{
4735
    const char *rn = "invalid";
4736

    
4737
    if (sel != 0)
4738
        check_insn(env, ctx, ISA_MIPS32);
4739

    
4740
    if (use_icount)
4741
        gen_io_start();
4742

    
4743
    switch (reg) {
4744
    case 0:
4745
        switch (sel) {
4746
        case 0:
4747
            gen_helper_mtc0_index(cpu_env, arg);
4748
            rn = "Index";
4749
            break;
4750
        case 1:
4751
            check_insn(env, ctx, ASE_MT);
4752
            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4753
            rn = "MVPControl";
4754
            break;
4755
        case 2:
4756
            check_insn(env, ctx, ASE_MT);
4757
            /* ignored */
4758
            rn = "MVPConf0";
4759
            break;
4760
        case 3:
4761
            check_insn(env, ctx, ASE_MT);
4762
            /* ignored */
4763
            rn = "MVPConf1";
4764
            break;
4765
        default:
4766
            goto die;
4767
        }
4768
        break;
4769
    case 1:
4770
        switch (sel) {
4771
        case 0:
4772
            /* ignored */
4773
            rn = "Random";
4774
            break;
4775
        case 1:
4776
            check_insn(env, ctx, ASE_MT);
4777
            gen_helper_mtc0_vpecontrol(cpu_env, arg);
4778
            rn = "VPEControl";
4779
            break;
4780
        case 2:
4781
            check_insn(env, ctx, ASE_MT);
4782
            gen_helper_mtc0_vpeconf0(cpu_env, arg);
4783
            rn = "VPEConf0";
4784
            break;
4785
        case 3:
4786
            check_insn(env, ctx, ASE_MT);
4787
            gen_helper_mtc0_vpeconf1(cpu_env, arg);
4788
            rn = "VPEConf1";
4789
            break;
4790
        case 4:
4791
            check_insn(env, ctx, ASE_MT);
4792
            gen_helper_mtc0_yqmask(cpu_env, arg);
4793
            rn = "YQMask";
4794
            break;
4795
        case 5:
4796
            check_insn(env, ctx, ASE_MT);
4797
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4798
            rn = "VPESchedule";
4799
            break;
4800
        case 6:
4801
            check_insn(env, ctx, ASE_MT);
4802
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4803
            rn = "VPEScheFBack";
4804
            break;
4805
        case 7:
4806
            check_insn(env, ctx, ASE_MT);
4807
            gen_helper_mtc0_vpeopt(cpu_env, arg);
4808
            rn = "VPEOpt";
4809
            break;
4810
        default:
4811
            goto die;
4812
        }
4813
        break;
4814
    case 2:
4815
        switch (sel) {
4816
        case 0:
4817
            gen_helper_mtc0_entrylo0(cpu_env, arg);
4818
            rn = "EntryLo0";
4819
            break;
4820
        case 1:
4821
            check_insn(env, ctx, ASE_MT);
4822
            gen_helper_mtc0_tcstatus(cpu_env, arg);
4823
            rn = "TCStatus";
4824
            break;
4825
        case 2:
4826
            check_insn(env, ctx, ASE_MT);
4827
            gen_helper_mtc0_tcbind(cpu_env, arg);
4828
            rn = "TCBind";
4829
            break;
4830
        case 3:
4831
            check_insn(env, ctx, ASE_MT);
4832
            gen_helper_mtc0_tcrestart(cpu_env, arg);
4833
            rn = "TCRestart";
4834
            break;
4835
        case 4:
4836
            check_insn(env, ctx, ASE_MT);
4837
            gen_helper_mtc0_tchalt(cpu_env, arg);
4838
            rn = "TCHalt";
4839
            break;
4840
        case 5:
4841
            check_insn(env, ctx, ASE_MT);
4842
            gen_helper_mtc0_tccontext(cpu_env, arg);
4843
            rn = "TCContext";
4844
            break;
4845
        case 6:
4846
            check_insn(env, ctx, ASE_MT);
4847
            gen_helper_mtc0_tcschedule(cpu_env, arg);
4848
            rn = "TCSchedule";
4849
            break;
4850
        case 7:
4851
            check_insn(env, ctx, ASE_MT);
4852
            gen_helper_mtc0_tcschefback(cpu_env, arg);
4853
            rn = "TCScheFBack";
4854
            break;
4855
        default:
4856
            goto die;
4857
        }
4858
        break;
4859
    case 3:
4860
        switch (sel) {
4861
        case 0:
4862
            gen_helper_mtc0_entrylo1(cpu_env, arg);
4863
            rn = "EntryLo1";
4864
            break;
4865
        default:
4866
            goto die;
4867
        }
4868
        break;
4869
    case 4:
4870
        switch (sel) {
4871
        case 0:
4872
            gen_helper_mtc0_context(cpu_env, arg);
4873
            rn = "Context";
4874
            break;
4875
        case 1:
4876
//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4877
            rn = "ContextConfig";
4878
//            break;
4879
        default:
4880
            goto die;
4881
        }
4882
        break;
4883
    case 5:
4884
        switch (sel) {
4885
        case 0:
4886
            gen_helper_mtc0_pagemask(cpu_env, arg);
4887
            rn = "PageMask";
4888
            break;
4889
        case 1:
4890
            check_insn(env, ctx, ISA_MIPS32R2);
4891
            gen_helper_mtc0_pagegrain(cpu_env, arg);
4892
            rn = "PageGrain";
4893
            break;
4894
        default:
4895
            goto die;
4896
        }
4897
        break;
4898
    case 6:
4899
        switch (sel) {
4900
        case 0:
4901
            gen_helper_mtc0_wired(cpu_env, arg);
4902
            rn = "Wired";
4903
            break;
4904
        case 1:
4905
            check_insn(env, ctx, ISA_MIPS32R2);
4906
            gen_helper_mtc0_srsconf0(cpu_env, arg);
4907
            rn = "SRSConf0";
4908
            break;
4909
        case 2:
4910
            check_insn(env, ctx, ISA_MIPS32R2);
4911
            gen_helper_mtc0_srsconf1(cpu_env, arg);
4912
            rn = "SRSConf1";
4913
            break;
4914
        case 3:
4915
            check_insn(env, ctx, ISA_MIPS32R2);
4916
            gen_helper_mtc0_srsconf2(cpu_env, arg);
4917
            rn = "SRSConf2";
4918
            break;
4919
        case 4:
4920
            check_insn(env, ctx, ISA_MIPS32R2);
4921
            gen_helper_mtc0_srsconf3(cpu_env, arg);
4922
            rn = "SRSConf3";
4923
            break;
4924
        case 5:
4925
            check_insn(env, ctx, ISA_MIPS32R2);
4926
            gen_helper_mtc0_srsconf4(cpu_env, arg);
4927
            rn = "SRSConf4";
4928
            break;
4929
        default:
4930
            goto die;
4931
        }
4932
        break;
4933
    case 7:
4934
        switch (sel) {
4935
        case 0:
4936
            check_insn(env, ctx, ISA_MIPS32R2);
4937
            gen_helper_mtc0_hwrena(cpu_env, arg);
4938
            rn = "HWREna";
4939
            break;
4940
        default:
4941
            goto die;
4942
        }
4943
        break;
4944
    case 8:
4945
        /* ignored */
4946
        rn = "BadVAddr";
4947
        break;
4948
    case 9:
4949
        switch (sel) {
4950
        case 0:
4951
            gen_helper_mtc0_count(cpu_env, arg);
4952
            rn = "Count";
4953
            break;
4954
        /* 6,7 are implementation dependent */
4955
        default:
4956
            goto die;
4957
        }
4958
        break;
4959
    case 10:
4960
        switch (sel) {
4961
        case 0:
4962
            gen_helper_mtc0_entryhi(cpu_env, arg);
4963
            rn = "EntryHi";
4964
            break;
4965
        default:
4966
            goto die;
4967
        }
4968
        break;
4969
    case 11:
4970
        switch (sel) {
4971
        case 0:
4972
            gen_helper_mtc0_compare(cpu_env, arg);
4973
            rn = "Compare";
4974
            break;
4975
        /* 6,7 are implementation dependent */
4976
        default:
4977
            goto die;
4978
        }
4979
        break;
4980
    case 12:
4981
        switch (sel) {
4982
        case 0:
4983
            save_cpu_state(ctx, 1);
4984
            gen_helper_mtc0_status(cpu_env, arg);
4985
            /* BS_STOP isn't good enough here, hflags may have changed. */
4986
            gen_save_pc(ctx->pc + 4);
4987
            ctx->bstate = BS_EXCP;
4988
            rn = "Status";
4989
            break;
4990
        case 1:
4991
            check_insn(env, ctx, ISA_MIPS32R2);
4992
            gen_helper_mtc0_intctl(cpu_env, arg);
4993
            /* Stop translation as we may have switched the execution mode */
4994
            ctx->bstate = BS_STOP;
4995
            rn = "IntCtl";
4996
            break;
4997
        case 2:
4998
            check_insn(env, ctx, ISA_MIPS32R2);
4999
            gen_helper_mtc0_srsctl(cpu_env, arg);
5000
            /* Stop translation as we may have switched the execution mode */
5001
            ctx->bstate = BS_STOP;
5002
            rn = "SRSCtl";
5003
            break;
5004
        case 3:
5005
            check_insn(env, ctx, ISA_MIPS32R2);
5006
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5007
            /* Stop translation as we may have switched the execution mode */
5008
            ctx->bstate = BS_STOP;
5009
            rn = "SRSMap";
5010
            break;
5011
        default:
5012
            goto die;
5013
        }
5014
        break;
5015
    case 13:
5016
        switch (sel) {
5017
        case 0:
5018
            save_cpu_state(ctx, 1);
5019
            gen_helper_mtc0_cause(cpu_env, arg);
5020
            rn = "Cause";
5021
            break;
5022
        default:
5023
            goto die;
5024
        }
5025
        break;
5026
    case 14:
5027
        switch (sel) {
5028
        case 0:
5029
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5030
            rn = "EPC";
5031
            break;
5032
        default:
5033
            goto die;
5034
        }
5035
        break;
5036
    case 15:
5037
        switch (sel) {
5038
        case 0:
5039
            /* ignored */
5040
            rn = "PRid";
5041
            break;
5042
        case 1:
5043
            check_insn(env, ctx, ISA_MIPS32R2);
5044
            gen_helper_mtc0_ebase(cpu_env, arg);
5045
            rn = "EBase";
5046
            break;
5047
        default:
5048
            goto die;
5049
        }
5050
        break;
5051
    case 16:
5052
        switch (sel) {
5053
        case 0:
5054
            gen_helper_mtc0_config0(cpu_env, arg);
5055
            rn = "Config";
5056
            /* Stop translation as we may have switched the execution mode */
5057
            ctx->bstate = BS_STOP;
5058
            break;
5059
        case 1:
5060
            /* ignored, read only */
5061
            rn = "Config1";
5062
            break;
5063
        case 2:
5064
            gen_helper_mtc0_config2(cpu_env, arg);
5065
            rn = "Config2";
5066
            /* Stop translation as we may have switched the execution mode */
5067
            ctx->bstate = BS_STOP;
5068
            break;
5069
        case 3:
5070
            /* ignored, read only */
5071
            rn = "Config3";
5072
            break;
5073
        /* 4,5 are reserved */
5074
        /* 6,7 are implementation dependent */
5075
        case 6:
5076
            /* ignored */
5077
            rn = "Config6";
5078
            break;
5079
        case 7:
5080
            /* ignored */
5081
            rn = "Config7";
5082
            break;
5083
        default:
5084
            rn = "Invalid config selector";
5085
            goto die;
5086
        }
5087
        break;
5088
    case 17:
5089
        switch (sel) {
5090
        case 0:
5091
            gen_helper_mtc0_lladdr(cpu_env, arg);
5092
            rn = "LLAddr";
5093
            break;
5094
        default:
5095
            goto die;
5096
        }
5097
        break;
5098
    case 18:
5099
        switch (sel) {
5100
        case 0 ... 7:
5101
            gen_helper_0e1i(mtc0_watchlo, arg, sel);
5102
            rn = "WatchLo";
5103
            break;
5104
        default:
5105
            goto die;
5106
        }
5107
        break;
5108
    case 19:
5109
        switch (sel) {
5110
        case 0 ... 7:
5111
            gen_helper_0e1i(mtc0_watchhi, arg, sel);
5112
            rn = "WatchHi";
5113
            break;
5114
        default:
5115
            goto die;
5116
        }
5117
        break;
5118
    case 20:
5119
        switch (sel) {
5120
        case 0:
5121
#if defined(TARGET_MIPS64)
5122
            check_insn(env, ctx, ISA_MIPS3);
5123
            gen_helper_mtc0_xcontext(cpu_env, arg);
5124
            rn = "XContext";
5125
            break;
5126
#endif
5127
        default:
5128
            goto die;
5129
        }
5130
        break;
5131
    case 21:
5132
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5133
        switch (sel) {
5134
        case 0:
5135
            gen_helper_mtc0_framemask(cpu_env, arg);
5136
            rn = "Framemask";
5137
            break;
5138
        default:
5139
            goto die;
5140
        }
5141
        break;
5142
    case 22:
5143
        /* ignored */
5144
        rn = "Diagnostic"; /* implementation dependent */
5145
        break;
5146
    case 23:
5147
        switch (sel) {
5148
        case 0:
5149
            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5150
            /* BS_STOP isn't good enough here, hflags may have changed. */
5151
            gen_save_pc(ctx->pc + 4);
5152
            ctx->bstate = BS_EXCP;
5153
            rn = "Debug";
5154
            break;
5155
        case 1:
5156
//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5157
            rn = "TraceControl";
5158
            /* Stop translation as we may have switched the execution mode */
5159
            ctx->bstate = BS_STOP;
5160
//            break;
5161
        case 2:
5162
//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5163
            rn = "TraceControl2";
5164
            /* Stop translation as we may have switched the execution mode */
5165
            ctx->bstate = BS_STOP;
5166
//            break;
5167
        case 3:
5168
            /* Stop translation as we may have switched the execution mode */
5169
            ctx->bstate = BS_STOP;
5170
//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5171
            rn = "UserTraceData";
5172
            /* Stop translation as we may have switched the execution mode */
5173
            ctx->bstate = BS_STOP;
5174
//            break;
5175
        case 4:
5176
//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5177
            /* Stop translation as we may have switched the execution mode */
5178
            ctx->bstate = BS_STOP;
5179
            rn = "TraceBPC";
5180
//            break;
5181
        default:
5182
            goto die;
5183
        }
5184
        break;
5185
    case 24:
5186
        switch (sel) {
5187
        case 0:
5188
            /* EJTAG support */
5189
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5190
            rn = "DEPC";
5191
            break;
5192
        default:
5193
            goto die;
5194
        }
5195
        break;
5196
    case 25:
5197
        switch (sel) {
5198
        case 0:
5199
            gen_helper_mtc0_performance0(cpu_env, arg);
5200
            rn = "Performance0";
5201
            break;
5202
        case 1:
5203
//            gen_helper_mtc0_performance1(arg);
5204
            rn = "Performance1";
5205
//            break;
5206
        case 2:
5207
//            gen_helper_mtc0_performance2(arg);
5208
            rn = "Performance2";
5209
//            break;
5210
        case 3:
5211
//            gen_helper_mtc0_performance3(arg);
5212
            rn = "Performance3";
5213
//            break;
5214
        case 4:
5215
//            gen_helper_mtc0_performance4(arg);
5216
            rn = "Performance4";
5217
//            break;
5218
        case 5:
5219
//            gen_helper_mtc0_performance5(arg);
5220
            rn = "Performance5";
5221
//            break;
5222
        case 6:
5223
//            gen_helper_mtc0_performance6(arg);
5224
            rn = "Performance6";
5225
//            break;
5226
        case 7:
5227
//            gen_helper_mtc0_performance7(arg);
5228
            rn = "Performance7";
5229
//            break;
5230
        default:
5231
            goto die;
5232
        }
5233
       break;
5234
    case 26:
5235
        /* ignored */
5236
        rn = "ECC";
5237
        break;
5238
    case 27:
5239
        switch (sel) {
5240
        case 0 ... 3:
5241
            /* ignored */
5242
            rn = "CacheErr";
5243
            break;
5244
        default:
5245
            goto die;
5246
        }
5247
       break;
5248
    case 28:
5249
        switch (sel) {
5250
        case 0:
5251
        case 2:
5252
        case 4:
5253
        case 6:
5254
            gen_helper_mtc0_taglo(cpu_env, arg);
5255
            rn = "TagLo";
5256
            break;
5257
        case 1:
5258
        case 3:
5259
        case 5:
5260
        case 7:
5261
            gen_helper_mtc0_datalo(cpu_env, arg);
5262
            rn = "DataLo";
5263
            break;
5264
        default:
5265
            goto die;
5266
        }
5267
        break;
5268
    case 29:
5269
        switch (sel) {
5270
        case 0:
5271
        case 2:
5272
        case 4:
5273
        case 6:
5274
            gen_helper_mtc0_taghi(cpu_env, arg);
5275
            rn = "TagHi";
5276
            break;
5277
        case 1:
5278
        case 3:
5279
        case 5:
5280
        case 7:
5281
            gen_helper_mtc0_datahi(cpu_env, arg);
5282
            rn = "DataHi";
5283
            break;
5284
        default:
5285
            rn = "invalid sel";
5286
            goto die;
5287
        }
5288
       break;
5289
    case 30:
5290
        switch (sel) {
5291
        case 0:
5292
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5293
            rn = "ErrorEPC";
5294
            break;
5295
        default:
5296
            goto die;
5297
        }
5298
        break;
5299
    case 31:
5300
        switch (sel) {
5301
        case 0:
5302
            /* EJTAG support */
5303
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5304
            rn = "DESAVE";
5305
            break;
5306
        default:
5307
            goto die;
5308
        }
5309
        /* Stop translation as we may have switched the execution mode */
5310
        ctx->bstate = BS_STOP;
5311
        break;
5312
    default:
5313
       goto die;
5314
    }
5315
    (void)rn; /* avoid a compiler warning */
5316
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5317
    /* For simplicity assume that all writes can cause interrupts.  */
5318
    if (use_icount) {
5319
        gen_io_end();
5320
        ctx->bstate = BS_STOP;
5321
    }
5322
    return;
5323

    
5324
die:
5325
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5326
    generate_exception(ctx, EXCP_RI);
5327
}
5328

    
5329
#if defined(TARGET_MIPS64)
5330
static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5331
{
5332
    const char *rn = "invalid";
5333

    
5334
    if (sel != 0)
5335
        check_insn(env, ctx, ISA_MIPS64);
5336

    
5337
    switch (reg) {
5338
    case 0:
5339
        switch (sel) {
5340
        case 0:
5341
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5342
            rn = "Index";
5343
            break;
5344
        case 1:
5345
            check_insn(env, ctx, ASE_MT);
5346
            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5347
            rn = "MVPControl";
5348
            break;
5349
        case 2:
5350
            check_insn(env, ctx, ASE_MT);
5351
            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5352
            rn = "MVPConf0";
5353
            break;
5354
        case 3:
5355
            check_insn(env, ctx, ASE_MT);
5356
            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5357
            rn = "MVPConf1";
5358
            break;
5359
        default:
5360
            goto die;
5361
        }
5362
        break;
5363
    case 1:
5364
        switch (sel) {
5365
        case 0:
5366
            gen_helper_mfc0_random(arg, cpu_env);
5367
            rn = "Random";
5368
            break;
5369
        case 1:
5370
            check_insn(env, ctx, ASE_MT);
5371
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5372
            rn = "VPEControl";
5373
            break;
5374
        case 2:
5375
            check_insn(env, ctx, ASE_MT);
5376
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5377
            rn = "VPEConf0";
5378
            break;
5379
        case 3:
5380
            check_insn(env, ctx, ASE_MT);
5381
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5382
            rn = "VPEConf1";
5383
            break;
5384
        case 4:
5385
            check_insn(env, ctx, ASE_MT);
5386
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5387
            rn = "YQMask";
5388
            break;
5389
        case 5:
5390
            check_insn(env, ctx, ASE_MT);
5391
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5392
            rn = "VPESchedule";
5393
            break;
5394
        case 6:
5395
            check_insn(env, ctx, ASE_MT);
5396
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5397
            rn = "VPEScheFBack";
5398
            break;
5399
        case 7:
5400
            check_insn(env, ctx, ASE_MT);
5401
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5402
            rn = "VPEOpt";
5403
            break;
5404
        default:
5405
            goto die;
5406
        }
5407
        break;
5408
    case 2:
5409
        switch (sel) {
5410
        case 0:
5411
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5412
            rn = "EntryLo0";
5413
            break;
5414
        case 1:
5415
            check_insn(env, ctx, ASE_MT);
5416
            gen_helper_mfc0_tcstatus(arg, cpu_env);
5417
            rn = "TCStatus";
5418
            break;
5419
        case 2:
5420
            check_insn(env, ctx, ASE_MT);
5421
            gen_helper_mfc0_tcbind(arg, cpu_env);
5422
            rn = "TCBind";
5423
            break;
5424
        case 3:
5425
            check_insn(env, ctx, ASE_MT);
5426
            gen_helper_dmfc0_tcrestart(arg, cpu_env);
5427
            rn = "TCRestart";
5428
            break;
5429
        case 4:
5430
            check_insn(env, ctx, ASE_MT);
5431
            gen_helper_dmfc0_tchalt(arg, cpu_env);
5432
            rn = "TCHalt";
5433
            break;
5434
        case 5:
5435
            check_insn(env, ctx, ASE_MT);
5436
            gen_helper_dmfc0_tccontext(arg, cpu_env);
5437
            rn = "TCContext";
5438
            break;
5439
        case 6:
5440
            check_insn(env, ctx, ASE_MT);
5441
            gen_helper_dmfc0_tcschedule(arg, cpu_env);
5442
            rn = "TCSchedule";
5443
            break;
5444
        case 7:
5445
            check_insn(env, ctx, ASE_MT);
5446
            gen_helper_dmfc0_tcschefback(arg, cpu_env);
5447
            rn = "TCScheFBack";
5448
            break;
5449
        default:
5450
            goto die;
5451
        }
5452
        break;
5453
    case 3:
5454
        switch (sel) {
5455
        case 0:
5456
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5457
            rn = "EntryLo1";
5458
            break;
5459
        default:
5460
            goto die;
5461
        }
5462
        break;
5463
    case 4:
5464
        switch (sel) {
5465
        case 0:
5466
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5467
            rn = "Context";
5468
            break;
5469
        case 1:
5470
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5471
            rn = "ContextConfig";
5472
//            break;
5473
        default:
5474
            goto die;
5475
        }
5476
        break;
5477
    case 5:
5478
        switch (sel) {
5479
        case 0:
5480
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5481
            rn = "PageMask";
5482
            break;
5483
        case 1:
5484
            check_insn(env, ctx, ISA_MIPS32R2);
5485
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5486
            rn = "PageGrain";
5487
            break;
5488
        default:
5489
            goto die;
5490
        }
5491
        break;
5492
    case 6:
5493
        switch (sel) {
5494
        case 0:
5495
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5496
            rn = "Wired";
5497
            break;
5498
        case 1:
5499
            check_insn(env, ctx, ISA_MIPS32R2);
5500
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5501
            rn = "SRSConf0";
5502
            break;
5503
        case 2:
5504
            check_insn(env, ctx, ISA_MIPS32R2);
5505
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5506
            rn = "SRSConf1";
5507
            break;
5508
        case 3:
5509
            check_insn(env, ctx, ISA_MIPS32R2);
5510
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5511
            rn = "SRSConf2";
5512
            break;
5513
        case 4:
5514
            check_insn(env, ctx, ISA_MIPS32R2);
5515
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5516
            rn = "SRSConf3";
5517
            break;
5518
        case 5:
5519
            check_insn(env, ctx, ISA_MIPS32R2);
5520
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5521
            rn = "SRSConf4";
5522
            break;
5523
        default:
5524
            goto die;
5525
        }
5526
        break;
5527
    case 7:
5528
        switch (sel) {
5529
        case 0:
5530
            check_insn(env, ctx, ISA_MIPS32R2);
5531
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5532
            rn = "HWREna";
5533
            break;
5534
        default:
5535
            goto die;
5536
        }
5537
        break;
5538
    case 8:
5539
        switch (sel) {
5540
        case 0:
5541
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5542
            rn = "BadVAddr";
5543
            break;
5544
        default:
5545
            goto die;
5546
        }
5547
        break;
5548
    case 9:
5549
        switch (sel) {
5550
        case 0:
5551
            /* Mark as an IO operation because we read the time.  */
5552
            if (use_icount)
5553
                gen_io_start();
5554
            gen_helper_mfc0_count(arg, cpu_env);
5555
            if (use_icount) {
5556
                gen_io_end();
5557
            }
5558
            /* Break the TB to be able to take timer interrupts immediately
5559
               after reading count.  */
5560
            ctx->bstate = BS_STOP;
5561
            rn = "Count";
5562
            break;
5563
        /* 6,7 are implementation dependent */
5564
        default:
5565
            goto die;
5566
        }
5567
        break;
5568
    case 10:
5569
        switch (sel) {
5570
        case 0:
5571
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5572
            rn = "EntryHi";
5573
            break;
5574
        default:
5575
            goto die;
5576
        }
5577
        break;
5578
    case 11:
5579
        switch (sel) {
5580
        case 0:
5581
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5582
            rn = "Compare";
5583
            break;
5584
        /* 6,7 are implementation dependent */
5585
        default:
5586
            goto die;
5587
        }
5588
        break;
5589
    case 12:
5590
        switch (sel) {
5591
        case 0:
5592
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5593
            rn = "Status";
5594
            break;
5595
        case 1:
5596
            check_insn(env, ctx, ISA_MIPS32R2);
5597
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5598
            rn = "IntCtl";
5599
            break;
5600
        case 2:
5601
            check_insn(env, ctx, ISA_MIPS32R2);
5602
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5603
            rn = "SRSCtl";
5604
            break;
5605
        case 3:
5606
            check_insn(env, ctx, ISA_MIPS32R2);
5607
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5608
            rn = "SRSMap";
5609
            break;
5610
        default:
5611
            goto die;
5612
        }
5613
        break;
5614
    case 13:
5615
        switch (sel) {
5616
        case 0:
5617
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5618
            rn = "Cause";
5619
            break;
5620
        default:
5621
            goto die;
5622
        }
5623
        break;
5624
    case 14:
5625
        switch (sel) {
5626
        case 0:
5627
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5628
            rn = "EPC";
5629
            break;
5630
        default:
5631
            goto die;
5632
        }
5633
        break;
5634
    case 15:
5635
        switch (sel) {
5636
        case 0:
5637
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5638
            rn = "PRid";
5639
            break;
5640
        case 1:
5641
            check_insn(env, ctx, ISA_MIPS32R2);
5642
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5643
            rn = "EBase";
5644
            break;
5645
        default:
5646
            goto die;
5647
        }
5648
        break;
5649
    case 16:
5650
        switch (sel) {
5651
        case 0:
5652
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5653
            rn = "Config";
5654
            break;
5655
        case 1:
5656
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5657
            rn = "Config1";
5658
            break;
5659
        case 2:
5660
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5661
            rn = "Config2";
5662
            break;
5663
        case 3:
5664
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5665
            rn = "Config3";
5666
            break;
5667
       /* 6,7 are implementation dependent */
5668
        case 6:
5669
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5670
            rn = "Config6";
5671
            break;
5672
        case 7:
5673
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5674
            rn = "Config7";
5675
            break;
5676
        default:
5677
            goto die;
5678
        }
5679
        break;
5680
    case 17:
5681
        switch (sel) {
5682
        case 0:
5683
            gen_helper_dmfc0_lladdr(arg, cpu_env);
5684
            rn = "LLAddr";
5685
            break;
5686
        default:
5687
            goto die;
5688
        }
5689
        break;
5690
    case 18:
5691
        switch (sel) {
5692
        case 0 ... 7:
5693
            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5694
            rn = "WatchLo";
5695
            break;
5696
        default:
5697
            goto die;
5698
        }
5699
        break;
5700
    case 19:
5701
        switch (sel) {
5702
        case 0 ... 7:
5703
            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5704
            rn = "WatchHi";
5705
            break;
5706
        default:
5707
            goto die;
5708
        }
5709
        break;
5710
    case 20:
5711
        switch (sel) {
5712
        case 0:
5713
            check_insn(env, ctx, ISA_MIPS3);
5714
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5715
            rn = "XContext";
5716
            break;
5717
        default:
5718
            goto die;
5719
        }
5720
        break;
5721
    case 21:
5722
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5723
        switch (sel) {
5724
        case 0:
5725
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5726
            rn = "Framemask";
5727
            break;
5728
        default:
5729
            goto die;
5730
        }
5731
        break;
5732
    case 22:
5733
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5734
        rn = "'Diagnostic"; /* implementation dependent */
5735
        break;
5736
    case 23:
5737
        switch (sel) {
5738
        case 0:
5739
            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5740
            rn = "Debug";
5741
            break;
5742
        case 1:
5743
//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5744
            rn = "TraceControl";
5745
//            break;
5746
        case 2:
5747
//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5748
            rn = "TraceControl2";
5749
//            break;
5750
        case 3:
5751
//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5752
            rn = "UserTraceData";
5753
//            break;
5754
        case 4:
5755
//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5756
            rn = "TraceBPC";
5757
//            break;
5758
        default:
5759
            goto die;
5760
        }
5761
        break;
5762
    case 24:
5763
        switch (sel) {
5764
        case 0:
5765
            /* EJTAG support */
5766
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5767
            rn = "DEPC";
5768
            break;
5769
        default:
5770
            goto die;
5771
        }
5772
        break;
5773
    case 25:
5774
        switch (sel) {
5775
        case 0:
5776
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5777
            rn = "Performance0";
5778
            break;
5779
        case 1:
5780
//            gen_helper_dmfc0_performance1(arg);
5781
            rn = "Performance1";
5782
//            break;
5783
        case 2:
5784
//            gen_helper_dmfc0_performance2(arg);
5785
            rn = "Performance2";
5786
//            break;
5787
        case 3:
5788
//            gen_helper_dmfc0_performance3(arg);
5789
            rn = "Performance3";
5790
//            break;
5791
        case 4:
5792
//            gen_helper_dmfc0_performance4(arg);
5793
            rn = "Performance4";
5794
//            break;
5795
        case 5:
5796
//            gen_helper_dmfc0_performance5(arg);
5797
            rn = "Performance5";
5798
//            break;
5799
        case 6:
5800
//            gen_helper_dmfc0_performance6(arg);
5801
            rn = "Performance6";
5802
//            break;
5803
        case 7:
5804
//            gen_helper_dmfc0_performance7(arg);
5805
            rn = "Performance7";
5806
//            break;
5807
        default:
5808
            goto die;
5809
        }
5810
        break;
5811
    case 26:
5812
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5813
        rn = "ECC";
5814
        break;
5815
    case 27:
5816
        switch (sel) {
5817
        /* ignored */
5818
        case 0 ... 3:
5819
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5820
            rn = "CacheErr";
5821
            break;
5822
        default:
5823
            goto die;
5824
        }
5825
        break;
5826
    case 28:
5827
        switch (sel) {
5828
        case 0:
5829
        case 2:
5830
        case 4:
5831
        case 6:
5832
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5833
            rn = "TagLo";
5834
            break;
5835
        case 1:
5836
        case 3:
5837
        case 5:
5838
        case 7:
5839
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5840
            rn = "DataLo";
5841
            break;
5842
        default:
5843
            goto die;
5844
        }
5845
        break;
5846
    case 29:
5847
        switch (sel) {
5848
        case 0:
5849
        case 2:
5850
        case 4:
5851
        case 6:
5852
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5853
            rn = "TagHi";
5854
            break;
5855
        case 1:
5856
        case 3:
5857
        case 5:
5858
        case 7:
5859
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5860
            rn = "DataHi";
5861
            break;
5862
        default:
5863
            goto die;
5864
        }
5865
        break;
5866
    case 30:
5867
        switch (sel) {
5868
        case 0:
5869
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5870
            rn = "ErrorEPC";
5871
            break;
5872
        default:
5873
            goto die;
5874
        }
5875
        break;
5876
    case 31:
5877
        switch (sel) {
5878
        case 0:
5879
            /* EJTAG support */
5880
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5881
            rn = "DESAVE";
5882
            break;
5883
        default:
5884
            goto die;
5885
        }
5886
        break;
5887
    default:
5888
        goto die;
5889
    }
5890
    (void)rn; /* avoid a compiler warning */
5891
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5892
    return;
5893

    
5894
die:
5895
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5896
    generate_exception(ctx, EXCP_RI);
5897
}
5898

    
5899
static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5900
{
5901
    const char *rn = "invalid";
5902

    
5903
    if (sel != 0)
5904
        check_insn(env, ctx, ISA_MIPS64);
5905

    
5906
    if (use_icount)
5907
        gen_io_start();
5908

    
5909
    switch (reg) {
5910
    case 0:
5911
        switch (sel) {
5912
        case 0:
5913
            gen_helper_mtc0_index(cpu_env, arg);
5914
            rn = "Index";
5915
            break;
5916
        case 1:
5917
            check_insn(env, ctx, ASE_MT);
5918
            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5919
            rn = "MVPControl";
5920
            break;
5921
        case 2:
5922
            check_insn(env, ctx, ASE_MT);
5923
            /* ignored */
5924
            rn = "MVPConf0";
5925
            break;
5926
        case 3:
5927
            check_insn(env, ctx, ASE_MT);
5928
            /* ignored */
5929
            rn = "MVPConf1";
5930
            break;
5931
        default:
5932
            goto die;
5933
        }
5934
        break;
5935
    case 1:
5936
        switch (sel) {
5937
        case 0:
5938
            /* ignored */
5939
            rn = "Random";
5940
            break;
5941
        case 1:
5942
            check_insn(env, ctx, ASE_MT);
5943
            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5944
            rn = "VPEControl";
5945
            break;
5946
        case 2:
5947
            check_insn(env, ctx, ASE_MT);
5948
            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5949
            rn = "VPEConf0";
5950
            break;
5951
        case 3:
5952
            check_insn(env, ctx, ASE_MT);
5953
            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5954
            rn = "VPEConf1";
5955
            break;
5956
        case 4:
5957
            check_insn(env, ctx, ASE_MT);
5958
            gen_helper_mtc0_yqmask(cpu_env, arg);
5959
            rn = "YQMask";
5960
            break;
5961
        case 5:
5962
            check_insn(env, ctx, ASE_MT);
5963
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5964
            rn = "VPESchedule";
5965
            break;
5966
        case 6:
5967
            check_insn(env, ctx, ASE_MT);
5968
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5969
            rn = "VPEScheFBack";
5970
            break;
5971
        case 7:
5972
            check_insn(env, ctx, ASE_MT);
5973
            gen_helper_mtc0_vpeopt(cpu_env, arg);
5974
            rn = "VPEOpt";
5975
            break;
5976
        default:
5977
            goto die;
5978
        }
5979
        break;
5980
    case 2:
5981
        switch (sel) {
5982
        case 0:
5983
            gen_helper_mtc0_entrylo0(cpu_env, arg);
5984
            rn = "EntryLo0";
5985
            break;
5986
        case 1:
5987
            check_insn(env, ctx, ASE_MT);
5988
            gen_helper_mtc0_tcstatus(cpu_env, arg);
5989
            rn = "TCStatus";
5990
            break;
5991
        case 2:
5992
            check_insn(env, ctx, ASE_MT);
5993
            gen_helper_mtc0_tcbind(cpu_env, arg);
5994
            rn = "TCBind";
5995
            break;
5996
        case 3:
5997
            check_insn(env, ctx, ASE_MT);
5998
            gen_helper_mtc0_tcrestart(cpu_env, arg);
5999
            rn = "TCRestart";
6000
            break;
6001
        case 4:
6002
            check_insn(env, ctx, ASE_MT);
6003
            gen_helper_mtc0_tchalt(cpu_env, arg);
6004
            rn = "TCHalt";
6005
            break;
6006
        case 5:
6007
            check_insn(env, ctx, ASE_MT);
6008
            gen_helper_mtc0_tccontext(cpu_env, arg);
6009
            rn = "TCContext";
6010
            break;
6011
        case 6:
6012
            check_insn(env, ctx, ASE_MT);
6013
            gen_helper_mtc0_tcschedule(cpu_env, arg);
6014
            rn = "TCSchedule";
6015
            break;
6016
        case 7:
6017
            check_insn(env, ctx, ASE_MT);
6018
            gen_helper_mtc0_tcschefback(cpu_env, arg);
6019
            rn = "TCScheFBack";
6020
            break;
6021
        default:
6022
            goto die;
6023
        }
6024
        break;
6025
    case 3:
6026
        switch (sel) {
6027
        case 0:
6028
            gen_helper_mtc0_entrylo1(cpu_env, arg);
6029
            rn = "EntryLo1";
6030
            break;
6031
        default:
6032
            goto die;
6033
        }
6034
        break;
6035
    case 4:
6036
        switch (sel) {
6037
        case 0:
6038
            gen_helper_mtc0_context(cpu_env, arg);
6039
            rn = "Context";
6040
            break;
6041
        case 1:
6042
//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6043
            rn = "ContextConfig";
6044
//           break;
6045
        default:
6046
            goto die;
6047
        }
6048
        break;
6049
    case 5:
6050
        switch (sel) {
6051
        case 0:
6052
            gen_helper_mtc0_pagemask(cpu_env, arg);
6053
            rn = "PageMask";
6054
            break;
6055
        case 1:
6056
            check_insn(env, ctx, ISA_MIPS32R2);
6057
            gen_helper_mtc0_pagegrain(cpu_env, arg);
6058
            rn = "PageGrain";
6059
            break;
6060
        default:
6061
            goto die;
6062
        }
6063
        break;
6064
    case 6:
6065
        switch (sel) {
6066
        case 0:
6067
            gen_helper_mtc0_wired(cpu_env, arg);
6068
            rn = "Wired";
6069
            break;
6070
        case 1:
6071
            check_insn(env, ctx, ISA_MIPS32R2);
6072
            gen_helper_mtc0_srsconf0(cpu_env, arg);
6073
            rn = "SRSConf0";
6074
            break;
6075
        case 2:
6076
            check_insn(env, ctx, ISA_MIPS32R2);
6077
            gen_helper_mtc0_srsconf1(cpu_env, arg);
6078
            rn = "SRSConf1";
6079
            break;
6080
        case 3:
6081
            check_insn(env, ctx, ISA_MIPS32R2);
6082
            gen_helper_mtc0_srsconf2(cpu_env, arg);
6083
            rn = "SRSConf2";
6084
            break;
6085
        case 4:
6086
            check_insn(env, ctx, ISA_MIPS32R2);
6087
            gen_helper_mtc0_srsconf3(cpu_env, arg);
6088
            rn = "SRSConf3";
6089
            break;
6090
        case 5:
6091
            check_insn(env, ctx, ISA_MIPS32R2);
6092
            gen_helper_mtc0_srsconf4(cpu_env, arg);
6093
            rn = "SRSConf4";
6094
            break;
6095
        default:
6096
            goto die;
6097
        }
6098
        break;
6099
    case 7:
6100
        switch (sel) {
6101
        case 0:
6102
            check_insn(env, ctx, ISA_MIPS32R2);
6103
            gen_helper_mtc0_hwrena(cpu_env, arg);
6104
            rn = "HWREna";
6105
            break;
6106
        default:
6107
            goto die;
6108
        }
6109
        break;
6110
    case 8:
6111
        /* ignored */
6112
        rn = "BadVAddr";
6113
        break;
6114
    case 9:
6115
        switch (sel) {
6116
        case 0:
6117
            gen_helper_mtc0_count(cpu_env, arg);
6118
            rn = "Count";
6119
            break;
6120
        /* 6,7 are implementation dependent */
6121
        default:
6122
            goto die;
6123
        }
6124
        /* Stop translation as we may have switched the execution mode */
6125
        ctx->bstate = BS_STOP;
6126
        break;
6127
    case 10:
6128
        switch (sel) {
6129
        case 0:
6130
            gen_helper_mtc0_entryhi(cpu_env, arg);
6131
            rn = "EntryHi";
6132
            break;
6133
        default:
6134
            goto die;
6135
        }
6136
        break;
6137
    case 11:
6138
        switch (sel) {
6139
        case 0:
6140
            gen_helper_mtc0_compare(cpu_env, arg);
6141
            rn = "Compare";
6142
            break;
6143
        /* 6,7 are implementation dependent */
6144
        default:
6145
            goto die;
6146
        }
6147
        /* Stop translation as we may have switched the execution mode */
6148
        ctx->bstate = BS_STOP;
6149
        break;
6150
    case 12:
6151
        switch (sel) {
6152
        case 0:
6153
            save_cpu_state(ctx, 1);
6154
            gen_helper_mtc0_status(cpu_env, arg);
6155
            /* BS_STOP isn't good enough here, hflags may have changed. */
6156
            gen_save_pc(ctx->pc + 4);
6157
            ctx->bstate = BS_EXCP;
6158
            rn = "Status";
6159
            break;
6160
        case 1:
6161
            check_insn(env, ctx, ISA_MIPS32R2);
6162
            gen_helper_mtc0_intctl(cpu_env, arg);
6163
            /* Stop translation as we may have switched the execution mode */
6164
            ctx->bstate = BS_STOP;
6165
            rn = "IntCtl";
6166
            break;
6167
        case 2:
6168
            check_insn(env, ctx, ISA_MIPS32R2);
6169
            gen_helper_mtc0_srsctl(cpu_env, arg);
6170
            /* Stop translation as we may have switched the execution mode */
6171
            ctx->bstate = BS_STOP;
6172
            rn = "SRSCtl";
6173
            break;
6174
        case 3:
6175
            check_insn(env, ctx, ISA_MIPS32R2);
6176
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6177
            /* Stop translation as we may have switched the execution mode */
6178
            ctx->bstate = BS_STOP;
6179
            rn = "SRSMap";
6180
            break;
6181
        default:
6182
            goto die;
6183
        }
6184
        break;
6185
    case 13:
6186
        switch (sel) {
6187
        case 0:
6188
            save_cpu_state(ctx, 1);
6189
            /* Mark as an IO operation because we may trigger a software
6190
               interrupt.  */
6191
            if (use_icount) {
6192
                gen_io_start();
6193
            }
6194
            gen_helper_mtc0_cause(cpu_env, arg);
6195
            if (use_icount) {
6196
                gen_io_end();
6197
            }
6198
            /* Stop translation as we may have triggered an intetrupt */
6199
            ctx->bstate = BS_STOP;
6200
            rn = "Cause";
6201
            break;
6202
        default:
6203
            goto die;
6204
        }
6205
        break;
6206
    case 14:
6207
        switch (sel) {
6208
        case 0:
6209
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6210
            rn = "EPC";
6211
            break;
6212
        default:
6213
            goto die;
6214
        }
6215
        break;
6216
    case 15:
6217
        switch (sel) {
6218
        case 0:
6219
            /* ignored */
6220
            rn = "PRid";
6221
            break;
6222
        case 1:
6223
            check_insn(env, ctx, ISA_MIPS32R2);
6224
            gen_helper_mtc0_ebase(cpu_env, arg);
6225
            rn = "EBase";
6226
            break;
6227
        default:
6228
            goto die;
6229
        }
6230
        break;
6231
    case 16:
6232
        switch (sel) {
6233
        case 0:
6234
            gen_helper_mtc0_config0(cpu_env, arg);
6235
            rn = "Config";
6236
            /* Stop translation as we may have switched the execution mode */
6237
            ctx->bstate = BS_STOP;
6238
            break;
6239
        case 1:
6240
            /* ignored, read only */
6241
            rn = "Config1";
6242
            break;
6243
        case 2:
6244
            gen_helper_mtc0_config2(cpu_env, arg);
6245
            rn = "Config2";
6246
            /* Stop translation as we may have switched the execution mode */
6247
            ctx->bstate = BS_STOP;
6248
            break;
6249
        case 3:
6250
            /* ignored */
6251
            rn = "Config3";
6252
            break;
6253
        /* 6,7 are implementation dependent */
6254
        default:
6255
            rn = "Invalid config selector";
6256
            goto die;
6257
        }
6258
        break;
6259
    case 17:
6260
        switch (sel) {
6261
        case 0:
6262
            gen_helper_mtc0_lladdr(cpu_env, arg);
6263
            rn = "LLAddr";
6264
            break;
6265
        default:
6266
            goto die;
6267
        }
6268
        break;
6269
    case 18:
6270
        switch (sel) {
6271
        case 0 ... 7:
6272
            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6273
            rn = "WatchLo";
6274
            break;
6275
        default:
6276
            goto die;
6277
        }
6278
        break;
6279
    case 19:
6280
        switch (sel) {
6281
        case 0 ... 7:
6282
            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6283
            rn = "WatchHi";
6284
            break;
6285
        default:
6286
            goto die;
6287
        }
6288
        break;
6289
    case 20:
6290
        switch (sel) {
6291
        case 0:
6292
            check_insn(env, ctx, ISA_MIPS3);
6293
            gen_helper_mtc0_xcontext(cpu_env, arg);
6294
            rn = "XContext";
6295
            break;
6296
        default:
6297
            goto die;
6298
        }
6299
        break;
6300
    case 21:
6301
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6302
        switch (sel) {
6303
        case 0:
6304
            gen_helper_mtc0_framemask(cpu_env, arg);
6305
            rn = "Framemask";
6306
            break;
6307
        default:
6308
            goto die;
6309
        }
6310
        break;
6311
    case 22:
6312
        /* ignored */
6313
        rn = "Diagnostic"; /* implementation dependent */
6314
        break;
6315
    case 23:
6316
        switch (sel) {
6317
        case 0:
6318
            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6319
            /* BS_STOP isn't good enough here, hflags may have changed. */
6320
            gen_save_pc(ctx->pc + 4);
6321
            ctx->bstate = BS_EXCP;
6322
            rn = "Debug";
6323
            break;
6324
        case 1:
6325
//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6326
            /* Stop translation as we may have switched the execution mode */
6327
            ctx->bstate = BS_STOP;
6328
            rn = "TraceControl";
6329
//            break;
6330
        case 2:
6331
//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6332
            /* Stop translation as we may have switched the execution mode */
6333
            ctx->bstate = BS_STOP;
6334
            rn = "TraceControl2";
6335
//            break;
6336
        case 3:
6337
//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6338
            /* Stop translation as we may have switched the execution mode */
6339
            ctx->bstate = BS_STOP;
6340
            rn = "UserTraceData";
6341
//            break;
6342
        case 4:
6343
//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6344
            /* Stop translation as we may have switched the execution mode */
6345
            ctx->bstate = BS_STOP;
6346
            rn = "TraceBPC";
6347
//            break;
6348
        default:
6349
            goto die;
6350
        }
6351
        break;
6352
    case 24:
6353
        switch (sel) {
6354
        case 0:
6355
            /* EJTAG support */
6356
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6357
            rn = "DEPC";
6358
            break;
6359
        default:
6360
            goto die;
6361
        }
6362
        break;
6363
    case 25:
6364
        switch (sel) {
6365
        case 0:
6366
            gen_helper_mtc0_performance0(cpu_env, arg);
6367
            rn = "Performance0";
6368
            break;
6369
        case 1:
6370
//            gen_helper_mtc0_performance1(cpu_env, arg);
6371
            rn = "Performance1";
6372
//            break;
6373
        case 2:
6374
//            gen_helper_mtc0_performance2(cpu_env, arg);
6375
            rn = "Performance2";
6376
//            break;
6377
        case 3:
6378
//            gen_helper_mtc0_performance3(cpu_env, arg);
6379
            rn = "Performance3";
6380
//            break;
6381
        case 4:
6382
//            gen_helper_mtc0_performance4(cpu_env, arg);
6383
            rn = "Performance4";
6384
//            break;
6385
        case 5:
6386
//            gen_helper_mtc0_performance5(cpu_env, arg);
6387
            rn = "Performance5";
6388
//            break;
6389
        case 6:
6390
//            gen_helper_mtc0_performance6(cpu_env, arg);
6391
            rn = "Performance6";
6392
//            break;
6393
        case 7:
6394
//            gen_helper_mtc0_performance7(cpu_env, arg);
6395
            rn = "Performance7";
6396
//            break;
6397
        default:
6398
            goto die;
6399
        }
6400
        break;
6401
    case 26:
6402
        /* ignored */
6403
        rn = "ECC";
6404
        break;
6405
    case 27:
6406
        switch (sel) {
6407
        case 0 ... 3:
6408
            /* ignored */
6409
            rn = "CacheErr";
6410
            break;
6411
        default:
6412
            goto die;
6413
        }
6414
        break;
6415
    case 28:
6416
        switch (sel) {
6417
        case 0:
6418
        case 2:
6419
        case 4:
6420
        case 6:
6421
            gen_helper_mtc0_taglo(cpu_env, arg);
6422
            rn = "TagLo";
6423
            break;
6424
        case 1:
6425
        case 3:
6426
        case 5:
6427
        case 7:
6428
            gen_helper_mtc0_datalo(cpu_env, arg);
6429
            rn = "DataLo";
6430
            break;
6431
        default:
6432
            goto die;
6433
        }
6434
        break;
6435
    case 29:
6436
        switch (sel) {
6437
        case 0:
6438
        case 2:
6439
        case 4:
6440
        case 6:
6441
            gen_helper_mtc0_taghi(cpu_env, arg);
6442
            rn = "TagHi";
6443
            break;
6444
        case 1:
6445
        case 3:
6446
        case 5:
6447
        case 7:
6448
            gen_helper_mtc0_datahi(cpu_env, arg);
6449
            rn = "DataHi";
6450
            break;
6451
        default:
6452
            rn = "invalid sel";
6453
            goto die;
6454
        }
6455
        break;
6456
    case 30:
6457
        switch (sel) {
6458
        case 0:
6459
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6460
            rn = "ErrorEPC";
6461
            break;
6462
        default:
6463
            goto die;
6464
        }
6465
        break;
6466
    case 31:
6467
        switch (sel) {
6468
        case 0:
6469
            /* EJTAG support */
6470
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6471
            rn = "DESAVE";
6472
            break;
6473
        default:
6474
            goto die;
6475
        }
6476
        /* Stop translation as we may have switched the execution mode */
6477
        ctx->bstate = BS_STOP;
6478
        break;
6479
    default:
6480
        goto die;
6481
    }
6482
    (void)rn; /* avoid a compiler warning */
6483
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6484
    /* For simplicity assume that all writes can cause interrupts.  */
6485
    if (use_icount) {
6486
        gen_io_end();
6487
        ctx->bstate = BS_STOP;
6488
    }
6489
    return;
6490

    
6491
die:
6492
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6493
    generate_exception(ctx, EXCP_RI);
6494
}
6495
#endif /* TARGET_MIPS64 */
6496

    
6497
static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6498
                     int u, int sel, int h)
6499
{
6500
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6501
    TCGv t0 = tcg_temp_local_new();
6502

    
6503
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6504
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6505
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6506
        tcg_gen_movi_tl(t0, -1);
6507
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6508
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6509
        tcg_gen_movi_tl(t0, -1);
6510
    else if (u == 0) {
6511
        switch (rt) {
6512
        case 1:
6513
            switch (sel) {
6514
            case 1:
6515
                gen_helper_mftc0_vpecontrol(t0, cpu_env);
6516
                break;
6517
            case 2:
6518
                gen_helper_mftc0_vpeconf0(t0, cpu_env);
6519
                break;
6520
            default:
6521
                goto die;
6522
                break;
6523
            }
6524
            break;
6525
        case 2:
6526
            switch (sel) {
6527
            case 1:
6528
                gen_helper_mftc0_tcstatus(t0, cpu_env);
6529
                break;
6530
            case 2:
6531
                gen_helper_mftc0_tcbind(t0, cpu_env);
6532
                break;
6533
            case 3:
6534
                gen_helper_mftc0_tcrestart(t0, cpu_env);
6535
                break;
6536
            case 4:
6537
                gen_helper_mftc0_tchalt(t0, cpu_env);
6538
                break;
6539
            case 5:
6540
                gen_helper_mftc0_tccontext(t0, cpu_env);
6541
                break;
6542
            case 6:
6543
                gen_helper_mftc0_tcschedule(t0, cpu_env);
6544
                break;
6545
            case 7:
6546
                gen_helper_mftc0_tcschefback(t0, cpu_env);
6547
                break;
6548
            default:
6549
                gen_mfc0(env, ctx, t0, rt, sel);
6550
                break;
6551
            }
6552
            break;
6553
        case 10:
6554
            switch (sel) {
6555
            case 0:
6556
                gen_helper_mftc0_entryhi(t0, cpu_env);
6557
                break;
6558
            default:
6559
                gen_mfc0(env, ctx, t0, rt, sel);
6560
                break;
6561
            }
6562
        case 12:
6563
            switch (sel) {
6564
            case 0:
6565
                gen_helper_mftc0_status(t0, cpu_env);
6566
                break;
6567
            default:
6568
                gen_mfc0(env, ctx, t0, rt, sel);
6569
                break;
6570
            }
6571
        case 13:
6572
            switch (sel) {
6573
            case 0:
6574
                gen_helper_mftc0_cause(t0, cpu_env);
6575
                break;
6576
            default:
6577
                goto die;
6578
                break;
6579
            }
6580
            break;
6581
        case 14:
6582
            switch (sel) {
6583
            case 0:
6584
                gen_helper_mftc0_epc(t0, cpu_env);
6585
                break;
6586
            default:
6587
                goto die;
6588
                break;
6589
            }
6590
            break;
6591
        case 15:
6592
            switch (sel) {
6593
            case 1:
6594
                gen_helper_mftc0_ebase(t0, cpu_env);
6595
                break;
6596
            default:
6597
                goto die;
6598
                break;
6599
            }
6600
            break;
6601
        case 16:
6602
            switch (sel) {
6603
            case 0 ... 7:
6604
                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6605
                break;
6606
            default:
6607
                goto die;
6608
                break;
6609
            }
6610
            break;
6611
        case 23:
6612
            switch (sel) {
6613
            case 0:
6614
                gen_helper_mftc0_debug(t0, cpu_env);
6615
                break;
6616
            default:
6617
                gen_mfc0(env, ctx, t0, rt, sel);
6618
                break;
6619
            }
6620
            break;
6621
        default:
6622
            gen_mfc0(env, ctx, t0, rt, sel);
6623
        }
6624
    } else switch (sel) {
6625
    /* GPR registers. */
6626
    case 0:
6627
        gen_helper_1e0i(mftgpr, t0, rt);
6628
        break;
6629
    /* Auxiliary CPU registers */
6630
    case 1:
6631
        switch (rt) {
6632
        case 0:
6633
            gen_helper_1e0i(mftlo, t0, 0);
6634
            break;
6635
        case 1:
6636
            gen_helper_1e0i(mfthi, t0, 0);
6637
            break;
6638
        case 2:
6639
            gen_helper_1e0i(mftacx, t0, 0);
6640
            break;
6641
        case 4:
6642
            gen_helper_1e0i(mftlo, t0, 1);
6643
            break;
6644
        case 5:
6645
            gen_helper_1e0i(mfthi, t0, 1);
6646
            break;
6647
        case 6:
6648
            gen_helper_1e0i(mftacx, t0, 1);
6649
            break;
6650
        case 8:
6651
            gen_helper_1e0i(mftlo, t0, 2);
6652
            break;
6653
        case 9:
6654
            gen_helper_1e0i(mfthi, t0, 2);
6655
            break;
6656
        case 10:
6657
            gen_helper_1e0i(mftacx, t0, 2);
6658
            break;
6659
        case 12:
6660
            gen_helper_1e0i(mftlo, t0, 3);
6661
            break;
6662
        case 13:
6663
            gen_helper_1e0i(mfthi, t0, 3);
6664
            break;
6665
        case 14:
6666
            gen_helper_1e0i(mftacx, t0, 3);
6667
            break;
6668
        case 16:
6669
            gen_helper_mftdsp(t0, cpu_env);
6670
            break;
6671
        default:
6672
            goto die;
6673
        }
6674
        break;
6675
    /* Floating point (COP1). */
6676
    case 2:
6677
        /* XXX: For now we support only a single FPU context. */
6678
        if (h == 0) {
6679
            TCGv_i32 fp0 = tcg_temp_new_i32();
6680

    
6681
            gen_load_fpr32(fp0, rt);
6682
            tcg_gen_ext_i32_tl(t0, fp0);
6683
            tcg_temp_free_i32(fp0);
6684
        } else {
6685
            TCGv_i32 fp0 = tcg_temp_new_i32();
6686

    
6687
            gen_load_fpr32h(fp0, rt);
6688
            tcg_gen_ext_i32_tl(t0, fp0);
6689
            tcg_temp_free_i32(fp0);
6690
        }
6691
        break;
6692
    case 3:
6693
        /* XXX: For now we support only a single FPU context. */
6694
        gen_helper_1e0i(cfc1, t0, rt);
6695
        break;
6696
    /* COP2: Not implemented. */
6697
    case 4:
6698
    case 5:
6699
        /* fall through */
6700
    default:
6701
        goto die;
6702
    }
6703
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6704
    gen_store_gpr(t0, rd);
6705
    tcg_temp_free(t0);
6706
    return;
6707

    
6708
die:
6709
    tcg_temp_free(t0);
6710
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6711
    generate_exception(ctx, EXCP_RI);
6712
}
6713

    
6714
static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6715
                     int u, int sel, int h)
6716
{
6717
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6718
    TCGv t0 = tcg_temp_local_new();
6719

    
6720
    gen_load_gpr(t0, rt);
6721
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6722
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6723
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6724
        /* NOP */ ;
6725
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6726
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6727
        /* NOP */ ;
6728
    else if (u == 0) {
6729
        switch (rd) {
6730
        case 1:
6731
            switch (sel) {
6732
            case 1:
6733
                gen_helper_mttc0_vpecontrol(cpu_env, t0);
6734
                break;
6735
            case 2:
6736
                gen_helper_mttc0_vpeconf0(cpu_env, t0);
6737
                break;
6738
            default:
6739
                goto die;
6740
                break;
6741
            }
6742
            break;
6743
        case 2:
6744
            switch (sel) {
6745
            case 1:
6746
                gen_helper_mttc0_tcstatus(cpu_env, t0);
6747
                break;
6748
            case 2:
6749
                gen_helper_mttc0_tcbind(cpu_env, t0);
6750
                break;
6751
            case 3:
6752
                gen_helper_mttc0_tcrestart(cpu_env, t0);
6753
                break;
6754
            case 4:
6755
                gen_helper_mttc0_tchalt(cpu_env, t0);
6756
                break;
6757
            case 5:
6758
                gen_helper_mttc0_tccontext(cpu_env, t0);
6759
                break;
6760
            case 6:
6761
                gen_helper_mttc0_tcschedule(cpu_env, t0);
6762
                break;
6763
            case 7:
6764
                gen_helper_mttc0_tcschefback(cpu_env, t0);
6765
                break;
6766
            default:
6767
                gen_mtc0(env, ctx, t0, rd, sel);
6768
                break;
6769
            }
6770
            break;
6771
        case 10:
6772
            switch (sel) {
6773
            case 0:
6774
                gen_helper_mttc0_entryhi(cpu_env, t0);
6775
                break;
6776
            default:
6777
                gen_mtc0(env, ctx, t0, rd, sel);
6778
                break;
6779
            }
6780
        case 12:
6781
            switch (sel) {
6782
            case 0:
6783
                gen_helper_mttc0_status(cpu_env, t0);
6784
                break;
6785
            default:
6786
                gen_mtc0(env, ctx, t0, rd, sel);
6787
                break;
6788
            }
6789
        case 13:
6790
            switch (sel) {
6791
            case 0:
6792
                gen_helper_mttc0_cause(cpu_env, t0);
6793
                break;
6794
            default:
6795
                goto die;
6796
                break;
6797
            }
6798
            break;
6799
        case 15:
6800
            switch (sel) {
6801
            case 1:
6802
                gen_helper_mttc0_ebase(cpu_env, t0);
6803
                break;
6804
            default:
6805
                goto die;
6806
                break;
6807
            }
6808
            break;
6809
        case 23:
6810
            switch (sel) {
6811
            case 0:
6812
                gen_helper_mttc0_debug(cpu_env, t0);
6813
                break;
6814
            default:
6815
                gen_mtc0(env, ctx, t0, rd, sel);
6816
                break;
6817
            }
6818
            break;
6819
        default:
6820
            gen_mtc0(env, ctx, t0, rd, sel);
6821
        }
6822
    } else switch (sel) {
6823
    /* GPR registers. */
6824
    case 0:
6825
        gen_helper_0e1i(mttgpr, t0, rd);
6826
        break;
6827
    /* Auxiliary CPU registers */
6828
    case 1:
6829
        switch (rd) {
6830
        case 0:
6831
            gen_helper_0e1i(mttlo, t0, 0);
6832
            break;
6833
        case 1:
6834
            gen_helper_0e1i(mtthi, t0, 0);
6835
            break;
6836
        case 2:
6837
            gen_helper_0e1i(mttacx, t0, 0);
6838
            break;
6839
        case 4:
6840
            gen_helper_0e1i(mttlo, t0, 1);
6841
            break;
6842
        case 5:
6843
            gen_helper_0e1i(mtthi, t0, 1);
6844
            break;
6845
        case 6:
6846
            gen_helper_0e1i(mttacx, t0, 1);
6847
            break;
6848
        case 8:
6849
            gen_helper_0e1i(mttlo, t0, 2);
6850
            break;
6851
        case 9:
6852
            gen_helper_0e1i(mtthi, t0, 2);
6853
            break;
6854
        case 10:
6855
            gen_helper_0e1i(mttacx, t0, 2);
6856
            break;
6857
        case 12:
6858
            gen_helper_0e1i(mttlo, t0, 3);
6859
            break;
6860
        case 13:
6861
            gen_helper_0e1i(mtthi, t0, 3);
6862
            break;
6863
        case 14:
6864
            gen_helper_0e1i(mttacx, t0, 3);
6865
            break;
6866
        case 16:
6867
            gen_helper_mttdsp(cpu_env, t0);
6868
            break;
6869
        default:
6870
            goto die;
6871
        }
6872
        break;
6873
    /* Floating point (COP1). */
6874
    case 2:
6875
        /* XXX: For now we support only a single FPU context. */
6876
        if (h == 0) {
6877
            TCGv_i32 fp0 = tcg_temp_new_i32();
6878

    
6879
            tcg_gen_trunc_tl_i32(fp0, t0);
6880
            gen_store_fpr32(fp0, rd);
6881
            tcg_temp_free_i32(fp0);
6882
        } else {
6883
            TCGv_i32 fp0 = tcg_temp_new_i32();
6884

    
6885
            tcg_gen_trunc_tl_i32(fp0, t0);
6886
            gen_store_fpr32h(fp0, rd);
6887
            tcg_temp_free_i32(fp0);
6888
        }
6889
        break;
6890
    case 3:
6891
        /* XXX: For now we support only a single FPU context. */
6892
        gen_helper_0e1i(ctc1, t0, rd);
6893
        break;
6894
    /* COP2: Not implemented. */
6895
    case 4:
6896
    case 5:
6897
        /* fall through */
6898
    default:
6899
        goto die;
6900
    }
6901
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6902
    tcg_temp_free(t0);
6903
    return;
6904

    
6905
die:
6906
    tcg_temp_free(t0);
6907
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6908
    generate_exception(ctx, EXCP_RI);
6909
}
6910

    
6911
static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6912
{
6913
    const char *opn = "ldst";
6914

    
6915
    check_cp0_enabled(ctx);
6916
    switch (opc) {
6917
    case OPC_MFC0:
6918
        if (rt == 0) {
6919
            /* Treat as NOP. */
6920
            return;
6921
        }
6922
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6923
        opn = "mfc0";
6924
        break;
6925
    case OPC_MTC0:
6926
        {
6927
            TCGv t0 = tcg_temp_new();
6928

    
6929
            gen_load_gpr(t0, rt);
6930
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6931
            tcg_temp_free(t0);
6932
        }
6933
        opn = "mtc0";
6934
        break;
6935
#if defined(TARGET_MIPS64)
6936
    case OPC_DMFC0:
6937
        check_insn(env, ctx, ISA_MIPS3);
6938
        if (rt == 0) {
6939
            /* Treat as NOP. */
6940
            return;
6941
        }
6942
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6943
        opn = "dmfc0";
6944
        break;
6945
    case OPC_DMTC0:
6946
        check_insn(env, ctx, ISA_MIPS3);
6947
        {
6948
            TCGv t0 = tcg_temp_new();
6949

    
6950
            gen_load_gpr(t0, rt);
6951
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6952
            tcg_temp_free(t0);
6953
        }
6954
        opn = "dmtc0";
6955
        break;
6956
#endif
6957
    case OPC_MFTR:
6958
        check_insn(env, ctx, ASE_MT);
6959
        if (rd == 0) {
6960
            /* Treat as NOP. */
6961
            return;
6962
        }
6963
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6964
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6965
        opn = "mftr";
6966
        break;
6967
    case OPC_MTTR:
6968
        check_insn(env, ctx, ASE_MT);
6969
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6970
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6971
        opn = "mttr";
6972
        break;
6973
    case OPC_TLBWI:
6974
        opn = "tlbwi";
6975
        if (!env->tlb->helper_tlbwi)
6976
            goto die;
6977
        gen_helper_tlbwi(cpu_env);
6978
        break;
6979
    case OPC_TLBWR:
6980
        opn = "tlbwr";
6981
        if (!env->tlb->helper_tlbwr)
6982
            goto die;
6983
        gen_helper_tlbwr(cpu_env);
6984
        break;
6985
    case OPC_TLBP:
6986
        opn = "tlbp";
6987
        if (!env->tlb->helper_tlbp)
6988
            goto die;
6989
        gen_helper_tlbp(cpu_env);
6990
        break;
6991
    case OPC_TLBR:
6992
        opn = "tlbr";
6993
        if (!env->tlb->helper_tlbr)
6994
            goto die;
6995
        gen_helper_tlbr(cpu_env);
6996
        break;
6997
    case OPC_ERET:
6998
        opn = "eret";
6999
        check_insn(env, ctx, ISA_MIPS2);
7000
        gen_helper_eret(cpu_env);
7001
        ctx->bstate = BS_EXCP;
7002
        break;
7003
    case OPC_DERET:
7004
        opn = "deret";
7005
        check_insn(env, ctx, ISA_MIPS32);
7006
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7007
            MIPS_INVAL(opn);
7008
            generate_exception(ctx, EXCP_RI);
7009
        } else {
7010
            gen_helper_deret(cpu_env);
7011
            ctx->bstate = BS_EXCP;
7012
        }
7013
        break;
7014
    case OPC_WAIT:
7015
        opn = "wait";
7016
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7017
        /* If we get an exception, we want to restart at next instruction */
7018
        ctx->pc += 4;
7019
        save_cpu_state(ctx, 1);
7020
        ctx->pc -= 4;
7021
        gen_helper_wait(cpu_env);
7022
        ctx->bstate = BS_EXCP;
7023
        break;
7024
    default:
7025
 die:
7026
        MIPS_INVAL(opn);
7027
        generate_exception(ctx, EXCP_RI);
7028
        return;
7029
    }
7030
    (void)opn; /* avoid a compiler warning */
7031
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7032
}
7033
#endif /* !CONFIG_USER_ONLY */
7034

    
7035
/* CP1 Branches (before delay slot) */
7036
static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7037
                                 int32_t cc, int32_t offset)
7038
{
7039
    target_ulong btarget;
7040
    const char *opn = "cp1 cond branch";
7041
    TCGv_i32 t0 = tcg_temp_new_i32();
7042

    
7043
    if (cc != 0)
7044
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7045

    
7046
    btarget = ctx->pc + 4 + offset;
7047

    
7048
    switch (op) {
7049
    case OPC_BC1F:
7050
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7051
        tcg_gen_not_i32(t0, t0);
7052
        tcg_gen_andi_i32(t0, t0, 1);
7053
        tcg_gen_extu_i32_tl(bcond, t0);
7054
        opn = "bc1f";
7055
        goto not_likely;
7056
    case OPC_BC1FL:
7057
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7058
        tcg_gen_not_i32(t0, t0);
7059
        tcg_gen_andi_i32(t0, t0, 1);
7060
        tcg_gen_extu_i32_tl(bcond, t0);
7061
        opn = "bc1fl";
7062
        goto likely;
7063
    case OPC_BC1T:
7064
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7065
        tcg_gen_andi_i32(t0, t0, 1);
7066
        tcg_gen_extu_i32_tl(bcond, t0);
7067
        opn = "bc1t";
7068
        goto not_likely;
7069
    case OPC_BC1TL:
7070
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071
        tcg_gen_andi_i32(t0, t0, 1);
7072
        tcg_gen_extu_i32_tl(bcond, t0);
7073
        opn = "bc1tl";
7074
    likely:
7075
        ctx->hflags |= MIPS_HFLAG_BL;
7076
        break;
7077
    case OPC_BC1FANY2:
7078
        {
7079
            TCGv_i32 t1 = tcg_temp_new_i32();
7080
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7081
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7082
            tcg_gen_nand_i32(t0, t0, t1);
7083
            tcg_temp_free_i32(t1);
7084
            tcg_gen_andi_i32(t0, t0, 1);
7085
            tcg_gen_extu_i32_tl(bcond, t0);
7086
        }
7087
        opn = "bc1any2f";
7088
        goto not_likely;
7089
    case OPC_BC1TANY2:
7090
        {
7091
            TCGv_i32 t1 = tcg_temp_new_i32();
7092
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7093
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7094
            tcg_gen_or_i32(t0, t0, t1);
7095
            tcg_temp_free_i32(t1);
7096
            tcg_gen_andi_i32(t0, t0, 1);
7097
            tcg_gen_extu_i32_tl(bcond, t0);
7098
        }
7099
        opn = "bc1any2t";
7100
        goto not_likely;
7101
    case OPC_BC1FANY4:
7102
        {
7103
            TCGv_i32 t1 = tcg_temp_new_i32();
7104
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7105
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7106
            tcg_gen_and_i32(t0, t0, t1);
7107
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7108
            tcg_gen_and_i32(t0, t0, t1);
7109
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7110
            tcg_gen_nand_i32(t0, t0, t1);
7111
            tcg_temp_free_i32(t1);
7112
            tcg_gen_andi_i32(t0, t0, 1);
7113
            tcg_gen_extu_i32_tl(bcond, t0);
7114
        }
7115
        opn = "bc1any4f";
7116
        goto not_likely;
7117
    case OPC_BC1TANY4:
7118
        {
7119
            TCGv_i32 t1 = tcg_temp_new_i32();
7120
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7121
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7122
            tcg_gen_or_i32(t0, t0, t1);
7123
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7124
            tcg_gen_or_i32(t0, t0, t1);
7125
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7126
            tcg_gen_or_i32(t0, t0, t1);
7127
            tcg_temp_free_i32(t1);
7128
            tcg_gen_andi_i32(t0, t0, 1);
7129
            tcg_gen_extu_i32_tl(bcond, t0);
7130
        }
7131
        opn = "bc1any4t";
7132
    not_likely:
7133
        ctx->hflags |= MIPS_HFLAG_BC;
7134
        break;
7135
    default:
7136
        MIPS_INVAL(opn);
7137
        generate_exception (ctx, EXCP_RI);
7138
        goto out;
7139
    }
7140
    (void)opn; /* avoid a compiler warning */
7141
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7142
               ctx->hflags, btarget);
7143
    ctx->btarget = btarget;
7144

    
7145
 out:
7146
    tcg_temp_free_i32(t0);
7147
}
7148

    
7149
/* Coprocessor 1 (FPU) */
7150

    
7151
#define FOP(func, fmt) (((fmt) << 21) | (func))
7152

    
7153
enum fopcode {
7154
    OPC_ADD_S = FOP(0, FMT_S),
7155
    OPC_SUB_S = FOP(1, FMT_S),
7156
    OPC_MUL_S = FOP(2, FMT_S),
7157
    OPC_DIV_S = FOP(3, FMT_S),
7158
    OPC_SQRT_S = FOP(4, FMT_S),
7159
    OPC_ABS_S = FOP(5, FMT_S),
7160
    OPC_MOV_S = FOP(6, FMT_S),
7161
    OPC_NEG_S = FOP(7, FMT_S),
7162
    OPC_ROUND_L_S = FOP(8, FMT_S),
7163
    OPC_TRUNC_L_S = FOP(9, FMT_S),
7164
    OPC_CEIL_L_S = FOP(10, FMT_S),
7165
    OPC_FLOOR_L_S = FOP(11, FMT_S),
7166
    OPC_ROUND_W_S = FOP(12, FMT_S),
7167
    OPC_TRUNC_W_S = FOP(13, FMT_S),
7168
    OPC_CEIL_W_S = FOP(14, FMT_S),
7169
    OPC_FLOOR_W_S = FOP(15, FMT_S),
7170
    OPC_MOVCF_S = FOP(17, FMT_S),
7171
    OPC_MOVZ_S = FOP(18, FMT_S),
7172
    OPC_MOVN_S = FOP(19, FMT_S),
7173
    OPC_RECIP_S = FOP(21, FMT_S),
7174
    OPC_RSQRT_S = FOP(22, FMT_S),
7175
    OPC_RECIP2_S = FOP(28, FMT_S),
7176
    OPC_RECIP1_S = FOP(29, FMT_S),
7177
    OPC_RSQRT1_S = FOP(30, FMT_S),
7178
    OPC_RSQRT2_S = FOP(31, FMT_S),
7179
    OPC_CVT_D_S = FOP(33, FMT_S),
7180
    OPC_CVT_W_S = FOP(36, FMT_S),
7181
    OPC_CVT_L_S = FOP(37, FMT_S),
7182
    OPC_CVT_PS_S = FOP(38, FMT_S),
7183
    OPC_CMP_F_S = FOP (48, FMT_S),
7184
    OPC_CMP_UN_S = FOP (49, FMT_S),
7185
    OPC_CMP_EQ_S = FOP (50, FMT_S),
7186
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
7187
    OPC_CMP_OLT_S = FOP (52, FMT_S),
7188
    OPC_CMP_ULT_S = FOP (53, FMT_S),
7189
    OPC_CMP_OLE_S = FOP (54, FMT_S),
7190
    OPC_CMP_ULE_S = FOP (55, FMT_S),
7191
    OPC_CMP_SF_S = FOP (56, FMT_S),
7192
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
7193
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
7194
    OPC_CMP_NGL_S = FOP (59, FMT_S),
7195
    OPC_CMP_LT_S = FOP (60, FMT_S),
7196
    OPC_CMP_NGE_S = FOP (61, FMT_S),
7197
    OPC_CMP_LE_S = FOP (62, FMT_S),
7198
    OPC_CMP_NGT_S = FOP (63, FMT_S),
7199

    
7200
    OPC_ADD_D = FOP(0, FMT_D),
7201
    OPC_SUB_D = FOP(1, FMT_D),
7202
    OPC_MUL_D = FOP(2, FMT_D),
7203
    OPC_DIV_D = FOP(3, FMT_D),
7204
    OPC_SQRT_D = FOP(4, FMT_D),
7205
    OPC_ABS_D = FOP(5, FMT_D),
7206
    OPC_MOV_D = FOP(6, FMT_D),
7207
    OPC_NEG_D = FOP(7, FMT_D),
7208
    OPC_ROUND_L_D = FOP(8, FMT_D),
7209
    OPC_TRUNC_L_D = FOP(9, FMT_D),
7210
    OPC_CEIL_L_D = FOP(10, FMT_D),
7211
    OPC_FLOOR_L_D = FOP(11, FMT_D),
7212
    OPC_ROUND_W_D = FOP(12, FMT_D),
7213
    OPC_TRUNC_W_D = FOP(13, FMT_D),
7214
    OPC_CEIL_W_D = FOP(14, FMT_D),
7215
    OPC_FLOOR_W_D = FOP(15, FMT_D),
7216
    OPC_MOVCF_D = FOP(17, FMT_D),
7217
    OPC_MOVZ_D = FOP(18, FMT_D),
7218
    OPC_MOVN_D = FOP(19, FMT_D),
7219
    OPC_RECIP_D = FOP(21, FMT_D),
7220
    OPC_RSQRT_D = FOP(22, FMT_D),
7221
    OPC_RECIP2_D = FOP(28, FMT_D),
7222
    OPC_RECIP1_D = FOP(29, FMT_D),
7223
    OPC_RSQRT1_D = FOP(30, FMT_D),
7224
    OPC_RSQRT2_D = FOP(31, FMT_D),
7225
    OPC_CVT_S_D = FOP(32, FMT_D),
7226
    OPC_CVT_W_D = FOP(36, FMT_D),
7227
    OPC_CVT_L_D = FOP(37, FMT_D),
7228
    OPC_CMP_F_D = FOP (48, FMT_D),
7229
    OPC_CMP_UN_D = FOP (49, FMT_D),
7230
    OPC_CMP_EQ_D = FOP (50, FMT_D),
7231
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
7232
    OPC_CMP_OLT_D = FOP (52, FMT_D),
7233
    OPC_CMP_ULT_D = FOP (53, FMT_D),
7234
    OPC_CMP_OLE_D = FOP (54, FMT_D),
7235
    OPC_CMP_ULE_D = FOP (55, FMT_D),
7236
    OPC_CMP_SF_D = FOP (56, FMT_D),
7237
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
7238
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
7239
    OPC_CMP_NGL_D = FOP (59, FMT_D),
7240
    OPC_CMP_LT_D = FOP (60, FMT_D),
7241
    OPC_CMP_NGE_D = FOP (61, FMT_D),
7242
    OPC_CMP_LE_D = FOP (62, FMT_D),
7243
    OPC_CMP_NGT_D = FOP (63, FMT_D),
7244

    
7245
    OPC_CVT_S_W = FOP(32, FMT_W),
7246
    OPC_CVT_D_W = FOP(33, FMT_W),
7247
    OPC_CVT_S_L = FOP(32, FMT_L),
7248
    OPC_CVT_D_L = FOP(33, FMT_L),
7249
    OPC_CVT_PS_PW = FOP(38, FMT_W),
7250

    
7251
    OPC_ADD_PS = FOP(0, FMT_PS),
7252
    OPC_SUB_PS = FOP(1, FMT_PS),
7253
    OPC_MUL_PS = FOP(2, FMT_PS),
7254
    OPC_DIV_PS = FOP(3, FMT_PS),
7255
    OPC_ABS_PS = FOP(5, FMT_PS),
7256
    OPC_MOV_PS = FOP(6, FMT_PS),
7257
    OPC_NEG_PS = FOP(7, FMT_PS),
7258
    OPC_MOVCF_PS = FOP(17, FMT_PS),
7259
    OPC_MOVZ_PS = FOP(18, FMT_PS),
7260
    OPC_MOVN_PS = FOP(19, FMT_PS),
7261
    OPC_ADDR_PS = FOP(24, FMT_PS),
7262
    OPC_MULR_PS = FOP(26, FMT_PS),
7263
    OPC_RECIP2_PS = FOP(28, FMT_PS),
7264
    OPC_RECIP1_PS = FOP(29, FMT_PS),
7265
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
7266
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
7267

    
7268
    OPC_CVT_S_PU = FOP(32, FMT_PS),
7269
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
7270
    OPC_CVT_S_PL = FOP(40, FMT_PS),
7271
    OPC_PLL_PS = FOP(44, FMT_PS),
7272
    OPC_PLU_PS = FOP(45, FMT_PS),
7273
    OPC_PUL_PS = FOP(46, FMT_PS),
7274
    OPC_PUU_PS = FOP(47, FMT_PS),
7275
    OPC_CMP_F_PS = FOP (48, FMT_PS),
7276
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
7277
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7278
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7279
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7280
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7281
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7282
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7283
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
7284
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7285
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7286
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7287
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
7288
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7289
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
7290
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7291
};
7292

    
7293
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7294
{
7295
    const char *opn = "cp1 move";
7296
    TCGv t0 = tcg_temp_new();
7297

    
7298
    switch (opc) {
7299
    case OPC_MFC1:
7300
        {
7301
            TCGv_i32 fp0 = tcg_temp_new_i32();
7302

    
7303
            gen_load_fpr32(fp0, fs);
7304
            tcg_gen_ext_i32_tl(t0, fp0);
7305
            tcg_temp_free_i32(fp0);
7306
        }
7307
        gen_store_gpr(t0, rt);
7308
        opn = "mfc1";
7309
        break;
7310
    case OPC_MTC1:
7311
        gen_load_gpr(t0, rt);
7312
        {
7313
            TCGv_i32 fp0 = tcg_temp_new_i32();
7314

    
7315
            tcg_gen_trunc_tl_i32(fp0, t0);
7316
            gen_store_fpr32(fp0, fs);
7317
            tcg_temp_free_i32(fp0);
7318
        }
7319
        opn = "mtc1";
7320
        break;
7321
    case OPC_CFC1:
7322
        gen_helper_1e0i(cfc1, t0, fs);
7323
        gen_store_gpr(t0, rt);
7324
        opn = "cfc1";
7325
        break;
7326
    case OPC_CTC1:
7327
        gen_load_gpr(t0, rt);
7328
        gen_helper_0e1i(ctc1, t0, fs);
7329
        opn = "ctc1";
7330
        break;
7331
#if defined(TARGET_MIPS64)
7332
    case OPC_DMFC1:
7333
        gen_load_fpr64(ctx, t0, fs);
7334
        gen_store_gpr(t0, rt);
7335
        opn = "dmfc1";
7336
        break;
7337
    case OPC_DMTC1:
7338
        gen_load_gpr(t0, rt);
7339
        gen_store_fpr64(ctx, t0, fs);
7340
        opn = "dmtc1";
7341
        break;
7342
#endif
7343
    case OPC_MFHC1:
7344
        {
7345
            TCGv_i32 fp0 = tcg_temp_new_i32();
7346

    
7347
            gen_load_fpr32h(fp0, fs);
7348
            tcg_gen_ext_i32_tl(t0, fp0);
7349
            tcg_temp_free_i32(fp0);
7350
        }
7351
        gen_store_gpr(t0, rt);
7352
        opn = "mfhc1";
7353
        break;
7354
    case OPC_MTHC1:
7355
        gen_load_gpr(t0, rt);
7356
        {
7357
            TCGv_i32 fp0 = tcg_temp_new_i32();
7358

    
7359
            tcg_gen_trunc_tl_i32(fp0, t0);
7360
            gen_store_fpr32h(fp0, fs);
7361
            tcg_temp_free_i32(fp0);
7362
        }
7363
        opn = "mthc1";
7364
        break;
7365
    default:
7366
        MIPS_INVAL(opn);
7367
        generate_exception (ctx, EXCP_RI);
7368
        goto out;
7369
    }
7370
    (void)opn; /* avoid a compiler warning */
7371
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7372

    
7373
 out:
7374
    tcg_temp_free(t0);
7375
}
7376

    
7377
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7378
{
7379
    int l1;
7380
    TCGCond cond;
7381
    TCGv_i32 t0;
7382

    
7383
    if (rd == 0) {
7384
        /* Treat as NOP. */
7385
        return;
7386
    }
7387

    
7388
    if (tf)
7389
        cond = TCG_COND_EQ;
7390
    else
7391
        cond = TCG_COND_NE;
7392

    
7393
    l1 = gen_new_label();
7394
    t0 = tcg_temp_new_i32();
7395
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7396
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7397
    tcg_temp_free_i32(t0);
7398
    if (rs == 0) {
7399
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
7400
    } else {
7401
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7402
    }
7403
    gen_set_label(l1);
7404
}
7405

    
7406
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7407
{
7408
    int cond;
7409
    TCGv_i32 t0 = tcg_temp_new_i32();
7410
    int l1 = gen_new_label();
7411

    
7412
    if (tf)
7413
        cond = TCG_COND_EQ;
7414
    else
7415
        cond = TCG_COND_NE;
7416

    
7417
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7418
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7419
    gen_load_fpr32(t0, fs);
7420
    gen_store_fpr32(t0, fd);
7421
    gen_set_label(l1);
7422
    tcg_temp_free_i32(t0);
7423
}
7424

    
7425
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7426
{
7427
    int cond;
7428
    TCGv_i32 t0 = tcg_temp_new_i32();
7429
    TCGv_i64 fp0;
7430
    int l1 = gen_new_label();
7431

    
7432
    if (tf)
7433
        cond = TCG_COND_EQ;
7434
    else
7435
        cond = TCG_COND_NE;
7436

    
7437
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7438
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7439
    tcg_temp_free_i32(t0);
7440
    fp0 = tcg_temp_new_i64();
7441
    gen_load_fpr64(ctx, fp0, fs);
7442
    gen_store_fpr64(ctx, fp0, fd);
7443
    tcg_temp_free_i64(fp0);
7444
    gen_set_label(l1);
7445
}
7446

    
7447
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7448
{
7449
    int cond;
7450
    TCGv_i32 t0 = tcg_temp_new_i32();
7451
    int l1 = gen_new_label();
7452
    int l2 = gen_new_label();
7453

    
7454
    if (tf)
7455
        cond = TCG_COND_EQ;
7456
    else
7457
        cond = TCG_COND_NE;
7458

    
7459
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7460
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7461
    gen_load_fpr32(t0, fs);
7462
    gen_store_fpr32(t0, fd);
7463
    gen_set_label(l1);
7464

    
7465
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7466
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
7467
    gen_load_fpr32h(t0, fs);
7468
    gen_store_fpr32h(t0, fd);
7469
    tcg_temp_free_i32(t0);
7470
    gen_set_label(l2);
7471
}
7472

    
7473

    
7474
static void gen_farith (DisasContext *ctx, enum fopcode op1,
7475
                        int ft, int fs, int fd, int cc)
7476
{
7477
    const char *opn = "farith";
7478
    const char *condnames[] = {
7479
            "c.f",
7480
            "c.un",
7481
            "c.eq",
7482
            "c.ueq",
7483
            "c.olt",
7484
            "c.ult",
7485
            "c.ole",
7486
            "c.ule",
7487
            "c.sf",
7488
            "c.ngle",
7489
            "c.seq",
7490
            "c.ngl",
7491
            "c.lt",
7492
            "c.nge",
7493
            "c.le",
7494
            "c.ngt",
7495
    };
7496
    const char *condnames_abs[] = {
7497
            "cabs.f",
7498
            "cabs.un",
7499
            "cabs.eq",
7500
            "cabs.ueq",
7501
            "cabs.olt",
7502
            "cabs.ult",
7503
            "cabs.ole",
7504
            "cabs.ule",
7505
            "cabs.sf",
7506
            "cabs.ngle",
7507
            "cabs.seq",
7508
            "cabs.ngl",
7509
            "cabs.lt",
7510
            "cabs.nge",
7511
            "cabs.le",
7512
            "cabs.ngt",
7513
    };
7514
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7515
    uint32_t func = ctx->opcode & 0x3f;
7516

    
7517
    switch (op1) {
7518
    case OPC_ADD_S:
7519
        {
7520
            TCGv_i32 fp0 = tcg_temp_new_i32();
7521
            TCGv_i32 fp1 = tcg_temp_new_i32();
7522

    
7523
            gen_load_fpr32(fp0, fs);
7524
            gen_load_fpr32(fp1, ft);
7525
            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7526
            tcg_temp_free_i32(fp1);
7527
            gen_store_fpr32(fp0, fd);
7528
            tcg_temp_free_i32(fp0);
7529
        }
7530
        opn = "add.s";
7531
        optype = BINOP;
7532
        break;
7533
    case OPC_SUB_S:
7534
        {
7535
            TCGv_i32 fp0 = tcg_temp_new_i32();
7536
            TCGv_i32 fp1 = tcg_temp_new_i32();
7537

    
7538
            gen_load_fpr32(fp0, fs);
7539
            gen_load_fpr32(fp1, ft);
7540
            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7541
            tcg_temp_free_i32(fp1);
7542
            gen_store_fpr32(fp0, fd);
7543
            tcg_temp_free_i32(fp0);
7544
        }
7545
        opn = "sub.s";
7546
        optype = BINOP;
7547
        break;
7548
    case OPC_MUL_S:
7549
        {
7550
            TCGv_i32 fp0 = tcg_temp_new_i32();
7551
            TCGv_i32 fp1 = tcg_temp_new_i32();
7552

    
7553
            gen_load_fpr32(fp0, fs);
7554
            gen_load_fpr32(fp1, ft);
7555
            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7556
            tcg_temp_free_i32(fp1);
7557
            gen_store_fpr32(fp0, fd);
7558
            tcg_temp_free_i32(fp0);
7559
        }
7560
        opn = "mul.s";
7561
        optype = BINOP;
7562
        break;
7563
    case OPC_DIV_S:
7564
        {
7565
            TCGv_i32 fp0 = tcg_temp_new_i32();
7566
            TCGv_i32 fp1 = tcg_temp_new_i32();
7567

    
7568
            gen_load_fpr32(fp0, fs);
7569
            gen_load_fpr32(fp1, ft);
7570
            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7571
            tcg_temp_free_i32(fp1);
7572
            gen_store_fpr32(fp0, fd);
7573
            tcg_temp_free_i32(fp0);
7574
        }
7575
        opn = "div.s";
7576
        optype = BINOP;
7577
        break;
7578
    case OPC_SQRT_S:
7579
        {
7580
            TCGv_i32 fp0 = tcg_temp_new_i32();
7581

    
7582
            gen_load_fpr32(fp0, fs);
7583
            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7584
            gen_store_fpr32(fp0, fd);
7585
            tcg_temp_free_i32(fp0);
7586
        }
7587
        opn = "sqrt.s";
7588
        break;
7589
    case OPC_ABS_S:
7590
        {
7591
            TCGv_i32 fp0 = tcg_temp_new_i32();
7592

    
7593
            gen_load_fpr32(fp0, fs);
7594
            gen_helper_float_abs_s(fp0, fp0);
7595
            gen_store_fpr32(fp0, fd);
7596
            tcg_temp_free_i32(fp0);
7597
        }
7598
        opn = "abs.s";
7599
        break;
7600
    case OPC_MOV_S:
7601
        {
7602
            TCGv_i32 fp0 = tcg_temp_new_i32();
7603

    
7604
            gen_load_fpr32(fp0, fs);
7605
            gen_store_fpr32(fp0, fd);
7606
            tcg_temp_free_i32(fp0);
7607
        }
7608
        opn = "mov.s";
7609
        break;
7610
    case OPC_NEG_S:
7611
        {
7612
            TCGv_i32 fp0 = tcg_temp_new_i32();
7613

    
7614
            gen_load_fpr32(fp0, fs);
7615
            gen_helper_float_chs_s(fp0, fp0);
7616
            gen_store_fpr32(fp0, fd);
7617
            tcg_temp_free_i32(fp0);
7618
        }
7619
        opn = "neg.s";
7620
        break;
7621
    case OPC_ROUND_L_S:
7622
        check_cp1_64bitmode(ctx);
7623
        {
7624
            TCGv_i32 fp32 = tcg_temp_new_i32();
7625
            TCGv_i64 fp64 = tcg_temp_new_i64();
7626

    
7627
            gen_load_fpr32(fp32, fs);
7628
            gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7629
            tcg_temp_free_i32(fp32);
7630
            gen_store_fpr64(ctx, fp64, fd);
7631
            tcg_temp_free_i64(fp64);
7632
        }
7633
        opn = "round.l.s";
7634
        break;
7635
    case OPC_TRUNC_L_S:
7636
        check_cp1_64bitmode(ctx);
7637
        {
7638
            TCGv_i32 fp32 = tcg_temp_new_i32();
7639
            TCGv_i64 fp64 = tcg_temp_new_i64();
7640

    
7641
            gen_load_fpr32(fp32, fs);
7642
            gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7643
            tcg_temp_free_i32(fp32);
7644
            gen_store_fpr64(ctx, fp64, fd);
7645
            tcg_temp_free_i64(fp64);
7646
        }
7647
        opn = "trunc.l.s";
7648
        break;
7649
    case OPC_CEIL_L_S:
7650
        check_cp1_64bitmode(ctx);
7651
        {
7652
            TCGv_i32 fp32 = tcg_temp_new_i32();
7653
            TCGv_i64 fp64 = tcg_temp_new_i64();
7654

    
7655
            gen_load_fpr32(fp32, fs);
7656
            gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7657
            tcg_temp_free_i32(fp32);
7658
            gen_store_fpr64(ctx, fp64, fd);
7659
            tcg_temp_free_i64(fp64);
7660
        }
7661
        opn = "ceil.l.s";
7662
        break;
7663
    case OPC_FLOOR_L_S:
7664
        check_cp1_64bitmode(ctx);
7665
        {
7666
            TCGv_i32 fp32 = tcg_temp_new_i32();
7667
            TCGv_i64 fp64 = tcg_temp_new_i64();
7668

    
7669
            gen_load_fpr32(fp32, fs);
7670
            gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7671
            tcg_temp_free_i32(fp32);
7672
            gen_store_fpr64(ctx, fp64, fd);
7673
            tcg_temp_free_i64(fp64);
7674
        }
7675
        opn = "floor.l.s";
7676
        break;
7677
    case OPC_ROUND_W_S:
7678
        {
7679
            TCGv_i32 fp0 = tcg_temp_new_i32();
7680

    
7681
            gen_load_fpr32(fp0, fs);
7682
            gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7683
            gen_store_fpr32(fp0, fd);
7684
            tcg_temp_free_i32(fp0);
7685
        }
7686
        opn = "round.w.s";
7687
        break;
7688
    case OPC_TRUNC_W_S:
7689
        {
7690
            TCGv_i32 fp0 = tcg_temp_new_i32();
7691

    
7692
            gen_load_fpr32(fp0, fs);
7693
            gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7694
            gen_store_fpr32(fp0, fd);
7695
            tcg_temp_free_i32(fp0);
7696
        }
7697
        opn = "trunc.w.s";
7698
        break;
7699
    case OPC_CEIL_W_S:
7700
        {
7701
            TCGv_i32 fp0 = tcg_temp_new_i32();
7702

    
7703
            gen_load_fpr32(fp0, fs);
7704
            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7705
            gen_store_fpr32(fp0, fd);
7706
            tcg_temp_free_i32(fp0);
7707
        }
7708
        opn = "ceil.w.s";
7709
        break;
7710
    case OPC_FLOOR_W_S:
7711
        {
7712
            TCGv_i32 fp0 = tcg_temp_new_i32();
7713

    
7714
            gen_load_fpr32(fp0, fs);
7715
            gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7716
            gen_store_fpr32(fp0, fd);
7717
            tcg_temp_free_i32(fp0);
7718
        }
7719
        opn = "floor.w.s";
7720
        break;
7721
    case OPC_MOVCF_S:
7722
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7723
        opn = "movcf.s";
7724
        break;
7725
    case OPC_MOVZ_S:
7726
        {
7727
            int l1 = gen_new_label();
7728
            TCGv_i32 fp0;
7729

    
7730
            if (ft != 0) {
7731
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7732
            }
7733
            fp0 = tcg_temp_new_i32();
7734
            gen_load_fpr32(fp0, fs);
7735
            gen_store_fpr32(fp0, fd);
7736
            tcg_temp_free_i32(fp0);
7737
            gen_set_label(l1);
7738
        }
7739
        opn = "movz.s";
7740
        break;
7741
    case OPC_MOVN_S:
7742
        {
7743
            int l1 = gen_new_label();
7744
            TCGv_i32 fp0;
7745

    
7746
            if (ft != 0) {
7747
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7748
                fp0 = tcg_temp_new_i32();
7749
                gen_load_fpr32(fp0, fs);
7750
                gen_store_fpr32(fp0, fd);
7751
                tcg_temp_free_i32(fp0);
7752
                gen_set_label(l1);
7753
            }
7754
        }
7755
        opn = "movn.s";
7756
        break;
7757
    case OPC_RECIP_S:
7758
        check_cop1x(ctx);
7759
        {
7760
            TCGv_i32 fp0 = tcg_temp_new_i32();
7761

    
7762
            gen_load_fpr32(fp0, fs);
7763
            gen_helper_float_recip_s(fp0, cpu_env, fp0);
7764
            gen_store_fpr32(fp0, fd);
7765
            tcg_temp_free_i32(fp0);
7766
        }
7767
        opn = "recip.s";
7768
        break;
7769
    case OPC_RSQRT_S:
7770
        check_cop1x(ctx);
7771
        {
7772
            TCGv_i32 fp0 = tcg_temp_new_i32();
7773

    
7774
            gen_load_fpr32(fp0, fs);
7775
            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7776
            gen_store_fpr32(fp0, fd);
7777
            tcg_temp_free_i32(fp0);
7778
        }
7779
        opn = "rsqrt.s";
7780
        break;
7781
    case OPC_RECIP2_S:
7782
        check_cp1_64bitmode(ctx);
7783
        {
7784
            TCGv_i32 fp0 = tcg_temp_new_i32();
7785
            TCGv_i32 fp1 = tcg_temp_new_i32();
7786

    
7787
            gen_load_fpr32(fp0, fs);
7788
            gen_load_fpr32(fp1, ft);
7789
            gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7790
            tcg_temp_free_i32(fp1);
7791
            gen_store_fpr32(fp0, fd);
7792
            tcg_temp_free_i32(fp0);
7793
        }
7794
        opn = "recip2.s";
7795
        break;
7796
    case OPC_RECIP1_S:
7797
        check_cp1_64bitmode(ctx);
7798
        {
7799
            TCGv_i32 fp0 = tcg_temp_new_i32();
7800

    
7801
            gen_load_fpr32(fp0, fs);
7802
            gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7803
            gen_store_fpr32(fp0, fd);
7804
            tcg_temp_free_i32(fp0);
7805
        }
7806
        opn = "recip1.s";
7807
        break;
7808
    case OPC_RSQRT1_S:
7809
        check_cp1_64bitmode(ctx);
7810
        {
7811
            TCGv_i32 fp0 = tcg_temp_new_i32();
7812

    
7813
            gen_load_fpr32(fp0, fs);
7814
            gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7815
            gen_store_fpr32(fp0, fd);
7816
            tcg_temp_free_i32(fp0);
7817
        }
7818
        opn = "rsqrt1.s";
7819
        break;
7820
    case OPC_RSQRT2_S:
7821
        check_cp1_64bitmode(ctx);
7822
        {
7823
            TCGv_i32 fp0 = tcg_temp_new_i32();
7824
            TCGv_i32 fp1 = tcg_temp_new_i32();
7825

    
7826
            gen_load_fpr32(fp0, fs);
7827
            gen_load_fpr32(fp1, ft);
7828
            gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7829
            tcg_temp_free_i32(fp1);
7830
            gen_store_fpr32(fp0, fd);
7831
            tcg_temp_free_i32(fp0);
7832
        }
7833
        opn = "rsqrt2.s";
7834
        break;
7835
    case OPC_CVT_D_S:
7836
        check_cp1_registers(ctx, fd);
7837
        {
7838
            TCGv_i32 fp32 = tcg_temp_new_i32();
7839
            TCGv_i64 fp64 = tcg_temp_new_i64();
7840

    
7841
            gen_load_fpr32(fp32, fs);
7842
            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7843
            tcg_temp_free_i32(fp32);
7844
            gen_store_fpr64(ctx, fp64, fd);
7845
            tcg_temp_free_i64(fp64);
7846
        }
7847
        opn = "cvt.d.s";
7848
        break;
7849
    case OPC_CVT_W_S:
7850
        {
7851
            TCGv_i32 fp0 = tcg_temp_new_i32();
7852

    
7853
            gen_load_fpr32(fp0, fs);
7854
            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7855
            gen_store_fpr32(fp0, fd);
7856
            tcg_temp_free_i32(fp0);
7857
        }
7858
        opn = "cvt.w.s";
7859
        break;
7860
    case OPC_CVT_L_S:
7861
        check_cp1_64bitmode(ctx);
7862
        {
7863
            TCGv_i32 fp32 = tcg_temp_new_i32();
7864
            TCGv_i64 fp64 = tcg_temp_new_i64();
7865

    
7866
            gen_load_fpr32(fp32, fs);
7867
            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7868
            tcg_temp_free_i32(fp32);
7869
            gen_store_fpr64(ctx, fp64, fd);
7870
            tcg_temp_free_i64(fp64);
7871
        }
7872
        opn = "cvt.l.s";
7873
        break;
7874
    case OPC_CVT_PS_S:
7875
        check_cp1_64bitmode(ctx);
7876
        {
7877
            TCGv_i64 fp64 = tcg_temp_new_i64();
7878
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
7879
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
7880

    
7881
            gen_load_fpr32(fp32_0, fs);
7882
            gen_load_fpr32(fp32_1, ft);
7883
            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7884
            tcg_temp_free_i32(fp32_1);
7885
            tcg_temp_free_i32(fp32_0);
7886
            gen_store_fpr64(ctx, fp64, fd);
7887
            tcg_temp_free_i64(fp64);
7888
        }
7889
        opn = "cvt.ps.s";
7890
        break;
7891
    case OPC_CMP_F_S:
7892
    case OPC_CMP_UN_S:
7893
    case OPC_CMP_EQ_S:
7894
    case OPC_CMP_UEQ_S:
7895
    case OPC_CMP_OLT_S:
7896
    case OPC_CMP_ULT_S:
7897
    case OPC_CMP_OLE_S:
7898
    case OPC_CMP_ULE_S:
7899
    case OPC_CMP_SF_S:
7900
    case OPC_CMP_NGLE_S:
7901
    case OPC_CMP_SEQ_S:
7902
    case OPC_CMP_NGL_S:
7903
    case OPC_CMP_LT_S:
7904
    case OPC_CMP_NGE_S:
7905
    case OPC_CMP_LE_S:
7906
    case OPC_CMP_NGT_S:
7907
        if (ctx->opcode & (1 << 6)) {
7908
            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7909
            opn = condnames_abs[func-48];
7910
        } else {
7911
            gen_cmp_s(ctx, func-48, ft, fs, cc);
7912
            opn = condnames[func-48];
7913
        }
7914
        break;
7915
    case OPC_ADD_D:
7916
        check_cp1_registers(ctx, fs | ft | fd);
7917
        {
7918
            TCGv_i64 fp0 = tcg_temp_new_i64();
7919
            TCGv_i64 fp1 = tcg_temp_new_i64();
7920

    
7921
            gen_load_fpr64(ctx, fp0, fs);
7922
            gen_load_fpr64(ctx, fp1, ft);
7923
            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7924
            tcg_temp_free_i64(fp1);
7925
            gen_store_fpr64(ctx, fp0, fd);
7926
            tcg_temp_free_i64(fp0);
7927
        }
7928
        opn = "add.d";
7929
        optype = BINOP;
7930
        break;
7931
    case OPC_SUB_D:
7932
        check_cp1_registers(ctx, fs | ft | fd);
7933
        {
7934
            TCGv_i64 fp0 = tcg_temp_new_i64();
7935
            TCGv_i64 fp1 = tcg_temp_new_i64();
7936

    
7937
            gen_load_fpr64(ctx, fp0, fs);
7938
            gen_load_fpr64(ctx, fp1, ft);
7939
            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7940
            tcg_temp_free_i64(fp1);
7941
            gen_store_fpr64(ctx, fp0, fd);
7942
            tcg_temp_free_i64(fp0);
7943
        }
7944
        opn = "sub.d";
7945
        optype = BINOP;
7946
        break;
7947
    case OPC_MUL_D:
7948
        check_cp1_registers(ctx, fs | ft | fd);
7949
        {
7950
            TCGv_i64 fp0 = tcg_temp_new_i64();
7951
            TCGv_i64 fp1 = tcg_temp_new_i64();
7952

    
7953
            gen_load_fpr64(ctx, fp0, fs);
7954
            gen_load_fpr64(ctx, fp1, ft);
7955
            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7956
            tcg_temp_free_i64(fp1);
7957
            gen_store_fpr64(ctx, fp0, fd);
7958
            tcg_temp_free_i64(fp0);
7959
        }
7960
        opn = "mul.d";
7961
        optype = BINOP;
7962
        break;
7963
    case OPC_DIV_D:
7964
        check_cp1_registers(ctx, fs | ft | fd);
7965
        {
7966
            TCGv_i64 fp0 = tcg_temp_new_i64();
7967
            TCGv_i64 fp1 = tcg_temp_new_i64();
7968

    
7969
            gen_load_fpr64(ctx, fp0, fs);
7970
            gen_load_fpr64(ctx, fp1, ft);
7971
            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7972
            tcg_temp_free_i64(fp1);
7973
            gen_store_fpr64(ctx, fp0, fd);
7974
            tcg_temp_free_i64(fp0);
7975
        }
7976
        opn = "div.d";
7977
        optype = BINOP;
7978
        break;
7979
    case OPC_SQRT_D:
7980
        check_cp1_registers(ctx, fs | fd);
7981
        {
7982
            TCGv_i64 fp0 = tcg_temp_new_i64();
7983

    
7984
            gen_load_fpr64(ctx, fp0, fs);
7985
            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7986
            gen_store_fpr64(ctx, fp0, fd);
7987
            tcg_temp_free_i64(fp0);
7988
        }
7989
        opn = "sqrt.d";
7990
        break;
7991
    case OPC_ABS_D:
7992
        check_cp1_registers(ctx, fs | fd);
7993
        {
7994
            TCGv_i64 fp0 = tcg_temp_new_i64();
7995

    
7996
            gen_load_fpr64(ctx, fp0, fs);
7997
            gen_helper_float_abs_d(fp0, fp0);
7998
            gen_store_fpr64(ctx, fp0, fd);
7999
            tcg_temp_free_i64(fp0);
8000
        }
8001
        opn = "abs.d";
8002
        break;
8003
    case OPC_MOV_D:
8004
        check_cp1_registers(ctx, fs | fd);
8005
        {
8006
            TCGv_i64 fp0 = tcg_temp_new_i64();
8007

    
8008
            gen_load_fpr64(ctx, fp0, fs);
8009
            gen_store_fpr64(ctx, fp0, fd);
8010
            tcg_temp_free_i64(fp0);
8011
        }
8012
        opn = "mov.d";
8013
        break;
8014
    case OPC_NEG_D:
8015
        check_cp1_registers(ctx, fs | fd);
8016
        {
8017
            TCGv_i64 fp0 = tcg_temp_new_i64();
8018

    
8019
            gen_load_fpr64(ctx, fp0, fs);
8020
            gen_helper_float_chs_d(fp0, fp0);
8021
            gen_store_fpr64(ctx, fp0, fd);
8022
            tcg_temp_free_i64(fp0);
8023
        }
8024
        opn = "neg.d";
8025
        break;
8026
    case OPC_ROUND_L_D:
8027
        check_cp1_64bitmode(ctx);
8028
        {
8029
            TCGv_i64 fp0 = tcg_temp_new_i64();
8030

    
8031
            gen_load_fpr64(ctx, fp0, fs);
8032
            gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8033
            gen_store_fpr64(ctx, fp0, fd);
8034
            tcg_temp_free_i64(fp0);
8035
        }
8036
        opn = "round.l.d";
8037
        break;
8038
    case OPC_TRUNC_L_D:
8039
        check_cp1_64bitmode(ctx);
8040
        {
8041
            TCGv_i64 fp0 = tcg_temp_new_i64();
8042

    
8043
            gen_load_fpr64(ctx, fp0, fs);
8044
            gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8045
            gen_store_fpr64(ctx, fp0, fd);
8046
            tcg_temp_free_i64(fp0);
8047
        }
8048
        opn = "trunc.l.d";
8049
        break;
8050
    case OPC_CEIL_L_D:
8051
        check_cp1_64bitmode(ctx);
8052
        {
8053
            TCGv_i64 fp0 = tcg_temp_new_i64();
8054

    
8055
            gen_load_fpr64(ctx, fp0, fs);
8056
            gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8057
            gen_store_fpr64(ctx, fp0, fd);
8058
            tcg_temp_free_i64(fp0);
8059
        }
8060
        opn = "ceil.l.d";
8061
        break;
8062
    case OPC_FLOOR_L_D:
8063
        check_cp1_64bitmode(ctx);
8064
        {
8065
            TCGv_i64 fp0 = tcg_temp_new_i64();
8066

    
8067
            gen_load_fpr64(ctx, fp0, fs);
8068
            gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8069
            gen_store_fpr64(ctx, fp0, fd);
8070
            tcg_temp_free_i64(fp0);
8071
        }
8072
        opn = "floor.l.d";
8073
        break;
8074
    case OPC_ROUND_W_D:
8075
        check_cp1_registers(ctx, fs);
8076
        {
8077
            TCGv_i32 fp32 = tcg_temp_new_i32();
8078
            TCGv_i64 fp64 = tcg_temp_new_i64();
8079

    
8080
            gen_load_fpr64(ctx, fp64, fs);
8081
            gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8082
            tcg_temp_free_i64(fp64);
8083
            gen_store_fpr32(fp32, fd);
8084
            tcg_temp_free_i32(fp32);
8085
        }
8086
        opn = "round.w.d";
8087
        break;
8088
    case OPC_TRUNC_W_D:
8089
        check_cp1_registers(ctx, fs);
8090
        {
8091
            TCGv_i32 fp32 = tcg_temp_new_i32();
8092
            TCGv_i64 fp64 = tcg_temp_new_i64();
8093

    
8094
            gen_load_fpr64(ctx, fp64, fs);
8095
            gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8096
            tcg_temp_free_i64(fp64);
8097
            gen_store_fpr32(fp32, fd);
8098
            tcg_temp_free_i32(fp32);
8099
        }
8100
        opn = "trunc.w.d";
8101
        break;
8102
    case OPC_CEIL_W_D:
8103
        check_cp1_registers(ctx, fs);
8104
        {
8105
            TCGv_i32 fp32 = tcg_temp_new_i32();
8106
            TCGv_i64 fp64 = tcg_temp_new_i64();
8107

    
8108
            gen_load_fpr64(ctx, fp64, fs);
8109
            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8110
            tcg_temp_free_i64(fp64);
8111
            gen_store_fpr32(fp32, fd);
8112
            tcg_temp_free_i32(fp32);
8113
        }
8114
        opn = "ceil.w.d";
8115
        break;
8116
    case OPC_FLOOR_W_D:
8117
        check_cp1_registers(ctx, fs);
8118
        {
8119
            TCGv_i32 fp32 = tcg_temp_new_i32();
8120
            TCGv_i64 fp64 = tcg_temp_new_i64();
8121

    
8122
            gen_load_fpr64(ctx, fp64, fs);
8123
            gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8124
            tcg_temp_free_i64(fp64);
8125
            gen_store_fpr32(fp32, fd);
8126
            tcg_temp_free_i32(fp32);
8127
        }
8128
        opn = "floor.w.d";
8129
        break;
8130
    case OPC_MOVCF_D:
8131
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8132
        opn = "movcf.d";
8133
        break;
8134
    case OPC_MOVZ_D:
8135
        {
8136
            int l1 = gen_new_label();
8137
            TCGv_i64 fp0;
8138

    
8139
            if (ft != 0) {
8140
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8141
            }
8142
            fp0 = tcg_temp_new_i64();
8143
            gen_load_fpr64(ctx, fp0, fs);
8144
            gen_store_fpr64(ctx, fp0, fd);
8145
            tcg_temp_free_i64(fp0);
8146
            gen_set_label(l1);
8147
        }
8148
        opn = "movz.d";
8149
        break;
8150
    case OPC_MOVN_D:
8151
        {
8152
            int l1 = gen_new_label();
8153
            TCGv_i64 fp0;
8154

    
8155
            if (ft != 0) {
8156
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8157
                fp0 = tcg_temp_new_i64();
8158
                gen_load_fpr64(ctx, fp0, fs);
8159
                gen_store_fpr64(ctx, fp0, fd);
8160
                tcg_temp_free_i64(fp0);
8161
                gen_set_label(l1);
8162
            }
8163
        }
8164
        opn = "movn.d";
8165
        break;
8166
    case OPC_RECIP_D:
8167
        check_cp1_64bitmode(ctx);
8168
        {
8169
            TCGv_i64 fp0 = tcg_temp_new_i64();
8170

    
8171
            gen_load_fpr64(ctx, fp0, fs);
8172
            gen_helper_float_recip_d(fp0, cpu_env, fp0);
8173
            gen_store_fpr64(ctx, fp0, fd);
8174
            tcg_temp_free_i64(fp0);
8175
        }
8176
        opn = "recip.d";
8177
        break;
8178
    case OPC_RSQRT_D:
8179
        check_cp1_64bitmode(ctx);
8180
        {
8181
            TCGv_i64 fp0 = tcg_temp_new_i64();
8182

    
8183
            gen_load_fpr64(ctx, fp0, fs);
8184
            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8185
            gen_store_fpr64(ctx, fp0, fd);
8186
            tcg_temp_free_i64(fp0);
8187
        }
8188
        opn = "rsqrt.d";
8189
        break;
8190
    case OPC_RECIP2_D:
8191
        check_cp1_64bitmode(ctx);
8192
        {
8193
            TCGv_i64 fp0 = tcg_temp_new_i64();
8194
            TCGv_i64 fp1 = tcg_temp_new_i64();
8195

    
8196
            gen_load_fpr64(ctx, fp0, fs);
8197
            gen_load_fpr64(ctx, fp1, ft);
8198
            gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8199
            tcg_temp_free_i64(fp1);
8200
            gen_store_fpr64(ctx, fp0, fd);
8201
            tcg_temp_free_i64(fp0);
8202
        }
8203
        opn = "recip2.d";
8204
        break;
8205
    case OPC_RECIP1_D:
8206
        check_cp1_64bitmode(ctx);
8207
        {
8208
            TCGv_i64 fp0 = tcg_temp_new_i64();
8209

    
8210
            gen_load_fpr64(ctx, fp0, fs);
8211
            gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8212
            gen_store_fpr64(ctx, fp0, fd);
8213
            tcg_temp_free_i64(fp0);
8214
        }
8215
        opn = "recip1.d";
8216
        break;
8217
    case OPC_RSQRT1_D:
8218
        check_cp1_64bitmode(ctx);
8219
        {
8220
            TCGv_i64 fp0 = tcg_temp_new_i64();
8221

    
8222
            gen_load_fpr64(ctx, fp0, fs);
8223
            gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8224
            gen_store_fpr64(ctx, fp0, fd);
8225
            tcg_temp_free_i64(fp0);
8226
        }
8227
        opn = "rsqrt1.d";
8228
        break;
8229
    case OPC_RSQRT2_D:
8230
        check_cp1_64bitmode(ctx);
8231
        {
8232
            TCGv_i64 fp0 = tcg_temp_new_i64();
8233
            TCGv_i64 fp1 = tcg_temp_new_i64();
8234

    
8235
            gen_load_fpr64(ctx, fp0, fs);
8236
            gen_load_fpr64(ctx, fp1, ft);
8237
            gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8238
            tcg_temp_free_i64(fp1);
8239
            gen_store_fpr64(ctx, fp0, fd);
8240
            tcg_temp_free_i64(fp0);
8241
        }
8242
        opn = "rsqrt2.d";
8243
        break;
8244
    case OPC_CMP_F_D:
8245
    case OPC_CMP_UN_D:
8246
    case OPC_CMP_EQ_D:
8247
    case OPC_CMP_UEQ_D:
8248
    case OPC_CMP_OLT_D:
8249
    case OPC_CMP_ULT_D:
8250
    case OPC_CMP_OLE_D:
8251
    case OPC_CMP_ULE_D:
8252
    case OPC_CMP_SF_D:
8253
    case OPC_CMP_NGLE_D:
8254
    case OPC_CMP_SEQ_D:
8255
    case OPC_CMP_NGL_D:
8256
    case OPC_CMP_LT_D:
8257
    case OPC_CMP_NGE_D:
8258
    case OPC_CMP_LE_D:
8259
    case OPC_CMP_NGT_D:
8260
        if (ctx->opcode & (1 << 6)) {
8261
            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8262
            opn = condnames_abs[func-48];
8263
        } else {
8264
            gen_cmp_d(ctx, func-48, ft, fs, cc);
8265
            opn = condnames[func-48];
8266
        }
8267
        break;
8268
    case OPC_CVT_S_D:
8269
        check_cp1_registers(ctx, fs);
8270
        {
8271
            TCGv_i32 fp32 = tcg_temp_new_i32();
8272
            TCGv_i64 fp64 = tcg_temp_new_i64();
8273

    
8274
            gen_load_fpr64(ctx, fp64, fs);
8275
            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8276
            tcg_temp_free_i64(fp64);
8277
            gen_store_fpr32(fp32, fd);
8278
            tcg_temp_free_i32(fp32);
8279
        }
8280
        opn = "cvt.s.d";
8281
        break;
8282
    case OPC_CVT_W_D:
8283
        check_cp1_registers(ctx, fs);
8284
        {
8285
            TCGv_i32 fp32 = tcg_temp_new_i32();
8286
            TCGv_i64 fp64 = tcg_temp_new_i64();
8287

    
8288
            gen_load_fpr64(ctx, fp64, fs);
8289
            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8290
            tcg_temp_free_i64(fp64);
8291
            gen_store_fpr32(fp32, fd);
8292
            tcg_temp_free_i32(fp32);
8293
        }
8294
        opn = "cvt.w.d";
8295
        break;
8296
    case OPC_CVT_L_D:
8297
        check_cp1_64bitmode(ctx);
8298
        {
8299
            TCGv_i64 fp0 = tcg_temp_new_i64();
8300

    
8301
            gen_load_fpr64(ctx, fp0, fs);
8302
            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8303
            gen_store_fpr64(ctx, fp0, fd);
8304
            tcg_temp_free_i64(fp0);
8305
        }
8306
        opn = "cvt.l.d";
8307
        break;
8308
    case OPC_CVT_S_W:
8309
        {
8310
            TCGv_i32 fp0 = tcg_temp_new_i32();
8311

    
8312
            gen_load_fpr32(fp0, fs);
8313
            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8314
            gen_store_fpr32(fp0, fd);
8315
            tcg_temp_free_i32(fp0);
8316
        }
8317
        opn = "cvt.s.w";
8318
        break;
8319
    case OPC_CVT_D_W:
8320
        check_cp1_registers(ctx, fd);
8321
        {
8322
            TCGv_i32 fp32 = tcg_temp_new_i32();
8323
            TCGv_i64 fp64 = tcg_temp_new_i64();
8324

    
8325
            gen_load_fpr32(fp32, fs);
8326
            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8327
            tcg_temp_free_i32(fp32);
8328
            gen_store_fpr64(ctx, fp64, fd);
8329
            tcg_temp_free_i64(fp64);
8330
        }
8331
        opn = "cvt.d.w";
8332
        break;
8333
    case OPC_CVT_S_L:
8334
        check_cp1_64bitmode(ctx);
8335
        {
8336
            TCGv_i32 fp32 = tcg_temp_new_i32();
8337
            TCGv_i64 fp64 = tcg_temp_new_i64();
8338

    
8339
            gen_load_fpr64(ctx, fp64, fs);
8340
            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8341
            tcg_temp_free_i64(fp64);
8342
            gen_store_fpr32(fp32, fd);
8343
            tcg_temp_free_i32(fp32);
8344
        }
8345
        opn = "cvt.s.l";
8346
        break;
8347
    case OPC_CVT_D_L:
8348
        check_cp1_64bitmode(ctx);
8349
        {
8350
            TCGv_i64 fp0 = tcg_temp_new_i64();
8351

    
8352
            gen_load_fpr64(ctx, fp0, fs);
8353
            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8354
            gen_store_fpr64(ctx, fp0, fd);
8355
            tcg_temp_free_i64(fp0);
8356
        }
8357
        opn = "cvt.d.l";
8358
        break;
8359
    case OPC_CVT_PS_PW:
8360
        check_cp1_64bitmode(ctx);
8361
        {
8362
            TCGv_i64 fp0 = tcg_temp_new_i64();
8363

    
8364
            gen_load_fpr64(ctx, fp0, fs);
8365
            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8366
            gen_store_fpr64(ctx, fp0, fd);
8367
            tcg_temp_free_i64(fp0);
8368
        }
8369
        opn = "cvt.ps.pw";
8370
        break;
8371
    case OPC_ADD_PS:
8372
        check_cp1_64bitmode(ctx);
8373
        {
8374
            TCGv_i64 fp0 = tcg_temp_new_i64();
8375
            TCGv_i64 fp1 = tcg_temp_new_i64();
8376

    
8377
            gen_load_fpr64(ctx, fp0, fs);
8378
            gen_load_fpr64(ctx, fp1, ft);
8379
            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8380
            tcg_temp_free_i64(fp1);
8381
            gen_store_fpr64(ctx, fp0, fd);
8382
            tcg_temp_free_i64(fp0);
8383
        }
8384
        opn = "add.ps";
8385
        break;
8386
    case OPC_SUB_PS:
8387
        check_cp1_64bitmode(ctx);
8388
        {
8389
            TCGv_i64 fp0 = tcg_temp_new_i64();
8390
            TCGv_i64 fp1 = tcg_temp_new_i64();
8391

    
8392
            gen_load_fpr64(ctx, fp0, fs);
8393
            gen_load_fpr64(ctx, fp1, ft);
8394
            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8395
            tcg_temp_free_i64(fp1);
8396
            gen_store_fpr64(ctx, fp0, fd);
8397
            tcg_temp_free_i64(fp0);
8398
        }
8399
        opn = "sub.ps";
8400
        break;
8401
    case OPC_MUL_PS:
8402
        check_cp1_64bitmode(ctx);
8403
        {
8404
            TCGv_i64 fp0 = tcg_temp_new_i64();
8405
            TCGv_i64 fp1 = tcg_temp_new_i64();
8406

    
8407
            gen_load_fpr64(ctx, fp0, fs);
8408
            gen_load_fpr64(ctx, fp1, ft);
8409
            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8410
            tcg_temp_free_i64(fp1);
8411
            gen_store_fpr64(ctx, fp0, fd);
8412
            tcg_temp_free_i64(fp0);
8413
        }
8414
        opn = "mul.ps";
8415
        break;
8416
    case OPC_ABS_PS:
8417
        check_cp1_64bitmode(ctx);
8418
        {
8419
            TCGv_i64 fp0 = tcg_temp_new_i64();
8420

    
8421
            gen_load_fpr64(ctx, fp0, fs);
8422
            gen_helper_float_abs_ps(fp0, fp0);
8423
            gen_store_fpr64(ctx, fp0, fd);
8424
            tcg_temp_free_i64(fp0);
8425
        }
8426
        opn = "abs.ps";
8427
        break;
8428
    case OPC_MOV_PS:
8429
        check_cp1_64bitmode(ctx);
8430
        {
8431
            TCGv_i64 fp0 = tcg_temp_new_i64();
8432

    
8433
            gen_load_fpr64(ctx, fp0, fs);
8434
            gen_store_fpr64(ctx, fp0, fd);
8435
            tcg_temp_free_i64(fp0);
8436
        }
8437
        opn = "mov.ps";
8438
        break;
8439
    case OPC_NEG_PS:
8440
        check_cp1_64bitmode(ctx);
8441
        {
8442
            TCGv_i64 fp0 = tcg_temp_new_i64();
8443

    
8444
            gen_load_fpr64(ctx, fp0, fs);
8445
            gen_helper_float_chs_ps(fp0, fp0);
8446
            gen_store_fpr64(ctx, fp0, fd);
8447
            tcg_temp_free_i64(fp0);
8448
        }
8449
        opn = "neg.ps";
8450
        break;
8451
    case OPC_MOVCF_PS:
8452
        check_cp1_64bitmode(ctx);
8453
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8454
        opn = "movcf.ps";
8455
        break;
8456
    case OPC_MOVZ_PS:
8457
        check_cp1_64bitmode(ctx);
8458
        {
8459
            int l1 = gen_new_label();
8460
            TCGv_i64 fp0;
8461

    
8462
            if (ft != 0)
8463
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8464
            fp0 = tcg_temp_new_i64();
8465
            gen_load_fpr64(ctx, fp0, fs);
8466
            gen_store_fpr64(ctx, fp0, fd);
8467
            tcg_temp_free_i64(fp0);
8468
            gen_set_label(l1);
8469
        }
8470
        opn = "movz.ps";
8471
        break;
8472
    case OPC_MOVN_PS:
8473
        check_cp1_64bitmode(ctx);
8474
        {
8475
            int l1 = gen_new_label();
8476
            TCGv_i64 fp0;
8477

    
8478
            if (ft != 0) {
8479
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8480
                fp0 = tcg_temp_new_i64();
8481
                gen_load_fpr64(ctx, fp0, fs);
8482
                gen_store_fpr64(ctx, fp0, fd);
8483
                tcg_temp_free_i64(fp0);
8484
                gen_set_label(l1);
8485
            }
8486
        }
8487
        opn = "movn.ps";
8488
        break;
8489
    case OPC_ADDR_PS:
8490
        check_cp1_64bitmode(ctx);
8491
        {
8492
            TCGv_i64 fp0 = tcg_temp_new_i64();
8493
            TCGv_i64 fp1 = tcg_temp_new_i64();
8494

    
8495
            gen_load_fpr64(ctx, fp0, ft);
8496
            gen_load_fpr64(ctx, fp1, fs);
8497
            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8498
            tcg_temp_free_i64(fp1);
8499
            gen_store_fpr64(ctx, fp0, fd);
8500
            tcg_temp_free_i64(fp0);
8501
        }
8502
        opn = "addr.ps";
8503
        break;
8504
    case OPC_MULR_PS:
8505
        check_cp1_64bitmode(ctx);
8506
        {
8507
            TCGv_i64 fp0 = tcg_temp_new_i64();
8508
            TCGv_i64 fp1 = tcg_temp_new_i64();
8509

    
8510
            gen_load_fpr64(ctx, fp0, ft);
8511
            gen_load_fpr64(ctx, fp1, fs);
8512
            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8513
            tcg_temp_free_i64(fp1);
8514
            gen_store_fpr64(ctx, fp0, fd);
8515
            tcg_temp_free_i64(fp0);
8516
        }
8517
        opn = "mulr.ps";
8518
        break;
8519
    case OPC_RECIP2_PS:
8520
        check_cp1_64bitmode(ctx);
8521
        {
8522
            TCGv_i64 fp0 = tcg_temp_new_i64();
8523
            TCGv_i64 fp1 = tcg_temp_new_i64();
8524

    
8525
            gen_load_fpr64(ctx, fp0, fs);
8526
            gen_load_fpr64(ctx, fp1, ft);
8527
            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8528
            tcg_temp_free_i64(fp1);
8529
            gen_store_fpr64(ctx, fp0, fd);
8530
            tcg_temp_free_i64(fp0);
8531
        }
8532
        opn = "recip2.ps";
8533
        break;
8534
    case OPC_RECIP1_PS:
8535
        check_cp1_64bitmode(ctx);
8536
        {
8537
            TCGv_i64 fp0 = tcg_temp_new_i64();
8538

    
8539
            gen_load_fpr64(ctx, fp0, fs);
8540
            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8541
            gen_store_fpr64(ctx, fp0, fd);
8542
            tcg_temp_free_i64(fp0);
8543
        }
8544
        opn = "recip1.ps";
8545
        break;
8546
    case OPC_RSQRT1_PS:
8547
        check_cp1_64bitmode(ctx);
8548
        {
8549
            TCGv_i64 fp0 = tcg_temp_new_i64();
8550

    
8551
            gen_load_fpr64(ctx, fp0, fs);
8552
            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8553
            gen_store_fpr64(ctx, fp0, fd);
8554
            tcg_temp_free_i64(fp0);
8555
        }
8556
        opn = "rsqrt1.ps";
8557
        break;
8558
    case OPC_RSQRT2_PS:
8559
        check_cp1_64bitmode(ctx);
8560
        {
8561
            TCGv_i64 fp0 = tcg_temp_new_i64();
8562
            TCGv_i64 fp1 = tcg_temp_new_i64();
8563

    
8564
            gen_load_fpr64(ctx, fp0, fs);
8565
            gen_load_fpr64(ctx, fp1, ft);
8566
            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8567
            tcg_temp_free_i64(fp1);
8568
            gen_store_fpr64(ctx, fp0, fd);
8569
            tcg_temp_free_i64(fp0);
8570
        }
8571
        opn = "rsqrt2.ps";
8572
        break;
8573
    case OPC_CVT_S_PU:
8574
        check_cp1_64bitmode(ctx);
8575
        {
8576
            TCGv_i32 fp0 = tcg_temp_new_i32();
8577

    
8578
            gen_load_fpr32h(fp0, fs);
8579
            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8580
            gen_store_fpr32(fp0, fd);
8581
            tcg_temp_free_i32(fp0);
8582
        }
8583
        opn = "cvt.s.pu";
8584
        break;
8585
    case OPC_CVT_PW_PS:
8586
        check_cp1_64bitmode(ctx);
8587
        {
8588
            TCGv_i64 fp0 = tcg_temp_new_i64();
8589

    
8590
            gen_load_fpr64(ctx, fp0, fs);
8591
            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8592
            gen_store_fpr64(ctx, fp0, fd);
8593
            tcg_temp_free_i64(fp0);
8594
        }
8595
        opn = "cvt.pw.ps";
8596
        break;
8597
    case OPC_CVT_S_PL:
8598
        check_cp1_64bitmode(ctx);
8599
        {
8600
            TCGv_i32 fp0 = tcg_temp_new_i32();
8601

    
8602
            gen_load_fpr32(fp0, fs);
8603
            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8604
            gen_store_fpr32(fp0, fd);
8605
            tcg_temp_free_i32(fp0);
8606
        }
8607
        opn = "cvt.s.pl";
8608
        break;
8609
    case OPC_PLL_PS:
8610
        check_cp1_64bitmode(ctx);
8611
        {
8612
            TCGv_i32 fp0 = tcg_temp_new_i32();
8613
            TCGv_i32 fp1 = tcg_temp_new_i32();
8614

    
8615
            gen_load_fpr32(fp0, fs);
8616
            gen_load_fpr32(fp1, ft);
8617
            gen_store_fpr32h(fp0, fd);
8618
            gen_store_fpr32(fp1, fd);
8619
            tcg_temp_free_i32(fp0);
8620
            tcg_temp_free_i32(fp1);
8621
        }
8622
        opn = "pll.ps";
8623
        break;
8624
    case OPC_PLU_PS:
8625
        check_cp1_64bitmode(ctx);
8626
        {
8627
            TCGv_i32 fp0 = tcg_temp_new_i32();
8628
            TCGv_i32 fp1 = tcg_temp_new_i32();
8629

    
8630
            gen_load_fpr32(fp0, fs);
8631
            gen_load_fpr32h(fp1, ft);
8632
            gen_store_fpr32(fp1, fd);
8633
            gen_store_fpr32h(fp0, fd);
8634
            tcg_temp_free_i32(fp0);
8635
            tcg_temp_free_i32(fp1);
8636
        }
8637
        opn = "plu.ps";
8638
        break;
8639
    case OPC_PUL_PS:
8640
        check_cp1_64bitmode(ctx);
8641
        {
8642
            TCGv_i32 fp0 = tcg_temp_new_i32();
8643
            TCGv_i32 fp1 = tcg_temp_new_i32();
8644

    
8645
            gen_load_fpr32h(fp0, fs);
8646
            gen_load_fpr32(fp1, ft);
8647
            gen_store_fpr32(fp1, fd);
8648
            gen_store_fpr32h(fp0, fd);
8649
            tcg_temp_free_i32(fp0);
8650
            tcg_temp_free_i32(fp1);
8651
        }
8652
        opn = "pul.ps";
8653
        break;
8654
    case OPC_PUU_PS:
8655
        check_cp1_64bitmode(ctx);
8656
        {
8657
            TCGv_i32 fp0 = tcg_temp_new_i32();
8658
            TCGv_i32 fp1 = tcg_temp_new_i32();
8659

    
8660
            gen_load_fpr32h(fp0, fs);
8661
            gen_load_fpr32h(fp1, ft);
8662
            gen_store_fpr32(fp1, fd);
8663
            gen_store_fpr32h(fp0, fd);
8664
            tcg_temp_free_i32(fp0);
8665
            tcg_temp_free_i32(fp1);
8666
        }
8667
        opn = "puu.ps";
8668
        break;
8669
    case OPC_CMP_F_PS:
8670
    case OPC_CMP_UN_PS:
8671
    case OPC_CMP_EQ_PS:
8672
    case OPC_CMP_UEQ_PS:
8673
    case OPC_CMP_OLT_PS:
8674
    case OPC_CMP_ULT_PS:
8675
    case OPC_CMP_OLE_PS:
8676
    case OPC_CMP_ULE_PS:
8677
    case OPC_CMP_SF_PS:
8678
    case OPC_CMP_NGLE_PS:
8679
    case OPC_CMP_SEQ_PS:
8680
    case OPC_CMP_NGL_PS:
8681
    case OPC_CMP_LT_PS:
8682
    case OPC_CMP_NGE_PS:
8683
    case OPC_CMP_LE_PS:
8684
    case OPC_CMP_NGT_PS:
8685
        if (ctx->opcode & (1 << 6)) {
8686
            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8687
            opn = condnames_abs[func-48];
8688
        } else {
8689
            gen_cmp_ps(ctx, func-48, ft, fs, cc);
8690
            opn = condnames[func-48];
8691
        }
8692
        break;
8693
    default:
8694
        MIPS_INVAL(opn);
8695
        generate_exception (ctx, EXCP_RI);
8696
        return;
8697
    }
8698
    (void)opn; /* avoid a compiler warning */
8699
    switch (optype) {
8700
    case BINOP:
8701
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8702
        break;
8703
    case CMPOP:
8704
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8705
        break;
8706
    default:
8707
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8708
        break;
8709
    }
8710
}
8711

    
8712
/* Coprocessor 3 (FPU) */
8713
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8714
                           int fd, int fs, int base, int index)
8715
{
8716
    const char *opn = "extended float load/store";
8717
    int store = 0;
8718
    TCGv t0 = tcg_temp_new();
8719

    
8720
    if (base == 0) {
8721
        gen_load_gpr(t0, index);
8722
    } else if (index == 0) {
8723
        gen_load_gpr(t0, base);
8724
    } else {
8725
        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8726
    }
8727
    /* Don't do NOP if destination is zero: we must perform the actual
8728
       memory access. */
8729
    save_cpu_state(ctx, 0);
8730
    switch (opc) {
8731
    case OPC_LWXC1:
8732
        check_cop1x(ctx);
8733
        {
8734
            TCGv_i32 fp0 = tcg_temp_new_i32();
8735

    
8736
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8737
            tcg_gen_trunc_tl_i32(fp0, t0);
8738
            gen_store_fpr32(fp0, fd);
8739
            tcg_temp_free_i32(fp0);
8740
        }
8741
        opn = "lwxc1";
8742
        break;
8743
    case OPC_LDXC1:
8744
        check_cop1x(ctx);
8745
        check_cp1_registers(ctx, fd);
8746
        {
8747
            TCGv_i64 fp0 = tcg_temp_new_i64();
8748

    
8749
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8750
            gen_store_fpr64(ctx, fp0, fd);
8751
            tcg_temp_free_i64(fp0);
8752
        }
8753
        opn = "ldxc1";
8754
        break;
8755
    case OPC_LUXC1:
8756
        check_cp1_64bitmode(ctx);
8757
        tcg_gen_andi_tl(t0, t0, ~0x7);
8758
        {
8759
            TCGv_i64 fp0 = tcg_temp_new_i64();
8760

    
8761
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8762
            gen_store_fpr64(ctx, fp0, fd);
8763
            tcg_temp_free_i64(fp0);
8764
        }
8765
        opn = "luxc1";
8766
        break;
8767
    case OPC_SWXC1:
8768
        check_cop1x(ctx);
8769
        {
8770
            TCGv_i32 fp0 = tcg_temp_new_i32();
8771
            TCGv t1 = tcg_temp_new();
8772

    
8773
            gen_load_fpr32(fp0, fs);
8774
            tcg_gen_extu_i32_tl(t1, fp0);
8775
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8776
            tcg_temp_free_i32(fp0);
8777
            tcg_temp_free(t1);
8778
        }
8779
        opn = "swxc1";
8780
        store = 1;
8781
        break;
8782
    case OPC_SDXC1:
8783
        check_cop1x(ctx);
8784
        check_cp1_registers(ctx, fs);
8785
        {
8786
            TCGv_i64 fp0 = tcg_temp_new_i64();
8787

    
8788
            gen_load_fpr64(ctx, fp0, fs);
8789
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8790
            tcg_temp_free_i64(fp0);
8791
        }
8792
        opn = "sdxc1";
8793
        store = 1;
8794
        break;
8795
    case OPC_SUXC1:
8796
        check_cp1_64bitmode(ctx);
8797
        tcg_gen_andi_tl(t0, t0, ~0x7);
8798
        {
8799
            TCGv_i64 fp0 = tcg_temp_new_i64();
8800

    
8801
            gen_load_fpr64(ctx, fp0, fs);
8802
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8803
            tcg_temp_free_i64(fp0);
8804
        }
8805
        opn = "suxc1";
8806
        store = 1;
8807
        break;
8808
    }
8809
    tcg_temp_free(t0);
8810
    (void)opn; (void)store; /* avoid compiler warnings */
8811
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8812
               regnames[index], regnames[base]);
8813
}
8814

    
8815
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8816
                            int fd, int fr, int fs, int ft)
8817
{
8818
    const char *opn = "flt3_arith";
8819

    
8820
    switch (opc) {
8821
    case OPC_ALNV_PS:
8822
        check_cp1_64bitmode(ctx);
8823
        {
8824
            TCGv t0 = tcg_temp_local_new();
8825
            TCGv_i32 fp = tcg_temp_new_i32();
8826
            TCGv_i32 fph = tcg_temp_new_i32();
8827
            int l1 = gen_new_label();
8828
            int l2 = gen_new_label();
8829

    
8830
            gen_load_gpr(t0, fr);
8831
            tcg_gen_andi_tl(t0, t0, 0x7);
8832

    
8833
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8834
            gen_load_fpr32(fp, fs);
8835
            gen_load_fpr32h(fph, fs);
8836
            gen_store_fpr32(fp, fd);
8837
            gen_store_fpr32h(fph, fd);
8838
            tcg_gen_br(l2);
8839
            gen_set_label(l1);
8840
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8841
            tcg_temp_free(t0);
8842
#ifdef TARGET_WORDS_BIGENDIAN
8843
            gen_load_fpr32(fp, fs);
8844
            gen_load_fpr32h(fph, ft);
8845
            gen_store_fpr32h(fp, fd);
8846
            gen_store_fpr32(fph, fd);
8847
#else
8848
            gen_load_fpr32h(fph, fs);
8849
            gen_load_fpr32(fp, ft);
8850
            gen_store_fpr32(fph, fd);
8851
            gen_store_fpr32h(fp, fd);
8852
#endif
8853
            gen_set_label(l2);
8854
            tcg_temp_free_i32(fp);
8855
            tcg_temp_free_i32(fph);
8856
        }
8857
        opn = "alnv.ps";
8858
        break;
8859
    case OPC_MADD_S:
8860
        check_cop1x(ctx);
8861
        {
8862
            TCGv_i32 fp0 = tcg_temp_new_i32();
8863
            TCGv_i32 fp1 = tcg_temp_new_i32();
8864
            TCGv_i32 fp2 = tcg_temp_new_i32();
8865

    
8866
            gen_load_fpr32(fp0, fs);
8867
            gen_load_fpr32(fp1, ft);
8868
            gen_load_fpr32(fp2, fr);
8869
            gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8870
            tcg_temp_free_i32(fp0);
8871
            tcg_temp_free_i32(fp1);
8872
            gen_store_fpr32(fp2, fd);
8873
            tcg_temp_free_i32(fp2);
8874
        }
8875
        opn = "madd.s";
8876
        break;
8877
    case OPC_MADD_D:
8878
        check_cop1x(ctx);
8879
        check_cp1_registers(ctx, fd | fs | ft | fr);
8880
        {
8881
            TCGv_i64 fp0 = tcg_temp_new_i64();
8882
            TCGv_i64 fp1 = tcg_temp_new_i64();
8883
            TCGv_i64 fp2 = tcg_temp_new_i64();
8884

    
8885
            gen_load_fpr64(ctx, fp0, fs);
8886
            gen_load_fpr64(ctx, fp1, ft);
8887
            gen_load_fpr64(ctx, fp2, fr);
8888
            gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8889
            tcg_temp_free_i64(fp0);
8890
            tcg_temp_free_i64(fp1);
8891
            gen_store_fpr64(ctx, fp2, fd);
8892
            tcg_temp_free_i64(fp2);
8893
        }
8894
        opn = "madd.d";
8895
        break;
8896
    case OPC_MADD_PS:
8897
        check_cp1_64bitmode(ctx);
8898
        {
8899
            TCGv_i64 fp0 = tcg_temp_new_i64();
8900
            TCGv_i64 fp1 = tcg_temp_new_i64();
8901
            TCGv_i64 fp2 = tcg_temp_new_i64();
8902

    
8903
            gen_load_fpr64(ctx, fp0, fs);
8904
            gen_load_fpr64(ctx, fp1, ft);
8905
            gen_load_fpr64(ctx, fp2, fr);
8906
            gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8907
            tcg_temp_free_i64(fp0);
8908
            tcg_temp_free_i64(fp1);
8909
            gen_store_fpr64(ctx, fp2, fd);
8910
            tcg_temp_free_i64(fp2);
8911
        }
8912
        opn = "madd.ps";
8913
        break;
8914
    case OPC_MSUB_S:
8915
        check_cop1x(ctx);
8916
        {
8917
            TCGv_i32 fp0 = tcg_temp_new_i32();
8918
            TCGv_i32 fp1 = tcg_temp_new_i32();
8919
            TCGv_i32 fp2 = tcg_temp_new_i32();
8920

    
8921
            gen_load_fpr32(fp0, fs);
8922
            gen_load_fpr32(fp1, ft);
8923
            gen_load_fpr32(fp2, fr);
8924
            gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8925
            tcg_temp_free_i32(fp0);
8926
            tcg_temp_free_i32(fp1);
8927
            gen_store_fpr32(fp2, fd);
8928
            tcg_temp_free_i32(fp2);
8929
        }
8930
        opn = "msub.s";
8931
        break;
8932
    case OPC_MSUB_D:
8933
        check_cop1x(ctx);
8934
        check_cp1_registers(ctx, fd | fs | ft | fr);
8935
        {
8936
            TCGv_i64 fp0 = tcg_temp_new_i64();
8937
            TCGv_i64 fp1 = tcg_temp_new_i64();
8938
            TCGv_i64 fp2 = tcg_temp_new_i64();
8939

    
8940
            gen_load_fpr64(ctx, fp0, fs);
8941
            gen_load_fpr64(ctx, fp1, ft);
8942
            gen_load_fpr64(ctx, fp2, fr);
8943
            gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8944
            tcg_temp_free_i64(fp0);
8945
            tcg_temp_free_i64(fp1);
8946
            gen_store_fpr64(ctx, fp2, fd);
8947
            tcg_temp_free_i64(fp2);
8948
        }
8949
        opn = "msub.d";
8950
        break;
8951
    case OPC_MSUB_PS:
8952
        check_cp1_64bitmode(ctx);
8953
        {
8954
            TCGv_i64 fp0 = tcg_temp_new_i64();
8955
            TCGv_i64 fp1 = tcg_temp_new_i64();
8956
            TCGv_i64 fp2 = tcg_temp_new_i64();
8957

    
8958
            gen_load_fpr64(ctx, fp0, fs);
8959
            gen_load_fpr64(ctx, fp1, ft);
8960
            gen_load_fpr64(ctx, fp2, fr);
8961
            gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8962
            tcg_temp_free_i64(fp0);
8963
            tcg_temp_free_i64(fp1);
8964
            gen_store_fpr64(ctx, fp2, fd);
8965
            tcg_temp_free_i64(fp2);
8966
        }
8967
        opn = "msub.ps";
8968
        break;
8969
    case OPC_NMADD_S:
8970
        check_cop1x(ctx);
8971
        {
8972
            TCGv_i32 fp0 = tcg_temp_new_i32();
8973
            TCGv_i32 fp1 = tcg_temp_new_i32();
8974
            TCGv_i32 fp2 = tcg_temp_new_i32();
8975

    
8976
            gen_load_fpr32(fp0, fs);
8977
            gen_load_fpr32(fp1, ft);
8978
            gen_load_fpr32(fp2, fr);
8979
            gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8980
            tcg_temp_free_i32(fp0);
8981
            tcg_temp_free_i32(fp1);
8982
            gen_store_fpr32(fp2, fd);
8983
            tcg_temp_free_i32(fp2);
8984
        }
8985
        opn = "nmadd.s";
8986
        break;
8987
    case OPC_NMADD_D:
8988
        check_cop1x(ctx);
8989
        check_cp1_registers(ctx, fd | fs | ft | fr);
8990
        {
8991
            TCGv_i64 fp0 = tcg_temp_new_i64();
8992
            TCGv_i64 fp1 = tcg_temp_new_i64();
8993
            TCGv_i64 fp2 = tcg_temp_new_i64();
8994

    
8995
            gen_load_fpr64(ctx, fp0, fs);
8996
            gen_load_fpr64(ctx, fp1, ft);
8997
            gen_load_fpr64(ctx, fp2, fr);
8998
            gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8999
            tcg_temp_free_i64(fp0);
9000
            tcg_temp_free_i64(fp1);
9001
            gen_store_fpr64(ctx, fp2, fd);
9002
            tcg_temp_free_i64(fp2);
9003
        }
9004
        opn = "nmadd.d";
9005
        break;
9006
    case OPC_NMADD_PS:
9007
        check_cp1_64bitmode(ctx);
9008
        {
9009
            TCGv_i64 fp0 = tcg_temp_new_i64();
9010
            TCGv_i64 fp1 = tcg_temp_new_i64();
9011
            TCGv_i64 fp2 = tcg_temp_new_i64();
9012

    
9013
            gen_load_fpr64(ctx, fp0, fs);
9014
            gen_load_fpr64(ctx, fp1, ft);
9015
            gen_load_fpr64(ctx, fp2, fr);
9016
            gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
9017
            tcg_temp_free_i64(fp0);
9018
            tcg_temp_free_i64(fp1);
9019
            gen_store_fpr64(ctx, fp2, fd);
9020
            tcg_temp_free_i64(fp2);
9021
        }
9022
        opn = "nmadd.ps";
9023
        break;
9024
    case OPC_NMSUB_S:
9025
        check_cop1x(ctx);
9026
        {
9027
            TCGv_i32 fp0 = tcg_temp_new_i32();
9028
            TCGv_i32 fp1 = tcg_temp_new_i32();
9029
            TCGv_i32 fp2 = tcg_temp_new_i32();
9030

    
9031
            gen_load_fpr32(fp0, fs);
9032
            gen_load_fpr32(fp1, ft);
9033
            gen_load_fpr32(fp2, fr);
9034
            gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
9035
            tcg_temp_free_i32(fp0);
9036
            tcg_temp_free_i32(fp1);
9037
            gen_store_fpr32(fp2, fd);
9038
            tcg_temp_free_i32(fp2);
9039
        }
9040
        opn = "nmsub.s";
9041
        break;
9042
    case OPC_NMSUB_D:
9043
        check_cop1x(ctx);
9044
        check_cp1_registers(ctx, fd | fs | ft | fr);
9045
        {
9046
            TCGv_i64 fp0 = tcg_temp_new_i64();
9047
            TCGv_i64 fp1 = tcg_temp_new_i64();
9048
            TCGv_i64 fp2 = tcg_temp_new_i64();
9049

    
9050
            gen_load_fpr64(ctx, fp0, fs);
9051
            gen_load_fpr64(ctx, fp1, ft);
9052
            gen_load_fpr64(ctx, fp2, fr);
9053
            gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
9054
            tcg_temp_free_i64(fp0);
9055
            tcg_temp_free_i64(fp1);
9056
            gen_store_fpr64(ctx, fp2, fd);
9057
            tcg_temp_free_i64(fp2);
9058
        }
9059
        opn = "nmsub.d";
9060
        break;
9061
    case OPC_NMSUB_PS:
9062
        check_cp1_64bitmode(ctx);
9063
        {
9064
            TCGv_i64 fp0 = tcg_temp_new_i64();
9065
            TCGv_i64 fp1 = tcg_temp_new_i64();
9066
            TCGv_i64 fp2 = tcg_temp_new_i64();
9067

    
9068
            gen_load_fpr64(ctx, fp0, fs);
9069
            gen_load_fpr64(ctx, fp1, ft);
9070
            gen_load_fpr64(ctx, fp2, fr);
9071
            gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9072
            tcg_temp_free_i64(fp0);
9073
            tcg_temp_free_i64(fp1);
9074
            gen_store_fpr64(ctx, fp2, fd);
9075
            tcg_temp_free_i64(fp2);
9076
        }
9077
        opn = "nmsub.ps";
9078
        break;
9079
    default:
9080
        MIPS_INVAL(opn);
9081
        generate_exception (ctx, EXCP_RI);
9082
        return;
9083
    }
9084
    (void)opn; /* avoid a compiler warning */
9085
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9086
               fregnames[fs], fregnames[ft]);
9087
}
9088

    
9089
static void
9090
gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9091
{
9092
    TCGv t0;
9093

    
9094
#if !defined(CONFIG_USER_ONLY)
9095
    /* The Linux kernel will emulate rdhwr if it's not supported natively.
9096
       Therefore only check the ISA in system mode.  */
9097
    check_insn(env, ctx, ISA_MIPS32R2);
9098
#endif
9099
    t0 = tcg_temp_new();
9100

    
9101
    switch (rd) {
9102
    case 0:
9103
        save_cpu_state(ctx, 1);
9104
        gen_helper_rdhwr_cpunum(t0, cpu_env);
9105
        gen_store_gpr(t0, rt);
9106
        break;
9107
    case 1:
9108
        save_cpu_state(ctx, 1);
9109
        gen_helper_rdhwr_synci_step(t0, cpu_env);
9110
        gen_store_gpr(t0, rt);
9111
        break;
9112
    case 2:
9113
        save_cpu_state(ctx, 1);
9114
        gen_helper_rdhwr_cc(t0, cpu_env);
9115
        gen_store_gpr(t0, rt);
9116
        break;
9117
    case 3:
9118
        save_cpu_state(ctx, 1);
9119
        gen_helper_rdhwr_ccres(t0, cpu_env);
9120
        gen_store_gpr(t0, rt);
9121
        break;
9122
    case 29:
9123
#if defined(CONFIG_USER_ONLY)
9124
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9125
        gen_store_gpr(t0, rt);
9126
        break;
9127
#else
9128
        /* XXX: Some CPUs implement this in hardware.
9129
           Not supported yet. */
9130
#endif
9131
    default:            /* Invalid */
9132
        MIPS_INVAL("rdhwr");
9133
        generate_exception(ctx, EXCP_RI);
9134
        break;
9135
    }
9136
    tcg_temp_free(t0);
9137
}
9138

    
9139
static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9140
                               int insn_bytes)
9141
{
9142
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9143
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9144
        /* Branches completion */
9145
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
9146
        ctx->bstate = BS_BRANCH;
9147
        save_cpu_state(ctx, 0);
9148
        /* FIXME: Need to clear can_do_io.  */
9149
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9150
        case MIPS_HFLAG_B:
9151
            /* unconditional branch */
9152
            MIPS_DEBUG("unconditional branch");
9153
            if (proc_hflags & MIPS_HFLAG_BX) {
9154
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9155
            }
9156
            gen_goto_tb(ctx, 0, ctx->btarget);
9157
            break;
9158
        case MIPS_HFLAG_BL:
9159
            /* blikely taken case */
9160
            MIPS_DEBUG("blikely branch taken");
9161
            gen_goto_tb(ctx, 0, ctx->btarget);
9162
            break;
9163
        case MIPS_HFLAG_BC:
9164
            /* Conditional branch */
9165
            MIPS_DEBUG("conditional branch");
9166
            {
9167
                int l1 = gen_new_label();
9168

    
9169
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9170
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9171
                gen_set_label(l1);
9172
                gen_goto_tb(ctx, 0, ctx->btarget);
9173
            }
9174
            break;
9175
        case MIPS_HFLAG_BR:
9176
            /* unconditional branch to register */
9177
            MIPS_DEBUG("branch to register");
9178
            if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9179
                TCGv t0 = tcg_temp_new();
9180
                TCGv_i32 t1 = tcg_temp_new_i32();
9181

    
9182
                tcg_gen_andi_tl(t0, btarget, 0x1);
9183
                tcg_gen_trunc_tl_i32(t1, t0);
9184
                tcg_temp_free(t0);
9185
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9186
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9187
                tcg_gen_or_i32(hflags, hflags, t1);
9188
                tcg_temp_free_i32(t1);
9189

    
9190
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9191
            } else {
9192
                tcg_gen_mov_tl(cpu_PC, btarget);
9193
            }
9194
            if (ctx->singlestep_enabled) {
9195
                save_cpu_state(ctx, 0);
9196
                gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9197
            }
9198
            tcg_gen_exit_tb(0);
9199
            break;
9200
        default:
9201
            MIPS_DEBUG("unknown branch");
9202
            break;
9203
        }
9204
    }
9205
}
9206

    
9207
/* ISA extensions (ASEs) */
9208
/* MIPS16 extension to MIPS32 */
9209

    
9210
/* MIPS16 major opcodes */
9211
enum {
9212
  M16_OPC_ADDIUSP = 0x00,
9213
  M16_OPC_ADDIUPC = 0x01,
9214
  M16_OPC_B = 0x02,
9215
  M16_OPC_JAL = 0x03,
9216
  M16_OPC_BEQZ = 0x04,
9217
  M16_OPC_BNEQZ = 0x05,
9218
  M16_OPC_SHIFT = 0x06,
9219
  M16_OPC_LD = 0x07,
9220
  M16_OPC_RRIA = 0x08,
9221
  M16_OPC_ADDIU8 = 0x09,
9222
  M16_OPC_SLTI = 0x0a,
9223
  M16_OPC_SLTIU = 0x0b,
9224
  M16_OPC_I8 = 0x0c,
9225
  M16_OPC_LI = 0x0d,
9226
  M16_OPC_CMPI = 0x0e,
9227
  M16_OPC_SD = 0x0f,
9228
  M16_OPC_LB = 0x10,
9229
  M16_OPC_LH = 0x11,
9230
  M16_OPC_LWSP = 0x12,
9231
  M16_OPC_LW = 0x13,
9232
  M16_OPC_LBU = 0x14,
9233
  M16_OPC_LHU = 0x15,
9234
  M16_OPC_LWPC = 0x16,
9235
  M16_OPC_LWU = 0x17,
9236
  M16_OPC_SB = 0x18,
9237
  M16_OPC_SH = 0x19,
9238
  M16_OPC_SWSP = 0x1a,
9239
  M16_OPC_SW = 0x1b,
9240
  M16_OPC_RRR = 0x1c,
9241
  M16_OPC_RR = 0x1d,
9242
  M16_OPC_EXTEND = 0x1e,
9243
  M16_OPC_I64 = 0x1f
9244
};
9245

    
9246
/* I8 funct field */
9247
enum {
9248
  I8_BTEQZ = 0x0,
9249
  I8_BTNEZ = 0x1,
9250
  I8_SWRASP = 0x2,
9251
  I8_ADJSP = 0x3,
9252
  I8_SVRS = 0x4,
9253
  I8_MOV32R = 0x5,
9254
  I8_MOVR32 = 0x7
9255
};
9256

    
9257
/* RRR f field */
9258
enum {
9259
  RRR_DADDU = 0x0,
9260
  RRR_ADDU = 0x1,
9261
  RRR_DSUBU = 0x2,
9262
  RRR_SUBU = 0x3
9263
};
9264

    
9265
/* RR funct field */
9266
enum {
9267
  RR_JR = 0x00,
9268
  RR_SDBBP = 0x01,
9269
  RR_SLT = 0x02,
9270
  RR_SLTU = 0x03,
9271
  RR_SLLV = 0x04,
9272
  RR_BREAK = 0x05,
9273
  RR_SRLV = 0x06,
9274
  RR_SRAV = 0x07,
9275
  RR_DSRL = 0x08,
9276
  RR_CMP = 0x0a,
9277
  RR_NEG = 0x0b,
9278
  RR_AND = 0x0c,
9279
  RR_OR = 0x0d,
9280
  RR_XOR = 0x0e,
9281
  RR_NOT = 0x0f,
9282
  RR_MFHI = 0x10,
9283
  RR_CNVT = 0x11,
9284
  RR_MFLO = 0x12,
9285
  RR_DSRA = 0x13,
9286
  RR_DSLLV = 0x14,
9287
  RR_DSRLV = 0x16,
9288
  RR_DSRAV = 0x17,
9289
  RR_MULT = 0x18,
9290
  RR_MULTU = 0x19,
9291
  RR_DIV = 0x1a,
9292
  RR_DIVU = 0x1b,
9293
  RR_DMULT = 0x1c,
9294
  RR_DMULTU = 0x1d,
9295
  RR_DDIV = 0x1e,
9296
  RR_DDIVU = 0x1f
9297
};
9298

    
9299
/* I64 funct field */
9300
enum {
9301
  I64_LDSP = 0x0,
9302
  I64_SDSP = 0x1,
9303
  I64_SDRASP = 0x2,
9304
  I64_DADJSP = 0x3,
9305
  I64_LDPC = 0x4,
9306
  I64_DADDIU5 = 0x5,
9307
  I64_DADDIUPC = 0x6,
9308
  I64_DADDIUSP = 0x7
9309
};
9310

    
9311
/* RR ry field for CNVT */
9312
enum {
9313
  RR_RY_CNVT_ZEB = 0x0,
9314
  RR_RY_CNVT_ZEH = 0x1,
9315
  RR_RY_CNVT_ZEW = 0x2,
9316
  RR_RY_CNVT_SEB = 0x4,
9317
  RR_RY_CNVT_SEH = 0x5,
9318
  RR_RY_CNVT_SEW = 0x6,
9319
};
9320

    
9321
static int xlat (int r)
9322
{
9323
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9324

    
9325
  return map[r];
9326
}
9327

    
9328
static void gen_mips16_save (DisasContext *ctx,
9329
                             int xsregs, int aregs,
9330
                             int do_ra, int do_s0, int do_s1,
9331
                             int framesize)
9332
{
9333
    TCGv t0 = tcg_temp_new();
9334
    TCGv t1 = tcg_temp_new();
9335
    int args, astatic;
9336

    
9337
    switch (aregs) {
9338
    case 0:
9339
    case 1:
9340
    case 2:
9341
    case 3:
9342
    case 11:
9343
        args = 0;
9344
        break;
9345
    case 4:
9346
    case 5:
9347
    case 6:
9348
    case 7:
9349
        args = 1;
9350
        break;
9351
    case 8:
9352
    case 9:
9353
    case 10:
9354
        args = 2;
9355
        break;
9356
    case 12:
9357
    case 13:
9358
        args = 3;
9359
        break;
9360
    case 14:
9361
        args = 4;
9362
        break;
9363
    default:
9364
        generate_exception(ctx, EXCP_RI);
9365
        return;
9366
    }
9367

    
9368
    switch (args) {
9369
    case 4:
9370
        gen_base_offset_addr(ctx, t0, 29, 12);
9371
        gen_load_gpr(t1, 7);
9372
        op_st_sw(t1, t0, ctx);
9373
        /* Fall through */
9374
    case 3:
9375
        gen_base_offset_addr(ctx, t0, 29, 8);
9376
        gen_load_gpr(t1, 6);
9377
        op_st_sw(t1, t0, ctx);
9378
        /* Fall through */
9379
    case 2:
9380
        gen_base_offset_addr(ctx, t0, 29, 4);
9381
        gen_load_gpr(t1, 5);
9382
        op_st_sw(t1, t0, ctx);
9383
        /* Fall through */
9384
    case 1:
9385
        gen_base_offset_addr(ctx, t0, 29, 0);
9386
        gen_load_gpr(t1, 4);
9387
        op_st_sw(t1, t0, ctx);
9388
    }
9389

    
9390
    gen_load_gpr(t0, 29);
9391

    
9392
#define DECR_AND_STORE(reg) do {                \
9393
        tcg_gen_subi_tl(t0, t0, 4);             \
9394
        gen_load_gpr(t1, reg);                  \
9395
        op_st_sw(t1, t0, ctx);                  \
9396
    } while (0)
9397

    
9398
    if (do_ra) {
9399
        DECR_AND_STORE(31);
9400
    }
9401

    
9402
    switch (xsregs) {
9403
    case 7:
9404
        DECR_AND_STORE(30);
9405
        /* Fall through */
9406
    case 6:
9407
        DECR_AND_STORE(23);
9408
        /* Fall through */
9409
    case 5:
9410
        DECR_AND_STORE(22);
9411
        /* Fall through */
9412
    case 4:
9413
        DECR_AND_STORE(21);
9414
        /* Fall through */
9415
    case 3:
9416
        DECR_AND_STORE(20);
9417
        /* Fall through */
9418
    case 2:
9419
        DECR_AND_STORE(19);
9420
        /* Fall through */
9421
    case 1:
9422
        DECR_AND_STORE(18);
9423
    }
9424

    
9425
    if (do_s1) {
9426
        DECR_AND_STORE(17);
9427
    }
9428
    if (do_s0) {
9429
        DECR_AND_STORE(16);
9430
    }
9431

    
9432
    switch (aregs) {
9433
    case 0:
9434
    case 4:
9435
    case 8:
9436
    case 12:
9437
    case 14:
9438
        astatic = 0;
9439
        break;
9440
    case 1:
9441
    case 5:
9442
    case 9:
9443
    case 13:
9444
        astatic = 1;
9445
        break;
9446
    case 2:
9447
    case 6:
9448
    case 10:
9449
        astatic = 2;
9450
        break;
9451
    case 3:
9452
    case 7:
9453
        astatic = 3;
9454
        break;
9455
    case 11:
9456
        astatic = 4;
9457
        break;
9458
    default:
9459
        generate_exception(ctx, EXCP_RI);
9460
        return;
9461
    }
9462

    
9463
    if (astatic > 0) {
9464
        DECR_AND_STORE(7);
9465
        if (astatic > 1) {
9466
            DECR_AND_STORE(6);
9467
            if (astatic > 2) {
9468
                DECR_AND_STORE(5);
9469
                if (astatic > 3) {
9470
                    DECR_AND_STORE(4);
9471
                }
9472
            }
9473
        }
9474
    }
9475
#undef DECR_AND_STORE
9476

    
9477
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9478
    tcg_temp_free(t0);
9479
    tcg_temp_free(t1);
9480
}
9481

    
9482
static void gen_mips16_restore (DisasContext *ctx,
9483
                                int xsregs, int aregs,
9484
                                int do_ra, int do_s0, int do_s1,
9485
                                int framesize)
9486
{
9487
    int astatic;
9488
    TCGv t0 = tcg_temp_new();
9489
    TCGv t1 = tcg_temp_new();
9490

    
9491
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9492

    
9493
#define DECR_AND_LOAD(reg) do {                 \
9494
        tcg_gen_subi_tl(t0, t0, 4);             \
9495
        op_ld_lw(t1, t0, ctx);                  \
9496
        gen_store_gpr(t1, reg);                 \
9497
    } while (0)
9498

    
9499
    if (do_ra) {
9500
        DECR_AND_LOAD(31);
9501
    }
9502

    
9503
    switch (xsregs) {
9504
    case 7:
9505
        DECR_AND_LOAD(30);
9506
        /* Fall through */
9507
    case 6:
9508
        DECR_AND_LOAD(23);
9509
        /* Fall through */
9510
    case 5:
9511
        DECR_AND_LOAD(22);
9512
        /* Fall through */
9513
    case 4:
9514
        DECR_AND_LOAD(21);
9515
        /* Fall through */
9516
    case 3:
9517
        DECR_AND_LOAD(20);
9518
        /* Fall through */
9519
    case 2:
9520
        DECR_AND_LOAD(19);
9521
        /* Fall through */
9522
    case 1:
9523
        DECR_AND_LOAD(18);
9524
    }
9525

    
9526
    if (do_s1) {
9527
        DECR_AND_LOAD(17);
9528
    }
9529
    if (do_s0) {
9530
        DECR_AND_LOAD(16);
9531
    }
9532

    
9533
    switch (aregs) {
9534
    case 0:
9535
    case 4:
9536
    case 8:
9537
    case 12:
9538
    case 14:
9539
        astatic = 0;
9540
        break;
9541
    case 1:
9542
    case 5:
9543
    case 9:
9544
    case 13:
9545
        astatic = 1;
9546
        break;
9547
    case 2:
9548
    case 6:
9549
    case 10:
9550
        astatic = 2;
9551
        break;
9552
    case 3:
9553
    case 7:
9554
        astatic = 3;
9555
        break;
9556
    case 11:
9557
        astatic = 4;
9558
        break;
9559
    default:
9560
        generate_exception(ctx, EXCP_RI);
9561
        return;
9562
    }
9563

    
9564
    if (astatic > 0) {
9565
        DECR_AND_LOAD(7);
9566
        if (astatic > 1) {
9567
            DECR_AND_LOAD(6);
9568
            if (astatic > 2) {
9569
                DECR_AND_LOAD(5);
9570
                if (astatic > 3) {
9571
                    DECR_AND_LOAD(4);
9572
                }
9573
            }
9574
        }
9575
    }
9576
#undef DECR_AND_LOAD
9577

    
9578
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9579
    tcg_temp_free(t0);
9580
    tcg_temp_free(t1);
9581
}
9582

    
9583
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9584
                         int is_64_bit, int extended)
9585
{
9586
    TCGv t0;
9587

    
9588
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9589
        generate_exception(ctx, EXCP_RI);
9590
        return;
9591
    }
9592

    
9593
    t0 = tcg_temp_new();
9594

    
9595
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9596
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9597
    if (!is_64_bit) {
9598
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9599
    }
9600

    
9601
    tcg_temp_free(t0);
9602
}
9603

    
9604
#if defined(TARGET_MIPS64)
9605
static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9606
                               int ry, int funct, int16_t offset,
9607
                               int extended)
9608
{
9609
    switch (funct) {
9610
    case I64_LDSP:
9611
        check_mips_64(ctx);
9612
        offset = extended ? offset : offset << 3;
9613
        gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9614
        break;
9615
    case I64_SDSP:
9616
        check_mips_64(ctx);
9617
        offset = extended ? offset : offset << 3;
9618
        gen_st(ctx, OPC_SD, ry, 29, offset);
9619
        break;
9620
    case I64_SDRASP:
9621
        check_mips_64(ctx);
9622
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9623
        gen_st(ctx, OPC_SD, 31, 29, offset);
9624
        break;
9625
    case I64_DADJSP:
9626
        check_mips_64(ctx);
9627
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9628
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9629
        break;
9630
    case I64_LDPC:
9631
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9632
            generate_exception(ctx, EXCP_RI);
9633
        } else {
9634
            offset = extended ? offset : offset << 3;
9635
            gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9636
        }
9637
        break;
9638
    case I64_DADDIU5:
9639
        check_mips_64(ctx);
9640
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9641
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9642
        break;
9643
    case I64_DADDIUPC:
9644
        check_mips_64(ctx);
9645
        offset = extended ? offset : offset << 2;
9646
        gen_addiupc(ctx, ry, offset, 1, extended);
9647
        break;
9648
    case I64_DADDIUSP:
9649
        check_mips_64(ctx);
9650
        offset = extended ? offset : offset << 2;
9651
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9652
        break;
9653
    }
9654
}
9655
#endif
9656

    
9657
static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9658
                                       int *is_branch)
9659
{
9660
    int extend = cpu_lduw_code(env, ctx->pc + 2);
9661
    int op, rx, ry, funct, sa;
9662
    int16_t imm, offset;
9663

    
9664
    ctx->opcode = (ctx->opcode << 16) | extend;
9665
    op = (ctx->opcode >> 11) & 0x1f;
9666
    sa = (ctx->opcode >> 22) & 0x1f;
9667
    funct = (ctx->opcode >> 8) & 0x7;
9668
    rx = xlat((ctx->opcode >> 8) & 0x7);
9669
    ry = xlat((ctx->opcode >> 5) & 0x7);
9670
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9671
                              | ((ctx->opcode >> 21) & 0x3f) << 5
9672
                              | (ctx->opcode & 0x1f));
9673

    
9674
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9675
       counterparts.  */
9676
    switch (op) {
9677
    case M16_OPC_ADDIUSP:
9678
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9679
        break;
9680
    case M16_OPC_ADDIUPC:
9681
        gen_addiupc(ctx, rx, imm, 0, 1);
9682
        break;
9683
    case M16_OPC_B:
9684
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9685
        /* No delay slot, so just process as a normal instruction */
9686
        break;
9687
    case M16_OPC_BEQZ:
9688
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9689
        /* No delay slot, so just process as a normal instruction */
9690
        break;
9691
    case M16_OPC_BNEQZ:
9692
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9693
        /* No delay slot, so just process as a normal instruction */
9694
        break;
9695
    case M16_OPC_SHIFT:
9696
        switch (ctx->opcode & 0x3) {
9697
        case 0x0:
9698
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9699
            break;
9700
        case 0x1:
9701
#if defined(TARGET_MIPS64)
9702
            check_mips_64(ctx);
9703
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9704
#else
9705
            generate_exception(ctx, EXCP_RI);
9706
#endif
9707
            break;
9708
        case 0x2:
9709
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9710
            break;
9711
        case 0x3:
9712
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9713
            break;
9714
        }
9715
        break;
9716
#if defined(TARGET_MIPS64)
9717
    case M16_OPC_LD:
9718
            check_mips_64(ctx);
9719
        gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9720
        break;
9721
#endif
9722
    case M16_OPC_RRIA:
9723
        imm = ctx->opcode & 0xf;
9724
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9725
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9726
        imm = (int16_t) (imm << 1) >> 1;
9727
        if ((ctx->opcode >> 4) & 0x1) {
9728
#if defined(TARGET_MIPS64)
9729
            check_mips_64(ctx);
9730
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9731
#else
9732
            generate_exception(ctx, EXCP_RI);
9733
#endif
9734
        } else {
9735
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9736
        }
9737
        break;
9738
    case M16_OPC_ADDIU8:
9739
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9740
        break;
9741
    case M16_OPC_SLTI:
9742
        gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9743
        break;
9744
    case M16_OPC_SLTIU:
9745
        gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9746
        break;
9747
    case M16_OPC_I8:
9748
        switch (funct) {
9749
        case I8_BTEQZ:
9750
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9751
            break;
9752
        case I8_BTNEZ:
9753
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9754
            break;
9755
        case I8_SWRASP:
9756
            gen_st(ctx, OPC_SW, 31, 29, imm);
9757
            break;
9758
        case I8_ADJSP:
9759
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9760
            break;
9761
        case I8_SVRS:
9762
            {
9763
                int xsregs = (ctx->opcode >> 24) & 0x7;
9764
                int aregs = (ctx->opcode >> 16) & 0xf;
9765
                int do_ra = (ctx->opcode >> 6) & 0x1;
9766
                int do_s0 = (ctx->opcode >> 5) & 0x1;
9767
                int do_s1 = (ctx->opcode >> 4) & 0x1;
9768
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9769
                                 | (ctx->opcode & 0xf)) << 3;
9770

    
9771
                if (ctx->opcode & (1 << 7)) {
9772
                    gen_mips16_save(ctx, xsregs, aregs,
9773
                                    do_ra, do_s0, do_s1,
9774
                                    framesize);
9775
                } else {
9776
                    gen_mips16_restore(ctx, xsregs, aregs,
9777
                                       do_ra, do_s0, do_s1,
9778
                                       framesize);
9779
                }
9780
            }
9781
            break;
9782
        default:
9783
            generate_exception(ctx, EXCP_RI);
9784
            break;
9785
        }
9786
        break;
9787
    case M16_OPC_LI:
9788
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9789
        break;
9790
    case M16_OPC_CMPI:
9791
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9792
        break;
9793
#if defined(TARGET_MIPS64)
9794
    case M16_OPC_SD:
9795
        gen_st(ctx, OPC_SD, ry, rx, offset);
9796
        break;
9797
#endif
9798
    case M16_OPC_LB:
9799
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9800
        break;
9801
    case M16_OPC_LH:
9802
        gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9803
        break;
9804
    case M16_OPC_LWSP:
9805
        gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9806
        break;
9807
    case M16_OPC_LW:
9808
        gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9809
        break;
9810
    case M16_OPC_LBU:
9811
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9812
        break;
9813
    case M16_OPC_LHU:
9814
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9815
        break;
9816
    case M16_OPC_LWPC:
9817
        gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9818
        break;
9819
#if defined(TARGET_MIPS64)
9820
    case M16_OPC_LWU:
9821
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9822
        break;
9823
#endif
9824
    case M16_OPC_SB:
9825
        gen_st(ctx, OPC_SB, ry, rx, offset);
9826
        break;
9827
    case M16_OPC_SH:
9828
        gen_st(ctx, OPC_SH, ry, rx, offset);
9829
        break;
9830
    case M16_OPC_SWSP:
9831
        gen_st(ctx, OPC_SW, rx, 29, offset);
9832
        break;
9833
    case M16_OPC_SW:
9834
        gen_st(ctx, OPC_SW, ry, rx, offset);
9835
        break;
9836
#if defined(TARGET_MIPS64)
9837
    case M16_OPC_I64:
9838
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9839
        break;
9840
#endif
9841
    default:
9842
        generate_exception(ctx, EXCP_RI);
9843
        break;
9844
    }
9845

    
9846
    return 4;
9847
}
9848

    
9849
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9850
                              int *is_branch)
9851
{
9852
    int rx, ry;
9853
    int sa;
9854
    int op, cnvt_op, op1, offset;
9855
    int funct;
9856
    int n_bytes;
9857

    
9858
    op = (ctx->opcode >> 11) & 0x1f;
9859
    sa = (ctx->opcode >> 2) & 0x7;
9860
    sa = sa == 0 ? 8 : sa;
9861
    rx = xlat((ctx->opcode >> 8) & 0x7);
9862
    cnvt_op = (ctx->opcode >> 5) & 0x7;
9863
    ry = xlat((ctx->opcode >> 5) & 0x7);
9864
    op1 = offset = ctx->opcode & 0x1f;
9865

    
9866
    n_bytes = 2;
9867

    
9868
    switch (op) {
9869
    case M16_OPC_ADDIUSP:
9870
        {
9871
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
9872

    
9873
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9874
        }
9875
        break;
9876
    case M16_OPC_ADDIUPC:
9877
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9878
        break;
9879
    case M16_OPC_B:
9880
        offset = (ctx->opcode & 0x7ff) << 1;
9881
        offset = (int16_t)(offset << 4) >> 4;
9882
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9883
        /* No delay slot, so just process as a normal instruction */
9884
        break;
9885
    case M16_OPC_JAL:
9886
        offset = cpu_lduw_code(env, ctx->pc + 2);
9887
        offset = (((ctx->opcode & 0x1f) << 21)
9888
                  | ((ctx->opcode >> 5) & 0x1f) << 16
9889
                  | offset) << 2;
9890
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9891
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
9892
        n_bytes = 4;
9893
        *is_branch = 1;
9894
        break;
9895
    case M16_OPC_BEQZ:
9896
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9897
        /* No delay slot, so just process as a normal instruction */
9898
        break;
9899
    case M16_OPC_BNEQZ:
9900
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9901
        /* No delay slot, so just process as a normal instruction */
9902
        break;
9903
    case M16_OPC_SHIFT:
9904
        switch (ctx->opcode & 0x3) {
9905
        case 0x0:
9906
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9907
            break;
9908
        case 0x1:
9909
#if defined(TARGET_MIPS64)
9910
            check_mips_64(ctx);
9911
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9912
#else
9913
            generate_exception(ctx, EXCP_RI);
9914
#endif
9915
            break;
9916
        case 0x2:
9917
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9918
            break;
9919
        case 0x3:
9920
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9921
            break;
9922
        }
9923
        break;
9924
#if defined(TARGET_MIPS64)
9925
    case M16_OPC_LD:
9926
        check_mips_64(ctx);
9927
        gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9928
        break;
9929
#endif
9930
    case M16_OPC_RRIA:
9931
        {
9932
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9933

    
9934
            if ((ctx->opcode >> 4) & 1) {
9935
#if defined(TARGET_MIPS64)
9936
                check_mips_64(ctx);
9937
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9938
#else
9939
                generate_exception(ctx, EXCP_RI);
9940
#endif
9941
            } else {
9942
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9943
            }
9944
        }
9945
        break;
9946
    case M16_OPC_ADDIU8:
9947
        {
9948
            int16_t imm = (int8_t) ctx->opcode;
9949

    
9950
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9951
        }
9952
        break;
9953
    case M16_OPC_SLTI:
9954
        {
9955
            int16_t imm = (uint8_t) ctx->opcode;
9956
            gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9957
        }
9958
        break;
9959
    case M16_OPC_SLTIU:
9960
        {
9961
            int16_t imm = (uint8_t) ctx->opcode;
9962
            gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9963
        }
9964
        break;
9965
    case M16_OPC_I8:
9966
        {
9967
            int reg32;
9968

    
9969
            funct = (ctx->opcode >> 8) & 0x7;
9970
            switch (funct) {
9971
            case I8_BTEQZ:
9972
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9973
                                   ((int8_t)ctx->opcode) << 1);
9974
                break;
9975
            case I8_BTNEZ:
9976
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9977
                                   ((int8_t)ctx->opcode) << 1);
9978
                break;
9979
            case I8_SWRASP:
9980
                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9981
                break;
9982
            case I8_ADJSP:
9983
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9984
                              ((int8_t)ctx->opcode) << 3);
9985
                break;
9986
            case I8_SVRS:
9987
                {
9988
                    int do_ra = ctx->opcode & (1 << 6);
9989
                    int do_s0 = ctx->opcode & (1 << 5);
9990
                    int do_s1 = ctx->opcode & (1 << 4);
9991
                    int framesize = ctx->opcode & 0xf;
9992

    
9993
                    if (framesize == 0) {
9994
                        framesize = 128;
9995
                    } else {
9996
                        framesize = framesize << 3;
9997
                    }
9998

    
9999
                    if (ctx->opcode & (1 << 7)) {
10000
                        gen_mips16_save(ctx, 0, 0,
10001
                                        do_ra, do_s0, do_s1, framesize);
10002
                    } else {
10003
                        gen_mips16_restore(ctx, 0, 0,
10004
                                           do_ra, do_s0, do_s1, framesize);
10005
                    }
10006
                }
10007
                break;
10008
            case I8_MOV32R:
10009
                {
10010
                    int rz = xlat(ctx->opcode & 0x7);
10011

    
10012
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10013
                        ((ctx->opcode >> 5) & 0x7);
10014
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
10015
                }
10016
                break;
10017
            case I8_MOVR32:
10018
                reg32 = ctx->opcode & 0x1f;
10019
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
10020
                break;
10021
            default:
10022
                generate_exception(ctx, EXCP_RI);
10023
                break;
10024
            }
10025
        }
10026
        break;
10027
    case M16_OPC_LI:
10028
        {
10029
            int16_t imm = (uint8_t) ctx->opcode;
10030

    
10031
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10032
        }
10033
        break;
10034
    case M16_OPC_CMPI:
10035
        {
10036
            int16_t imm = (uint8_t) ctx->opcode;
10037
            gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10038
        }
10039
        break;
10040
#if defined(TARGET_MIPS64)
10041
    case M16_OPC_SD:
10042
        check_mips_64(ctx);
10043
        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10044
        break;
10045
#endif
10046
    case M16_OPC_LB:
10047
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10048
        break;
10049
    case M16_OPC_LH:
10050
        gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10051
        break;
10052
    case M16_OPC_LWSP:
10053
        gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10054
        break;
10055
    case M16_OPC_LW:
10056
        gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10057
        break;
10058
    case M16_OPC_LBU:
10059
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10060
        break;
10061
    case M16_OPC_LHU:
10062
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10063
        break;
10064
    case M16_OPC_LWPC:
10065
        gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10066
        break;
10067
#if defined (TARGET_MIPS64)
10068
    case M16_OPC_LWU:
10069
        check_mips_64(ctx);
10070
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10071
        break;
10072
#endif
10073
    case M16_OPC_SB:
10074
        gen_st(ctx, OPC_SB, ry, rx, offset);
10075
        break;
10076
    case M16_OPC_SH:
10077
        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10078
        break;
10079
    case M16_OPC_SWSP:
10080
        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10081
        break;
10082
    case M16_OPC_SW:
10083
        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10084
        break;
10085
    case M16_OPC_RRR:
10086
        {
10087
            int rz = xlat((ctx->opcode >> 2) & 0x7);
10088
            int mips32_op;
10089

    
10090
            switch (ctx->opcode & 0x3) {
10091
            case RRR_ADDU:
10092
                mips32_op = OPC_ADDU;
10093
                break;
10094
            case RRR_SUBU:
10095
                mips32_op = OPC_SUBU;
10096
                break;
10097
#if defined(TARGET_MIPS64)
10098
            case RRR_DADDU:
10099
                mips32_op = OPC_DADDU;
10100
                check_mips_64(ctx);
10101
                break;
10102
            case RRR_DSUBU:
10103
                mips32_op = OPC_DSUBU;
10104
                check_mips_64(ctx);
10105
                break;
10106
#endif
10107
            default:
10108
                generate_exception(ctx, EXCP_RI);
10109
                goto done;
10110
            }
10111

    
10112
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
10113
        done:
10114
            ;
10115
        }
10116
        break;
10117
    case M16_OPC_RR:
10118
        switch (op1) {
10119
        case RR_JR:
10120
            {
10121
                int nd = (ctx->opcode >> 7) & 0x1;
10122
                int link = (ctx->opcode >> 6) & 0x1;
10123
                int ra = (ctx->opcode >> 5) & 0x1;
10124

    
10125
                if (link) {
10126
                    op = nd ? OPC_JALRC : OPC_JALRS;
10127
                } else {
10128
                    op = OPC_JR;
10129
                }
10130

    
10131
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10132
                if (!nd) {
10133
                    *is_branch = 1;
10134
                }
10135
            }
10136
            break;
10137
        case RR_SDBBP:
10138
            /* XXX: not clear which exception should be raised
10139
             *      when in debug mode...
10140
             */
10141
            check_insn(env, ctx, ISA_MIPS32);
10142
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10143
                generate_exception(ctx, EXCP_DBp);
10144
            } else {
10145
                generate_exception(ctx, EXCP_DBp);
10146
            }
10147
            break;
10148
        case RR_SLT:
10149
            gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10150
            break;
10151
        case RR_SLTU:
10152
            gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10153
            break;
10154
        case RR_BREAK:
10155
            generate_exception(ctx, EXCP_BREAK);
10156
            break;
10157
        case RR_SLLV:
10158
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10159
            break;
10160
        case RR_SRLV:
10161
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10162
            break;
10163
        case RR_SRAV:
10164
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10165
            break;
10166
#if defined (TARGET_MIPS64)
10167
        case RR_DSRL:
10168
            check_mips_64(ctx);
10169
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10170
            break;
10171
#endif
10172
        case RR_CMP:
10173
            gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10174
            break;
10175
        case RR_NEG:
10176
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10177
            break;
10178
        case RR_AND:
10179
            gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10180
            break;
10181
        case RR_OR:
10182
            gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10183
            break;
10184
        case RR_XOR:
10185
            gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10186
            break;
10187
        case RR_NOT:
10188
            gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10189
            break;
10190
        case RR_MFHI:
10191
            gen_HILO(ctx, OPC_MFHI, rx);
10192
            break;
10193
        case RR_CNVT:
10194
            switch (cnvt_op) {
10195
            case RR_RY_CNVT_ZEB:
10196
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10197
                break;
10198
            case RR_RY_CNVT_ZEH:
10199
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10200
                break;
10201
            case RR_RY_CNVT_SEB:
10202
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10203
                break;
10204
            case RR_RY_CNVT_SEH:
10205
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10206
                break;
10207
#if defined (TARGET_MIPS64)
10208
            case RR_RY_CNVT_ZEW:
10209
                check_mips_64(ctx);
10210
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10211
                break;
10212
            case RR_RY_CNVT_SEW:
10213
                check_mips_64(ctx);
10214
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10215
                break;
10216
#endif
10217
            default:
10218
                generate_exception(ctx, EXCP_RI);
10219
                break;
10220
            }
10221
            break;
10222
        case RR_MFLO:
10223
            gen_HILO(ctx, OPC_MFLO, rx);
10224
            break;
10225
#if defined (TARGET_MIPS64)
10226
        case RR_DSRA:
10227
            check_mips_64(ctx);
10228
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10229
            break;
10230
        case RR_DSLLV:
10231
            check_mips_64(ctx);
10232
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10233
            break;
10234
        case RR_DSRLV:
10235
            check_mips_64(ctx);
10236
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10237
            break;
10238
        case RR_DSRAV:
10239
            check_mips_64(ctx);
10240
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10241
            break;
10242
#endif
10243
        case RR_MULT:
10244
            gen_muldiv(ctx, OPC_MULT, rx, ry);
10245
            break;
10246
        case RR_MULTU:
10247
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
10248
            break;
10249
        case RR_DIV:
10250
            gen_muldiv(ctx, OPC_DIV, rx, ry);
10251
            break;
10252
        case RR_DIVU:
10253
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
10254
            break;
10255
#if defined (TARGET_MIPS64)
10256
        case RR_DMULT:
10257
            check_mips_64(ctx);
10258
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
10259
            break;
10260
        case RR_DMULTU:
10261
            check_mips_64(ctx);
10262
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10263
            break;
10264
        case RR_DDIV:
10265
            check_mips_64(ctx);
10266
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
10267
            break;
10268
        case RR_DDIVU:
10269
            check_mips_64(ctx);
10270
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10271
            break;
10272
#endif
10273
        default:
10274
            generate_exception(ctx, EXCP_RI);
10275
            break;
10276
        }
10277
        break;
10278
    case M16_OPC_EXTEND:
10279
        decode_extended_mips16_opc(env, ctx, is_branch);
10280
        n_bytes = 4;
10281
        break;
10282
#if defined(TARGET_MIPS64)
10283
    case M16_OPC_I64:
10284
        funct = (ctx->opcode >> 8) & 0x7;
10285
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10286
        break;
10287
#endif
10288
    default:
10289
        generate_exception(ctx, EXCP_RI);
10290
        break;
10291
    }
10292

    
10293
    return n_bytes;
10294
}
10295

    
10296
/* microMIPS extension to MIPS32 */
10297

    
10298
/* microMIPS32 major opcodes */
10299

    
10300
enum {
10301
    POOL32A = 0x00,
10302
    POOL16A = 0x01,
10303
    LBU16 = 0x02,
10304
    MOVE16 = 0x03,
10305
    ADDI32 = 0x04,
10306
    LBU32 = 0x05,
10307
    SB32 = 0x06,
10308
    LB32 = 0x07,
10309

    
10310
    POOL32B = 0x08,
10311
    POOL16B = 0x09,
10312
    LHU16 = 0x0a,
10313
    ANDI16 = 0x0b,
10314
    ADDIU32 = 0x0c,
10315
    LHU32 = 0x0d,
10316
    SH32 = 0x0e,
10317
    LH32 = 0x0f,
10318

    
10319
    POOL32I = 0x10,
10320
    POOL16C = 0x11,
10321
    LWSP16 = 0x12,
10322
    POOL16D = 0x13,
10323
    ORI32 = 0x14,
10324
    POOL32F = 0x15,
10325
    POOL32S = 0x16,
10326
    DADDIU32 = 0x17,
10327

    
10328
    POOL32C = 0x18,
10329
    LWGP16 = 0x19,
10330
    LW16 = 0x1a,
10331
    POOL16E = 0x1b,
10332
    XORI32 = 0x1c,
10333
    JALS32 = 0x1d,
10334
    ADDIUPC = 0x1e,
10335
    POOL48A = 0x1f,
10336

    
10337
    /* 0x20 is reserved */
10338
    RES_20 = 0x20,
10339
    POOL16F = 0x21,
10340
    SB16 = 0x22,
10341
    BEQZ16 = 0x23,
10342
    SLTI32 = 0x24,
10343
    BEQ32 = 0x25,
10344
    SWC132 = 0x26,
10345
    LWC132 = 0x27,
10346

    
10347
    /* 0x28 and 0x29 are reserved */
10348
    RES_28 = 0x28,
10349
    RES_29 = 0x29,
10350
    SH16 = 0x2a,
10351
    BNEZ16 = 0x2b,
10352
    SLTIU32 = 0x2c,
10353
    BNE32 = 0x2d,
10354
    SDC132 = 0x2e,
10355
    LDC132 = 0x2f,
10356

    
10357
    /* 0x30 and 0x31 are reserved */
10358
    RES_30 = 0x30,
10359
    RES_31 = 0x31,
10360
    SWSP16 = 0x32,
10361
    B16 = 0x33,
10362
    ANDI32 = 0x34,
10363
    J32 = 0x35,
10364
    SD32 = 0x36,
10365
    LD32 = 0x37,
10366

    
10367
    /* 0x38 and 0x39 are reserved */
10368
    RES_38 = 0x38,
10369
    RES_39 = 0x39,
10370
    SW16 = 0x3a,
10371
    LI16 = 0x3b,
10372
    JALX32 = 0x3c,
10373
    JAL32 = 0x3d,
10374
    SW32 = 0x3e,
10375
    LW32 = 0x3f
10376
};
10377

    
10378
/* POOL32A encoding of minor opcode field */
10379

    
10380
enum {
10381
    /* These opcodes are distinguished only by bits 9..6; those bits are
10382
     * what are recorded below. */
10383
    SLL32 = 0x0,
10384
    SRL32 = 0x1,
10385
    SRA = 0x2,
10386
    ROTR = 0x3,
10387

    
10388
    SLLV = 0x0,
10389
    SRLV = 0x1,
10390
    SRAV = 0x2,
10391
    ROTRV = 0x3,
10392
    ADD = 0x4,
10393
    ADDU32 = 0x5,
10394
    SUB = 0x6,
10395
    SUBU32 = 0x7,
10396
    MUL = 0x8,
10397
    AND = 0x9,
10398
    OR32 = 0xa,
10399
    NOR = 0xb,
10400
    XOR32 = 0xc,
10401
    SLT = 0xd,
10402
    SLTU = 0xe,
10403

    
10404
    MOVN = 0x0,
10405
    MOVZ = 0x1,
10406
    LWXS = 0x4,
10407

    
10408
    /* The following can be distinguished by their lower 6 bits. */
10409
    INS = 0x0c,
10410
    EXT = 0x2c,
10411
    POOL32AXF = 0x3c
10412
};
10413

    
10414
/* POOL32AXF encoding of minor opcode field extension */
10415

    
10416
enum {
10417
    /* bits 11..6 */
10418
    TEQ = 0x00,
10419
    TGE = 0x08,
10420
    TGEU = 0x10,
10421
    TLT = 0x20,
10422
    TLTU = 0x28,
10423
    TNE = 0x30,
10424

    
10425
    MFC0 = 0x03,
10426
    MTC0 = 0x0b,
10427

    
10428
    /* bits 13..12 for 0x01 */
10429
    MFHI_ACC = 0x0,
10430
    MFLO_ACC = 0x1,
10431
    MTHI_ACC = 0x2,
10432
    MTLO_ACC = 0x3,
10433

    
10434
    /* bits 13..12 for 0x2a */
10435
    MADD_ACC = 0x0,
10436
    MADDU_ACC = 0x1,
10437
    MSUB_ACC = 0x2,
10438
    MSUBU_ACC = 0x3,
10439

    
10440
    /* bits 13..12 for 0x32 */
10441
    MULT_ACC = 0x0,
10442
    MULTU_ACC = 0x0,
10443

    
10444
    /* bits 15..12 for 0x2c */
10445
    SEB = 0x2,
10446
    SEH = 0x3,
10447
    CLO = 0x4,
10448
    CLZ = 0x5,
10449
    RDHWR = 0x6,
10450
    WSBH = 0x7,
10451
    MULT = 0x8,
10452
    MULTU = 0x9,
10453
    DIV = 0xa,
10454
    DIVU = 0xb,
10455
    MADD = 0xc,
10456
    MADDU = 0xd,
10457
    MSUB = 0xe,
10458
    MSUBU = 0xf,
10459

    
10460
    /* bits 15..12 for 0x34 */
10461
    MFC2 = 0x4,
10462
    MTC2 = 0x5,
10463
    MFHC2 = 0x8,
10464
    MTHC2 = 0x9,
10465
    CFC2 = 0xc,
10466
    CTC2 = 0xd,
10467

    
10468
    /* bits 15..12 for 0x3c */
10469
    JALR = 0x0,
10470
    JR = 0x0,                   /* alias */
10471
    JALR_HB = 0x1,
10472
    JALRS = 0x4,
10473
    JALRS_HB = 0x5,
10474

    
10475
    /* bits 15..12 for 0x05 */
10476
    RDPGPR = 0xe,
10477
    WRPGPR = 0xf,
10478

    
10479
    /* bits 15..12 for 0x0d */
10480
    TLBP = 0x0,
10481
    TLBR = 0x1,
10482
    TLBWI = 0x2,
10483
    TLBWR = 0x3,
10484
    WAIT = 0x9,
10485
    IRET = 0xd,
10486
    DERET = 0xe,
10487
    ERET = 0xf,
10488

    
10489
    /* bits 15..12 for 0x15 */
10490
    DMT = 0x0,
10491
    DVPE = 0x1,
10492
    EMT = 0x2,
10493
    EVPE = 0x3,
10494

    
10495
    /* bits 15..12 for 0x1d */
10496
    DI = 0x4,
10497
    EI = 0x5,
10498

    
10499
    /* bits 15..12 for 0x2d */
10500
    SYNC = 0x6,
10501
    SYSCALL = 0x8,
10502
    SDBBP = 0xd,
10503

    
10504
    /* bits 15..12 for 0x35 */
10505
    MFHI32 = 0x0,
10506
    MFLO32 = 0x1,
10507
    MTHI32 = 0x2,
10508
    MTLO32 = 0x3,
10509
};
10510

    
10511
/* POOL32B encoding of minor opcode field (bits 15..12) */
10512

    
10513
enum {
10514
    LWC2 = 0x0,
10515
    LWP = 0x1,
10516
    LDP = 0x4,
10517
    LWM32 = 0x5,
10518
    CACHE = 0x6,
10519
    LDM = 0x7,
10520
    SWC2 = 0x8,
10521
    SWP = 0x9,
10522
    SDP = 0xc,
10523
    SWM32 = 0xd,
10524
    SDM = 0xf
10525
};
10526

    
10527
/* POOL32C encoding of minor opcode field (bits 15..12) */
10528

    
10529
enum {
10530
    LWL = 0x0,
10531
    SWL = 0x8,
10532
    LWR = 0x1,
10533
    SWR = 0x9,
10534
    PREF = 0x2,
10535
    /* 0xa is reserved */
10536
    LL = 0x3,
10537
    SC = 0xb,
10538
    LDL = 0x4,
10539
    SDL = 0xc,
10540
    LDR = 0x5,
10541
    SDR = 0xd,
10542
    /* 0x6 is reserved */
10543
    LWU = 0xe,
10544
    LLD = 0x7,
10545
    SCD = 0xf
10546
};
10547

    
10548
/* POOL32F encoding of minor opcode field (bits 5..0) */
10549

    
10550
enum {
10551
    /* These are the bit 7..6 values */
10552
    ADD_FMT = 0x0,
10553
    MOVN_FMT = 0x0,
10554

    
10555
    SUB_FMT = 0x1,
10556
    MOVZ_FMT = 0x1,
10557

    
10558
    MUL_FMT = 0x2,
10559

    
10560
    DIV_FMT = 0x3,
10561

    
10562
    /* These are the bit 8..6 values */
10563
    RSQRT2_FMT = 0x0,
10564
    MOVF_FMT = 0x0,
10565

    
10566
    LWXC1 = 0x1,
10567
    MOVT_FMT = 0x1,
10568

    
10569
    PLL_PS = 0x2,
10570
    SWXC1 = 0x2,
10571

    
10572
    PLU_PS = 0x3,
10573
    LDXC1 = 0x3,
10574

    
10575
    PUL_PS = 0x4,
10576
    SDXC1 = 0x4,
10577
    RECIP2_FMT = 0x4,
10578

    
10579
    PUU_PS = 0x5,
10580
    LUXC1 = 0x5,
10581

    
10582
    CVT_PS_S = 0x6,
10583
    SUXC1 = 0x6,
10584
    ADDR_PS = 0x6,
10585
    PREFX = 0x6,
10586

    
10587
    MULR_PS = 0x7,
10588

    
10589
    MADD_S = 0x01,
10590
    MADD_D = 0x09,
10591
    MADD_PS = 0x11,
10592
    ALNV_PS = 0x19,
10593
    MSUB_S = 0x21,
10594
    MSUB_D = 0x29,
10595
    MSUB_PS = 0x31,
10596

    
10597
    NMADD_S = 0x02,
10598
    NMADD_D = 0x0a,
10599
    NMADD_PS = 0x12,
10600
    NMSUB_S = 0x22,
10601
    NMSUB_D = 0x2a,
10602
    NMSUB_PS = 0x32,
10603

    
10604
    POOL32FXF = 0x3b,
10605

    
10606
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
10607
    C_COND_FMT = 0x3c
10608
};
10609

    
10610
/* POOL32Fxf encoding of minor opcode extension field */
10611

    
10612
enum {
10613
    CVT_L = 0x04,
10614
    RSQRT_FMT = 0x08,
10615
    FLOOR_L = 0x0c,
10616
    CVT_PW_PS = 0x1c,
10617
    CVT_W = 0x24,
10618
    SQRT_FMT = 0x28,
10619
    FLOOR_W = 0x2c,
10620
    CVT_PS_PW = 0x3c,
10621
    CFC1 = 0x40,
10622
    RECIP_FMT = 0x48,
10623
    CEIL_L = 0x4c,
10624
    CTC1 = 0x60,
10625
    CEIL_W = 0x6c,
10626
    MFC1 = 0x80,
10627
    CVT_S_PL = 0x84,
10628
    TRUNC_L = 0x8c,
10629
    MTC1 = 0xa0,
10630
    CVT_S_PU = 0xa4,
10631
    TRUNC_W = 0xac,
10632
    MFHC1 = 0xc0,
10633
    ROUND_L = 0xcc,
10634
    MTHC1 = 0xe0,
10635
    ROUND_W = 0xec,
10636

    
10637
    MOV_FMT = 0x01,
10638
    MOVF = 0x05,
10639
    ABS_FMT = 0x0d,
10640
    RSQRT1_FMT = 0x1d,
10641
    MOVT = 0x25,
10642
    NEG_FMT = 0x2d,
10643
    CVT_D = 0x4d,
10644
    RECIP1_FMT = 0x5d,
10645
    CVT_S = 0x6d
10646
};
10647

    
10648
/* POOL32I encoding of minor opcode field (bits 25..21) */
10649

    
10650
enum {
10651
    BLTZ = 0x00,
10652
    BLTZAL = 0x01,
10653
    BGEZ = 0x02,
10654
    BGEZAL = 0x03,
10655
    BLEZ = 0x04,
10656
    BNEZC = 0x05,
10657
    BGTZ = 0x06,
10658
    BEQZC = 0x07,
10659
    TLTI = 0x08,
10660
    TGEI = 0x09,
10661
    TLTIU = 0x0a,
10662
    TGEIU = 0x0b,
10663
    TNEI = 0x0c,
10664
    LUI = 0x0d,
10665
    TEQI = 0x0e,
10666
    SYNCI = 0x10,
10667
    BLTZALS = 0x11,
10668
    BGEZALS = 0x13,
10669
    BC2F = 0x14,
10670
    BC2T = 0x15,
10671
    BPOSGE64 = 0x1a,
10672
    BPOSGE32 = 0x1b,
10673
    /* These overlap and are distinguished by bit16 of the instruction */
10674
    BC1F = 0x1c,
10675
    BC1T = 0x1d,
10676
    BC1ANY2F = 0x1c,
10677
    BC1ANY2T = 0x1d,
10678
    BC1ANY4F = 0x1e,
10679
    BC1ANY4T = 0x1f
10680
};
10681

    
10682
/* POOL16A encoding of minor opcode field */
10683

    
10684
enum {
10685
    ADDU16 = 0x0,
10686
    SUBU16 = 0x1
10687
};
10688

    
10689
/* POOL16B encoding of minor opcode field */
10690

    
10691
enum {
10692
    SLL16 = 0x0,
10693
    SRL16 = 0x1
10694
};
10695

    
10696
/* POOL16C encoding of minor opcode field */
10697

    
10698
enum {
10699
    NOT16 = 0x00,
10700
    XOR16 = 0x04,
10701
    AND16 = 0x08,
10702
    OR16 = 0x0c,
10703
    LWM16 = 0x10,
10704
    SWM16 = 0x14,
10705
    JR16 = 0x18,
10706
    JRC16 = 0x1a,
10707
    JALR16 = 0x1c,
10708
    JALR16S = 0x1e,
10709
    MFHI16 = 0x20,
10710
    MFLO16 = 0x24,
10711
    BREAK16 = 0x28,
10712
    SDBBP16 = 0x2c,
10713
    JRADDIUSP = 0x30
10714
};
10715

    
10716
/* POOL16D encoding of minor opcode field */
10717

    
10718
enum {
10719
    ADDIUS5 = 0x0,
10720
    ADDIUSP = 0x1
10721
};
10722

    
10723
/* POOL16E encoding of minor opcode field */
10724

    
10725
enum {
10726
    ADDIUR2 = 0x0,
10727
    ADDIUR1SP = 0x1
10728
};
10729

    
10730
static int mmreg (int r)
10731
{
10732
    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10733

    
10734
    return map[r];
10735
}
10736

    
10737
/* Used for 16-bit store instructions.  */
10738
static int mmreg2 (int r)
10739
{
10740
    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10741

    
10742
    return map[r];
10743
}
10744

    
10745
#define uMIPS_RD(op) ((op >> 7) & 0x7)
10746
#define uMIPS_RS(op) ((op >> 4) & 0x7)
10747
#define uMIPS_RS2(op) uMIPS_RS(op)
10748
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10749
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10750
#define uMIPS_RS5(op) (op & 0x1f)
10751

    
10752
/* Signed immediate */
10753
#define SIMM(op, start, width)                                          \
10754
    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
10755
               << (32-width))                                           \
10756
     >> (32-width))
10757
/* Zero-extended immediate */
10758
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10759

    
10760
static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10761
{
10762
    int rd = mmreg(uMIPS_RD(ctx->opcode));
10763

    
10764
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10765
}
10766

    
10767
static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10768
{
10769
    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10770
    int rd = mmreg(uMIPS_RD(ctx->opcode));
10771
    int rs = mmreg(uMIPS_RS(ctx->opcode));
10772

    
10773
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10774
}
10775

    
10776
static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10777
{
10778
    int encoded = ZIMM(ctx->opcode, 1, 9);
10779
    int decoded;
10780

    
10781
    if (encoded <= 1) {
10782
        decoded = 256 + encoded;
10783
    } else if (encoded <= 255) {
10784
        decoded = encoded;
10785
    } else if (encoded <= 509) {
10786
        decoded = encoded - 512;
10787
    } else {
10788
        decoded = encoded - 768;
10789
    }
10790

    
10791
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10792
}
10793

    
10794
static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10795
{
10796
    int imm = SIMM(ctx->opcode, 1, 4);
10797
    int rd = (ctx->opcode >> 5) & 0x1f;
10798

    
10799
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10800
}
10801

    
10802
static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10803
{
10804
    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10805
                                 31, 32, 63, 64, 255, 32768, 65535 };
10806
    int rd = mmreg(uMIPS_RD(ctx->opcode));
10807
    int rs = mmreg(uMIPS_RS(ctx->opcode));
10808
    int encoded = ZIMM(ctx->opcode, 0, 4);
10809

    
10810
    gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10811
}
10812

    
10813
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10814
                               int base, int16_t offset)
10815
{
10816
    const char *opn = "ldst_multiple";
10817
    TCGv t0, t1;
10818
    TCGv_i32 t2;
10819

    
10820
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10821
        generate_exception(ctx, EXCP_RI);
10822
        return;
10823
    }
10824

    
10825
    t0 = tcg_temp_new();
10826

    
10827
    gen_base_offset_addr(ctx, t0, base, offset);
10828

    
10829
    t1 = tcg_const_tl(reglist);
10830
    t2 = tcg_const_i32(ctx->mem_idx);
10831

    
10832
    save_cpu_state(ctx, 1);
10833
    switch (opc) {
10834
    case LWM32:
10835
        gen_helper_lwm(cpu_env, t0, t1, t2);
10836
        opn = "lwm";
10837
        break;
10838
    case SWM32:
10839
        gen_helper_swm(cpu_env, t0, t1, t2);
10840
        opn = "swm";
10841
        break;
10842
#ifdef TARGET_MIPS64
10843
    case LDM:
10844
        gen_helper_ldm(cpu_env, t0, t1, t2);
10845
        opn = "ldm";
10846
        break;
10847
    case SDM:
10848
        gen_helper_sdm(cpu_env, t0, t1, t2);
10849
        opn = "sdm";
10850
        break;
10851
#endif
10852
    }
10853
    (void)opn;
10854
    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10855
    tcg_temp_free(t0);
10856
    tcg_temp_free(t1);
10857
    tcg_temp_free_i32(t2);
10858
}
10859

    
10860

    
10861
static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10862
{
10863
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
10864
    int rs = mmreg(ctx->opcode & 0x7);
10865
    int opc;
10866

    
10867
    switch (((ctx->opcode) >> 4) & 0x3f) {
10868
    case NOT16 + 0:
10869
    case NOT16 + 1:
10870
    case NOT16 + 2:
10871
    case NOT16 + 3:
10872
        gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10873
        break;
10874
    case XOR16 + 0:
10875
    case XOR16 + 1:
10876
    case XOR16 + 2:
10877
    case XOR16 + 3:
10878
        gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10879
        break;
10880
    case AND16 + 0:
10881
    case AND16 + 1:
10882
    case AND16 + 2:
10883
    case AND16 + 3:
10884
        gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10885
        break;
10886
    case OR16 + 0:
10887
    case OR16 + 1:
10888
    case OR16 + 2:
10889
    case OR16 + 3:
10890
        gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10891
        break;
10892
    case LWM16 + 0:
10893
    case LWM16 + 1:
10894
    case LWM16 + 2:
10895
    case LWM16 + 3:
10896
        {
10897
            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10898
            int offset = ZIMM(ctx->opcode, 0, 4);
10899

    
10900
            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10901
                              29, offset << 2);
10902
        }
10903
        break;
10904
    case SWM16 + 0:
10905
    case SWM16 + 1:
10906
    case SWM16 + 2:
10907
    case SWM16 + 3:
10908
        {
10909
            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10910
            int offset = ZIMM(ctx->opcode, 0, 4);
10911

    
10912
            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10913
                              29, offset << 2);
10914
        }
10915
        break;
10916
    case JR16 + 0:
10917
    case JR16 + 1:
10918
        {
10919
            int reg = ctx->opcode & 0x1f;
10920

    
10921
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10922
        }
10923
        *is_branch = 1;
10924
        break;
10925
    case JRC16 + 0:
10926
    case JRC16 + 1:
10927
        {
10928
            int reg = ctx->opcode & 0x1f;
10929

    
10930
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10931
            /* Let normal delay slot handling in our caller take us
10932
               to the branch target.  */
10933
        }
10934
        break;
10935
    case JALR16 + 0:
10936
    case JALR16 + 1:
10937
        opc = OPC_JALR;
10938
        goto do_jalr;
10939
    case JALR16S + 0:
10940
    case JALR16S + 1:
10941
        opc = OPC_JALRS;
10942
    do_jalr:
10943
        {
10944
            int reg = ctx->opcode & 0x1f;
10945

    
10946
            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10947
        }
10948
        *is_branch = 1;
10949
        break;
10950
    case MFHI16 + 0:
10951
    case MFHI16 + 1:
10952
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10953
        break;
10954
    case MFLO16 + 0:
10955
    case MFLO16 + 1:
10956
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10957
        break;
10958
    case BREAK16:
10959
        generate_exception(ctx, EXCP_BREAK);
10960
        break;
10961
    case SDBBP16:
10962
        /* XXX: not clear which exception should be raised
10963
         *      when in debug mode...
10964
         */
10965
        check_insn(env, ctx, ISA_MIPS32);
10966
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10967
            generate_exception(ctx, EXCP_DBp);
10968
        } else {
10969
            generate_exception(ctx, EXCP_DBp);
10970
        }
10971
        break;
10972
    case JRADDIUSP + 0:
10973
    case JRADDIUSP + 1:
10974
        {
10975
            int imm = ZIMM(ctx->opcode, 0, 5);
10976

    
10977
            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10978
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10979
            /* Let normal delay slot handling in our caller take us
10980
               to the branch target.  */
10981
        }
10982
        break;
10983
    default:
10984
        generate_exception(ctx, EXCP_RI);
10985
        break;
10986
    }
10987
}
10988

    
10989
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10990
{
10991
    TCGv t0 = tcg_temp_new();
10992
    TCGv t1 = tcg_temp_new();
10993

    
10994
    gen_load_gpr(t0, base);
10995

    
10996
    if (index != 0) {
10997
        gen_load_gpr(t1, index);
10998
        tcg_gen_shli_tl(t1, t1, 2);
10999
        gen_op_addr_add(ctx, t0, t1, t0);
11000
    }
11001

    
11002
    save_cpu_state(ctx, 0);
11003
    op_ld_lw(t1, t0, ctx);
11004
    gen_store_gpr(t1, rd);
11005

    
11006
    tcg_temp_free(t0);
11007
    tcg_temp_free(t1);
11008
}
11009

    
11010
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11011
                           int base, int16_t offset)
11012
{
11013
    const char *opn = "ldst_pair";
11014
    TCGv t0, t1;
11015

    
11016
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
11017
        generate_exception(ctx, EXCP_RI);
11018
        return;
11019
    }
11020

    
11021
    t0 = tcg_temp_new();
11022
    t1 = tcg_temp_new();
11023

    
11024
    gen_base_offset_addr(ctx, t0, base, offset);
11025

    
11026
    switch (opc) {
11027
    case LWP:
11028
        if (rd == base) {
11029
            generate_exception(ctx, EXCP_RI);
11030
            return;
11031
        }
11032
        save_cpu_state(ctx, 0);
11033
        op_ld_lw(t1, t0, ctx);
11034
        gen_store_gpr(t1, rd);
11035
        tcg_gen_movi_tl(t1, 4);
11036
        gen_op_addr_add(ctx, t0, t0, t1);
11037
        op_ld_lw(t1, t0, ctx);
11038
        gen_store_gpr(t1, rd+1);
11039
        opn = "lwp";
11040
        break;
11041
    case SWP:
11042
        save_cpu_state(ctx, 0);
11043
        gen_load_gpr(t1, rd);
11044
        op_st_sw(t1, t0, ctx);
11045
        tcg_gen_movi_tl(t1, 4);
11046
        gen_op_addr_add(ctx, t0, t0, t1);
11047
        gen_load_gpr(t1, rd+1);
11048
        op_st_sw(t1, t0, ctx);
11049
        opn = "swp";
11050
        break;
11051
#ifdef TARGET_MIPS64
11052
    case LDP:
11053
        if (rd == base) {
11054
            generate_exception(ctx, EXCP_RI);
11055
            return;
11056
        }
11057
        save_cpu_state(ctx, 0);
11058
        op_ld_ld(t1, t0, ctx);
11059
        gen_store_gpr(t1, rd);
11060
        tcg_gen_movi_tl(t1, 8);
11061
        gen_op_addr_add(ctx, t0, t0, t1);
11062
        op_ld_ld(t1, t0, ctx);
11063
        gen_store_gpr(t1, rd+1);
11064
        opn = "ldp";
11065
        break;
11066
    case SDP:
11067
        save_cpu_state(ctx, 0);
11068
        gen_load_gpr(t1, rd);
11069
        op_st_sd(t1, t0, ctx);
11070
        tcg_gen_movi_tl(t1, 8);
11071
        gen_op_addr_add(ctx, t0, t0, t1);
11072
        gen_load_gpr(t1, rd+1);
11073
        op_st_sd(t1, t0, ctx);
11074
        opn = "sdp";
11075
        break;
11076
#endif
11077
    }
11078
    (void)opn; /* avoid a compiler warning */
11079
    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11080
    tcg_temp_free(t0);
11081
    tcg_temp_free(t1);
11082
}
11083

    
11084
static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11085
                           int *is_branch)
11086
{
11087
    int extension = (ctx->opcode >> 6) & 0x3f;
11088
    int minor = (ctx->opcode >> 12) & 0xf;
11089
    uint32_t mips32_op;
11090

    
11091
    switch (extension) {
11092
    case TEQ:
11093
        mips32_op = OPC_TEQ;
11094
        goto do_trap;
11095
    case TGE:
11096
        mips32_op = OPC_TGE;
11097
        goto do_trap;
11098
    case TGEU:
11099
        mips32_op = OPC_TGEU;
11100
        goto do_trap;
11101
    case TLT:
11102
        mips32_op = OPC_TLT;
11103
        goto do_trap;
11104
    case TLTU:
11105
        mips32_op = OPC_TLTU;
11106
        goto do_trap;
11107
    case TNE:
11108
        mips32_op = OPC_TNE;
11109
    do_trap:
11110
        gen_trap(ctx, mips32_op, rs, rt, -1);
11111
        break;
11112
#ifndef CONFIG_USER_ONLY
11113
    case MFC0:
11114
    case MFC0 + 32:
11115
        check_cp0_enabled(ctx);
11116
        if (rt == 0) {
11117
            /* Treat as NOP. */
11118
            break;
11119
        }
11120
        gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11121
        break;
11122
    case MTC0:
11123
    case MTC0 + 32:
11124
        check_cp0_enabled(ctx);
11125
        {
11126
            TCGv t0 = tcg_temp_new();
11127

    
11128
            gen_load_gpr(t0, rt);
11129
            gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11130
            tcg_temp_free(t0);
11131
        }
11132
        break;
11133
#endif
11134
    case 0x2c:
11135
        switch (minor) {
11136
        case SEB:
11137
            gen_bshfl(ctx, OPC_SEB, rs, rt);
11138
            break;
11139
        case SEH:
11140
            gen_bshfl(ctx, OPC_SEH, rs, rt);
11141
            break;
11142
        case CLO:
11143
            mips32_op = OPC_CLO;
11144
            goto do_cl;
11145
        case CLZ:
11146
            mips32_op = OPC_CLZ;
11147
        do_cl:
11148
            check_insn(env, ctx, ISA_MIPS32);
11149
            gen_cl(ctx, mips32_op, rt, rs);
11150
            break;
11151
        case RDHWR:
11152
            gen_rdhwr(env, ctx, rt, rs);
11153
            break;
11154
        case WSBH:
11155
            gen_bshfl(ctx, OPC_WSBH, rs, rt);
11156
            break;
11157
        case MULT:
11158
            mips32_op = OPC_MULT;
11159
            goto do_muldiv;
11160
        case MULTU:
11161
            mips32_op = OPC_MULTU;
11162
            goto do_muldiv;
11163
        case DIV:
11164
            mips32_op = OPC_DIV;
11165
            goto do_muldiv;
11166
        case DIVU:
11167
            mips32_op = OPC_DIVU;
11168
            goto do_muldiv;
11169
        case MADD:
11170
            mips32_op = OPC_MADD;
11171
            goto do_muldiv;
11172
        case MADDU:
11173
            mips32_op = OPC_MADDU;
11174
            goto do_muldiv;
11175
        case MSUB:
11176
            mips32_op = OPC_MSUB;
11177
            goto do_muldiv;
11178
        case MSUBU:
11179
            mips32_op = OPC_MSUBU;
11180
        do_muldiv:
11181
            check_insn(env, ctx, ISA_MIPS32);
11182
            gen_muldiv(ctx, mips32_op, rs, rt);
11183
            break;
11184
        default:
11185
            goto pool32axf_invalid;
11186
        }
11187
        break;
11188
    case 0x34:
11189
        switch (minor) {
11190
        case MFC2:
11191
        case MTC2:
11192
        case MFHC2:
11193
        case MTHC2:
11194
        case CFC2:
11195
        case CTC2:
11196
            generate_exception_err(ctx, EXCP_CpU, 2);
11197
            break;
11198
        default:
11199
            goto pool32axf_invalid;
11200
        }
11201
        break;
11202
    case 0x3c:
11203
        switch (minor) {
11204
        case JALR:
11205
        case JALR_HB:
11206
            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11207
            *is_branch = 1;
11208
            break;
11209
        case JALRS:
11210
        case JALRS_HB:
11211
            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11212
            *is_branch = 1;
11213
            break;
11214
        default:
11215
            goto pool32axf_invalid;
11216
        }
11217
        break;
11218
    case 0x05:
11219
        switch (minor) {
11220
        case RDPGPR:
11221
            check_cp0_enabled(ctx);
11222
            check_insn(env, ctx, ISA_MIPS32R2);
11223
            gen_load_srsgpr(rt, rs);
11224
            break;
11225
        case WRPGPR:
11226
            check_cp0_enabled(ctx);
11227
            check_insn(env, ctx, ISA_MIPS32R2);
11228
            gen_store_srsgpr(rt, rs);
11229
            break;
11230
        default:
11231
            goto pool32axf_invalid;
11232
        }
11233
        break;
11234
#ifndef CONFIG_USER_ONLY
11235
    case 0x0d:
11236
        switch (minor) {
11237
        case TLBP:
11238
            mips32_op = OPC_TLBP;
11239
            goto do_cp0;
11240
        case TLBR:
11241
            mips32_op = OPC_TLBR;
11242
            goto do_cp0;
11243
        case TLBWI:
11244
            mips32_op = OPC_TLBWI;
11245
            goto do_cp0;
11246
        case TLBWR:
11247
            mips32_op = OPC_TLBWR;
11248
            goto do_cp0;
11249
        case WAIT:
11250
            mips32_op = OPC_WAIT;
11251
            goto do_cp0;
11252
        case DERET:
11253
            mips32_op = OPC_DERET;
11254
            goto do_cp0;
11255
        case ERET:
11256
            mips32_op = OPC_ERET;
11257
        do_cp0:
11258
            gen_cp0(env, ctx, mips32_op, rt, rs);
11259
            break;
11260
        default:
11261
            goto pool32axf_invalid;
11262
        }
11263
        break;
11264
    case 0x1d:
11265
        switch (minor) {
11266
        case DI:
11267
            check_cp0_enabled(ctx);
11268
            {
11269
                TCGv t0 = tcg_temp_new();
11270

    
11271
                save_cpu_state(ctx, 1);
11272
                gen_helper_di(t0, cpu_env);
11273
                gen_store_gpr(t0, rs);
11274
                /* Stop translation as we may have switched the execution mode */
11275
                ctx->bstate = BS_STOP;
11276
                tcg_temp_free(t0);
11277
            }
11278
            break;
11279
        case EI:
11280
            check_cp0_enabled(ctx);
11281
            {
11282
                TCGv t0 = tcg_temp_new();
11283

    
11284
                save_cpu_state(ctx, 1);
11285
                gen_helper_ei(t0, cpu_env);
11286
                gen_store_gpr(t0, rs);
11287
                /* Stop translation as we may have switched the execution mode */
11288
                ctx->bstate = BS_STOP;
11289
                tcg_temp_free(t0);
11290
            }
11291
            break;
11292
        default:
11293
            goto pool32axf_invalid;
11294
        }
11295
        break;
11296
#endif
11297
    case 0x2d:
11298
        switch (minor) {
11299
        case SYNC:
11300
            /* NOP */
11301
            break;
11302
        case SYSCALL:
11303
            generate_exception(ctx, EXCP_SYSCALL);
11304
            ctx->bstate = BS_STOP;
11305
            break;
11306
        case SDBBP:
11307
            check_insn(env, ctx, ISA_MIPS32);
11308
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11309
                generate_exception(ctx, EXCP_DBp);
11310
            } else {
11311
                generate_exception(ctx, EXCP_DBp);
11312
            }
11313
            break;
11314
        default:
11315
            goto pool32axf_invalid;
11316
        }
11317
        break;
11318
    case 0x35:
11319
        switch (minor) {
11320
        case MFHI32:
11321
            gen_HILO(ctx, OPC_MFHI, rs);
11322
            break;
11323
        case MFLO32:
11324
            gen_HILO(ctx, OPC_MFLO, rs);
11325
            break;
11326
        case MTHI32:
11327
            gen_HILO(ctx, OPC_MTHI, rs);
11328
            break;
11329
        case MTLO32:
11330
            gen_HILO(ctx, OPC_MTLO, rs);
11331
            break;
11332
        default:
11333
            goto pool32axf_invalid;
11334
        }
11335
        break;
11336
    default:
11337
    pool32axf_invalid:
11338
        MIPS_INVAL("pool32axf");
11339
        generate_exception(ctx, EXCP_RI);
11340
        break;
11341
    }
11342
}
11343

    
11344
/* Values for microMIPS fmt field.  Variable-width, depending on which
11345
   formats the instruction supports.  */
11346

    
11347
enum {
11348
    FMT_SD_S = 0,
11349
    FMT_SD_D = 1,
11350

    
11351
    FMT_SDPS_S = 0,
11352
    FMT_SDPS_D = 1,
11353
    FMT_SDPS_PS = 2,
11354

    
11355
    FMT_SWL_S = 0,
11356
    FMT_SWL_W = 1,
11357
    FMT_SWL_L = 2,
11358

    
11359
    FMT_DWL_D = 0,
11360
    FMT_DWL_W = 1,
11361
    FMT_DWL_L = 2
11362
};
11363

    
11364
static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11365
{
11366
    int extension = (ctx->opcode >> 6) & 0x3ff;
11367
    uint32_t mips32_op;
11368

    
11369
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11370
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11371
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11372

    
11373
    switch (extension) {
11374
    case FLOAT_1BIT_FMT(CFC1, 0):
11375
        mips32_op = OPC_CFC1;
11376
        goto do_cp1;
11377
    case FLOAT_1BIT_FMT(CTC1, 0):
11378
        mips32_op = OPC_CTC1;
11379
        goto do_cp1;
11380
    case FLOAT_1BIT_FMT(MFC1, 0):
11381
        mips32_op = OPC_MFC1;
11382
        goto do_cp1;
11383
    case FLOAT_1BIT_FMT(MTC1, 0):
11384
        mips32_op = OPC_MTC1;
11385
        goto do_cp1;
11386
    case FLOAT_1BIT_FMT(MFHC1, 0):
11387
        mips32_op = OPC_MFHC1;
11388
        goto do_cp1;
11389
    case FLOAT_1BIT_FMT(MTHC1, 0):
11390
        mips32_op = OPC_MTHC1;
11391
    do_cp1:
11392
        gen_cp1(ctx, mips32_op, rt, rs);
11393
        break;
11394

    
11395
        /* Reciprocal square root */
11396
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11397
        mips32_op = OPC_RSQRT_S;
11398
        goto do_unaryfp;
11399
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11400
        mips32_op = OPC_RSQRT_D;
11401
        goto do_unaryfp;
11402

    
11403
        /* Square root */
11404
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11405
        mips32_op = OPC_SQRT_S;
11406
        goto do_unaryfp;
11407
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11408
        mips32_op = OPC_SQRT_D;
11409
        goto do_unaryfp;
11410

    
11411
        /* Reciprocal */
11412
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11413
        mips32_op = OPC_RECIP_S;
11414
        goto do_unaryfp;
11415
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11416
        mips32_op = OPC_RECIP_D;
11417
        goto do_unaryfp;
11418

    
11419
        /* Floor */
11420
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11421
        mips32_op = OPC_FLOOR_L_S;
11422
        goto do_unaryfp;
11423
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11424
        mips32_op = OPC_FLOOR_L_D;
11425
        goto do_unaryfp;
11426
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11427
        mips32_op = OPC_FLOOR_W_S;
11428
        goto do_unaryfp;
11429
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11430
        mips32_op = OPC_FLOOR_W_D;
11431
        goto do_unaryfp;
11432

    
11433
        /* Ceiling */
11434
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11435
        mips32_op = OPC_CEIL_L_S;
11436
        goto do_unaryfp;
11437
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11438
        mips32_op = OPC_CEIL_L_D;
11439
        goto do_unaryfp;
11440
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11441
        mips32_op = OPC_CEIL_W_S;
11442
        goto do_unaryfp;
11443
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11444
        mips32_op = OPC_CEIL_W_D;
11445
        goto do_unaryfp;
11446

    
11447
        /* Truncation */
11448
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11449
        mips32_op = OPC_TRUNC_L_S;
11450
        goto do_unaryfp;
11451
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11452
        mips32_op = OPC_TRUNC_L_D;
11453
        goto do_unaryfp;
11454
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11455
        mips32_op = OPC_TRUNC_W_S;
11456
        goto do_unaryfp;
11457
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11458
        mips32_op = OPC_TRUNC_W_D;
11459
        goto do_unaryfp;
11460

    
11461
        /* Round */
11462
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11463
        mips32_op = OPC_ROUND_L_S;
11464
        goto do_unaryfp;
11465
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11466
        mips32_op = OPC_ROUND_L_D;
11467
        goto do_unaryfp;
11468
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11469
        mips32_op = OPC_ROUND_W_S;
11470
        goto do_unaryfp;
11471
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11472
        mips32_op = OPC_ROUND_W_D;
11473
        goto do_unaryfp;
11474

    
11475
        /* Integer to floating-point conversion */
11476
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11477
        mips32_op = OPC_CVT_L_S;
11478
        goto do_unaryfp;
11479
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11480
        mips32_op = OPC_CVT_L_D;
11481
        goto do_unaryfp;
11482
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11483
        mips32_op = OPC_CVT_W_S;
11484
        goto do_unaryfp;
11485
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11486
        mips32_op = OPC_CVT_W_D;
11487
        goto do_unaryfp;
11488

    
11489
        /* Paired-foo conversions */
11490
    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11491
        mips32_op = OPC_CVT_S_PL;
11492
        goto do_unaryfp;
11493
    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11494
        mips32_op = OPC_CVT_S_PU;
11495
        goto do_unaryfp;
11496
    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11497
        mips32_op = OPC_CVT_PW_PS;
11498
        goto do_unaryfp;
11499
    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11500
        mips32_op = OPC_CVT_PS_PW;
11501
        goto do_unaryfp;
11502

    
11503
        /* Floating-point moves */
11504
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11505
        mips32_op = OPC_MOV_S;
11506
        goto do_unaryfp;
11507
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11508
        mips32_op = OPC_MOV_D;
11509
        goto do_unaryfp;
11510
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11511
        mips32_op = OPC_MOV_PS;
11512
        goto do_unaryfp;
11513

    
11514
        /* Absolute value */
11515
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11516
        mips32_op = OPC_ABS_S;
11517
        goto do_unaryfp;
11518
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11519
        mips32_op = OPC_ABS_D;
11520
        goto do_unaryfp;
11521
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11522
        mips32_op = OPC_ABS_PS;
11523
        goto do_unaryfp;
11524

    
11525
        /* Negation */
11526
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11527
        mips32_op = OPC_NEG_S;
11528
        goto do_unaryfp;
11529
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11530
        mips32_op = OPC_NEG_D;
11531
        goto do_unaryfp;
11532
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11533
        mips32_op = OPC_NEG_PS;
11534
        goto do_unaryfp;
11535

    
11536
        /* Reciprocal square root step */
11537
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11538
        mips32_op = OPC_RSQRT1_S;
11539
        goto do_unaryfp;
11540
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11541
        mips32_op = OPC_RSQRT1_D;
11542
        goto do_unaryfp;
11543
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11544
        mips32_op = OPC_RSQRT1_PS;
11545
        goto do_unaryfp;
11546

    
11547
        /* Reciprocal step */
11548
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11549
        mips32_op = OPC_RECIP1_S;
11550
        goto do_unaryfp;
11551
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11552
        mips32_op = OPC_RECIP1_S;
11553
        goto do_unaryfp;
11554
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11555
        mips32_op = OPC_RECIP1_PS;
11556
        goto do_unaryfp;
11557

    
11558
        /* Conversions from double */
11559
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11560
        mips32_op = OPC_CVT_D_S;
11561
        goto do_unaryfp;
11562
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11563
        mips32_op = OPC_CVT_D_W;
11564
        goto do_unaryfp;
11565
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11566
        mips32_op = OPC_CVT_D_L;
11567
        goto do_unaryfp;
11568

    
11569
        /* Conversions from single */
11570
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11571
        mips32_op = OPC_CVT_S_D;
11572
        goto do_unaryfp;
11573
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11574
        mips32_op = OPC_CVT_S_W;
11575
        goto do_unaryfp;
11576
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11577
        mips32_op = OPC_CVT_S_L;
11578
    do_unaryfp:
11579
        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11580
        break;
11581

    
11582
        /* Conditional moves on floating-point codes */
11583
    case COND_FLOAT_MOV(MOVT, 0):
11584
    case COND_FLOAT_MOV(MOVT, 1):
11585
    case COND_FLOAT_MOV(MOVT, 2):
11586
    case COND_FLOAT_MOV(MOVT, 3):
11587
    case COND_FLOAT_MOV(MOVT, 4):
11588
    case COND_FLOAT_MOV(MOVT, 5):
11589
    case COND_FLOAT_MOV(MOVT, 6):
11590
    case COND_FLOAT_MOV(MOVT, 7):
11591
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11592
        break;
11593
    case COND_FLOAT_MOV(MOVF, 0):
11594
    case COND_FLOAT_MOV(MOVF, 1):
11595
    case COND_FLOAT_MOV(MOVF, 2):
11596
    case COND_FLOAT_MOV(MOVF, 3):
11597
    case COND_FLOAT_MOV(MOVF, 4):
11598
    case COND_FLOAT_MOV(MOVF, 5):
11599
    case COND_FLOAT_MOV(MOVF, 6):
11600
    case COND_FLOAT_MOV(MOVF, 7):
11601
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11602
        break;
11603
    default:
11604
        MIPS_INVAL("pool32fxf");
11605
        generate_exception(ctx, EXCP_RI);
11606
        break;
11607
    }
11608
}
11609

    
11610
static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11611
                                    uint16_t insn_hw1, int *is_branch)
11612
{
11613
    int32_t offset;
11614
    uint16_t insn;
11615
    int rt, rs, rd, rr;
11616
    int16_t imm;
11617
    uint32_t op, minor, mips32_op;
11618
    uint32_t cond, fmt, cc;
11619

    
11620
    insn = cpu_lduw_code(env, ctx->pc + 2);
11621
    ctx->opcode = (ctx->opcode << 16) | insn;
11622

    
11623
    rt = (ctx->opcode >> 21) & 0x1f;
11624
    rs = (ctx->opcode >> 16) & 0x1f;
11625
    rd = (ctx->opcode >> 11) & 0x1f;
11626
    rr = (ctx->opcode >> 6) & 0x1f;
11627
    imm = (int16_t) ctx->opcode;
11628

    
11629
    op = (ctx->opcode >> 26) & 0x3f;
11630
    switch (op) {
11631
    case POOL32A:
11632
        minor = ctx->opcode & 0x3f;
11633
        switch (minor) {
11634
        case 0x00:
11635
            minor = (ctx->opcode >> 6) & 0xf;
11636
            switch (minor) {
11637
            case SLL32:
11638
                mips32_op = OPC_SLL;
11639
                goto do_shifti;
11640
            case SRA:
11641
                mips32_op = OPC_SRA;
11642
                goto do_shifti;
11643
            case SRL32:
11644
                mips32_op = OPC_SRL;
11645
                goto do_shifti;
11646
            case ROTR:
11647
                mips32_op = OPC_ROTR;
11648
            do_shifti:
11649
                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11650
                break;
11651
            default:
11652
                goto pool32a_invalid;
11653
            }
11654
            break;
11655
        case 0x10:
11656
            minor = (ctx->opcode >> 6) & 0xf;
11657
            switch (minor) {
11658
                /* Arithmetic */
11659
            case ADD:
11660
                mips32_op = OPC_ADD;
11661
                goto do_arith;
11662
            case ADDU32:
11663
                mips32_op = OPC_ADDU;
11664
                goto do_arith;
11665
            case SUB:
11666
                mips32_op = OPC_SUB;
11667
                goto do_arith;
11668
            case SUBU32:
11669
                mips32_op = OPC_SUBU;
11670
                goto do_arith;
11671
            case MUL:
11672
                mips32_op = OPC_MUL;
11673
            do_arith:
11674
                gen_arith(env, ctx, mips32_op, rd, rs, rt);
11675
                break;
11676
                /* Shifts */
11677
            case SLLV:
11678
                mips32_op = OPC_SLLV;
11679
                goto do_shift;
11680
            case SRLV:
11681
                mips32_op = OPC_SRLV;
11682
                goto do_shift;
11683
            case SRAV:
11684
                mips32_op = OPC_SRAV;
11685
                goto do_shift;
11686
            case ROTRV:
11687
                mips32_op = OPC_ROTRV;
11688
            do_shift:
11689
                gen_shift(env, ctx, mips32_op, rd, rs, rt);
11690
                break;
11691
                /* Logical operations */
11692
            case AND:
11693
                mips32_op = OPC_AND;
11694
                goto do_logic;
11695
            case OR32:
11696
                mips32_op = OPC_OR;
11697
                goto do_logic;
11698
            case NOR:
11699
                mips32_op = OPC_NOR;
11700
                goto do_logic;
11701
            case XOR32:
11702
                mips32_op = OPC_XOR;
11703
            do_logic:
11704
                gen_logic(env, ctx, mips32_op, rd, rs, rt);
11705
                break;
11706
                /* Set less than */
11707
            case SLT:
11708
                mips32_op = OPC_SLT;
11709
                goto do_slt;
11710
            case SLTU:
11711
                mips32_op = OPC_SLTU;
11712
            do_slt:
11713
                gen_slt(env, ctx, mips32_op, rd, rs, rt);
11714
                break;
11715
            default:
11716
                goto pool32a_invalid;
11717
            }
11718
            break;
11719
        case 0x18:
11720
            minor = (ctx->opcode >> 6) & 0xf;
11721
            switch (minor) {
11722
                /* Conditional moves */
11723
            case MOVN:
11724
                mips32_op = OPC_MOVN;
11725
                goto do_cmov;
11726
            case MOVZ:
11727
                mips32_op = OPC_MOVZ;
11728
            do_cmov:
11729
                gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11730
                break;
11731
            case LWXS:
11732
                gen_ldxs(ctx, rs, rt, rd);
11733
                break;
11734
            default:
11735
                goto pool32a_invalid;
11736
            }
11737
            break;
11738
        case INS:
11739
            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11740
            return;
11741
        case EXT:
11742
            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11743
            return;
11744
        case POOL32AXF:
11745
            gen_pool32axf(env, ctx, rt, rs, is_branch);
11746
            break;
11747
        case 0x07:
11748
            generate_exception(ctx, EXCP_BREAK);
11749
            break;
11750
        default:
11751
        pool32a_invalid:
11752
                MIPS_INVAL("pool32a");
11753
                generate_exception(ctx, EXCP_RI);
11754
                break;
11755
        }
11756
        break;
11757
    case POOL32B:
11758
        minor = (ctx->opcode >> 12) & 0xf;
11759
        switch (minor) {
11760
        case CACHE:
11761
            check_cp0_enabled(ctx);
11762
            /* Treat as no-op. */
11763
            break;
11764
        case LWC2:
11765
        case SWC2:
11766
            /* COP2: Not implemented. */
11767
            generate_exception_err(ctx, EXCP_CpU, 2);
11768
            break;
11769
        case LWP:
11770
        case SWP:
11771
#ifdef TARGET_MIPS64
11772
        case LDP:
11773
        case SDP:
11774
#endif
11775
            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11776
            break;
11777
        case LWM32:
11778
        case SWM32:
11779
#ifdef TARGET_MIPS64
11780
        case LDM:
11781
        case SDM:
11782
#endif
11783
            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11784
            break;
11785
        default:
11786
            MIPS_INVAL("pool32b");
11787
            generate_exception(ctx, EXCP_RI);
11788
            break;
11789
        }
11790
        break;
11791
    case POOL32F:
11792
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11793
            minor = ctx->opcode & 0x3f;
11794
            check_cp1_enabled(ctx);
11795
            switch (minor) {
11796
            case ALNV_PS:
11797
                mips32_op = OPC_ALNV_PS;
11798
                goto do_madd;
11799
            case MADD_S:
11800
                mips32_op = OPC_MADD_S;
11801
                goto do_madd;
11802
            case MADD_D:
11803
                mips32_op = OPC_MADD_D;
11804
                goto do_madd;
11805
            case MADD_PS:
11806
                mips32_op = OPC_MADD_PS;
11807
                goto do_madd;
11808
            case MSUB_S:
11809
                mips32_op = OPC_MSUB_S;
11810
                goto do_madd;
11811
            case MSUB_D:
11812
                mips32_op = OPC_MSUB_D;
11813
                goto do_madd;
11814
            case MSUB_PS:
11815
                mips32_op = OPC_MSUB_PS;
11816
                goto do_madd;
11817
            case NMADD_S:
11818
                mips32_op = OPC_NMADD_S;
11819
                goto do_madd;
11820
            case NMADD_D:
11821
                mips32_op = OPC_NMADD_D;
11822
                goto do_madd;
11823
            case NMADD_PS:
11824
                mips32_op = OPC_NMADD_PS;
11825
                goto do_madd;
11826
            case NMSUB_S:
11827
                mips32_op = OPC_NMSUB_S;
11828
                goto do_madd;
11829
            case NMSUB_D:
11830
                mips32_op = OPC_NMSUB_D;
11831
                goto do_madd;
11832
            case NMSUB_PS:
11833
                mips32_op = OPC_NMSUB_PS;
11834
            do_madd:
11835
                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11836
                break;
11837
            case CABS_COND_FMT:
11838
                cond = (ctx->opcode >> 6) & 0xf;
11839
                cc = (ctx->opcode >> 13) & 0x7;
11840
                fmt = (ctx->opcode >> 10) & 0x3;
11841
                switch (fmt) {
11842
                case 0x0:
11843
                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
11844
                    break;
11845
                case 0x1:
11846
                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
11847
                    break;
11848
                case 0x2:
11849
                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11850
                    break;
11851
                default:
11852
                    goto pool32f_invalid;
11853
                }
11854
                break;
11855
            case C_COND_FMT:
11856
                cond = (ctx->opcode >> 6) & 0xf;
11857
                cc = (ctx->opcode >> 13) & 0x7;
11858
                fmt = (ctx->opcode >> 10) & 0x3;
11859
                switch (fmt) {
11860
                case 0x0:
11861
                    gen_cmp_s(ctx, cond, rt, rs, cc);
11862
                    break;
11863
                case 0x1:
11864
                    gen_cmp_d(ctx, cond, rt, rs, cc);
11865
                    break;
11866
                case 0x2:
11867
                    gen_cmp_ps(ctx, cond, rt, rs, cc);
11868
                    break;
11869
                default:
11870
                    goto pool32f_invalid;
11871
                }
11872
                break;
11873
            case POOL32FXF:
11874
                gen_pool32fxf(env, ctx, rt, rs);
11875
                break;
11876
            case 0x00:
11877
                /* PLL foo */
11878
                switch ((ctx->opcode >> 6) & 0x7) {
11879
                case PLL_PS:
11880
                    mips32_op = OPC_PLL_PS;
11881
                    goto do_ps;
11882
                case PLU_PS:
11883
                    mips32_op = OPC_PLU_PS;
11884
                    goto do_ps;
11885
                case PUL_PS:
11886
                    mips32_op = OPC_PUL_PS;
11887
                    goto do_ps;
11888
                case PUU_PS:
11889
                    mips32_op = OPC_PUU_PS;
11890
                    goto do_ps;
11891
                case CVT_PS_S:
11892
                    mips32_op = OPC_CVT_PS_S;
11893
                do_ps:
11894
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11895
                    break;
11896
                default:
11897
                    goto pool32f_invalid;
11898
                }
11899
                break;
11900
            case 0x08:
11901
                /* [LS][WDU]XC1 */
11902
                switch ((ctx->opcode >> 6) & 0x7) {
11903
                case LWXC1:
11904
                    mips32_op = OPC_LWXC1;
11905
                    goto do_ldst_cp1;
11906
                case SWXC1:
11907
                    mips32_op = OPC_SWXC1;
11908
                    goto do_ldst_cp1;
11909
                case LDXC1:
11910
                    mips32_op = OPC_LDXC1;
11911
                    goto do_ldst_cp1;
11912
                case SDXC1:
11913
                    mips32_op = OPC_SDXC1;
11914
                    goto do_ldst_cp1;
11915
                case LUXC1:
11916
                    mips32_op = OPC_LUXC1;
11917
                    goto do_ldst_cp1;
11918
                case SUXC1:
11919
                    mips32_op = OPC_SUXC1;
11920
                do_ldst_cp1:
11921
                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11922
                    break;
11923
                default:
11924
                    goto pool32f_invalid;
11925
                }
11926
                break;
11927
            case 0x18:
11928
                /* 3D insns */
11929
                fmt = (ctx->opcode >> 9) & 0x3;
11930
                switch ((ctx->opcode >> 6) & 0x7) {
11931
                case RSQRT2_FMT:
11932
                    switch (fmt) {
11933
                    case FMT_SDPS_S:
11934
                        mips32_op = OPC_RSQRT2_S;
11935
                        goto do_3d;
11936
                    case FMT_SDPS_D:
11937
                        mips32_op = OPC_RSQRT2_D;
11938
                        goto do_3d;
11939
                    case FMT_SDPS_PS:
11940
                        mips32_op = OPC_RSQRT2_PS;
11941
                        goto do_3d;
11942
                    default:
11943
                        goto pool32f_invalid;
11944
                    }
11945
                    break;
11946
                case RECIP2_FMT:
11947
                    switch (fmt) {
11948
                    case FMT_SDPS_S:
11949
                        mips32_op = OPC_RECIP2_S;
11950
                        goto do_3d;
11951
                    case FMT_SDPS_D:
11952
                        mips32_op = OPC_RECIP2_D;
11953
                        goto do_3d;
11954
                    case FMT_SDPS_PS:
11955
                        mips32_op = OPC_RECIP2_PS;
11956
                        goto do_3d;
11957
                    default:
11958
                        goto pool32f_invalid;
11959
                    }
11960
                    break;
11961
                case ADDR_PS:
11962
                    mips32_op = OPC_ADDR_PS;
11963
                    goto do_3d;
11964
                case MULR_PS:
11965
                    mips32_op = OPC_MULR_PS;
11966
                do_3d:
11967
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11968
                    break;
11969
                default:
11970
                    goto pool32f_invalid;
11971
                }
11972
                break;
11973
            case 0x20:
11974
                /* MOV[FT].fmt and PREFX */
11975
                cc = (ctx->opcode >> 13) & 0x7;
11976
                fmt = (ctx->opcode >> 9) & 0x3;
11977
                switch ((ctx->opcode >> 6) & 0x7) {
11978
                case MOVF_FMT:
11979
                    switch (fmt) {
11980
                    case FMT_SDPS_S:
11981
                        gen_movcf_s(rs, rt, cc, 0);
11982
                        break;
11983
                    case FMT_SDPS_D:
11984
                        gen_movcf_d(ctx, rs, rt, cc, 0);
11985
                        break;
11986
                    case FMT_SDPS_PS:
11987
                        gen_movcf_ps(rs, rt, cc, 0);
11988
                        break;
11989
                    default:
11990
                        goto pool32f_invalid;
11991
                    }
11992
                    break;
11993
                case MOVT_FMT:
11994
                    switch (fmt) {
11995
                    case FMT_SDPS_S:
11996
                        gen_movcf_s(rs, rt, cc, 1);
11997
                        break;
11998
                    case FMT_SDPS_D:
11999
                        gen_movcf_d(ctx, rs, rt, cc, 1);
12000
                        break;
12001
                    case FMT_SDPS_PS:
12002
                        gen_movcf_ps(rs, rt, cc, 1);
12003
                        break;
12004
                    default:
12005
                        goto pool32f_invalid;
12006
                    }
12007
                    break;
12008
                case PREFX:
12009
                    break;
12010
                default:
12011
                    goto pool32f_invalid;
12012
                }
12013
                break;
12014
#define FINSN_3ARG_SDPS(prfx)                           \
12015
                switch ((ctx->opcode >> 8) & 0x3) {     \
12016
                case FMT_SDPS_S:                        \
12017
                    mips32_op = OPC_##prfx##_S;         \
12018
                    goto do_fpop;                       \
12019
                case FMT_SDPS_D:                        \
12020
                    mips32_op = OPC_##prfx##_D;         \
12021
                    goto do_fpop;                       \
12022
                case FMT_SDPS_PS:                       \
12023
                    mips32_op = OPC_##prfx##_PS;        \
12024
                    goto do_fpop;                       \
12025
                default:                                \
12026
                    goto pool32f_invalid;               \
12027
                }
12028
            case 0x30:
12029
                /* regular FP ops */
12030
                switch ((ctx->opcode >> 6) & 0x3) {
12031
                case ADD_FMT:
12032
                    FINSN_3ARG_SDPS(ADD);
12033
                    break;
12034
                case SUB_FMT:
12035
                    FINSN_3ARG_SDPS(SUB);
12036
                    break;
12037
                case MUL_FMT:
12038
                    FINSN_3ARG_SDPS(MUL);
12039
                    break;
12040
                case DIV_FMT:
12041
                    fmt = (ctx->opcode >> 8) & 0x3;
12042
                    if (fmt == 1) {
12043
                        mips32_op = OPC_DIV_D;
12044
                    } else if (fmt == 0) {
12045
                        mips32_op = OPC_DIV_S;
12046
                    } else {
12047
                        goto pool32f_invalid;
12048
                    }
12049
                    goto do_fpop;
12050
                default:
12051
                    goto pool32f_invalid;
12052
                }
12053
                break;
12054
            case 0x38:
12055
                /* cmovs */
12056
                switch ((ctx->opcode >> 6) & 0x3) {
12057
                case MOVN_FMT:
12058
                    FINSN_3ARG_SDPS(MOVN);
12059
                    break;
12060
                case MOVZ_FMT:
12061
                    FINSN_3ARG_SDPS(MOVZ);
12062
                    break;
12063
                default:
12064
                    goto pool32f_invalid;
12065
                }
12066
                break;
12067
            do_fpop:
12068
                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12069
                break;
12070
            default:
12071
            pool32f_invalid:
12072
                MIPS_INVAL("pool32f");
12073
                generate_exception(ctx, EXCP_RI);
12074
                break;
12075
            }
12076
        } else {
12077
            generate_exception_err(ctx, EXCP_CpU, 1);
12078
        }
12079
        break;
12080
    case POOL32I:
12081
        minor = (ctx->opcode >> 21) & 0x1f;
12082
        switch (minor) {
12083
        case BLTZ:
12084
            mips32_op = OPC_BLTZ;
12085
            goto do_branch;
12086
        case BLTZAL:
12087
            mips32_op = OPC_BLTZAL;
12088
            goto do_branch;
12089
        case BLTZALS:
12090
            mips32_op = OPC_BLTZALS;
12091
            goto do_branch;
12092
        case BGEZ:
12093
            mips32_op = OPC_BGEZ;
12094
            goto do_branch;
12095
        case BGEZAL:
12096
            mips32_op = OPC_BGEZAL;
12097
            goto do_branch;
12098
        case BGEZALS:
12099
            mips32_op = OPC_BGEZALS;
12100
            goto do_branch;
12101
        case BLEZ:
12102
            mips32_op = OPC_BLEZ;
12103
            goto do_branch;
12104
        case BGTZ:
12105
            mips32_op = OPC_BGTZ;
12106
        do_branch:
12107
            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12108
            *is_branch = 1;
12109
            break;
12110

    
12111
            /* Traps */
12112
        case TLTI:
12113
            mips32_op = OPC_TLTI;
12114
            goto do_trapi;
12115
        case TGEI:
12116
            mips32_op = OPC_TGEI;
12117
            goto do_trapi;
12118
        case TLTIU:
12119
            mips32_op = OPC_TLTIU;
12120
            goto do_trapi;
12121
        case TGEIU:
12122
            mips32_op = OPC_TGEIU;
12123
            goto do_trapi;
12124
        case TNEI:
12125
            mips32_op = OPC_TNEI;
12126
            goto do_trapi;
12127
        case TEQI:
12128
            mips32_op = OPC_TEQI;
12129
        do_trapi:
12130
            gen_trap(ctx, mips32_op, rs, -1, imm);
12131
            break;
12132

    
12133
        case BNEZC:
12134
        case BEQZC:
12135
            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12136
                               4, rs, 0, imm << 1);
12137
            /* Compact branches don't have a delay slot, so just let
12138
               the normal delay slot handling take us to the branch
12139
               target. */
12140
            break;
12141
        case LUI:
12142
            gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12143
            break;
12144
        case SYNCI:
12145
            break;
12146
        case BC2F:
12147
        case BC2T:
12148
            /* COP2: Not implemented. */
12149
            generate_exception_err(ctx, EXCP_CpU, 2);
12150
            break;
12151
        case BC1F:
12152
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12153
            goto do_cp1branch;
12154
        case BC1T:
12155
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12156
            goto do_cp1branch;
12157
        case BC1ANY4F:
12158
            mips32_op = OPC_BC1FANY4;
12159
            goto do_cp1mips3d;
12160
        case BC1ANY4T:
12161
            mips32_op = OPC_BC1TANY4;
12162
        do_cp1mips3d:
12163
            check_cop1x(ctx);
12164
            check_insn(env, ctx, ASE_MIPS3D);
12165
            /* Fall through */
12166
        do_cp1branch:
12167
            gen_compute_branch1(env, ctx, mips32_op,
12168
                                (ctx->opcode >> 18) & 0x7, imm << 1);
12169
            *is_branch = 1;
12170
            break;
12171
        case BPOSGE64:
12172
        case BPOSGE32:
12173
            /* MIPS DSP: not implemented */
12174
            /* Fall through */
12175
        default:
12176
            MIPS_INVAL("pool32i");
12177
            generate_exception(ctx, EXCP_RI);
12178
            break;
12179
        }
12180
        break;
12181
    case POOL32C:
12182
        minor = (ctx->opcode >> 12) & 0xf;
12183
        switch (minor) {
12184
        case LWL:
12185
            mips32_op = OPC_LWL;
12186
            goto do_ld_lr;
12187
        case SWL:
12188
            mips32_op = OPC_SWL;
12189
            goto do_st_lr;
12190
        case LWR:
12191
            mips32_op = OPC_LWR;
12192
            goto do_ld_lr;
12193
        case SWR:
12194
            mips32_op = OPC_SWR;
12195
            goto do_st_lr;
12196
#if defined(TARGET_MIPS64)
12197
        case LDL:
12198
            mips32_op = OPC_LDL;
12199
            goto do_ld_lr;
12200
        case SDL:
12201
            mips32_op = OPC_SDL;
12202
            goto do_st_lr;
12203
        case LDR:
12204
            mips32_op = OPC_LDR;
12205
            goto do_ld_lr;
12206
        case SDR:
12207
            mips32_op = OPC_SDR;
12208
            goto do_st_lr;
12209
        case LWU:
12210
            mips32_op = OPC_LWU;
12211
            goto do_ld_lr;
12212
        case LLD:
12213
            mips32_op = OPC_LLD;
12214
            goto do_ld_lr;
12215
#endif
12216
        case LL:
12217
            mips32_op = OPC_LL;
12218
            goto do_ld_lr;
12219
        do_ld_lr:
12220
            gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12221
            break;
12222
        do_st_lr:
12223
            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12224
            break;
12225
        case SC:
12226
            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12227
            break;
12228
#if defined(TARGET_MIPS64)
12229
        case SCD:
12230
            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12231
            break;
12232
#endif
12233
        case PREF:
12234
            /* Treat as no-op */
12235
            break;
12236
        default:
12237
            MIPS_INVAL("pool32c");
12238
            generate_exception(ctx, EXCP_RI);
12239
            break;
12240
        }
12241
        break;
12242
    case ADDI32:
12243
        mips32_op = OPC_ADDI;
12244
        goto do_addi;
12245
    case ADDIU32:
12246
        mips32_op = OPC_ADDIU;
12247
    do_addi:
12248
        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12249
        break;
12250

    
12251
        /* Logical operations */
12252
    case ORI32:
12253
        mips32_op = OPC_ORI;
12254
        goto do_logici;
12255
    case XORI32:
12256
        mips32_op = OPC_XORI;
12257
        goto do_logici;
12258
    case ANDI32:
12259
        mips32_op = OPC_ANDI;
12260
    do_logici:
12261
        gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12262
        break;
12263

    
12264
        /* Set less than immediate */
12265
    case SLTI32:
12266
        mips32_op = OPC_SLTI;
12267
        goto do_slti;
12268
    case SLTIU32:
12269
        mips32_op = OPC_SLTIU;
12270
    do_slti:
12271
        gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12272
        break;
12273
    case JALX32:
12274
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12275
        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12276
        *is_branch = 1;
12277
        break;
12278
    case JALS32:
12279
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12280
        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12281
        *is_branch = 1;
12282
        break;
12283
    case BEQ32:
12284
        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12285
        *is_branch = 1;
12286
        break;
12287
    case BNE32:
12288
        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12289
        *is_branch = 1;
12290
        break;
12291
    case J32:
12292
        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12293
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12294
        *is_branch = 1;
12295
        break;
12296
    case JAL32:
12297
        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12298
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12299
        *is_branch = 1;
12300
        break;
12301
        /* Floating point (COP1) */
12302
    case LWC132:
12303
        mips32_op = OPC_LWC1;
12304
        goto do_cop1;
12305
    case LDC132:
12306
        mips32_op = OPC_LDC1;
12307
        goto do_cop1;
12308
    case SWC132:
12309
        mips32_op = OPC_SWC1;
12310
        goto do_cop1;
12311
    case SDC132:
12312
        mips32_op = OPC_SDC1;
12313
    do_cop1:
12314
        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12315
        break;
12316
    case ADDIUPC:
12317
        {
12318
            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12319
            int offset = SIMM(ctx->opcode, 0, 23) << 2;
12320

    
12321
            gen_addiupc(ctx, reg, offset, 0, 0);
12322
        }
12323
        break;
12324
        /* Loads and stores */
12325
    case LB32:
12326
        mips32_op = OPC_LB;
12327
        goto do_ld;
12328
    case LBU32:
12329
        mips32_op = OPC_LBU;
12330
        goto do_ld;
12331
    case LH32:
12332
        mips32_op = OPC_LH;
12333
        goto do_ld;
12334
    case LHU32:
12335
        mips32_op = OPC_LHU;
12336
        goto do_ld;
12337
    case LW32:
12338
        mips32_op = OPC_LW;
12339
        goto do_ld;
12340
#ifdef TARGET_MIPS64
12341
    case LD32:
12342
        mips32_op = OPC_LD;
12343
        goto do_ld;
12344
    case SD32:
12345
        mips32_op = OPC_SD;
12346
        goto do_st;
12347
#endif
12348
    case SB32:
12349
        mips32_op = OPC_SB;
12350
        goto do_st;
12351
    case SH32:
12352
        mips32_op = OPC_SH;
12353
        goto do_st;
12354
    case SW32:
12355
        mips32_op = OPC_SW;
12356
        goto do_st;
12357
    do_ld:
12358
        gen_ld(env, ctx, mips32_op, rt, rs, imm);
12359
        break;
12360
    do_st:
12361
        gen_st(ctx, mips32_op, rt, rs, imm);
12362
        break;
12363
    default:
12364
        generate_exception(ctx, EXCP_RI);
12365
        break;
12366
    }
12367
}
12368

    
12369
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12370
{
12371
    uint32_t op;
12372

    
12373
    /* make sure instructions are on a halfword boundary */
12374
    if (ctx->pc & 0x1) {
12375
        env->CP0_BadVAddr = ctx->pc;
12376
        generate_exception(ctx, EXCP_AdEL);
12377
        ctx->bstate = BS_STOP;
12378
        return 2;
12379
    }
12380

    
12381
    op = (ctx->opcode >> 10) & 0x3f;
12382
    /* Enforce properly-sized instructions in a delay slot */
12383
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12384
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12385

    
12386
        switch (op) {
12387
        case POOL32A:
12388
        case POOL32B:
12389
        case POOL32I:
12390
        case POOL32C:
12391
        case ADDI32:
12392
        case ADDIU32:
12393
        case ORI32:
12394
        case XORI32:
12395
        case SLTI32:
12396
        case SLTIU32:
12397
        case ANDI32:
12398
        case JALX32:
12399
        case LBU32:
12400
        case LHU32:
12401
        case POOL32F:
12402
        case JALS32:
12403
        case BEQ32:
12404
        case BNE32:
12405
        case J32:
12406
        case JAL32:
12407
        case SB32:
12408
        case SH32:
12409
        case POOL32S:
12410
        case ADDIUPC:
12411
        case SWC132:
12412
        case SDC132:
12413
        case SD32:
12414
        case SW32:
12415
        case LB32:
12416
        case LH32:
12417
        case DADDIU32:
12418
        case POOL48A:           /* ??? */
12419
        case LWC132:
12420
        case LDC132:
12421
        case LD32:
12422
        case LW32:
12423
            if (bits & MIPS_HFLAG_BDS16) {
12424
                generate_exception(ctx, EXCP_RI);
12425
                /* Just stop translation; the user is confused.  */
12426
                ctx->bstate = BS_STOP;
12427
                return 2;
12428
            }
12429
            break;
12430
        case POOL16A:
12431
        case POOL16B:
12432
        case POOL16C:
12433
        case LWGP16:
12434
        case POOL16F:
12435
        case LBU16:
12436
        case LHU16:
12437
        case LWSP16:
12438
        case LW16:
12439
        case SB16:
12440
        case SH16:
12441
        case SWSP16:
12442
        case SW16:
12443
        case MOVE16:
12444
        case ANDI16:
12445
        case POOL16D:
12446
        case POOL16E:
12447
        case BEQZ16:
12448
        case BNEZ16:
12449
        case B16:
12450
        case LI16:
12451
            if (bits & MIPS_HFLAG_BDS32) {
12452
                generate_exception(ctx, EXCP_RI);
12453
                /* Just stop translation; the user is confused.  */
12454
                ctx->bstate = BS_STOP;
12455
                return 2;
12456
            }
12457
            break;
12458
        default:
12459
            break;
12460
        }
12461
    }
12462
    switch (op) {
12463
    case POOL16A:
12464
        {
12465
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12466
            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12467
            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12468
            uint32_t opc = 0;
12469

    
12470
            switch (ctx->opcode & 0x1) {
12471
            case ADDU16:
12472
                opc = OPC_ADDU;
12473
                break;
12474
            case SUBU16:
12475
                opc = OPC_SUBU;
12476
                break;
12477
            }
12478

    
12479
            gen_arith(env, ctx, opc, rd, rs1, rs2);
12480
        }
12481
        break;
12482
    case POOL16B:
12483
        {
12484
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12485
            int rs = mmreg(uMIPS_RS(ctx->opcode));
12486
            int amount = (ctx->opcode >> 1) & 0x7;
12487
            uint32_t opc = 0;
12488
            amount = amount == 0 ? 8 : amount;
12489

    
12490
            switch (ctx->opcode & 0x1) {
12491
            case SLL16:
12492
                opc = OPC_SLL;
12493
                break;
12494
            case SRL16:
12495
                opc = OPC_SRL;
12496
                break;
12497
            }
12498

    
12499
            gen_shift_imm(env, ctx, opc, rd, rs, amount);
12500
        }
12501
        break;
12502
    case POOL16C:
12503
        gen_pool16c_insn(env, ctx, is_branch);
12504
        break;
12505
    case LWGP16:
12506
        {
12507
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12508
            int rb = 28;            /* GP */
12509
            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12510

    
12511
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12512
        }
12513
        break;
12514
    case POOL16F:
12515
        if (ctx->opcode & 1) {
12516
            generate_exception(ctx, EXCP_RI);
12517
        } else {
12518
            /* MOVEP */
12519
            int enc_dest = uMIPS_RD(ctx->opcode);
12520
            int enc_rt = uMIPS_RS2(ctx->opcode);
12521
            int enc_rs = uMIPS_RS1(ctx->opcode);
12522
            int rd, rs, re, rt;
12523
            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12524
            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12525
            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12526

    
12527
            rd = rd_enc[enc_dest];
12528
            re = re_enc[enc_dest];
12529
            rs = rs_rt_enc[enc_rs];
12530
            rt = rs_rt_enc[enc_rt];
12531

    
12532
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12533
            gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12534
        }
12535
        break;
12536
    case LBU16:
12537
        {
12538
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12539
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12540
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
12541
            offset = (offset == 0xf ? -1 : offset);
12542

    
12543
            gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12544
        }
12545
        break;
12546
    case LHU16:
12547
        {
12548
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12549
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12550
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12551

    
12552
            gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12553
        }
12554
        break;
12555
    case LWSP16:
12556
        {
12557
            int rd = (ctx->opcode >> 5) & 0x1f;
12558
            int rb = 29;            /* SP */
12559
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12560

    
12561
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12562
        }
12563
        break;
12564
    case LW16:
12565
        {
12566
            int rd = mmreg(uMIPS_RD(ctx->opcode));
12567
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12568
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12569

    
12570
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12571
        }
12572
        break;
12573
    case SB16:
12574
        {
12575
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12576
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12577
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
12578

    
12579
            gen_st(ctx, OPC_SB, rd, rb, offset);
12580
        }
12581
        break;
12582
    case SH16:
12583
        {
12584
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12585
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12586
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12587

    
12588
            gen_st(ctx, OPC_SH, rd, rb, offset);
12589
        }
12590
        break;
12591
    case SWSP16:
12592
        {
12593
            int rd = (ctx->opcode >> 5) & 0x1f;
12594
            int rb = 29;            /* SP */
12595
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12596

    
12597
            gen_st(ctx, OPC_SW, rd, rb, offset);
12598
        }
12599
        break;
12600
    case SW16:
12601
        {
12602
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12603
            int rb = mmreg(uMIPS_RS(ctx->opcode));
12604
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12605

    
12606
            gen_st(ctx, OPC_SW, rd, rb, offset);
12607
        }
12608
        break;
12609
    case MOVE16:
12610
        {
12611
            int rd = uMIPS_RD5(ctx->opcode);
12612
            int rs = uMIPS_RS5(ctx->opcode);
12613

    
12614
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12615
        }
12616
        break;
12617
    case ANDI16:
12618
        gen_andi16(env, ctx);
12619
        break;
12620
    case POOL16D:
12621
        switch (ctx->opcode & 0x1) {
12622
        case ADDIUS5:
12623
            gen_addius5(env, ctx);
12624
            break;
12625
        case ADDIUSP:
12626
            gen_addiusp(env, ctx);
12627
            break;
12628
        }
12629
        break;
12630
    case POOL16E:
12631
        switch (ctx->opcode & 0x1) {
12632
        case ADDIUR2:
12633
            gen_addiur2(env, ctx);
12634
            break;
12635
        case ADDIUR1SP:
12636
            gen_addiur1sp(env, ctx);
12637
            break;
12638
        }
12639
        break;
12640
    case B16:
12641
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12642
                           SIMM(ctx->opcode, 0, 10) << 1);
12643
        *is_branch = 1;
12644
        break;
12645
    case BNEZ16:
12646
    case BEQZ16:
12647
        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12648
                           mmreg(uMIPS_RD(ctx->opcode)),
12649
                           0, SIMM(ctx->opcode, 0, 7) << 1);
12650
        *is_branch = 1;
12651
        break;
12652
    case LI16:
12653
        {
12654
            int reg = mmreg(uMIPS_RD(ctx->opcode));
12655
            int imm = ZIMM(ctx->opcode, 0, 7);
12656

    
12657
            imm = (imm == 0x7f ? -1 : imm);
12658
            tcg_gen_movi_tl(cpu_gpr[reg], imm);
12659
        }
12660
        break;
12661
    case RES_20:
12662
    case RES_28:
12663
    case RES_29:
12664
    case RES_30:
12665
    case RES_31:
12666
    case RES_38:
12667
    case RES_39:
12668
        generate_exception(ctx, EXCP_RI);
12669
        break;
12670
    default:
12671
        decode_micromips32_opc (env, ctx, op, is_branch);
12672
        return 4;
12673
    }
12674

    
12675
    return 2;
12676
}
12677

    
12678
/* SmartMIPS extension to MIPS32 */
12679

    
12680
#if defined(TARGET_MIPS64)
12681

    
12682
/* MDMX extension to MIPS64 */
12683

    
12684
#endif
12685

    
12686
/* MIPSDSP functions. */
12687
static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12688
                           int rd, int base, int offset)
12689
{
12690
    const char *opn = "ldx";
12691
    TCGv t0;
12692

    
12693
    if (rd == 0) {
12694
        MIPS_DEBUG("NOP");
12695
        return;
12696
    }
12697

    
12698
    check_dsp(ctx);
12699
    t0 = tcg_temp_new();
12700

    
12701
    if (base == 0) {
12702
        gen_load_gpr(t0, offset);
12703
    } else if (offset == 0) {
12704
        gen_load_gpr(t0, base);
12705
    } else {
12706
        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12707
    }
12708

    
12709
    save_cpu_state(ctx, 0);
12710
    switch (opc) {
12711
    case OPC_LBUX:
12712
        op_ld_lbu(t0, t0, ctx);
12713
        gen_store_gpr(t0, rd);
12714
        opn = "lbux";
12715
        break;
12716
    case OPC_LHX:
12717
        op_ld_lh(t0, t0, ctx);
12718
        gen_store_gpr(t0, rd);
12719
        opn = "lhx";
12720
        break;
12721
    case OPC_LWX:
12722
        op_ld_lw(t0, t0, ctx);
12723
        gen_store_gpr(t0, rd);
12724
        opn = "lwx";
12725
        break;
12726
#if defined(TARGET_MIPS64)
12727
    case OPC_LDX:
12728
        op_ld_ld(t0, t0, ctx);
12729
        gen_store_gpr(t0, rd);
12730
        opn = "ldx";
12731
        break;
12732
#endif
12733
    }
12734
    (void)opn; /* avoid a compiler warning */
12735
    MIPS_DEBUG("%s %s, %s(%s)", opn,
12736
               regnames[rd], regnames[offset], regnames[base]);
12737
    tcg_temp_free(t0);
12738
}
12739

    
12740
static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12741
                              int ret, int v1, int v2)
12742
{
12743
    const char *opn = "mipsdsp arith";
12744
    TCGv v1_t;
12745
    TCGv v2_t;
12746

    
12747
    if (ret == 0) {
12748
        /* Treat as NOP. */
12749
        MIPS_DEBUG("NOP");
12750
        return;
12751
    }
12752

    
12753
    v1_t = tcg_temp_new();
12754
    v2_t = tcg_temp_new();
12755

    
12756
    gen_load_gpr(v1_t, v1);
12757
    gen_load_gpr(v2_t, v2);
12758

    
12759
    switch (op1) {
12760
    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12761
    case OPC_MULT_G_2E:
12762
        check_dspr2(ctx);
12763
        switch (op2) {
12764
        case OPC_ADDUH_QB:
12765
            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12766
            break;
12767
        case OPC_ADDUH_R_QB:
12768
            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12769
            break;
12770
        case OPC_ADDQH_PH:
12771
            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12772
            break;
12773
        case OPC_ADDQH_R_PH:
12774
            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12775
            break;
12776
        case OPC_ADDQH_W:
12777
            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12778
            break;
12779
        case OPC_ADDQH_R_W:
12780
            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12781
            break;
12782
        case OPC_SUBUH_QB:
12783
            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12784
            break;
12785
        case OPC_SUBUH_R_QB:
12786
            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12787
            break;
12788
        case OPC_SUBQH_PH:
12789
            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12790
            break;
12791
        case OPC_SUBQH_R_PH:
12792
            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12793
            break;
12794
        case OPC_SUBQH_W:
12795
            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12796
            break;
12797
        case OPC_SUBQH_R_W:
12798
            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12799
            break;
12800
        }
12801
        break;
12802
    case OPC_ABSQ_S_PH_DSP:
12803
        switch (op2) {
12804
        case OPC_ABSQ_S_QB:
12805
            check_dspr2(ctx);
12806
            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12807
            break;
12808
        case OPC_ABSQ_S_PH:
12809
            check_dsp(ctx);
12810
            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12811
            break;
12812
        case OPC_ABSQ_S_W:
12813
            check_dsp(ctx);
12814
            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12815
            break;
12816
        case OPC_PRECEQ_W_PHL:
12817
            check_dsp(ctx);
12818
            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12819
            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12820
            break;
12821
        case OPC_PRECEQ_W_PHR:
12822
            check_dsp(ctx);
12823
            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12824
            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12825
            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12826
            break;
12827
        case OPC_PRECEQU_PH_QBL:
12828
            check_dsp(ctx);
12829
            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12830
            break;
12831
        case OPC_PRECEQU_PH_QBR:
12832
            check_dsp(ctx);
12833
            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12834
            break;
12835
        case OPC_PRECEQU_PH_QBLA:
12836
            check_dsp(ctx);
12837
            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12838
            break;
12839
        case OPC_PRECEQU_PH_QBRA:
12840
            check_dsp(ctx);
12841
            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12842
            break;
12843
        case OPC_PRECEU_PH_QBL:
12844
            check_dsp(ctx);
12845
            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12846
            break;
12847
        case OPC_PRECEU_PH_QBR:
12848
            check_dsp(ctx);
12849
            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12850
            break;
12851
        case OPC_PRECEU_PH_QBLA:
12852
            check_dsp(ctx);
12853
            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12854
            break;
12855
        case OPC_PRECEU_PH_QBRA:
12856
            check_dsp(ctx);
12857
            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12858
            break;
12859
        }
12860
        break;
12861
    case OPC_ADDU_QB_DSP:
12862
        switch (op2) {
12863
        case OPC_ADDQ_PH:
12864
            check_dsp(ctx);
12865
            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866
            break;
12867
        case OPC_ADDQ_S_PH:
12868
            check_dsp(ctx);
12869
            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870
            break;
12871
        case OPC_ADDQ_S_W:
12872
            check_dsp(ctx);
12873
            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12874
            break;
12875
        case OPC_ADDU_QB:
12876
            check_dsp(ctx);
12877
            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878
            break;
12879
        case OPC_ADDU_S_QB:
12880
            check_dsp(ctx);
12881
            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12882
            break;
12883
        case OPC_ADDU_PH:
12884
            check_dspr2(ctx);
12885
            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886
            break;
12887
        case OPC_ADDU_S_PH:
12888
            check_dspr2(ctx);
12889
            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12890
            break;
12891
        case OPC_SUBQ_PH:
12892
            check_dsp(ctx);
12893
            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12894
            break;
12895
        case OPC_SUBQ_S_PH:
12896
            check_dsp(ctx);
12897
            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12898
            break;
12899
        case OPC_SUBQ_S_W:
12900
            check_dsp(ctx);
12901
            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12902
            break;
12903
        case OPC_SUBU_QB:
12904
            check_dsp(ctx);
12905
            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12906
            break;
12907
        case OPC_SUBU_S_QB:
12908
            check_dsp(ctx);
12909
            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12910
            break;
12911
        case OPC_SUBU_PH:
12912
            check_dspr2(ctx);
12913
            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12914
            break;
12915
        case OPC_SUBU_S_PH:
12916
            check_dspr2(ctx);
12917
            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12918
            break;
12919
        case OPC_ADDSC:
12920
            check_dsp(ctx);
12921
            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12922
            break;
12923
        case OPC_ADDWC:
12924
            check_dsp(ctx);
12925
            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12926
            break;
12927
        case OPC_MODSUB:
12928
            check_dsp(ctx);
12929
            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12930
            break;
12931
        case OPC_RADDU_W_QB:
12932
            check_dsp(ctx);
12933
            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12934
            break;
12935
        }
12936
        break;
12937
    case OPC_CMPU_EQ_QB_DSP:
12938
        switch (op2) {
12939
        case OPC_PRECR_QB_PH:
12940
            check_dspr2(ctx);
12941
            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12942
            break;
12943
        case OPC_PRECRQ_QB_PH:
12944
            check_dsp(ctx);
12945
            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12946
            break;
12947
        case OPC_PRECR_SRA_PH_W:
12948
            check_dspr2(ctx);
12949
            {
12950
                TCGv_i32 sa_t = tcg_const_i32(v2);
12951
                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12952
                                          cpu_gpr[ret]);
12953
                tcg_temp_free_i32(sa_t);
12954
                break;
12955
            }
12956
        case OPC_PRECR_SRA_R_PH_W:
12957
            check_dspr2(ctx);
12958
            {
12959
                TCGv_i32 sa_t = tcg_const_i32(v2);
12960
                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12961
                                            cpu_gpr[ret]);
12962
                tcg_temp_free_i32(sa_t);
12963
                break;
12964
            }
12965
        case OPC_PRECRQ_PH_W:
12966
            check_dsp(ctx);
12967
            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12968
            break;
12969
        case OPC_PRECRQ_RS_PH_W:
12970
            check_dsp(ctx);
12971
            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12972
            break;
12973
        case OPC_PRECRQU_S_QB_PH:
12974
            check_dsp(ctx);
12975
            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12976
            break;
12977
        }
12978
        break;
12979
#ifdef TARGET_MIPS64
12980
    case OPC_ABSQ_S_QH_DSP:
12981
        switch (op2) {
12982
        case OPC_PRECEQ_L_PWL:
12983
            check_dsp(ctx);
12984
            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12985
            break;
12986
        case OPC_PRECEQ_L_PWR:
12987
            check_dsp(ctx);
12988
            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12989
            break;
12990
        case OPC_PRECEQ_PW_QHL:
12991
            check_dsp(ctx);
12992
            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12993
            break;
12994
        case OPC_PRECEQ_PW_QHR:
12995
            check_dsp(ctx);
12996
            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12997
            break;
12998
        case OPC_PRECEQ_PW_QHLA:
12999
            check_dsp(ctx);
13000
            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13001
            break;
13002
        case OPC_PRECEQ_PW_QHRA:
13003
            check_dsp(ctx);
13004
            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13005
            break;
13006
        case OPC_PRECEQU_QH_OBL:
13007
            check_dsp(ctx);
13008
            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13009
            break;
13010
        case OPC_PRECEQU_QH_OBR:
13011
            check_dsp(ctx);
13012
            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13013
            break;
13014
        case OPC_PRECEQU_QH_OBLA:
13015
            check_dsp(ctx);
13016
            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13017
            break;
13018
        case OPC_PRECEQU_QH_OBRA:
13019
            check_dsp(ctx);
13020
            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13021
            break;
13022
        case OPC_PRECEU_QH_OBL:
13023
            check_dsp(ctx);
13024
            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13025
            break;
13026
        case OPC_PRECEU_QH_OBR:
13027
            check_dsp(ctx);
13028
            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13029
            break;
13030
        case OPC_PRECEU_QH_OBLA:
13031
            check_dsp(ctx);
13032
            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13033
            break;
13034
        case OPC_PRECEU_QH_OBRA:
13035
            check_dsp(ctx);
13036
            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13037
            break;
13038
        case OPC_ABSQ_S_OB:
13039
            check_dspr2(ctx);
13040
            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13041
            break;
13042
        case OPC_ABSQ_S_PW:
13043
            check_dsp(ctx);
13044
            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13045
            break;
13046
        case OPC_ABSQ_S_QH:
13047
            check_dsp(ctx);
13048
            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13049
            break;
13050
        }
13051
        break;
13052
    case OPC_ADDU_OB_DSP:
13053
        switch (op2) {
13054
        case OPC_RADDU_L_OB:
13055
            check_dsp(ctx);
13056
            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13057
            break;
13058
        case OPC_SUBQ_PW:
13059
            check_dsp(ctx);
13060
            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061
            break;
13062
        case OPC_SUBQ_S_PW:
13063
            check_dsp(ctx);
13064
            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065
            break;
13066
        case OPC_SUBQ_QH:
13067
            check_dsp(ctx);
13068
            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13069
            break;
13070
        case OPC_SUBQ_S_QH:
13071
            check_dsp(ctx);
13072
            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073
            break;
13074
        case OPC_SUBU_OB:
13075
            check_dsp(ctx);
13076
            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13077
            break;
13078
        case OPC_SUBU_S_OB:
13079
            check_dsp(ctx);
13080
            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081
            break;
13082
        case OPC_SUBU_QH:
13083
            check_dspr2(ctx);
13084
            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13085
            break;
13086
        case OPC_SUBU_S_QH:
13087
            check_dspr2(ctx);
13088
            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089
            break;
13090
        case OPC_SUBUH_OB:
13091
            check_dspr2(ctx);
13092
            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13093
            break;
13094
        case OPC_SUBUH_R_OB:
13095
            check_dspr2(ctx);
13096
            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13097
            break;
13098
        case OPC_ADDQ_PW:
13099
            check_dsp(ctx);
13100
            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13101
            break;
13102
        case OPC_ADDQ_S_PW:
13103
            check_dsp(ctx);
13104
            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13105
            break;
13106
        case OPC_ADDQ_QH:
13107
            check_dsp(ctx);
13108
            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13109
            break;
13110
        case OPC_ADDQ_S_QH:
13111
            check_dsp(ctx);
13112
            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13113
            break;
13114
        case OPC_ADDU_OB:
13115
            check_dsp(ctx);
13116
            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13117
            break;
13118
        case OPC_ADDU_S_OB:
13119
            check_dsp(ctx);
13120
            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13121
            break;
13122
        case OPC_ADDU_QH:
13123
            check_dspr2(ctx);
13124
            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13125
            break;
13126
        case OPC_ADDU_S_QH:
13127
            check_dspr2(ctx);
13128
            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13129
            break;
13130
        case OPC_ADDUH_OB:
13131
            check_dspr2(ctx);
13132
            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13133
            break;
13134
        case OPC_ADDUH_R_OB:
13135
            check_dspr2(ctx);
13136
            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13137
            break;
13138
        }
13139
        break;
13140
    case OPC_CMPU_EQ_OB_DSP:
13141
        switch (op2) {
13142
        case OPC_PRECR_OB_QH:
13143
            check_dspr2(ctx);
13144
            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13145
            break;
13146
        case OPC_PRECR_SRA_QH_PW:
13147
            check_dspr2(ctx);
13148
            {
13149
                TCGv_i32 ret_t = tcg_const_i32(ret);
13150
                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13151
                tcg_temp_free_i32(ret_t);
13152
                break;
13153
            }
13154
        case OPC_PRECR_SRA_R_QH_PW:
13155
            check_dspr2(ctx);
13156
            {
13157
                TCGv_i32 sa_v = tcg_const_i32(ret);
13158
                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13159
                tcg_temp_free_i32(sa_v);
13160
                break;
13161
            }
13162
        case OPC_PRECRQ_OB_QH:
13163
            check_dsp(ctx);
13164
            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13165
            break;
13166
        case OPC_PRECRQ_PW_L:
13167
            check_dsp(ctx);
13168
            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13169
            break;
13170
        case OPC_PRECRQ_QH_PW:
13171
            check_dsp(ctx);
13172
            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13173
            break;
13174
        case OPC_PRECRQ_RS_QH_PW:
13175
            check_dsp(ctx);
13176
            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177
            break;
13178
        case OPC_PRECRQU_S_OB_QH:
13179
            check_dsp(ctx);
13180
            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181
            break;
13182
        }
13183
        break;
13184
#endif
13185
    }
13186

    
13187
    tcg_temp_free(v1_t);
13188
    tcg_temp_free(v2_t);
13189

    
13190
    (void)opn; /* avoid a compiler warning */
13191
    MIPS_DEBUG("%s", opn);
13192
}
13193

    
13194
static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13195
                              int ret, int v1, int v2)
13196
{
13197
    uint32_t op2;
13198
    const char *opn = "mipsdsp shift";
13199
    TCGv t0;
13200
    TCGv v1_t;
13201
    TCGv v2_t;
13202

    
13203
    if (ret == 0) {
13204
        /* Treat as NOP. */
13205
        MIPS_DEBUG("NOP");
13206
        return;
13207
    }
13208

    
13209
    t0 = tcg_temp_new();
13210
    v1_t = tcg_temp_new();
13211
    v2_t = tcg_temp_new();
13212

    
13213
    tcg_gen_movi_tl(t0, v1);
13214
    gen_load_gpr(v1_t, v1);
13215
    gen_load_gpr(v2_t, v2);
13216

    
13217
    switch (opc) {
13218
    case OPC_SHLL_QB_DSP:
13219
        {
13220
            op2 = MASK_SHLL_QB(ctx->opcode);
13221
            switch (op2) {
13222
            case OPC_SHLL_QB:
13223
                check_dsp(ctx);
13224
                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13225
                break;
13226
            case OPC_SHLLV_QB:
13227
                check_dsp(ctx);
13228
                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13229
                break;
13230
            case OPC_SHLL_PH:
13231
                check_dsp(ctx);
13232
                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13233
                break;
13234
            case OPC_SHLLV_PH:
13235
                check_dsp(ctx);
13236
                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13237
                break;
13238
            case OPC_SHLL_S_PH:
13239
                check_dsp(ctx);
13240
                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13241
                break;
13242
            case OPC_SHLLV_S_PH:
13243
                check_dsp(ctx);
13244
                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13245
                break;
13246
            case OPC_SHLL_S_W:
13247
                check_dsp(ctx);
13248
                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13249
                break;
13250
            case OPC_SHLLV_S_W:
13251
                check_dsp(ctx);
13252
                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13253
                break;
13254
            case OPC_SHRL_QB:
13255
                check_dsp(ctx);
13256
                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13257
                break;
13258
            case OPC_SHRLV_QB:
13259
                check_dsp(ctx);
13260
                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13261
                break;
13262
            case OPC_SHRL_PH:
13263
                check_dspr2(ctx);
13264
                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13265
                break;
13266
            case OPC_SHRLV_PH:
13267
                check_dspr2(ctx);
13268
                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13269
                break;
13270
            case OPC_SHRA_QB:
13271
                check_dspr2(ctx);
13272
                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13273
                break;
13274
            case OPC_SHRA_R_QB:
13275
                check_dspr2(ctx);
13276
                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13277
                break;
13278
            case OPC_SHRAV_QB:
13279
                check_dspr2(ctx);
13280
                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13281
                break;
13282
            case OPC_SHRAV_R_QB:
13283
                check_dspr2(ctx);
13284
                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13285
                break;
13286
            case OPC_SHRA_PH:
13287
                check_dsp(ctx);
13288
                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13289
                break;
13290
            case OPC_SHRA_R_PH:
13291
                check_dsp(ctx);
13292
                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13293
                break;
13294
            case OPC_SHRAV_PH:
13295
                check_dsp(ctx);
13296
                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13297
                break;
13298
            case OPC_SHRAV_R_PH:
13299
                check_dsp(ctx);
13300
                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13301
                break;
13302
            case OPC_SHRA_R_W:
13303
                check_dsp(ctx);
13304
                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13305
                break;
13306
            case OPC_SHRAV_R_W:
13307
                check_dsp(ctx);
13308
                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13309
                break;
13310
            default:            /* Invalid */
13311
                MIPS_INVAL("MASK SHLL.QB");
13312
                generate_exception(ctx, EXCP_RI);
13313
                break;
13314
            }
13315
            break;
13316
        }
13317
#ifdef TARGET_MIPS64
13318
    case OPC_SHLL_OB_DSP:
13319
        op2 = MASK_SHLL_OB(ctx->opcode);
13320
        switch (op2) {
13321
        case OPC_SHLL_PW:
13322
            check_dsp(ctx);
13323
            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13324
            break;
13325
        case OPC_SHLLV_PW:
13326
            check_dsp(ctx);
13327
            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13328
            break;
13329
        case OPC_SHLL_S_PW:
13330
            check_dsp(ctx);
13331
            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13332
            break;
13333
        case OPC_SHLLV_S_PW:
13334
            check_dsp(ctx);
13335
            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13336
            break;
13337
        case OPC_SHLL_OB:
13338
            check_dsp(ctx);
13339
            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13340
            break;
13341
        case OPC_SHLLV_OB:
13342
            check_dsp(ctx);
13343
            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13344
            break;
13345
        case OPC_SHLL_QH:
13346
            check_dsp(ctx);
13347
            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13348
            break;
13349
        case OPC_SHLLV_QH:
13350
            check_dsp(ctx);
13351
            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13352
            break;
13353
        case OPC_SHLL_S_QH:
13354
            check_dsp(ctx);
13355
            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13356
            break;
13357
        case OPC_SHLLV_S_QH:
13358
            check_dsp(ctx);
13359
            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13360
            break;
13361
        case OPC_SHRA_OB:
13362
            check_dspr2(ctx);
13363
            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13364
            break;
13365
        case OPC_SHRAV_OB:
13366
            check_dspr2(ctx);
13367
            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13368
            break;
13369
        case OPC_SHRA_R_OB:
13370
            check_dspr2(ctx);
13371
            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13372
            break;
13373
        case OPC_SHRAV_R_OB:
13374
            check_dspr2(ctx);
13375
            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13376
            break;
13377
        case OPC_SHRA_PW:
13378
            check_dsp(ctx);
13379
            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13380
            break;
13381
        case OPC_SHRAV_PW:
13382
            check_dsp(ctx);
13383
            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13384
            break;
13385
        case OPC_SHRA_R_PW:
13386
            check_dsp(ctx);
13387
            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13388
            break;
13389
        case OPC_SHRAV_R_PW:
13390
            check_dsp(ctx);
13391
            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13392
            break;
13393
        case OPC_SHRA_QH:
13394
            check_dsp(ctx);
13395
            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13396
            break;
13397
        case OPC_SHRAV_QH:
13398
            check_dsp(ctx);
13399
            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13400
            break;
13401
        case OPC_SHRA_R_QH:
13402
            check_dsp(ctx);
13403
            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13404
            break;
13405
        case OPC_SHRAV_R_QH:
13406
            check_dsp(ctx);
13407
            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13408
            break;
13409
        case OPC_SHRL_OB:
13410
            check_dsp(ctx);
13411
            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13412
            break;
13413
        case OPC_SHRLV_OB:
13414
            check_dsp(ctx);
13415
            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13416
            break;
13417
        case OPC_SHRL_QH:
13418
            check_dspr2(ctx);
13419
            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13420
            break;
13421
        case OPC_SHRLV_QH:
13422
            check_dspr2(ctx);
13423
            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13424
            break;
13425
        default:            /* Invalid */
13426
            MIPS_INVAL("MASK SHLL.OB");
13427
            generate_exception(ctx, EXCP_RI);
13428
            break;
13429
        }
13430
        break;
13431
#endif
13432
    }
13433

    
13434
    tcg_temp_free(t0);
13435
    tcg_temp_free(v1_t);
13436
    tcg_temp_free(v2_t);
13437
    (void)opn; /* avoid a compiler warning */
13438
    MIPS_DEBUG("%s", opn);
13439
}
13440

    
13441
static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13442
                                 int ret, int v1, int v2, int check_ret)
13443
{
13444
    const char *opn = "mipsdsp multiply";
13445
    TCGv_i32 t0;
13446
    TCGv v1_t;
13447
    TCGv v2_t;
13448

    
13449
    if ((ret == 0) && (check_ret == 1)) {
13450
        /* Treat as NOP. */
13451
        MIPS_DEBUG("NOP");
13452
        return;
13453
    }
13454

    
13455
    t0 = tcg_temp_new_i32();
13456
    v1_t = tcg_temp_new();
13457
    v2_t = tcg_temp_new();
13458

    
13459
    tcg_gen_movi_i32(t0, ret);
13460
    gen_load_gpr(v1_t, v1);
13461
    gen_load_gpr(v2_t, v2);
13462

    
13463
    switch (op1) {
13464
    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13465
     * the same mask and op1. */
13466
    case OPC_MULT_G_2E:
13467
        switch (op2) {
13468
        case  OPC_MUL_PH:
13469
            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13470
            break;
13471
        case  OPC_MUL_S_PH:
13472
            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13473
            break;
13474
        case OPC_MULQ_S_W:
13475
            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13476
            break;
13477
        case OPC_MULQ_RS_W:
13478
            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13479
            break;
13480
        }
13481
        break;
13482
    case OPC_DPA_W_PH_DSP:
13483
        switch (op2) {
13484
        case OPC_DPAU_H_QBL:
13485
            check_dsp(ctx);
13486
            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13487
            break;
13488
        case OPC_DPAU_H_QBR:
13489
            check_dsp(ctx);
13490
            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13491
            break;
13492
        case OPC_DPSU_H_QBL:
13493
            check_dsp(ctx);
13494
            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13495
            break;
13496
        case OPC_DPSU_H_QBR:
13497
            check_dsp(ctx);
13498
            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13499
            break;
13500
        case OPC_DPA_W_PH:
13501
            check_dspr2(ctx);
13502
            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13503
            break;
13504
        case OPC_DPAX_W_PH:
13505
            check_dspr2(ctx);
13506
            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13507
            break;
13508
        case OPC_DPAQ_S_W_PH:
13509
            check_dsp(ctx);
13510
            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13511
            break;
13512
        case OPC_DPAQX_S_W_PH:
13513
            check_dspr2(ctx);
13514
            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13515
            break;
13516
        case OPC_DPAQX_SA_W_PH:
13517
            check_dspr2(ctx);
13518
            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13519
            break;
13520
        case OPC_DPS_W_PH:
13521
            check_dspr2(ctx);
13522
            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13523
            break;
13524
        case OPC_DPSX_W_PH:
13525
            check_dspr2(ctx);
13526
            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13527
            break;
13528
        case OPC_DPSQ_S_W_PH:
13529
            check_dsp(ctx);
13530
            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13531
            break;
13532
        case OPC_DPSQX_S_W_PH:
13533
            check_dspr2(ctx);
13534
            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13535
            break;
13536
        case OPC_DPSQX_SA_W_PH:
13537
            check_dspr2(ctx);
13538
            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13539
            break;
13540
        case OPC_MULSAQ_S_W_PH:
13541
            check_dsp(ctx);
13542
            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13543
            break;
13544
        case OPC_DPAQ_SA_L_W:
13545
            check_dsp(ctx);
13546
            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13547
            break;
13548
        case OPC_DPSQ_SA_L_W:
13549
            check_dsp(ctx);
13550
            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13551
            break;
13552
        case OPC_MAQ_S_W_PHL:
13553
            check_dsp(ctx);
13554
            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13555
            break;
13556
        case OPC_MAQ_S_W_PHR:
13557
            check_dsp(ctx);
13558
            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13559
            break;
13560
        case OPC_MAQ_SA_W_PHL:
13561
            check_dsp(ctx);
13562
            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13563
            break;
13564
        case OPC_MAQ_SA_W_PHR:
13565
            check_dsp(ctx);
13566
            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13567
            break;
13568
        case OPC_MULSA_W_PH:
13569
            check_dspr2(ctx);
13570
            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13571
            break;
13572
        }
13573
        break;
13574
#ifdef TARGET_MIPS64
13575
    case OPC_DPAQ_W_QH_DSP:
13576
        {
13577
            int ac = ret & 0x03;
13578
            tcg_gen_movi_i32(t0, ac);
13579

    
13580
            switch (op2) {
13581
            case OPC_DMADD:
13582
                check_dsp(ctx);
13583
                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13584
                break;
13585
            case OPC_DMADDU:
13586
                check_dsp(ctx);
13587
                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13588
                break;
13589
            case OPC_DMSUB:
13590
                check_dsp(ctx);
13591
                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13592
                break;
13593
            case OPC_DMSUBU:
13594
                check_dsp(ctx);
13595
                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13596
                break;
13597
            case OPC_DPA_W_QH:
13598
                check_dspr2(ctx);
13599
                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13600
                break;
13601
            case OPC_DPAQ_S_W_QH:
13602
                check_dsp(ctx);
13603
                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13604
                break;
13605
            case OPC_DPAQ_SA_L_PW:
13606
                check_dsp(ctx);
13607
                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13608
                break;
13609
            case OPC_DPAU_H_OBL:
13610
                check_dsp(ctx);
13611
                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13612
                break;
13613
            case OPC_DPAU_H_OBR:
13614
                check_dsp(ctx);
13615
                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13616
                break;
13617
            case OPC_DPS_W_QH:
13618
                check_dspr2(ctx);
13619
                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13620
                break;
13621
            case OPC_DPSQ_S_W_QH:
13622
                check_dsp(ctx);
13623
                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13624
                break;
13625
            case OPC_DPSQ_SA_L_PW:
13626
                check_dsp(ctx);
13627
                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13628
                break;
13629
            case OPC_DPSU_H_OBL:
13630
                check_dsp(ctx);
13631
                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13632
                break;
13633
            case OPC_DPSU_H_OBR:
13634
                check_dsp(ctx);
13635
                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13636
                break;
13637
            case OPC_MAQ_S_L_PWL:
13638
                check_dsp(ctx);
13639
                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13640
                break;
13641
            case OPC_MAQ_S_L_PWR:
13642
                check_dsp(ctx);
13643
                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13644
                break;
13645
            case OPC_MAQ_S_W_QHLL:
13646
                check_dsp(ctx);
13647
                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13648
                break;
13649
            case OPC_MAQ_SA_W_QHLL:
13650
                check_dsp(ctx);
13651
                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13652
                break;
13653
            case OPC_MAQ_S_W_QHLR:
13654
                check_dsp(ctx);
13655
                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13656
                break;
13657
            case OPC_MAQ_SA_W_QHLR:
13658
                check_dsp(ctx);
13659
                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13660
                break;
13661
            case OPC_MAQ_S_W_QHRL:
13662
                check_dsp(ctx);
13663
                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13664
                break;
13665
            case OPC_MAQ_SA_W_QHRL:
13666
                check_dsp(ctx);
13667
                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13668
                break;
13669
            case OPC_MAQ_S_W_QHRR:
13670
                check_dsp(ctx);
13671
                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13672
                break;
13673
            case OPC_MAQ_SA_W_QHRR:
13674
                check_dsp(ctx);
13675
                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13676
                break;
13677
            case OPC_MULSAQ_S_L_PW:
13678
                check_dsp(ctx);
13679
                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13680
                break;
13681
            case OPC_MULSAQ_S_W_QH:
13682
                check_dsp(ctx);
13683
                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13684
                break;
13685
            }
13686
        }
13687
        break;
13688
#endif
13689
    case OPC_ADDU_QB_DSP:
13690
        switch (op2) {
13691
        case OPC_MULEU_S_PH_QBL:
13692
            check_dsp(ctx);
13693
            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13694
            break;
13695
        case OPC_MULEU_S_PH_QBR:
13696
            check_dsp(ctx);
13697
            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698
            break;
13699
        case OPC_MULQ_RS_PH:
13700
            check_dsp(ctx);
13701
            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13702
            break;
13703
        case OPC_MULEQ_S_W_PHL:
13704
            check_dsp(ctx);
13705
            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13706
            break;
13707
        case OPC_MULEQ_S_W_PHR:
13708
            check_dsp(ctx);
13709
            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13710
            break;
13711
        case OPC_MULQ_S_PH:
13712
            check_dspr2(ctx);
13713
            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13714
            break;
13715
        }
13716
        break;
13717
#ifdef TARGET_MIPS64
13718
    case OPC_ADDU_OB_DSP:
13719
        switch (op2) {
13720
        case OPC_MULEQ_S_PW_QHL:
13721
            check_dsp(ctx);
13722
            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13723
            break;
13724
        case OPC_MULEQ_S_PW_QHR:
13725
            check_dsp(ctx);
13726
            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13727
            break;
13728
        case OPC_MULEU_S_QH_OBL:
13729
            check_dsp(ctx);
13730
            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13731
            break;
13732
        case OPC_MULEU_S_QH_OBR:
13733
            check_dsp(ctx);
13734
            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13735
            break;
13736
        case OPC_MULQ_RS_QH:
13737
            check_dsp(ctx);
13738
            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13739
            break;
13740
        }
13741
        break;
13742
#endif
13743
    }
13744

    
13745
    tcg_temp_free_i32(t0);
13746
    tcg_temp_free(v1_t);
13747
    tcg_temp_free(v2_t);
13748

    
13749
    (void)opn; /* avoid a compiler warning */
13750
    MIPS_DEBUG("%s", opn);
13751

    
13752
}
13753

    
13754
static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13755
                                uint32_t op1, uint32_t op2,
13756
                                int ret, int val)
13757
{
13758
    const char *opn = "mipsdsp Bit/ Manipulation";
13759
    int16_t imm;
13760
    TCGv t0;
13761
    TCGv val_t;
13762

    
13763
    if (ret == 0) {
13764
        /* Treat as NOP. */
13765
        MIPS_DEBUG("NOP");
13766
        return;
13767
    }
13768

    
13769
    t0 = tcg_temp_new();
13770
    val_t = tcg_temp_new();
13771
    gen_load_gpr(val_t, val);
13772

    
13773
    switch (op1) {
13774
    case OPC_ABSQ_S_PH_DSP:
13775
        switch (op2) {
13776
        case OPC_BITREV:
13777
            check_dsp(ctx);
13778
            gen_helper_bitrev(cpu_gpr[ret], val_t);
13779
            break;
13780
        case OPC_REPL_QB:
13781
            check_dsp(ctx);
13782
            {
13783
                target_long result;
13784
                imm = (ctx->opcode >> 16) & 0xFF;
13785
                result = (uint32_t)imm << 24 |
13786
                         (uint32_t)imm << 16 |
13787
                         (uint32_t)imm << 8  |
13788
                         (uint32_t)imm;
13789
                result = (int32_t)result;
13790
                tcg_gen_movi_tl(cpu_gpr[ret], result);
13791
            }
13792
            break;
13793
        case OPC_REPLV_QB:
13794
            check_dsp(ctx);
13795
            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13796
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13797
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13798
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13799
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13800
            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13801
            break;
13802
        case OPC_REPL_PH:
13803
            check_dsp(ctx);
13804
            {
13805
                imm = (ctx->opcode >> 16) & 0x03FF;
13806
                tcg_gen_movi_tl(cpu_gpr[ret], \
13807
                                (target_long)((int32_t)imm << 16 | \
13808
                                (uint32_t)(uint16_t)imm));
13809
            }
13810
            break;
13811
        case OPC_REPLV_PH:
13812
            check_dsp(ctx);
13813
            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13814
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13815
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816
            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13817
            break;
13818
        }
13819
        break;
13820
#ifdef TARGET_MIPS64
13821
    case OPC_ABSQ_S_QH_DSP:
13822
        switch (op2) {
13823
        case OPC_REPL_OB:
13824
            check_dsp(ctx);
13825
            {
13826
                target_long temp;
13827

    
13828
                imm = (ctx->opcode >> 16) & 0xFF;
13829
                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13830
                temp = (temp << 16) | temp;
13831
                temp = (temp << 32) | temp;
13832
                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13833
                break;
13834
            }
13835
        case OPC_REPL_PW:
13836
            check_dsp(ctx);
13837
            {
13838
                target_long temp;
13839

    
13840
                imm = (ctx->opcode >> 16) & 0x03FF;
13841
                imm = (int16_t)(imm << 6) >> 6;
13842
                temp = ((target_long)imm << 32) \
13843
                       | ((target_long)imm & 0xFFFFFFFF);
13844
                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13845
                break;
13846
            }
13847
        case OPC_REPL_QH:
13848
            check_dsp(ctx);
13849
            {
13850
                target_long temp;
13851

    
13852
                imm = (ctx->opcode >> 16) & 0x03FF;
13853
                imm = (int16_t)(imm << 6) >> 6;
13854

    
13855
                temp = ((uint64_t)(uint16_t)imm << 48) |
13856
                       ((uint64_t)(uint16_t)imm << 32) |
13857
                       ((uint64_t)(uint16_t)imm << 16) |
13858
                       (uint64_t)(uint16_t)imm;
13859
                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13860
                break;
13861
            }
13862
        case OPC_REPLV_OB:
13863
            check_dsp(ctx);
13864
            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13865
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13866
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13867
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13868
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13869
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13870
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13871
            break;
13872
        case OPC_REPLV_PW:
13873
            check_dsp(ctx);
13874
            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13875
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13876
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13877
            break;
13878
        case OPC_REPLV_QH:
13879
            check_dsp(ctx);
13880
            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13881
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13882
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13883
            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13884
            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13885
            break;
13886
        }
13887
        break;
13888
#endif
13889
    }
13890
    tcg_temp_free(t0);
13891
    tcg_temp_free(val_t);
13892

    
13893
    (void)opn; /* avoid a compiler warning */
13894
    MIPS_DEBUG("%s", opn);
13895
}
13896

    
13897
static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13898
                                     uint32_t op1, uint32_t op2,
13899
                                     int ret, int v1, int v2, int check_ret)
13900
{
13901
    const char *opn = "mipsdsp add compare pick";
13902
    TCGv_i32 t0;
13903
    TCGv t1;
13904
    TCGv v1_t;
13905
    TCGv v2_t;
13906

    
13907
    if ((ret == 0) && (check_ret == 1)) {
13908
        /* Treat as NOP. */
13909
        MIPS_DEBUG("NOP");
13910
        return;
13911
    }
13912

    
13913
    t0 = tcg_temp_new_i32();
13914
    t1 = tcg_temp_new();
13915
    v1_t = tcg_temp_new();
13916
    v2_t = tcg_temp_new();
13917

    
13918
    gen_load_gpr(v1_t, v1);
13919
    gen_load_gpr(v2_t, v2);
13920

    
13921
    switch (op1) {
13922
    case OPC_APPEND_DSP:
13923
        switch (op2) {
13924
        case OPC_APPEND:
13925
            tcg_gen_movi_i32(t0, v2);
13926
            gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13927
            break;
13928
        case OPC_PREPEND:
13929
            tcg_gen_movi_i32(t0, v2);
13930
            gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13931
            break;
13932
        case OPC_BALIGN:
13933
            tcg_gen_movi_i32(t0, v2);
13934
            gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13935
            break;
13936
        default:            /* Invid */
13937
            MIPS_INVAL("MASK APPEND");
13938
            generate_exception(ctx, EXCP_RI);
13939
            break;
13940
        }
13941
        break;
13942
    case OPC_CMPU_EQ_QB_DSP:
13943
        switch (op2) {
13944
        case OPC_CMPU_EQ_QB:
13945
            check_dsp(ctx);
13946
            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13947
            break;
13948
        case OPC_CMPU_LT_QB:
13949
            check_dsp(ctx);
13950
            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13951
            break;
13952
        case OPC_CMPU_LE_QB:
13953
            check_dsp(ctx);
13954
            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13955
            break;
13956
        case OPC_CMPGU_EQ_QB:
13957
            check_dsp(ctx);
13958
            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13959
            break;
13960
        case OPC_CMPGU_LT_QB:
13961
            check_dsp(ctx);
13962
            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13963
            break;
13964
        case OPC_CMPGU_LE_QB:
13965
            check_dsp(ctx);
13966
            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13967
            break;
13968
        case OPC_CMPGDU_EQ_QB:
13969
            check_dspr2(ctx);
13970
            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13971
            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13972
            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13973
            tcg_gen_shli_tl(t1, t1, 24);
13974
            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13975
            break;
13976
        case OPC_CMPGDU_LT_QB:
13977
            check_dspr2(ctx);
13978
            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13979
            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13980
            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13981
            tcg_gen_shli_tl(t1, t1, 24);
13982
            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13983
            break;
13984
        case OPC_CMPGDU_LE_QB:
13985
            check_dspr2(ctx);
13986
            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13987
            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13988
            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13989
            tcg_gen_shli_tl(t1, t1, 24);
13990
            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13991
            break;
13992
        case OPC_CMP_EQ_PH:
13993
            check_dsp(ctx);
13994
            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13995
            break;
13996
        case OPC_CMP_LT_PH:
13997
            check_dsp(ctx);
13998
            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13999
            break;
14000
        case OPC_CMP_LE_PH:
14001
            check_dsp(ctx);
14002
            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14003
            break;
14004
        case OPC_PICK_QB:
14005
            check_dsp(ctx);
14006
            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14007
            break;
14008
        case OPC_PICK_PH:
14009
            check_dsp(ctx);
14010
            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14011
            break;
14012
        case OPC_PACKRL_PH:
14013
            check_dsp(ctx);
14014
            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14015
            break;
14016
        }
14017
        break;
14018
#ifdef TARGET_MIPS64
14019
    case OPC_CMPU_EQ_OB_DSP:
14020
        switch (op2) {
14021
        case OPC_CMP_EQ_PW:
14022
            check_dsp(ctx);
14023
            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14024
            break;
14025
        case OPC_CMP_LT_PW:
14026
            check_dsp(ctx);
14027
            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14028
            break;
14029
        case OPC_CMP_LE_PW:
14030
            check_dsp(ctx);
14031
            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14032
            break;
14033
        case OPC_CMP_EQ_QH:
14034
            check_dsp(ctx);
14035
            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14036
            break;
14037
        case OPC_CMP_LT_QH:
14038
            check_dsp(ctx);
14039
            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14040
            break;
14041
        case OPC_CMP_LE_QH:
14042
            check_dsp(ctx);
14043
            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14044
            break;
14045
        case OPC_CMPGDU_EQ_OB:
14046
            check_dspr2(ctx);
14047
            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14048
            break;
14049
        case OPC_CMPGDU_LT_OB:
14050
            check_dspr2(ctx);
14051
            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14052
            break;
14053
        case OPC_CMPGDU_LE_OB:
14054
            check_dspr2(ctx);
14055
            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14056
            break;
14057
        case OPC_CMPGU_EQ_OB:
14058
            check_dsp(ctx);
14059
            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14060
            break;
14061
        case OPC_CMPGU_LT_OB:
14062
            check_dsp(ctx);
14063
            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14064
            break;
14065
        case OPC_CMPGU_LE_OB:
14066
            check_dsp(ctx);
14067
            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14068
            break;
14069
        case OPC_CMPU_EQ_OB:
14070
            check_dsp(ctx);
14071
            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14072
            break;
14073
        case OPC_CMPU_LT_OB:
14074
            check_dsp(ctx);
14075
            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14076
            break;
14077
        case OPC_CMPU_LE_OB:
14078
            check_dsp(ctx);
14079
            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14080
            break;
14081
        case OPC_PACKRL_PW:
14082
            check_dsp(ctx);
14083
            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14084
            break;
14085
        case OPC_PICK_OB:
14086
            check_dsp(ctx);
14087
            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14088
            break;
14089
        case OPC_PICK_PW:
14090
            check_dsp(ctx);
14091
            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14092
            break;
14093
        case OPC_PICK_QH:
14094
            check_dsp(ctx);
14095
            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14096
            break;
14097
        }
14098
        break;
14099
    case OPC_DAPPEND_DSP:
14100
        switch (op2) {
14101
        case OPC_DAPPEND:
14102
            tcg_gen_movi_i32(t0, v2);
14103
            gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14104
            break;
14105
        case OPC_PREPENDD:
14106
            tcg_gen_movi_i32(t0, v2);
14107
            gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14108
            break;
14109
        case OPC_PREPENDW:
14110
            tcg_gen_movi_i32(t0, v2);
14111
            gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14112
            break;
14113
        case OPC_DBALIGN:
14114
            tcg_gen_movi_i32(t0, v2);
14115
            gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14116
            break;
14117
        default:            /* Invalid */
14118
            MIPS_INVAL("MASK DAPPEND");
14119
            generate_exception(ctx, EXCP_RI);
14120
            break;
14121
        }
14122
        break;
14123
#endif
14124
    }
14125

    
14126
    tcg_temp_free_i32(t0);
14127
    tcg_temp_free(t1);
14128
    tcg_temp_free(v1_t);
14129
    tcg_temp_free(v2_t);
14130

    
14131
    (void)opn; /* avoid a compiler warning */
14132
    MIPS_DEBUG("%s", opn);
14133
}
14134

    
14135
static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14136
                                int ret, int v1, int v2, int check_ret)
14137

    
14138
{
14139
    const char *opn = "mipsdsp accumulator";
14140
    TCGv t0;
14141
    TCGv t1;
14142
    TCGv v1_t;
14143
    TCGv v2_t;
14144
    int16_t imm;
14145

    
14146
    if ((ret == 0) && (check_ret == 1)) {
14147
        /* Treat as NOP. */
14148
        MIPS_DEBUG("NOP");
14149
        return;
14150
    }
14151

    
14152
    t0 = tcg_temp_new();
14153
    t1 = tcg_temp_new();
14154
    v1_t = tcg_temp_new();
14155
    v2_t = tcg_temp_new();
14156

    
14157
    gen_load_gpr(v1_t, v1);
14158
    gen_load_gpr(v2_t, v2);
14159

    
14160
    switch (op1) {
14161
    case OPC_EXTR_W_DSP:
14162
        check_dsp(ctx);
14163
        switch (op2) {
14164
        case OPC_EXTR_W:
14165
            tcg_gen_movi_tl(t0, v2);
14166
            tcg_gen_movi_tl(t1, v1);
14167
            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14168
            break;
14169
        case OPC_EXTR_R_W:
14170
            tcg_gen_movi_tl(t0, v2);
14171
            tcg_gen_movi_tl(t1, v1);
14172
            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14173
            break;
14174
        case OPC_EXTR_RS_W:
14175
            tcg_gen_movi_tl(t0, v2);
14176
            tcg_gen_movi_tl(t1, v1);
14177
            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14178
            break;
14179
        case OPC_EXTR_S_H:
14180
            tcg_gen_movi_tl(t0, v2);
14181
            tcg_gen_movi_tl(t1, v1);
14182
            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14183
            break;
14184
        case OPC_EXTRV_S_H:
14185
            tcg_gen_movi_tl(t0, v2);
14186
            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14187
            break;
14188
        case OPC_EXTRV_W:
14189
            tcg_gen_movi_tl(t0, v2);
14190
            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14191
            break;
14192
        case OPC_EXTRV_R_W:
14193
            tcg_gen_movi_tl(t0, v2);
14194
            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14195
            break;
14196
        case OPC_EXTRV_RS_W:
14197
            tcg_gen_movi_tl(t0, v2);
14198
            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14199
            break;
14200
        case OPC_EXTP:
14201
            tcg_gen_movi_tl(t0, v2);
14202
            tcg_gen_movi_tl(t1, v1);
14203
            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14204
            break;
14205
        case OPC_EXTPV:
14206
            tcg_gen_movi_tl(t0, v2);
14207
            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14208
            break;
14209
        case OPC_EXTPDP:
14210
            tcg_gen_movi_tl(t0, v2);
14211
            tcg_gen_movi_tl(t1, v1);
14212
            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14213
            break;
14214
        case OPC_EXTPDPV:
14215
            tcg_gen_movi_tl(t0, v2);
14216
            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14217
            break;
14218
        case OPC_SHILO:
14219
            imm = (ctx->opcode >> 20) & 0x3F;
14220
            tcg_gen_movi_tl(t0, ret);
14221
            tcg_gen_movi_tl(t1, imm);
14222
            gen_helper_shilo(t0, t1, cpu_env);
14223
            break;
14224
        case OPC_SHILOV:
14225
            tcg_gen_movi_tl(t0, ret);
14226
            gen_helper_shilo(t0, v1_t, cpu_env);
14227
            break;
14228
        case OPC_MTHLIP:
14229
            tcg_gen_movi_tl(t0, ret);
14230
            gen_helper_mthlip(t0, v1_t, cpu_env);
14231
            break;
14232
        case OPC_WRDSP:
14233
            imm = (ctx->opcode >> 11) & 0x3FF;
14234
            tcg_gen_movi_tl(t0, imm);
14235
            gen_helper_wrdsp(v1_t, t0, cpu_env);
14236
            break;
14237
        case OPC_RDDSP:
14238
            imm = (ctx->opcode >> 16) & 0x03FF;
14239
            tcg_gen_movi_tl(t0, imm);
14240
            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14241
            break;
14242
        }
14243
        break;
14244
#ifdef TARGET_MIPS64
14245
    case OPC_DEXTR_W_DSP:
14246
        check_dsp(ctx);
14247
        switch (op2) {
14248
        case OPC_DMTHLIP:
14249
            tcg_gen_movi_tl(t0, ret);
14250
            gen_helper_dmthlip(v1_t, t0, cpu_env);
14251
            break;
14252
        case OPC_DSHILO:
14253
            {
14254
                int shift = (ctx->opcode >> 19) & 0x7F;
14255
                int ac = (ctx->opcode >> 11) & 0x03;
14256
                tcg_gen_movi_tl(t0, shift);
14257
                tcg_gen_movi_tl(t1, ac);
14258
                gen_helper_dshilo(t0, t1, cpu_env);
14259
                break;
14260
            }
14261
        case OPC_DSHILOV:
14262
            {
14263
                int ac = (ctx->opcode >> 11) & 0x03;
14264
                tcg_gen_movi_tl(t0, ac);
14265
                gen_helper_dshilo(v1_t, t0, cpu_env);
14266
                break;
14267
            }
14268
        case OPC_DEXTP:
14269
            tcg_gen_movi_tl(t0, v2);
14270
            tcg_gen_movi_tl(t1, v1);
14271

    
14272
            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14273
            break;
14274
        case OPC_DEXTPV:
14275
            tcg_gen_movi_tl(t0, v2);
14276
            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14277
            break;
14278
        case OPC_DEXTPDP:
14279
            tcg_gen_movi_tl(t0, v2);
14280
            tcg_gen_movi_tl(t1, v1);
14281
            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14282
            break;
14283
        case OPC_DEXTPDPV:
14284
            tcg_gen_movi_tl(t0, v2);
14285
            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14286
            break;
14287
        case OPC_DEXTR_L:
14288
            tcg_gen_movi_tl(t0, v2);
14289
            tcg_gen_movi_tl(t1, v1);
14290
            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14291
            break;
14292
        case OPC_DEXTR_R_L:
14293
            tcg_gen_movi_tl(t0, v2);
14294
            tcg_gen_movi_tl(t1, v1);
14295
            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14296
            break;
14297
        case OPC_DEXTR_RS_L:
14298
            tcg_gen_movi_tl(t0, v2);
14299
            tcg_gen_movi_tl(t1, v1);
14300
            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14301
            break;
14302
        case OPC_DEXTR_W:
14303
            tcg_gen_movi_tl(t0, v2);
14304
            tcg_gen_movi_tl(t1, v1);
14305
            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14306
            break;
14307
        case OPC_DEXTR_R_W:
14308
            tcg_gen_movi_tl(t0, v2);
14309
            tcg_gen_movi_tl(t1, v1);
14310
            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14311
            break;
14312
        case OPC_DEXTR_RS_W:
14313
            tcg_gen_movi_tl(t0, v2);
14314
            tcg_gen_movi_tl(t1, v1);
14315
            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14316
            break;
14317
        case OPC_DEXTR_S_H:
14318
            tcg_gen_movi_tl(t0, v2);
14319
            tcg_gen_movi_tl(t1, v1);
14320
            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14321
            break;
14322
        case OPC_DEXTRV_S_H:
14323
            tcg_gen_movi_tl(t0, v2);
14324
            tcg_gen_movi_tl(t1, v1);
14325
            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14326
            break;
14327
        case OPC_DEXTRV_L:
14328
            tcg_gen_movi_tl(t0, v2);
14329
            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14330
            break;
14331
        case OPC_DEXTRV_R_L:
14332
            tcg_gen_movi_tl(t0, v2);
14333
            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14334
            break;
14335
        case OPC_DEXTRV_RS_L:
14336
            tcg_gen_movi_tl(t0, v2);
14337
            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14338
            break;
14339
        case OPC_DEXTRV_W:
14340
            tcg_gen_movi_tl(t0, v2);
14341
            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14342
            break;
14343
        case OPC_DEXTRV_R_W:
14344
            tcg_gen_movi_tl(t0, v2);
14345
            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14346
            break;
14347
        case OPC_DEXTRV_RS_W:
14348
            tcg_gen_movi_tl(t0, v2);
14349
            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14350
            break;
14351
        }
14352
        break;
14353
#endif
14354
    }
14355

    
14356
    tcg_temp_free(t0);
14357
    tcg_temp_free(t1);
14358
    tcg_temp_free(v1_t);
14359
    tcg_temp_free(v2_t);
14360

    
14361
    (void)opn; /* avoid a compiler warning */
14362
    MIPS_DEBUG("%s", opn);
14363
}
14364

    
14365
/* End MIPSDSP functions. */
14366

    
14367
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14368
{
14369
    int32_t offset;
14370
    int rs, rt, rd, sa;
14371
    uint32_t op, op1, op2;
14372
    int16_t imm;
14373

    
14374
    /* make sure instructions are on a word boundary */
14375
    if (ctx->pc & 0x3) {
14376
        env->CP0_BadVAddr = ctx->pc;
14377
        generate_exception(ctx, EXCP_AdEL);
14378
        return;
14379
    }
14380

    
14381
    /* Handle blikely not taken case */
14382
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14383
        int l1 = gen_new_label();
14384

    
14385
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14386
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14387
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14388
        gen_goto_tb(ctx, 1, ctx->pc + 4);
14389
        gen_set_label(l1);
14390
    }
14391

    
14392
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14393
        tcg_gen_debug_insn_start(ctx->pc);
14394
    }
14395

    
14396
    op = MASK_OP_MAJOR(ctx->opcode);
14397
    rs = (ctx->opcode >> 21) & 0x1f;
14398
    rt = (ctx->opcode >> 16) & 0x1f;
14399
    rd = (ctx->opcode >> 11) & 0x1f;
14400
    sa = (ctx->opcode >> 6) & 0x1f;
14401
    imm = (int16_t)ctx->opcode;
14402
    switch (op) {
14403
    case OPC_SPECIAL:
14404
        op1 = MASK_SPECIAL(ctx->opcode);
14405
        switch (op1) {
14406
        case OPC_SLL:          /* Shift with immediate */
14407
        case OPC_SRA:
14408
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
14409
            break;
14410
        case OPC_SRL:
14411
            switch ((ctx->opcode >> 21) & 0x1f) {
14412
            case 1:
14413
                /* rotr is decoded as srl on non-R2 CPUs */
14414
                if (env->insn_flags & ISA_MIPS32R2) {
14415
                    op1 = OPC_ROTR;
14416
                }
14417
                /* Fallthrough */
14418
            case 0:
14419
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
14420
                break;
14421
            default:
14422
                generate_exception(ctx, EXCP_RI);
14423
                break;
14424
            }
14425
            break;
14426
        case OPC_MOVN:         /* Conditional move */
14427
        case OPC_MOVZ:
14428
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14429
                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
14430
            gen_cond_move(env, ctx, op1, rd, rs, rt);
14431
            break;
14432
        case OPC_ADD ... OPC_SUBU:
14433
            gen_arith(env, ctx, op1, rd, rs, rt);
14434
            break;
14435
        case OPC_SLLV:         /* Shifts */
14436
        case OPC_SRAV:
14437
            gen_shift(env, ctx, op1, rd, rs, rt);
14438
            break;
14439
        case OPC_SRLV:
14440
            switch ((ctx->opcode >> 6) & 0x1f) {
14441
            case 1:
14442
                /* rotrv is decoded as srlv on non-R2 CPUs */
14443
                if (env->insn_flags & ISA_MIPS32R2) {
14444
                    op1 = OPC_ROTRV;
14445
                }
14446
                /* Fallthrough */
14447
            case 0:
14448
                gen_shift(env, ctx, op1, rd, rs, rt);
14449
                break;
14450
            default:
14451
                generate_exception(ctx, EXCP_RI);
14452
                break;
14453
            }
14454
            break;
14455
        case OPC_SLT:          /* Set on less than */
14456
        case OPC_SLTU:
14457
            gen_slt(env, ctx, op1, rd, rs, rt);
14458
            break;
14459
        case OPC_AND:          /* Logic*/
14460
        case OPC_OR:
14461
        case OPC_NOR:
14462
        case OPC_XOR:
14463
            gen_logic(env, ctx, op1, rd, rs, rt);
14464
            break;
14465
        case OPC_MULT ... OPC_DIVU:
14466
            if (sa) {
14467
                check_insn(env, ctx, INSN_VR54XX);
14468
                op1 = MASK_MUL_VR54XX(ctx->opcode);
14469
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14470
            } else
14471
                gen_muldiv(ctx, op1, rs, rt);
14472
            break;
14473
        case OPC_JR ... OPC_JALR:
14474
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14475
            *is_branch = 1;
14476
            break;
14477
        case OPC_TGE ... OPC_TEQ: /* Traps */
14478
        case OPC_TNE:
14479
            gen_trap(ctx, op1, rs, rt, -1);
14480
            break;
14481
        case OPC_MFHI:          /* Move from HI/LO */
14482
        case OPC_MFLO:
14483
            gen_HILO(ctx, op1, rd);
14484
            break;
14485
        case OPC_MTHI:
14486
        case OPC_MTLO:          /* Move to HI/LO */
14487
            gen_HILO(ctx, op1, rs);
14488
            break;
14489
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
14490
#ifdef MIPS_STRICT_STANDARD
14491
            MIPS_INVAL("PMON / selsl");
14492
            generate_exception(ctx, EXCP_RI);
14493
#else
14494
            gen_helper_0e0i(pmon, sa);
14495
#endif
14496
            break;
14497
        case OPC_SYSCALL:
14498
            generate_exception(ctx, EXCP_SYSCALL);
14499
            ctx->bstate = BS_STOP;
14500
            break;
14501
        case OPC_BREAK:
14502
            generate_exception(ctx, EXCP_BREAK);
14503
            break;
14504
        case OPC_SPIM:
14505
#ifdef MIPS_STRICT_STANDARD
14506
            MIPS_INVAL("SPIM");
14507
            generate_exception(ctx, EXCP_RI);
14508
#else
14509
           /* Implemented as RI exception for now. */
14510
            MIPS_INVAL("spim (unofficial)");
14511
            generate_exception(ctx, EXCP_RI);
14512
#endif
14513
            break;
14514
        case OPC_SYNC:
14515
            /* Treat as NOP. */
14516
            break;
14517

    
14518
        case OPC_MOVCI:
14519
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14520
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14521
                check_cp1_enabled(ctx);
14522
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14523
                          (ctx->opcode >> 16) & 1);
14524
            } else {
14525
                generate_exception_err(ctx, EXCP_CpU, 1);
14526
            }
14527
            break;
14528

    
14529
#if defined(TARGET_MIPS64)
14530
       /* MIPS64 specific opcodes */
14531
        case OPC_DSLL:
14532
        case OPC_DSRA:
14533
        case OPC_DSLL32:
14534
        case OPC_DSRA32:
14535
            check_insn(env, ctx, ISA_MIPS3);
14536
            check_mips_64(ctx);
14537
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
14538
            break;
14539
        case OPC_DSRL:
14540
            switch ((ctx->opcode >> 21) & 0x1f) {
14541
            case 1:
14542
                /* drotr is decoded as dsrl on non-R2 CPUs */
14543
                if (env->insn_flags & ISA_MIPS32R2) {
14544
                    op1 = OPC_DROTR;
14545
                }
14546
                /* Fallthrough */
14547
            case 0:
14548
                check_insn(env, ctx, ISA_MIPS3);
14549
                check_mips_64(ctx);
14550
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
14551
                break;
14552
            default:
14553
                generate_exception(ctx, EXCP_RI);
14554
                break;
14555
            }
14556
            break;
14557
        case OPC_DSRL32:
14558
            switch ((ctx->opcode >> 21) & 0x1f) {
14559
            case 1:
14560
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14561
                if (env->insn_flags & ISA_MIPS32R2) {
14562
                    op1 = OPC_DROTR32;
14563
                }
14564
                /* Fallthrough */
14565
            case 0:
14566
                check_insn(env, ctx, ISA_MIPS3);
14567
                check_mips_64(ctx);
14568
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
14569
                break;
14570
            default:
14571
                generate_exception(ctx, EXCP_RI);
14572
                break;
14573
            }
14574
            break;
14575
        case OPC_DADD ... OPC_DSUBU:
14576
            check_insn(env, ctx, ISA_MIPS3);
14577
            check_mips_64(ctx);
14578
            gen_arith(env, ctx, op1, rd, rs, rt);
14579
            break;
14580
        case OPC_DSLLV:
14581
        case OPC_DSRAV:
14582
            check_insn(env, ctx, ISA_MIPS3);
14583
            check_mips_64(ctx);
14584
            gen_shift(env, ctx, op1, rd, rs, rt);
14585
            break;
14586
        case OPC_DSRLV:
14587
            switch ((ctx->opcode >> 6) & 0x1f) {
14588
            case 1:
14589
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
14590
                if (env->insn_flags & ISA_MIPS32R2) {
14591
                    op1 = OPC_DROTRV;
14592
                }
14593
                /* Fallthrough */
14594
            case 0:
14595
                check_insn(env, ctx, ISA_MIPS3);
14596
                check_mips_64(ctx);
14597
                gen_shift(env, ctx, op1, rd, rs, rt);
14598
                break;
14599
            default:
14600
                generate_exception(ctx, EXCP_RI);
14601
                break;
14602
            }
14603
            break;
14604
        case OPC_DMULT ... OPC_DDIVU:
14605
            check_insn(env, ctx, ISA_MIPS3);
14606
            check_mips_64(ctx);
14607
            gen_muldiv(ctx, op1, rs, rt);
14608
            break;
14609
#endif
14610
        default:            /* Invalid */
14611
            MIPS_INVAL("special");
14612
            generate_exception(ctx, EXCP_RI);
14613
            break;
14614
        }
14615
        break;
14616
    case OPC_SPECIAL2:
14617
        op1 = MASK_SPECIAL2(ctx->opcode);
14618
        switch (op1) {
14619
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14620
        case OPC_MSUB ... OPC_MSUBU:
14621
            check_insn(env, ctx, ISA_MIPS32);
14622
            gen_muldiv(ctx, op1, rs, rt);
14623
            break;
14624
        case OPC_MUL:
14625
            gen_arith(env, ctx, op1, rd, rs, rt);
14626
            break;
14627
        case OPC_CLO:
14628
        case OPC_CLZ:
14629
            check_insn(env, ctx, ISA_MIPS32);
14630
            gen_cl(ctx, op1, rd, rs);
14631
            break;
14632
        case OPC_SDBBP:
14633
            /* XXX: not clear which exception should be raised
14634
             *      when in debug mode...
14635
             */
14636
            check_insn(env, ctx, ISA_MIPS32);
14637
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14638
                generate_exception(ctx, EXCP_DBp);
14639
            } else {
14640
                generate_exception(ctx, EXCP_DBp);
14641
            }
14642
            /* Treat as NOP. */
14643
            break;
14644
        case OPC_DIV_G_2F:
14645
        case OPC_DIVU_G_2F:
14646
        case OPC_MULT_G_2F:
14647
        case OPC_MULTU_G_2F:
14648
        case OPC_MOD_G_2F:
14649
        case OPC_MODU_G_2F:
14650
            check_insn(env, ctx, INSN_LOONGSON2F);
14651
            gen_loongson_integer(ctx, op1, rd, rs, rt);
14652
            break;
14653
#if defined(TARGET_MIPS64)
14654
        case OPC_DCLO:
14655
        case OPC_DCLZ:
14656
            check_insn(env, ctx, ISA_MIPS64);
14657
            check_mips_64(ctx);
14658
            gen_cl(ctx, op1, rd, rs);
14659
            break;
14660
        case OPC_DMULT_G_2F:
14661
        case OPC_DMULTU_G_2F:
14662
        case OPC_DDIV_G_2F:
14663
        case OPC_DDIVU_G_2F:
14664
        case OPC_DMOD_G_2F:
14665
        case OPC_DMODU_G_2F:
14666
            check_insn(env, ctx, INSN_LOONGSON2F);
14667
            gen_loongson_integer(ctx, op1, rd, rs, rt);
14668
            break;
14669
#endif
14670
        default:            /* Invalid */
14671
            MIPS_INVAL("special2");
14672
            generate_exception(ctx, EXCP_RI);
14673
            break;
14674
        }
14675
        break;
14676
    case OPC_SPECIAL3:
14677
        op1 = MASK_SPECIAL3(ctx->opcode);
14678
        switch (op1) {
14679
        case OPC_EXT:
14680
        case OPC_INS:
14681
            check_insn(env, ctx, ISA_MIPS32R2);
14682
            gen_bitops(ctx, op1, rt, rs, sa, rd);
14683
            break;
14684
        case OPC_BSHFL:
14685
            check_insn(env, ctx, ISA_MIPS32R2);
14686
            op2 = MASK_BSHFL(ctx->opcode);
14687
            gen_bshfl(ctx, op2, rt, rd);
14688
            break;
14689
        case OPC_RDHWR:
14690
            gen_rdhwr(env, ctx, rt, rd);
14691
            break;
14692
        case OPC_FORK:
14693
            check_insn(env, ctx, ASE_MT);
14694
            {
14695
                TCGv t0 = tcg_temp_new();
14696
                TCGv t1 = tcg_temp_new();
14697

    
14698
                gen_load_gpr(t0, rt);
14699
                gen_load_gpr(t1, rs);
14700
                gen_helper_fork(t0, t1);
14701
                tcg_temp_free(t0);
14702
                tcg_temp_free(t1);
14703
            }
14704
            break;
14705
        case OPC_YIELD:
14706
            check_insn(env, ctx, ASE_MT);
14707
            {
14708
                TCGv t0 = tcg_temp_new();
14709

    
14710
                save_cpu_state(ctx, 1);
14711
                gen_load_gpr(t0, rs);
14712
                gen_helper_yield(t0, cpu_env, t0);
14713
                gen_store_gpr(t0, rd);
14714
                tcg_temp_free(t0);
14715
            }
14716
            break;
14717
        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14718
        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14719
        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14720
        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14721
         * the same mask and op1. */
14722
            if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14723
                op2 = MASK_ADDUH_QB(ctx->opcode);
14724
                switch (op2) {
14725
                case OPC_ADDUH_QB:
14726
                case OPC_ADDUH_R_QB:
14727
                case OPC_ADDQH_PH:
14728
                case OPC_ADDQH_R_PH:
14729
                case OPC_ADDQH_W:
14730
                case OPC_ADDQH_R_W:
14731
                case OPC_SUBUH_QB:
14732
                case OPC_SUBUH_R_QB:
14733
                case OPC_SUBQH_PH:
14734
                case OPC_SUBQH_R_PH:
14735
                case OPC_SUBQH_W:
14736
                case OPC_SUBQH_R_W:
14737
                    gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14738
                    break;
14739
                case OPC_MUL_PH:
14740
                case OPC_MUL_S_PH:
14741
                case OPC_MULQ_S_W:
14742
                case OPC_MULQ_RS_W:
14743
                    gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14744
                    break;
14745
                default:
14746
                    MIPS_INVAL("MASK ADDUH.QB");
14747
                    generate_exception(ctx, EXCP_RI);
14748
                    break;
14749
                }
14750
            } else if (env->insn_flags & INSN_LOONGSON2E) {
14751
                gen_loongson_integer(ctx, op1, rd, rs, rt);
14752
            } else {
14753
                generate_exception(ctx, EXCP_RI);
14754
            }
14755
            break;
14756
        case OPC_LX_DSP:
14757
            op2 = MASK_LX(ctx->opcode);
14758
            switch (op2) {
14759
#if defined(TARGET_MIPS64)
14760
            case OPC_LDX:
14761
#endif
14762
            case OPC_LBUX:
14763
            case OPC_LHX:
14764
            case OPC_LWX:
14765
                gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14766
                break;
14767
            default:            /* Invalid */
14768
                MIPS_INVAL("MASK LX");
14769
                generate_exception(ctx, EXCP_RI);
14770
                break;
14771
            }
14772
            break;
14773
        case OPC_ABSQ_S_PH_DSP:
14774
            op2 = MASK_ABSQ_S_PH(ctx->opcode);
14775
            switch (op2) {
14776
            case OPC_ABSQ_S_QB:
14777
            case OPC_ABSQ_S_PH:
14778
            case OPC_ABSQ_S_W:
14779
            case OPC_PRECEQ_W_PHL:
14780
            case OPC_PRECEQ_W_PHR:
14781
            case OPC_PRECEQU_PH_QBL:
14782
            case OPC_PRECEQU_PH_QBR:
14783
            case OPC_PRECEQU_PH_QBLA:
14784
            case OPC_PRECEQU_PH_QBRA:
14785
            case OPC_PRECEU_PH_QBL:
14786
            case OPC_PRECEU_PH_QBR:
14787
            case OPC_PRECEU_PH_QBLA:
14788
            case OPC_PRECEU_PH_QBRA:
14789
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14790
                break;
14791
            case OPC_BITREV:
14792
            case OPC_REPL_QB:
14793
            case OPC_REPLV_QB:
14794
            case OPC_REPL_PH:
14795
            case OPC_REPLV_PH:
14796
                gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14797
                break;
14798
            default:
14799
                MIPS_INVAL("MASK ABSQ_S.PH");
14800
                generate_exception(ctx, EXCP_RI);
14801
                break;
14802
            }
14803
            break;
14804
        case OPC_ADDU_QB_DSP:
14805
            op2 = MASK_ADDU_QB(ctx->opcode);
14806
            switch (op2) {
14807
            case OPC_ADDQ_PH:
14808
            case OPC_ADDQ_S_PH:
14809
            case OPC_ADDQ_S_W:
14810
            case OPC_ADDU_QB:
14811
            case OPC_ADDU_S_QB:
14812
            case OPC_ADDU_PH:
14813
            case OPC_ADDU_S_PH:
14814
            case OPC_SUBQ_PH:
14815
            case OPC_SUBQ_S_PH:
14816
            case OPC_SUBQ_S_W:
14817
            case OPC_SUBU_QB:
14818
            case OPC_SUBU_S_QB:
14819
            case OPC_SUBU_PH:
14820
            case OPC_SUBU_S_PH:
14821
            case OPC_ADDSC:
14822
            case OPC_ADDWC:
14823
            case OPC_MODSUB:
14824
            case OPC_RADDU_W_QB:
14825
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826
                break;
14827
            case OPC_MULEU_S_PH_QBL:
14828
            case OPC_MULEU_S_PH_QBR:
14829
            case OPC_MULQ_RS_PH:
14830
            case OPC_MULEQ_S_W_PHL:
14831
            case OPC_MULEQ_S_W_PHR:
14832
            case OPC_MULQ_S_PH:
14833
                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14834
                break;
14835
            default:            /* Invalid */
14836
                MIPS_INVAL("MASK ADDU.QB");
14837
                generate_exception(ctx, EXCP_RI);
14838
                break;
14839

    
14840
            }
14841
            break;
14842
        case OPC_CMPU_EQ_QB_DSP:
14843
            op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14844
            switch (op2) {
14845
            case OPC_PRECR_SRA_PH_W:
14846
            case OPC_PRECR_SRA_R_PH_W:
14847
                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14848
                break;
14849
            case OPC_PRECR_QB_PH:
14850
            case OPC_PRECRQ_QB_PH:
14851
            case OPC_PRECRQ_PH_W:
14852
            case OPC_PRECRQ_RS_PH_W:
14853
            case OPC_PRECRQU_S_QB_PH:
14854
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14855
                break;
14856
            case OPC_CMPU_EQ_QB:
14857
            case OPC_CMPU_LT_QB:
14858
            case OPC_CMPU_LE_QB:
14859
            case OPC_CMP_EQ_PH:
14860
            case OPC_CMP_LT_PH:
14861
            case OPC_CMP_LE_PH:
14862
                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14863
                break;
14864
            case OPC_CMPGU_EQ_QB:
14865
            case OPC_CMPGU_LT_QB:
14866
            case OPC_CMPGU_LE_QB:
14867
            case OPC_CMPGDU_EQ_QB:
14868
            case OPC_CMPGDU_LT_QB:
14869
            case OPC_CMPGDU_LE_QB:
14870
            case OPC_PICK_QB:
14871
            case OPC_PICK_PH:
14872
            case OPC_PACKRL_PH:
14873
                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14874
                break;
14875
            default:            /* Invalid */
14876
                MIPS_INVAL("MASK CMPU.EQ.QB");
14877
                generate_exception(ctx, EXCP_RI);
14878
                break;
14879
            }
14880
            break;
14881
        case OPC_SHLL_QB_DSP:
14882
            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14883
            break;
14884
        case OPC_DPA_W_PH_DSP:
14885
            op2 = MASK_DPA_W_PH(ctx->opcode);
14886
            switch (op2) {
14887
            case OPC_DPAU_H_QBL:
14888
            case OPC_DPAU_H_QBR:
14889
            case OPC_DPSU_H_QBL:
14890
            case OPC_DPSU_H_QBR:
14891
            case OPC_DPA_W_PH:
14892
            case OPC_DPAX_W_PH:
14893
            case OPC_DPAQ_S_W_PH:
14894
            case OPC_DPAQX_S_W_PH:
14895
            case OPC_DPAQX_SA_W_PH:
14896
            case OPC_DPS_W_PH:
14897
            case OPC_DPSX_W_PH:
14898
            case OPC_DPSQ_S_W_PH:
14899
            case OPC_DPSQX_S_W_PH:
14900
            case OPC_DPSQX_SA_W_PH:
14901
            case OPC_MULSAQ_S_W_PH:
14902
            case OPC_DPAQ_SA_L_W:
14903
            case OPC_DPSQ_SA_L_W:
14904
            case OPC_MAQ_S_W_PHL:
14905
            case OPC_MAQ_S_W_PHR:
14906
            case OPC_MAQ_SA_W_PHL:
14907
            case OPC_MAQ_SA_W_PHR:
14908
            case OPC_MULSA_W_PH:
14909
                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14910
                break;
14911
            default:            /* Invalid */
14912
                MIPS_INVAL("MASK DPAW.PH");
14913
                generate_exception(ctx, EXCP_RI);
14914
                break;
14915
            }
14916
            break;
14917
        case OPC_INSV_DSP:
14918
            op2 = MASK_INSV(ctx->opcode);
14919
            switch (op2) {
14920
            case OPC_INSV:
14921
                check_dsp(ctx);
14922
                {
14923
                    TCGv t0, t1;
14924

    
14925
                    if (rt == 0) {
14926
                        MIPS_DEBUG("NOP");
14927
                        break;
14928
                    }
14929

    
14930
                    t0 = tcg_temp_new();
14931
                    t1 = tcg_temp_new();
14932

    
14933
                    gen_load_gpr(t0, rt);
14934
                    gen_load_gpr(t1, rs);
14935

    
14936
                    gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14937

    
14938
                    tcg_temp_free(t0);
14939
                    tcg_temp_free(t1);
14940
                    break;
14941
                }
14942
            default:            /* Invalid */
14943
                MIPS_INVAL("MASK INSV");
14944
                generate_exception(ctx, EXCP_RI);
14945
                break;
14946
            }
14947
            break;
14948
        case OPC_APPEND_DSP:
14949
            check_dspr2(ctx);
14950
            op2 = MASK_APPEND(ctx->opcode);
14951
            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14952
            break;
14953
        case OPC_EXTR_W_DSP:
14954
            op2 = MASK_EXTR_W(ctx->opcode);
14955
            switch (op2) {
14956
            case OPC_EXTR_W:
14957
            case OPC_EXTR_R_W:
14958
            case OPC_EXTR_RS_W:
14959
            case OPC_EXTR_S_H:
14960
            case OPC_EXTRV_S_H:
14961
            case OPC_EXTRV_W:
14962
            case OPC_EXTRV_R_W:
14963
            case OPC_EXTRV_RS_W:
14964
            case OPC_EXTP:
14965
            case OPC_EXTPV:
14966
            case OPC_EXTPDP:
14967
            case OPC_EXTPDPV:
14968
                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14969
                break;
14970
            case OPC_RDDSP:
14971
                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14972
                break;
14973
            case OPC_SHILO:
14974
            case OPC_SHILOV:
14975
            case OPC_MTHLIP:
14976
            case OPC_WRDSP:
14977
                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14978
                break;
14979
            default:            /* Invalid */
14980
                MIPS_INVAL("MASK EXTR.W");
14981
                generate_exception(ctx, EXCP_RI);
14982
                break;
14983
            }
14984
            break;
14985
#if defined(TARGET_MIPS64)
14986
        case OPC_DEXTM ... OPC_DEXT:
14987
        case OPC_DINSM ... OPC_DINS:
14988
            check_insn(env, ctx, ISA_MIPS64R2);
14989
            check_mips_64(ctx);
14990
            gen_bitops(ctx, op1, rt, rs, sa, rd);
14991
            break;
14992
        case OPC_DBSHFL:
14993
            check_insn(env, ctx, ISA_MIPS64R2);
14994
            check_mips_64(ctx);
14995
            op2 = MASK_DBSHFL(ctx->opcode);
14996
            gen_bshfl(ctx, op2, rt, rd);
14997
            break;
14998
        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14999
        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15000
        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15001
            check_insn(env, ctx, INSN_LOONGSON2E);
15002
            gen_loongson_integer(ctx, op1, rd, rs, rt);
15003
            break;
15004
        case OPC_ABSQ_S_QH_DSP:
15005
            op2 = MASK_ABSQ_S_QH(ctx->opcode);
15006
            switch (op2) {
15007
            case OPC_PRECEQ_L_PWL:
15008
            case OPC_PRECEQ_L_PWR:
15009
            case OPC_PRECEQ_PW_QHL:
15010
            case OPC_PRECEQ_PW_QHR:
15011
            case OPC_PRECEQ_PW_QHLA:
15012
            case OPC_PRECEQ_PW_QHRA:
15013
            case OPC_PRECEQU_QH_OBL:
15014
            case OPC_PRECEQU_QH_OBR:
15015
            case OPC_PRECEQU_QH_OBLA:
15016
            case OPC_PRECEQU_QH_OBRA:
15017
            case OPC_PRECEU_QH_OBL:
15018
            case OPC_PRECEU_QH_OBR:
15019
            case OPC_PRECEU_QH_OBLA:
15020
            case OPC_PRECEU_QH_OBRA:
15021
            case OPC_ABSQ_S_OB:
15022
            case OPC_ABSQ_S_PW:
15023
            case OPC_ABSQ_S_QH:
15024
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15025
                break;
15026
            case OPC_REPL_OB:
15027
            case OPC_REPL_PW:
15028
            case OPC_REPL_QH:
15029
            case OPC_REPLV_OB:
15030
            case OPC_REPLV_PW:
15031
            case OPC_REPLV_QH:
15032
                gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15033
                break;
15034
            default:            /* Invalid */
15035
                MIPS_INVAL("MASK ABSQ_S.QH");
15036
                generate_exception(ctx, EXCP_RI);
15037
                break;
15038
            }
15039
            break;
15040
        case OPC_ADDU_OB_DSP:
15041
            op2 = MASK_ADDU_OB(ctx->opcode);
15042
            switch (op2) {
15043
            case OPC_RADDU_L_OB:
15044
            case OPC_SUBQ_PW:
15045
            case OPC_SUBQ_S_PW:
15046
            case OPC_SUBQ_QH:
15047
            case OPC_SUBQ_S_QH:
15048
            case OPC_SUBU_OB:
15049
            case OPC_SUBU_S_OB:
15050
            case OPC_SUBU_QH:
15051
            case OPC_SUBU_S_QH:
15052
            case OPC_SUBUH_OB:
15053
            case OPC_SUBUH_R_OB:
15054
            case OPC_ADDQ_PW:
15055
            case OPC_ADDQ_S_PW:
15056
            case OPC_ADDQ_QH:
15057
            case OPC_ADDQ_S_QH:
15058
            case OPC_ADDU_OB:
15059
            case OPC_ADDU_S_OB:
15060
            case OPC_ADDU_QH:
15061
            case OPC_ADDU_S_QH:
15062
            case OPC_ADDUH_OB:
15063
            case OPC_ADDUH_R_OB:
15064
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15065
                break;
15066
            case OPC_MULEQ_S_PW_QHL:
15067
            case OPC_MULEQ_S_PW_QHR:
15068
            case OPC_MULEU_S_QH_OBL:
15069
            case OPC_MULEU_S_QH_OBR:
15070
            case OPC_MULQ_RS_QH:
15071
                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15072
                break;
15073
            default:            /* Invalid */
15074
                MIPS_INVAL("MASK ADDU.OB");
15075
                generate_exception(ctx, EXCP_RI);
15076
                break;
15077
            }
15078
            break;
15079
        case OPC_CMPU_EQ_OB_DSP:
15080
            op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15081
            switch (op2) {
15082
            case OPC_PRECR_SRA_QH_PW:
15083
            case OPC_PRECR_SRA_R_QH_PW:
15084
                /* Return value is rt. */
15085
                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15086
                break;
15087
            case OPC_PRECR_OB_QH:
15088
            case OPC_PRECRQ_OB_QH:
15089
            case OPC_PRECRQ_PW_L:
15090
            case OPC_PRECRQ_QH_PW:
15091
            case OPC_PRECRQ_RS_QH_PW:
15092
            case OPC_PRECRQU_S_OB_QH:
15093
                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15094
                break;
15095
            case OPC_CMPU_EQ_OB:
15096
            case OPC_CMPU_LT_OB:
15097
            case OPC_CMPU_LE_OB:
15098
            case OPC_CMP_EQ_QH:
15099
            case OPC_CMP_LT_QH:
15100
            case OPC_CMP_LE_QH:
15101
            case OPC_CMP_EQ_PW:
15102
            case OPC_CMP_LT_PW:
15103
            case OPC_CMP_LE_PW:
15104
                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15105
                break;
15106
            case OPC_CMPGDU_EQ_OB:
15107
            case OPC_CMPGDU_LT_OB:
15108
            case OPC_CMPGDU_LE_OB:
15109
            case OPC_CMPGU_EQ_OB:
15110
            case OPC_CMPGU_LT_OB:
15111
            case OPC_CMPGU_LE_OB:
15112
            case OPC_PACKRL_PW:
15113
            case OPC_PICK_OB:
15114
            case OPC_PICK_PW:
15115
            case OPC_PICK_QH:
15116
                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15117
                break;
15118
            default:            /* Invalid */
15119
                MIPS_INVAL("MASK CMPU_EQ.OB");
15120
                generate_exception(ctx, EXCP_RI);
15121
                break;
15122
            }
15123
            break;
15124
        case OPC_DAPPEND_DSP:
15125
            check_dspr2(ctx);
15126
            op2 = MASK_DAPPEND(ctx->opcode);
15127
            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15128
            break;
15129
        case OPC_DEXTR_W_DSP:
15130
            op2 = MASK_DEXTR_W(ctx->opcode);
15131
            switch (op2) {
15132
            case OPC_DEXTP:
15133
            case OPC_DEXTPDP:
15134
            case OPC_DEXTPDPV:
15135
            case OPC_DEXTPV:
15136
            case OPC_DEXTR_L:
15137
            case OPC_DEXTR_R_L:
15138
            case OPC_DEXTR_RS_L:
15139
            case OPC_DEXTR_W:
15140
            case OPC_DEXTR_R_W:
15141
            case OPC_DEXTR_RS_W:
15142
            case OPC_DEXTR_S_H:
15143
            case OPC_DEXTRV_L:
15144
            case OPC_DEXTRV_R_L:
15145
            case OPC_DEXTRV_RS_L:
15146
            case OPC_DEXTRV_S_H:
15147
            case OPC_DEXTRV_W:
15148
            case OPC_DEXTRV_R_W:
15149
            case OPC_DEXTRV_RS_W:
15150
                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15151
                break;
15152
            case OPC_DMTHLIP:
15153
            case OPC_DSHILO:
15154
            case OPC_DSHILOV:
15155
                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15156
                break;
15157
            default:            /* Invalid */
15158
                MIPS_INVAL("MASK EXTR.W");
15159
                generate_exception(ctx, EXCP_RI);
15160
                break;
15161
            }
15162
            break;
15163
        case OPC_DPAQ_W_QH_DSP:
15164
            op2 = MASK_DPAQ_W_QH(ctx->opcode);
15165
            switch (op2) {
15166
            case OPC_DPAU_H_OBL:
15167
            case OPC_DPAU_H_OBR:
15168
            case OPC_DPSU_H_OBL:
15169
            case OPC_DPSU_H_OBR:
15170
            case OPC_DPA_W_QH:
15171
            case OPC_DPAQ_S_W_QH:
15172
            case OPC_DPS_W_QH:
15173
            case OPC_DPSQ_S_W_QH:
15174
            case OPC_MULSAQ_S_W_QH:
15175
            case OPC_DPAQ_SA_L_PW:
15176
            case OPC_DPSQ_SA_L_PW:
15177
            case OPC_MULSAQ_S_L_PW:
15178
                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15179
                break;
15180
            case OPC_MAQ_S_W_QHLL:
15181
            case OPC_MAQ_S_W_QHLR:
15182
            case OPC_MAQ_S_W_QHRL:
15183
            case OPC_MAQ_S_W_QHRR:
15184
            case OPC_MAQ_SA_W_QHLL:
15185
            case OPC_MAQ_SA_W_QHLR:
15186
            case OPC_MAQ_SA_W_QHRL:
15187
            case OPC_MAQ_SA_W_QHRR:
15188
            case OPC_MAQ_S_L_PWL:
15189
            case OPC_MAQ_S_L_PWR:
15190
            case OPC_DMADD:
15191
            case OPC_DMADDU:
15192
            case OPC_DMSUB:
15193
            case OPC_DMSUBU:
15194
                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15195
                break;
15196
            default:            /* Invalid */
15197
                MIPS_INVAL("MASK DPAQ.W.QH");
15198
                generate_exception(ctx, EXCP_RI);
15199
                break;
15200
            }
15201
            break;
15202
        case OPC_DINSV_DSP:
15203
            op2 = MASK_INSV(ctx->opcode);
15204
            switch (op2) {
15205
            case OPC_DINSV:
15206
                {
15207
                    TCGv t0, t1;
15208

    
15209
                    if (rt == 0) {
15210
                        MIPS_DEBUG("NOP");
15211
                        break;
15212
                    }
15213
                    check_dsp(ctx);
15214

    
15215
                    t0 = tcg_temp_new();
15216
                    t1 = tcg_temp_new();
15217

    
15218
                    gen_load_gpr(t0, rt);
15219
                    gen_load_gpr(t1, rs);
15220

    
15221
                    gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15222
                    break;
15223
                }
15224
            default:            /* Invalid */
15225
                MIPS_INVAL("MASK DINSV");
15226
                generate_exception(ctx, EXCP_RI);
15227
                break;
15228
            }
15229
            break;
15230
        case OPC_SHLL_OB_DSP:
15231
            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15232
            break;
15233
#endif
15234
        default:            /* Invalid */
15235
            MIPS_INVAL("special3");
15236
            generate_exception(ctx, EXCP_RI);
15237
            break;
15238
        }
15239
        break;
15240
    case OPC_REGIMM:
15241
        op1 = MASK_REGIMM(ctx->opcode);
15242
        switch (op1) {
15243
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15244
        case OPC_BLTZAL ... OPC_BGEZALL:
15245
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15246
            *is_branch = 1;
15247
            break;
15248
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15249
        case OPC_TNEI:
15250
            gen_trap(ctx, op1, rs, -1, imm);
15251
            break;
15252
        case OPC_SYNCI:
15253
            check_insn(env, ctx, ISA_MIPS32R2);
15254
            /* Treat as NOP. */
15255
            break;
15256
        case OPC_BPOSGE32:    /* MIPS DSP branch */
15257
#if defined(TARGET_MIPS64)
15258
        case OPC_BPOSGE64:
15259
#endif
15260
            check_dsp(ctx);
15261
            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15262
            *is_branch = 1;
15263
            break;
15264
        default:            /* Invalid */
15265
            MIPS_INVAL("regimm");
15266
            generate_exception(ctx, EXCP_RI);
15267
            break;
15268
        }
15269
        break;
15270
    case OPC_CP0:
15271
        check_cp0_enabled(ctx);
15272
        op1 = MASK_CP0(ctx->opcode);
15273
        switch (op1) {
15274
        case OPC_MFC0:
15275
        case OPC_MTC0:
15276
        case OPC_MFTR:
15277
        case OPC_MTTR:
15278
#if defined(TARGET_MIPS64)
15279
        case OPC_DMFC0:
15280
        case OPC_DMTC0:
15281
#endif
15282
#ifndef CONFIG_USER_ONLY
15283
            gen_cp0(env, ctx, op1, rt, rd);
15284
#endif /* !CONFIG_USER_ONLY */
15285
            break;
15286
        case OPC_C0_FIRST ... OPC_C0_LAST:
15287
#ifndef CONFIG_USER_ONLY
15288
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15289
#endif /* !CONFIG_USER_ONLY */
15290
            break;
15291
        case OPC_MFMC0:
15292
#ifndef CONFIG_USER_ONLY
15293
            {
15294
                TCGv t0 = tcg_temp_new();
15295

    
15296
                op2 = MASK_MFMC0(ctx->opcode);
15297
                switch (op2) {
15298
                case OPC_DMT:
15299
                    check_insn(env, ctx, ASE_MT);
15300
                    gen_helper_dmt(t0);
15301
                    gen_store_gpr(t0, rt);
15302
                    break;
15303
                case OPC_EMT:
15304
                    check_insn(env, ctx, ASE_MT);
15305
                    gen_helper_emt(t0);
15306
                    gen_store_gpr(t0, rt);
15307
                    break;
15308
                case OPC_DVPE:
15309
                    check_insn(env, ctx, ASE_MT);
15310
                    gen_helper_dvpe(t0, cpu_env);
15311
                    gen_store_gpr(t0, rt);
15312
                    break;
15313
                case OPC_EVPE:
15314
                    check_insn(env, ctx, ASE_MT);
15315
                    gen_helper_evpe(t0, cpu_env);
15316
                    gen_store_gpr(t0, rt);
15317
                    break;
15318
                case OPC_DI:
15319
                    check_insn(env, ctx, ISA_MIPS32R2);
15320
                    save_cpu_state(ctx, 1);
15321
                    gen_helper_di(t0, cpu_env);
15322
                    gen_store_gpr(t0, rt);
15323
                    /* Stop translation as we may have switched the execution mode */
15324
                    ctx->bstate = BS_STOP;
15325
                    break;
15326
                case OPC_EI:
15327
                    check_insn(env, ctx, ISA_MIPS32R2);
15328
                    save_cpu_state(ctx, 1);
15329
                    gen_helper_ei(t0, cpu_env);
15330
                    gen_store_gpr(t0, rt);
15331
                    /* Stop translation as we may have switched the execution mode */
15332
                    ctx->bstate = BS_STOP;
15333
                    break;
15334
                default:            /* Invalid */
15335
                    MIPS_INVAL("mfmc0");
15336
                    generate_exception(ctx, EXCP_RI);
15337
                    break;
15338
                }
15339
                tcg_temp_free(t0);
15340
            }
15341
#endif /* !CONFIG_USER_ONLY */
15342
            break;
15343
        case OPC_RDPGPR:
15344
            check_insn(env, ctx, ISA_MIPS32R2);
15345
            gen_load_srsgpr(rt, rd);
15346
            break;
15347
        case OPC_WRPGPR:
15348
            check_insn(env, ctx, ISA_MIPS32R2);
15349
            gen_store_srsgpr(rt, rd);
15350
            break;
15351
        default:
15352
            MIPS_INVAL("cp0");
15353
            generate_exception(ctx, EXCP_RI);
15354
            break;
15355
        }
15356
        break;
15357
    case OPC_ADDI: /* Arithmetic with immediate opcode */
15358
    case OPC_ADDIU:
15359
         gen_arith_imm(env, ctx, op, rt, rs, imm);
15360
         break;
15361
    case OPC_SLTI: /* Set on less than with immediate opcode */
15362
    case OPC_SLTIU:
15363
         gen_slt_imm(env, ctx, op, rt, rs, imm);
15364
         break;
15365
    case OPC_ANDI: /* Arithmetic with immediate opcode */
15366
    case OPC_LUI:
15367
    case OPC_ORI:
15368
    case OPC_XORI:
15369
         gen_logic_imm(env, ctx, op, rt, rs, imm);
15370
         break;
15371
    case OPC_J ... OPC_JAL: /* Jump */
15372
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15373
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
15374
         *is_branch = 1;
15375
         break;
15376
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
15377
    case OPC_BEQL ... OPC_BGTZL:
15378
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15379
         *is_branch = 1;
15380
         break;
15381
    case OPC_LB ... OPC_LWR: /* Load and stores */
15382
    case OPC_LL:
15383
         gen_ld(env, ctx, op, rt, rs, imm);
15384
         break;
15385
    case OPC_SB ... OPC_SW:
15386
    case OPC_SWR:
15387
         gen_st(ctx, op, rt, rs, imm);
15388
         break;
15389
    case OPC_SC:
15390
         gen_st_cond(ctx, op, rt, rs, imm);
15391
         break;
15392
    case OPC_CACHE:
15393
        check_cp0_enabled(ctx);
15394
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15395
        /* Treat as NOP. */
15396
        break;
15397
    case OPC_PREF:
15398
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15399
        /* Treat as NOP. */
15400
        break;
15401

    
15402
    /* Floating point (COP1). */
15403
    case OPC_LWC1:
15404
    case OPC_LDC1:
15405
    case OPC_SWC1:
15406
    case OPC_SDC1:
15407
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15408
        break;
15409

    
15410
    case OPC_CP1:
15411
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15412
            check_cp1_enabled(ctx);
15413
            op1 = MASK_CP1(ctx->opcode);
15414
            switch (op1) {
15415
            case OPC_MFHC1:
15416
            case OPC_MTHC1:
15417
                check_insn(env, ctx, ISA_MIPS32R2);
15418
            case OPC_MFC1:
15419
            case OPC_CFC1:
15420
            case OPC_MTC1:
15421
            case OPC_CTC1:
15422
                gen_cp1(ctx, op1, rt, rd);
15423
                break;
15424
#if defined(TARGET_MIPS64)
15425
            case OPC_DMFC1:
15426
            case OPC_DMTC1:
15427
                check_insn(env, ctx, ISA_MIPS3);
15428
                gen_cp1(ctx, op1, rt, rd);
15429
                break;
15430
#endif
15431
            case OPC_BC1ANY2:
15432
            case OPC_BC1ANY4:
15433
                check_cop1x(ctx);
15434
                check_insn(env, ctx, ASE_MIPS3D);
15435
                /* fall through */
15436
            case OPC_BC1:
15437
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15438
                                    (rt >> 2) & 0x7, imm << 2);
15439
                *is_branch = 1;
15440
                break;
15441
            case OPC_S_FMT:
15442
            case OPC_D_FMT:
15443
            case OPC_W_FMT:
15444
            case OPC_L_FMT:
15445
            case OPC_PS_FMT:
15446
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15447
                           (imm >> 8) & 0x7);
15448
                break;
15449
            default:
15450
                MIPS_INVAL("cp1");
15451
                generate_exception (ctx, EXCP_RI);
15452
                break;
15453
            }
15454
        } else {
15455
            generate_exception_err(ctx, EXCP_CpU, 1);
15456
        }
15457
        break;
15458

    
15459
    /* COP2.  */
15460
    case OPC_LWC2:
15461
    case OPC_LDC2:
15462
    case OPC_SWC2:
15463
    case OPC_SDC2:
15464
        /* COP2: Not implemented. */
15465
        generate_exception_err(ctx, EXCP_CpU, 2);
15466
        break;
15467
    case OPC_CP2:
15468
        check_insn(env, ctx, INSN_LOONGSON2F);
15469
        /* Note that these instructions use different fields.  */
15470
        gen_loongson_multimedia(ctx, sa, rd, rt);
15471
        break;
15472

    
15473
    case OPC_CP3:
15474
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15475
            check_cp1_enabled(ctx);
15476
            op1 = MASK_CP3(ctx->opcode);
15477
            switch (op1) {
15478
            case OPC_LWXC1:
15479
            case OPC_LDXC1:
15480
            case OPC_LUXC1:
15481
            case OPC_SWXC1:
15482
            case OPC_SDXC1:
15483
            case OPC_SUXC1:
15484
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15485
                break;
15486
            case OPC_PREFX:
15487
                /* Treat as NOP. */
15488
                break;
15489
            case OPC_ALNV_PS:
15490
            case OPC_MADD_S:
15491
            case OPC_MADD_D:
15492
            case OPC_MADD_PS:
15493
            case OPC_MSUB_S:
15494
            case OPC_MSUB_D:
15495
            case OPC_MSUB_PS:
15496
            case OPC_NMADD_S:
15497
            case OPC_NMADD_D:
15498
            case OPC_NMADD_PS:
15499
            case OPC_NMSUB_S:
15500
            case OPC_NMSUB_D:
15501
            case OPC_NMSUB_PS:
15502
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15503
                break;
15504
            default:
15505
                MIPS_INVAL("cp3");
15506
                generate_exception (ctx, EXCP_RI);
15507
                break;
15508
            }
15509
        } else {
15510
            generate_exception_err(ctx, EXCP_CpU, 1);
15511
        }
15512
        break;
15513

    
15514
#if defined(TARGET_MIPS64)
15515
    /* MIPS64 opcodes */
15516
    case OPC_LWU:
15517
    case OPC_LDL ... OPC_LDR:
15518
    case OPC_LLD:
15519
    case OPC_LD:
15520
        check_insn(env, ctx, ISA_MIPS3);
15521
        check_mips_64(ctx);
15522
        gen_ld(env, ctx, op, rt, rs, imm);
15523
        break;
15524
    case OPC_SDL ... OPC_SDR:
15525
    case OPC_SD:
15526
        check_insn(env, ctx, ISA_MIPS3);
15527
        check_mips_64(ctx);
15528
        gen_st(ctx, op, rt, rs, imm);
15529
        break;
15530
    case OPC_SCD:
15531
        check_insn(env, ctx, ISA_MIPS3);
15532
        check_mips_64(ctx);
15533
        gen_st_cond(ctx, op, rt, rs, imm);
15534
        break;
15535
    case OPC_DADDI:
15536
    case OPC_DADDIU:
15537
        check_insn(env, ctx, ISA_MIPS3);
15538
        check_mips_64(ctx);
15539
        gen_arith_imm(env, ctx, op, rt, rs, imm);
15540
        break;
15541
#endif
15542
    case OPC_JALX:
15543
        check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15544
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15545
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
15546
        *is_branch = 1;
15547
        break;
15548
    case OPC_MDMX:
15549
        check_insn(env, ctx, ASE_MDMX);
15550
        /* MDMX: Not implemented. */
15551
    default:            /* Invalid */
15552
        MIPS_INVAL("major opcode");
15553
        generate_exception(ctx, EXCP_RI);
15554
        break;
15555
    }
15556
}
15557

    
15558
static inline void
15559
gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15560
                                int search_pc)
15561
{
15562
    DisasContext ctx;
15563
    target_ulong pc_start;
15564
    uint16_t *gen_opc_end;
15565
    CPUBreakpoint *bp;
15566
    int j, lj = -1;
15567
    int num_insns;
15568
    int max_insns;
15569
    int insn_bytes;
15570
    int is_branch;
15571

    
15572
    if (search_pc)
15573
        qemu_log("search pc %d\n", search_pc);
15574

    
15575
    pc_start = tb->pc;
15576
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15577
    ctx.pc = pc_start;
15578
    ctx.saved_pc = -1;
15579
    ctx.singlestep_enabled = env->singlestep_enabled;
15580
    ctx.tb = tb;
15581
    ctx.bstate = BS_NONE;
15582
    /* Restore delay slot state from the tb context.  */
15583
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15584
    restore_cpu_state(env, &ctx);
15585
#ifdef CONFIG_USER_ONLY
15586
        ctx.mem_idx = MIPS_HFLAG_UM;
15587
#else
15588
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15589
#endif
15590
    num_insns = 0;
15591
    max_insns = tb->cflags & CF_COUNT_MASK;
15592
    if (max_insns == 0)
15593
        max_insns = CF_COUNT_MASK;
15594
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15595
    gen_icount_start();
15596
    while (ctx.bstate == BS_NONE) {
15597
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15598
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15599
                if (bp->pc == ctx.pc) {
15600
                    save_cpu_state(&ctx, 1);
15601
                    ctx.bstate = BS_BRANCH;
15602
                    gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15603
                    /* Include the breakpoint location or the tb won't
15604
                     * be flushed when it must be.  */
15605
                    ctx.pc += 4;
15606
                    goto done_generating;
15607
                }
15608
            }
15609
        }
15610

    
15611
        if (search_pc) {
15612
            j = gen_opc_ptr - gen_opc_buf;
15613
            if (lj < j) {
15614
                lj++;
15615
                while (lj < j)
15616
                    gen_opc_instr_start[lj++] = 0;
15617
            }
15618
            gen_opc_pc[lj] = ctx.pc;
15619
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15620
            gen_opc_instr_start[lj] = 1;
15621
            gen_opc_icount[lj] = num_insns;
15622
        }
15623
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15624
            gen_io_start();
15625

    
15626
        is_branch = 0;
15627
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15628
            ctx.opcode = cpu_ldl_code(env, ctx.pc);
15629
            insn_bytes = 4;
15630
            decode_opc(env, &ctx, &is_branch);
15631
        } else if (env->insn_flags & ASE_MICROMIPS) {
15632
            ctx.opcode = cpu_lduw_code(env, ctx.pc);
15633
            insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15634
        } else if (env->insn_flags & ASE_MIPS16) {
15635
            ctx.opcode = cpu_lduw_code(env, ctx.pc);
15636
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15637
        } else {
15638
            generate_exception(&ctx, EXCP_RI);
15639
            ctx.bstate = BS_STOP;
15640
            break;
15641
        }
15642
        if (!is_branch) {
15643
            handle_delay_slot(env, &ctx, insn_bytes);
15644
        }
15645
        ctx.pc += insn_bytes;
15646

    
15647
        num_insns++;
15648

    
15649
        /* Execute a branch and its delay slot as a single instruction.
15650
           This is what GDB expects and is consistent with what the
15651
           hardware does (e.g. if a delay slot instruction faults, the
15652
           reported PC is the PC of the branch).  */
15653
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15654
            break;
15655

    
15656
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15657
            break;
15658

    
15659
        if (gen_opc_ptr >= gen_opc_end)
15660
            break;
15661

    
15662
        if (num_insns >= max_insns)
15663
            break;
15664

    
15665
        if (singlestep)
15666
            break;
15667
    }
15668
    if (tb->cflags & CF_LAST_IO)
15669
        gen_io_end();
15670
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15671
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15672
        gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15673
    } else {
15674
        switch (ctx.bstate) {
15675
        case BS_STOP:
15676
            gen_goto_tb(&ctx, 0, ctx.pc);
15677
            break;
15678
        case BS_NONE:
15679
            save_cpu_state(&ctx, 0);
15680
            gen_goto_tb(&ctx, 0, ctx.pc);
15681
            break;
15682
        case BS_EXCP:
15683
            tcg_gen_exit_tb(0);
15684
            break;
15685
        case BS_BRANCH:
15686
        default:
15687
            break;
15688
        }
15689
    }
15690
done_generating:
15691
    gen_icount_end(tb, num_insns);
15692
    *gen_opc_ptr = INDEX_op_end;
15693
    if (search_pc) {
15694
        j = gen_opc_ptr - gen_opc_buf;
15695
        lj++;
15696
        while (lj <= j)
15697
            gen_opc_instr_start[lj++] = 0;
15698
    } else {
15699
        tb->size = ctx.pc - pc_start;
15700
        tb->icount = num_insns;
15701
    }
15702
#ifdef DEBUG_DISAS
15703
    LOG_DISAS("\n");
15704
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15705
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
15706
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
15707
        qemu_log("\n");
15708
    }
15709
#endif
15710
}
15711

    
15712
void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15713
{
15714
    gen_intermediate_code_internal(env, tb, 0);
15715
}
15716

    
15717
void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15718
{
15719
    gen_intermediate_code_internal(env, tb, 1);
15720
}
15721

    
15722
static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15723
                           int flags)
15724
{
15725
    int i;
15726
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15727

    
15728
#define printfpr(fp)                                                    \
15729
    do {                                                                \
15730
        if (is_fpu64)                                                   \
15731
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
15732
                        " fd:%13g fs:%13g psu: %13g\n",                 \
15733
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
15734
                        (double)(fp)->fd,                               \
15735
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
15736
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
15737
        else {                                                          \
15738
            fpr_t tmp;                                                  \
15739
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
15740
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
15741
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
15742
                        " fd:%13g fs:%13g psu:%13g\n",                  \
15743
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
15744
                        (double)tmp.fd,                                 \
15745
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
15746
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
15747
        }                                                               \
15748
    } while(0)
15749

    
15750

    
15751
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
15752
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15753
                get_float_exception_flags(&env->active_fpu.fp_status));
15754
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15755
        fpu_fprintf(f, "%3s: ", fregnames[i]);
15756
        printfpr(&env->active_fpu.fpr[i]);
15757
    }
15758

    
15759
#undef printfpr
15760
}
15761

    
15762
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15763
/* Debug help: The architecture requires 32bit code to maintain proper
15764
   sign-extended values on 64bit machines.  */
15765

    
15766
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15767

    
15768
static void
15769
cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15770
                                fprintf_function cpu_fprintf,
15771
                                int flags)
15772
{
15773
    int i;
15774

    
15775
    if (!SIGN_EXT_P(env->active_tc.PC))
15776
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15777
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
15778
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15779
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
15780
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15781
    if (!SIGN_EXT_P(env->btarget))
15782
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15783

    
15784
    for (i = 0; i < 32; i++) {
15785
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15786
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15787
    }
15788

    
15789
    if (!SIGN_EXT_P(env->CP0_EPC))
15790
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15791
    if (!SIGN_EXT_P(env->lladdr))
15792
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15793
}
15794
#endif
15795

    
15796
void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15797
                     int flags)
15798
{
15799
    int i;
15800

    
15801
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15802
                " LO=0x" TARGET_FMT_lx " ds %04x "
15803
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15804
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15805
                env->hflags, env->btarget, env->bcond);
15806
    for (i = 0; i < 32; i++) {
15807
        if ((i & 3) == 0)
15808
            cpu_fprintf(f, "GPR%02d:", i);
15809
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15810
        if ((i & 3) == 3)
15811
            cpu_fprintf(f, "\n");
15812
    }
15813

    
15814
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
15815
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15816
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15817
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
15818
    if (env->hflags & MIPS_HFLAG_FPU)
15819
        fpu_dump_state(env, f, cpu_fprintf, flags);
15820
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15821
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15822
#endif
15823
}
15824

    
15825
static void mips_tcg_init(void)
15826
{
15827
    int i;
15828
    static int inited;
15829

    
15830
    /* Initialize various static tables. */
15831
    if (inited)
15832
        return;
15833

    
15834
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15835
    TCGV_UNUSED(cpu_gpr[0]);
15836
    for (i = 1; i < 32; i++)
15837
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15838
                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
15839
                                        regnames[i]);
15840

    
15841
    for (i = 0; i < 32; i++) {
15842
        int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15843
        fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15844
    }
15845

    
15846
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
15847
                                offsetof(CPUMIPSState, active_tc.PC), "PC");
15848
    for (i = 0; i < MIPS_DSP_ACC; i++) {
15849
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15850
                                       offsetof(CPUMIPSState, active_tc.HI[i]),
15851
                                       regnames_HI[i]);
15852
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15853
                                       offsetof(CPUMIPSState, active_tc.LO[i]),
15854
                                       regnames_LO[i]);
15855
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15856
                                        offsetof(CPUMIPSState, active_tc.ACX[i]),
15857
                                        regnames_ACX[i]);
15858
    }
15859
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15860
                                     offsetof(CPUMIPSState, active_tc.DSPControl),
15861
                                     "DSPControl");
15862
    bcond = tcg_global_mem_new(TCG_AREG0,
15863
                               offsetof(CPUMIPSState, bcond), "bcond");
15864
    btarget = tcg_global_mem_new(TCG_AREG0,
15865
                                 offsetof(CPUMIPSState, btarget), "btarget");
15866
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
15867
                                    offsetof(CPUMIPSState, hflags), "hflags");
15868

    
15869
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15870
                                      offsetof(CPUMIPSState, active_fpu.fcr0),
15871
                                      "fcr0");
15872
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15873
                                       offsetof(CPUMIPSState, active_fpu.fcr31),
15874
                                       "fcr31");
15875

    
15876
    /* register helpers */
15877
#define GEN_HELPER 2
15878
#include "helper.h"
15879

    
15880
    inited = 1;
15881
}
15882

    
15883
#include "translate_init.c"
15884

    
15885
MIPSCPU *cpu_mips_init(const char *cpu_model)
15886
{
15887
    MIPSCPU *cpu;
15888
    CPUMIPSState *env;
15889
    const mips_def_t *def;
15890

    
15891
    def = cpu_mips_find_by_name(cpu_model);
15892
    if (!def)
15893
        return NULL;
15894
    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15895
    env = &cpu->env;
15896
    env->cpu_model = def;
15897
    env->cpu_model_str = cpu_model;
15898

    
15899
#ifndef CONFIG_USER_ONLY
15900
    mmu_init(env, def);
15901
#endif
15902
    fpu_init(env, def);
15903
    mvp_init(env, def);
15904
    mips_tcg_init();
15905
    cpu_reset(CPU(cpu));
15906
    qemu_init_vcpu(env);
15907
    return cpu;
15908
}
15909

    
15910
void cpu_state_reset(CPUMIPSState *env)
15911
{
15912
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15913
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15914
        log_cpu_state(env, 0);
15915
    }
15916

    
15917
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15918
    tlb_flush(env, 1);
15919

    
15920
    /* Reset registers to their default values */
15921
    env->CP0_PRid = env->cpu_model->CP0_PRid;
15922
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
15923
#ifdef TARGET_WORDS_BIGENDIAN
15924
    env->CP0_Config0 |= (1 << CP0C0_BE);
15925
#endif
15926
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
15927
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
15928
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
15929
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
15930
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
15931
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15932
                                 << env->cpu_model->CP0_LLAddr_shift;
15933
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15934
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15935
    env->CCRes = env->cpu_model->CCRes;
15936
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15937
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15938
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15939
    env->current_tc = 0;
15940
    env->SEGBITS = env->cpu_model->SEGBITS;
15941
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15942
#if defined(TARGET_MIPS64)
15943
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
15944
        env->SEGMask |= 3ULL << 62;
15945
    }
15946
#endif
15947
    env->PABITS = env->cpu_model->PABITS;
15948
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15949
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15950
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15951
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15952
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15953
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15954
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15955
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15956
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15957
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15958
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15959
    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15960
    env->insn_flags = env->cpu_model->insn_flags;
15961

    
15962
#if defined(CONFIG_USER_ONLY)
15963
    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15964
    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15965
       hardware registers.  */
15966
    env->CP0_HWREna |= 0x0000000F;
15967
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15968
        env->CP0_Status |= (1 << CP0St_CU1);
15969
    }
15970
    if (env->cpu_model->insn_flags & ASE_DSPR2) {
15971
        env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15972
    } else if (env->cpu_model->insn_flags & ASE_DSP) {
15973
        env->hflags |= MIPS_HFLAG_DSP;
15974
    }
15975
#else
15976
    if (env->hflags & MIPS_HFLAG_BMASK) {
15977
        /* If the exception was raised from a delay slot,
15978
           come back to the jump.  */
15979
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
15980
    } else {
15981
        env->CP0_ErrorEPC = env->active_tc.PC;
15982
    }
15983
    env->active_tc.PC = (int32_t)0xBFC00000;
15984
    env->CP0_Random = env->tlb->nb_tlb - 1;
15985
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
15986
    env->CP0_Wired = 0;
15987
    env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15988
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15989
    /* vectored interrupts not implemented, timer on int 7,
15990
       no performance counters. */
15991
    env->CP0_IntCtl = 0xe0000000;
15992
    {
15993
        int i;
15994

    
15995
        for (i = 0; i < 7; i++) {
15996
            env->CP0_WatchLo[i] = 0;
15997
            env->CP0_WatchHi[i] = 0x80000000;
15998
        }
15999
        env->CP0_WatchLo[7] = 0;
16000
        env->CP0_WatchHi[7] = 0;
16001
    }
16002
    /* Count register increments in debug mode, EJTAG version 1 */
16003
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16004

    
16005
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16006
        int i;
16007

    
16008
        /* Only TC0 on VPE 0 starts as active.  */
16009
        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16010
            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
16011
            env->tcs[i].CP0_TCHalt = 1;
16012
        }
16013
        env->active_tc.CP0_TCHalt = 1;
16014
        env->halted = 1;
16015

    
16016
        if (!env->cpu_index) {
16017
            /* VPE0 starts up enabled.  */
16018
            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16019
            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16020

    
16021
            /* TC0 starts up unhalted.  */
16022
            env->halted = 0;
16023
            env->active_tc.CP0_TCHalt = 0;
16024
            env->tcs[0].CP0_TCHalt = 0;
16025
            /* With thread 0 active.  */
16026
            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16027
            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16028
        }
16029
    }
16030
#endif
16031
    compute_hflags(env);
16032
    env->exception_index = EXCP_NONE;
16033
}
16034

    
16035
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16036
{
16037
    env->active_tc.PC = gen_opc_pc[pc_pos];
16038
    env->hflags &= ~MIPS_HFLAG_BMASK;
16039
    env->hflags |= gen_opc_hflags[pc_pos];
16040
}