Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 51cc2e78

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

    
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <inttypes.h>
27

    
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31
#include "tcg-op.h"
32
#include "qemu-common.h"
33

    
34
#include "helper.h"
35
#define GEN_HELPER 1
36
#include "helper.h"
37

    
38
//#define MIPS_DEBUG_DISAS
39
//#define MIPS_DEBUG_SIGN_EXTENSIONS
40

    
41
/* MIPS major opcodes */
42
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
43

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

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

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

    
189
    /* Special */
190
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
191
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
192
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
193
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
194
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
195

    
196
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
197
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
198
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
199
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
200
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
201
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
202
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
203
};
204

    
205
/* Multiplication variants of the vr54xx. */
206
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
207

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

    
225
/* REGIMM (rt field) opcodes */
226
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
227

    
228
enum {
229
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
230
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
231
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
232
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
233
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
234
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
235
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
236
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
237
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
238
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
239
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
240
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
241
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
242
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
243
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
244
};
245

    
246
/* Special2 opcodes */
247
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
248

    
249
enum {
250
    /* Multiply & xxx operations */
251
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
252
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
253
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
254
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
255
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
256
    /* Misc */
257
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
258
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
259
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
260
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
261
    /* Special */
262
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
263
};
264

    
265
/* Special3 opcodes */
266
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
267

    
268
enum {
269
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
270
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
271
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
272
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
273
    OPC_INS      = 0x04 | OPC_SPECIAL3,
274
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
275
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
276
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
277
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
278
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
279
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
280
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
281
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
282
};
283

    
284
/* BSHFL opcodes */
285
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
286

    
287
enum {
288
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
289
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
290
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
291
};
292

    
293
/* DBSHFL opcodes */
294
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
295

    
296
enum {
297
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
298
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
299
};
300

    
301
/* Coprocessor 0 (rs field) */
302
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
303

    
304
enum {
305
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
306
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
307
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
308
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
309
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
310
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
311
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
312
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
313
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
314
    OPC_C0       = (0x10 << 21) | OPC_CP0,
315
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
316
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
317
};
318

    
319
/* MFMC0 opcodes */
320
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
321

    
322
enum {
323
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
324
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
325
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
326
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
327
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
328
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
329
};
330

    
331
/* Coprocessor 0 (with rs == C0) */
332
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
333

    
334
enum {
335
    OPC_TLBR     = 0x01 | OPC_C0,
336
    OPC_TLBWI    = 0x02 | OPC_C0,
337
    OPC_TLBWR    = 0x06 | OPC_C0,
338
    OPC_TLBP     = 0x08 | OPC_C0,
339
    OPC_RFE      = 0x10 | OPC_C0,
340
    OPC_ERET     = 0x18 | OPC_C0,
341
    OPC_DERET    = 0x1F | OPC_C0,
342
    OPC_WAIT     = 0x20 | OPC_C0,
343
};
344

    
345
/* Coprocessor 1 (rs field) */
346
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
347

    
348
enum {
349
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
350
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
351
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
352
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
353
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
354
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
355
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
356
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
357
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
358
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
359
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
360
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
361
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
362
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
363
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
364
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
365
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
366
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
367
};
368

    
369
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
370
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
371

    
372
enum {
373
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
374
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
375
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
376
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
377
};
378

    
379
enum {
380
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
381
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
382
};
383

    
384
enum {
385
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
386
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
387
};
388

    
389
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
390

    
391
enum {
392
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
393
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
394
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
395
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
396
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
397
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
398
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
399
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
400
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
401
};
402

    
403
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
404

    
405
enum {
406
    OPC_LWXC1   = 0x00 | OPC_CP3,
407
    OPC_LDXC1   = 0x01 | OPC_CP3,
408
    OPC_LUXC1   = 0x05 | OPC_CP3,
409
    OPC_SWXC1   = 0x08 | OPC_CP3,
410
    OPC_SDXC1   = 0x09 | OPC_CP3,
411
    OPC_SUXC1   = 0x0D | OPC_CP3,
412
    OPC_PREFX   = 0x0F | OPC_CP3,
413
    OPC_ALNV_PS = 0x1E | OPC_CP3,
414
    OPC_MADD_S  = 0x20 | OPC_CP3,
415
    OPC_MADD_D  = 0x21 | OPC_CP3,
416
    OPC_MADD_PS = 0x26 | OPC_CP3,
417
    OPC_MSUB_S  = 0x28 | OPC_CP3,
418
    OPC_MSUB_D  = 0x29 | OPC_CP3,
419
    OPC_MSUB_PS = 0x2E | OPC_CP3,
420
    OPC_NMADD_S = 0x30 | OPC_CP3,
421
    OPC_NMADD_D = 0x31 | OPC_CP3,
422
    OPC_NMADD_PS= 0x36 | OPC_CP3,
423
    OPC_NMSUB_S = 0x38 | OPC_CP3,
424
    OPC_NMSUB_D = 0x39 | OPC_CP3,
425
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
426
};
427

    
428
/* global register indices */
429
static TCGv_ptr cpu_env;
430
static TCGv cpu_gpr[32], cpu_PC;
431
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
432
static TCGv cpu_dspctrl, btarget, bcond;
433
static TCGv_i32 hflags;
434
static TCGv_i32 fpu_fcr0, fpu_fcr31;
435

    
436
#include "gen-icount.h"
437

    
438
#define gen_helper_0i(name, arg) do {                             \
439
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
440
    gen_helper_##name(helper_tmp);                                \
441
    tcg_temp_free_i32(helper_tmp);                                \
442
    } while(0)
443

    
444
#define gen_helper_1i(name, arg1, arg2) do {                      \
445
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
446
    gen_helper_##name(arg1, helper_tmp);                          \
447
    tcg_temp_free_i32(helper_tmp);                                \
448
    } while(0)
449

    
450
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
451
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
452
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
453
    tcg_temp_free_i32(helper_tmp);                                \
454
    } while(0)
455

    
456
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
457
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
458
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
459
    tcg_temp_free_i32(helper_tmp);                                \
460
    } while(0)
461

    
462
typedef struct DisasContext {
463
    struct TranslationBlock *tb;
464
    target_ulong pc, saved_pc;
465
    uint32_t opcode;
466
    int singlestep_enabled;
467
    /* Routine used to access memory */
468
    int mem_idx;
469
    uint32_t hflags, saved_hflags;
470
    int bstate;
471
    target_ulong btarget;
472
} DisasContext;
473

    
474
enum {
475
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
476
                      * exception condition */
477
    BS_STOP     = 1, /* We want to stop translation for any reason */
478
    BS_BRANCH   = 2, /* We reached a branch condition     */
479
    BS_EXCP     = 3, /* We reached an exception condition */
480
};
481

    
482
static const char *regnames[] =
483
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
484
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
485
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
486
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
487

    
488
static const char *regnames_HI[] =
489
    { "HI0", "HI1", "HI2", "HI3", };
490

    
491
static const char *regnames_LO[] =
492
    { "LO0", "LO1", "LO2", "LO3", };
493

    
494
static const char *regnames_ACX[] =
495
    { "ACX0", "ACX1", "ACX2", "ACX3", };
496

    
497
static const char *fregnames[] =
498
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
499
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
500
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
501
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
502

    
503
#ifdef MIPS_DEBUG_DISAS
504
#define MIPS_DEBUG(fmt, ...)                         \
505
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
506
                       TARGET_FMT_lx ": %08x " fmt "\n", \
507
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
508
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
509
#else
510
#define MIPS_DEBUG(fmt, ...) do { } while(0)
511
#define LOG_DISAS(...) do { } while (0)
512
#endif
513

    
514
#define MIPS_INVAL(op)                                                        \
515
do {                                                                          \
516
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
517
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
518
} while (0)
519

    
520
/* General purpose registers moves. */
521
static inline void gen_load_gpr (TCGv t, int reg)
522
{
523
    if (reg == 0)
524
        tcg_gen_movi_tl(t, 0);
525
    else
526
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
527
}
528

    
529
static inline void gen_store_gpr (TCGv t, int reg)
530
{
531
    if (reg != 0)
532
        tcg_gen_mov_tl(cpu_gpr[reg], t);
533
}
534

    
535
/* Moves to/from ACX register.  */
536
static inline void gen_load_ACX (TCGv t, int reg)
537
{
538
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
539
}
540

    
541
static inline void gen_store_ACX (TCGv t, int reg)
542
{
543
    tcg_gen_mov_tl(cpu_ACX[reg], t);
544
}
545

    
546
/* Moves to/from shadow registers. */
547
static inline void gen_load_srsgpr (int from, int to)
548
{
549
    TCGv t0 = tcg_temp_new();
550

    
551
    if (from == 0)
552
        tcg_gen_movi_tl(t0, 0);
553
    else {
554
        TCGv_i32 t2 = tcg_temp_new_i32();
555
        TCGv_ptr addr = tcg_temp_new_ptr();
556

    
557
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
558
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
559
        tcg_gen_andi_i32(t2, t2, 0xf);
560
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
561
        tcg_gen_ext_i32_ptr(addr, t2);
562
        tcg_gen_add_ptr(addr, cpu_env, addr);
563

    
564
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
565
        tcg_temp_free_ptr(addr);
566
        tcg_temp_free_i32(t2);
567
    }
568
    gen_store_gpr(t0, to);
569
    tcg_temp_free(t0);
570
}
571

    
572
static inline void gen_store_srsgpr (int from, int to)
573
{
574
    if (to != 0) {
575
        TCGv t0 = tcg_temp_new();
576
        TCGv_i32 t2 = tcg_temp_new_i32();
577
        TCGv_ptr addr = tcg_temp_new_ptr();
578

    
579
        gen_load_gpr(t0, from);
580
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
581
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
582
        tcg_gen_andi_i32(t2, t2, 0xf);
583
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
584
        tcg_gen_ext_i32_ptr(addr, t2);
585
        tcg_gen_add_ptr(addr, cpu_env, addr);
586

    
587
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
588
        tcg_temp_free_ptr(addr);
589
        tcg_temp_free_i32(t2);
590
        tcg_temp_free(t0);
591
    }
592
}
593

    
594
/* Floating point register moves. */
595
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
596
{
597
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
598
}
599

    
600
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
601
{
602
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
603
}
604

    
605
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
606
{
607
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
608
}
609

    
610
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
611
{
612
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
613
}
614

    
615
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
616
{
617
    if (ctx->hflags & MIPS_HFLAG_F64) {
618
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
619
    } else {
620
        TCGv_i32 t0 = tcg_temp_new_i32();
621
        TCGv_i32 t1 = tcg_temp_new_i32();
622
        gen_load_fpr32(t0, reg & ~1);
623
        gen_load_fpr32(t1, reg | 1);
624
        tcg_gen_concat_i32_i64(t, t0, t1);
625
        tcg_temp_free_i32(t0);
626
        tcg_temp_free_i32(t1);
627
    }
628
}
629

    
630
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
631
{
632
    if (ctx->hflags & MIPS_HFLAG_F64) {
633
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
634
    } else {
635
        TCGv_i64 t0 = tcg_temp_new_i64();
636
        TCGv_i32 t1 = tcg_temp_new_i32();
637
        tcg_gen_trunc_i64_i32(t1, t);
638
        gen_store_fpr32(t1, reg & ~1);
639
        tcg_gen_shri_i64(t0, t, 32);
640
        tcg_gen_trunc_i64_i32(t1, t0);
641
        gen_store_fpr32(t1, reg | 1);
642
        tcg_temp_free_i32(t1);
643
        tcg_temp_free_i64(t0);
644
    }
645
}
646

    
647
static inline int get_fp_bit (int cc)
648
{
649
    if (cc)
650
        return 24 + cc;
651
    else
652
        return 23;
653
}
654

    
655
#define FOP_CONDS(type, fmt, bits)                                            \
656
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
657
                                               TCGv_i##bits b, int cc)        \
658
{                                                                             \
659
    switch (n) {                                                              \
660
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
661
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
662
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
663
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
664
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
665
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
666
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
667
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
668
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
669
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
670
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
671
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
672
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
673
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
674
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
675
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
676
    default: abort();                                                         \
677
    }                                                                         \
678
}
679

    
680
FOP_CONDS(, d, 64)
681
FOP_CONDS(abs, d, 64)
682
FOP_CONDS(, s, 32)
683
FOP_CONDS(abs, s, 32)
684
FOP_CONDS(, ps, 64)
685
FOP_CONDS(abs, ps, 64)
686
#undef FOP_CONDS
687

    
688
/* Tests */
689
#define OP_COND(name, cond)                                         \
690
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
691
{                                                                   \
692
    int l1 = gen_new_label();                                       \
693
    int l2 = gen_new_label();                                       \
694
                                                                    \
695
    tcg_gen_brcond_tl(cond, t0, t1, l1);                            \
696
    tcg_gen_movi_tl(ret, 0);                                        \
697
    tcg_gen_br(l2);                                                 \
698
    gen_set_label(l1);                                              \
699
    tcg_gen_movi_tl(ret, 1);                                        \
700
    gen_set_label(l2);                                              \
701
}
702
OP_COND(eq, TCG_COND_EQ);
703
OP_COND(ne, TCG_COND_NE);
704
OP_COND(ge, TCG_COND_GE);
705
OP_COND(geu, TCG_COND_GEU);
706
OP_COND(lt, TCG_COND_LT);
707
OP_COND(ltu, TCG_COND_LTU);
708
#undef OP_COND
709

    
710
#define OP_CONDI(name, cond)                                                 \
711
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
712
{                                                                            \
713
    int l1 = gen_new_label();                                                \
714
    int l2 = gen_new_label();                                                \
715
                                                                             \
716
    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
717
    tcg_gen_movi_tl(ret, 0);                                                 \
718
    tcg_gen_br(l2);                                                          \
719
    gen_set_label(l1);                                                       \
720
    tcg_gen_movi_tl(ret, 1);                                                 \
721
    gen_set_label(l2);                                                       \
722
}
723
OP_CONDI(lti, TCG_COND_LT);
724
OP_CONDI(ltiu, TCG_COND_LTU);
725
#undef OP_CONDI
726

    
727
#define OP_CONDZ(name, cond)                                  \
728
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
729
{                                                             \
730
    int l1 = gen_new_label();                                 \
731
    int l2 = gen_new_label();                                 \
732
                                                              \
733
    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
734
    tcg_gen_movi_tl(ret, 0);                                  \
735
    tcg_gen_br(l2);                                           \
736
    gen_set_label(l1);                                        \
737
    tcg_gen_movi_tl(ret, 1);                                  \
738
    gen_set_label(l2);                                        \
739
}
740
OP_CONDZ(gez, TCG_COND_GE);
741
OP_CONDZ(gtz, TCG_COND_GT);
742
OP_CONDZ(lez, TCG_COND_LE);
743
OP_CONDZ(ltz, TCG_COND_LT);
744
#undef OP_CONDZ
745

    
746
static inline void gen_save_pc(target_ulong pc)
747
{
748
    tcg_gen_movi_tl(cpu_PC, pc);
749
}
750

    
751
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
752
{
753
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
754
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
755
        gen_save_pc(ctx->pc);
756
        ctx->saved_pc = ctx->pc;
757
    }
758
    if (ctx->hflags != ctx->saved_hflags) {
759
        tcg_gen_movi_i32(hflags, ctx->hflags);
760
        ctx->saved_hflags = ctx->hflags;
761
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
762
        case MIPS_HFLAG_BR:
763
            break;
764
        case MIPS_HFLAG_BC:
765
        case MIPS_HFLAG_BL:
766
        case MIPS_HFLAG_B:
767
            tcg_gen_movi_tl(btarget, ctx->btarget);
768
            break;
769
        }
770
    }
771
}
772

    
773
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
774
{
775
    ctx->saved_hflags = ctx->hflags;
776
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
777
    case MIPS_HFLAG_BR:
778
        break;
779
    case MIPS_HFLAG_BC:
780
    case MIPS_HFLAG_BL:
781
    case MIPS_HFLAG_B:
782
        ctx->btarget = env->btarget;
783
        break;
784
    }
785
}
786

    
787
static inline void
788
generate_exception_err (DisasContext *ctx, int excp, int err)
789
{
790
    TCGv_i32 texcp = tcg_const_i32(excp);
791
    TCGv_i32 terr = tcg_const_i32(err);
792
    save_cpu_state(ctx, 1);
793
    gen_helper_raise_exception_err(texcp, terr);
794
    tcg_temp_free_i32(terr);
795
    tcg_temp_free_i32(texcp);
796
}
797

    
798
static inline void
799
generate_exception (DisasContext *ctx, int excp)
800
{
801
    save_cpu_state(ctx, 1);
802
    gen_helper_0i(raise_exception, excp);
803
}
804

    
805
/* Addresses computation */
806
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
807
{
808
    tcg_gen_add_tl(ret, arg0, arg1);
809

    
810
#if defined(TARGET_MIPS64)
811
    /* For compatibility with 32-bit code, data reference in user mode
812
       with Status_UX = 0 should be casted to 32-bit and sign extended.
813
       See the MIPS64 PRA manual, section 4.10. */
814
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
815
        !(ctx->hflags & MIPS_HFLAG_UX)) {
816
        tcg_gen_ext32s_i64(ret, ret);
817
    }
