Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 72cf2d4f

History | View | Annotate | Download (250.6 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, /* inofficial */
191
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
192
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
193
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
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
    /* Routine used to access memory */
467
    int mem_idx;
468
    uint32_t hflags, saved_hflags;
469
    int bstate;
470
    target_ulong btarget;
471
} DisasContext;
472

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
804
/* Addresses computation */
805
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
806
{
807
    tcg_gen_add_tl(t0, t0, t1);
808

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1157
    t0 = tcg_temp_local_new();
1158

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2458
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2459
{
2460
    TranslationBlock *tb;
2461
    tb = ctx->tb;
2462
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2463
        tcg_gen_goto_tb(n);
2464
        gen_save_pc(dest);
2465
        tcg_gen_exit_tb((long)tb + n);
2466
    } else {
2467
        gen_save_pc(dest);
2468
        tcg_gen_exit_tb(0);
2469
    }
2470
}
2471

    
2472
/* Branches (before delay slot) */
2473
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2474
                                int rs, int rt, int32_t offset)
2475
{
2476
    target_ulong btgt = -1;
2477
    int blink = 0;
2478
    int bcond_compute = 0;
2479
    TCGv t0 = tcg_temp_new();
2480
    TCGv t1 = tcg_temp_new();
2481

    
2482
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2483
#ifdef MIPS_DEBUG_DISAS
2484
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2485
#endif
2486
        generate_exception(ctx, EXCP_RI);
2487
        goto out;
2488
    }
2489

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

    
2698
    ctx->btarget = btgt;
2699
    if (blink > 0) {
2700
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2701
    }
2702

    
2703
 out:
2704
    tcg_temp_free(t0);
2705
    tcg_temp_free(t1);
2706
}
2707

    
2708
/* special3 bitfield operations */
2709
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2710
                        int rs, int lsb, int msb)
2711
{
2712
    TCGv t0 = tcg_temp_new();
2713
    TCGv t1 = tcg_temp_new();
2714
    target_ulong mask;
2715

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

    
2801
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2802
{
2803
    TCGv t0;
2804

    
2805
    if (rd == 0) {
2806
        /* If no destination, treat it as a NOP. */
2807
        MIPS_DEBUG("NOP");
2808
        return;
2809
    }
2810

    
2811
    t0 = tcg_temp_new();
2812
    gen_load_gpr(t0, rt);
2813
    switch (op2) {
2814
    case OPC_WSBH:
2815
        {
2816
            TCGv t1 = tcg_temp_new();
2817

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

    
2838
            tcg_gen_shri_tl(t1, t0, 8);
2839
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2840
            tcg_gen_shli_tl(t0, t0, 8);
2841
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2842
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2843
            tcg_temp_free(t1);
2844
        }
2845
        break;
2846
    case OPC_DSHD:
2847
        {
2848
            TCGv t1 = tcg_temp_new();
2849

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

    
2871
#ifndef CONFIG_USER_ONLY
2872
/* CP0 (MMU and control) */
2873
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2874
{
2875
    TCGv_i32 t0 = tcg_temp_new_i32();
2876

    
2877
    tcg_gen_ld_i32(t0, cpu_env, off);
2878
    tcg_gen_ext_i32_tl(arg, t0);
2879
    tcg_temp_free_i32(t0);
2880
}
2881

    
2882
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2883
{
2884
    tcg_gen_ld_tl(arg, cpu_env, off);
2885
    tcg_gen_ext32s_tl(arg, arg);
2886
}
2887

    
2888
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2889
{
2890
    TCGv_i32 t0 = tcg_temp_new_i32();
2891

    
2892
    tcg_gen_trunc_tl_i32(t0, arg);
2893
    tcg_gen_st_i32(t0, cpu_env, off);
2894
    tcg_temp_free_i32(t0);
2895
}
2896

    
2897
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2898
{
2899
    tcg_gen_ext32s_tl(arg, arg);
2900
    tcg_gen_st_tl(arg, cpu_env, off);
2901
}
2902

    
2903
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2904
{
2905
    const char *rn = "invalid";
2906

    
2907
    if (sel != 0)
2908
        check_insn(env, ctx, ISA_MIPS32);
2909

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

    
3475
die:
3476
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3477
    generate_exception(ctx, EXCP_RI);
3478
}
3479

    
3480
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3481
{
3482
    const char *rn = "invalid";
3483

    
3484
    if (sel != 0)
3485
        check_insn(env, ctx, ISA_MIPS32);
3486

    
3487
    if (use_icount)
3488
        gen_io_start();
3489

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

    
4070
die:
4071
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4072
    generate_exception(ctx, EXCP_RI);
4073
}
4074

    
4075
#if defined(TARGET_MIPS64)
4076
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4077
{
4078
    const char *rn = "invalid";
4079

    
4080
    if (sel != 0)
4081
        check_insn(env, ctx, ISA_MIPS64);
4082

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

    
4637
die:
4638
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4639
    generate_exception(ctx, EXCP_RI);
4640
}
4641

    
4642
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4643
{
4644
    const char *rn = "invalid";
4645

    
4646
    if (sel != 0)
4647
        check_insn(env, ctx, ISA_MIPS64);
4648

    
4649
    if (use_icount)
4650
        gen_io_start();
4651

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