Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a7200c9f

History | View | Annotate | Download (281.8 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *  Copyright (c) 2009 CodeSourcery (MIPS16 support)
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21
 */
22

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

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

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

    
39
//#define MIPS_DEBUG_DISAS
40
//#define MIPS_DEBUG_SIGN_EXTENSIONS
41

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

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

    
124
/* MIPS special opcodes */
125
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
126

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

    
196
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
197

    
198
    /* Special */
199
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
200
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
201
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
202
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
203
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
204

    
205
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
206
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
207
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
208
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
209
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
210
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
211
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
212
};
213

    
214
/* Multiplication variants of the vr54xx. */
215
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
216

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

    
234
/* REGIMM (rt field) opcodes */
235
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
236

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

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

    
258
enum {
259
    /* Multiply & xxx operations */
260
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
261
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
262
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
263
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
264
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
265
    /* Misc */
266
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
267
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
268
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
269
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
270
    /* Special */
271
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
272
};
273

    
274
/* Special3 opcodes */
275
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
276

    
277
enum {
278
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
279
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
280
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
281
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
282
    OPC_INS      = 0x04 | OPC_SPECIAL3,
283
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
284
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
285
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
286
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
287
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
288
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
289
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
290
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
291
};
292

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

    
296
enum {
297
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
298
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
299
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
300
};
301

    
302
/* DBSHFL opcodes */
303
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
304

    
305
enum {
306
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
307
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
308
};
309

    
310
/* Coprocessor 0 (rs field) */
311
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
312

    
313
enum {
314
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
315
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
316
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
317
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
318
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
319
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
320
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
321
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
322
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
323
    OPC_C0       = (0x10 << 21) | OPC_CP0,
324
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
325
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
326
};
327

    
328
/* MFMC0 opcodes */
329
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
330

    
331
enum {
332
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
333
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
334
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
335
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
336
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
337
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
338
};
339

    
340
/* Coprocessor 0 (with rs == C0) */
341
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
342

    
343
enum {
344
    OPC_TLBR     = 0x01 | OPC_C0,
345
    OPC_TLBWI    = 0x02 | OPC_C0,
346
    OPC_TLBWR    = 0x06 | OPC_C0,
347
    OPC_TLBP     = 0x08 | OPC_C0,
348
    OPC_RFE      = 0x10 | OPC_C0,
349
    OPC_ERET     = 0x18 | OPC_C0,
350
    OPC_DERET    = 0x1F | OPC_C0,
351
    OPC_WAIT     = 0x20 | OPC_C0,
352
};
353

    
354
/* Coprocessor 1 (rs field) */
355
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
356

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

    
378
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
379
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
380

    
381
enum {
382
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
383
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
384
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
385
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
386
};
387

    
388
enum {
389
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
390
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
391
};
392

    
393
enum {
394
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
395
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
396
};
397

    
398
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
399

    
400
enum {
401
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
402
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
403
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
404
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
405
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
406
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
407
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
408
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
409
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
410
};
411

    
412
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
413

    
414
enum {
415
    OPC_LWXC1   = 0x00 | OPC_CP3,
416
    OPC_LDXC1   = 0x01 | OPC_CP3,
417
    OPC_LUXC1   = 0x05 | OPC_CP3,
418
    OPC_SWXC1   = 0x08 | OPC_CP3,
419
    OPC_SDXC1   = 0x09 | OPC_CP3,
420
    OPC_SUXC1   = 0x0D | OPC_CP3,
421
    OPC_PREFX   = 0x0F | OPC_CP3,
422
    OPC_ALNV_PS = 0x1E | OPC_CP3,
423
    OPC_MADD_S  = 0x20 | OPC_CP3,
424
    OPC_MADD_D  = 0x21 | OPC_CP3,
425
    OPC_MADD_PS = 0x26 | OPC_CP3,
426
    OPC_MSUB_S  = 0x28 | OPC_CP3,
427
    OPC_MSUB_D  = 0x29 | OPC_CP3,
428
    OPC_MSUB_PS = 0x2E | OPC_CP3,
429
    OPC_NMADD_S = 0x30 | OPC_CP3,
430
    OPC_NMADD_D = 0x31 | OPC_CP3,
431
    OPC_NMADD_PS= 0x36 | OPC_CP3,
432
    OPC_NMSUB_S = 0x38 | OPC_CP3,
433
    OPC_NMSUB_D = 0x39 | OPC_CP3,
434
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
435
};
436

    
437
/* global register indices */
438
static TCGv_ptr cpu_env;
439
static TCGv cpu_gpr[32], cpu_PC;
440
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
441
static TCGv cpu_dspctrl, btarget, bcond;
442
static TCGv_i32 hflags;
443
static TCGv_i32 fpu_fcr0, fpu_fcr31;
444

    
445
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
446

    
447
#include "gen-icount.h"
448

    
449
#define gen_helper_0i(name, arg) do {                             \
450
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
451
    gen_helper_##name(helper_tmp);                                \
452
    tcg_temp_free_i32(helper_tmp);                                \
453
    } while(0)
454

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

    
461
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
462
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
463
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
464
    tcg_temp_free_i32(helper_tmp);                                \
465
    } while(0)
466

    
467
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
468
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
469
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
470
    tcg_temp_free_i32(helper_tmp);                                \
471
    } while(0)
472

    
473
typedef struct DisasContext {
474
    struct TranslationBlock *tb;
475
    target_ulong pc, saved_pc;
476
    uint32_t opcode;
477
    int singlestep_enabled;
478
    /* Routine used to access memory */
479
    int mem_idx;
480
    uint32_t hflags, saved_hflags;
481
    int bstate;
482
    target_ulong btarget;
483
} DisasContext;
484

    
485
enum {
486
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
487
                      * exception condition */
488
    BS_STOP     = 1, /* We want to stop translation for any reason */
489
    BS_BRANCH   = 2, /* We reached a branch condition     */
490
    BS_EXCP     = 3, /* We reached an exception condition */
491
};
492

    
493
static const char *regnames[] =
494
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
495
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
496
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
497
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
498

    
499
static const char *regnames_HI[] =
500
    { "HI0", "HI1", "HI2", "HI3", };
501

    
502
static const char *regnames_LO[] =
503
    { "LO0", "LO1", "LO2", "LO3", };
504

    
505
static const char *regnames_ACX[] =
506
    { "ACX0", "ACX1", "ACX2", "ACX3", };
507

    
508
static const char *fregnames[] =
509
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
510
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
511
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
512
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
513

    
514
#ifdef MIPS_DEBUG_DISAS
515
#define MIPS_DEBUG(fmt, ...)                         \
516
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
517
                       TARGET_FMT_lx ": %08x " fmt "\n", \
518
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
519
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
520
#else
521
#define MIPS_DEBUG(fmt, ...) do { } while(0)
522
#define LOG_DISAS(...) do { } while (0)
523
#endif
524

    
525
#define MIPS_INVAL(op)                                                        \
526
do {                                                                          \
527
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
528
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
529
} while (0)
530

    
531
/* General purpose registers moves. */
532
static inline void gen_load_gpr (TCGv t, int reg)
533
{
534
    if (reg == 0)
535
        tcg_gen_movi_tl(t, 0);
536
    else
537
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
538
}
539

    
540
static inline void gen_store_gpr (TCGv t, int reg)
541
{
542
    if (reg != 0)
543
        tcg_gen_mov_tl(cpu_gpr[reg], t);
544
}
545

    
546
/* Moves to/from ACX register.  */
547
static inline void gen_load_ACX (TCGv t, int reg)
548
{
549
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
550
}
551

    
552
static inline void gen_store_ACX (TCGv t, int reg)
553
{
554
    tcg_gen_mov_tl(cpu_ACX[reg], t);
555
}
556

    
557
/* Moves to/from shadow registers. */
558
static inline void gen_load_srsgpr (int from, int to)
559
{
560
    TCGv t0 = tcg_temp_new();
561

    
562
    if (from == 0)
563
        tcg_gen_movi_tl(t0, 0);
564
    else {
565
        TCGv_i32 t2 = tcg_temp_new_i32();
566
        TCGv_ptr addr = tcg_temp_new_ptr();
567

    
568
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
569
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
570
        tcg_gen_andi_i32(t2, t2, 0xf);
571
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
572
        tcg_gen_ext_i32_ptr(addr, t2);
573
        tcg_gen_add_ptr(addr, cpu_env, addr);
574

    
575
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
576
        tcg_temp_free_ptr(addr);
577
        tcg_temp_free_i32(t2);
578
    }
579
    gen_store_gpr(t0, to);
580
    tcg_temp_free(t0);
581
}
582

    
583
static inline void gen_store_srsgpr (int from, int to)
584
{
585
    if (to != 0) {
586
        TCGv t0 = tcg_temp_new();
587
        TCGv_i32 t2 = tcg_temp_new_i32();
588
        TCGv_ptr addr = tcg_temp_new_ptr();
589

    
590
        gen_load_gpr(t0, from);
591
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
592
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
593
        tcg_gen_andi_i32(t2, t2, 0xf);
594
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
595
        tcg_gen_ext_i32_ptr(addr, t2);
596
        tcg_gen_add_ptr(addr, cpu_env, addr);
597

    
598
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
599
        tcg_temp_free_ptr(addr);
600
        tcg_temp_free_i32(t2);
601
        tcg_temp_free(t0);
602
    }
603
}
604

    
605
/* Floating point register moves. */
606
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
607
{
608
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
609
}
610

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

    
616
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
617
{
618
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
619
}
620

    
621
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
622
{
623
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
624
}
625

    
626
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
627
{
628
    if (ctx->hflags & MIPS_HFLAG_F64) {
629
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
630
    } else {
631
        TCGv_i32 t0 = tcg_temp_new_i32();
632
        TCGv_i32 t1 = tcg_temp_new_i32();
633
        gen_load_fpr32(t0, reg & ~1);
634
        gen_load_fpr32(t1, reg | 1);
635
        tcg_gen_concat_i32_i64(t, t0, t1);
636
        tcg_temp_free_i32(t0);
637
        tcg_temp_free_i32(t1);
638
    }
639
}
640

    
641
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
642
{
643
    if (ctx->hflags & MIPS_HFLAG_F64) {
644
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
645
    } else {
646
        TCGv_i64 t0 = tcg_temp_new_i64();
647
        TCGv_i32 t1 = tcg_temp_new_i32();
648
        tcg_gen_trunc_i64_i32(t1, t);
649
        gen_store_fpr32(t1, reg & ~1);
650
        tcg_gen_shri_i64(t0, t, 32);
651
        tcg_gen_trunc_i64_i32(t1, t0);
652
        gen_store_fpr32(t1, reg | 1);
653
        tcg_temp_free_i32(t1);
654
        tcg_temp_free_i64(t0);
655
    }
656
}
657

    
658
static inline int get_fp_bit (int cc)
659
{
660
    if (cc)
661
        return 24 + cc;
662
    else
663
        return 23;
664
}
665

    
666
#define FOP_CONDS(type, fmt, bits)                                            \
667
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
668
                                               TCGv_i##bits b, int cc)        \