818
#endif
819
}
820

    
821
static inline void check_cp0_enabled(DisasContext *ctx)
822
{
823
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
824
        generate_exception_err(ctx, EXCP_CpU, 1);
825
}
826

    
827
static inline void check_cp1_enabled(DisasContext *ctx)
828
{
829
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
830
        generate_exception_err(ctx, EXCP_CpU, 1);
831
}
832

    
833
/* Verify that the processor is running with COP1X instructions enabled.
834
   This is associated with the nabla symbol in the MIPS32 and MIPS64
835
   opcode tables.  */
836

    
837
static inline void check_cop1x(DisasContext *ctx)
838
{
839
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
840
        generate_exception(ctx, EXCP_RI);
841
}
842

    
843
/* Verify that the processor is running with 64-bit floating-point
844
   operations enabled.  */
845

    
846
static inline void check_cp1_64bitmode(DisasContext *ctx)
847
{
848
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/*
853
 * Verify if floating point register is valid; an operation is not defined
854
 * if bit 0 of any register specification is set and the FR bit in the
855
 * Status register equals zero, since the register numbers specify an
856
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
857
 * in the Status register equals one, both even and odd register numbers
858
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
859
 *
860
 * Multiple 64 bit wide registers can be checked by calling
861
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
862
 */
863
static inline void check_cp1_registers(DisasContext *ctx, int regs)
864
{
865
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
866
        generate_exception(ctx, EXCP_RI);
867
}
868

    
869
/* This code generates a "reserved instruction" exception if the
870
   CPU does not support the instruction set corresponding to flags. */
871
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
872
{
873
    if (unlikely(!(env->insn_flags & flags)))
874
        generate_exception(ctx, EXCP_RI);
875
}
876

    
877
/* This code generates a "reserved instruction" exception if 64-bit
878
   instructions are not enabled. */
879
static inline void check_mips_64(DisasContext *ctx)
880
{
881
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
882
        generate_exception(ctx, EXCP_RI);
883
}
884

    
885
/* load/store instructions. */
886
#define OP_LD(insn,fname)                                                 \
887
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
888
{                                                                         \
889
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
890
}
891
OP_LD(lb,ld8s);
892
OP_LD(lbu,ld8u);
893
OP_LD(lh,ld16s);
894
OP_LD(lhu,ld16u);
895
OP_LD(lw,ld32s);
896
#if defined(TARGET_MIPS64)
897
OP_LD(lwu,ld32u);
898
OP_LD(ld,ld64);
899
#endif
900
#undef OP_LD
901

    
902
#define OP_ST(insn,fname)                                                  \
903
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
904
{                                                                          \
905
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
906
}
907
OP_ST(sb,st8);
908
OP_ST(sh,st16);
909
OP_ST(sw,st32);
910
#if defined(TARGET_MIPS64)
911
OP_ST(sd,st64);
912
#endif
913
#undef OP_ST
914

    
915
#define OP_LD_ATOMIC(insn,fname)                                           \
916
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
917
{                                                                          \
918
    TCGv t0 = tcg_temp_new();                                              \
919
    tcg_gen_mov_tl(t0, arg1);                                              \
920
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
921
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));            \
922
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
923
    tcg_temp_free(t0);                                                     \
924
}
925
OP_LD_ATOMIC(ll,ld32s);
926
#if defined(TARGET_MIPS64)
927
OP_LD_ATOMIC(lld,ld64);
928
#endif
929
#undef OP_LD_ATOMIC
930

    
931
#ifdef CONFIG_USER_ONLY
932
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
933
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
934
{                                                                            \
935
    TCGv t0 = tcg_temp_new();                                                \
936
    int l1 = gen_new_label();                                                \
937
    int l2 = gen_new_label();                                                \
938
                                                                             \
939
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
940
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
941
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
942
    generate_exception(ctx, EXCP_AdES);                                      \
943
    gen_set_label(l1);                                                       \
944
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
945
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
946
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
947
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
948
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
949
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
950
    gen_set_label(l2);                                                       \
951
    tcg_gen_movi_tl(t0, 0);                                                  \
952
    gen_store_gpr(t0, rt);                                                   \
953
    tcg_temp_free(t0);                                                       \
954
}
955
#else
956
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
957
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
958
{                                                                            \
959
    TCGv t0 = tcg_temp_new();                                                \
960
    TCGv t1 = tcg_temp_new();                                                \
961
    int l1 = gen_new_label();                                                \
962
    int l2 = gen_new_label();                                                \
963
    int l3 = gen_new_label();                                                \
964
                                                                             \
965
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
966
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
967
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
968
    generate_exception(ctx, EXCP_AdES);                                      \
969
    gen_set_label(l1);                                                       \
970
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
971
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
972
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, llval));                   \
973
    tcg_gen_qemu_##ldname(t1, arg2, ctx->mem_idx);                           \
974
    tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l2);                              \
975
    tcg_temp_free(t1);                                                       \
976
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                          \
977
    tcg_gen_movi_tl(t0, 1);                                                  \
978
    gen_store_gpr(t0, rt);                                                   \
979
    tcg_gen_br(l3);                                                          \
980
    gen_set_label(l2);                                                       \
981
    tcg_gen_movi_tl(t0, 0);                                                  \
982
    gen_store_gpr(t0, rt);                                                   \
983
    gen_set_label(l3);                                                       \
984
    tcg_temp_free(t0);                                                       \
985
}
986
#endif
987

    
988
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
989
#if defined(TARGET_MIPS64)
990
OP_ST_ATOMIC(scd,st64,ld64,0x7);
991
#endif
992
#undef OP_ST_ATOMIC
993

    
994
/* Load and store */
995
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
996
                      int base, int16_t offset)
997
{
998
    const char *opn = "ldst";
999
    TCGv t0 = tcg_temp_new();
1000
    TCGv t1 = tcg_temp_new();
1001

    
1002
    if (base == 0) {
1003
        tcg_gen_movi_tl(t0, offset);
1004
    } else if (offset == 0) {
1005
        gen_load_gpr(t0, base);
1006
    } else {
1007
        tcg_gen_movi_tl(t0, offset);
1008
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1009
    }
1010
    /* Don't do NOP if destination is zero: we must perform the actual
1011
       memory access. */
1012
    switch (opc) {
1013
#if defined(TARGET_MIPS64)
1014
    case OPC_LWU:
1015
        save_cpu_state(ctx, 0);
1016
        op_ldst_lwu(t0, t0, ctx);
1017
        gen_store_gpr(t0, rt);
1018
        opn = "lwu";
1019
        break;
1020
    case OPC_LD:
1021
        save_cpu_state(ctx, 0);
1022
        op_ldst_ld(t0, t0, ctx);
1023
        gen_store_gpr(t0, rt);
1024
        opn = "ld";
1025
        break;
1026
    case OPC_LLD:
1027
        save_cpu_state(ctx, 0);
1028
        op_ldst_lld(t0, t0, ctx);
1029
        gen_store_gpr(t0, rt);
1030
        opn = "lld";
1031
        break;
1032
    case OPC_SD:
1033
        save_cpu_state(ctx, 0);
1034
        gen_load_gpr(t1, rt);
1035
        op_ldst_sd(t1, t0, ctx);
1036
        opn = "sd";
1037
        break;
1038
    case OPC_LDL:
1039
        save_cpu_state(ctx, 1);
1040
        gen_load_gpr(t1, rt);
1041
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1042
        gen_store_gpr(t1, rt);
1043
        opn = "ldl";
1044
        break;
1045
    case OPC_SDL:
1046
        save_cpu_state(ctx, 1);
1047
        gen_load_gpr(t1, rt);
1048
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1049
        opn = "sdl";
1050
        break;
1051
    case OPC_LDR:
1052
        save_cpu_state(ctx, 1);
1053
        gen_load_gpr(t1, rt);
1054
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1055
        gen_store_gpr(t1, rt);
1056
        opn = "ldr";
1057
        break;
1058
    case OPC_SDR:
1059
        save_cpu_state(ctx, 1);
1060
        gen_load_gpr(t1, rt);
1061
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1062
        opn = "sdr";
1063
        break;
1064
#endif
1065
    case OPC_LW:
1066
        save_cpu_state(ctx, 0);
1067
        op_ldst_lw(t0, t0, ctx);
1068
        gen_store_gpr(t0, rt);
1069
        opn = "lw";
1070
        break;
1071
    case OPC_SW:
1072
        save_cpu_state(ctx, 0);
1073
        gen_load_gpr(t1, rt);
1074
        op_ldst_sw(t1, t0, ctx);
1075
        opn = "sw";
1076
        break;
1077
    case OPC_LH:
1078
        save_cpu_state(ctx, 0);
1079
        op_ldst_lh(t0, t0, ctx);
1080
        gen_store_gpr(t0, rt);
1081
        opn = "lh";
1082
        break;
1083
    case OPC_SH:
1084
        save_cpu_state(ctx, 0);
1085
        gen_load_gpr(t1, rt);
1086
        op_ldst_sh(t1, t0, ctx);
1087
        opn = "sh";
1088
        break;
1089
    case OPC_LHU:
1090
        save_cpu_state(ctx, 0);
1091
        op_ldst_lhu(t0, t0, ctx);
1092
        gen_store_gpr(t0, rt);
1093
        opn = "lhu";
1094
        break;
1095
    case OPC_LB:
1096
        save_cpu_state(ctx, 0);
1097
        op_ldst_lb(t0, t0, ctx);
1098
        gen_store_gpr(t0, rt);
1099
        opn = "lb";
1100
        break;
1101
    case OPC_SB:
1102
        save_cpu_state(ctx, 0);
1103
        gen_load_gpr(t1, rt);
1104
        op_ldst_sb(t1, t0, ctx);
1105
        opn = "sb";
1106
        break;
1107
    case OPC_LBU:
1108
        save_cpu_state(ctx, 0);
1109
        op_ldst_lbu(t0, t0, ctx);
1110
        gen_store_gpr(t0, rt);
1111
        opn = "lbu";
1112
        break;
1113
    case OPC_LWL:
1114
        save_cpu_state(ctx, 1);
1115
        gen_load_gpr(t1, rt);
1116
        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1117
        gen_store_gpr(t1, rt);
1118
        opn = "lwl";
1119
        break;
1120
    case OPC_SWL:
1121
        save_cpu_state(ctx, 1);
1122
        gen_load_gpr(t1, rt);
1123
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1124
        opn = "swr";
1125
        break;
1126
    case OPC_LWR:
1127
        save_cpu_state(ctx, 1);
1128
        gen_load_gpr(t1, rt);
1129
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1130
        gen_store_gpr(t1, rt);
1131
        opn = "lwr";
1132
        break;
1133
    case OPC_SWR:
1134
        save_cpu_state(ctx, 1);
1135
        gen_load_gpr(t1, rt);
1136
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1137
        opn = "swr";
1138
        break;
1139
    case OPC_LL:
1140
        save_cpu_state(ctx, 0);
1141
        op_ldst_ll(t0, t0, ctx);
1142
        gen_store_gpr(t0, rt);
1143
        opn = "ll";
1144
        break;
1145
    }
1146
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1147
    tcg_temp_free(t0);
1148
    tcg_temp_free(t1);
1149
}
1150

    
1151
/* Store conditional */
1152
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1153
                         int base, int16_t offset)
1154
{
1155
    const char *opn = "st_cond";
1156
    TCGv t0, t1;
1157

    
1158
    t0 = tcg_temp_local_new();
1159

    
1160
    if (base == 0) {
1161
        tcg_gen_movi_tl(t0, offset);
1162
    } else if (offset == 0) {
1163
        gen_load_gpr(t0, base);
1164
    } else {
1165
        tcg_gen_movi_tl(t0, offset);
1166
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1167
    }
1168
    /* Don't do NOP if destination is zero: we must perform the actual
1169
       memory access. */
1170

    
1171
    t1 = tcg_temp_local_new();
1172
    gen_load_gpr(t1, rt);
1173
    switch (opc) {
1174
#if defined(TARGET_MIPS64)
1175
    case OPC_SCD:
1176
        save_cpu_state(ctx, 0);
1177
        op_ldst_scd(t1, t0, rt, ctx);
1178
        opn = "scd";
1179
        break;
1180
#endif
1181
    case OPC_SC:
1182
        save_cpu_state(ctx, 0);
1183
        op_ldst_sc(t1, t0, rt, ctx);
1184
        opn = "sc";
1185
        break;
1186
    }
1187
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1188
    tcg_temp_free(t1);
1189
    tcg_temp_free(t0);
1190
}
1191

    
1192
/* Load and store */
1193
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1194
                          int base, int16_t offset)
1195
{
1196
    const char *opn = "flt_ldst";
1197
    TCGv t0 = tcg_temp_new();
1198

    
1199
    if (base == 0) {
1200
        tcg_gen_movi_tl(t0, offset);
1201
    } else if (offset == 0) {
1202
        gen_load_gpr(t0, base);
1203
    } else {
1204
        tcg_gen_movi_tl(t0, offset);
1205
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1206
    }
1207
    /* Don't do NOP if destination is zero: we must perform the actual
1208
       memory access. */
1209
    switch (opc) {
1210
    case OPC_LWC1:
1211
        {
1212
            TCGv_i32 fp0 = tcg_temp_new_i32();
1213

    
1214
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1215
            tcg_gen_trunc_tl_i32(fp0, t0);
1216
            gen_store_fpr32(fp0, ft);
1217
            tcg_temp_free_i32(fp0);
1218
        }
1219
        opn = "lwc1";
1220
        break;
1221
    case OPC_SWC1:
1222
        {
1223
            TCGv_i32 fp0 = tcg_temp_new_i32();
1224
            TCGv t1 = tcg_temp_new();
1225

    
1226
            gen_load_fpr32(fp0, ft);
1227
            tcg_gen_extu_i32_tl(t1, fp0);
1228
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1229
            tcg_temp_free(t1);
1230
            tcg_temp_free_i32(fp0);
1231
        }
1232
        opn = "swc1";
1233
        break;
1234
    case OPC_LDC1:
1235
        {
1236
            TCGv_i64 fp0 = tcg_temp_new_i64();
1237

    
1238
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1239
            gen_store_fpr64(ctx, fp0, ft);
1240
            tcg_temp_free_i64(fp0);
1241
        }
1242
        opn = "ldc1";
1243
        break;
1244
    case OPC_SDC1:
1245
        {
1246
            TCGv_i64 fp0 = tcg_temp_new_i64();
1247

    
1248
            gen_load_fpr64(ctx, fp0, ft);
1249
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1250
            tcg_temp_free_i64(fp0);
1251
        }
1252
        opn = "sdc1";
1253
        break;
1254
    default:
1255
        MIPS_INVAL(opn);
1256
        generate_exception(ctx, EXCP_RI);
1257
        goto out;
1258
    }
1259
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1260
 out:
1261
    tcg_temp_free(t0);
1262
}
1263

    
1264
/* Arithmetic with immediate operand */
1265
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1266
                           int rt, int rs, int16_t imm)
1267
{
1268
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1269
    const char *opn = "imm arith";
1270

    
1271
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1272
        /* If no destination, treat it as a NOP.
1273
           For addi, we must generate the overflow exception when needed. */
1274
        MIPS_DEBUG("NOP");
1275
        return;
1276
    }
1277
    switch (opc) {
1278
    case OPC_ADDI:
1279
        {
1280
            TCGv t0 = tcg_temp_local_new();
1281
            TCGv t1 = tcg_temp_new();
1282
            TCGv t2 = tcg_temp_new();
1283
            int l1 = gen_new_label();
1284

    
1285
            gen_load_gpr(t1, rs);
1286
            tcg_gen_addi_tl(t0, t1, uimm);
1287
            tcg_gen_ext32s_tl(t0, t0);
1288

    
1289
            tcg_gen_xori_tl(t1, t1, ~uimm);
1290
            tcg_gen_xori_tl(t2, t0, uimm);
1291
            tcg_gen_and_tl(t1, t1, t2);
1292
            tcg_temp_free(t2);
1293
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1294
            tcg_temp_free(t1);
1295
            /* operands of same sign, result different sign */
1296
            generate_exception(ctx, EXCP_OVERFLOW);
1297
            gen_set_label(l1);
1298
            tcg_gen_ext32s_tl(t0, t0);
1299
            gen_store_gpr(t0, rt);
1300
            tcg_temp_free(t0);
1301
        }
1302
        opn = "addi";
1303
        break;
1304
    case OPC_ADDIU:
1305
        if (rs != 0) {
1306
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1307
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1308
        } else {
1309
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1310
        }
1311
        opn = "addiu";
1312
        break;
1313
#if defined(TARGET_MIPS64)
1314
    case OPC_DADDI:
1315
        {
1316
            TCGv t0 = tcg_temp_local_new();
1317
            TCGv t1 = tcg_temp_new();
1318
            TCGv t2 = tcg_temp_new();
1319
            int l1 = gen_new_label();
1320

    
1321
            gen_load_gpr(t1, rs);
1322
            tcg_gen_addi_tl(t0, t1, uimm);
1323

    
1324
            tcg_gen_xori_tl(t1, t1, ~uimm);
1325
            tcg_gen_xori_tl(t2, t0, uimm);
1326
            tcg_gen_and_tl(t1, t1, t2);
1327
            tcg_temp_free(t2);
1328
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1329
            tcg_temp_free(t1);
1330
            /* operands of same sign, result different sign */
1331
            generate_exception(ctx, EXCP_OVERFLOW);
1332
            gen_set_label(l1);
1333
            gen_store_gpr(t0, rt);
1334
            tcg_temp_free(t0);
1335
        }
1336
        opn = "daddi";
1337
        break;
1338
    case OPC_DADDIU:
1339
        if (rs != 0) {
1340
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1341
        } else {
1342
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1343
        }
1344
        opn = "daddiu";
1345
        break;
1346
#endif
1347
    }
1348
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1349
}
1350

    
1351
/* Logic with immediate operand */
1352
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1353
{
1354
    target_ulong uimm;
1355
    const char *opn = "imm logic";
1356

    
1357
    if (rt == 0) {
1358
        /* If no destination, treat it as a NOP. */
1359
        MIPS_DEBUG("NOP");
1360
        return;
1361
    }
1362
    uimm = (uint16_t)imm;
1363
    switch (opc) {
1364
    case OPC_ANDI:
1365
        if (likely(rs != 0))
1366
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1367
        else
1368
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1369
        opn = "andi";
1370
        break;
1371
    case OPC_ORI:
1372
        if (rs != 0)
1373
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1374
        else
1375
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1376
        opn = "ori";
1377
        break;
1378
    case OPC_XORI:
1379
        if (likely(rs != 0))
1380
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1381
        else
1382
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1383
        opn = "xori";
1384
        break;
1385
    case OPC_LUI:
1386
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1387
        opn = "lui";
1388
        break;
1389
    }
1390
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1391
}
1392

    
1393
/* Set on less than with immediate operand */
1394
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1395
{
1396
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1397
    const char *opn = "imm arith";
1398
    TCGv t0;
1399

    
1400
    if (rt == 0) {
1401
        /* If no destination, treat it as a NOP. */
1402
        MIPS_DEBUG("NOP");
1403
        return;
1404
    }
1405
    t0 = tcg_temp_new();
1406
    gen_load_gpr(t0, rs);
1407
    switch (opc) {
1408
    case OPC_SLTI:
1409
        gen_op_lti(cpu_gpr[rt], t0, uimm);
1410
        opn = "slti";
1411
        break;
1412
    case OPC_SLTIU:
1413
        gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1414
        opn = "sltiu";
1415
        break;
1416
    }
1417
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1418
    tcg_temp_free(t0);
1419
}
1420

    
1421
/* Shifts with immediate operand */
1422
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1423
                          int rt, int rs, int16_t imm)
1424
{
1425
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1426
    const char *opn = "imm shift";
1427
    TCGv t0;
1428

    
1429
    if (rt == 0) {
1430
        /* If no destination, treat it as a NOP. */
1431
        MIPS_DEBUG("NOP");
1432
        return;
1433
    }
1434

    
1435
    t0 = tcg_temp_new();
1436
    gen_load_gpr(t0, rs);
1437
    switch (opc) {
1438
    case OPC_SLL:
1439
        tcg_gen_shli_tl(t0, t0, uimm);
1440
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1441
        opn = "sll";
1442
        break;
1443
    case OPC_SRA:
1444
        tcg_gen_ext32s_tl(t0, t0);
1445
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1446
        opn = "sra";
1447
        break;
1448
    case OPC_SRL:
1449
        switch ((ctx->opcode >> 21) & 0x1f) {
1450
        case 0:
1451
            if (uimm != 0) {
1452
                tcg_gen_ext32u_tl(t0, t0);
1453
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1454
            } else {
1455
                tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1456
            }
1457
            opn = "srl";
1458
            break;
1459
        case 1:
1460
            /* rotr is decoded as srl on non-R2 CPUs */
1461
            if (env->insn_flags & ISA_MIPS32R2) {
1462
                if (uimm != 0) {
1463
                    TCGv_i32 t1 = tcg_temp_new_i32();
1464

    
1465
                    tcg_gen_trunc_tl_i32(t1, t0);
1466
                    tcg_gen_rotri_i32(t1, t1, uimm);
1467
                    tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1468
                    tcg_temp_free_i32(t1);
1469
                }
1470
                opn = "rotr";
1471
            } else {
1472
                if (uimm != 0) {
1473
                    tcg_gen_ext32u_tl(t0, t0);
1474
                    tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1475
                } else {
1476
                    tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1477
                }
1478
                opn = "srl";
1479
            }
1480
            break;
1481
        default:
1482
            MIPS_INVAL("invalid srl flag");
1483
            generate_exception(ctx, EXCP_RI);
1484
            break;
1485
        }
1486
        break;
1487
#if defined(TARGET_MIPS64)
1488
    case OPC_DSLL:
1489
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1490
        opn = "dsll";
1491
        break;
1492
    case OPC_DSRA:
1493
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1494
        opn = "dsra";
1495
        break;
1496
    case OPC_DSRL:
1497
        switch ((ctx->opcode >> 21) & 0x1f) {
1498
        case 0:
1499
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1500
            opn = "dsrl";
1501
            break;
1502
        case 1:
1503
            /* drotr is decoded as dsrl on non-R2 CPUs */
1504
            if (env->insn_flags & ISA_MIPS32R2) {
1505
                if (uimm != 0) {
1506
                    tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1507
                }
1508
                opn = "drotr";
1509
            } else {
1510
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1511
                opn = "dsrl";
1512
            }
1513
            break;
1514
        default:
1515
            MIPS_INVAL("invalid dsrl flag");
1516
            generate_exception(ctx, EXCP_RI);
1517
            break;
1518
        }
1519
        break;
1520
    case OPC_DSLL32:
1521
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1522
        opn = "dsll32";
1523
        break;
1524
    case OPC_DSRA32:
1525
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1526
        opn = "dsra32";
1527
        break;
1528
    case OPC_DSRL32:
1529
        switch ((ctx->opcode >> 21) & 0x1f) {
1530
        case 0:
1531
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1532
            opn = "dsrl32";
1533
            break;
1534
        case 1:
1535
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1536
            if (env->insn_flags & ISA_MIPS32R2) {
1537
                tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1538
                opn = "drotr32";
1539
            } else {
1540
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1541
                opn = "dsrl32";
1542
            }
1543
            break;
1544
        default:
1545
            MIPS_INVAL("invalid dsrl32 flag");
1546
            generate_exception(ctx, EXCP_RI);
1547
            break;
1548
        }
1549
        break;
1550
#endif
1551
    }
1552
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1553
    tcg_temp_free(t0);
1554
}
1555

    
1556
/* Arithmetic */
1557
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1558
                       int rd, int rs, int rt)
1559
{
1560
    const char *opn = "arith";
1561

    
1562
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1563
       && opc != OPC_DADD && opc != OPC_DSUB) {
1564
        /* If no destination, treat it as a NOP.
1565
           For add & sub, we must generate the overflow exception when needed. */
1566
        MIPS_DEBUG("NOP");
1567
        return;
1568
    }
1569

    
1570
    switch (opc) {
1571
    case OPC_ADD:
1572
        {
1573
            TCGv t0 = tcg_temp_local_new();
1574
            TCGv t1 = tcg_temp_new();
1575
            TCGv t2 = tcg_temp_new();
1576
            int l1 = gen_new_label();
1577

    
1578
            gen_load_gpr(t1, rs);
1579
            gen_load_gpr(t2, rt);
1580
            tcg_gen_add_tl(t0, t1, t2);
1581
            tcg_gen_ext32s_tl(t0, t0);
1582
            tcg_gen_xor_tl(t1, t1, t2);
1583
            tcg_gen_not_tl(t1, t1);
1584
            tcg_gen_xor_tl(t2, t0, t2);
1585
            tcg_gen_and_tl(t1, t1, t2);
1586
            tcg_temp_free(t2);
1587
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1588
            tcg_temp_free(t1);
1589
            /* operands of same sign, result different sign */
1590
            generate_exception(ctx, EXCP_OVERFLOW);
1591
            gen_set_label(l1);
1592
            gen_store_gpr(t0, rd);
1593
            tcg_temp_free(t0);
1594
        }
1595
        opn = "add";
1596
        break;
1597
    case OPC_ADDU:
1598
        if (rs != 0 && rt != 0) {
1599
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1600
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1601
        } else if (rs == 0 && rt != 0) {
1602
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1603
        } else if (rs != 0 && rt == 0) {
1604
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1605
        } else {
1606
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1607
        }
1608
        opn = "addu";
1609
        break;
1610
    case OPC_SUB:
1611
        {
1612
            TCGv t0 = tcg_temp_local_new();
1613
            TCGv t1 = tcg_temp_new();
1614
            TCGv t2 = tcg_temp_new();
1615
            int l1 = gen_new_label();
1616

    
1617
            gen_load_gpr(t1, rs);
1618
            gen_load_gpr(t2, rt);
1619
            tcg_gen_sub_tl(t0, t1, t2);
1620
            tcg_gen_ext32s_tl(t0, t0);
1621
            tcg_gen_xor_tl(t2, t1, t2);
1622
            tcg_gen_xor_tl(t1, t0, t1);
1623
            tcg_gen_and_tl(t1, t1, t2);
1624
            tcg_temp_free(t2);
1625
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1626
            tcg_temp_free(t1);
1627
            /* operands of different sign, first operand and result different sign */
1628
            generate_exception(ctx, EXCP_OVERFLOW);
1629
            gen_set_label(l1);
1630
            gen_store_gpr(t0, rd);
1631
            tcg_temp_free(t0);
1632
        }
1633
        opn = "sub";
1634
        break;
1635
    case OPC_SUBU:
1636
        if (rs != 0 && rt != 0) {
1637
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1638
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1639
        } else if (rs == 0 && rt != 0) {
1640
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1641
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1642
        } else if (rs != 0 && rt == 0) {
1643
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1644
        } else {
1645
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1646
        }
1647
        opn = "subu";
1648
        break;
1649
#if defined(TARGET_MIPS64)
1650
    case OPC_DADD:
1651
        {
1652
            TCGv t0 = tcg_temp_local_new();
1653
            TCGv t1 = tcg_temp_new();
1654
            TCGv t2 = tcg_temp_new();
1655
            int l1 = gen_new_label();
1656

    
1657
            gen_load_gpr(t1, rs);
1658
            gen_load_gpr(t2, rt);
1659
            tcg_gen_add_tl(t0, t1, t2);
1660
            tcg_gen_xor_tl(t1, t1, t2);
1661
            tcg_gen_not_tl(t1, t1);
1662
            tcg_gen_xor_tl(t2, t0, t2);
1663
            tcg_gen_and_tl(t1, t1, t2);
1664
            tcg_temp_free(t2);
1665
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1666
            tcg_temp_free(t1);
1667
            /* operands of same sign, result different sign */
1668
            generate_exception(ctx, EXCP_OVERFLOW);
1669
            gen_set_label(l1);
1670
            gen_store_gpr(t0, rd);
1671
            tcg_temp_free(t0);
1672
        }
1673
        opn = "dadd";
1674
        break;
1675
    case OPC_DADDU:
1676
        if (rs != 0 && rt != 0) {
1677
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1678
        } else if (rs == 0 && rt != 0) {
1679
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1680
        } else if (rs != 0 && rt == 0) {
1681
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1682
        } else {
1683
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1684
        }
1685
        opn = "daddu";
1686
        break;
1687
    case OPC_DSUB:
1688
        {
1689
            TCGv t0 = tcg_temp_local_new();
1690
            TCGv t1 = tcg_temp_new();
1691
            TCGv t2 = tcg_temp_new();
1692
            int l1 = gen_new_label();
1693

    
1694
            gen_load_gpr(t1, rs);
1695
            gen_load_gpr(t2, rt);
1696
            tcg_gen_sub_tl(t0, t1, t2);
1697
            tcg_gen_xor_tl(t2, t1, t2);
1698
            tcg_gen_xor_tl(t1, t0, t1);
1699
            tcg_gen_and_tl(t1, t1, t2);
1700
            tcg_temp_free(t2);
1701
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1702
            tcg_temp_free(t1);
1703
            /* operands of different sign, first operand and result different sign */
1704
            generate_exception(ctx, EXCP_OVERFLOW);
1705
            gen_set_label(l1);
1706
            gen_store_gpr(t0, rd);
1707
            tcg_temp_free(t0);
1708
        }
1709
        opn = "dsub";
1710
        break;
1711
    case OPC_DSUBU:
1712
        if (rs != 0 && rt != 0) {
1713
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1714
        } else if (rs == 0 && rt != 0) {
1715
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1716
        } else if (rs != 0 && rt == 0) {
1717
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1718
        } else {
1719
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1720
        }
1721
        opn = "dsubu";
1722
        break;
1723
#endif
1724
    case OPC_MUL:
1725
        if (likely(rs != 0 && rt != 0)) {
1726
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1727
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1728
        } else {
1729
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1730
        }
1731
        opn = "mul";
1732
        break;
1733
    }
1734
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1735
}
1736

    
1737
/* Conditional move */
1738
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1739
{
1740
    const char *opn = "cond move";
1741
    int l1;
1742

    
1743
    if (rd == 0) {
1744
        /* If no destination, treat it as a NOP.
1745
           For add & sub, we must generate the overflow exception when needed. */
1746
        MIPS_DEBUG("NOP");
1747
        return;
1748
    }
1749

    
1750
    l1 = gen_new_label();
1751
    switch (opc) {
1752
    case OPC_MOVN:
1753
        if (likely(rt != 0))
1754
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1755
        else
1756
            tcg_gen_br(l1);
1757
        opn = "movn";
1758
        break;
1759
    case OPC_MOVZ:
1760
        if (likely(rt != 0))
1761
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1762
        opn = "movz";
1763
        break;
1764
    }
1765
    if (rs != 0)
1766
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1767
    else
1768
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1769
    gen_set_label(l1);
1770

    
1771
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1772
}
1773

    
1774
/* Logic */
1775
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1776
{
1777
    const char *opn = "logic";
1778

    
1779
    if (rd == 0) {
1780
        /* If no destination, treat it as a NOP. */
1781
        MIPS_DEBUG("NOP");
1782
        return;
1783
    }
1784

    
1785
    switch (opc) {
1786
    case OPC_AND:
1787
        if (likely(rs != 0 && rt != 0)) {
1788
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1789
        } else {
1790
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1791
        }
1792
        opn = "and";
1793
        break;
1794
    case OPC_NOR:
1795
        if (rs != 0 && rt != 0) {
1796
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1797
        } else if (rs == 0 && rt != 0) {
1798
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1799
        } else if (rs != 0 && rt == 0) {
1800
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1801
        } else {
1802
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1803
        }
1804
        opn = "nor";
1805
        break;
1806
    case OPC_OR:
1807
        if (likely(rs != 0 && rt != 0)) {
1808
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1809
        } else if (rs == 0 && rt != 0) {
1810
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1811
        } else if (rs != 0 && rt == 0) {
1812
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1813
        } else {
1814
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1815
        }
1816
        opn = "or";
1817
        break;
1818
    case OPC_XOR:
1819
        if (likely(rs != 0 && rt != 0)) {
1820
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1821
        } else if (rs == 0 && rt != 0) {
1822
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1823
        } else if (rs != 0 && rt == 0) {
1824
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1825
        } else {
1826
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1827
        }
1828
        opn = "xor";
1829
        break;
1830
    }
1831
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1832
}
1833

    
1834
/* Set on lower than */
1835
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1836
{
1837
    const char *opn = "slt";
1838
    TCGv t0, t1;
1839

    
1840
    if (rd == 0) {
1841
        /* If no destination, treat it as a NOP. */
1842
        MIPS_DEBUG("NOP");
1843
        return;
1844
    }
1845

    
1846
    t0 = tcg_temp_new();
1847
    t1 = tcg_temp_new();
1848
    gen_load_gpr(t0, rs);
1849
    gen_load_gpr(t1, rt);
1850
    switch (opc) {
1851
    case OPC_SLT:
1852
        gen_op_lt(cpu_gpr[rd], t0, t1);
1853
        opn = "slt";
1854
        break;
1855
    case OPC_SLTU:
1856
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1857
        opn = "sltu";
1858
        break;
1859
    }
1860
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1861
    tcg_temp_free(t0);
1862
    tcg_temp_free(t1);
1863
}
1864

    
1865
/* Shifts */
1866
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1867
                       int rd, int rs, int rt)