669
{                                                                             \
670
    switch (n) {                                                              \
671
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
672
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
673
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
674
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
675
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
676
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
677
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
678
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
679
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
680
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
681
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
682
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
683
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
684
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
685
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
686
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
687
    default: abort();                                                         \
688
    }                                                                         \
689
}
690

    
691
FOP_CONDS(, d, 64)
692
FOP_CONDS(abs, d, 64)
693
FOP_CONDS(, s, 32)
694
FOP_CONDS(abs, s, 32)
695
FOP_CONDS(, ps, 64)
696
FOP_CONDS(abs, ps, 64)
697
#undef FOP_CONDS
698

    
699
/* Tests */
700
static inline void gen_save_pc(target_ulong pc)
701
{
702
    tcg_gen_movi_tl(cpu_PC, pc);
703
}
704

    
705
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
706
{
707
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
708
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
709
        gen_save_pc(ctx->pc);
710
        ctx->saved_pc = ctx->pc;
711
    }
712
    if (ctx->hflags != ctx->saved_hflags) {
713
        tcg_gen_movi_i32(hflags, ctx->hflags);
714
        ctx->saved_hflags = ctx->hflags;
715
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
716
        case MIPS_HFLAG_BR:
717
            break;
718
        case MIPS_HFLAG_BC:
719
        case MIPS_HFLAG_BL:
720
        case MIPS_HFLAG_B:
721
            tcg_gen_movi_tl(btarget, ctx->btarget);
722
            break;
723
        }
724
    }
725
}
726

    
727
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
728
{
729
    ctx->saved_hflags = ctx->hflags;
730
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
731
    case MIPS_HFLAG_BR:
732
        break;
733
    case MIPS_HFLAG_BC:
734
    case MIPS_HFLAG_BL:
735
    case MIPS_HFLAG_B:
736
        ctx->btarget = env->btarget;
737
        break;
738
    }
739
}
740

    
741
static inline void
742
generate_exception_err (DisasContext *ctx, int excp, int err)
743
{
744
    TCGv_i32 texcp = tcg_const_i32(excp);
745
    TCGv_i32 terr = tcg_const_i32(err);
746
    save_cpu_state(ctx, 1);
747
    gen_helper_raise_exception_err(texcp, terr);
748
    tcg_temp_free_i32(terr);
749
    tcg_temp_free_i32(texcp);
750
}
751

    
752
static inline void
753
generate_exception (DisasContext *ctx, int excp)
754
{
755
    save_cpu_state(ctx, 1);
756
    gen_helper_0i(raise_exception, excp);
757
}
758

    
759
/* Addresses computation */
760
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
761
{
762
    tcg_gen_add_tl(ret, arg0, arg1);
763

    
764
#if defined(TARGET_MIPS64)
765
    /* For compatibility with 32-bit code, data reference in user mode
766
       with Status_UX = 0 should be casted to 32-bit and sign extended.
767
       See the MIPS64 PRA manual, section 4.10. */
768
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
769
        !(ctx->hflags & MIPS_HFLAG_UX)) {
770
        tcg_gen_ext32s_i64(ret, ret);
771
    }
772
#endif
773
}
774

    
775
static inline void check_cp0_enabled(DisasContext *ctx)
776
{
777
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
778
        generate_exception_err(ctx, EXCP_CpU, 0);
779
}
780

    
781
static inline void check_cp1_enabled(DisasContext *ctx)
782
{
783
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
784
        generate_exception_err(ctx, EXCP_CpU, 1);
785
}
786

    
787
/* Verify that the processor is running with COP1X instructions enabled.
788
   This is associated with the nabla symbol in the MIPS32 and MIPS64
789
   opcode tables.  */
790

    
791
static inline void check_cop1x(DisasContext *ctx)
792
{
793
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
794
        generate_exception(ctx, EXCP_RI);
795
}
796

    
797
/* Verify that the processor is running with 64-bit floating-point
798
   operations enabled.  */
799

    
800
static inline void check_cp1_64bitmode(DisasContext *ctx)
801
{
802
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
803
        generate_exception(ctx, EXCP_RI);
804
}
805

    
806
/*
807
 * Verify if floating point register is valid; an operation is not defined
808
 * if bit 0 of any register specification is set and the FR bit in the
809
 * Status register equals zero, since the register numbers specify an
810
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
811
 * in the Status register equals one, both even and odd register numbers
812
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
813
 *
814
 * Multiple 64 bit wide registers can be checked by calling
815
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
816
 */
817
static inline void check_cp1_registers(DisasContext *ctx, int regs)
818
{
819
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
820
        generate_exception(ctx, EXCP_RI);
821
}
822

    
823
/* This code generates a "reserved instruction" exception if the
824
   CPU does not support the instruction set corresponding to flags. */
825
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
826
{
827
    if (unlikely(!(env->insn_flags & flags)))
828
        generate_exception(ctx, EXCP_RI);
829
}
830

    
831
/* This code generates a "reserved instruction" exception if 64-bit
832
   instructions are not enabled. */
833
static inline void check_mips_64(DisasContext *ctx)
834
{
835
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
836
        generate_exception(ctx, EXCP_RI);
837
}
838

    
839
/* load/store instructions. */
840
#define OP_LD(insn,fname)                                                 \
841
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
842
{                                                                         \
843
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
844
}
845
OP_LD(lb,ld8s);
846
OP_LD(lbu,ld8u);
847
OP_LD(lh,ld16s);
848
OP_LD(lhu,ld16u);
849
OP_LD(lw,ld32s);
850
#if defined(TARGET_MIPS64)
851
OP_LD(lwu,ld32u);
852
OP_LD(ld,ld64);
853
#endif
854
#undef OP_LD
855

    
856
#define OP_ST(insn,fname)                                                  \
857
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
858
{                                                                          \
859
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
860
}
861
OP_ST(sb,st8);
862
OP_ST(sh,st16);
863
OP_ST(sw,st32);
864
#if defined(TARGET_MIPS64)
865
OP_ST(sd,st64);
866
#endif
867
#undef OP_ST
868

    
869
#ifdef CONFIG_USER_ONLY
870
#define OP_LD_ATOMIC(insn,fname)                                           \
871
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
872
{                                                                          \
873
    TCGv t0 = tcg_temp_new();                                              \
874
    tcg_gen_mov_tl(t0, arg1);                                              \
875
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
876
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
877
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
878
    tcg_temp_free(t0);                                                     \
879
}
880
#else
881
#define OP_LD_ATOMIC(insn,fname)                                           \
882
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
883
{                                                                          \
884
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
885
}
886
#endif
887
OP_LD_ATOMIC(ll,ld32s);
888
#if defined(TARGET_MIPS64)
889
OP_LD_ATOMIC(lld,ld64);
890
#endif
891
#undef OP_LD_ATOMIC
892

    
893
#ifdef CONFIG_USER_ONLY
894
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
895
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
896
{                                                                            \
897
    TCGv t0 = tcg_temp_new();                                                \
898
    int l1 = gen_new_label();                                                \
899
    int l2 = gen_new_label();                                                \
900
                                                                             \
901
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
902
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
903
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
904
    generate_exception(ctx, EXCP_AdES);                                      \
905
    gen_set_label(l1);                                                       \
906
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
907
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
908
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
909
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
910
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
911
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
912
    gen_set_label(l2);                                                       \
913
    tcg_gen_movi_tl(t0, 0);                                                  \
914
    gen_store_gpr(t0, rt);                                                   \
915
    tcg_temp_free(t0);                                                       \
916
}
917
#else
918
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
919
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
920
{                                                                            \
921
    TCGv t0 = tcg_temp_new();                                                \
922
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
923
    gen_store_gpr(t0, rt);                                                   \
924
    tcg_temp_free(t0);                                                       \
925
}
926
#endif
927
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
928
#if defined(TARGET_MIPS64)
929
OP_ST_ATOMIC(scd,st64,ld64,0x7);
930
#endif
931
#undef OP_ST_ATOMIC
932

    
933
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
934
                                  int base, int16_t offset)
935
{
936
    if (base == 0) {
937
        tcg_gen_movi_tl(addr, offset);
938
    } else if (offset == 0) {
939
        gen_load_gpr(addr, base);
940
    } else {
941
        tcg_gen_movi_tl(addr, offset);
942
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
943
    }
944
}
945

    
946
static target_ulong pc_relative_pc (DisasContext *ctx)
947
{
948
    target_ulong pc = ctx->pc;
949

    
950
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
951
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
952

    
953
        pc -= branch_bytes;
954
    }
955

    
956
    pc &= ~(target_ulong)3;
957
    return pc;
958
}
959

    
960
/* Load and store */
961
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
962
                      int base, int16_t offset)
963
{
964
    const char *opn = "ldst";
965
    TCGv t0 = tcg_temp_new();
966
    TCGv t1 = tcg_temp_new();
967

    
968
    gen_base_offset_addr(ctx, t0, base, offset);
969
    /* Don't do NOP if destination is zero: we must perform the actual
970
       memory access. */
971
    switch (opc) {
972
#if defined(TARGET_MIPS64)
973
    case OPC_LWU:
974
        save_cpu_state(ctx, 0);
975
        op_ldst_lwu(t0, t0, ctx);
976
        gen_store_gpr(t0, rt);
977
        opn = "lwu";
978
        break;
979
    case OPC_LD:
980
        save_cpu_state(ctx, 0);
981
        op_ldst_ld(t0, t0, ctx);
982
        gen_store_gpr(t0, rt);
983
        opn = "ld";
984
        break;
985
    case OPC_LLD:
986
        save_cpu_state(ctx, 0);
987
        op_ldst_lld(t0, t0, ctx);
988
        gen_store_gpr(t0, rt);
989
        opn = "lld";
990
        break;
991
    case OPC_SD:
992
        save_cpu_state(ctx, 0);
993
        gen_load_gpr(t1, rt);
994
        op_ldst_sd(t1, t0, ctx);
995
        opn = "sd";
996
        break;
997
    case OPC_LDL:
998
        save_cpu_state(ctx, 1);
999
        gen_load_gpr(t1, rt);
1000
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1001
        gen_store_gpr(t1, rt);
1002
        opn = "ldl";
1003
        break;
1004
    case OPC_SDL:
1005
        save_cpu_state(ctx, 1);
1006
        gen_load_gpr(t1, rt);
1007
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1008
        opn = "sdl";
1009
        break;
1010
    case OPC_LDR:
1011
        save_cpu_state(ctx, 1);
1012
        gen_load_gpr(t1, rt);
1013
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1014
        gen_store_gpr(t1, rt);
1015
        opn = "ldr";
1016
        break;
1017
    case OPC_SDR:
1018
        save_cpu_state(ctx, 1);
1019
        gen_load_gpr(t1, rt);
1020
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1021
        opn = "sdr";
1022
        break;
1023
    case OPC_LDPC:
1024
        save_cpu_state(ctx, 1);
1025
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1026
        gen_op_addr_add(ctx, t0, t0, t1);
1027
        op_ldst_ld(t0, t0, ctx);
1028
        gen_store_gpr(t0, rt);
1029
        break;
1030
#endif
1031
    case OPC_LWPC:
1032
        save_cpu_state(ctx, 1);
1033
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1034
        gen_op_addr_add(ctx, t0, t0, t1);
1035
        op_ldst_lw(t0, t0, ctx);
1036
        gen_store_gpr(t0, rt);
1037
        break;
1038
    case OPC_LW:
1039
        save_cpu_state(ctx, 0);
1040
        op_ldst_lw(t0, t0, ctx);
1041
        gen_store_gpr(t0, rt);
1042
        opn = "lw";
1043
        break;
1044
    case OPC_SW:
1045
        save_cpu_state(ctx, 0);
1046
        gen_load_gpr(t1, rt);
1047
        op_ldst_sw(t1, t0, ctx);
1048
        opn = "sw";
1049
        break;
1050
    case OPC_LH:
1051
        save_cpu_state(ctx, 0);
1052
        op_ldst_lh(t0, t0, ctx);
1053
        gen_store_gpr(t0, rt);
1054
        opn = "lh";
1055
        break;
1056
    case OPC_SH:
1057
        save_cpu_state(ctx, 0);
1058
        gen_load_gpr(t1, rt);
1059
        op_ldst_sh(t1, t0, ctx);
1060
        opn = "sh";
1061
        break;
1062
    case OPC_LHU:
1063
        save_cpu_state(ctx, 0);
1064
        op_ldst_lhu(t0, t0, ctx);
1065
        gen_store_gpr(t0, rt);
1066
        opn = "lhu";
1067
        break;
1068
    case OPC_LB:
1069
        save_cpu_state(ctx, 0);
1070
        op_ldst_lb(t0, t0, ctx);
1071
        gen_store_gpr(t0, rt);
1072
        opn = "lb";
1073
        break;
1074
    case OPC_SB:
1075
        save_cpu_state(ctx, 0);
1076
        gen_load_gpr(t1, rt);
1077
        op_ldst_sb(t1, t0, ctx);
1078
        opn = "sb";
1079
        break;
1080
    case OPC_LBU:
1081
        save_cpu_state(ctx, 0);
1082
        op_ldst_lbu(t0, t0, ctx);
1083
        gen_store_gpr(t0, rt);
1084
        opn = "lbu";
1085
        break;
1086
    case OPC_LWL:
1087
        save_cpu_state(ctx, 1);
1088
        gen_load_gpr(t1, rt);
1089
        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1090
        gen_store_gpr(t1, rt);
1091
        opn = "lwl";
1092
        break;
1093
    case OPC_SWL:
1094
        save_cpu_state(ctx, 1);
1095
        gen_load_gpr(t1, rt);
1096
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1097
        opn = "swr";
1098
        break;
1099
    case OPC_LWR:
1100
        save_cpu_state(ctx, 1);
1101
        gen_load_gpr(t1, rt);
1102
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1103
        gen_store_gpr(t1, rt);
1104
        opn = "lwr";
1105
        break;
1106
    case OPC_SWR:
1107
        save_cpu_state(ctx, 1);
1108
        gen_load_gpr(t1, rt);
1109
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1110
        opn = "swr";
1111
        break;
1112
    case OPC_LL:
1113
        save_cpu_state(ctx, 1);
1114
        op_ldst_ll(t0, t0, ctx);
1115
        gen_store_gpr(t0, rt);
1116
        opn = "ll";
1117
        break;
1118
    }
1119
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1120
    tcg_temp_free(t0);
1121
    tcg_temp_free(t1);
1122
}
1123

    
1124
/* Store conditional */
1125
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1126
                         int base, int16_t offset)
1127
{
1128
    const char *opn = "st_cond";
1129
    TCGv t0, t1;
1130

    
1131
    t0 = tcg_temp_local_new();
1132

    
1133
    gen_base_offset_addr(ctx, t0, base, offset);
1134
    /* Don't do NOP if destination is zero: we must perform the actual
1135
       memory access. */
1136

    
1137
    t1 = tcg_temp_local_new();
1138
    gen_load_gpr(t1, rt);
1139
    switch (opc) {
1140
#if defined(TARGET_MIPS64)
1141
    case OPC_SCD:
1142
        save_cpu_state(ctx, 0);
1143
        op_ldst_scd(t1, t0, rt, ctx);
1144
        opn = "scd";
1145
        break;
1146
#endif
1147
    case OPC_SC:
1148
        save_cpu_state(ctx, 1);
1149
        op_ldst_sc(t1, t0, rt, ctx);
1150
        opn = "sc";
1151
        break;
1152
    }
1153
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1154
    tcg_temp_free(t1);
1155
    tcg_temp_free(t0);
1156
}
1157

    
1158
/* Load and store */
1159
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1160
                          int base, int16_t offset)
1161
{
1162
    const char *opn = "flt_ldst";
1163
    TCGv t0 = tcg_temp_new();
1164

    
1165
    gen_base_offset_addr(ctx, t0, base, offset);
1166
    /* Don't do NOP if destination is zero: we must perform the actual
1167
       memory access. */
1168
    switch (opc) {
1169
    case OPC_LWC1:
1170
        {
1171
            TCGv_i32 fp0 = tcg_temp_new_i32();
1172

    
1173
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1174
            tcg_gen_trunc_tl_i32(fp0, t0);
1175
            gen_store_fpr32(fp0, ft);
1176
            tcg_temp_free_i32(fp0);
1177
        }
1178
        opn = "lwc1";
1179
        break;
1180
    case OPC_SWC1:
1181
        {
1182
            TCGv_i32 fp0 = tcg_temp_new_i32();
1183
            TCGv t1 = tcg_temp_new();
1184

    
1185
            gen_load_fpr32(fp0, ft);
1186
            tcg_gen_extu_i32_tl(t1, fp0);
1187
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1188
            tcg_temp_free(t1);
1189
            tcg_temp_free_i32(fp0);
1190
        }
1191
        opn = "swc1";
1192
        break;
1193
    case OPC_LDC1:
1194
        {
1195
            TCGv_i64 fp0 = tcg_temp_new_i64();
1196

    
1197
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1198
            gen_store_fpr64(ctx, fp0, ft);
1199
            tcg_temp_free_i64(fp0);
1200
        }
1201
        opn = "ldc1";
1202
        break;
1203
    case OPC_SDC1:
1204
        {
1205
            TCGv_i64 fp0 = tcg_temp_new_i64();
1206

    
1207
            gen_load_fpr64(ctx, fp0, ft);
1208
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1209
            tcg_temp_free_i64(fp0);
1210
        }
1211
        opn = "sdc1";
1212
        break;
1213
    default:
1214
        MIPS_INVAL(opn);
1215
        generate_exception(ctx, EXCP_RI);
1216
        goto out;
1217
    }
1218
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1219
 out:
1220
    tcg_temp_free(t0);
1221
}
1222

    
1223
/* Arithmetic with immediate operand */
1224
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1225
                           int rt, int rs, int16_t imm)
1226
{
1227
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1228
    const char *opn = "imm arith";
1229

    
1230
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1231
        /* If no destination, treat it as a NOP.
1232
           For addi, we must generate the overflow exception when needed. */
1233
        MIPS_DEBUG("NOP");
1234
        return;
1235
    }
1236
    switch (opc) {
1237
    case OPC_ADDI:
1238
        {
1239
            TCGv t0 = tcg_temp_local_new();
1240
            TCGv t1 = tcg_temp_new();
1241
            TCGv t2 = tcg_temp_new();
1242
            int l1 = gen_new_label();
1243

    
1244
            gen_load_gpr(t1, rs);
1245
            tcg_gen_addi_tl(t0, t1, uimm);
1246
            tcg_gen_ext32s_tl(t0, t0);
1247

    
1248
            tcg_gen_xori_tl(t1, t1, ~uimm);
1249
            tcg_gen_xori_tl(t2, t0, uimm);
1250
            tcg_gen_and_tl(t1, t1, t2);
1251
            tcg_temp_free(t2);
1252
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1253
            tcg_temp_free(t1);
1254
            /* operands of same sign, result different sign */
1255
            generate_exception(ctx, EXCP_OVERFLOW);
1256
            gen_set_label(l1);
1257
            tcg_gen_ext32s_tl(t0, t0);
1258
            gen_store_gpr(t0, rt);
1259
            tcg_temp_free(t0);
1260
        }
1261
        opn = "addi";
1262
        break;
1263
    case OPC_ADDIU:
1264
        if (rs != 0) {
1265
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1266
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1267
        } else {
1268
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1269
        }
1270
        opn = "addiu";
1271
        break;
1272
#if defined(TARGET_MIPS64)
1273
    case OPC_DADDI:
1274
        {
1275
            TCGv t0 = tcg_temp_local_new();
1276
            TCGv t1 = tcg_temp_new();
1277
            TCGv t2 = tcg_temp_new();
1278
            int l1 = gen_new_label();
1279

    
1280
            gen_load_gpr(t1, rs);
1281
            tcg_gen_addi_tl(t0, t1, uimm);
1282

    
1283
            tcg_gen_xori_tl(t1, t1, ~uimm);
1284
            tcg_gen_xori_tl(t2, t0, uimm);
1285
            tcg_gen_and_tl(t1, t1, t2);
1286
            tcg_temp_free(t2);
1287
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1288
            tcg_temp_free(t1);
1289
            /* operands of same sign, result different sign */
1290
            generate_exception(ctx, EXCP_OVERFLOW);
1291
            gen_set_label(l1);
1292
            gen_store_gpr(t0, rt);
1293
            tcg_temp_free(t0);
1294
        }
1295
        opn = "daddi";
1296
        break;
1297
    case OPC_DADDIU:
1298
        if (rs != 0) {
1299
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1300
        } else {
1301
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1302
        }
1303
        opn = "daddiu";
1304
        break;
1305
#endif
1306
    }