1868
{
1869
    const char *opn = "shifts";
1870
    TCGv t0, t1;
1871

    
1872
    if (rd == 0) {
1873
        /* If no destination, treat it as a NOP.
1874
           For add & sub, we must generate the overflow exception when needed. */
1875
        MIPS_DEBUG("NOP");
1876
        return;
1877
    }
1878

    
1879
    t0 = tcg_temp_new();
1880
    t1 = tcg_temp_new();
1881
    gen_load_gpr(t0, rs);
1882
    gen_load_gpr(t1, rt);
1883
    switch (opc) {
1884
    case OPC_SLLV:
1885
        tcg_gen_andi_tl(t0, t0, 0x1f);
1886
        tcg_gen_shl_tl(t0, t1, t0);
1887
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1888
        opn = "sllv";
1889
        break;
1890
    case OPC_SRAV:
1891
        tcg_gen_ext32s_tl(t1, t1);
1892
        tcg_gen_andi_tl(t0, t0, 0x1f);
1893
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1894
        opn = "srav";
1895
        break;
1896
    case OPC_SRLV:
1897
        switch ((ctx->opcode >> 6) & 0x1f) {
1898
        case 0:
1899
            tcg_gen_ext32u_tl(t1, t1);
1900
            tcg_gen_andi_tl(t0, t0, 0x1f);
1901
            tcg_gen_shr_tl(t0, t1, t0);
1902
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1903
            opn = "srlv";
1904
            break;
1905
        case 1:
1906
            /* rotrv is decoded as srlv on non-R2 CPUs */
1907
            if (env->insn_flags & ISA_MIPS32R2) {
1908
                TCGv_i32 t2 = tcg_temp_new_i32();
1909
                TCGv_i32 t3 = tcg_temp_new_i32();
1910

    
1911
                tcg_gen_trunc_tl_i32(t2, t0);
1912
                tcg_gen_trunc_tl_i32(t3, t1);
1913
                tcg_gen_andi_i32(t2, t2, 0x1f);
1914
                tcg_gen_rotr_i32(t2, t3, t2);
1915
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1916
                tcg_temp_free_i32(t2);
1917
                tcg_temp_free_i32(t3);
1918
                opn = "rotrv";
1919
            } else {
1920
                tcg_gen_ext32u_tl(t1, t1);
1921
                tcg_gen_andi_tl(t0, t0, 0x1f);
1922
                tcg_gen_shr_tl(t0, t1, t0);
1923
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1924
                opn = "srlv";
1925
            }
1926
            break;
1927
        default:
1928
            MIPS_INVAL("invalid srlv flag");
1929
            generate_exception(ctx, EXCP_RI);
1930
            break;
1931
        }
1932
        break;
1933
#if defined(TARGET_MIPS64)
1934
    case OPC_DSLLV:
1935
        tcg_gen_andi_tl(t0, t0, 0x3f);
1936
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1937
        opn = "dsllv";
1938
        break;
1939
    case OPC_DSRAV:
1940
        tcg_gen_andi_tl(t0, t0, 0x3f);
1941
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1942
        opn = "dsrav";
1943
        break;
1944
    case OPC_DSRLV:
1945
        switch ((ctx->opcode >> 6) & 0x1f) {
1946
        case 0:
1947
            tcg_gen_andi_tl(t0, t0, 0x3f);
1948
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1949
            opn = "dsrlv";
1950
            break;
1951
        case 1:
1952
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1953
            if (env->insn_flags & ISA_MIPS32R2) {
1954
                tcg_gen_andi_tl(t0, t0, 0x3f);
1955
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1956
                opn = "drotrv";
1957
            } else {
1958
                tcg_gen_andi_tl(t0, t0, 0x3f);
1959
                tcg_gen_shr_tl(t0, t1, t0);
1960
                opn = "dsrlv";
1961
            }
1962
            break;
1963
        default:
1964
            MIPS_INVAL("invalid dsrlv flag");
1965
            generate_exception(ctx, EXCP_RI);
1966
            break;
1967
        }
1968
        break;
1969
#endif
1970
    }
1971
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1972
    tcg_temp_free(t0);
1973
    tcg_temp_free(t1);
1974
}
1975

    
1976
/* Arithmetic on HI/LO registers */
1977
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1978
{
1979
    const char *opn = "hilo";
1980

    
1981
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1982
        /* Treat as NOP. */
1983
        MIPS_DEBUG("NOP");
1984
        return;
1985
    }
1986
    switch (opc) {
1987
    case OPC_MFHI:
1988
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1989
        opn = "mfhi";
1990
        break;
1991
    case OPC_MFLO:
1992
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1993
        opn = "mflo";
1994
        break;
1995
    case OPC_MTHI:
1996
        if (reg != 0)
1997
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1998
        else
1999
            tcg_gen_movi_tl(cpu_HI[0], 0);
2000
        opn = "mthi";
2001
        break;
2002
    case OPC_MTLO:
2003
        if (reg != 0)
2004
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2005
        else
2006
            tcg_gen_movi_tl(cpu_LO[0], 0);
2007
        opn = "mtlo";
2008
        break;
2009
    }
2010
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2011
}
2012

    
2013
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2014
                        int rs, int rt)
2015
{
2016
    const char *opn = "mul/div";
2017
    TCGv t0, t1;
2018

    
2019
    switch (opc) {
2020
    case OPC_DIV:
2021
    case OPC_DIVU:
2022
#if defined(TARGET_MIPS64)
2023
    case OPC_DDIV:
2024
    case OPC_DDIVU:
2025
#endif
2026
        t0 = tcg_temp_local_new();
2027
        t1 = tcg_temp_local_new();
2028
        break;
2029
    default:
2030
        t0 = tcg_temp_new();
2031
        t1 = tcg_temp_new();
2032
        break;
2033
    }
2034

    
2035
    gen_load_gpr(t0, rs);
2036
    gen_load_gpr(t1, rt);
2037
    switch (opc) {
2038
    case OPC_DIV:
2039
        {
2040
            int l1 = gen_new_label();
2041
            int l2 = gen_new_label();
2042

    
2043
            tcg_gen_ext32s_tl(t0, t0);
2044
            tcg_gen_ext32s_tl(t1, t1);
2045
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2046
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2047
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2048

    
2049
            tcg_gen_mov_tl(cpu_LO[0], t0);
2050
            tcg_gen_movi_tl(cpu_HI[0], 0);
2051
            tcg_gen_br(l1);
2052
            gen_set_label(l2);
2053
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2054
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2055
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2056
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2057
            gen_set_label(l1);
2058
        }
2059
        opn = "div";
2060
        break;
2061
    case OPC_DIVU:
2062
        {
2063
            int l1 = gen_new_label();
2064

    
2065
            tcg_gen_ext32u_tl(t0, t0);
2066
            tcg_gen_ext32u_tl(t1, t1);
2067
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2068
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2069
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2070
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2071
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2072
            gen_set_label(l1);
2073
        }
2074
        opn = "divu";
2075
        break;
2076
    case OPC_MULT:
2077
        {
2078
            TCGv_i64 t2 = tcg_temp_new_i64();
2079
            TCGv_i64 t3 = tcg_temp_new_i64();
2080

    
2081
            tcg_gen_ext_tl_i64(t2, t0);
2082
            tcg_gen_ext_tl_i64(t3, t1);
2083
            tcg_gen_mul_i64(t2, t2, t3);
2084
            tcg_temp_free_i64(t3);
2085
            tcg_gen_trunc_i64_tl(t0, t2);
2086
            tcg_gen_shri_i64(t2, t2, 32);
2087
            tcg_gen_trunc_i64_tl(t1, t2);
2088
            tcg_temp_free_i64(t2);
2089
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2090
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2091
        }
2092
        opn = "mult";
2093
        break;
2094
    case OPC_MULTU:
2095
        {
2096
            TCGv_i64 t2 = tcg_temp_new_i64();
2097
            TCGv_i64 t3 = tcg_temp_new_i64();
2098

    
2099
            tcg_gen_ext32u_tl(t0, t0);
2100
            tcg_gen_ext32u_tl(t1, t1);
2101
            tcg_gen_extu_tl_i64(t2, t0);
2102
            tcg_gen_extu_tl_i64(t3, t1);
2103
            tcg_gen_mul_i64(t2, t2, t3);
2104
            tcg_temp_free_i64(t3);
2105
            tcg_gen_trunc_i64_tl(t0, t2);
2106
            tcg_gen_shri_i64(t2, t2, 32);
2107
            tcg_gen_trunc_i64_tl(t1, t2);
2108
            tcg_temp_free_i64(t2);
2109
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2110
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2111
        }
2112
        opn = "multu";
2113
        break;
2114
#if defined(TARGET_MIPS64)
2115
    case OPC_DDIV:
2116
        {
2117
            int l1 = gen_new_label();
2118
            int l2 = gen_new_label();
2119

    
2120
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2121
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2122
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2123
            tcg_gen_mov_tl(cpu_LO[0], t0);
2124
            tcg_gen_movi_tl(cpu_HI[0], 0);
2125
            tcg_gen_br(l1);
2126
            gen_set_label(l2);
2127
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2128
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2129
            gen_set_label(l1);
2130
        }
2131
        opn = "ddiv";
2132
        break;
2133
    case OPC_DDIVU:
2134
        {
2135
            int l1 = gen_new_label();
2136

    
2137
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2138
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2139
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2140
            gen_set_label(l1);
2141
        }
2142
        opn = "ddivu";
2143
        break;
2144
    case OPC_DMULT:
2145
        gen_helper_dmult(t0, t1);
2146
        opn = "dmult";
2147
        break;
2148
    case OPC_DMULTU:
2149
        gen_helper_dmultu(t0, t1);
2150
        opn = "dmultu";
2151
        break;
2152
#endif
2153
    case OPC_MADD:
2154
        {
2155
            TCGv_i64 t2 = tcg_temp_new_i64();
2156
            TCGv_i64 t3 = tcg_temp_new_i64();
2157

    
2158
            tcg_gen_ext_tl_i64(t2, t0);
2159
            tcg_gen_ext_tl_i64(t3, t1);
2160
            tcg_gen_mul_i64(t2, t2, t3);
2161
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2162
            tcg_gen_add_i64(t2, t2, t3);
2163
            tcg_temp_free_i64(t3);
2164
            tcg_gen_trunc_i64_tl(t0, t2);
2165
            tcg_gen_shri_i64(t2, t2, 32);
2166
            tcg_gen_trunc_i64_tl(t1, t2);
2167
            tcg_temp_free_i64(t2);
2168
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2169
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2170
        }
2171
        opn = "madd";
2172
        break;
2173
    case OPC_MADDU:
2174
       {
2175
            TCGv_i64 t2 = tcg_temp_new_i64();
2176
            TCGv_i64 t3 = tcg_temp_new_i64();
2177

    
2178
            tcg_gen_ext32u_tl(t0, t0);
2179
            tcg_gen_ext32u_tl(t1, t1);
2180
            tcg_gen_extu_tl_i64(t2, t0);
2181
            tcg_gen_extu_tl_i64(t3, t1);
2182
            tcg_gen_mul_i64(t2, t2, t3);
2183
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2184
            tcg_gen_add_i64(t2, t2, t3);
2185
            tcg_temp_free_i64(t3);
2186
            tcg_gen_trunc_i64_tl(t0, t2);
2187
            tcg_gen_shri_i64(t2, t2, 32);
2188
            tcg_gen_trunc_i64_tl(t1, t2);
2189
            tcg_temp_free_i64(t2);
2190
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2191
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2192
        }
2193
        opn = "maddu";
2194
        break;
2195
    case OPC_MSUB:
2196
        {
2197
            TCGv_i64 t2 = tcg_temp_new_i64();
2198
            TCGv_i64 t3 = tcg_temp_new_i64();
2199

    
2200
            tcg_gen_ext_tl_i64(t2, t0);
2201
            tcg_gen_ext_tl_i64(t3, t1);
2202
            tcg_gen_mul_i64(t2, t2, t3);
2203
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2204
            tcg_gen_sub_i64(t2, t3, t2);
2205
            tcg_temp_free_i64(t3);
2206
            tcg_gen_trunc_i64_tl(t0, t2);
2207
            tcg_gen_shri_i64(t2, t2, 32);
2208
            tcg_gen_trunc_i64_tl(t1, t2);
2209
            tcg_temp_free_i64(t2);
2210
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2211
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2212
        }
2213
        opn = "msub";
2214
        break;
2215
    case OPC_MSUBU:
2216
        {
2217
            TCGv_i64 t2 = tcg_temp_new_i64();
2218
            TCGv_i64 t3 = tcg_temp_new_i64();
2219

    
2220
            tcg_gen_ext32u_tl(t0, t0);
2221
            tcg_gen_ext32u_tl(t1, t1);
2222
            tcg_gen_extu_tl_i64(t2, t0);
2223
            tcg_gen_extu_tl_i64(t3, t1);
2224
            tcg_gen_mul_i64(t2, t2, t3);
2225
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2226
            tcg_gen_sub_i64(t2, t3, t2);
2227
            tcg_temp_free_i64(t3);
2228
            tcg_gen_trunc_i64_tl(t0, t2);
2229
            tcg_gen_shri_i64(t2, t2, 32);
2230
            tcg_gen_trunc_i64_tl(t1, t2);
2231
            tcg_temp_free_i64(t2);
2232
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2233
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2234
        }
2235
        opn = "msubu";
2236
        break;
2237
    default:
2238
        MIPS_INVAL(opn);
2239
        generate_exception(ctx, EXCP_RI);
2240
        goto out;
2241
    }
2242
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2243
 out:
2244
    tcg_temp_free(t0);
2245
    tcg_temp_free(t1);
2246
}
2247

    
2248
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2249
                            int rd, int rs, int rt)
2250
{
2251
    const char *opn = "mul vr54xx";
2252
    TCGv t0 = tcg_temp_new();
2253
    TCGv t1 = tcg_temp_new();
2254

    
2255
    gen_load_gpr(t0, rs);
2256
    gen_load_gpr(t1, rt);
2257

    
2258
    switch (opc) {
2259
    case OPC_VR54XX_MULS:
2260
        gen_helper_muls(t0, t0, t1);
2261
        opn = "muls";
2262
        break;
2263
    case OPC_VR54XX_MULSU:
2264
        gen_helper_mulsu(t0, t0, t1);
2265
        opn = "mulsu";
2266
        break;
2267
    case OPC_VR54XX_MACC:
2268
        gen_helper_macc(t0, t0, t1);
2269
        opn = "macc";
2270
        break;
2271
    case OPC_VR54XX_MACCU:
2272
        gen_helper_maccu(t0, t0, t1);
2273
        opn = "maccu";
2274
        break;
2275
    case OPC_VR54XX_MSAC:
2276
        gen_helper_msac(t0, t0, t1);
2277
        opn = "msac";
2278
        break;
2279
    case OPC_VR54XX_MSACU:
2280
        gen_helper_msacu(t0, t0, t1);
2281
        opn = "msacu";
2282
        break;
2283
    case OPC_VR54XX_MULHI:
2284
        gen_helper_mulhi(t0, t0, t1);
2285
        opn = "mulhi";
2286
        break;
2287
    case OPC_VR54XX_MULHIU:
2288
        gen_helper_mulhiu(t0, t0, t1);
2289
        opn = "mulhiu";
2290
        break;
2291
    case OPC_VR54XX_MULSHI:
2292
        gen_helper_mulshi(t0, t0, t1);
2293
        opn = "mulshi";
2294
        break;
2295
    case OPC_VR54XX_MULSHIU:
2296
        gen_helper_mulshiu(t0, t0, t1);
2297
        opn = "mulshiu";
2298
        break;
2299
    case OPC_VR54XX_MACCHI:
2300
        gen_helper_macchi(t0, t0, t1);
2301
        opn = "macchi";
2302
        break;
2303
    case OPC_VR54XX_MACCHIU:
2304
        gen_helper_macchiu(t0, t0, t1);
2305
        opn = "macchiu";
2306
        break;
2307
    case OPC_VR54XX_MSACHI:
2308
        gen_helper_msachi(t0, t0, t1);
2309
        opn = "msachi";
2310
        break;
2311
    case OPC_VR54XX_MSACHIU:
2312
        gen_helper_msachiu(t0, t0, t1);
2313
        opn = "msachiu";
2314
        break;
2315
    default:
2316
        MIPS_INVAL("mul vr54xx");
2317
        generate_exception(ctx, EXCP_RI);
2318
        goto out;
2319
    }
2320
    gen_store_gpr(t0, rd);
2321
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2322

    
2323
 out:
2324
    tcg_temp_free(t0);
2325
    tcg_temp_free(t1);
2326
}
2327

    
2328
static void gen_cl (DisasContext *ctx, uint32_t opc,
2329
                    int rd, int rs)