1307
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1308
}
1309

    
1310
/* Logic with immediate operand */
1311
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1312
{
1313
    target_ulong uimm;
1314
    const char *opn = "imm logic";
1315

    
1316
    if (rt == 0) {
1317
        /* If no destination, treat it as a NOP. */
1318
        MIPS_DEBUG("NOP");
1319
        return;
1320
    }
1321
    uimm = (uint16_t)imm;
1322
    switch (opc) {
1323
    case OPC_ANDI:
1324
        if (likely(rs != 0))
1325
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1326
        else
1327
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1328
        opn = "andi";
1329
        break;
1330
    case OPC_ORI:
1331
        if (rs != 0)
1332
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1333
        else
1334
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1335
        opn = "ori";
1336
        break;
1337
    case OPC_XORI:
1338
        if (likely(rs != 0))
1339
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1340
        else
1341
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1342
        opn = "xori";
1343
        break;
1344
    case OPC_LUI:
1345
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1346
        opn = "lui";
1347
        break;
1348
    }
1349
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1350
}
1351

    
1352
/* Set on less than with immediate operand */
1353
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1354
{
1355
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1356
    const char *opn = "imm arith";
1357
    TCGv t0;
1358

    
1359
    if (rt == 0) {
1360
        /* If no destination, treat it as a NOP. */
1361
        MIPS_DEBUG("NOP");
1362
        return;
1363
    }
1364
    t0 = tcg_temp_new();
1365
    gen_load_gpr(t0, rs);
1366
    switch (opc) {
1367
    case OPC_SLTI:
1368
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1369
        opn = "slti";
1370
        break;
1371
    case OPC_SLTIU:
1372
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1373
        opn = "sltiu";
1374
        break;
1375
    }
1376
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1377
    tcg_temp_free(t0);
1378
}
1379

    
1380
/* Shifts with immediate operand */
1381
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1382
                          int rt, int rs, int16_t imm)
1383
{
1384
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1385
    const char *opn = "imm shift";
1386
    TCGv t0;
1387

    
1388
    if (rt == 0) {
1389
        /* If no destination, treat it as a NOP. */
1390
        MIPS_DEBUG("NOP");
1391
        return;
1392
    }
1393

    
1394
    t0 = tcg_temp_new();
1395
    gen_load_gpr(t0, rs);
1396
    switch (opc) {
1397
    case OPC_SLL:
1398
        tcg_gen_shli_tl(t0, t0, uimm);
1399
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1400
        opn = "sll";
1401
        break;
1402
    case OPC_SRA:
1403
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1404
        opn = "sra";
1405
        break;
1406
    case OPC_SRL:
1407
        if (uimm != 0) {
1408
            tcg_gen_ext32u_tl(t0, t0);
1409
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1410
        } else {
1411
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1412
        }
1413
        opn = "srl";
1414
        break;
1415
    case OPC_ROTR:
1416
        if (uimm != 0) {
1417
            TCGv_i32 t1 = tcg_temp_new_i32();
1418

    
1419
            tcg_gen_trunc_tl_i32(t1, t0);
1420
            tcg_gen_rotri_i32(t1, t1, uimm);
1421
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1422
            tcg_temp_free_i32(t1);
1423
        } else {
1424
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1425
        }
1426
        opn = "rotr";
1427
        break;
1428
#if defined(TARGET_MIPS64)
1429
    case OPC_DSLL:
1430
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1431
        opn = "dsll";
1432
        break;
1433
    case OPC_DSRA:
1434
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1435
        opn = "dsra";
1436
        break;
1437
    case OPC_DSRL:
1438
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1439
        opn = "dsrl";
1440
        break;
1441
    case OPC_DROTR:
1442
        if (uimm != 0) {
1443
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1444
        } else {
1445
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1446
        }
1447
        opn = "drotr";
1448
        break;
1449
    case OPC_DSLL32:
1450
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1451
        opn = "dsll32";
1452
        break;
1453
    case OPC_DSRA32:
1454
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1455
        opn = "dsra32";
1456
        break;
1457
    case OPC_DSRL32:
1458
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1459
        opn = "dsrl32";
1460
        break;
1461
    case OPC_DROTR32:
1462
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1463
        opn = "drotr32";
1464
        break;
1465
#endif
1466
    }
1467
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1468
    tcg_temp_free(t0);
1469
}
1470

    
1471
/* Arithmetic */
1472
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1473
                       int rd, int rs, int rt)
1474
{
1475
    const char *opn = "arith";
1476

    
1477
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1478
       && opc != OPC_DADD && opc != OPC_DSUB) {
1479
        /* If no destination, treat it as a NOP.
1480
           For add & sub, we must generate the overflow exception when needed. */
1481
        MIPS_DEBUG("NOP");
1482
        return;
1483
    }
1484

    
1485
    switch (opc) {
1486
    case OPC_ADD:
1487
        {
1488
            TCGv t0 = tcg_temp_local_new();
1489
            TCGv t1 = tcg_temp_new();
1490
            TCGv t2 = tcg_temp_new();
1491
            int l1 = gen_new_label();
1492

    
1493
            gen_load_gpr(t1, rs);
1494
            gen_load_gpr(t2, rt);
1495
            tcg_gen_add_tl(t0, t1, t2);
1496
            tcg_gen_ext32s_tl(t0, t0);
1497
            tcg_gen_xor_tl(t1, t1, t2);
1498
            tcg_gen_xor_tl(t2, t0, t2);
1499
            tcg_gen_andc_tl(t1, t2, t1);
1500
            tcg_temp_free(t2);
1501
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1502
            tcg_temp_free(t1);
1503
            /* operands of same sign, result different sign */
1504
            generate_exception(ctx, EXCP_OVERFLOW);
1505
            gen_set_label(l1);
1506
            gen_store_gpr(t0, rd);
1507
            tcg_temp_free(t0);
1508
        }
1509
        opn = "add";
1510
        break;
1511
    case OPC_ADDU:
1512
        if (rs != 0 && rt != 0) {
1513
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1514
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1515
        } else if (rs == 0 && rt != 0) {
1516
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1517
        } else if (rs != 0 && rt == 0) {
1518
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1519
        } else {
1520
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1521
        }
1522
        opn = "addu";
1523
        break;
1524
    case OPC_SUB:
1525
        {
1526
            TCGv t0 = tcg_temp_local_new();
1527
            TCGv t1 = tcg_temp_new();
1528
            TCGv t2 = tcg_temp_new();
1529
            int l1 = gen_new_label();
1530

    
1531
            gen_load_gpr(t1, rs);
1532
            gen_load_gpr(t2, rt);
1533
            tcg_gen_sub_tl(t0, t1, t2);
1534
            tcg_gen_ext32s_tl(t0, t0);
1535
            tcg_gen_xor_tl(t2, t1, t2);
1536
            tcg_gen_xor_tl(t1, t0, t1);
1537
            tcg_gen_and_tl(t1, t1, t2);
1538
            tcg_temp_free(t2);
1539
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1540
            tcg_temp_free(t1);
1541
            /* operands of different sign, first operand and result different sign */
1542
            generate_exception(ctx, EXCP_OVERFLOW);
1543
            gen_set_label(l1);
1544
            gen_store_gpr(t0, rd);
1545
            tcg_temp_free(t0);
1546
        }
1547
        opn = "sub";
1548
        break;
1549
    case OPC_SUBU:
1550
        if (rs != 0 && rt != 0) {
1551
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1552
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1553
        } else if (rs == 0 && rt != 0) {
1554
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1555
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1556
        } else if (rs != 0 && rt == 0) {
1557
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1558
        } else {
1559
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1560
        }
1561
        opn = "subu";
1562
        break;
1563
#if defined(TARGET_MIPS64)
1564
    case OPC_DADD:
1565
        {
1566
            TCGv t0 = tcg_temp_local_new();
1567
            TCGv t1 = tcg_temp_new();
1568
            TCGv t2 = tcg_temp_new();
1569
            int l1 = gen_new_label();
1570

    
1571
            gen_load_gpr(t1, rs);
1572
            gen_load_gpr(t2, rt);
1573
            tcg_gen_add_tl(t0, t1, t2);
1574
            tcg_gen_xor_tl(t1, t1, t2);
1575
            tcg_gen_xor_tl(t2, t0, t2);
1576
            tcg_gen_andc_tl(t1, t2, t1);
1577
            tcg_temp_free(t2);
1578
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1579
            tcg_temp_free(t1);
1580
            /* operands of same sign, result different sign */
1581
            generate_exception(ctx, EXCP_OVERFLOW);
1582
            gen_set_label(l1);
1583
            gen_store_gpr(t0, rd);
1584
            tcg_temp_free(t0);
1585
        }
1586
        opn = "dadd";
1587
        break;
1588
    case OPC_DADDU:
1589
        if (rs != 0 && rt != 0) {
1590
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1591
        } else if (rs == 0 && rt != 0) {
1592
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1593
        } else if (rs != 0 && rt == 0) {
1594
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1595
        } else {
1596
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1597
        }
1598
        opn = "daddu";
1599
        break;
1600
    case OPC_DSUB:
1601
        {
1602
            TCGv t0 = tcg_temp_local_new();
1603
            TCGv t1 = tcg_temp_new();
1604
            TCGv t2 = tcg_temp_new();
1605
            int l1 = gen_new_label();
1606

    
1607
            gen_load_gpr(t1, rs);
1608
            gen_load_gpr(t2, rt);
1609
            tcg_gen_sub_tl(t0, t1, t2);
1610
            tcg_gen_xor_tl(t2, t1, t2);
1611
            tcg_gen_xor_tl(t1, t0, t1);
1612
            tcg_gen_and_tl(t1, t1, t2);
1613
            tcg_temp_free(t2);
1614
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1615
            tcg_temp_free(t1);
1616
            /* operands of different sign, first operand and result different sign */
1617
            generate_exception(ctx, EXCP_OVERFLOW);
1618
            gen_set_label(l1);
1619
            gen_store_gpr(t0, rd);
1620
            tcg_temp_free(t0);
1621
        }
1622
        opn = "dsub";
1623
        break;
1624
    case OPC_DSUBU:
1625
        if (rs != 0 && rt != 0) {
1626
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1627
        } else if (rs == 0 && rt != 0) {
1628
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1629
        } else if (rs != 0 && rt == 0) {
1630
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1631
        } else {
1632
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1633
        }
1634
        opn = "dsubu";
1635
        break;
1636
#endif
1637
    case OPC_MUL:
1638
        if (likely(rs != 0 && rt != 0)) {
1639
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1640
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1641
        } else {
1642
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1643
        }
1644
        opn = "mul";
1645
        break;
1646
    }