2330
{
2331
    const char *opn = "CLx";
2332
    TCGv t0;
2333

    
2334
    if (rd == 0) {
2335
        /* Treat as NOP. */
2336
        MIPS_DEBUG("NOP");
2337
        return;
2338
    }
2339
    t0 = tcg_temp_new();
2340
    gen_load_gpr(t0, rs);
2341
    switch (opc) {
2342
    case OPC_CLO:
2343
        gen_helper_clo(cpu_gpr[rd], t0);
2344
        opn = "clo";
2345
        break;
2346
    case OPC_CLZ:
2347
        gen_helper_clz(cpu_gpr[rd], t0);
2348
        opn = "clz";
2349
        break;
2350
#if defined(TARGET_MIPS64)
2351
    case OPC_DCLO:
2352
        gen_helper_dclo(cpu_gpr[rd], t0);
2353
        opn = "dclo";
2354
        break;
2355
    case OPC_DCLZ:
2356
        gen_helper_dclz(cpu_gpr[rd], t0);
2357
        opn = "dclz";
2358
        break;
2359
#endif
2360
    }
2361
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2362
    tcg_temp_free(t0);
2363
}
2364

    
2365
/* Traps */
2366
static void gen_trap (DisasContext *ctx, uint32_t opc,
2367
                      int rs, int rt, int16_t imm)
2368
{
2369
    int cond;
2370
    TCGv t0 = tcg_temp_new();
2371
    TCGv t1 = tcg_temp_new();
2372

    
2373
    cond = 0;
2374
    /* Load needed operands */
2375
    switch (opc) {
2376
    case OPC_TEQ:
2377
    case OPC_TGE:
2378
    case OPC_TGEU:
2379
    case OPC_TLT:
2380
    case OPC_TLTU:
2381
    case OPC_TNE:
2382
        /* Compare two registers */
2383
        if (rs != rt) {
2384
            gen_load_gpr(t0, rs);
2385
            gen_load_gpr(t1, rt);
2386
            cond = 1;
2387
        }
2388
        break;
2389
    case OPC_TEQI:
2390
    case OPC_TGEI:
2391
    case OPC_TGEIU:
2392
    case OPC_TLTI:
2393
    case OPC_TLTIU:
2394
    case OPC_TNEI:
2395
        /* Compare register to immediate */
2396
        if (rs != 0 || imm != 0) {
2397
            gen_load_gpr(t0, rs);
2398
            tcg_gen_movi_tl(t1, (int32_t)imm);
2399
            cond = 1;
2400
        }
2401
        break;
2402
    }
2403
    if (cond == 0) {
2404
        switch (opc) {
2405
        case OPC_TEQ:   /* rs == rs */
2406
        case OPC_TEQI:  /* r0 == 0  */
2407
        case OPC_TGE:   /* rs >= rs */
2408
        case OPC_TGEI:  /* r0 >= 0  */
2409
        case OPC_TGEU:  /* rs >= rs unsigned */
2410
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2411
            /* Always trap */
2412
            generate_exception(ctx, EXCP_TRAP);
2413
            break;
2414
        case OPC_TLT:   /* rs < rs           */
2415
        case OPC_TLTI:  /* r0 < 0            */
2416
        case OPC_TLTU:  /* rs < rs unsigned  */
2417
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2418
        case OPC_TNE:   /* rs != rs          */
2419
        case OPC_TNEI:  /* r0 != 0           */
2420
            /* Never trap: treat as NOP. */
2421
            break;
2422
        }
2423
    } else {
2424
        int l1 = gen_new_label();
2425

    
2426
        switch (opc) {
2427
        case OPC_TEQ:
2428
        case OPC_TEQI:
2429
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2430
            break;
2431
        case OPC_TGE:
2432
        case OPC_TGEI:
2433
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2434
            break;
2435
        case OPC_TGEU:
2436
        case OPC_TGEIU:
2437
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2438
            break;
2439
        case OPC_TLT:
2440
        case OPC_TLTI:
2441
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2442
            break;
2443
        case OPC_TLTU:
2444
        case OPC_TLTIU:
2445
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2446
            break;
2447
        case OPC_TNE:
2448
        case OPC_TNEI:
2449
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2450
            break;
2451
        }
2452
        generate_exception(ctx, EXCP_TRAP);
2453
        gen_set_label(l1);
2454
    }
2455
    tcg_temp_free(t0);
2456
    tcg_temp_free(t1);
2457
}
2458

    
2459
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2460
{
2461
    TranslationBlock *tb;
2462
    tb = ctx->tb;
2463
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2464
        likely(!ctx->singlestep_enabled)) {
2465
        tcg_gen_goto_tb(n);
2466
        gen_save_pc(dest);
2467
        tcg_gen_exit_tb((long)tb + n);
2468
    } else {
2469
        gen_save_pc(dest);
2470
        if (ctx->singlestep_enabled) {
2471
            save_cpu_state(ctx, 0);
2472
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2473
        }
2474
        tcg_gen_exit_tb(0);
2475
    }
2476
}
2477

    
2478
/* Branches (before delay slot) */
2479
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2480
                                int rs, int rt, int32_t offset)
2481
{
2482
    target_ulong btgt = -1;
2483
    int blink = 0;
2484
    int bcond_compute = 0;
2485
    TCGv t0 = tcg_temp_new();
2486
    TCGv t1 = tcg_temp_new();
2487

    
2488
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2489
#ifdef MIPS_DEBUG_DISAS
2490
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2491
#endif
2492
        generate_exception(ctx, EXCP_RI);
2493
        goto out;
2494
    }
2495

    
2496
    /* Load needed operands */
2497
    switch (opc) {
2498
    case OPC_BEQ:
2499
    case OPC_BEQL:
2500
    case OPC_BNE:
2501
    case OPC_BNEL:
2502
        /* Compare two registers */
2503
        if (rs != rt) {
2504
            gen_load_gpr(t0, rs);
2505
            gen_load_gpr(t1, rt);
2506
            bcond_compute = 1;
2507
        }
2508
        btgt = ctx->pc + 4 + offset;
2509
        break;
2510
    case OPC_BGEZ:
2511
    case OPC_BGEZAL:
2512
    case OPC_BGEZALL:
2513
    case OPC_BGEZL:
2514
    case OPC_BGTZ:
2515
    case OPC_BGTZL:
2516
    case OPC_BLEZ:
2517
    case OPC_BLEZL:
2518
    case OPC_BLTZ:
2519
    case OPC_BLTZAL:
2520
    case OPC_BLTZALL:
2521
    case OPC_BLTZL:
2522
        /* Compare to zero */
2523
        if (rs != 0) {
2524
            gen_load_gpr(t0, rs);
2525
            bcond_compute = 1;
2526
        }
2527
        btgt = ctx->pc + 4 + offset;
2528
        break;
2529
    case OPC_J:
2530
    case OPC_JAL:
2531
        /* Jump to immediate */
2532
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2533
        break;
2534
    case OPC_JR:
2535
    case OPC_JALR:
2536
        /* Jump to register */
2537
        if (offset != 0 && offset != 16) {
2538
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2539
               others are reserved. */
2540
            MIPS_INVAL("jump hint");
2541
            generate_exception(ctx, EXCP_RI);
2542
            goto out;
2543
        }
2544
        gen_load_gpr(btarget, rs);
2545
        break;
2546
    default:
2547
        MIPS_INVAL("branch/jump");
2548
        generate_exception(ctx, EXCP_RI);
2549
        goto out;
2550
    }
2551
    if (bcond_compute == 0) {
2552
        /* No condition to be computed */
2553
        switch (opc) {
2554
        case OPC_BEQ:     /* rx == rx        */
2555
        case OPC_BEQL:    /* rx == rx likely */
2556
        case OPC_BGEZ:    /* 0 >= 0          */
2557
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2558
        case OPC_BLEZ:    /* 0 <= 0          */
2559
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2560
            /* Always take */
2561
            ctx->hflags |= MIPS_HFLAG_B;
2562
            MIPS_DEBUG("balways");
2563
            break;
2564
        case OPC_BGEZAL:  /* 0 >= 0          */
2565
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2566
            /* Always take and link */
2567
            blink = 31;
2568
            ctx->hflags |= MIPS_HFLAG_B;
2569
            MIPS_DEBUG("balways and link");
2570
            break;
2571
        case OPC_BNE:     /* rx != rx        */
2572
        case OPC_BGTZ:    /* 0 > 0           */
2573
        case OPC_BLTZ:    /* 0 < 0           */
2574
            /* Treat as NOP. */
2575
            MIPS_DEBUG("bnever (NOP)");
2576
            goto out;
2577
        case OPC_BLTZAL:  /* 0 < 0           */
2578
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2579
            MIPS_DEBUG("bnever and link");
2580
            goto out;
2581
        case OPC_BLTZALL: /* 0 < 0 likely */
2582
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2583
            /* Skip the instruction in the delay slot */
2584
            MIPS_DEBUG("bnever, link and skip");
2585
            ctx->pc += 4;
2586
            goto out;
2587
        case OPC_BNEL:    /* rx != rx likely */
2588
        case OPC_BGTZL:   /* 0 > 0 likely */
2589
        case OPC_BLTZL:   /* 0 < 0 likely */
2590
            /* Skip the instruction in the delay slot */
2591
            MIPS_DEBUG("bnever and skip");
2592
            ctx->pc += 4;
2593
            goto out;
2594
        case OPC_J:
2595
            ctx->hflags |= MIPS_HFLAG_B;
2596
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2597
            break;
2598
        case OPC_JAL:
2599
            blink = 31;
2600
            ctx->hflags |= MIPS_HFLAG_B;
2601
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2602
            break;
2603
        case OPC_JR:
2604
            ctx->hflags |= MIPS_HFLAG_BR;
2605
            MIPS_DEBUG("jr %s", regnames[rs]);
2606
            break;
2607
        case OPC_JALR:
2608
            blink = rt;
2609
            ctx->hflags |= MIPS_HFLAG_BR;
2610
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2611
            break;
2612
        default:
2613
            MIPS_INVAL("branch/jump");
2614
            generate_exception(ctx, EXCP_RI);
2615
            goto out;
2616
        }
2617
    } else {
2618
        switch (opc) {
2619
        case OPC_BEQ:
2620
            gen_op_eq(bcond, t0, t1);
2621
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2622
                       regnames[rs], regnames[rt], btgt);
2623
            goto not_likely;
2624
        case OPC_BEQL:
2625
            gen_op_eq(bcond, t0, t1);
2626
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2627
                       regnames[rs], regnames[rt], btgt);
2628
            goto likely;
2629
        case OPC_BNE:
2630
            gen_op_ne(bcond, t0, t1);
2631
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2632
                       regnames[rs], regnames[rt], btgt);
2633
            goto not_likely;
2634
        case OPC_BNEL:
2635
            gen_op_ne(bcond, t0, t1);
2636
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2637
                       regnames[rs], regnames[rt], btgt);
2638
            goto likely;
2639
        case OPC_BGEZ:
2640
            gen_op_gez(bcond, t0);
2641
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2642
            goto not_likely;
2643
        case OPC_BGEZL:
2644
            gen_op_gez(bcond, t0);
2645
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2646
            goto likely;
2647
        case OPC_BGEZAL:
2648
            gen_op_gez(bcond, t0);
2649
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2650
            blink = 31;
2651
            goto not_likely;
2652
        case OPC_BGEZALL:
2653
            gen_op_gez(bcond, t0);
2654
            blink = 31;
2655
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656
            goto likely;
2657
        case OPC_BGTZ:
2658
            gen_op_gtz(bcond, t0);
2659
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660
            goto not_likely;
2661
        case OPC_BGTZL:
2662
            gen_op_gtz(bcond, t0);
2663
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2664
            goto likely;
2665
        case OPC_BLEZ:
2666
            gen_op_lez(bcond, t0);
2667
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2668
            goto not_likely;
2669
        case OPC_BLEZL:
2670
            gen_op_lez(bcond, t0);
2671
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2672
            goto likely;
2673
        case OPC_BLTZ:
2674
            gen_op_ltz(bcond, t0);
2675
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676
            goto not_likely;
2677
        case OPC_BLTZL:
2678
            gen_op_ltz(bcond, t0);
2679
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2680
            goto likely;
2681
        case OPC_BLTZAL:
2682
            gen_op_ltz(bcond, t0);
2683
            blink = 31;
2684
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2685
        not_likely:
2686
            ctx->hflags |= MIPS_HFLAG_BC;
2687
            break;
2688
        case OPC_BLTZALL:
2689
            gen_op_ltz(bcond, t0);
2690
            blink = 31;
2691
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2692
        likely:
2693
            ctx->hflags |= MIPS_HFLAG_BL;
2694
            break;
2695
        default:
2696
            MIPS_INVAL("conditional branch/jump");
2697
            generate_exception(ctx, EXCP_RI);
2698
            goto out;
2699
        }
2700
    }
2701
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2702
               blink, ctx->hflags, btgt);
2703

    
2704
    ctx->btarget = btgt;
2705
    if (blink > 0) {
2706
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2707
    }
2708

    
2709
 out:
2710
    tcg_temp_free(t0);
2711
    tcg_temp_free(t1);
2712
}
2713

    
2714
/* special3 bitfield operations */
2715
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2716
                        int rs, int lsb, int msb)