1647
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1648
}
1649

    
1650
/* Conditional move */
1651
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1652
{
1653
    const char *opn = "cond move";
1654
    int l1;
1655

    
1656
    if (rd == 0) {
1657
        /* If no destination, treat it as a NOP.
1658
           For add & sub, we must generate the overflow exception when needed. */
1659
        MIPS_DEBUG("NOP");
1660
        return;
1661
    }
1662

    
1663
    l1 = gen_new_label();
1664
    switch (opc) {
1665
    case OPC_MOVN:
1666
        if (likely(rt != 0))
1667
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1668
        else
1669
            tcg_gen_br(l1);
1670
        opn = "movn";
1671
        break;
1672
    case OPC_MOVZ:
1673
        if (likely(rt != 0))
1674
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1675
        opn = "movz";
1676
        break;
1677
    }
1678
    if (rs != 0)
1679
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1680
    else
1681
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1682
    gen_set_label(l1);
1683

    
1684
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1685
}
1686

    
1687
/* Logic */
1688
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1689
{
1690
    const char *opn = "logic";
1691

    
1692
    if (rd == 0) {
1693
        /* If no destination, treat it as a NOP. */
1694
        MIPS_DEBUG("NOP");
1695
        return;
1696
    }
1697

    
1698
    switch (opc) {
1699
    case OPC_AND:
1700
        if (likely(rs != 0 && rt != 0)) {
1701
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1702
        } else {
1703
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1704
        }
1705
        opn = "and";
1706
        break;
1707
    case OPC_NOR:
1708
        if (rs != 0 && rt != 0) {
1709
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1710
        } else if (rs == 0 && rt != 0) {
1711
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1712
        } else if (rs != 0 && rt == 0) {
1713
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1714
        } else {
1715
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1716
        }
1717
        opn = "nor";
1718
        break;
1719
    case OPC_OR:
1720
        if (likely(rs != 0 && rt != 0)) {
1721
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1722
        } else if (rs == 0 && rt != 0) {
1723
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1724
        } else if (rs != 0 && rt == 0) {
1725
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1726
        } else {
1727
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1728
        }
1729
        opn = "or";
1730
        break;
1731
    case OPC_XOR:
1732
        if (likely(rs != 0 && rt != 0)) {
1733
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1734
        } else if (rs == 0 && rt != 0) {
1735
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1736
        } else if (rs != 0 && rt == 0) {
1737
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1738
        } else {
1739
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1740
        }
1741
        opn = "xor";
1742
        break;
1743
    }
1744
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1745
}
1746

    
1747
/* Set on lower than */
1748
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1749
{
1750
    const char *opn = "slt";
1751
    TCGv t0, t1;
1752

    
1753
    if (rd == 0) {
1754
        /* If no destination, treat it as a NOP. */
1755
        MIPS_DEBUG("NOP");
1756
        return;
1757
    }
1758

    
1759
    t0 = tcg_temp_new();
1760
    t1 = tcg_temp_new();
1761
    gen_load_gpr(t0, rs);
1762
    gen_load_gpr(t1, rt);
1763
    switch (opc) {
1764
    case OPC_SLT:
1765
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1766
        opn = "slt";
1767
        break;
1768
    case OPC_SLTU:
1769
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1770
        opn = "sltu";
1771
        break;
1772
    }
1773
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1774
    tcg_temp_free(t0);
1775
    tcg_temp_free(t1);
1776
}
1777

    
1778
/* Shifts */
1779
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1780
                       int rd, int rs, int rt)
1781
{
1782
    const char *opn = "shifts";
1783
    TCGv t0, t1;
1784

    
1785
    if (rd == 0) {
1786
        /* If no destination, treat it as a NOP.
1787
           For add & sub, we must generate the overflow exception when needed. */
1788
        MIPS_DEBUG("NOP");
1789
        return;
1790
    }
1791

    
1792
    t0 = tcg_temp_new();
1793
    t1 = tcg_temp_new();
1794
    gen_load_gpr(t0, rs);
1795
    gen_load_gpr(t1, rt);
1796
    switch (opc) {
1797
    case OPC_SLLV:
1798
        tcg_gen_andi_tl(t0, t0, 0x1f);
1799
        tcg_gen_shl_tl(t0, t1, t0);
1800
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1801
        opn = "sllv";
1802
        break;
1803
    case OPC_SRAV:
1804
        tcg_gen_andi_tl(t0, t0, 0x1f);
1805
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1806
        opn = "srav";
1807
        break;
1808
    case OPC_SRLV:
1809
        tcg_gen_ext32u_tl(t1, t1);
1810
        tcg_gen_andi_tl(t0, t0, 0x1f);
1811
        tcg_gen_shr_tl(t0, t1, t0);
1812
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1813
        opn = "srlv";
1814
        break;
1815
    case OPC_ROTRV:
1816
        {
1817
            TCGv_i32 t2 = tcg_temp_new_i32();
1818
            TCGv_i32 t3 = tcg_temp_new_i32();
1819

    
1820
            tcg_gen_trunc_tl_i32(t2, t0);
1821
            tcg_gen_trunc_tl_i32(t3, t1);
1822
            tcg_gen_andi_i32(t2, t2, 0x1f);
1823
            tcg_gen_rotr_i32(t2, t3, t2);
1824
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1825
            tcg_temp_free_i32(t2);
1826
            tcg_temp_free_i32(t3);
1827
            opn = "rotrv";
1828
        }
1829
        break;
1830
#if defined(TARGET_MIPS64)
1831
    case OPC_DSLLV:
1832
        tcg_gen_andi_tl(t0, t0, 0x3f);
1833
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1834
        opn = "dsllv";
1835
        break;
1836
    case OPC_DSRAV:
1837
        tcg_gen_andi_tl(t0, t0, 0x3f);
1838
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1839
        opn = "dsrav";
1840
        break;
1841
    case OPC_DSRLV:
1842
        tcg_gen_andi_tl(t0, t0, 0x3f);
1843
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1844
        opn = "dsrlv";
1845
        break;
1846
    case OPC_DROTRV:
1847
        tcg_gen_andi_tl(t0, t0, 0x3f);
1848
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1849
        opn = "drotrv";
1850
        break;
1851
#endif
1852
    }
1853
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1854
    tcg_temp_free(t0);
1855
    tcg_temp_free(t1);
1856
}
1857

    
1858
/* Arithmetic on HI/LO registers */
1859
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1860
{
1861
    const char *opn = "hilo";
1862

    
1863
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1864
        /* Treat as NOP. */
1865
        MIPS_DEBUG("NOP");
1866
        return;
1867
    }
1868
    switch (opc) {
1869
    case OPC_MFHI:
1870
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1871
        opn = "mfhi";
1872
        break;
1873
    case OPC_MFLO:
1874
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1875
        opn = "mflo";
1876
        break;
1877
    case OPC_MTHI:
1878
        if (reg != 0)
1879
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1880
        else
1881
            tcg_gen_movi_tl(cpu_HI[0], 0);
1882
        opn = "mthi";
1883
        break;
1884
    case OPC_MTLO:
1885
        if (reg != 0)
1886
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1887
        else
1888
            tcg_gen_movi_tl(cpu_LO[0], 0);
1889
        opn = "mtlo";
1890
        break;
1891
    }
1892
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1893
}
1894

    
1895
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1896
                        int rs, int rt)
1897
{
1898
    const char *opn = "mul/div";
1899
    TCGv t0, t1;
1900

    
1901
    switch (opc) {
1902
    case OPC_DIV:
1903
    case OPC_DIVU:
1904
#if defined(TARGET_MIPS64)
1905
    case OPC_DDIV:
1906
    case OPC_DDIVU:
1907
#endif
1908
        t0 = tcg_temp_local_new();
1909
        t1 = tcg_temp_local_new();
1910
        break;
1911
    default:
1912
        t0 = tcg_temp_new();
1913
        t1 = tcg_temp_new();
1914
        break;
1915
    }
1916

    
1917
    gen_load_gpr(t0, rs);
1918
    gen_load_gpr(t1, rt);
1919
    switch (opc) {
1920
    case OPC_DIV:
1921
        {
1922
            int l1 = gen_new_label();
1923
            int l2 = gen_new_label();
1924

    
1925
            tcg_gen_ext32s_tl(t0, t0);
1926
            tcg_gen_ext32s_tl(t1, t1);
1927
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1928
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1929
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1930

    
1931
            tcg_gen_mov_tl(cpu_LO[0], t0);
1932
            tcg_gen_movi_tl(cpu_HI[0], 0);
1933
            tcg_gen_br(l1);
1934
            gen_set_label(l2);
1935
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1936
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1937
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1938
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1939
            gen_set_label(l1);
1940
        }
1941
        opn = "div";
1942
        break;
1943
    case OPC_DIVU:
1944
        {
1945
            int l1 = gen_new_label();
1946

    
1947
            tcg_gen_ext32u_tl(t0, t0);
1948
            tcg_gen_ext32u_tl(t1, t1);
1949
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1950
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1951
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1952
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1953
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1954
            gen_set_label(l1);
1955
        }
1956
        opn = "divu";
1957
        break;
1958
    case OPC_MULT:
1959
        {
1960
            TCGv_i64 t2 = tcg_temp_new_i64();
1961
            TCGv_i64 t3 = tcg_temp_new_i64();
1962

    
1963
            tcg_gen_ext_tl_i64(t2, t0);
1964
            tcg_gen_ext_tl_i64(t3, t1);
1965
            tcg_gen_mul_i64(t2, t2, t3);
1966
            tcg_temp_free_i64(t3);
1967
            tcg_gen_trunc_i64_tl(t0, t2);
1968
            tcg_gen_shri_i64(t2, t2, 32);
1969
            tcg_gen_trunc_i64_tl(t1, t2);
1970
            tcg_temp_free_i64(t2);
1971
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1972
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1973
        }
1974
        opn = "mult";
1975
        break;
1976
    case OPC_MULTU:
1977
        {
1978
            TCGv_i64 t2 = tcg_temp_new_i64();
1979
            TCGv_i64 t3 = tcg_temp_new_i64();
1980

    
1981
            tcg_gen_ext32u_tl(t0, t0);
1982
            tcg_gen_ext32u_tl(t1, t1);
1983
            tcg_gen_extu_tl_i64(t2, t0);
1984
            tcg_gen_extu_tl_i64(t3, t1);
1985
            tcg_gen_mul_i64(t2, t2, t3);
1986
            tcg_temp_free_i64(t3);
1987
            tcg_gen_trunc_i64_tl(t0, t2);
1988
            tcg_gen_shri_i64(t2, t2, 32);
1989
            tcg_gen_trunc_i64_tl(t1, t2);
1990
            tcg_temp_free_i64(t2);
1991
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1992
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1993
        }
1994
        opn = "multu";
1995
        break;
1996
#if defined(TARGET_MIPS64)
1997
    case OPC_DDIV:
1998
        {
1999
            int l1 = gen_new_label();
2000
            int l2 = gen_new_label();
2001

    
2002
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2003
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2004
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2005
            tcg_gen_mov_tl(cpu_LO[0], t0);
2006
            tcg_gen_movi_tl(cpu_HI[0], 0);
2007
            tcg_gen_br(l1);
2008
            gen_set_label(l2);
2009
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2010
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2011
            gen_set_label(l1);
2012
        }
2013
        opn = "ddiv";
2014
        break;
2015
    case OPC_DDIVU:
2016
        {
2017
            int l1 = gen_new_label();
2018

    
2019
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2020
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2021
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2022
            gen_set_label(l1);
2023
        }
2024
        opn = "ddivu";
2025
        break;
2026
    case OPC_DMULT:
2027
        gen_helper_dmult(t0, t1);
2028
        opn = "dmult";
2029
        break;
2030
    case OPC_DMULTU:
2031
        gen_helper_dmultu(t0, t1);
2032
        opn = "dmultu";
2033
        break;
2034
#endif
2035
    case OPC_MADD:
2036
        {
2037
            TCGv_i64 t2 = tcg_temp_new_i64();
2038
            TCGv_i64 t3 = tcg_temp_new_i64();
2039

    
2040
            tcg_gen_ext_tl_i64(t2, t0);
2041
            tcg_gen_ext_tl_i64(t3, t1);
2042
            tcg_gen_mul_i64(t2, t2, t3);
2043
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2044
            tcg_gen_add_i64(t2, t2, t3);
2045
            tcg_temp_free_i64(t3);
2046
            tcg_gen_trunc_i64_tl(t0, t2);
2047
            tcg_gen_shri_i64(t2, t2, 32);
2048
            tcg_gen_trunc_i64_tl(t1, t2);
2049
            tcg_temp_free_i64(t2);
2050
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2051
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2052
        }
2053
        opn = "madd";
2054
        break;
2055
    case OPC_MADDU:
2056
       {
2057
            TCGv_i64 t2 = tcg_temp_new_i64();
2058
            TCGv_i64 t3 = tcg_temp_new_i64();
2059

    
2060
            tcg_gen_ext32u_tl(t0, t0);
2061
            tcg_gen_ext32u_tl(t1, t1);
2062
            tcg_gen_extu_tl_i64(t2, t0);
2063
            tcg_gen_extu_tl_i64(t3, t1);
2064
            tcg_gen_mul_i64(t2, t2, t3);
2065
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2066
            tcg_gen_add_i64(t2, t2, t3);
2067
            tcg_temp_free_i64(t3);
2068
            tcg_gen_trunc_i64_tl(t0, t2);
2069
            tcg_gen_shri_i64(t2, t2, 32);
2070
            tcg_gen_trunc_i64_tl(t1, t2);
2071
            tcg_temp_free_i64(t2);
2072
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2073
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2074
        }
2075
        opn = "maddu";
2076
        break;
2077
    case OPC_MSUB:
2078
        {
2079
            TCGv_i64 t2 = tcg_temp_new_i64();
2080
            TCGv_i64 t3 = tcg_temp_new_i64();
2081

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

    
2102
            tcg_gen_ext32u_tl(t0, t0);
2103
            tcg_gen_ext32u_tl(t1, t1);
2104
            tcg_gen_extu_tl_i64(t2, t0);
2105
            tcg_gen_extu_tl_i64(t3, t1);
2106
            tcg_gen_mul_i64(t2, t2, t3);
2107
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2108
            tcg_gen_sub_i64(t2, t3, t2);
2109
            tcg_temp_free_i64(t3);
2110
            tcg_gen_trunc_i64_tl(t0, t2);
2111
            tcg_gen_shri_i64(t2, t2, 32);
2112
            tcg_gen_trunc_i64_tl(t1, t2);
2113
            tcg_temp_free_i64(t2);
2114
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2115
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2116
        }
2117
        opn = "msubu";
2118
        break;
2119
    default:
2120
        MIPS_INVAL(opn);
2121
        generate_exception(ctx, EXCP_RI);
2122
        goto out;
2123
    }
2124
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2125
 out:
2126
    tcg_temp_free(t0);
2127
    tcg_temp_free(t1);
2128
}
2129

    
2130
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2131
                            int rd, int rs, int rt)
2132
{
2133
    const char *opn = "mul vr54xx";
2134
    TCGv t0 = tcg_temp_new();
2135
    TCGv t1 = tcg_temp_new();
2136

    
2137
    gen_load_gpr(t0, rs);
2138
    gen_load_gpr(t1, rt);
2139

    
2140
    switch (opc) {
2141
    case OPC_VR54XX_MULS:
2142
        gen_helper_muls(t0, t0, t1);
2143
        opn = "muls";
2144
        break;
2145
    case OPC_VR54XX_MULSU:
2146
        gen_helper_mulsu(t0, t0, t1);
2147
        opn = "mulsu";
2148
        break;
2149
    case OPC_VR54XX_MACC:
2150
        gen_helper_macc(t0, t0, t1);
2151
        opn = "macc";
2152
        break;
2153
    case OPC_VR54XX_MACCU:
2154
        gen_helper_maccu(t0, t0, t1);
2155
        opn = "maccu";
2156
        break;
2157
    case OPC_VR54XX_MSAC:
2158
        gen_helper_msac(t0, t0, t1);
2159
        opn = "msac";
2160
        break;
2161
    case OPC_VR54XX_MSACU:
2162
        gen_helper_msacu(t0, t0, t1);
2163
        opn = "msacu";
2164
        break;
2165
    case OPC_VR54XX_MULHI:
2166
        gen_helper_mulhi(t0, t0, t1);
2167
        opn = "mulhi";
2168
        break;
2169
    case OPC_VR54XX_MULHIU:
2170
        gen_helper_mulhiu(t0, t0, t1);
2171
        opn = "mulhiu";
2172
        break;
2173
    case OPC_VR54XX_MULSHI:
2174
        gen_helper_mulshi(t0, t0, t1);
2175
        opn = "mulshi";
2176
        break;
2177
    case OPC_VR54XX_MULSHIU:
2178
        gen_helper_mulshiu(t0, t0, t1);
2179
        opn = "mulshiu";
2180
        break;
2181
    case OPC_VR54XX_MACCHI:
2182
        gen_helper_macchi(t0, t0, t1);
2183
        opn = "macchi";
2184
        break;
2185
    case OPC_VR54XX_MACCHIU:
2186
        gen_helper_macchiu(t0, t0, t1);
2187
        opn = "macchiu";
2188
        break;
2189
    case OPC_VR54XX_MSACHI:
2190
        gen_helper_msachi(t0, t0, t1);
2191
        opn = "msachi";
2192
        break;
2193
    case OPC_VR54XX_MSACHIU:
2194
        gen_helper_msachiu(t0, t0, t1);
2195
        opn = "msachiu";
2196
        break;
2197
    default:
2198
        MIPS_INVAL("mul vr54xx");
2199
        generate_exception(ctx, EXCP_RI);
2200
        goto out;
2201
    }
2202
    gen_store_gpr(t0, rd);
2203
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2204

    
2205
 out:
2206
    tcg_temp_free(t0);
2207
    tcg_temp_free(t1);
2208
}
2209

    
2210
static void gen_cl (DisasContext *ctx, uint32_t opc,
2211
                    int rd, int rs)
2212
{
2213
    const char *opn = "CLx";
2214
    TCGv t0;
2215

    
2216
    if (rd == 0) {
2217
        /* Treat as NOP. */
2218
        MIPS_DEBUG("NOP");
2219
        return;
2220
    }
2221
    t0 = tcg_temp_new();
2222
    gen_load_gpr(t0, rs);
2223
    switch (opc) {
2224
    case OPC_CLO:
2225
        gen_helper_clo(cpu_gpr[rd], t0);
2226
        opn = "clo";
2227
        break;
2228
    case OPC_CLZ:
2229
        gen_helper_clz(cpu_gpr[rd], t0);
2230
        opn = "clz";
2231
        break;
2232
#if defined(TARGET_MIPS64)
2233
    case OPC_DCLO:
2234
        gen_helper_dclo(cpu_gpr[rd], t0);
2235
        opn = "dclo";
2236
        break;
2237
    case OPC_DCLZ:
2238
        gen_helper_dclz(cpu_gpr[rd], t0);
2239
        opn = "dclz";
2240
        break;
2241
#endif
2242
    }
2243
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2244
    tcg_temp_free(t0);
2245
}
2246

    
2247
/* Traps */
2248
static void gen_trap (DisasContext *ctx, uint32_t opc,
2249
                      int rs, int rt, int16_t imm)
2250
{
2251
    int cond;
2252
    TCGv t0 = tcg_temp_new();
2253
    TCGv t1 = tcg_temp_new();
2254

    
2255
    cond = 0;
2256
    /* Load needed operands */
2257
    switch (opc) {
2258
    case OPC_TEQ:
2259
    case OPC_TGE:
2260
    case OPC_TGEU:
2261
    case OPC_TLT:
2262
    case OPC_TLTU:
2263
    case OPC_TNE:
2264
        /* Compare two registers */
2265
        if (rs != rt) {
2266
            gen_load_gpr(t0, rs);
2267
            gen_load_gpr(t1, rt);
2268
            cond = 1;
2269
        }
2270
        break;
2271
    case OPC_TEQI:
2272
    case OPC_TGEI:
2273
    case OPC_TGEIU:
2274
    case OPC_TLTI:
2275
    case OPC_TLTIU:
2276
    case OPC_TNEI:
2277
        /* Compare register to immediate */
2278
        if (rs != 0 || imm != 0) {
2279
            gen_load_gpr(t0, rs);
2280
            tcg_gen_movi_tl(t1, (int32_t)imm);
2281
            cond = 1;
2282
        }
2283
        break;
2284
    }
2285
    if (cond == 0) {
2286
        switch (opc) {
2287
        case OPC_TEQ:   /* rs == rs */
2288
        case OPC_TEQI:  /* r0 == 0  */
2289
        case OPC_TGE:   /* rs >= rs */
2290
        case OPC_TGEI:  /* r0 >= 0  */
2291
        case OPC_TGEU:  /* rs >= rs unsigned */
2292
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2293
            /* Always trap */
2294
            generate_exception(ctx, EXCP_TRAP);
2295
            break;
2296
        case OPC_TLT:   /* rs < rs           */
2297
        case OPC_TLTI:  /* r0 < 0            */
2298
        case OPC_TLTU:  /* rs < rs unsigned  */
2299
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2300
        case OPC_TNE:   /* rs != rs          */
2301
        case OPC_TNEI:  /* r0 != 0           */
2302
            /* Never trap: treat as NOP. */
2303
            break;
2304
        }
2305
    } else {
2306
        int l1 = gen_new_label();
2307

    
2308
        switch (opc) {
2309
        case OPC_TEQ:
2310
        case OPC_TEQI:
2311
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2312
            break;
2313
        case OPC_TGE:
2314
        case OPC_TGEI:
2315
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2316
            break;
2317
        case OPC_TGEU:
2318
        case OPC_TGEIU:
2319
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2320
            break;
2321
        case OPC_TLT:
2322
        case OPC_TLTI:
2323
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2324
            break;
2325
        case OPC_TLTU:
2326
        case OPC_TLTIU:
2327
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2328
            break;
2329
        case OPC_TNE:
2330
        case OPC_TNEI:
2331
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2332
            break;
2333
        }
2334
        generate_exception(ctx, EXCP_TRAP);
2335
        gen_set_label(l1);
2336
    }
2337
    tcg_temp_free(t0);
2338
    tcg_temp_free(t1);
2339
}
2340

    
2341
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2342
{
2343
    TranslationBlock *tb;
2344
    tb = ctx->tb;
2345
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2346
        likely(!ctx->singlestep_enabled)) {
2347
        tcg_gen_goto_tb(n);
2348
        gen_save_pc(dest);
2349
        tcg_gen_exit_tb((long)tb + n);
2350
    } else {
2351
        gen_save_pc(dest);
2352
        if (ctx->singlestep_enabled) {
2353
            save_cpu_state(ctx, 0);
2354
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2355
        }
2356
        tcg_gen_exit_tb(0);
2357
    }