2717
{
2718
    TCGv t0 = tcg_temp_new();
2719
    TCGv t1 = tcg_temp_new();
2720
    target_ulong mask;
2721

    
2722
    gen_load_gpr(t1, rs);
2723
    switch (opc) {
2724
    case OPC_EXT:
2725
        if (lsb + msb > 31)
2726
            goto fail;
2727
        tcg_gen_shri_tl(t0, t1, lsb);
2728
        if (msb != 31) {
2729
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2730
        } else {
2731
            tcg_gen_ext32s_tl(t0, t0);
2732
        }
2733
        break;
2734
#if defined(TARGET_MIPS64)
2735
    case OPC_DEXTM:
2736
        tcg_gen_shri_tl(t0, t1, lsb);
2737
        if (msb != 31) {
2738
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2739
        }
2740
        break;
2741
    case OPC_DEXTU:
2742
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2743
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2744
        break;
2745
    case OPC_DEXT:
2746
        tcg_gen_shri_tl(t0, t1, lsb);
2747
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2748
        break;
2749
#endif
2750
    case OPC_INS:
2751
        if (lsb > msb)
2752
            goto fail;
2753
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2754
        gen_load_gpr(t0, rt);
2755
        tcg_gen_andi_tl(t0, t0, ~mask);
2756
        tcg_gen_shli_tl(t1, t1, lsb);
2757
        tcg_gen_andi_tl(t1, t1, mask);
2758
        tcg_gen_or_tl(t0, t0, t1);
2759
        tcg_gen_ext32s_tl(t0, t0);
2760
        break;
2761
#if defined(TARGET_MIPS64)
2762
    case OPC_DINSM:
2763
        if (lsb > msb)
2764
            goto fail;
2765
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2766
        gen_load_gpr(t0, rt);
2767
        tcg_gen_andi_tl(t0, t0, ~mask);
2768
        tcg_gen_shli_tl(t1, t1, lsb);
2769
        tcg_gen_andi_tl(t1, t1, mask);
2770
        tcg_gen_or_tl(t0, t0, t1);
2771
        break;
2772
    case OPC_DINSU:
2773
        if (lsb > msb)
2774
            goto fail;
2775
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2776
        gen_load_gpr(t0, rt);
2777
        tcg_gen_andi_tl(t0, t0, ~mask);
2778
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2779
        tcg_gen_andi_tl(t1, t1, mask);
2780
        tcg_gen_or_tl(t0, t0, t1);
2781
        break;
2782
    case OPC_DINS:
2783
        if (lsb > msb)
2784
            goto fail;
2785
        gen_load_gpr(t0, rt);
2786
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2787
        gen_load_gpr(t0, rt);
2788
        tcg_gen_andi_tl(t0, t0, ~mask);
2789
        tcg_gen_shli_tl(t1, t1, lsb);
2790
        tcg_gen_andi_tl(t1, t1, mask);
2791
        tcg_gen_or_tl(t0, t0, t1);
2792
        break;
2793
#endif
2794
    default:
2795
fail:
2796
        MIPS_INVAL("bitops");
2797
        generate_exception(ctx, EXCP_RI);
2798
        tcg_temp_free(t0);
2799
        tcg_temp_free(t1);
2800
        return;
2801
    }
2802
    gen_store_gpr(t0, rt);
2803
    tcg_temp_free(t0);
2804
    tcg_temp_free(t1);
2805
}
2806

    
2807
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2808
{
2809
    TCGv t0;
2810

    
2811
    if (rd == 0) {
2812
        /* If no destination, treat it as a NOP. */
2813
        MIPS_DEBUG("NOP");
2814
        return;
2815
    }
2816

    
2817
    t0 = tcg_temp_new();
2818
    gen_load_gpr(t0, rt);
2819
    switch (op2) {
2820
    case OPC_WSBH:
2821
        {
2822
            TCGv t1 = tcg_temp_new();
2823

    
2824
            tcg_gen_shri_tl(t1, t0, 8);
2825
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2826
            tcg_gen_shli_tl(t0, t0, 8);
2827
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2828
            tcg_gen_or_tl(t0, t0, t1);
2829
            tcg_temp_free(t1);
2830
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2831
        }
2832
        break;
2833
    case OPC_SEB:
2834
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2835
        break;
2836
    case OPC_SEH:
2837
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2838
        break;
2839
#if defined(TARGET_MIPS64)
2840
    case OPC_DSBH:
2841
        {
2842
            TCGv t1 = tcg_temp_new();
2843

    
2844
            tcg_gen_shri_tl(t1, t0, 8);
2845
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2846
            tcg_gen_shli_tl(t0, t0, 8);
2847
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2848
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2849
            tcg_temp_free(t1);
2850
        }
2851
        break;
2852
    case OPC_DSHD:
2853
        {
2854
            TCGv t1 = tcg_temp_new();
2855

    
2856
            tcg_gen_shri_tl(t1, t0, 16);
2857
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2858
            tcg_gen_shli_tl(t0, t0, 16);
2859
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2860
            tcg_gen_or_tl(t0, t0, t1);
2861
            tcg_gen_shri_tl(t1, t0, 32);
2862
            tcg_gen_shli_tl(t0, t0, 32);
2863
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2864
            tcg_temp_free(t1);
2865
        }
2866
        break;
2867
#endif
2868
    default:
2869
        MIPS_INVAL("bsfhl");
2870
        generate_exception(ctx, EXCP_RI);
2871
        tcg_temp_free(t0);
2872
        return;
2873
    }
2874
    tcg_temp_free(t0);
2875
}
2876

    
2877
#ifndef CONFIG_USER_ONLY
2878
/* CP0 (MMU and control) */
2879
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2880
{
2881
    TCGv_i32 t0 = tcg_temp_new_i32();
2882

    
2883
    tcg_gen_ld_i32(t0, cpu_env, off);
2884
    tcg_gen_ext_i32_tl(arg, t0);
2885
    tcg_temp_free_i32(t0);
2886
}
2887

    
2888
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2889
{
2890
    tcg_gen_ld_tl(arg, cpu_env, off);
2891
    tcg_gen_ext32s_tl(arg, arg);
2892
}
2893

    
2894
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2895
{
2896
    TCGv_i32 t0 = tcg_temp_new_i32();
2897

    
2898
    tcg_gen_trunc_tl_i32(t0, arg);
2899
    tcg_gen_st_i32(t0, cpu_env, off);
2900
    tcg_temp_free_i32(t0);
2901
}
2902

    
2903
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2904
{
2905
    tcg_gen_ext32s_tl(arg, arg);
2906
    tcg_gen_st_tl(arg, cpu_env, off);
2907
}
2908

    
2909
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2910
{
2911
    const char *rn = "invalid";
2912

    
2913
    if (sel != 0)
2914
        check_insn(env, ctx, ISA_MIPS32);
2915

    
2916
    switch (reg) {
2917
    case 0:
2918
        switch (sel) {
2919
        case 0:
2920
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2921
            rn = "Index";
2922
            break;
2923
        case 1:
2924
            check_insn(env, ctx, ASE_MT);
2925
            gen_helper_mfc0_mvpcontrol(arg);
2926
            rn = "MVPControl";
2927
            break;
2928
        case 2:
2929
            check_insn(env, ctx, ASE_MT);
2930
            gen_helper_mfc0_mvpconf0(arg);
2931
            rn = "MVPConf0";
2932
            break;
2933
        case 3:
2934
            check_insn(env, ctx, ASE_MT);
2935
            gen_helper_mfc0_mvpconf1(arg);
2936
            rn = "MVPConf1";
2937
            break;
2938
        default:
2939
            goto die;
2940
        }
2941
        break;
2942
    case 1:
2943
        switch (sel) {
2944
        case 0:
2945
            gen_helper_mfc0_random(arg);
2946
            rn = "Random";
2947
            break;
2948
        case 1:
2949
            check_insn(env, ctx, ASE_MT);
2950
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2951
            rn = "VPEControl";
2952
            break;
2953
        case 2:
2954
            check_insn(env, ctx, ASE_MT);
2955
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2956
            rn = "VPEConf0";
2957
            break;
2958
        case 3:
2959
            check_insn(env, ctx, ASE_MT);
2960
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2961
            rn = "VPEConf1";
2962
            break;
2963
        case 4:
2964
            check_insn(env, ctx, ASE_MT);
2965
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2966
            rn = "YQMask";
2967
            break;
2968
        case 5:
2969
            check_insn(env, ctx, ASE_MT);
2970
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2971
            rn = "VPESchedule";
2972
            break;
2973
        case 6:
2974
            check_insn(env, ctx, ASE_MT);
2975
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2976
            rn = "VPEScheFBack";
2977
            break;
2978
        case 7:
2979
            check_insn(env, ctx, ASE_MT);
2980
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2981
            rn = "VPEOpt";
2982
            break;
2983
        default:
2984
            goto die;
2985
        }
2986
        break;
2987
    case 2:
2988
        switch (sel) {
2989
        case 0:
2990
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2991
            tcg_gen_ext32s_tl(arg, arg);
2992
            rn = "EntryLo0";
2993
            break;
2994
        case 1:
2995
            check_insn(env, ctx, ASE_MT);
2996
            gen_helper_mfc0_tcstatus(arg);
2997
            rn = "TCStatus";
2998
            break;
2999
        case 2:
3000
            check_insn(env, ctx, ASE_MT);
3001
            gen_helper_mfc0_tcbind(arg);
3002
            rn = "TCBind";
3003
            break;
3004
        case 3:
3005
            check_insn(env, ctx, ASE_MT);
3006
            gen_helper_mfc0_tcrestart(arg);
3007
            rn = "TCRestart";
3008
            break;
3009
        case 4:
3010
            check_insn(env, ctx, ASE_MT);
3011
            gen_helper_mfc0_tchalt(arg);
3012
            rn = "TCHalt";
3013
            break;
3014
        case 5:
3015
            check_insn(env, ctx, ASE_MT);
3016
            gen_helper_mfc0_tccontext(arg);
3017
            rn = "TCContext";
3018
            break;
3019
        case 6:
3020
            check_insn(env, ctx, ASE_MT);
3021
            gen_helper_mfc0_tcschedule(arg);
3022
            rn = "TCSchedule";
3023
            break;
3024
        case 7:
3025
            check_insn(env, ctx, ASE_MT);
3026
            gen_helper_mfc0_tcschefback(arg);
3027
            rn = "TCScheFBack";
3028
            break;
3029
        default:
3030
            goto die;
3031
        }
3032
        break;
3033
    case 3:
3034
        switch (sel) {
3035
        case 0:
3036
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3037
            tcg_gen_ext32s_tl(arg, arg);
3038
            rn = "EntryLo1";
3039
            break;
3040
        default:
3041
            goto die;
3042
        }
3043
        break;
3044
    case 4:
3045
        switch (sel) {
3046
        case 0:
3047
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3048
            tcg_gen_ext32s_tl(arg, arg);
3049
            rn = "Context";
3050
            break;
3051
        case 1:
3052
//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3053
            rn = "ContextConfig";
3054
//            break;
3055
        default:
3056
            goto die;
3057
        }
3058
        break;
3059
    case 5:
3060
        switch (sel) {
3061
        case 0:
3062
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3063
            rn = "PageMask";
3064
            break;
3065
        case 1:
3066
            check_insn(env, ctx, ISA_MIPS32R2);
3067
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3068
            rn = "PageGrain";
3069
            break;
3070
        default:
3071
            goto die;
3072
        }
3073
        break;
3074
    case 6:
3075
        switch (sel) {
3076
        case 0:
3077
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3078
            rn = "Wired";
3079
            break;
3080
        case 1:
3081
            check_insn(env, ctx, ISA_MIPS32R2);
3082
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3083
            rn = "SRSConf0";
3084
            break;
3085
        case 2:
3086
            check_insn(env, ctx, ISA_MIPS32R2);
3087
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3088
            rn = "SRSConf1";
3089
            break;
3090
        case 3:
3091
            check_insn(env, ctx, ISA_MIPS32R2);
3092
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3093
            rn = "SRSConf2";
3094
            break;
3095
        case 4:
3096
            check_insn(env, ctx, ISA_MIPS32R2);
3097
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3098
            rn = "SRSConf3";
3099
            break;
3100
        case 5:
3101
            check_insn(env, ctx, ISA_MIPS32R2);
3102
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3103
            rn = "SRSConf4";
3104
            break;
3105
        default:
3106
            goto die;
3107
        }
3108
        break;
3109
    case 7:
3110
        switch (sel) {
3111
        case 0:
3112
            check_insn(env, ctx, ISA_MIPS32R2);
3113
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3114
            rn = "HWREna";
3115
            break;
3116
        default:
3117
            goto die;
3118
        }
3119
        break;
3120
    case 8:
3121
        switch (sel) {
3122
        case 0:
3123
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3124
            tcg_gen_ext32s_tl(arg, arg);
3125
            rn = "BadVAddr";
3126
            break;
3127
        default:
3128
            goto die;
3129
       }
3130
        break;
3131
    case 9:
3132
        switch (sel) {
3133
        case 0:
3134
            /* Mark as an IO operation because we read the time.  */
3135
            if (use_icount)
3136
                gen_io_start();
3137
            gen_helper_mfc0_count(arg);
3138
            if (use_icount) {
3139
                gen_io_end();
3140
                ctx->bstate = BS_STOP;
3141
            }
3142
            rn = "Count";
3143
            break;
3144
        /* 6,7 are implementation dependent */
3145
        default:
3146
            goto die;
3147
        }
3148
        break;
3149
    case 10:
3150
        switch (sel) {
3151
        case 0:
3152
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3153
            tcg_gen_ext32s_tl(arg, arg);
3154
            rn = "EntryHi";
3155
            break;
3156
        default:
3157
            goto die;
3158
        }
3159
        break;
3160
    case 11:
3161
        switch (sel) {
3162
        case 0:
3163
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3164
            rn = "Compare";
3165
            break;
3166
        /* 6,7 are implementation dependent */
3167
        default:
3168
            goto die;
3169
        }
3170
        break;
3171
    case 12:
3172
        switch (sel) {
3173
        case 0:
3174
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3175
            rn = "Status";
3176
            break;
3177
        case 1:
3178
            check_insn(env, ctx, ISA_MIPS32R2);
3179
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3180
            rn = "IntCtl";
3181
            break;
3182
        case 2:
3183
            check_insn(env, ctx, ISA_MIPS32R2);
3184
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3185
            rn = "SRSCtl";
3186
            break;
3187
        case 3:
3188
            check_insn(env, ctx, ISA_MIPS32R2);
3189
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3190
            rn = "SRSMap";
3191
            break;
3192
        default:
3193
            goto die;
3194
       }
3195
        break;
3196
    case 13:
3197
        switch (sel) {
3198
        case 0:
3199
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3200
            rn = "Cause";
3201
            break;
3202
        default:
3203
            goto die;
3204
       }
3205
        break;
3206
    case 14:
3207
        switch (sel) {
3208
        case 0:
3209
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3210
            tcg_gen_ext32s_tl(arg, arg);
3211
            rn = "EPC";
3212
            break;
3213
        default:
3214
            goto die;
3215
        }
3216
        break;
3217
    case 15:
3218
        switch (sel) {
3219
        case 0:
3220
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3221
            rn = "PRid";
3222
            break;
3223
        case 1:
3224
            check_insn(env, ctx, ISA_MIPS32R2);
3225
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3226
            rn = "EBase";
3227
            break;
3228
        default:
3229
            goto die;
3230
       }
3231
        break;
3232
    case 16:
3233
        switch (sel) {
3234
        case 0:
3235
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3236
            rn = "Config";
3237
            break;
3238
        case 1:
3239
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3240
            rn = "Config1";
3241
            break;
3242
        case 2:
3243
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3244
            rn = "Config2";
3245
            break;
3246
        case 3:
3247
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3248
            rn = "Config3";
3249
            break;
3250
        /* 4,5 are reserved */
3251
        /* 6,7 are implementation dependent */
3252
        case 6:
3253
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3254
            rn = "Config6";
3255
            break;
3256
        case 7:
3257
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3258
            rn = "Config7";
3259
            break;
3260
        default:
3261
            goto die;
3262
        }
3263
        break;
3264
    case 17:
3265
        switch (sel) {
3266
        case 0:
3267
            gen_helper_mfc0_lladdr(arg);
3268
            rn = "LLAddr";
3269
            break;
3270
        default:
3271
            goto die;
3272
        }
3273
        break;
3274
    case 18:
3275
        switch (sel) {
3276
        case 0 ... 7:
3277
            gen_helper_1i(mfc0_watchlo, arg, sel);
3278
            rn = "WatchLo";
3279
            break;
3280
        default:
3281
            goto die;
3282
        }
3283
        break;
3284
    case 19:
3285
        switch (sel) {
3286
        case 0 ...7:
3287
            gen_helper_1i(mfc0_watchhi, arg, sel);
3288
            rn = "WatchHi";
3289
            break;
3290
        default:
3291
            goto die;
3292
        }
3293
        break;
3294
    case 20:
3295
        switch (sel) {
3296
        case 0:
3297
#if defined(TARGET_MIPS64)
3298
            check_insn(env, ctx, ISA_MIPS3);
3299
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3300
            tcg_gen_ext32s_tl(arg, arg);
3301
            rn = "XContext";
3302
            break;
3303
#endif
3304
        default:
3305
            goto die;
3306
        }
3307
        break;
3308
    case 21:
3309
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3310
        switch (sel) {
3311
        case 0:
3312
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3313
            rn = "Framemask";
3314
            break;
3315
        default:
3316
            goto die;
3317
        }
3318
        break;
3319
    case 22:
3320
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3321
        rn = "'Diagnostic"; /* implementation dependent */
3322
        break;
3323
    case 23:
3324
        switch (sel) {
3325
        case 0:
3326
            gen_helper_mfc0_debug(arg); /* EJTAG support */
3327
            rn = "Debug";
3328
            break;
3329
        case 1:
3330
//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3331
            rn = "TraceControl";
3332
//            break;
3333
        case 2:
3334
//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3335
            rn = "TraceControl2";
3336
//            break;
3337
        case 3:
3338
//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3339
            rn = "UserTraceData";
3340
//            break;
3341
        case 4:
3342
//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3343
            rn = "TraceBPC";
3344
//            break;
3345
        default:
3346
            goto die;
3347
        }
3348
        break;
3349
    case 24:
3350
        switch (sel) {
3351
        case 0:
3352
            /* EJTAG support */
3353
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3354
            tcg_gen_ext32s_tl(arg, arg);
3355
            rn = "DEPC";
3356
            break;
3357
        default:
3358
            goto die;
3359
        }
3360
        break;
3361
    case 25:
3362
        switch (sel) {
3363
        case 0:
3364
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3365
            rn = "Performance0";
3366
            break;
3367
        case 1:
3368
//            gen_helper_mfc0_performance1(arg);
3369
            rn = "Performance1";
3370
//            break;
3371
        case 2:
3372
//            gen_helper_mfc0_performance2(arg);
3373
            rn = "Performance2";
3374
//            break;
3375
        case 3:
3376
//            gen_helper_mfc0_performance3(arg);
3377
            rn = "Performance3";
3378
//            break;
3379
        case 4:
3380
//            gen_helper_mfc0_performance4(arg);
3381
            rn = "Performance4";
3382
//            break;
3383
        case 5:
3384
//            gen_helper_mfc0_performance5(arg);
3385
            rn = "Performance5";
3386
//            break;
3387
        case 6:
3388
//            gen_helper_mfc0_performance6(arg);
3389
            rn = "Performance6";
3390
//            break;
3391
        case 7:
3392
//            gen_helper_mfc0_performance7(arg);
3393
            rn = "Performance7";
3394
//            break;
3395
        default:
3396
            goto die;
3397
        }
3398
        break;
3399
    case 26:
3400
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3401
        rn = "ECC";
3402
        break;
3403
    case 27:
3404
        switch (sel) {
3405
        case 0 ... 3:
3406
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
3407
            rn = "CacheErr";
3408
            break;
3409
        default:
3410
            goto die;
3411
        }
3412
        break;
3413
    case 28:
3414
        switch (sel) {
3415
        case 0:
3416
        case 2:
3417
        case 4:
3418
        case 6:
3419
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3420
            rn = "TagLo";
3421
            break;
3422
        case 1:
3423
        case 3:
3424
        case 5:
3425
        case 7:
3426
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3427
            rn = "DataLo";
3428
            break;
3429
        default:
3430
            goto die;
3431
        }
3432
        break;
3433
    case 29:
3434
        switch (sel) {
3435
        case 0:
3436
        case 2:
3437
        case 4:
3438
        case 6:
3439
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3440
            rn = "TagHi";
3441
            break;
3442
        case 1:
3443
        case 3:
3444
        case 5:
3445
        case 7:
3446
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3447
            rn = "DataHi";
3448
            break;
3449
        default:
3450
            goto die;
3451
        }
3452
        break;
3453
    case 30:
3454
        switch (sel) {
3455
        case 0:
3456
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3457
            tcg_gen_ext32s_tl(arg, arg);
3458
            rn = "ErrorEPC";
3459
            break;
3460
        default:
3461
            goto die;
3462
        }
3463
        break;
3464
    case 31:
3465
        switch (sel) {
3466
        case 0:
3467
            /* EJTAG support */
3468
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3469
            rn = "DESAVE";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        break;
3475
    default:
3476
       goto die;
3477
    }
3478
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3479
    return;
3480

    
3481
die:
3482
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3483
    generate_exception(ctx, EXCP_RI);
3484
}
3485

    
3486
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3487
{
3488
    const char *rn = "invalid";
3489

    
3490
    if (sel != 0)
3491
        check_insn(env, ctx, ISA_MIPS32);
3492

    
3493
    if (use_icount)
3494
        gen_io_start();
3495

    
3496
    switch (reg) {
3497
    case 0:
3498
        switch (sel) {
3499
        case 0:
3500
            gen_helper_mtc0_index(arg);
3501
            rn = "Index";
3502
            break;
3503
        case 1:
3504
            check_insn(env, ctx, ASE_MT);
3505
            gen_helper_mtc0_mvpcontrol(arg);
3506
            rn = "MVPControl";
3507
            break;
3508
        case 2:
3509
            check_insn(env, ctx, ASE_MT);
3510
            /* ignored */
3511
            rn = "MVPConf0";
3512
            break;
3513
        case 3:
3514
            check_insn(env, ctx, ASE_MT);
3515
            /* ignored */
3516
            rn = "MVPConf1";
3517
            break;
3518
        default:
3519
            goto die;
3520
        }
3521
        break;
3522
    case 1:
3523
        switch (sel) {
3524
        case 0:
3525
            /* ignored */
3526
            rn = "Random";
3527
            break;
3528
        case 1:
3529
            check_insn(env, ctx, ASE_MT);
3530
            gen_helper_mtc0_vpecontrol(arg);
3531
            rn = "VPEControl";
3532
            break;
3533
        case 2:
3534
            check_insn(env, ctx, ASE_MT);
3535
            gen_helper_mtc0_vpeconf0(arg);
3536
            rn = "VPEConf0";
3537
            break;
3538
        case 3:
3539
            check_insn(env, ctx, ASE_MT);
3540
            gen_helper_mtc0_vpeconf1(arg);
3541
            rn = "VPEConf1";
3542
            break;
3543
        case 4:
3544
            check_insn(env, ctx, ASE_MT);
3545
            gen_helper_mtc0_yqmask(arg);
3546
            rn = "YQMask";
3547
            break;
3548
        case 5:
3549
            check_insn(env, ctx, ASE_MT);
3550
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3551
            rn = "VPESchedule";
3552
            break;
3553
        case 6:
3554
            check_insn(env, ctx, ASE_MT);
3555
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3556
            rn = "VPEScheFBack";
3557
            break;
3558
        case 7:
3559
            check_insn(env, ctx, ASE_MT);
3560
            gen_helper_mtc0_vpeopt(arg);
3561
            rn = "VPEOpt";
3562
            break;
3563
        default:
3564
            goto die;
3565
        }
3566
        break;
3567
    case 2:
3568
        switch (sel) {
3569
        case 0:
3570
            gen_helper_mtc0_entrylo0(arg);
3571
            rn = "EntryLo0";
3572
            break;
3573
        case 1:
3574
            check_insn(env, ctx, ASE_MT);
3575
            gen_helper_mtc0_tcstatus(arg);
3576
            rn = "TCStatus";
3577
            break;
3578
        case 2:
3579
            check_insn(env, ctx, ASE_MT);
3580
            gen_helper_mtc0_tcbind(arg);
3581
            rn = "TCBind";
3582
            break;
3583
        case 3:
3584
            check_insn(env, ctx, ASE_MT);
3585
            gen_helper_mtc0_tcrestart(arg);
3586
            rn = "TCRestart";
3587
            break;
3588
        case 4:
3589
            check_insn(env, ctx, ASE_MT);
3590
            gen_helper_mtc0_tchalt(arg);
3591
            rn = "TCHalt";
3592
            break;
3593
        case 5:
3594
            check_insn(env, ctx, ASE_MT);
3595
            gen_helper_mtc0_tccontext(arg);
3596
            rn = "TCContext";
3597
            break;
3598
        case 6:
3599
            check_insn(env, ctx, ASE_MT);
3600
            gen_helper_mtc0_tcschedule(arg);
3601
            rn = "TCSchedule";
3602
            break;
3603
        case 7:
3604
            check_insn(env, ctx, ASE_MT);
3605
            gen_helper_mtc0_tcschefback(arg);
3606
            rn = "TCScheFBack";
3607
            break;
3608
        default:
3609
            goto die;
3610
        }
3611
        break;
3612
    case 3:
3613
        switch (sel) {
3614
        case 0:
3615
            gen_helper_mtc0_entrylo1(arg);
3616
            rn = "EntryLo1";
3617
            break;
3618
        default:
3619
            goto die;
3620
        }
3621
        break;
3622
    case 4:
3623
        switch (sel) {
3624
        case 0:
3625
            gen_helper_mtc0_context(arg);
3626
            rn = "Context";
3627
            break;
3628
        case 1:
3629
//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3630
            rn = "ContextConfig";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 5:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_helper_mtc0_pagemask(arg);
3640
            rn = "PageMask";
3641
            break;
3642
        case 1:
3643
            check_insn(env, ctx, ISA_MIPS32R2);
3644
            gen_helper_mtc0_pagegrain(arg);
3645
            rn = "PageGrain";
3646
            break;
3647
        default:
3648
            goto die;
3649
        }
3650
        break;
3651
    case 6:
3652
        switch (sel) {
3653
        case 0:
3654
            gen_helper_mtc0_wired(arg);
3655
            rn = "Wired";
3656
            break;
3657
        case 1:
3658
            check_insn(env, ctx, ISA_MIPS32R2);
3659
            gen_helper_mtc0_srsconf0(arg);
3660
            rn = "SRSConf0";
3661
            break;
3662
        case 2:
3663
            check_insn(env, ctx, ISA_MIPS32R2);
3664
            gen_helper_mtc0_srsconf1(arg);
3665
            rn = "SRSConf1";
3666
            break;
3667
        case 3:
3668
            check_insn(env, ctx, ISA_MIPS32R2);
3669
            gen_helper_mtc0_srsconf2(arg);
3670
            rn = "SRSConf2";
3671
            break;
3672
        case 4:
3673
            check_insn(env, ctx, ISA_MIPS32R2);
3674
            gen_helper_mtc0_srsconf3(arg);
3675
            rn = "SRSConf3";
3676
            break;
3677
        case 5:
3678
            check_insn(env, ctx, ISA_MIPS32R2);
3679
            gen_helper_mtc0_srsconf4(arg);
3680
            rn = "SRSConf4";
3681
            break;
3682
        default:
3683
            goto die;
3684
        }
3685
        break;
3686
    case 7:
3687
        switch (sel) {
3688
        case 0:
3689
            check_insn(env, ctx, ISA_MIPS32R2);
3690
            gen_helper_mtc0_hwrena(arg);
3691
            rn = "HWREna";
3692
            break;
3693
        default:
3694
            goto die;
3695
        }
3696
        break;
3697
    case 8:
3698
        /* ignored */
3699
        rn = "BadVAddr";
3700
        break;
3701
    case 9:
3702
        switch (sel) {
3703
        case 0:
3704
            gen_helper_mtc0_count(arg);
3705
            rn = "Count";
3706
            break;
3707
        /* 6,7 are implementation dependent */
3708
        default:
3709
            goto die;
3710
        }
3711
        break;
3712
    case 10:
3713
        switch (sel) {
3714
        case 0:
3715
            gen_helper_mtc0_entryhi(arg);
3716
            rn = "EntryHi";
3717
            break;
3718
        default:
3719
            goto die;
3720
        }
3721
        break;
3722
    case 11:
3723
        switch (sel) {
3724
        case 0:
3725
            gen_helper_mtc0_compare(arg);
3726
            rn = "Compare";
3727
            break;
3728
        /* 6,7 are implementation dependent */
3729
        default:
3730
            goto die;
3731
        }
3732
        break;
3733
    case 12:
3734
        switch (sel) {
3735
        case 0:
3736
            save_cpu_state(ctx, 1);
3737
            gen_helper_mtc0_status(arg);
3738
            /* BS_STOP isn't good enough here, hflags may have changed. */
3739
            gen_save_pc(ctx->pc + 4);
3740
            ctx->bstate = BS_EXCP;
3741
            rn = "Status";
3742
            break;
3743
        case 1:
3744
            check_insn(env, ctx, ISA_MIPS32R2);
3745
            gen_helper_mtc0_intctl(arg);
3746
            /* Stop translation as we may have switched the execution mode */
3747
            ctx->bstate = BS_STOP;
3748
            rn = "IntCtl";
3749
            break;
3750
        case 2:
3751
            check_insn(env, ctx, ISA_MIPS32R2);
3752
            gen_helper_mtc0_srsctl(arg);
3753
            /* Stop translation as we may have switched the execution mode */
3754
            ctx->bstate = BS_STOP;
3755
            rn = "SRSCtl";
3756
            break;
3757
        case 3:
3758
            check_insn(env, ctx, ISA_MIPS32R2);
3759
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3760
            /* Stop translation as we may have switched the execution mode */
3761
            ctx->bstate = BS_STOP;
3762
            rn = "SRSMap";
3763
            break;
3764
        default:
3765
            goto die;
3766
        }
3767
        break;
3768
    case 13:
3769
        switch (sel) {
3770
        case 0:
3771
            save_cpu_state(ctx, 1);
3772
            gen_helper_mtc0_cause(arg);
3773
            rn = "Cause";
3774
            break;
3775
        default:
3776
            goto die;
3777
        }
3778
        break;
3779
    case 14:
3780
        switch (sel) {
3781
        case 0:
3782
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3783
            rn = "EPC";
3784
            break;
3785
        default:
3786
            goto die;
3787
        }
3788
        break;
3789
    case 15:
3790
        switch (sel) {
3791
        case 0:
3792
            /* ignored */
3793
            rn = "PRid";
3794
            break;
3795
        case 1:
3796
            check_insn(env, ctx, ISA_MIPS32R2);
3797
            gen_helper_mtc0_ebase(arg);
3798
            rn = "EBase";
3799
            break;
3800
        default:
3801
            goto die;
3802
        }
3803
        break;
3804
    case 16:
3805
        switch (sel) {
3806
        case 0:
3807
            gen_helper_mtc0_config0(arg);
3808
            rn = "Config";
3809
            /* Stop translation as we may have switched the execution mode */
3810
            ctx->bstate = BS_STOP;
3811
            break;
3812
        case 1:
3813
            /* ignored, read only */
3814
            rn = "Config1";
3815
            break;
3816
        case 2:
3817
            gen_helper_mtc0_config2(arg);
3818
            rn = "Config2";
3819
            /* Stop translation as we may have switched the execution mode */
3820
            ctx->bstate = BS_STOP;
3821
            break;
3822
        case 3:
3823
            /* ignored, read only */
3824
            rn = "Config3";
3825
            break;
3826
        /* 4,5 are reserved */
3827
        /* 6,7 are implementation dependent */
3828
        case 6:
3829
            /* ignored */
3830
            rn = "Config6";
3831
            break;
3832
        case 7:
3833
            /* ignored */
3834
            rn = "Config7";
3835
            break;
3836
        default:
3837
            rn = "Invalid config selector";
3838
            goto die;
3839
        }
3840
        break;
3841
    case 17:
3842
        switch (sel) {
3843
        case 0:
3844
            /* ignored */
3845
            rn = "LLAddr";
3846
            break;
3847
        default:
3848
            goto die;
3849
        }
3850
        break;
3851
    case 18:
3852
        switch (sel) {
3853
        case 0 ... 7:
3854
            gen_helper_1i(mtc0_watchlo, arg, sel);
3855
            rn = "WatchLo";
3856
            break;
3857
        default:
3858
            goto die;
3859
        }
3860
        break;
3861
    case 19:
3862
        switch (sel) {
3863
        case 0 ... 7:
3864
            gen_helper_1i(mtc0_watchhi, arg, sel);
3865
            rn = "WatchHi";
3866
            break;
3867
        default:
3868
            goto die;
3869
        }
3870
        break;
3871
    case 20:
3872
        switch (sel) {
3873
        case 0:
3874
#if defined(TARGET_MIPS64)
3875
            check_insn(env, ctx, ISA_MIPS3);
3876
            gen_helper_mtc0_xcontext(arg);
3877
            rn = "XContext";
3878
            break;
3879
#endif
3880
        default:
3881
            goto die;
3882
        }
3883
        break;
3884
    case 21:
3885
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3886
        switch (sel) {
3887
        case 0:
3888
            gen_helper_mtc0_framemask(arg);
3889
            rn = "Framemask";
3890
            break;
3891
        default:
3892
            goto die;
3893
        }
3894
        break;
3895
    case 22:
3896
        /* ignored */
3897
        rn = "Diagnostic"; /* implementation dependent */
3898
        break;
3899
    case 23:
3900
        switch (sel) {
3901
        case 0:
3902
            gen_helper_mtc0_debug(arg); /* EJTAG support */
3903
            /* BS_STOP isn't good enough here, hflags may have changed. */
3904
            gen_save_pc(ctx->pc + 4);
3905
            ctx->bstate = BS_EXCP;
3906
            rn = "Debug";
3907
            break;
3908
        case 1:
3909
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3910
            rn = "TraceControl";
3911
            /* Stop translation as we may have switched the execution mode */
3912
            ctx->bstate = BS_STOP;
3913
//            break;
3914
        case 2:
3915
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3916
            rn = "TraceControl2";
3917
            /* Stop translation as we may have switched the execution mode */
3918
            ctx->bstate = BS_STOP;
3919
//            break;
3920
        case 3:
3921
            /* Stop translation as we may have switched the execution mode */
3922
            ctx->bstate = BS_STOP;
3923
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3924
            rn = "UserTraceData";
3925
            /* Stop translation as we may have switched the execution mode */
3926
            ctx->bstate = BS_STOP;
3927
//            break;
3928
        case 4:
3929
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3930
            /* Stop translation as we may have switched the execution mode */
3931
            ctx->bstate = BS_STOP;
3932
            rn = "TraceBPC";
3933
//            break;
3934
        default:
3935
            goto die;
3936
        }
3937
        break;
3938
    case 24:
3939
        switch (sel) {
3940
        case 0:
3941
            /* EJTAG support */
3942
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3943
            rn = "DEPC";
3944
            break;
3945
        default:
3946
            goto die;
3947
        }
3948
        break;
3949
    case 25:
3950
        switch (sel) {
3951
        case 0:
3952
            gen_helper_mtc0_performance0(arg);
3953
            rn = "Performance0";
3954
            break;
3955
        case 1:
3956
//            gen_helper_mtc0_performance1(arg);
3957
            rn = "Performance1";
3958
//            break;
3959
        case 2:
3960
//            gen_helper_mtc0_performance2(arg);
3961
            rn = "Performance2";
3962
//            break;
3963
        case 3:
3964
//            gen_helper_mtc0_performance3(arg);
3965
            rn = "Performance3";
3966
//            break;
3967
        case 4:
3968
//            gen_helper_mtc0_performance4(arg);
3969
            rn = "Performance4";
3970
//            break;
3971
        case 5:
3972
//            gen_helper_mtc0_performance5(arg);
3973
            rn = "Performance5";
3974
//            break;
3975
        case 6:
3976
//            gen_helper_mtc0_performance6(arg);
3977
            rn = "Performance6";
3978
//            break;
3979
        case 7:
3980
//            gen_helper_mtc0_performance7(arg);
3981
            rn = "Performance7";
3982
//            break;
3983
        default:
3984
            goto die;
3985
        }
3986
       break;
3987
    case 26:
3988
        /* ignored */
3989
        rn = "ECC";
3990
        break;
3991
    case 27:
3992
        switch (sel) {
3993
        case 0 ... 3:
3994
            /* ignored */
3995
            rn = "CacheErr";
3996
            break;
3997
        default:
3998
            goto die;
3999
        }
4000
       break;
4001
    case 28:
4002
        switch (sel) {
4003
        case 0:
4004
        case 2:
4005
        case 4:
4006
        case 6:
4007
            gen_helper_mtc0_taglo(arg);
4008
            rn = "TagLo";
4009
            break;
4010
        case 1:
4011
        case 3:
4012
        case 5:
4013
        case 7:
4014
            gen_helper_mtc0_datalo(arg);
4015
            rn = "DataLo";
4016
            break;
4017
        default:
4018
            goto die;
4019
        }
4020
        break;
4021
    case 29:
4022
        switch (sel) {
4023
        case 0:
4024
        case 2:
4025
        case 4:
4026
        case 6:
4027
            gen_helper_mtc0_taghi(arg);
4028
            rn = "TagHi";
4029
            break;
4030
        case 1:
4031
        case 3:
4032
        case 5:
4033
        case 7:
4034
            gen_helper_mtc0_datahi(arg);
4035
            rn = "DataHi";
4036
            break;
4037
        default:
4038
            rn = "invalid sel";
4039
            goto die;
4040
        }
4041
       break;
4042
    case 30:
4043
        switch (sel) {
4044
        case 0:
4045
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4046
            rn = "ErrorEPC";
4047
            break;
4048
        default:
4049
            goto die;
4050
        }
4051
        break;
4052
    case 31:
4053
        switch (sel) {
4054
        case 0:
4055
            /* EJTAG support */
4056
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4057
            rn = "DESAVE";
4058
            break;
4059
        default:
4060
            goto die;
4061
        }
4062
        /* Stop translation as we may have switched the execution mode */
4063
        ctx->bstate = BS_STOP;
4064
        break;
4065
    default:
4066
       goto die;
4067
    }
4068
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4069
    /* For simplicity assume that all writes can cause interrupts.  */
4070
    if (use_icount) {
4071
        gen_io_end();
4072
        ctx->bstate = BS_STOP;
4073
    }
4074
    return;
4075

    
4076
die:
4077
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4078
    generate_exception(ctx, EXCP_RI);
4079
}
4080

    
4081
#if defined(TARGET_MIPS64)
4082
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4083
{
4084
    const char *rn = "invalid";
4085

    
4086
    if (sel != 0)
4087
        check_insn(env, ctx, ISA_MIPS64);
4088

    
4089
    switch (reg) {
4090
    case 0:
4091
        switch (sel) {
4092
        case 0:
4093
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4094
            rn = "Index";
4095
            break;
4096
        case 1:
4097
            check_insn(env, ctx, ASE_MT);
4098
            gen_helper_mfc0_mvpcontrol(arg);
4099
            rn = "MVPControl";
4100
            break;
4101
        case 2:
4102
            check_insn(env, ctx, ASE_MT);
4103
            gen_helper_mfc0_mvpconf0(arg);
4104
            rn = "MVPConf0";
4105
            break;
4106
        case 3:
4107
            check_insn(env, ctx, ASE_MT);
4108
            gen_helper_mfc0_mvpconf1(arg);
4109
            rn = "MVPConf1";
4110
            break;
4111
        default:
4112
            goto die;
4113
        }
4114
        break;
4115
    case 1:
4116
        switch (sel) {
4117
        case 0:
4118
            gen_helper_mfc0_random(arg);
4119
            rn = "Random";
4120
            break;
4121
        case 1:
4122
            check_insn(env, ctx, ASE_MT);
4123
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4124
            rn = "VPEControl";
4125
            break;
4126
        case 2:
4127
            check_insn(env, ctx, ASE_MT);
4128
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4129
            rn = "VPEConf0";
4130
            break;
4131
        case 3:
4132
            check_insn(env, ctx, ASE_MT);
4133
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4134
            rn = "VPEConf1";
4135
            break;
4136
        case 4:
4137
            check_insn(env, ctx, ASE_MT);
4138
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4139
            rn = "YQMask";
4140
            break;
4141
        case 5:
4142
            check_insn(env, ctx, ASE_MT);
4143
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4144
            rn = "VPESchedule";
4145
            break;
4146
        case 6:
4147
            check_insn(env, ctx, ASE_MT);
4148
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4149
            rn = "VPEScheFBack";
4150
            break;
4151
        case 7:
4152
            check_insn(env, ctx, ASE_MT);
4153
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4154
            rn = "VPEOpt";
4155
            break;
4156
        default:
4157
            goto die;
4158
        }
4159
        break;
4160
    case 2:
4161
        switch (sel) {
4162
        case 0:
4163
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4164
            rn = "EntryLo0";
4165
            break;
4166
        case 1:
4167
            check_insn(env, ctx, ASE_MT);
4168
            gen_helper_mfc0_tcstatus(arg);
4169
            rn = "TCStatus";
4170
            break;
4171
        case 2:
4172
            check_insn(env, ctx, ASE_MT);
4173
            gen_helper_mfc0_tcbind(arg);
4174
            rn = "TCBind";
4175
            break;
4176
        case 3:
4177
            check_insn(env, ctx, ASE_MT);
4178
            gen_helper_dmfc0_tcrestart(arg);
4179
            rn = "TCRestart";
4180
            break;
4181
        case 4:
4182
            check_insn(env, ctx, ASE_MT);
4183
            gen_helper_dmfc0_tchalt(arg);
4184
            rn = "TCHalt";
4185
            break;
4186
        case 5:
4187
            check_insn(env, ctx, ASE_MT);
4188
            gen_helper_dmfc0_tccontext(arg);
4189
            rn = "TCContext";
4190
            break;
4191
        case 6:
4192
            check_insn(env, ctx, ASE_MT);
4193
            gen_helper_dmfc0_tcschedule(arg);
4194
            rn = "TCSchedule";
4195
            break;
4196
        case 7:
4197
            check_insn(env, ctx, ASE_MT);
4198
            gen_helper_dmfc0_tcschefback(arg);
4199
            rn = "TCScheFBack";
4200
            break;
4201
        default:
4202
            goto die;
4203
        }
4204
        break;
4205
    case 3:
4206
        switch (sel) {
4207
        case 0:
4208
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4209
            rn = "EntryLo1";
4210
            break;
4211
        default:
4212
            goto die;
4213
        }
4214
        break;
4215
    case 4:
4216
        switch (sel) {
4217
        case 0:
4218
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4219
            rn = "Context";
4220
            break;
4221
        case 1:
4222
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4223
            rn = "ContextConfig";
4224
//            break;
4225
        default:
4226
            goto die;
4227
        }
4228
        break;
4229
    case 5:
4230
        switch (sel) {
4231
        case 0:
4232
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4233
            rn = "PageMask";
4234
            break;
4235
        case 1:
4236
            check_insn(env, ctx, ISA_MIPS32R2);
4237
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4238
            rn = "PageGrain";
4239
            break;
4240
        default:
4241
            goto die;
4242
        }
4243
        break;
4244
    case 6:
4245
        switch (sel) {
4246
        case 0:
4247
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4248
            rn = "Wired";
4249
            break;
4250
        case 1:
4251
            check_insn(env, ctx, ISA_MIPS32R2);
4252
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4253
            rn = "SRSConf0";
4254
            break;
4255
        case 2:
4256
            check_insn(env, ctx, ISA_MIPS32R2);
4257
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4258
            rn = "SRSConf1";
4259
            break;
4260
        case 3:
4261
            check_insn(env, ctx, ISA_MIPS32R2);
4262
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4263
            rn = "SRSConf2";
4264
            break;
4265
        case 4:
4266
            check_insn(env, ctx, ISA_MIPS32R2);
4267
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4268
            rn = "SRSConf3";
4269
            break;
4270
        case 5:
4271
            check_insn(env, ctx, ISA_MIPS32R2);
4272
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4273
            rn = "SRSConf4";
4274
            break;
4275
        default:
4276
            goto die;
4277
        }
4278
        break;
4279
    case 7:
4280
        switch (sel) {
4281
        case 0:
4282
            check_insn(env, ctx, ISA_MIPS32R2);
4283
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4284
            rn = "HWREna";
4285
            break;
4286
        default:
4287
            goto die;
4288
        }
4289
        break;
4290
    case 8:
4291
        switch (sel) {
4292
        case 0:
4293
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4294
            rn = "BadVAddr";
4295
            break;
4296
        default:
4297
            goto die;
4298
        }
4299
        break;
4300
    case 9:
4301
        switch (sel) {
4302
        case 0:
4303
            /* Mark as an IO operation because we read the time.  */
4304
            if (use_icount)
4305
                gen_io_start();
4306
            gen_helper_mfc0_count(arg);
4307
            if (use_icount) {
4308
                gen_io_end();
4309
                ctx->bstate = BS_STOP;
4310
            }
4311
            rn = "Count";
4312
            break;
4313
        /* 6,7 are implementation dependent */
4314
        default:
4315
            goto die;
4316
        }
4317
        break;
4318
    case 10:
4319
        switch (sel) {
4320
        case 0:
4321
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4322
            rn = "EntryHi";
4323
            break;
4324
        default:
4325
            goto die;
4326
        }
4327
        break;
4328
    case 11:
4329
        switch (sel) {
4330
        case 0:
4331
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4332
            rn = "Compare";
4333
            break;
4334
        /* 6,7 are implementation dependent */
4335
        default:
4336
            goto die;
4337
        }
4338
        break;
4339
    case 12:
4340
        switch (sel) {
4341
        case 0:
4342
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4343
            rn = "Status";
4344
            break;
4345
        case 1:
4346
            check_insn(env, ctx, ISA_MIPS32R2);
4347
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4348
            rn = "IntCtl";
4349
            break;
4350
        case 2:
4351
            check_insn(env, ctx, ISA_MIPS32R2);
4352
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4353
            rn = "SRSCtl";
4354
            break;
4355
        case 3:
4356
            check_insn(env, ctx, ISA_MIPS32R2);
4357
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4358
            rn = "SRSMap";
4359
            break;
4360
        default:
4361
            goto die;
4362
        }
4363
        break;
4364
    case 13:
4365
        switch (sel) {
4366
        case 0:
4367
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4368
            rn = "Cause";
4369
            break;
4370
        default:
4371
            goto die;
4372
        }
4373
        break;
4374
    case 14:
4375
        switch (sel) {
4376
        case 0:
4377
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4378
            rn = "EPC";
4379
            break;
4380
        default:
4381
            goto die;
4382
        }
4383
        break;
4384
    case 15:
4385
        switch (sel) {
4386
        case 0:
4387
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4388
            rn = "PRid";
4389
            break;
4390
        case 1:
4391
            check_insn(env, ctx, ISA_MIPS32R2);
4392
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4393
            rn = "EBase";
4394
            break;
4395
        default:
4396
            goto die;
4397
        }
4398
        break;
4399
    case 16:
4400
        switch (sel) {
4401
        case 0:
4402
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4403
            rn = "Config";
4404
            break;
4405
        case 1:
4406
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4407
            rn = "Config1";
4408
            break;
4409
        case 2:
4410
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4411
            rn = "Config2";
4412
            break;
4413
        case 3:
4414
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4415
            rn = "Config3";
4416
            break;
4417
       /* 6,7 are implementation dependent */
4418
        case 6:
4419
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4420
            rn = "Config6";
4421
            break;
4422
        case 7:
4423
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4424
            rn = "Config7";
4425
            break;
4426
        default:
4427
            goto die;
4428
        }
4429
        break;
4430
    case 17:
4431
        switch (sel) {
4432
        case 0:
4433
            gen_helper_dmfc0_lladdr(arg);
4434
            rn = "LLAddr";
4435
            break;
4436
        default:
4437
            goto die;
4438
        }
4439
        break;
4440
    case 18:
4441
        switch (sel) {
4442
        case 0 ... 7:
4443
            gen_helper_1i(dmfc0_watchlo, arg, sel);
4444
            rn = "WatchLo";
4445
            break;
4446
        default:
4447
            goto die;
4448
        }
4449
        break;
4450
    case 19:
4451
        switch (sel) {
4452
        case 0 ... 7:
4453
            gen_helper_1i(mfc0_watchhi, arg, sel);
4454
            rn = "WatchHi";
4455
            break;
4456
        default:
4457
            goto die;
4458
        }
4459
        break;
4460
    case 20:
4461
        switch (sel) {
4462
        case 0:
4463
            check_insn(env, ctx, ISA_MIPS3);
4464
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4465
            rn = "XContext";
4466
            break;
4467
        default:
4468
            goto die;
4469
        }
4470
        break;
4471
    case 21:
4472
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4473
        switch (sel) {
4474
        case 0:
4475
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4476
            rn = "Framemask";
4477
            break;
4478
        default:
4479
            goto die;
4480
        }
4481
        break;
4482
    case 22:
4483
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4484
        rn = "'Diagnostic"; /* implementation dependent */
4485
        break;
4486
    case 23:
4487
        switch (sel) {
4488
        case 0:
4489
            gen_helper_mfc0_debug(arg); /* EJTAG support */
4490
            rn = "Debug";
4491
            break;
4492
        case 1:
4493
//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4494
            rn = "TraceControl";
4495
//            break;
4496
        case 2:
4497
//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4498
            rn = "TraceControl2";
4499
//            break;
4500
        case 3:
4501
//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4502
            rn = "UserTraceData";
4503
//            break;
4504
        case 4:
4505
//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4506
            rn = "TraceBPC";
4507
//            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    case 24:
4513
        switch (sel) {
4514
        case 0:
4515
            /* EJTAG support */
4516
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4517
            rn = "DEPC";
4518
            break;
4519
        default:
4520
            goto die;
4521
        }
4522
        break;
4523
    case 25:
4524
        switch (sel) {
4525
        case 0:
4526
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4527
            rn = "Performance0";
4528
            break;
4529
        case 1:
4530
//            gen_helper_dmfc0_performance1(arg);
4531
            rn = "Performance1";
4532
//            break;
4533
        case 2:
4534
//            gen_helper_dmfc0_performance2(arg);
4535
            rn = "Performance2";
4536
//            break;
4537
        case 3:
4538
//            gen_helper_dmfc0_performance3(arg);
4539
            rn = "Performance3";
4540
//            break;
4541
        case 4:
4542
//            gen_helper_dmfc0_performance4(arg);
4543
            rn = "Performance4";
4544
//            break;
4545
        case 5:
4546
//            gen_helper_dmfc0_performance5(arg);
4547
            rn = "Performance5";
4548
//            break;
4549
        case 6:
4550
//            gen_helper_dmfc0_performance6(arg);
4551
            rn = "Performance6";
4552
//            break;
4553
        case 7:
4554
//            gen_helper_dmfc0_performance7(arg);
4555
            rn = "Performance7";
4556
//            break;
4557
        default:
4558
            goto die;
4559
        }
4560
        break;
4561
    case 26:
4562
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4563
        rn = "ECC";
4564
        break;
4565
    case 27:
4566
        switch (sel) {
4567
        /* ignored */
4568
        case 0 ... 3:
4569
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4570
            rn = "CacheErr";
4571
            break;
4572
        default:
4573
            goto die;
4574
        }
4575
        break;
4576
    case 28:
4577
        switch (sel) {
4578
        case 0:
4579
        case 2:
4580
        case 4:
4581
        case 6:
4582
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4583
            rn = "TagLo";
4584
            break;
4585
        case 1:
4586
        case 3:
4587
        case 5:
4588
        case 7:
4589
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4590
            rn = "DataLo";
4591
            break;
4592
        default:
4593
            goto die;
4594
        }
4595
        break;
4596
    case 29:
4597
        switch (sel) {
4598
        case 0:
4599
        case 2:
4600
        case 4:
4601
        case 6:
4602
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4603
            rn = "TagHi";
4604
            break;
4605
        case 1:
4606
        case 3:
4607
        case 5:
4608
        case 7:
4609
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4610
            rn = "DataHi";
4611
            break;
4612
        default:
4613
            goto die;
4614
        }
4615
        break;
4616
    case 30:
4617
        switch (sel) {
4618
        case 0:
4619
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4620
            rn = "ErrorEPC";
4621
            break;
4622
        default:
4623
            goto die;
4624
        }
4625
        break;
4626
    case 31:
4627
        switch (sel) {
4628
        case 0:
4629
            /* EJTAG support */
4630
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4631
            rn = "DESAVE";
4632
            break;
4633
        default:
4634
            goto die;
4635
        }
4636
        break;
4637
    default:
4638
        goto die;
4639
    }
4640
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4641
    return;
4642

    
4643
die:
4644
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4645
    generate_exception(ctx, EXCP_RI);
4646
}
4647

    
4648
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4649
{
4650
    const char *rn = "invalid";
4651

    
4652
    if (sel != 0)
4653
        check_insn(env, ctx, ISA_MIPS64);
4654

    
4655
    if (use_icount)
4656
        gen_io_start();
4657

    
4658
    switch (reg) {
4659
    case 0:
4660
        switch (sel) {
4661
        case 0:
4662
            gen_helper_mtc0_index(arg);
4663
            rn = "Index";
4664
            break;
4665
        case 1:
4666
            check_insn(env, ctx, ASE_MT);
4667
            gen_helper_mtc0_mvpcontrol(arg);
4668
            rn = "MVPControl";
4669
            break;
4670
        case 2:
4671
            check_insn(env, ctx, ASE_MT);
4672
            /* ignored */
4673
            rn = "MVPConf0";
4674
            break;
4675
        case 3:
4676
            check_insn(env, ctx, ASE_MT);
4677
            /* ignored */
4678
            rn = "MVPConf1";
4679
            break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    case 1:
4685
        switch (sel) {
4686
        case 0:
4687
            /* ignored */
4688
            rn = "Random";
4689
            break;
4690
        case 1:
4691
            check_insn(env, ctx, ASE_MT);
4692
            gen_helper_mtc0_vpecontrol(arg);
4693
            rn = "VPEControl";
4694
            break;
4695
        case 2:
4696
            check_insn(env, ctx, ASE_MT);
4697
            gen_helper_mtc0_vpeconf0(arg);
4698
            rn = "VPEConf0";
4699
            break;
4700
        case 3:
4701
            check_insn(env, ctx, ASE_MT);
4702
            gen_helper_mtc0_vpeconf1(arg);
4703
            rn = "VPEConf1";
4704
            break;
4705
        case 4:
4706
            check_insn(env, ctx, ASE_MT);
4707
            gen_helper_mtc0_yqmask(