2358
}
2359

    
2360
/* Branches (before delay slot) */
2361
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2362
                                int insn_bytes,
2363
                                int rs, int rt, int32_t offset)
2364
{
2365
    target_ulong btgt = -1;
2366
    int blink = 0;
2367
    int bcond_compute = 0;
2368
    TCGv t0 = tcg_temp_new();
2369
    TCGv t1 = tcg_temp_new();
2370

    
2371
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2372
#ifdef MIPS_DEBUG_DISAS
2373
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2374
#endif
2375
        generate_exception(ctx, EXCP_RI);
2376
        goto out;
2377
    }
2378

    
2379
    /* Load needed operands */
2380
    switch (opc) {
2381
    case OPC_BEQ:
2382
    case OPC_BEQL:
2383
    case OPC_BNE:
2384
    case OPC_BNEL:
2385
        /* Compare two registers */
2386
        if (rs != rt) {
2387
            gen_load_gpr(t0, rs);
2388
            gen_load_gpr(t1, rt);
2389
            bcond_compute = 1;
2390
        }
2391
        btgt = ctx->pc + insn_bytes + offset;
2392
        break;
2393
    case OPC_BGEZ:
2394
    case OPC_BGEZAL:
2395
    case OPC_BGEZALL:
2396
    case OPC_BGEZL:
2397
    case OPC_BGTZ:
2398
    case OPC_BGTZL:
2399
    case OPC_BLEZ:
2400
    case OPC_BLEZL:
2401
    case OPC_BLTZ:
2402
    case OPC_BLTZAL:
2403
    case OPC_BLTZALL:
2404
    case OPC_BLTZL:
2405
        /* Compare to zero */
2406
        if (rs != 0) {
2407
            gen_load_gpr(t0, rs);
2408
            bcond_compute = 1;
2409
        }
2410
        btgt = ctx->pc + insn_bytes + offset;
2411
        break;
2412
    case OPC_J:
2413
    case OPC_JAL:
2414
    case OPC_JALX:
2415
        /* Jump to immediate */
2416
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2417
        break;
2418
    case OPC_JR:
2419
    case OPC_JALR:
2420
    case OPC_JALRC:
2421
        /* Jump to register */
2422
        if (offset != 0 && offset != 16) {
2423
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2424
               others are reserved. */
2425
            MIPS_INVAL("jump hint");
2426
            generate_exception(ctx, EXCP_RI);
2427
            goto out;
2428
        }
2429
        gen_load_gpr(btarget, rs);
2430
        break;
2431
    default:
2432
        MIPS_INVAL("branch/jump");
2433
        generate_exception(ctx, EXCP_RI);
2434
        goto out;
2435
    }
2436
    if (bcond_compute == 0) {
2437
        /* No condition to be computed */
2438
        switch (opc) {
2439
        case OPC_BEQ:     /* rx == rx        */
2440
        case OPC_BEQL:    /* rx == rx likely */
2441
        case OPC_BGEZ:    /* 0 >= 0          */
2442
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2443
        case OPC_BLEZ:    /* 0 <= 0          */
2444
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2445
            /* Always take */
2446
            ctx->hflags |= MIPS_HFLAG_B;
2447
            MIPS_DEBUG("balways");
2448
            break;
2449
        case OPC_BGEZAL:  /* 0 >= 0          */
2450
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2451
            /* Always take and link */
2452
            blink = 31;
2453
            ctx->hflags |= MIPS_HFLAG_B;
2454
            MIPS_DEBUG("balways and link");
2455
            break;
2456
        case OPC_BNE:     /* rx != rx        */
2457
        case OPC_BGTZ:    /* 0 > 0           */
2458
        case OPC_BLTZ:    /* 0 < 0           */
2459
            /* Treat as NOP. */
2460
            MIPS_DEBUG("bnever (NOP)");
2461
            goto out;
2462
        case OPC_BLTZAL:  /* 0 < 0           */
2463
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2464
            MIPS_DEBUG("bnever and link");
2465
            goto out;
2466
        case OPC_BLTZALL: /* 0 < 0 likely */
2467
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2468
            /* Skip the instruction in the delay slot */
2469
            MIPS_DEBUG("bnever, link and skip");
2470
            ctx->pc += 4;
2471
            goto out;
2472
        case OPC_BNEL:    /* rx != rx likely */
2473
        case OPC_BGTZL:   /* 0 > 0 likely */
2474
        case OPC_BLTZL:   /* 0 < 0 likely */
2475
            /* Skip the instruction in the delay slot */
2476
            MIPS_DEBUG("bnever and skip");
2477
            ctx->pc += 4;
2478
            goto out;
2479
        case OPC_J:
2480
            ctx->hflags |= MIPS_HFLAG_B;
2481
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2482
            break;
2483
        case OPC_JALX:
2484
            ctx->hflags |= MIPS_HFLAG_BX;
2485
            /* Fallthrough */
2486
        case OPC_JAL:
2487
            blink = 31;
2488
            ctx->hflags |= MIPS_HFLAG_B;
2489
            ctx->hflags |= (ctx->hflags & MIPS_HFLAG_M16
2490
                            ? MIPS_HFLAG_BDS16
2491
                            : MIPS_HFLAG_BDS32);
2492
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2493
            break;
2494
        case OPC_JR:
2495
            ctx->hflags |= MIPS_HFLAG_BR;
2496
            if (ctx->hflags & MIPS_HFLAG_M16)
2497
                ctx->hflags |= MIPS_HFLAG_BDS16;
2498
            MIPS_DEBUG("jr %s", regnames[rs]);
2499
            break;
2500
        case OPC_JALR:
2501
        case OPC_JALRC:
2502
            blink = rt;
2503
            ctx->hflags |= MIPS_HFLAG_BR;
2504
            if (ctx->hflags & MIPS_HFLAG_M16)
2505
                ctx->hflags |= MIPS_HFLAG_BDS16;
2506
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2507
            break;
2508
        default:
2509
            MIPS_INVAL("branch/jump");
2510
            generate_exception(ctx, EXCP_RI);
2511
            goto out;
2512
        }
2513
    } else {
2514
        switch (opc) {
2515
        case OPC_BEQ:
2516
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2517
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2518
                       regnames[rs], regnames[rt], btgt);
2519
            goto not_likely;
2520
        case OPC_BEQL:
2521
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2522
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2523
                       regnames[rs], regnames[rt], btgt);
2524
            goto likely;
2525
        case OPC_BNE:
2526
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2527
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2528
                       regnames[rs], regnames[rt], btgt);
2529
            goto not_likely;
2530
        case OPC_BNEL:
2531
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2532
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2533
                       regnames[rs], regnames[rt], btgt);
2534
            goto likely;
2535
        case OPC_BGEZ:
2536
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2537
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2538
            goto not_likely;
2539
        case OPC_BGEZL:
2540
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2541
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2542
            goto likely;
2543
        case OPC_BGEZAL:
2544
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2545
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2546
            blink = 31;
2547
            goto not_likely;
2548
        case OPC_BGEZALL:
2549
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2550
            blink = 31;
2551
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2552
            goto likely;
2553
        case OPC_BGTZ:
2554
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2555
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2556
            goto not_likely;
2557
        case OPC_BGTZL:
2558
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2559
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2560
            goto likely;
2561
        case OPC_BLEZ:
2562
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2563
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2564
            goto not_likely;
2565
        case OPC_BLEZL:
2566
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2567
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2568
            goto likely;
2569
        case OPC_BLTZ:
2570
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2571
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2572
            goto not_likely;
2573
        case OPC_BLTZL:
2574
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2575
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2576
            goto likely;
2577
        case OPC_BLTZAL:
2578
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2579
            blink = 31;
2580
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2581
        not_likely:
2582
            ctx->hflags |= MIPS_HFLAG_BC;
2583
            break;
2584
        case OPC_BLTZALL:
2585
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2586
            blink = 31;
2587
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2588
        likely:
2589
            ctx->hflags |= MIPS_HFLAG_BL;
2590
            break;
2591
        default:
2592
            MIPS_INVAL("conditional branch/jump");
2593
            generate_exception(ctx, EXCP_RI);
2594
            goto out;
2595
        }
2596
    }
2597
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2598
               blink, ctx->hflags, btgt);
2599

    
2600
    ctx->btarget = btgt;
2601
    if (blink > 0) {
2602
        int post_delay = insn_bytes;
2603
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2604

    
2605
        if (opc != OPC_JALRC)
2606
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2607

    
2608
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2609
    }
2610

    
2611
 out:
2612
    if (insn_bytes == 2)
2613
        ctx->hflags |= MIPS_HFLAG_B16;
2614
    tcg_temp_free(t0);
2615
    tcg_temp_free(t1);
2616
}
2617

    
2618
/* special3 bitfield operations */
2619
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2620
                        int rs, int lsb, int msb)
2621
{
2622
    TCGv t0 = tcg_temp_new();
2623
    TCGv t1 = tcg_temp_new();
2624
    target_ulong mask;
2625

    
2626
    gen_load_gpr(t1, rs);
2627
    switch (opc) {
2628
    case OPC_EXT:
2629
        if (lsb + msb > 31)
2630
            goto fail;
2631
        tcg_gen_shri_tl(t0, t1, lsb);
2632
        if (msb != 31) {
2633
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2634
        } else {
2635
            tcg_gen_ext32s_tl(t0, t0);
2636
        }
2637
        break;
2638
#if defined(TARGET_MIPS64)
2639
    case OPC_DEXTM:
2640
        tcg_gen_shri_tl(t0, t1, lsb);
2641
        if (msb != 31) {
2642
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2643
        }
2644
        break;
2645
    case OPC_DEXTU:
2646
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2647
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2648
        break;
2649
    case OPC_DEXT:
2650
        tcg_gen_shri_tl(t0, t1, lsb);
2651
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2652
        break;
2653
#endif
2654
    case OPC_INS:
2655
        if (lsb > msb)
2656
            goto fail;
2657
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2658
        gen_load_gpr(t0, rt);
2659
        tcg_gen_andi_tl(t0, t0, ~mask);
2660
        tcg_gen_shli_tl(t1, t1, lsb);
2661
        tcg_gen_andi_tl(t1, t1, mask);
2662
        tcg_gen_or_tl(t0, t0, t1);
2663
        tcg_gen_ext32s_tl(t0, t0);
2664
        break;
2665
#if defined(TARGET_MIPS64)
2666
    case OPC_DINSM:
2667
        if (lsb > msb)
2668
            goto fail;
2669
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2670
        gen_load_gpr(t0, rt);
2671
        tcg_gen_andi_tl(t0, t0, ~mask);
2672
        tcg_gen_shli_tl(t1, t1, lsb);
2673
        tcg_gen_andi_tl(t1, t1, mask);
2674
        tcg_gen_or_tl(t0, t0, t1);
2675
        break;
2676
    case OPC_DINSU:
2677
        if (lsb > msb)
2678
            goto fail;
2679
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2680
        gen_load_gpr(t0, rt);
2681
        tcg_gen_andi_tl(t0, t0, ~mask);
2682
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2683
        tcg_gen_andi_tl(t1, t1, mask);
2684
        tcg_gen_or_tl(t0, t0, t1);
2685
        break;
2686
    case OPC_DINS:
2687
        if (lsb > msb)
2688
            goto fail;
2689
        gen_load_gpr(t0, rt);
2690
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2691
        gen_load_gpr(t0, rt);
2692
        tcg_gen_andi_tl(t0, t0, ~mask);
2693
        tcg_gen_shli_tl(t1, t1, lsb);
2694
        tcg_gen_andi_tl(t1, t1, mask);
2695
        tcg_gen_or_tl(t0, t0, t1);
2696
        break;
2697
#endif
2698
    default:
2699
fail:
2700
        MIPS_INVAL("bitops");
2701
        generate_exception(ctx, EXCP_RI);
2702
        tcg_temp_free(t0);
2703
        tcg_temp_free(t1);
2704
        return;
2705
    }
2706
    gen_store_gpr(t0, rt);
2707
    tcg_temp_free(t0);
2708
    tcg_temp_free(t1);
2709
}
2710

    
2711
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2712
{
2713
    TCGv t0;
2714

    
2715
    if (rd == 0) {
2716
        /* If no destination, treat it as a NOP. */
2717
        MIPS_DEBUG("NOP");
2718
        return;
2719
    }
2720

    
2721
    t0 = tcg_temp_new();
2722
    gen_load_gpr(t0, rt);
2723
    switch (op2) {
2724
    case OPC_WSBH:
2725
        {
2726
            TCGv t1 = tcg_temp_new();
2727

    
2728
            tcg_gen_shri_tl(t1, t0, 8);
2729
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2730
            tcg_gen_shli_tl(t0, t0, 8);
2731
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2732
            tcg_gen_or_tl(t0, t0, t1);
2733
            tcg_temp_free(t1);
2734
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2735
        }
2736
        break;
2737
    case OPC_SEB:
2738
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2739
        break;
2740
    case OPC_SEH:
2741
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2742
        break;
2743
#if defined(TARGET_MIPS64)
2744
    case OPC_DSBH:
2745
        {
2746
            TCGv t1 = tcg_temp_new();
2747

    
2748
            tcg_gen_shri_tl(t1, t0, 8);
2749
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2750
            tcg_gen_shli_tl(t0, t0, 8);
2751
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2752
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2753
            tcg_temp_free(t1);
2754
        }
2755
        break;
2756
    case OPC_DSHD:
2757
        {
2758
            TCGv t1 = tcg_temp_new();
2759

    
2760
            tcg_gen_shri_tl(t1, t0, 16);
2761
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2762
            tcg_gen_shli_tl(t0, t0, 16);
2763
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2764
            tcg_gen_or_tl(t0, t0, t1);
2765
            tcg_gen_shri_tl(t1, t0, 32);
2766
            tcg_gen_shli_tl(t0, t0, 32);
2767
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2768
            tcg_temp_free(t1);
2769
        }
2770
        break;
2771
#endif
2772
    default:
2773
        MIPS_INVAL("bsfhl");
2774
        generate_exception(ctx, EXCP_RI);
2775
        tcg_temp_free(t0);
2776
        return;
2777
    }
2778
    tcg_temp_free(t0);
2779
}
2780

    
2781
#ifndef CONFIG_USER_ONLY
2782
/* CP0 (MMU and control) */
2783
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2784
{
2785
    TCGv_i32 t0 = tcg_temp_new_i32();
2786

    
2787
    tcg_gen_ld_i32(t0, cpu_env, off);
2788
    tcg_gen_ext_i32_tl(arg, t0);
2789
    tcg_temp_free_i32(t0);
2790
}
2791

    
2792
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2793
{
2794
    tcg_gen_ld_tl(arg, cpu_env, off);
2795
    tcg_gen_ext32s_tl(arg, arg);
2796
}
2797

    
2798
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2799
{
2800
    TCGv_i32 t0 = tcg_temp_new_i32();
2801

    
2802
    tcg_gen_trunc_tl_i32(t0, arg);
2803
    tcg_gen_st_i32(t0, cpu_env, off);
2804
    tcg_temp_free_i32(t0);
2805
}
2806

    
2807
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2808
{
2809
    tcg_gen_ext32s_tl(arg, arg);
2810
    tcg_gen_st_tl(arg, cpu_env, off);
2811
}
2812

    
2813
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2814
{
2815
    const char *rn = "invalid";
2816

    
2817
    if (sel != 0)
2818
        check_insn(env, ctx, ISA_MIPS32);
2819

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

    
3385
die:
3386
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3387
    generate_exception(ctx, EXCP_RI);
3388
}
3389

    
3390
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3391
{
3392
    const char *rn = "invalid";
3393

    
3394
    if (sel != 0)
3395
        check_insn(env, ctx, ISA_MIPS32);
3396

    
3397
    if (use_icount)
3398
        gen_io_start();
3399

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

    
3980
die:
3981
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3982
    generate_exception(ctx, EXCP_RI);
3983
}
3984

    
3985
#if defined(TARGET_MIPS64)
3986
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3987
{
3988
    const char *rn = "invalid";
3989

    
3990
    if (sel != 0)
3991
        check_insn(env, ctx, ISA_MIPS64);
3992

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

    
4547
die:
4548
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4549
    generate_exception(ctx, EXCP_RI);
4550
}
4551

    
4552
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4553
{
4554
    const char *rn = "invalid";
4555

    
4556
    if (sel != 0)
4557
        check_insn(env, ctx, ISA_MIPS64);
4558

    
4559
    if (use_icount)
4560
        gen_io_start();
4561

    
4562
    switch (reg) {
4563
    case 0:
4564
        switch (sel) {
4565
        case 0:
4566
            gen_helper_mtc0_index(arg);
4567
            rn = "Index";
4568
            break;
4569
        case 1:
4570
            check_insn(env, ctx, ASE_MT);
4571
            gen_helper_mtc0_mvpcontrol(arg);
4572
            rn = "MVPControl";
4573
            break;
4574
        case 2:
4575
            check_insn(env, ctx, ASE_MT);
4576
            /* ignored */
4577
            rn = "MVPConf0";
4578
            break;
4579
        case 3:
4580
            check_insn(env, ctx, ASE_MT);
4581
            /* ignored */
4582
            rn = "MVPConf1";
4583
            break;
4584
        default:
4585
            goto die;
4586
        }
4587
        break;
4588
    case 1:
4589
        switch (sel) {
4590
        case 0:
4591
            /* ignored */
4592
            rn = "Random";
4593
            break;
4594
        case 1:
4595
            check_insn(env, ctx, ASE_MT);
4596
            gen_helper_mtc0_vpecontrol(arg);
4597
            rn = "VPEControl";
4598
            break;
4599
        case 2:
4600
            check_insn(env, ctx, ASE_MT);
4601
            gen_helper_mtc0_vpeconf0(arg);
4602
            rn = "VPEConf0";
4603
            break;
4604
        case 3:
4605
            check_insn(env, ctx, ASE_MT);
4606
            gen_helper_mtc0_vpeconf1(arg);
4607
            rn = "VPEConf1";
4608
            break;
4609
        case 4:
4610
            check_insn(env, ctx, ASE_MT);
4611
            gen_helper_mtc0_yqmask(arg);
4612
            rn = "YQMask";
4613
            break;
4614
        case 5:
4615
            check_insn(env, ctx, ASE_MT);
4616
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4617
            rn = "VPESchedule";
4618
            break;
4619
        case 6:
4620
            check_insn(env, ctx, ASE_MT);
4621
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4622
            rn = "VPEScheFBack";
4623
            break;
4624
        case 7:
4625
            check_insn(env, ctx, ASE_MT);
4626
            gen_helper_mtc0_vpeopt(arg);
4627
            rn = "VPEOpt";
4628
            break;
4629
        default:
4630
            goto die;
4631
        }
4632
        break;
4633
    case 2:
4634
        switch (sel) {
4635
        case 0:
4636
            gen_helper_mtc0_entrylo0(arg);
4637
            rn = "EntryLo0";
4638
            break;
4639
        case 1:
4640
            check_insn(env, ctx, ASE_MT);
4641
            gen_helper_mtc0_tcstatus(arg);
4642
            rn = "TCStatus";
4643
            break;
4644
        case 2:
4645
            check_insn(env, ctx, ASE_MT);
4646
            gen_helper_mtc0_tcbind(arg);
4647
            rn = "TCBind";
4648
            break;
4649
        case 3:
4650
            check_insn(env, ctx, ASE_MT);
4651
            gen_helper_mtc0_tcrestart(arg);
4652
            rn = "TCRestart";
4653
            break;
4654
        case 4:
4655
            check_insn(env, ctx, ASE_MT);
4656
            gen_helper_mtc0_tchalt(arg);
4657
            rn = "TCHalt";
4658
            break;
4659
        case 5:
4660
            check_insn(env, ctx, ASE_MT);
4661
            gen_helper_mtc0_tccontext(arg);
4662
            rn = "TCContext";
4663
            break;
4664
        case 6:
4665
            check_insn(env, ctx, ASE_MT);
4666
            gen_helper_mtc0_tcschedule(arg);
4667
            rn = "TCSchedule";
4668
            break;
4669
        case 7:
4670
            check_insn(env, ctx, ASE_MT);
4671
            gen_helper_mtc0_tcschefback(arg);
4672
            rn = "TCScheFBack";
4673
            break;
4674
        default:
4675
            goto die;
4676
        }
4677
        break;
4678
    case 3:
4679
        switch (sel) {
4680
        case 0:
4681
            gen_helper_mtc0_entrylo1(arg);
4682
            rn = "EntryLo1";
4683
            break;
4684
        default:
4685
            goto die;
4686
        }
4687
        break;
4688
    case 4:
4689
        switch (sel) {
4690
        case 0:
4691
            gen_helper_mtc0_context(arg);
4692
            rn = "Context";
4693
            break;
4694
        case 1:
4695
//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4696
            rn = "ContextConfig";
4697
//           break;
4698
        default:
4699
            goto die;
4700
        }
4701
        break;
4702
    case 5:
4703
        switch (sel) {
4704
        case 0:
4705
            gen_helper_mtc0_pagemask(arg);
4706
            rn = "PageMask";
4707
            break;
4708
        case 1:
4709
            check_insn(env, ctx, ISA_MIPS32R2);
4710
            gen_helper_mtc0_pagegrain(arg);
4711
            rn = "PageGrain";
<