Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 958fb4a9

History | View | Annotate | Download (191.4 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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
//#define MIPS_DEBUG_DISAS
36
//#define MIPS_DEBUG_SIGN_EXTENSIONS
37
//#define MIPS_SINGLE_STEP
38

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

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

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

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

    
183
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
184

    
185
    /* Special */
186
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
187
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
188
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
189
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
190
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
191

    
192
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
193
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
194
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
195
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
196
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
197
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
198
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
199
};
200

    
201
/* Multiplication variants of the vr54xx. */
202
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
203

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

    
221
/* REGIMM (rt field) opcodes */
222
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
223

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

    
242
/* Special2 opcodes */
243
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
244

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

    
261
/* Special3 opcodes */
262
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
263

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

    
280
/* BSHFL opcodes */
281
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
282

    
283
enum {
284
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
285
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
286
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
287
};
288

    
289
/* DBSHFL opcodes */
290
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
291

    
292
enum {
293
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
294
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
295
};
296

    
297
/* Coprocessor 0 (rs field) */
298
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
299

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

    
315
/* MFMC0 opcodes */
316
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
317

    
318
enum {
319
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
320
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
321
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
322
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
323
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
324
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
325
};
326

    
327
/* Coprocessor 0 (with rs == C0) */
328
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
329

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

    
341
/* Coprocessor 1 (rs field) */
342
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
343

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

    
365
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
366
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
367

    
368
enum {
369
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
370
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
371
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
372
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
373
};
374

    
375
enum {
376
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
377
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
378
};
379

    
380
enum {
381
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
382
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
383
};
384

    
385
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
386

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

    
399
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
400

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

    
424
/* global register indices */
425
static TCGv cpu_env, current_tc_gprs, cpu_T[2];
426

    
427
/* General purpose registers moves */
428
const unsigned char *regnames[] =
429
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
430
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
431
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
432
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
433

    
434
static inline void gen_op_load_gpr_TN(int t_index, int reg)
435
{
436
    tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
437
}
438

    
439
static inline void gen_op_load_gpr_T0(int reg)
440
{
441
    gen_op_load_gpr_TN(0, reg);
442
}
443

    
444
static inline void gen_op_load_gpr_T1(int reg)
445
{
446
    gen_op_load_gpr_TN(1, reg);
447
}
448

    
449
static inline void gen_op_store_gpr_TN(int t_index, int reg)
450
{
451
    tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
452
}
453

    
454
static inline void gen_op_store_gpr_T0(int reg)
455
{
456
    gen_op_store_gpr_TN(0, reg);
457
}
458

    
459
static inline void gen_op_store_gpr_T1(int reg)
460
{
461
    gen_op_store_gpr_TN(1, reg);
462
}
463

    
464
/* Moves to/from shadow registers */
465
static inline void gen_op_load_srsgpr_T0(int reg)
466
{
467
    int r_tmp = tcg_temp_new(TCG_TYPE_I32);
468

    
469
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
470
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
471
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
472
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
473
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
474

    
475
    tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
476
}
477

    
478
static inline void gen_op_store_srsgpr_T0(int reg)
479
{
480
    int r_tmp = tcg_temp_new(TCG_TYPE_I32);
481

    
482
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
483
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
484
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
485
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
486
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
487

    
488
    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
489
}
490

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

    
497
#define FGEN32(func, NAME)                       \
498
static GenOpFunc *NAME ## _table [32] = {        \
499
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
500
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
501
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
502
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
503
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
504
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
505
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
506
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
507
};                                               \
508
static always_inline void func(int n)            \
509
{                                                \
510
    NAME ## _table[n]();                         \
511
}
512

    
513
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
514
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
515

    
516
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
517
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
518

    
519
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
520
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
521

    
522
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
523
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
524

    
525
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
526
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
527

    
528
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
529
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
530

    
531
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
532
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
533

    
534
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
535
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
536

    
537
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
538
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
539

    
540
#define FOP_CONDS(type, fmt)                                            \
541
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
542
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
543
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
544
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
545
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
546
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
547
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
548
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
549
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
550
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
551
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
552
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
553
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
554
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
555
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
556
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
557
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
558
};                                                                      \
559
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
560
{                                                                       \
561
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
562
}
563

    
564
FOP_CONDS(, d)
565
FOP_CONDS(abs, d)
566
FOP_CONDS(, s)
567
FOP_CONDS(abs, s)
568
FOP_CONDS(, ps)
569
FOP_CONDS(abs, ps)
570

    
571
typedef struct DisasContext {
572
    struct TranslationBlock *tb;
573
    target_ulong pc, saved_pc;
574
    uint32_t opcode;
575
    uint32_t fp_status;
576
    /* Routine used to access memory */
577
    int mem_idx;
578
    uint32_t hflags, saved_hflags;
579
    int bstate;
580
    target_ulong btarget;
581
    void *last_T0_store;
582
    int last_T0_gpr;
583
} DisasContext;
584

    
585
enum {
586
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
587
                      * exception condition
588
                      */
589
    BS_STOP     = 1, /* We want to stop translation for any reason */
590
    BS_BRANCH   = 2, /* We reached a branch condition     */
591
    BS_EXCP     = 3, /* We reached an exception condition */
592
};
593

    
594
#ifdef MIPS_DEBUG_DISAS
595
#define MIPS_DEBUG(fmt, args...)                                              \
596
do {                                                                          \
597
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
598
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
599
                ctx->pc, ctx->opcode , ##args);                               \
600
    }                                                                         \
601
} while (0)
602
#else
603
#define MIPS_DEBUG(fmt, args...) do { } while(0)
604
#endif
605

    
606
#define MIPS_INVAL(op)                                                        \
607
do {                                                                          \
608
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
609
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
610
} while (0)
611

    
612
#define GEN_LOAD_REG_T0(Rn)                                                   \
613
do {                                                                          \
614
    if (Rn == 0) {                                                            \
615
        gen_op_reset_T0();                                                    \
616
    } else {                                                                  \
617
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
618
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
619
                gen_op_load_gpr_T0(Rn);                                       \
620
        }                                                                     \
621
    }                                                                         \
622
} while (0)
623

    
624
#define GEN_LOAD_REG_T1(Rn)                                                   \
625
do {                                                                          \
626
    if (Rn == 0) {                                                            \
627
        gen_op_reset_T1();                                                    \
628
    } else {                                                                  \
629
        gen_op_load_gpr_T1(Rn);                                               \
630
    }                                                                         \
631
} while (0)
632

    
633
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
634
do {                                                                          \
635
    if (Rn == 0) {                                                            \
636
        glue(gen_op_reset_, Tn)();                                            \
637
    } else {                                                                  \
638
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
639
    }                                                                         \
640
} while (0)
641

    
642
#if defined(TARGET_MIPS64)
643
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
644
do {                                                                          \
645
    if (Imm == 0) {                                                           \
646
        glue(gen_op_reset_, Tn)();                                            \
647
    } else if ((int32_t)Imm == Imm) {                                         \
648
        glue(gen_op_set_, Tn)(Imm);                                           \
649
    } else {                                                                  \
650
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
651
    }                                                                         \
652
} while (0)
653
#else
654
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
655
do {                                                                          \
656
    if (Imm == 0) {                                                           \
657
        glue(gen_op_reset_, Tn)();                                            \
658
    } else {                                                                  \
659
        glue(gen_op_set_, Tn)(Imm);                                           \
660
    }                                                                         \
661
} while (0)
662
#endif
663

    
664
#define GEN_STORE_T0_REG(Rn)                                                  \
665
do {                                                                          \
666
    if (Rn != 0) {                                                            \
667
        gen_op_store_gpr_T0(Rn);                                              \
668
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
669
        ctx->glue(last_T0,_gpr) = Rn;                                         \
670
    }                                                                         \
671
} while (0)
672

    
673
#define GEN_STORE_T1_REG(Rn)                                                  \
674
do {                                                                          \
675
    if (Rn != 0)                                                              \
676
        gen_op_store_gpr_T1(Rn);                                              \
677
} while (0)
678

    
679
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
680
do {                                                                          \
681
    if (Rn != 0)                                                              \
682
        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \
683
} while (0)
684

    
685
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
686
do {                                                                          \
687
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
688
} while (0)
689

    
690
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
691
do {                                                                          \
692
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
693
} while (0)
694

    
695
static always_inline void gen_save_pc(target_ulong pc)
696
{
697
#if defined(TARGET_MIPS64)
698
    if (pc == (int32_t)pc) {
699
        gen_op_save_pc(pc);
700
    } else {
701
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
702
    }
703
#else
704
    gen_op_save_pc(pc);
705
#endif
706
}
707

    
708
static always_inline void gen_save_btarget(target_ulong btarget)
709
{
710
#if defined(TARGET_MIPS64)
711
    if (btarget == (int32_t)btarget) {
712
        gen_op_save_btarget(btarget);
713
    } else {
714
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
715
    }
716
#else
717
    gen_op_save_btarget(btarget);
718
#endif
719
}
720

    
721
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
722
{
723
#if defined MIPS_DEBUG_DISAS
724
    if (loglevel & CPU_LOG_TB_IN_ASM) {
725
            fprintf(logfile, "hflags %08x saved %08x\n",
726
                    ctx->hflags, ctx->saved_hflags);
727
    }
728
#endif
729
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
730
        gen_save_pc(ctx->pc);
731
        ctx->saved_pc = ctx->pc;
732
    }
733
    if (ctx->hflags != ctx->saved_hflags) {
734
        gen_op_save_state(ctx->hflags);
735
        ctx->saved_hflags = ctx->hflags;
736
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
737
        case MIPS_HFLAG_BR:
738
            break;
739
        case MIPS_HFLAG_BC:
740
        case MIPS_HFLAG_BL:
741
        case MIPS_HFLAG_B:
742
            gen_save_btarget(ctx->btarget);
743
            break;
744
        }
745
    }
746
}
747

    
748
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
749
{
750
    ctx->saved_hflags = ctx->hflags;
751
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
752
    case MIPS_HFLAG_BR:
753
        break;
754
    case MIPS_HFLAG_BC:
755
    case MIPS_HFLAG_BL:
756
    case MIPS_HFLAG_B:
757
        ctx->btarget = env->btarget;
758
        break;
759
    }
760
}
761

    
762
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
763
{
764
#if defined MIPS_DEBUG_DISAS
765
    if (loglevel & CPU_LOG_TB_IN_ASM)
766
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
767
#endif
768
    save_cpu_state(ctx, 1);
769
    if (err == 0)
770
        gen_op_raise_exception(excp);
771
    else
772
        gen_op_raise_exception_err(excp, err);
773
    ctx->bstate = BS_EXCP;
774
}
775

    
776
static always_inline void generate_exception (DisasContext *ctx, int excp)
777
{
778
    generate_exception_err (ctx, excp, 0);
779
}
780

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

    
787
static always_inline void check_cp1_enabled(DisasContext *ctx)
788
{
789
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
790
        generate_exception_err(ctx, EXCP_CpU, 1);
791
}
792

    
793
/* Verify that the processor is running with COP1X instructions enabled.
794
   This is associated with the nabla symbol in the MIPS32 and MIPS64
795
   opcode tables.  */
796

    
797
static always_inline void check_cop1x(DisasContext *ctx)
798
{
799
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
800
        generate_exception(ctx, EXCP_RI);
801
}
802

    
803
/* Verify that the processor is running with 64-bit floating-point
804
   operations enabled.  */
805

    
806
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
807
{
808
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
809
        generate_exception(ctx, EXCP_RI);
810
}
811

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

    
829
/* This code generates a "reserved instruction" exception if the
830
   CPU does not support the instruction set corresponding to flags. */
831
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
832
{
833
    if (unlikely(!(env->insn_flags & flags)))
834
        generate_exception(ctx, EXCP_RI);
835
}
836

    
837
/* This code generates a "reserved instruction" exception if 64-bit
838
   instructions are not enabled. */
839
static always_inline void check_mips_64(DisasContext *ctx)
840
{
841
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
842
        generate_exception(ctx, EXCP_RI);
843
}
844

    
845
/* load/store instructions. */
846
#if defined(CONFIG_USER_ONLY)
847
#define op_ldst(name)        gen_op_##name##_raw()
848
#define OP_LD_TABLE(width)
849
#define OP_ST_TABLE(width)
850
#else
851
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
852
#define OP_LD_TABLE(width)                                                    \
853
static GenOpFunc *gen_op_l##width[] = {                                       \
854
    &gen_op_l##width##_kernel,                                                \
855
    &gen_op_l##width##_super,                                                 \
856
    &gen_op_l##width##_user,                                                  \
857
}
858
#define OP_ST_TABLE(width)                                                    \
859
static GenOpFunc *gen_op_s##width[] = {                                       \
860
    &gen_op_s##width##_kernel,                                                \
861
    &gen_op_s##width##_super,                                                 \
862
    &gen_op_s##width##_user,                                                  \
863
}
864
#endif
865

    
866
#if defined(TARGET_MIPS64)
867
OP_LD_TABLE(d);
868
OP_LD_TABLE(dl);
869
OP_LD_TABLE(dr);
870
OP_ST_TABLE(d);
871
OP_ST_TABLE(dl);
872
OP_ST_TABLE(dr);
873
OP_LD_TABLE(ld);
874
OP_ST_TABLE(cd);
875
OP_LD_TABLE(wu);
876
#endif
877
OP_LD_TABLE(w);
878
OP_LD_TABLE(wl);
879
OP_LD_TABLE(wr);
880
OP_ST_TABLE(w);
881
OP_ST_TABLE(wl);
882
OP_ST_TABLE(wr);
883
OP_LD_TABLE(h);
884
OP_LD_TABLE(hu);
885
OP_ST_TABLE(h);
886
OP_LD_TABLE(b);
887
OP_LD_TABLE(bu);
888
OP_ST_TABLE(b);
889
OP_LD_TABLE(l);
890
OP_ST_TABLE(c);
891
OP_LD_TABLE(wc1);
892
OP_ST_TABLE(wc1);
893
OP_LD_TABLE(dc1);
894
OP_ST_TABLE(dc1);
895
OP_LD_TABLE(uxc1);
896
OP_ST_TABLE(uxc1);
897

    
898
/* Load and store */
899
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
900
                      int base, int16_t offset)
901
{
902
    const char *opn = "ldst";
903

    
904
    if (base == 0) {
905
        GEN_LOAD_IMM_TN(T0, offset);
906
    } else if (offset == 0) {
907
        gen_op_load_gpr_T0(base);
908
    } else {
909
        gen_op_load_gpr_T0(base);
910
        gen_op_set_T1(offset);
911
        gen_op_addr_add();
912
    }
913
    /* Don't do NOP if destination is zero: we must perform the actual
914
       memory access. */
915
    switch (opc) {
916
#if defined(TARGET_MIPS64)
917
    case OPC_LWU:
918
        op_ldst(lwu);
919
        GEN_STORE_T0_REG(rt);
920
        opn = "lwu";
921
        break;
922
    case OPC_LD:
923
        op_ldst(ld);
924
        GEN_STORE_T0_REG(rt);
925
        opn = "ld";
926
        break;
927
    case OPC_LLD:
928
        op_ldst(lld);
929
        GEN_STORE_T0_REG(rt);
930
        opn = "lld";
931
        break;
932
    case OPC_SD:
933
        GEN_LOAD_REG_T1(rt);
934
        op_ldst(sd);
935
        opn = "sd";
936
        break;
937
    case OPC_SCD:
938
        save_cpu_state(ctx, 1);
939
        GEN_LOAD_REG_T1(rt);
940
        op_ldst(scd);
941
        GEN_STORE_T0_REG(rt);
942
        opn = "scd";
943
        break;
944
    case OPC_LDL:
945
        GEN_LOAD_REG_T1(rt);
946
        op_ldst(ldl);
947
        GEN_STORE_T1_REG(rt);
948
        opn = "ldl";
949
        break;
950
    case OPC_SDL:
951
        GEN_LOAD_REG_T1(rt);
952
        op_ldst(sdl);
953
        opn = "sdl";
954
        break;
955
    case OPC_LDR:
956
        GEN_LOAD_REG_T1(rt);
957
        op_ldst(ldr);
958
        GEN_STORE_T1_REG(rt);
959
        opn = "ldr";
960
        break;
961
    case OPC_SDR:
962
        GEN_LOAD_REG_T1(rt);
963
        op_ldst(sdr);
964
        opn = "sdr";
965
        break;
966
#endif
967
    case OPC_LW:
968
        op_ldst(lw);
969
        GEN_STORE_T0_REG(rt);
970
        opn = "lw";
971
        break;
972
    case OPC_SW:
973
        GEN_LOAD_REG_T1(rt);
974
        op_ldst(sw);
975
        opn = "sw";
976
        break;
977
    case OPC_LH:
978
        op_ldst(lh);
979
        GEN_STORE_T0_REG(rt);
980
        opn = "lh";
981
        break;
982
    case OPC_SH:
983
        GEN_LOAD_REG_T1(rt);
984
        op_ldst(sh);
985
        opn = "sh";
986
        break;
987
    case OPC_LHU:
988
        op_ldst(lhu);
989
        GEN_STORE_T0_REG(rt);
990
        opn = "lhu";
991
        break;
992
    case OPC_LB:
993
        op_ldst(lb);
994
        GEN_STORE_T0_REG(rt);
995
        opn = "lb";
996
        break;
997
    case OPC_SB:
998
        GEN_LOAD_REG_T1(rt);
999
        op_ldst(sb);
1000
        opn = "sb";
1001
        break;
1002
    case OPC_LBU:
1003
        op_ldst(lbu);
1004
        GEN_STORE_T0_REG(rt);
1005
        opn = "lbu";
1006
        break;
1007
    case OPC_LWL:
1008
        GEN_LOAD_REG_T1(rt);
1009
        op_ldst(lwl);
1010
        GEN_STORE_T1_REG(rt);
1011
        opn = "lwl";
1012
        break;
1013
    case OPC_SWL:
1014
        GEN_LOAD_REG_T1(rt);
1015
        op_ldst(swl);
1016
        opn = "swr";
1017
        break;
1018
    case OPC_LWR:
1019
        GEN_LOAD_REG_T1(rt);
1020
        op_ldst(lwr);
1021
        GEN_STORE_T1_REG(rt);
1022
        opn = "lwr";
1023
        break;
1024
    case OPC_SWR:
1025
        GEN_LOAD_REG_T1(rt);
1026
        op_ldst(swr);
1027
        opn = "swr";
1028
        break;
1029
    case OPC_LL:
1030
        op_ldst(ll);
1031
        GEN_STORE_T0_REG(rt);
1032
        opn = "ll";
1033
        break;
1034
    case OPC_SC:
1035
        save_cpu_state(ctx, 1);
1036
        GEN_LOAD_REG_T1(rt);
1037
        op_ldst(sc);
1038
        GEN_STORE_T0_REG(rt);
1039
        opn = "sc";
1040
        break;
1041
    default:
1042
        MIPS_INVAL(opn);
1043
        generate_exception(ctx, EXCP_RI);
1044
        return;
1045
    }
1046
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1047
}
1048

    
1049
/* Load and store */
1050
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1051
                      int base, int16_t offset)
1052
{
1053
    const char *opn = "flt_ldst";
1054

    
1055
    if (base == 0) {
1056
        GEN_LOAD_IMM_TN(T0, offset);
1057
    } else if (offset == 0) {
1058
        gen_op_load_gpr_T0(base);
1059
    } else {
1060
        gen_op_load_gpr_T0(base);
1061
        gen_op_set_T1(offset);
1062
        gen_op_addr_add();
1063
    }
1064
    /* Don't do NOP if destination is zero: we must perform the actual
1065
       memory access. */
1066
    switch (opc) {
1067
    case OPC_LWC1:
1068
        op_ldst(lwc1);
1069
        GEN_STORE_FTN_FREG(ft, WT0);
1070
        opn = "lwc1";
1071
        break;
1072
    case OPC_SWC1:
1073
        GEN_LOAD_FREG_FTN(WT0, ft);
1074
        op_ldst(swc1);
1075
        opn = "swc1";
1076
        break;
1077
    case OPC_LDC1:
1078
        op_ldst(ldc1);
1079
        GEN_STORE_FTN_FREG(ft, DT0);
1080
        opn = "ldc1";
1081
        break;
1082
    case OPC_SDC1:
1083
        GEN_LOAD_FREG_FTN(DT0, ft);
1084
        op_ldst(sdc1);
1085
        opn = "sdc1";
1086
        break;
1087
    default:
1088
        MIPS_INVAL(opn);
1089
        generate_exception(ctx, EXCP_RI);
1090
        return;
1091
    }
1092
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1093
}
1094

    
1095
/* Arithmetic with immediate operand */
1096
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1097
                           int rt, int rs, int16_t imm)
1098
{
1099
    target_ulong uimm;
1100
    const char *opn = "imm arith";
1101

    
1102
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1103
        /* If no destination, treat it as a NOP.
1104
           For addi, we must generate the overflow exception when needed. */
1105
        MIPS_DEBUG("NOP");
1106
        return;
1107
    }
1108
    uimm = (uint16_t)imm;
1109
    switch (opc) {
1110
    case OPC_ADDI:
1111
    case OPC_ADDIU:
1112
#if defined(TARGET_MIPS64)
1113
    case OPC_DADDI:
1114
    case OPC_DADDIU:
1115
#endif
1116
    case OPC_SLTI:
1117
    case OPC_SLTIU:
1118
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1119
        /* Fall through. */
1120
    case OPC_ANDI:
1121
    case OPC_ORI:
1122
    case OPC_XORI:
1123
        GEN_LOAD_REG_T0(rs);
1124
        GEN_LOAD_IMM_TN(T1, uimm);
1125
        break;
1126
    case OPC_LUI:
1127
        GEN_LOAD_IMM_TN(T0, imm << 16);
1128
        break;
1129
    case OPC_SLL:
1130
    case OPC_SRA:
1131
    case OPC_SRL:
1132
#if defined(TARGET_MIPS64)
1133
    case OPC_DSLL:
1134
    case OPC_DSRA:
1135
    case OPC_DSRL:
1136
    case OPC_DSLL32:
1137
    case OPC_DSRA32:
1138
    case OPC_DSRL32:
1139
#endif
1140
        uimm &= 0x1f;
1141
        GEN_LOAD_REG_T0(rs);
1142
        GEN_LOAD_IMM_TN(T1, uimm);
1143
        break;
1144
    }
1145
    switch (opc) {
1146
    case OPC_ADDI:
1147
        save_cpu_state(ctx, 1);
1148
        gen_op_addo();
1149
        opn = "addi";
1150
        break;
1151
    case OPC_ADDIU:
1152
        gen_op_add();
1153
        opn = "addiu";
1154
        break;
1155
#if defined(TARGET_MIPS64)
1156
    case OPC_DADDI:
1157
        save_cpu_state(ctx, 1);
1158
        gen_op_daddo();
1159
        opn = "daddi";
1160
        break;
1161
    case OPC_DADDIU:
1162
        gen_op_dadd();
1163
        opn = "daddiu";
1164
        break;
1165
#endif
1166
    case OPC_SLTI:
1167
        gen_op_lt();
1168
        opn = "slti";
1169
        break;
1170
    case OPC_SLTIU:
1171
        gen_op_ltu();
1172
        opn = "sltiu";
1173
        break;
1174
    case OPC_ANDI:
1175
        gen_op_and();
1176
        opn = "andi";
1177
        break;
1178
    case OPC_ORI:
1179
        gen_op_or();
1180
        opn = "ori";
1181
        break;
1182
    case OPC_XORI:
1183
        gen_op_xor();
1184
        opn = "xori";
1185
        break;
1186
    case OPC_LUI:
1187
        opn = "lui";
1188
        break;
1189
    case OPC_SLL:
1190
        gen_op_sll();
1191
        opn = "sll";
1192
        break;
1193
    case OPC_SRA:
1194
        gen_op_sra();
1195
        opn = "sra";
1196
        break;
1197
    case OPC_SRL:
1198
        switch ((ctx->opcode >> 21) & 0x1f) {
1199
        case 0:
1200
            gen_op_srl();
1201
            opn = "srl";
1202
            break;
1203
        case 1:
1204
            /* rotr is decoded as srl on non-R2 CPUs */
1205
            if (env->insn_flags & ISA_MIPS32R2) {
1206
                gen_op_rotr();
1207
                opn = "rotr";
1208
            } else {
1209
                gen_op_srl();
1210
                opn = "srl";
1211
            }
1212
            break;
1213
        default:
1214
            MIPS_INVAL("invalid srl flag");
1215
            generate_exception(ctx, EXCP_RI);
1216
            break;
1217
        }
1218
        break;
1219
#if defined(TARGET_MIPS64)
1220
    case OPC_DSLL:
1221
        gen_op_dsll();
1222
        opn = "dsll";
1223
        break;
1224
    case OPC_DSRA:
1225
        gen_op_dsra();
1226
        opn = "dsra";
1227
        break;
1228
    case OPC_DSRL:
1229
        switch ((ctx->opcode >> 21) & 0x1f) {
1230
        case 0:
1231
            gen_op_dsrl();
1232
            opn = "dsrl";
1233
            break;
1234
        case 1:
1235
            /* drotr is decoded as dsrl on non-R2 CPUs */
1236
            if (env->insn_flags & ISA_MIPS32R2) {
1237
                gen_op_drotr();
1238
                opn = "drotr";
1239
            } else {
1240
                gen_op_dsrl();
1241
                opn = "dsrl";
1242
            }
1243
            break;
1244
        default:
1245
            MIPS_INVAL("invalid dsrl flag");
1246
            generate_exception(ctx, EXCP_RI);
1247
            break;
1248
        }
1249
        break;
1250
    case OPC_DSLL32:
1251
        gen_op_dsll32();
1252
        opn = "dsll32";
1253
        break;
1254
    case OPC_DSRA32:
1255
        gen_op_dsra32();
1256
        opn = "dsra32";
1257
        break;
1258
    case OPC_DSRL32:
1259
        switch ((ctx->opcode >> 21) & 0x1f) {
1260
        case 0:
1261
            gen_op_dsrl32();
1262
            opn = "dsrl32";
1263
            break;
1264
        case 1:
1265
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1266
            if (env->insn_flags & ISA_MIPS32R2) {
1267
                gen_op_drotr32();
1268
                opn = "drotr32";
1269
            } else {
1270
                gen_op_dsrl32();
1271
                opn = "dsrl32";
1272
            }
1273
            break;
1274
        default:
1275
            MIPS_INVAL("invalid dsrl32 flag");
1276
            generate_exception(ctx, EXCP_RI);
1277
            break;
1278
        }
1279
        break;
1280
#endif
1281
    default:
1282
        MIPS_INVAL(opn);
1283
        generate_exception(ctx, EXCP_RI);
1284
        return;
1285
    }
1286
    GEN_STORE_T0_REG(rt);
1287
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1288
}
1289

    
1290
/* Arithmetic */
1291
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1292
                       int rd, int rs, int rt)
1293
{
1294
    const char *opn = "arith";
1295

    
1296
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1297
       && opc != OPC_DADD && opc != OPC_DSUB) {
1298
        /* If no destination, treat it as a NOP.
1299
           For add & sub, we must generate the overflow exception when needed. */
1300
        MIPS_DEBUG("NOP");
1301
        return;
1302
    }
1303
    GEN_LOAD_REG_T0(rs);
1304
    /* Specialcase the conventional move operation. */
1305
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1306
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1307
        GEN_STORE_T0_REG(rd);
1308
        return;
1309
    }
1310
    GEN_LOAD_REG_T1(rt);
1311
    switch (opc) {
1312
    case OPC_ADD:
1313
        save_cpu_state(ctx, 1);
1314
        gen_op_addo();
1315
        opn = "add";
1316
        break;
1317
    case OPC_ADDU:
1318
        gen_op_add();
1319
        opn = "addu";
1320
        break;
1321
    case OPC_SUB:
1322
        save_cpu_state(ctx, 1);
1323
        gen_op_subo();
1324
        opn = "sub";
1325
        break;
1326
    case OPC_SUBU:
1327
        gen_op_sub();
1328
        opn = "subu";
1329
        break;
1330
#if defined(TARGET_MIPS64)
1331
    case OPC_DADD:
1332
        save_cpu_state(ctx, 1);
1333
        gen_op_daddo();
1334
        opn = "dadd";
1335
        break;
1336
    case OPC_DADDU:
1337
        gen_op_dadd();
1338
        opn = "daddu";
1339
        break;
1340
    case OPC_DSUB:
1341
        save_cpu_state(ctx, 1);
1342
        gen_op_dsubo();
1343
        opn = "dsub";
1344
        break;
1345
    case OPC_DSUBU:
1346
        gen_op_dsub();
1347
        opn = "dsubu";
1348
        break;
1349
#endif
1350
    case OPC_SLT:
1351
        gen_op_lt();
1352
        opn = "slt";
1353
        break;
1354
    case OPC_SLTU:
1355
        gen_op_ltu();
1356
        opn = "sltu";
1357
        break;
1358
    case OPC_AND:
1359
        gen_op_and();
1360
        opn = "and";
1361
        break;
1362
    case OPC_NOR:
1363
        gen_op_nor();
1364
        opn = "nor";
1365
        break;
1366
    case OPC_OR:
1367
        gen_op_or();
1368
        opn = "or";
1369
        break;
1370
    case OPC_XOR:
1371
        gen_op_xor();
1372
        opn = "xor";
1373
        break;
1374
    case OPC_MUL:
1375
        gen_op_mul();
1376
        opn = "mul";
1377
        break;
1378
    case OPC_MOVN:
1379
        gen_op_movn(rd);
1380
        opn = "movn";
1381
        goto print;
1382
    case OPC_MOVZ:
1383
        gen_op_movz(rd);
1384
        opn = "movz";
1385
        goto print;
1386
    case OPC_SLLV:
1387
        gen_op_sllv();
1388
        opn = "sllv";
1389
        break;
1390
    case OPC_SRAV:
1391
        gen_op_srav();
1392
        opn = "srav";
1393
        break;
1394
    case OPC_SRLV:
1395
        switch ((ctx->opcode >> 6) & 0x1f) {
1396
        case 0:
1397
            gen_op_srlv();
1398
            opn = "srlv";
1399
            break;
1400
        case 1:
1401
            /* rotrv is decoded as srlv on non-R2 CPUs */
1402
            if (env->insn_flags & ISA_MIPS32R2) {
1403
                gen_op_rotrv();
1404
                opn = "rotrv";
1405
            } else {
1406
                gen_op_srlv();
1407
                opn = "srlv";
1408
            }
1409
            break;
1410
        default:
1411
            MIPS_INVAL("invalid srlv flag");
1412
            generate_exception(ctx, EXCP_RI);
1413
            break;
1414
        }
1415
        break;
1416
#if defined(TARGET_MIPS64)
1417
    case OPC_DSLLV:
1418
        gen_op_dsllv();
1419
        opn = "dsllv";
1420
        break;
1421
    case OPC_DSRAV:
1422
        gen_op_dsrav();
1423
        opn = "dsrav";
1424
        break;
1425
    case OPC_DSRLV:
1426
        switch ((ctx->opcode >> 6) & 0x1f) {
1427
        case 0:
1428
            gen_op_dsrlv();
1429
            opn = "dsrlv";
1430
            break;
1431
        case 1:
1432
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1433
            if (env->insn_flags & ISA_MIPS32R2) {
1434
                gen_op_drotrv();
1435
                opn = "drotrv";
1436
            } else {
1437
                gen_op_dsrlv();
1438
                opn = "dsrlv";
1439
            }
1440
            break;
1441
        default:
1442
            MIPS_INVAL("invalid dsrlv flag");
1443
            generate_exception(ctx, EXCP_RI);
1444
            break;
1445
        }
1446
        break;
1447
#endif
1448
    default:
1449
        MIPS_INVAL(opn);
1450
        generate_exception(ctx, EXCP_RI);
1451
        return;
1452
    }
1453
    GEN_STORE_T0_REG(rd);
1454
 print:
1455
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1456
}
1457

    
1458
/* Arithmetic on HI/LO registers */
1459
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1460
{
1461
    const char *opn = "hilo";
1462

    
1463
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1464
        /* Treat as NOP. */
1465
        MIPS_DEBUG("NOP");
1466
        return;
1467
    }
1468
    switch (opc) {
1469
    case OPC_MFHI:
1470
        gen_op_load_HI(0);
1471
        GEN_STORE_T0_REG(reg);
1472
        opn = "mfhi";
1473
        break;
1474
    case OPC_MFLO:
1475
        gen_op_load_LO(0);
1476
        GEN_STORE_T0_REG(reg);
1477
        opn = "mflo";
1478
        break;
1479
    case OPC_MTHI:
1480
        GEN_LOAD_REG_T0(reg);
1481
        gen_op_store_HI(0);
1482
        opn = "mthi";
1483
        break;
1484
    case OPC_MTLO:
1485
        GEN_LOAD_REG_T0(reg);
1486
        gen_op_store_LO(0);
1487
        opn = "mtlo";
1488
        break;
1489
    default:
1490
        MIPS_INVAL(opn);
1491
        generate_exception(ctx, EXCP_RI);
1492
        return;
1493
    }
1494
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1495
}
1496

    
1497
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1498
                        int rs, int rt)
1499
{
1500
    const char *opn = "mul/div";
1501

    
1502
    GEN_LOAD_REG_T0(rs);
1503
    GEN_LOAD_REG_T1(rt);
1504
    switch (opc) {
1505
    case OPC_DIV:
1506
        gen_op_div();
1507
        opn = "div";
1508
        break;
1509
    case OPC_DIVU:
1510
        gen_op_divu();
1511
        opn = "divu";
1512
        break;
1513
    case OPC_MULT:
1514
        gen_op_mult();
1515
        opn = "mult";
1516
        break;
1517
    case OPC_MULTU:
1518
        gen_op_multu();
1519
        opn = "multu";
1520
        break;
1521
#if defined(TARGET_MIPS64)
1522
    case OPC_DDIV:
1523
        gen_op_ddiv();
1524
        opn = "ddiv";
1525
        break;
1526
    case OPC_DDIVU:
1527
        gen_op_ddivu();
1528
        opn = "ddivu";
1529
        break;
1530
    case OPC_DMULT:
1531
        gen_op_dmult();
1532
        opn = "dmult";
1533
        break;
1534
    case OPC_DMULTU:
1535
        gen_op_dmultu();
1536
        opn = "dmultu";
1537
        break;
1538
#endif
1539
    case OPC_MADD:
1540
        gen_op_madd();
1541
        opn = "madd";
1542
        break;
1543
    case OPC_MADDU:
1544
        gen_op_maddu();
1545
        opn = "maddu";
1546
        break;
1547
    case OPC_MSUB:
1548
        gen_op_msub();
1549
        opn = "msub";
1550
        break;
1551
    case OPC_MSUBU:
1552
        gen_op_msubu();
1553
        opn = "msubu";
1554
        break;
1555
    default:
1556
        MIPS_INVAL(opn);
1557
        generate_exception(ctx, EXCP_RI);
1558
        return;
1559
    }
1560
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1561
}
1562

    
1563
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1564
                            int rd, int rs, int rt)
1565
{
1566
    const char *opn = "mul vr54xx";
1567

    
1568
    GEN_LOAD_REG_T0(rs);
1569
    GEN_LOAD_REG_T1(rt);
1570

    
1571
    switch (opc) {
1572
    case OPC_VR54XX_MULS:
1573
        gen_op_muls();
1574
        opn = "muls";
1575
        break;
1576
    case OPC_VR54XX_MULSU:
1577
        gen_op_mulsu();
1578
        opn = "mulsu";
1579
        break;
1580
    case OPC_VR54XX_MACC:
1581
        gen_op_macc();
1582
        opn = "macc";
1583
        break;
1584
    case OPC_VR54XX_MACCU:
1585
        gen_op_maccu();
1586
        opn = "maccu";
1587
        break;
1588
    case OPC_VR54XX_MSAC:
1589
        gen_op_msac();
1590
        opn = "msac";
1591
        break;
1592
    case OPC_VR54XX_MSACU:
1593
        gen_op_msacu();
1594
        opn = "msacu";
1595
        break;
1596
    case OPC_VR54XX_MULHI:
1597
        gen_op_mulhi();
1598
        opn = "mulhi";
1599
        break;
1600
    case OPC_VR54XX_MULHIU:
1601
        gen_op_mulhiu();
1602
        opn = "mulhiu";
1603
        break;
1604
    case OPC_VR54XX_MULSHI:
1605
        gen_op_mulshi();
1606
        opn = "mulshi";
1607
        break;
1608
    case OPC_VR54XX_MULSHIU:
1609
        gen_op_mulshiu();
1610
        opn = "mulshiu";
1611
        break;
1612
    case OPC_VR54XX_MACCHI:
1613
        gen_op_macchi();
1614
        opn = "macchi";
1615
        break;
1616
    case OPC_VR54XX_MACCHIU:
1617
        gen_op_macchiu();
1618
        opn = "macchiu";
1619
        break;
1620
    case OPC_VR54XX_MSACHI:
1621
        gen_op_msachi();
1622
        opn = "msachi";
1623
        break;
1624
    case OPC_VR54XX_MSACHIU:
1625
        gen_op_msachiu();
1626
        opn = "msachiu";
1627
        break;
1628
    default:
1629
        MIPS_INVAL("mul vr54xx");
1630
        generate_exception(ctx, EXCP_RI);
1631
        return;
1632
    }
1633
    GEN_STORE_T0_REG(rd);
1634
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1635
}
1636

    
1637
static void gen_cl (DisasContext *ctx, uint32_t opc,
1638
                    int rd, int rs)
1639
{
1640
    const char *opn = "CLx";
1641
    if (rd == 0) {
1642
        /* Treat as NOP. */
1643
        MIPS_DEBUG("NOP");
1644
        return;
1645
    }
1646
    GEN_LOAD_REG_T0(rs);
1647
    switch (opc) {
1648
    case OPC_CLO:
1649
        gen_op_clo();
1650
        opn = "clo";
1651
        break;
1652
    case OPC_CLZ:
1653
        gen_op_clz();
1654
        opn = "clz";
1655
        break;
1656
#if defined(TARGET_MIPS64)
1657
    case OPC_DCLO:
1658
        gen_op_dclo();
1659
        opn = "dclo";
1660
        break;
1661
    case OPC_DCLZ:
1662
        gen_op_dclz();
1663
        opn = "dclz";
1664
        break;
1665
#endif
1666
    default:
1667
        MIPS_INVAL(opn);
1668
        generate_exception(ctx, EXCP_RI);
1669
        return;
1670
    }
1671
    gen_op_store_gpr_T0(rd);
1672
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1673
}
1674

    
1675
/* Traps */
1676
static void gen_trap (DisasContext *ctx, uint32_t opc,
1677
                      int rs, int rt, int16_t imm)
1678
{
1679
    int cond;
1680

    
1681
    cond = 0;
1682
    /* Load needed operands */
1683
    switch (opc) {
1684
    case OPC_TEQ:
1685
    case OPC_TGE:
1686
    case OPC_TGEU:
1687
    case OPC_TLT:
1688
    case OPC_TLTU:
1689
    case OPC_TNE:
1690
        /* Compare two registers */
1691
        if (rs != rt) {
1692
            GEN_LOAD_REG_T0(rs);
1693
            GEN_LOAD_REG_T1(rt);
1694
            cond = 1;
1695
        }
1696
        break;
1697
    case OPC_TEQI:
1698
    case OPC_TGEI:
1699
    case OPC_TGEIU:
1700
    case OPC_TLTI:
1701
    case OPC_TLTIU:
1702
    case OPC_TNEI:
1703
        /* Compare register to immediate */
1704
        if (rs != 0 || imm != 0) {
1705
            GEN_LOAD_REG_T0(rs);
1706
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1707
            cond = 1;
1708
        }
1709
        break;
1710
    }
1711
    if (cond == 0) {
1712
        switch (opc) {
1713
        case OPC_TEQ:   /* rs == rs */
1714
        case OPC_TEQI:  /* r0 == 0  */
1715
        case OPC_TGE:   /* rs >= rs */
1716
        case OPC_TGEI:  /* r0 >= 0  */
1717
        case OPC_TGEU:  /* rs >= rs unsigned */
1718
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1719
            /* Always trap */
1720
            gen_op_set_T0(1);
1721
            break;
1722
        case OPC_TLT:   /* rs < rs           */
1723
        case OPC_TLTI:  /* r0 < 0            */
1724
        case OPC_TLTU:  /* rs < rs unsigned  */
1725
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1726
        case OPC_TNE:   /* rs != rs          */
1727
        case OPC_TNEI:  /* r0 != 0           */
1728
            /* Never trap: treat as NOP. */
1729
            return;
1730
        default:
1731
            MIPS_INVAL("trap");
1732
            generate_exception(ctx, EXCP_RI);
1733
            return;
1734
        }
1735
    } else {
1736
        switch (opc) {
1737
        case OPC_TEQ:
1738
        case OPC_TEQI:
1739
            gen_op_eq();
1740
            break;
1741
        case OPC_TGE:
1742
        case OPC_TGEI:
1743
            gen_op_ge();
1744
            break;
1745
        case OPC_TGEU:
1746
        case OPC_TGEIU:
1747
            gen_op_geu();
1748
            break;
1749
        case OPC_TLT:
1750
        case OPC_TLTI:
1751
            gen_op_lt();
1752
            break;
1753
        case OPC_TLTU:
1754
        case OPC_TLTIU:
1755
            gen_op_ltu();
1756
            break;
1757
        case OPC_TNE:
1758
        case OPC_TNEI:
1759
            gen_op_ne();
1760
            break;
1761
        default:
1762
            MIPS_INVAL("trap");
1763
            generate_exception(ctx, EXCP_RI);
1764
            return;
1765
        }
1766
    }
1767
    save_cpu_state(ctx, 1);
1768
    gen_op_trap();
1769
    ctx->bstate = BS_STOP;
1770
}
1771

    
1772
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1773
{
1774
    TranslationBlock *tb;
1775
    tb = ctx->tb;
1776
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1777
        tcg_gen_goto_tb(n);
1778
        gen_save_pc(dest);
1779
        tcg_gen_exit_tb((long)tb + n);
1780
    } else {
1781
        gen_save_pc(dest);
1782
        tcg_gen_exit_tb(0);
1783
    }
1784
}
1785

    
1786
static inline void tcg_gen_set_bcond(void)
1787
{
1788
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
1789
}
1790

    
1791
static inline void tcg_gen_jnz_bcond(int label)
1792
{
1793
    int r_tmp = tcg_temp_new(TCG_TYPE_TL);
1794

    
1795
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
1796
    tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);
1797
}
1798

    
1799
/* Branches (before delay slot) */
1800
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1801
                                int rs, int rt, int32_t offset)
1802
{
1803
    target_ulong btarget = -1;
1804
    int blink = 0;
1805
    int bcond = 0;
1806

    
1807
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1808
#ifdef MIPS_DEBUG_DISAS
1809
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1810
            fprintf(logfile,
1811
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1812
                    ctx->pc);
1813
        }
1814
#endif
1815
        generate_exception(ctx, EXCP_RI);
1816
        return;
1817
    }
1818

    
1819
    /* Load needed operands */
1820
    switch (opc) {
1821
    case OPC_BEQ:
1822
    case OPC_BEQL:
1823
    case OPC_BNE:
1824
    case OPC_BNEL:
1825
        /* Compare two registers */
1826
        if (rs != rt) {
1827
            GEN_LOAD_REG_T0(rs);
1828
            GEN_LOAD_REG_T1(rt);
1829
            bcond = 1;
1830
        }
1831
        btarget = ctx->pc + 4 + offset;
1832
        break;
1833
    case OPC_BGEZ:
1834
    case OPC_BGEZAL:
1835
    case OPC_BGEZALL:
1836
    case OPC_BGEZL:
1837
    case OPC_BGTZ:
1838
    case OPC_BGTZL:
1839
    case OPC_BLEZ:
1840
    case OPC_BLEZL:
1841
    case OPC_BLTZ:
1842
    case OPC_BLTZAL:
1843
    case OPC_BLTZALL:
1844
    case OPC_BLTZL:
1845
        /* Compare to zero */
1846
        if (rs != 0) {
1847
            gen_op_load_gpr_T0(rs);
1848
            bcond = 1;
1849
        }
1850
        btarget = ctx->pc + 4 + offset;
1851
        break;
1852
    case OPC_J:
1853
    case OPC_JAL:
1854
        /* Jump to immediate */
1855
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1856
        break;
1857
    case OPC_JR:
1858
    case OPC_JALR:
1859
        /* Jump to register */
1860
        if (offset != 0 && offset != 16) {
1861
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1862
               others are reserved. */
1863
            MIPS_INVAL("jump hint");
1864
            generate_exception(ctx, EXCP_RI);
1865
            return;
1866
        }
1867
        GEN_LOAD_REG_T1(rs);
1868
        gen_op_save_breg_target();
1869
        break;
1870
    default:
1871
        MIPS_INVAL("branch/jump");
1872
        generate_exception(ctx, EXCP_RI);
1873
        return;
1874
    }
1875
    if (bcond == 0) {
1876
        /* No condition to be computed */
1877
        switch (opc) {
1878
        case OPC_BEQ:     /* rx == rx        */
1879
        case OPC_BEQL:    /* rx == rx likely */
1880
        case OPC_BGEZ:    /* 0 >= 0          */
1881
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1882
        case OPC_BLEZ:    /* 0 <= 0          */
1883
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1884
            /* Always take */
1885
            ctx->hflags |= MIPS_HFLAG_B;
1886
            MIPS_DEBUG("balways");
1887
            break;
1888
        case OPC_BGEZAL:  /* 0 >= 0          */
1889
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1890
            /* Always take and link */
1891
            blink = 31;
1892
            ctx->hflags |= MIPS_HFLAG_B;
1893
            MIPS_DEBUG("balways and link");
1894
            break;
1895
        case OPC_BNE:     /* rx != rx        */
1896
        case OPC_BGTZ:    /* 0 > 0           */
1897
        case OPC_BLTZ:    /* 0 < 0           */
1898
            /* Treat as NOP. */
1899
            MIPS_DEBUG("bnever (NOP)");
1900
            return;
1901
        case OPC_BLTZAL:  /* 0 < 0           */
1902
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1903
            gen_op_store_gpr_T0(31);
1904
            MIPS_DEBUG("bnever and link");
1905
            return;
1906
        case OPC_BLTZALL: /* 0 < 0 likely */
1907
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1908
            gen_op_store_gpr_T0(31);
1909
            /* Skip the instruction in the delay slot */
1910
            MIPS_DEBUG("bnever, link and skip");
1911
            ctx->pc += 4;
1912
            return;
1913
        case OPC_BNEL:    /* rx != rx likely */
1914
        case OPC_BGTZL:   /* 0 > 0 likely */
1915
        case OPC_BLTZL:   /* 0 < 0 likely */
1916
            /* Skip the instruction in the delay slot */
1917
            MIPS_DEBUG("bnever and skip");
1918
            ctx->pc += 4;
1919
            return;
1920
        case OPC_J:
1921
            ctx->hflags |= MIPS_HFLAG_B;
1922
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1923
            break;
1924
        case OPC_JAL:
1925
            blink = 31;
1926
            ctx->hflags |= MIPS_HFLAG_B;
1927
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1928
            break;
1929
        case OPC_JR:
1930
            ctx->hflags |= MIPS_HFLAG_BR;
1931
            MIPS_DEBUG("jr %s", regnames[rs]);
1932
            break;
1933
        case OPC_JALR:
1934
            blink = rt;
1935
            ctx->hflags |= MIPS_HFLAG_BR;
1936
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1937
            break;
1938
        default:
1939
            MIPS_INVAL("branch/jump");
1940
            generate_exception(ctx, EXCP_RI);
1941
            return;
1942
        }
1943
    } else {
1944
        switch (opc) {
1945
        case OPC_BEQ:
1946
            gen_op_eq();
1947
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1948
                       regnames[rs], regnames[rt], btarget);
1949
            goto not_likely;
1950
        case OPC_BEQL:
1951
            gen_op_eq();
1952
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1953
                       regnames[rs], regnames[rt], btarget);
1954
            goto likely;
1955
        case OPC_BNE:
1956
            gen_op_ne();
1957
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1958
                       regnames[rs], regnames[rt], btarget);
1959
            goto not_likely;
1960
        case OPC_BNEL:
1961
            gen_op_ne();
1962
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1963
                       regnames[rs], regnames[rt], btarget);
1964
            goto likely;
1965
        case OPC_BGEZ:
1966
            gen_op_gez();
1967
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1968
            goto not_likely;
1969
        case OPC_BGEZL:
1970
            gen_op_gez();
1971
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1972
            goto likely;
1973
        case OPC_BGEZAL:
1974
            gen_op_gez();
1975
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1976
            blink = 31;
1977
            goto not_likely;
1978
        case OPC_BGEZALL:
1979
            gen_op_gez();
1980
            blink = 31;
1981
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1982
            goto likely;
1983
        case OPC_BGTZ:
1984
            gen_op_gtz();
1985
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1986
            goto not_likely;
1987
        case OPC_BGTZL:
1988
            gen_op_gtz();
1989
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1990
            goto likely;
1991
        case OPC_BLEZ:
1992
            gen_op_lez();
1993
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1994
            goto not_likely;
1995
        case OPC_BLEZL:
1996
            gen_op_lez();
1997
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1998
            goto likely;
1999
        case OPC_BLTZ:
2000
            gen_op_ltz();
2001
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2002
            goto not_likely;
2003
        case OPC_BLTZL:
2004
            gen_op_ltz();
2005
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2006
            goto likely;
2007
        case OPC_BLTZAL:
2008
            gen_op_ltz();
2009
            blink = 31;
2010
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2011
        not_likely:
2012
            ctx->hflags |= MIPS_HFLAG_BC;
2013
            tcg_gen_set_bcond();
2014
            break;
2015
        case OPC_BLTZALL:
2016
            gen_op_ltz();
2017
            blink = 31;
2018
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2019
        likely:
2020
            ctx->hflags |= MIPS_HFLAG_BL;
2021
            tcg_gen_set_bcond();
2022
            break;
2023
        default:
2024
            MIPS_INVAL("conditional branch/jump");
2025
            generate_exception(ctx, EXCP_RI);
2026
            return;
2027
        }
2028
    }
2029
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2030
               blink, ctx->hflags, btarget);
2031

    
2032
    ctx->btarget = btarget;
2033
    if (blink > 0) {
2034
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2035
        gen_op_store_gpr_T0(blink);
2036
    }
2037
}
2038

    
2039
/* special3 bitfield operations */
2040
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2041
                       int rs, int lsb, int msb)
2042
{
2043
    GEN_LOAD_REG_T1(rs);
2044
    switch (opc) {
2045
    case OPC_EXT:
2046
        if (lsb + msb > 31)
2047
            goto fail;
2048
        gen_op_ext(lsb, msb + 1);
2049
        break;
2050
#if defined(TARGET_MIPS64)
2051
    case OPC_DEXTM:
2052
        if (lsb + msb > 63)
2053
            goto fail;
2054
        gen_op_dext(lsb, msb + 1 + 32);
2055
        break;
2056
    case OPC_DEXTU:
2057
        if (lsb + msb > 63)
2058
            goto fail;
2059
        gen_op_dext(lsb + 32, msb + 1);
2060
        break;
2061
    case OPC_DEXT:
2062
        if (lsb + msb > 63)
2063
            goto fail;
2064
        gen_op_dext(lsb, msb + 1);
2065
        break;
2066
#endif
2067
    case OPC_INS:
2068
        if (lsb > msb)
2069
            goto fail;
2070
        GEN_LOAD_REG_T0(rt);
2071
        gen_op_ins(lsb, msb - lsb + 1);
2072
        break;
2073
#if defined(TARGET_MIPS64)
2074
    case OPC_DINSM:
2075
        if (lsb > msb)
2076
            goto fail;
2077
        GEN_LOAD_REG_T0(rt);
2078
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2079
        break;
2080
    case OPC_DINSU:
2081
        if (lsb > msb)
2082
            goto fail;
2083
        GEN_LOAD_REG_T0(rt);
2084
        gen_op_dins(lsb + 32, msb - lsb + 1);
2085
        break;
2086
    case OPC_DINS:
2087
        if (lsb > msb)
2088
            goto fail;
2089
        GEN_LOAD_REG_T0(rt);
2090
        gen_op_dins(lsb, msb - lsb + 1);
2091
        break;
2092
#endif
2093
    default:
2094
fail:
2095
        MIPS_INVAL("bitops");
2096
        generate_exception(ctx, EXCP_RI);
2097
        return;
2098
    }
2099
    GEN_STORE_T0_REG(rt);
2100
}
2101

    
2102
/* CP0 (MMU and control) */
2103
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2104
{
2105
    const char *rn = "invalid";
2106

    
2107
    if (sel != 0)
2108
        check_insn(env, ctx, ISA_MIPS32);
2109

    
2110
    switch (reg) {
2111
    case 0:
2112
        switch (sel) {
2113
        case 0:
2114
            gen_op_mfc0_index();
2115
            rn = "Index";
2116
            break;
2117
        case 1:
2118
            check_insn(env, ctx, ASE_MT);
2119
            gen_op_mfc0_mvpcontrol();
2120
            rn = "MVPControl";
2121
            break;
2122
        case 2:
2123
            check_insn(env, ctx, ASE_MT);
2124
            gen_op_mfc0_mvpconf0();
2125
            rn = "MVPConf0";
2126
            break;
2127
        case 3:
2128
            check_insn(env, ctx, ASE_MT);
2129
            gen_op_mfc0_mvpconf1();
2130
            rn = "MVPConf1";
2131
            break;
2132
        default:
2133
            goto die;
2134
        }
2135
        break;
2136
    case 1:
2137
        switch (sel) {
2138
        case 0:
2139
            gen_op_mfc0_random();
2140
            rn = "Random";
2141
            break;
2142
        case 1:
2143
            check_insn(env, ctx, ASE_MT);
2144
            gen_op_mfc0_vpecontrol();
2145
            rn = "VPEControl";
2146
            break;
2147
        case 2:
2148
            check_insn(env, ctx, ASE_MT);
2149
            gen_op_mfc0_vpeconf0();
2150
            rn = "VPEConf0";
2151
            break;
2152
        case 3:
2153
            check_insn(env, ctx, ASE_MT);
2154
            gen_op_mfc0_vpeconf1();
2155
            rn = "VPEConf1";
2156
            break;
2157
        case 4:
2158
            check_insn(env, ctx, ASE_MT);
2159
            gen_op_mfc0_yqmask();
2160
            rn = "YQMask";
2161
            break;
2162
        case 5:
2163
            check_insn(env, ctx, ASE_MT);
2164
            gen_op_mfc0_vpeschedule();
2165
            rn = "VPESchedule";
2166
            break;
2167
        case 6:
2168
            check_insn(env, ctx, ASE_MT);
2169
            gen_op_mfc0_vpeschefback();
2170
            rn = "VPEScheFBack";
2171
            break;
2172
        case 7:
2173
            check_insn(env, ctx, ASE_MT);
2174
            gen_op_mfc0_vpeopt();
2175
            rn = "VPEOpt";
2176
            break;
2177
        default:
2178
            goto die;
2179
        }
2180
        break;
2181
    case 2:
2182
        switch (sel) {
2183
        case 0:
2184
            gen_op_mfc0_entrylo0();
2185
            rn = "EntryLo0";
2186
            break;
2187
        case 1:
2188
            check_insn(env, ctx, ASE_MT);
2189
            gen_op_mfc0_tcstatus();
2190
            rn = "TCStatus";
2191
            break;
2192
        case 2:
2193
            check_insn(env, ctx, ASE_MT);
2194
            gen_op_mfc0_tcbind();
2195
            rn = "TCBind";
2196
            break;
2197
        case 3:
2198
            check_insn(env, ctx, ASE_MT);
2199
            gen_op_mfc0_tcrestart();
2200
            rn = "TCRestart";
2201
            break;
2202
        case 4:
2203
            check_insn(env, ctx, ASE_MT);
2204
            gen_op_mfc0_tchalt();
2205
            rn = "TCHalt";
2206
            break;
2207
        case 5:
2208
            check_insn(env, ctx, ASE_MT);
2209
            gen_op_mfc0_tccontext();
2210
            rn = "TCContext";
2211
            break;
2212
        case 6:
2213
            check_insn(env, ctx, ASE_MT);
2214
            gen_op_mfc0_tcschedule();
2215
            rn = "TCSchedule";
2216
            break;
2217
        case 7:
2218
            check_insn(env, ctx, ASE_MT);
2219
            gen_op_mfc0_tcschefback();
2220
            rn = "TCScheFBack";
2221
            break;
2222
        default:
2223
            goto die;
2224
        }
2225
        break;
2226
    case 3:
2227
        switch (sel) {
2228
        case 0:
2229
            gen_op_mfc0_entrylo1();
2230
            rn = "EntryLo1";
2231
            break;
2232
        default:
2233
            goto die;
2234
        }
2235
        break;
2236
    case 4:
2237
        switch (sel) {
2238
        case 0:
2239
            gen_op_mfc0_context();
2240
            rn = "Context";
2241
            break;
2242
        case 1:
2243
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2244
            rn = "ContextConfig";
2245
//            break;
2246
        default:
2247
            goto die;
2248
        }
2249
        break;
2250
    case 5:
2251
        switch (sel) {
2252
        case 0:
2253
            gen_op_mfc0_pagemask();
2254
            rn = "PageMask";
2255
            break;
2256
        case 1:
2257
            check_insn(env, ctx, ISA_MIPS32R2);
2258
            gen_op_mfc0_pagegrain();
2259
            rn = "PageGrain";
2260
            break;
2261
        default:
2262
            goto die;
2263
        }
2264
        break;
2265
    case 6:
2266
        switch (sel) {
2267
        case 0:
2268
            gen_op_mfc0_wired();
2269
            rn = "Wired";
2270
            break;
2271
        case 1:
2272
            check_insn(env, ctx, ISA_MIPS32R2);
2273
            gen_op_mfc0_srsconf0();
2274
            rn = "SRSConf0";
2275
            break;
2276
        case 2:
2277
            check_insn(env, ctx, ISA_MIPS32R2);
2278
            gen_op_mfc0_srsconf1();
2279
            rn = "SRSConf1";
2280
            break;
2281
        case 3:
2282
            check_insn(env, ctx, ISA_MIPS32R2);
2283
            gen_op_mfc0_srsconf2();
2284
            rn = "SRSConf2";
2285
            break;
2286
        case 4:
2287
            check_insn(env, ctx, ISA_MIPS32R2);
2288
            gen_op_mfc0_srsconf3();
2289
            rn = "SRSConf3";
2290
            break;
2291
        case 5:
2292
            check_insn(env, ctx, ISA_MIPS32R2);
2293
            gen_op_mfc0_srsconf4();
2294
            rn = "SRSConf4";
2295
            break;
2296
        default:
2297
            goto die;
2298
        }
2299
        break;
2300
    case 7:
2301
        switch (sel) {
2302
        case 0:
2303
            check_insn(env, ctx, ISA_MIPS32R2);
2304
            gen_op_mfc0_hwrena();
2305
            rn = "HWREna";
2306
            break;
2307
        default:
2308
            goto die;
2309
        }
2310
        break;
2311
    case 8:
2312
        switch (sel) {
2313
        case 0:
2314
            gen_op_mfc0_badvaddr();
2315
            rn = "BadVaddr";
2316
            break;
2317
        default:
2318
            goto die;
2319
       }
2320
        break;
2321
    case 9:
2322
        switch (sel) {
2323
        case 0:
2324
            gen_op_mfc0_count();
2325
            rn = "Count";
2326
            break;
2327
        /* 6,7 are implementation dependent */
2328
        default:
2329
            goto die;
2330
        }
2331
        break;
2332
    case 10:
2333
        switch (sel) {
2334
        case 0:
2335
            gen_op_mfc0_entryhi();
2336
            rn = "EntryHi";
2337
            break;
2338
        default:
2339
            goto die;
2340
        }
2341
        break;
2342
    case 11:
2343
        switch (sel) {
2344
        case 0:
2345
            gen_op_mfc0_compare();
2346
            rn = "Compare";
2347
            break;
2348
        /* 6,7 are implementation dependent */
2349
        default:
2350
            goto die;
2351
        }
2352
        break;
2353
    case 12:
2354
        switch (sel) {
2355
        case 0:
2356
            gen_op_mfc0_status();
2357
            rn = "Status";
2358
            break;
2359
        case 1:
2360
            check_insn(env, ctx, ISA_MIPS32R2);
2361
            gen_op_mfc0_intctl();
2362
            rn = "IntCtl";
2363
            break;
2364
        case 2:
2365
            check_insn(env, ctx, ISA_MIPS32R2);
2366
            gen_op_mfc0_srsctl();
2367
            rn = "SRSCtl";
2368
            break;
2369
        case 3:
2370
            check_insn(env, ctx, ISA_MIPS32R2);
2371
            gen_op_mfc0_srsmap();
2372
            rn = "SRSMap";
2373
            break;
2374
        default:
2375
            goto die;
2376
       }
2377
        break;
2378
    case 13:
2379
        switch (sel) {
2380
        case 0:
2381
            gen_op_mfc0_cause();
2382
            rn = "Cause";
2383
            break;
2384
        default:
2385
            goto die;
2386
       }
2387
        break;
2388
    case 14:
2389
        switch (sel) {
2390
        case 0:
2391
            gen_op_mfc0_epc();
2392
            rn = "EPC";
2393
            break;
2394
        default:
2395
            goto die;
2396
        }
2397
        break;
2398
    case 15:
2399
        switch (sel) {
2400
        case 0:
2401
            gen_op_mfc0_prid();
2402
            rn = "PRid";
2403
            break;
2404
        case 1:
2405
            check_insn(env, ctx, ISA_MIPS32R2);
2406
            gen_op_mfc0_ebase();
2407
            rn = "EBase";
2408
            break;
2409
        default:
2410
            goto die;
2411
       }
2412
        break;
2413
    case 16:
2414
        switch (sel) {
2415
        case 0:
2416
            gen_op_mfc0_config0();
2417
            rn = "Config";
2418
            break;
2419
        case 1:
2420
            gen_op_mfc0_config1();
2421
            rn = "Config1";
2422
            break;
2423
        case 2:
2424
            gen_op_mfc0_config2();
2425
            rn = "Config2";
2426
            break;
2427
        case 3:
2428
            gen_op_mfc0_config3();
2429
            rn = "Config3";
2430
            break;
2431
        /* 4,5 are reserved */
2432
        /* 6,7 are implementation dependent */
2433
        case 6:
2434
            gen_op_mfc0_config6();
2435
            rn = "Config6";
2436
            break;
2437
        case 7:
2438
            gen_op_mfc0_config7();
2439
            rn = "Config7";
2440
            break;
2441
        default:
2442
            goto die;
2443
        }
2444
        break;
2445
    case 17:
2446
        switch (sel) {
2447
        case 0:
2448
            gen_op_mfc0_lladdr();
2449
            rn = "LLAddr";
2450
            break;
2451
        default:
2452
            goto die;
2453
        }
2454
        break;
2455
    case 18:
2456
        switch (sel) {
2457
        case 0 ... 7:
2458
            gen_op_mfc0_watchlo(sel);
2459
            rn = "WatchLo";
2460
            break;
2461
        default:
2462
            goto die;
2463
        }
2464
        break;
2465
    case 19:
2466
        switch (sel) {
2467
        case 0 ...7:
2468
            gen_op_mfc0_watchhi(sel);
2469
            rn = "WatchHi";
2470
            break;
2471
        default:
2472
            goto die;
2473
        }
2474
        break;
2475
    case 20:
2476
        switch (sel) {
2477
        case 0:
2478
#if defined(TARGET_MIPS64)
2479
            check_insn(env, ctx, ISA_MIPS3);
2480
            gen_op_mfc0_xcontext();
2481
            rn = "XContext";
2482
            break;
2483
#endif
2484
        default:
2485
            goto die;
2486
        }
2487
        break;
2488
    case 21:
2489
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2490
        switch (sel) {
2491
        case 0:
2492
            gen_op_mfc0_framemask();
2493
            rn = "Framemask";
2494
            break;
2495
        default:
2496
            goto die;
2497
        }
2498
        break;
2499
    case 22:
2500
        /* ignored */
2501
        rn = "'Diagnostic"; /* implementation dependent */
2502
        break;
2503
    case 23:
2504
        switch (sel) {
2505
        case 0:
2506
            gen_op_mfc0_debug(); /* EJTAG support */
2507
            rn = "Debug";
2508
            break;
2509
        case 1:
2510
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2511
            rn = "TraceControl";
2512
//            break;
2513
        case 2:
2514
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2515
            rn = "TraceControl2";
2516
//            break;
2517
        case 3:
2518
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2519
            rn = "UserTraceData";
2520
//            break;
2521
        case 4:
2522
//            gen_op_mfc0_debug(); /* PDtrace support */
2523
            rn = "TraceBPC";
2524
//            break;
2525
        default:
2526
            goto die;
2527
        }
2528
        break;
2529
    case 24:
2530
        switch (sel) {
2531
        case 0:
2532
            gen_op_mfc0_depc(); /* EJTAG support */
2533
            rn = "DEPC";
2534
            break;
2535
        default:
2536
            goto die;
2537
        }
2538
        break;
2539
    case 25:
2540
        switch (sel) {
2541
        case 0:
2542
            gen_op_mfc0_performance0();
2543
            rn = "Performance0";
2544
            break;
2545
        case 1:
2546
//            gen_op_mfc0_performance1();
2547
            rn = "Performance1";
2548
//            break;
2549
        case 2:
2550
//            gen_op_mfc0_performance2();
2551
            rn = "Performance2";
2552
//            break;
2553
        case 3:
2554
//            gen_op_mfc0_performance3();
2555
            rn = "Performance3";
2556
//            break;
2557
        case 4:
2558
//            gen_op_mfc0_performance4();
2559
            rn = "Performance4";
2560
//            break;
2561
        case 5:
2562
//            gen_op_mfc0_performance5();
2563
            rn = "Performance5";
2564
//            break;
2565
        case 6:
2566
//            gen_op_mfc0_performance6();
2567
            rn = "Performance6";
2568
//            break;
2569
        case 7:
2570
//            gen_op_mfc0_performance7();
2571
            rn = "Performance7";
2572
//            break;
2573
        default:
2574
            goto die;
2575
        }
2576
        break;
2577
    case 26:
2578
       rn = "ECC";
2579
       break;
2580
    case 27:
2581
        switch (sel) {
2582
        /* ignored */
2583
        case 0 ... 3:
2584
            rn = "CacheErr";
2585
            break;
2586
        default:
2587
            goto die;
2588
        }
2589
        break;
2590
    case 28:
2591
        switch (sel) {
2592
        case 0:
2593
        case 2:
2594
        case 4:
2595
        case 6:
2596
            gen_op_mfc0_taglo();
2597
            rn = "TagLo";
2598
            break;
2599
        case 1:
2600
        case 3:
2601
        case 5:
2602
        case 7:
2603
            gen_op_mfc0_datalo();
2604
            rn = "DataLo";
2605
            break;
2606
        default:
2607
            goto die;
2608
        }
2609
        break;
2610
    case 29:
2611
        switch (sel) {
2612
        case 0:
2613
        case 2:
2614
        case 4:
2615
        case 6:
2616
            gen_op_mfc0_taghi();
2617
            rn = "TagHi";
2618
            break;
2619
        case 1:
2620
        case 3:
2621
        case 5:
2622
        case 7:
2623
            gen_op_mfc0_datahi();
2624
            rn = "DataHi";
2625
            break;
2626
        default:
2627
            goto die;
2628
        }
2629
        break;
2630
    case 30:
2631
        switch (sel) {
2632
        case 0:
2633
            gen_op_mfc0_errorepc();
2634
            rn = "ErrorEPC";
2635
            break;
2636
        default:
2637
            goto die;
2638
        }
2639
        break;
2640
    case 31:
2641
        switch (sel) {
2642
        case 0:
2643
            gen_op_mfc0_desave(); /* EJTAG support */
2644
            rn = "DESAVE";
2645
            break;
2646
        default:
2647
            goto die;
2648
        }
2649
        break;
2650
    default:
2651
       goto die;
2652
    }
2653
#if defined MIPS_DEBUG_DISAS
2654
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2655
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2656
                rn, reg, sel);
2657
    }
2658
#endif
2659
    return;
2660

    
2661
die:
2662
#if defined MIPS_DEBUG_DISAS
2663
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2664
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2665
                rn, reg, sel);
2666
    }
2667
#endif
2668
    generate_exception(ctx, EXCP_RI);
2669
}
2670

    
2671
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2672
{
2673
    const char *rn = "invalid";
2674

    
2675
    if (sel != 0)
2676
        check_insn(env, ctx, ISA_MIPS32);
2677

    
2678
    switch (reg) {
2679
    case 0:
2680
        switch (sel) {
2681
        case 0:
2682
            gen_op_mtc0_index();
2683
            rn = "Index";
2684
            break;
2685
        case 1:
2686
            check_insn(env, ctx, ASE_MT);
2687
            gen_op_mtc0_mvpcontrol();
2688
            rn = "MVPControl";
2689
            break;
2690
        case 2:
2691
            check_insn(env, ctx, ASE_MT);
2692
            /* ignored */
2693
            rn = "MVPConf0";
2694
            break;
2695
        case 3:
2696
            check_insn(env, ctx, ASE_MT);
2697
            /* ignored */
2698
            rn = "MVPConf1";
2699
            break;
2700
        default:
2701
            goto die;
2702
        }
2703
        break;
2704
    case 1:
2705
        switch (sel) {
2706
        case 0:
2707
            /* ignored */
2708
            rn = "Random";
2709
            break;
2710
        case 1:
2711
            check_insn(env, ctx, ASE_MT);
2712
            gen_op_mtc0_vpecontrol();
2713
            rn = "VPEControl";
2714
            break;
2715
        case 2:
2716
            check_insn(env, ctx, ASE_MT);
2717
            gen_op_mtc0_vpeconf0();
2718
            rn = "VPEConf0";
2719
            break;
2720
        case 3:
2721
            check_insn(env, ctx, ASE_MT);
2722
            gen_op_mtc0_vpeconf1();
2723
            rn = "VPEConf1";
2724
            break;
2725
        case 4:
2726
            check_insn(env, ctx, ASE_MT);
2727
            gen_op_mtc0_yqmask();
2728
            rn = "YQMask";
2729
            break;
2730
        case 5:
2731
            check_insn(env, ctx, ASE_MT);
2732
            gen_op_mtc0_vpeschedule();
2733
            rn = "VPESchedule";
2734
            break;
2735
        case 6:
2736
            check_insn(env, ctx, ASE_MT);
2737
            gen_op_mtc0_vpeschefback();
2738
            rn = "VPEScheFBack";
2739
            break;
2740
        case 7:
2741
            check_insn(env, ctx, ASE_MT);
2742
            gen_op_mtc0_vpeopt();
2743
            rn = "VPEOpt";
2744
            break;
2745
        default:
2746
            goto die;
2747
        }
2748
        break;
2749
    case 2:
2750
        switch (sel) {
2751
        case 0:
2752
            gen_op_mtc0_entrylo0();
2753
            rn = "EntryLo0";
2754
            break;
2755
        case 1:
2756
            check_insn(env, ctx, ASE_MT);
2757
            gen_op_mtc0_tcstatus();
2758
            rn = "TCStatus";
2759
            break;
2760
        case 2:
2761
            check_insn(env, ctx, ASE_MT);
2762
            gen_op_mtc0_tcbind();
2763
            rn = "TCBind";
2764
            break;
2765
        case 3:
2766
            check_insn(env, ctx, ASE_MT);
2767
            gen_op_mtc0_tcrestart();
2768
            rn = "TCRestart";
2769
            break;
2770
        case 4:
2771
            check_insn(env, ctx, ASE_MT);
2772
            gen_op_mtc0_tchalt();
2773
            rn = "TCHalt";
2774
            break;
2775
        case 5:
2776
            check_insn(env, ctx, ASE_MT);
2777
            gen_op_mtc0_tccontext();
2778
            rn = "TCContext";
2779
            break;
2780
        case 6:
2781
            check_insn(env, ctx, ASE_MT);
2782
            gen_op_mtc0_tcschedule();
2783
            rn = "TCSchedule";
2784
            break;
2785
        case 7:
2786
            check_insn(env, ctx, ASE_MT);
2787
            gen_op_mtc0_tcschefback();
2788
            rn = "TCScheFBack";
2789
            break;
2790
        default:
2791
            goto die;
2792
        }
2793
        break;
2794
    case 3:
2795
        switch (sel) {
2796
        case 0:
2797
            gen_op_mtc0_entrylo1();
2798
            rn = "EntryLo1";
2799
            break;
2800
        default:
2801
            goto die;
2802
        }
2803
        break;
2804
    case 4:
2805
        switch (sel) {
2806
        case 0:
2807
            gen_op_mtc0_context();
2808
            rn = "Context";
2809
            break;
2810
        case 1:
2811
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2812
            rn = "ContextConfig";
2813
//            break;
2814
        default:
2815
            goto die;
2816
        }
2817
        break;
2818
    case 5:
2819
        switch (sel) {
2820
        case 0:
2821
            gen_op_mtc0_pagemask();
2822
            rn = "PageMask";
2823
            break;
2824
        case 1:
2825
            check_insn(env, ctx, ISA_MIPS32R2);
2826
            gen_op_mtc0_pagegrain();
2827
            rn = "PageGrain";
2828
            break;
2829
        default:
2830
            goto die;
2831
        }
2832
        break;
2833
    case 6:
2834
        switch (sel) {
2835
        case 0:
2836
            gen_op_mtc0_wired();
2837
            rn = "Wired";
2838
            break;
2839
        case 1:
2840
            check_insn(env, ctx, ISA_MIPS32R2);
2841
            gen_op_mtc0_srsconf0();
2842
            rn = "SRSConf0";
2843
            break;
2844
        case 2:
2845
            check_insn(env, ctx, ISA_MIPS32R2);
2846
            gen_op_mtc0_srsconf1();
2847
            rn = "SRSConf1";
2848
            break;
2849
        case 3:
2850
            check_insn(env, ctx, ISA_MIPS32R2);
2851
            gen_op_mtc0_srsconf2();
2852
            rn = "SRSConf2";
2853
            break;
2854
        case 4:
2855
            check_insn(env, ctx, ISA_MIPS32R2);
2856
            gen_op_mtc0_srsconf3();
2857
            rn = "SRSConf3";
2858
            break;
2859
        case 5:
2860
            check_insn(env, ctx, ISA_MIPS32R2);
2861
            gen_op_mtc0_srsconf4();
2862
            rn = "SRSConf4";
2863
            break;
2864
        default:
2865
            goto die;
2866
        }
2867
        break;
2868
    case 7:
2869
        switch (sel) {
2870
        case 0:
2871
            check_insn(env, ctx, ISA_MIPS32R2);
2872
            gen_op_mtc0_hwrena();
2873
            rn = "HWREna";
2874
            break;
2875
        default:
2876
            goto die;
2877
        }
2878
        break;
2879
    case 8:
2880
        /* ignored */
2881
        rn = "BadVaddr";
2882
        break;
2883
    case 9:
2884
        switch (sel) {
2885
        case 0:
2886
            gen_op_mtc0_count();
2887
            rn = "Count";
2888
            break;
2889
        /* 6,7 are implementation dependent */
2890
        default:
2891
            goto die;
2892
        }
2893
        /* Stop translation as we may have switched the execution mode */
2894
        ctx->bstate = BS_STOP;
2895
        break;
2896
    case 10:
2897
        switch (sel) {
2898
        case 0:
2899
            gen_op_mtc0_entryhi();
2900
            rn = "EntryHi";
2901
            break;
2902
        default:
2903
            goto die;
2904
        }
2905
        break;
2906
    case 11:
2907
        switch (sel) {
2908
        case 0:
2909
            gen_op_mtc0_compare();
2910
            rn = "Compare";
2911
            break;
2912
        /* 6,7 are implementation dependent */
2913
        default:
2914
            goto die;
2915
        }
2916
        /* Stop translation as we may have switched the execution mode */
2917
        ctx->bstate = BS_STOP;
2918
        break;
2919
    case 12:
2920
        switch (sel) {
2921
        case 0:
2922
            gen_op_mtc0_status();
2923
            /* BS_STOP isn't good enough here, hflags may have changed. */
2924
            gen_save_pc(ctx->pc + 4);
2925
            ctx->bstate = BS_EXCP;
2926
            rn = "Status";
2927
            break;
2928
        case 1:
2929
            check_insn(env, ctx, ISA_MIPS32R2);
2930
            gen_op_mtc0_intctl();
2931
            /* Stop translation as we may have switched the execution mode */
2932
            ctx->bstate = BS_STOP;
2933
            rn = "IntCtl";
2934
            break;
2935
        case 2:
2936
            check_insn(env, ctx, ISA_MIPS32R2);
2937
            gen_op_mtc0_srsctl();
2938
            /* Stop translation as we may have switched the execution mode */
2939
            ctx->bstate = BS_STOP;
2940
            rn = "SRSCtl";
2941
            break;
2942
        case 3:
2943
            check_insn(env, ctx, ISA_MIPS32R2);
2944
            gen_op_mtc0_srsmap();
2945
            /* Stop translation as we may have switched the execution mode */
2946
            ctx->bstate = BS_STOP;
2947
            rn = "SRSMap";
2948
            break;
2949
        default:
2950
            goto die;
2951
        }
2952
        break;
2953
    case 13:
2954
        switch (sel) {
2955
        case 0:
2956
            gen_op_mtc0_cause();
2957
            rn = "Cause";
2958
            break;
2959
        default:
2960
            goto die;
2961
        }
2962
        /* Stop translation as we may have switched the execution mode */
2963
        ctx->bstate = BS_STOP;
2964
        break;
2965
    case 14:
2966
        switch (sel) {
2967
        case 0:
2968
            gen_op_mtc0_epc();
2969
            rn = "EPC";
2970
            break;
2971
        default:
2972
            goto die;
2973
        }
2974
        break;
2975
    case 15:
2976
        switch (sel) {
2977
        case 0:
2978
            /* ignored */
2979
            rn = "PRid";
2980
            break;
2981
        case 1:
2982
            check_insn(env, ctx, ISA_MIPS32R2);
2983
            gen_op_mtc0_ebase();
2984
            rn = "EBase";
2985
            break;
2986
        default:
2987
            goto die;
2988
        }
2989
        break;
2990
    case 16:
2991
        switch (sel) {
2992
        case 0:
2993
            gen_op_mtc0_config0();
2994
            rn = "Config";
2995
            /* Stop translation as we may have switched the execution mode */
2996
            ctx->bstate = BS_STOP;
2997
            break;
2998
        case 1:
2999
            /* ignored, read only */
3000
            rn = "Config1";
3001
            break;
3002
        case 2:
3003
            gen_op_mtc0_config2();
3004
            rn = "Config2";
3005
            /* Stop translation as we may have switched the execution mode */
3006
            ctx->bstate = BS_STOP;
3007
            break;
3008
        case 3:
3009
            /* ignored, read only */
3010
            rn = "Config3";
3011
            break;
3012
        /* 4,5 are reserved */
3013
        /* 6,7 are implementation dependent */
3014
        case 6:
3015
            /* ignored */
3016
            rn = "Config6";
3017
            break;
3018
        case 7:
3019
            /* ignored */
3020
            rn = "Config7";
3021
            break;
3022
        default:
3023
            rn = "Invalid config selector";
3024
            goto die;
3025
        }
3026
        break;
3027
    case 17:
3028
        switch (sel) {
3029
        case 0:
3030
            /* ignored */
3031
            rn = "LLAddr";
3032
            break;
3033
        default:
3034
            goto die;
3035
        }
3036
        break;
3037
    case 18:
3038
        switch (sel) {
3039
        case 0 ... 7:
3040
            gen_op_mtc0_watchlo(sel);
3041
            rn = "WatchLo";
3042
            break;
3043
        default:
3044
            goto die;
3045
        }
3046
        break;
3047
    case 19:
3048
        switch (sel) {
3049
        case 0 ... 7:
3050
            gen_op_mtc0_watchhi(sel);
3051
            rn = "WatchHi";
3052
            break;
3053
        default:
3054
            goto die;
3055
        }
3056
        break;
3057
    case 20:
3058
        switch (sel) {
3059
        case 0:
3060
#if defined(TARGET_MIPS64)
3061
            check_insn(env, ctx, ISA_MIPS3);
3062
            gen_op_mtc0_xcontext();
3063
            rn = "XContext";
3064
            break;
3065
#endif
3066
        default:
3067
            goto die;
3068
        }
3069
        break;
3070
    case 21:
3071
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3072
        switch (sel) {
3073
        case 0:
3074
            gen_op_mtc0_framemask();
3075
            rn = "Framemask";
3076
            break;
3077
        default:
3078
            goto die;
3079
        }
3080
        break;
3081
    case 22:
3082
        /* ignored */
3083
        rn = "Diagnostic"; /* implementation dependent */
3084
        break;
3085
    case 23:
3086
        switch (sel) {
3087
        case 0:
3088
            gen_op_mtc0_debug(); /* EJTAG support */
3089
            /* BS_STOP isn't good enough here, hflags may have changed. */
3090
            gen_save_pc(ctx->pc + 4);
3091
            ctx->bstate = BS_EXCP;
3092
            rn = "Debug";
3093
            break;
3094
        case 1:
3095
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3096
            rn = "TraceControl";
3097
            /* Stop translation as we may have switched the execution mode */
3098
            ctx->bstate = BS_STOP;
3099
//            break;
3100
        case 2:
3101
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3102
            rn = "TraceControl2";
3103
            /* Stop translation as we may have switched the execution mode */
3104
            ctx->bstate = BS_STOP;
3105
//            break;
3106
        case 3:
3107
            /* Stop translation as we may have switched the execution mode */
3108
            ctx->bstate = BS_STOP;
3109
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3110
            rn = "UserTraceData";
3111
            /* Stop translation as we may have switched the execution mode */
3112
            ctx->bstate = BS_STOP;
3113
//            break;
3114
        case 4:
3115
//            gen_op_mtc0_debug(); /* PDtrace support */
3116
            /* Stop translation as we may have switched the execution mode */
3117
            ctx->bstate = BS_STOP;
3118
            rn = "TraceBPC";
3119
//            break;
3120
        default:
3121
            goto die;
3122
        }
3123
        break;
3124
    case 24:
3125
        switch (sel) {
3126
        case 0:
3127
            gen_op_mtc0_depc(); /* EJTAG support */
3128
            rn = "DEPC";
3129
            break;
3130
        default:
3131
            goto die;
3132
        }
3133
        break;
3134
    case 25:
3135
        switch (sel) {
3136
        case 0:
3137
            gen_op_mtc0_performance0();
3138
            rn = "Performance0";
3139
            break;
3140
        case 1:
3141
//            gen_op_mtc0_performance1();
3142
            rn = "Performance1";
3143
//            break;
3144
        case 2:
3145
//            gen_op_mtc0_performance2();
3146
            rn = "Performance2";
3147
//            break;
3148
        case 3:
3149
//            gen_op_mtc0_performance3();
3150
            rn = "Performance3";
3151
//            break;
3152
        case 4:
3153
//            gen_op_mtc0_performance4();
3154
            rn = "Performance4";
3155
//            break;
3156
        case 5:
3157
//            gen_op_mtc0_performance5();
3158
            rn = "Performance5";
3159
//            break;
3160
        case 6:
3161
//            gen_op_mtc0_performance6();
3162
            rn = "Performance6";
3163
//            break;
3164
        case 7:
3165
//            gen_op_mtc0_performance7();
3166
            rn = "Performance7";
3167
//            break;
3168
        default:
3169
            goto die;
3170
        }
3171
       break;
3172
    case 26:
3173
        /* ignored */
3174
        rn = "ECC";
3175
        break;
3176
    case 27:
3177
        switch (sel) {
3178
        case 0 ... 3:
3179
            /* ignored */
3180
            rn = "CacheErr";
3181
            break;
3182
        default:
3183
            goto die;
3184
        }
3185
       break;
3186
    case 28:
3187
        switch (sel) {
3188
        case 0:
3189
        case 2:
3190
        case 4:
3191
        case 6:
3192
            gen_op_mtc0_taglo();
3193
            rn = "TagLo";
3194
            break;
3195
        case 1:
3196
        case 3:
3197
        case 5:
3198
        case 7:
3199
            gen_op_mtc0_datalo();
3200
            rn = "DataLo";
3201
            break;
3202
        default:
3203
            goto die;
3204
        }
3205
        break;
3206
    case 29:
3207
        switch (sel) {
3208
        case 0:
3209
        case 2:
3210
        case 4:
3211
        case 6:
3212
            gen_op_mtc0_taghi();
3213
            rn = "TagHi";
3214
            break;
3215
        case 1:
3216
        case 3:
3217
        case 5:
3218
        case 7:
3219
            gen_op_mtc0_datahi();
3220
            rn = "DataHi";
3221
            break;
3222
        default:
3223
            rn = "invalid sel";
3224
            goto die;
3225
        }
3226
       break;
3227
    case 30:
3228
        switch (sel) {
3229
        case 0:
3230
            gen_op_mtc0_errorepc();
3231
            rn = "ErrorEPC";
3232
            break;
3233
        default:
3234
            goto die;
3235
        }
3236
        break;
3237
    case 31:
3238
        switch (sel) {
3239
        case 0:
3240
            gen_op_mtc0_desave(); /* EJTAG support */
3241
            rn = "DESAVE";
3242
            break;
3243
        default:
3244
            goto die;
3245
        }
3246
        /* Stop translation as we may have switched the execution mode */
3247
        ctx->bstate = BS_STOP;
3248
        break;
3249
    default:
3250
       goto die;
3251
    }
3252
#if defined MIPS_DEBUG_DISAS
3253
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3254
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3255
                rn, reg, sel);
3256
    }
3257
#endif
3258
    return;
3259

    
3260
die:
3261
#if defined MIPS_DEBUG_DISAS
3262
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3263
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3264
                rn, reg, sel);
3265
    }
3266
#endif
3267
    generate_exception(ctx, EXCP_RI);
3268
}
3269

    
3270
#if defined(TARGET_MIPS64)
3271
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3272
{
3273
    const char *rn = "invalid";
3274

    
3275
    if (sel != 0)
3276
        check_insn(env, ctx, ISA_MIPS64);
3277

    
3278
    switch (reg) {
3279
    case 0:
3280
        switch (sel) {
3281
        case 0:
3282
            gen_op_mfc0_index();
3283
            rn = "Index";
3284
            break;
3285
        case 1:
3286
            check_insn(env, ctx, ASE_MT);
3287
            gen_op_mfc0_mvpcontrol();
3288
            rn = "MVPControl";
3289
            break;
3290
        case 2:
3291
            check_insn(env, ctx, ASE_MT);
3292
            gen_op_mfc0_mvpconf0();
3293
            rn = "MVPConf0";
3294
            break;
3295
        case 3:
3296
            check_insn(env, ctx, ASE_MT);
3297
            gen_op_mfc0_mvpconf1();
3298
            rn = "MVPConf1";
3299
            break;
3300
        default:
3301
            goto die;
3302
        }
3303
        break;
3304
    case 1:
3305
        switch (sel) {
3306
        case 0:
3307
            gen_op_mfc0_random();
3308
            rn = "Random";
3309
            break;
3310
        case 1:
3311
            check_insn(env, ctx, ASE_MT);
3312
            gen_op_mfc0_vpecontrol();
3313
            rn = "VPEControl";
3314
            break;
3315
        case 2:
3316
            check_insn(env, ctx, ASE_MT);
3317
            gen_op_mfc0_vpeconf0();
3318
            rn = "VPEConf0";
3319
            break;
3320
        case 3:
3321
            check_insn(env, ctx, ASE_MT);
3322
            gen_op_mfc0_vpeconf1();
3323
            rn = "VPEConf1";
3324
            break;
3325
        case 4:
3326
            check_insn(env, ctx, ASE_MT);
3327
            gen_op_dmfc0_yqmask();
3328
            rn = "YQMask";
3329
            break;
3330
        case 5:
3331
            check_insn(env, ctx, ASE_MT);
3332
            gen_op_dmfc0_vpeschedule();
3333
            rn = "VPESchedule";
3334
            break;
3335
        case 6:
3336
            check_insn(env, ctx, ASE_MT);
3337
            gen_op_dmfc0_vpeschefback();
3338
            rn = "VPEScheFBack";
3339
            break;
3340
        case 7:
3341
            check_insn(env, ctx, ASE_MT);
3342
            gen_op_mfc0_vpeopt();
3343
            rn = "VPEOpt";
3344
            break;
3345
        default:
3346
            goto die;
3347
        }
3348
        break;
3349
    case 2:
3350
        switch (sel) {
3351
        case 0:
3352
            gen_op_dmfc0_entrylo0();
3353
            rn = "EntryLo0";
3354
            break;
3355
        case 1:
3356
            check_insn(env, ctx, ASE_MT);
3357
            gen_op_mfc0_tcstatus();
3358
            rn = "TCStatus";
3359
            break;
3360
        case 2:
3361
            check_insn(env, ctx, ASE_MT);
3362
            gen_op_mfc0_tcbind();
3363
            rn = "TCBind";
3364
            break;
3365
        case 3:
3366
            check_insn(env, ctx, ASE_MT);
3367
            gen_op_dmfc0_tcrestart();
3368
            rn = "TCRestart";
3369
            break;
3370
        case 4:
3371
            check_insn(env, ctx, ASE_MT);
3372
            gen_op_dmfc0_tchalt();
3373
            rn = "TCHalt";
3374
            break;
3375
        case 5:
3376
            check_insn(env, ctx, ASE_MT);
3377
            gen_op_dmfc0_tccontext();
3378
            rn = "TCContext";
3379
            break;
3380
        case 6:
3381
            check_insn(env, ctx, ASE_MT);
3382
            gen_op_dmfc0_tcschedule();
3383
            rn = "TCSchedule";
3384
            break;
3385
        case 7:
3386
            check_insn(env, ctx, ASE_MT);
3387
            gen_op_dmfc0_tcschefback();
3388
            rn = "TCScheFBack";
3389
            break;
3390
        default:
3391
            goto die;
3392
        }
3393
        break;
3394
    case 3:
3395
        switch (sel) {
3396
        case 0:
3397
            gen_op_dmfc0_entrylo1();
3398
            rn = "EntryLo1";
3399
            break;
3400
        default:
3401
            goto die;
3402
        }
3403
        break;
3404
    case 4:
3405
        switch (sel) {
3406
        case 0:
3407
            gen_op_dmfc0_context();
3408
            rn = "Context";
3409
            break;
3410
        case 1:
3411
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3412
            rn = "ContextConfig";
3413
//            break;
3414
        default:
3415
            goto die;
3416
        }
3417
        break;
3418
    case 5:
3419
        switch (sel) {
3420
        case 0:
3421
            gen_op_mfc0_pagemask();
3422
            rn = "PageMask";
3423
            break;
3424
        case 1:
3425
            check_insn(env, ctx, ISA_MIPS32R2);
3426
            gen_op_mfc0_pagegrain();
3427
            rn = "PageGrain";
3428
            break;
3429
        default:
3430
            goto die;
3431
        }
3432
        break;
3433
    case 6:
3434
        switch (sel) {
3435
        case 0:
3436
            gen_op_mfc0_wired();
3437
            rn = "Wired";
3438
            break;
3439
        case 1:
3440
            check_insn(env, ctx, ISA_MIPS32R2);
3441
            gen_op_mfc0_srsconf0();
3442
            rn = "SRSConf0";
3443
            break;
3444
        case 2:
3445
            check_insn(env, ctx, ISA_MIPS32R2);
3446
            gen_op_mfc0_srsconf1();
3447
            rn = "SRSConf1";
3448
            break;
3449
        case 3:
3450
            check_insn(env, ctx, ISA_MIPS32R2);
3451
            gen_op_mfc0_srsconf2();
3452
            rn = "SRSConf2";
3453
            break;
3454
        case 4:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_op_mfc0_srsconf3();
3457
            rn = "SRSConf3";
3458
            break;
3459
        case 5:
3460
            check_insn(env, ctx, ISA_MIPS32R2);
3461
            gen_op_mfc0_srsconf4();
3462
            rn = "SRSConf4";
3463
            break;
3464
        default:
3465
            goto die;
3466
        }
3467
        break;
3468
    case 7:
3469
        switch (sel) {
3470
        case 0:
3471
            check_insn(env, ctx, ISA_MIPS32R2);
3472
            gen_op_mfc0_hwrena();
3473
            rn = "HWREna";
3474
            break;
3475
        default:
3476
            goto die;
3477
        }
3478
        break;
3479
    case 8:
3480
        switch (sel) {
3481
        case 0:
3482
            gen_op_dmfc0_badvaddr();
3483
            rn = "BadVaddr";
3484
            break;
3485
        default:
3486
            goto die;
3487
        }
3488
        break;
3489
    case 9:
3490
        switch (sel) {
3491
        case 0:
3492
            gen_op_mfc0_count();
3493
            rn = "Count";
3494
            break;
3495
        /* 6,7 are implementation dependent */
3496
        default:
3497
            goto die;
3498
        }
3499
        break;
3500
    case 10:
3501
        switch (sel) {
3502
        case 0:
3503
            gen_op_dmfc0_entryhi();
3504
            rn = "EntryHi";
3505
            break;
3506
        default:
3507
            goto die;
3508
        }
3509
        break;
3510
    case 11:
3511
        switch (sel) {
3512
        case 0:
3513
            gen_op_mfc0_compare();
3514
            rn = "Compare";
3515
            break;
3516
        /* 6,7 are implementation dependent */
3517
        default:
3518
            goto die;
3519
        }
3520
        break;
3521
    case 12:
3522
        switch (sel) {
3523
        case 0:
3524
            gen_op_mfc0_status();
3525
            rn = "Status";
3526
            break;
3527
        case 1:
3528
            check_insn(env, ctx, ISA_MIPS32R2);
3529
            gen_op_mfc0_intctl();
3530
            rn = "IntCtl";
3531
            break;
3532
        case 2:
3533
            check_insn(env, ctx, ISA_MIPS32R2);
3534
            gen_op_mfc0_srsctl();
3535
            rn = "SRSCtl";
3536
            break;
3537
        case 3:
3538
            check_insn(env, ctx, ISA_MIPS32R2);
3539
            gen_op_mfc0_srsmap();
3540
            rn = "SRSMap";
3541
            break;
3542
        default:
3543
            goto die;
3544
        }
3545
        break;
3546
    case 13:
3547
        switch (sel) {
3548
        case 0:
3549
            gen_op_mfc0_cause();
3550
            rn = "Cause";
3551
            break;
3552
        default:
3553
            goto die;
3554
        }
3555
        break;
3556
    case 14:
3557
        switch (sel) {
3558
        case 0:
3559
            gen_op_dmfc0_epc();
3560
            rn = "EPC";
3561
            break;
3562
        default:
3563
            goto die;
3564
        }
3565
        break;
3566
    case 15:
3567
        switch (sel) {
3568
        case 0:
3569
            gen_op_mfc0_prid();
3570
            rn = "PRid";
3571
            break;
3572
        case 1:
3573
            check_insn(env, ctx, ISA_MIPS32R2);
3574
            gen_op_mfc0_ebase();
3575
            rn = "EBase";
3576
            break;
3577
        default:
3578
            goto die;
3579
        }
3580
        break;
3581
    case 16:
3582
        switch (sel) {
3583
        case 0:
3584
            gen_op_mfc0_config0();
3585
            rn = "Config";
3586
            break;
3587
        case 1:
3588
            gen_op_mfc0_config1();
3589
            rn = "Config1";
3590
            break;
3591
        case 2:
3592
            gen_op_mfc0_config2();
3593
            rn = "Config2";
3594
            break;
3595
        case 3:
3596
            gen_op_mfc0_config3();
3597
            rn = "Config3";
3598
            break;
3599
       /* 6,7 are implementation dependent */
3600
        default:
3601
            goto die;
3602
        }
3603
        break;
3604
    case 17:
3605
        switch (sel) {
3606
        case 0:
3607
            gen_op_dmfc0_lladdr();
3608
            rn = "LLAddr";
3609
            break;
3610
        default:
3611
            goto die;
3612
        }
3613
        break;
3614
    case 18:
3615
        switch (sel) {
3616
        case 0 ... 7:
3617
            gen_op_dmfc0_watchlo(sel);
3618
            rn = "WatchLo";
3619
            break;
3620
        default:
3621
            goto die;
3622
        }
3623
        break;
3624
    case 19:
3625
        switch (sel) {
3626
        case 0 ... 7:
3627
            gen_op_mfc0_watchhi(sel);
3628
            rn = "WatchHi";
3629
            break;
3630
        default:
3631
            goto die;
3632
        }
3633
        break;
3634
    case 20:
3635
        switch (sel) {
3636
        case 0:
3637
            check_insn(env, ctx, ISA_MIPS3);
3638
            gen_op_dmfc0_xcontext();
3639
            rn = "XContext";
3640
            break;
3641
        default:
3642
            goto die;
3643
        }
3644
        break;
3645
    case 21:
3646
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3647
        switch (sel) {
3648
        case 0:
3649
            gen_op_mfc0_framemask();
3650
            rn = "Framemask";
3651
            break;
3652
        default:
3653
            goto die;
3654
        }
3655
        break;
3656
    case 22:
3657
        /* ignored */
3658
        rn = "'Diagnostic"; /* implementation dependent */
3659
        break;
3660
    case 23:
3661
        switch (sel) {
3662
        case 0:
3663
            gen_op_mfc0_debug(); /* EJTAG support */
3664
            rn = "Debug";
3665
            break;
3666
        case 1:
3667
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3668
            rn = "TraceControl";
3669
//            break;
3670
        case 2:
3671
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3672
            rn = "TraceControl2";
3673
//            break;
3674
        case 3:
3675
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3676
            rn = "UserTraceData";
3677
//            break;
3678
        case 4:
3679
//            gen_op_dmfc0_debug(); /* PDtrace support */
3680
            rn = "TraceBPC";
3681
//            break;
3682
        default:
3683
            goto die;
3684
        }
3685
        break;
3686
    case 24:
3687
        switch (sel) {
3688
        case 0:
3689
            gen_op_dmfc0_depc(); /* EJTAG support */
3690
            rn = "DEPC";
3691
            break;
3692
        default:
3693
            goto die;
3694
        }
3695
        break;
3696
    case 25:
3697
        switch (sel) {
3698
        case 0:
3699
            gen_op_mfc0_performance0();
3700
            rn = "Performance0";
3701
            break;
3702
        case 1:
3703
//            gen_op_dmfc0_performance1();
3704
            rn = "Performance1";
3705
//            break;
3706
        case 2:
3707
//            gen_op_dmfc0_performance2();
3708
            rn = "Performance2";
3709
//            break;
3710
        case 3:
3711
//            gen_op_dmfc0_performance3();
3712
            rn = "Performance3";
3713
//            break;
3714
        case 4:
3715
//            gen_op_dmfc0_performance4();
3716
            rn = "Performance4";
3717
//            break;
3718
        case 5:
3719
//            gen_op_dmfc0_performance5();
3720
            rn = "Performance5";
3721
//            break;
3722
        case 6:
3723
//            gen_op_dmfc0_performance6();
3724
            rn = "Performance6";
3725
//            break;
3726
        case 7:
3727
//            gen_op_dmfc0_performance7();
3728
            rn = "Performance7";
3729
//            break;
3730
        default:
3731
            goto die;
3732
        }
3733
        break;
3734
    case 26:
3735
       rn = "ECC";
3736
       break;
3737
    case 27:
3738
        switch (sel) {
3739
        /* ignored */
3740
        case 0 ... 3:
3741
            rn = "CacheErr";
3742
            break;
3743
        default:
3744
            goto die;
3745
        }
3746
        break;
3747
    case 28:
3748
        switch (sel) {
3749
        case 0:
3750
        case 2:
3751
        case 4:
3752
        case 6:
3753
            gen_op_mfc0_taglo();
3754
            rn = "TagLo";
3755
            break;
3756
        case 1:
3757
        case 3:
3758
        case 5:
3759
        case 7:
3760
            gen_op_mfc0_datalo();
3761
            rn = "DataLo";
3762
            break;
3763
        default:
3764
            goto die;
3765
        }
3766
        break;
3767
    case 29:
3768
        switch (sel) {
3769
        case 0:
3770
        case 2:
3771
        case 4:
3772
        case 6:
3773
            gen_op_mfc0_taghi();
3774
            rn = "TagHi";
3775
            break;
3776
        case 1:
3777
        case 3:
3778
        case 5:
3779
        case 7:
3780
            gen_op_mfc0_datahi();
3781
            rn = "DataHi";
3782
            break;
3783
        default:
3784
            goto die;
3785
        }
3786
        break;
3787
    case 30:
3788
        switch (sel) {
3789
        case 0:
3790
            gen_op_dmfc0_errorepc();
3791
            rn = "ErrorEPC";
3792
            break;
3793
        default:
3794
            goto die;
3795
        }
3796
        break;
3797
    case 31:
3798
        switch (sel) {
3799
        case 0:
3800
            gen_op_mfc0_desave(); /* EJTAG support */
3801
            rn = "DESAVE";
3802
            break;
3803
        default:
3804
            goto die;
3805
        }
3806
        break;
3807
    default:
3808
        goto die;
3809
    }
3810
#if defined MIPS_DEBUG_DISAS
3811
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3812
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3813
                rn, reg, sel);
3814
    }
3815
#endif
3816
    return;
3817

    
3818
die:
3819
#if defined MIPS_DEBUG_DISAS
3820
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3821
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3822
                rn, reg, sel);
3823
    }
3824
#endif
3825
    generate_exception(ctx, EXCP_RI);
3826
}
3827

    
3828
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3829
{
3830
    const char *rn = "invalid";
3831

    
3832
    if (sel != 0)
3833
        check_insn(env, ctx, ISA_MIPS64);
3834

    
3835
    switch (reg) {
3836
    case 0:
3837
        switch (sel) {
3838
        case 0:
3839
            gen_op_mtc0_index();
3840
            rn = "Index";
3841
            break;
3842
        case 1:
3843
            check_insn(env, ctx, ASE_MT);
3844
            gen_op_mtc0_mvpcontrol();
3845
            rn = "MVPControl";
3846
            break;
3847
        case 2:
3848
            check_insn(env, ctx, ASE_MT);
3849
            /* ignored */
3850
            rn = "MVPConf0";
3851
            break;
3852
        case 3:
3853
            check_insn(env, ctx, ASE_MT);
3854
            /* ignored */
3855
            rn = "MVPConf1";
3856
            break;
3857
        default:
3858
            goto die;
3859
        }
3860
        break;
3861
    case 1:
3862
        switch (sel) {
3863
        case 0:
3864
            /* ignored */
3865
            rn = "Random";
3866
            break;
3867
        case 1:
3868
            check_insn(env, ctx, ASE_MT);
3869
            gen_op_mtc0_vpecontrol();
3870
            rn = "VPEControl";
3871
            break;
3872
        case 2:
3873
            check_insn(env, ctx, ASE_MT);
3874
            gen_op_mtc0_vpeconf0();
3875
            rn = "VPEConf0";
3876
            break;
3877
        case 3:
3878
            check_insn(env, ctx, ASE_MT);
3879
            gen_op_mtc0_vpeconf1();
3880
            rn = "VPEConf1";
3881
            break;
3882
        case 4:
3883
            check_insn(env, ctx, ASE_MT);
3884
            gen_op_mtc0_yqmask();
3885
            rn = "YQMask";
3886
            break;
3887
        case 5:
3888
            check_insn(env, ctx, ASE_MT);
3889
            gen_op_mtc0_vpeschedule();
3890
            rn = "VPESchedule";
3891
            break;
3892
        case 6:
3893
            check_insn(env, ctx, ASE_MT);
3894
            gen_op_mtc0_vpeschefback();
3895
            rn = "VPEScheFBack";
3896
            break;
3897
        case 7:
3898
            check_insn(env, ctx, ASE_MT);
3899
            gen_op_mtc0_vpeopt();
3900
            rn = "VPEOpt";
3901
            break;
3902
        default:
3903
            goto die;
3904
        }
3905
        break;
3906
    case 2:
3907
        switch (sel) {
3908
        case 0:
3909
            gen_op_mtc0_entrylo0();
3910
            rn = "EntryLo0";
3911
            break;
3912
        case 1:
3913
            check_insn(env, ctx, ASE_MT);
3914
            gen_op_mtc0_tcstatus();
3915
            rn = "TCStatus";
3916
            break;
3917
        case 2:
3918
            check_insn(env, ctx, ASE_MT);
3919
            gen_op_mtc0_tcbind();
3920
            rn = "TCBind";
3921
            break;
3922
        case 3:
3923
            check_insn(env, ctx, ASE_MT);
3924
            gen_op_mtc0_tcrestart();
3925
            rn = "TCRestart";
3926
            break;
3927
        case 4:
3928
            check_insn(env, ctx, ASE_MT);
3929
            gen_op_mtc0_tchalt();
3930
            rn = "TCHalt";
3931
            break;
3932
        case 5:
3933
            check_insn(env, ctx, ASE_MT);
3934
            gen_op_mtc0_tccontext();
3935
            rn = "TCContext";
3936
            break;
3937
        case 6:
3938
            check_insn(env, ctx, ASE_MT);
3939
            gen_op_mtc0_tcschedule();
3940
            rn = "TCSchedule";
3941
            break;
3942
        case 7:
3943
            check_insn(env, ctx, ASE_MT);
3944
            gen_op_mtc0_tcschefback();
3945
            rn = "TCScheFBack";
3946
            break;
3947
        default:
3948
            goto die;
3949
        }
3950
        break;
3951
    case 3:
3952
        switch (sel) {
3953
        case 0:
3954
            gen_op_mtc0_entrylo1();
3955
            rn = "EntryLo1";
3956
            break;
3957
        default:
3958
            goto die;
3959
        }
3960
        break;
3961
    case 4:
3962
        switch (sel) {
3963
        case 0:
3964
            gen_op_mtc0_context();
3965
            rn = "Context";
3966
            break;
3967
        case 1:
3968
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3969
            rn = "ContextConfig";
3970
//           break;
3971
        default:
3972
            goto die;
3973
        }
3974
        break;
3975
    case 5:
3976
        switch (sel) {
3977
        case 0:
3978
            gen_op_mtc0_pagemask();
3979
            rn = "PageMask";
3980
            break;
3981
        case 1:
3982
            check_insn(env, ctx, ISA_MIPS32R2);
3983
            gen_op_mtc0_pagegrain();
3984
            rn = "PageGrain";
3985
            break;
3986
        default:
3987
            goto die;
3988
        }
3989
        break;
3990
    case 6:
3991
        switch (sel) {
3992
        case 0:
3993
            gen_op_mtc0_wired();
3994
            rn = "Wired";
3995
            break;
3996
        case 1:
3997
            check_insn(env, ctx, ISA_MIPS32R2);
3998
            gen_op_mtc0_srsconf0();
3999
            rn = "SRSConf0";
4000
            break;
4001
        case 2:
4002
            check_insn(env, ctx, ISA_MIPS32R2);
4003
            gen_op_mtc0_srsconf1();
4004
            rn = "SRSConf1";
4005
            break;
4006
        case 3:
4007
            check_insn(env, ctx, ISA_MIPS32R2);
4008
            gen_op_mtc0_srsconf2();
4009
            rn = "SRSConf2";
4010
            break;
4011
        case 4:
4012
            check_insn(env, ctx, ISA_MIPS32R2);
4013
            gen_op_mtc0_srsconf3();
4014
            rn = "SRSConf3";
4015
            break;
4016
        case 5:
4017
            check_insn(env, ctx, ISA_MIPS32R2);
4018
            gen_op_mtc0_srsconf4();
4019
            rn = "SRSConf4";
4020
            break;
4021
        default:
4022
            goto die;
4023
        }
4024
        break;
4025
    case 7:
4026
        switch (sel) {
4027
        case 0:
4028
            check_insn(env, ctx, ISA_MIPS32R2);
4029
            gen_op_mtc0_hwrena();
4030
            rn = "HWREna";
4031
            break;
4032
        default:
4033
            goto die;
4034
        }
4035
        break;
4036
    case 8:
4037
        /* ignored */
4038
        rn = "BadVaddr";
4039
        break;
4040
    case 9:
4041
        switch (sel) {
4042
        case 0:
4043
            gen_op_mtc0_count();
4044
            rn = "Count";
4045
            break;
4046
        /* 6,7 are implementation dependent */
4047
        default:
4048
            goto die;
4049
        }
4050
        /* Stop translation as we may have switched the execution mode */
4051
        ctx->bstate = BS_STOP;
4052
        break;
4053
    case 10:
4054
        switch (sel) {
4055
        case 0:
4056
            gen_op_mtc0_entryhi();
4057
            rn = "EntryHi";
4058
            break;
4059
        default:
4060
            goto die;
4061
        }
4062
        break;
4063
    case 11:
4064
        switch (sel) {
4065
        case 0:
4066
            gen_op_mtc0_compare();
4067
            rn = "Compare";
4068
            break;
4069
        /* 6,7 are implementation dependent */
4070
        default:
4071
            goto die;
4072
        }
4073
        /* Stop translation as we may have switched the execution mode */
4074
        ctx->bstate = BS_STOP;
4075
        break;
4076
    case 12:
4077
        switch (sel) {
4078
        case 0:
4079
            gen_op_mtc0_status();
4080
            /* BS_STOP isn't good enough here, hflags may have changed. */
4081
            gen_save_pc(ctx->pc + 4);
4082
            ctx->bstate = BS_EXCP;
4083
            rn = "Status";
4084
            break;
4085
        case 1:
4086
            check_insn(env, ctx, ISA_MIPS32R2);
4087
            gen_op_mtc0_intctl();
4088
            /* Stop translation as we may have switched the execution mode */
4089
            ctx->bstate = BS_STOP;
4090
            rn = "IntCtl";
4091
            break;
4092
        case 2:
4093
            check_insn(env, ctx, ISA_MIPS32R2);
4094
            gen_op_mtc0_srsctl();
4095
            /* Stop translation as we may have switched the execution mode */
4096
            ctx->bstate = BS_STOP;
4097
            rn = "SRSCtl";
4098
            break;
4099
        case 3:
4100
            check_insn(env, ctx, ISA_MIPS32R2);
4101
            gen_op_mtc0_srsmap();
4102
            /* Stop translation as we may have switched the execution mode */
4103
            ctx->bstate = BS_STOP;
4104
            rn = "SRSMap";
4105
            break;
4106
        default:
4107
            goto die;
4108
        }
4109
        break;
4110
    case 13:
4111
        switch (sel) {
4112
        case 0:
4113
            gen_op_mtc0_cause();
4114
            rn = "Cause";
4115
            break;
4116
        default:
4117
            goto die;
4118
        }
4119
        /* Stop translation as we may have switched the execution mode */
4120
        ctx->bstate = BS_STOP;
4121
        break;
4122
    case 14:
4123
        switch (sel) {
4124
        case 0:
4125
            gen_op_mtc0_epc();
4126
            rn = "EPC";
4127
            break;
4128
        default:
4129
            goto die;
4130
        }
4131
        break;
4132
    case 15:
4133
        switch (sel) {
4134
        case 0:
4135
            /* ignored */
4136
            rn = "PRid";
4137
            break;
4138
        case 1:
4139
            check_insn(env, ctx, ISA_MIPS32R2);
4140
            gen_op_mtc0_ebase();
4141
            rn = "EBase";
4142
            break;
4143
        default:
4144
            goto die;
4145
        }
4146
        break;
4147
    case 16:
4148
        switch (sel) {
4149
        case 0:
4150
            gen_op_mtc0_config0();
4151
            rn = "Config";
4152
            /* Stop translation as we may have switched the execution mode */
4153
            ctx->bstate = BS_STOP;
4154
            break;
4155
        case 1:
4156
            /* ignored */
4157
            rn = "Config1";
4158
            break;
4159
        case 2:
4160
            gen_op_mtc0_config2();
4161
            rn = "Config2";
4162
            /* Stop translation as we may have switched the execution mode */
4163
            ctx->bstate = BS_STOP;
4164
            break;
4165
        case 3:
4166
            /* ignored */
4167
            rn = "Config3";
4168
            break;
4169
        /* 6,7 are implementation dependent */
4170
        default:
4171
            rn = "Invalid config selector";
4172
            goto die;
4173
        }
4174
        break;
4175
    case 17:
4176
        switch (sel) {
4177
        case 0:
4178
            /* ignored */
4179
            rn = "LLAddr";
4180
            break;
4181
        default:
4182
            goto die;
4183
        }
4184
        break;
4185
    case 18:
4186
        switch (sel) {
4187
        case 0 ... 7:
4188
            gen_op_mtc0_watchlo(sel);
4189
            rn = "WatchLo";
4190
            break;
4191
        default:
4192
            goto die;
4193
        }
4194
        break;
4195
    case 19:
4196
        switch (sel) {
4197
        case 0 ... 7:
4198
            gen_op_mtc0_watchhi(sel);
4199
            rn = "WatchHi";
4200
            break;
4201
        default:
4202
            goto die;
4203
        }
4204
        break;
4205
    case 20:
4206
        switch (sel) {
4207
        case 0:
4208
            check_insn(env, ctx, ISA_MIPS3);
4209
            gen_op_mtc0_xcontext();
4210
            rn = "XContext";
4211
            break;
4212
        default:
4213
            goto die;
4214
        }
4215
        break;
4216
    case 21:
4217
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4218
        switch (sel) {
4219
        case 0:
4220
            gen_op_mtc0_framemask();
4221
            rn = "Framemask";
4222
            break;
4223
        default:
4224
            goto die;
4225
        }
4226
        break;
4227
    case 22:
4228
        /* ignored */
4229
        rn = "Diagnostic"; /* implementation dependent */
4230
        break;
4231
    case 23:
4232
        switch (sel) {
4233
        case 0:
4234
            gen_op_mtc0_debug(); /* EJTAG support */
4235
            /* BS_STOP isn't good enough here, hflags may have changed. */
4236
            gen_save_pc(ctx->pc + 4);
4237
            ctx->bstate = BS_EXCP;
4238
            rn = "Debug";
4239
            break;
4240
        case 1:
4241
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4242
            /* Stop translation as we may have switched the execution mode */
4243
            ctx->bstate = BS_STOP;
4244
            rn = "TraceControl";
4245
//            break;
4246
        case 2:
4247
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4248
            /* Stop translation as we may have switched the execution mode */
4249
            ctx->bstate = BS_STOP;
4250
            rn = "TraceControl2";
4251
//            break;
4252
        case 3:
4253
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4254
            /* Stop translation as we may have switched the execution mode */
4255
            ctx->bstate = BS_STOP;
4256
            rn = "UserTraceData";
4257
//            break;
4258
        case 4:
4259
//            gen_op_mtc0_debug(); /* PDtrace support */
4260
            /* Stop translation as we may have switched the execution mode */
4261
            ctx->bstate = BS_STOP;
4262
            rn = "TraceBPC";
4263
//            break;
4264
        default:
4265
            goto die;
4266
        }
4267
        break;
4268
    case 24:
4269
        switch (sel) {
4270
        case 0:
4271
            gen_op_mtc0_depc(); /* EJTAG support */
4272
            rn = "DEPC";
4273
            break;
4274
        default:
4275
            goto die;
4276
        }
4277
        break;
4278
    case 25:
4279
        switch (sel) {
4280
        case 0:
4281
            gen_op_mtc0_performance0();
4282
            rn = "Performance0";
4283
            break;
4284
        case 1:
4285
//            gen_op_mtc0_performance1();
4286
            rn = "Performance1";
4287
//            break;
4288
        case 2:
4289
//            gen_op_mtc0_performance2();
4290
            rn = "Performance2";
4291
//            break;
4292
        case 3:
4293
//            gen_op_mtc0_performance3();
4294
            rn = "Performance3";
4295
//            break;
4296
        case 4:
4297
//            gen_op_mtc0_performance4();
4298
            rn = "Performance4";
4299
//            break;
4300
        case 5:
4301
//            gen_op_mtc0_performance5();
4302
            rn = "Performance5";
4303
//            break;
4304
        case 6:
4305
//            gen_op_mtc0_performance6();
4306
            rn = "Performance6";
4307
//            break;
4308
        case 7:
4309
//            gen_op_mtc0_performance7();
4310
            rn = "Performance7";
4311
//            break;
4312
        default:
4313
            goto die;
4314
        }
4315
        break;
4316
    case 26:
4317
        /* ignored */
4318
        rn = "ECC";
4319
        break;
4320
    case 27:
4321
        switch (sel) {
4322
        case 0 ... 3:
4323
            /* ignored */
4324
            rn = "CacheErr";
4325
            break;
4326
        default:
4327
            goto die;
4328
        }
4329
        break;
4330
    case 28:
4331
        switch (sel) {
4332
        case 0:
4333
        case 2:
4334
        case 4:
4335
        case 6:
4336
            gen_op_mtc0_taglo();
4337
            rn = "TagLo";
4338
            break;
4339
        case 1:
4340
        case 3:
4341
        case 5:
4342
        case 7:
4343
            gen_op_mtc0_datalo();
4344
            rn = "DataLo";
4345
            break;
4346
        default:
4347
            goto die;
4348
        }
4349
        break;
4350
    case 29:
4351
        switch (sel) {
4352
        case 0:
4353
        case 2:
4354
        case 4:
4355
        case 6:
4356
            gen_op_mtc0_taghi();
4357
            rn = "TagHi";
4358
            break;
4359
        case 1:
4360
        case 3:
4361
        case 5:
4362
        case 7:
4363
            gen_op_mtc0_datahi();
4364
            rn = "DataHi";
4365
            break;
4366
        default:
4367
            rn = "invalid sel";
4368
            goto die;
4369
        }
4370
        break;
4371
    case 30:
4372
        switch (sel) {
4373
        case 0:
4374
            gen_op_mtc0_errorepc();
4375
            rn = "ErrorEPC";
4376
            break;
4377
        default:
4378
            goto die;
4379
        }
4380
        break;
4381
    case 31:
4382
        switch (sel) {
4383
        case 0:
4384
            gen_op_mtc0_desave(); /* EJTAG support */
4385
            rn = "DESAVE";
4386
            break;
4387
        default:
4388
            goto die;
4389
        }
4390
        /* Stop translation as we may have switched the execution mode */
4391
        ctx->bstate = BS_STOP;
4392
        break;
4393
    default:
4394
        goto die;
4395
    }
4396
#if defined MIPS_DEBUG_DISAS
4397
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4398
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4399
                rn, reg, sel);
4400
    }
4401
#endif
4402
    return;
4403

    
4404
die:
4405
#if defined MIPS_DEBUG_DISAS
4406
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4407
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4408
                rn, reg, sel);
4409
    }
4410
#endif
4411
    generate_exception(ctx, EXCP_RI);
4412
}
4413
#endif /* TARGET_MIPS64 */
4414

    
4415
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4416
                     int u, int sel, int h)
4417
{
4418
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4419

    
4420
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4421
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4422
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4423
        gen_op_set_T0(-1);
4424
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4425
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4426
        gen_op_set_T0(-1);
4427
    else if (u == 0) {
4428
        switch (rt) {
4429
        case 2:
4430
            switch (sel) {
4431
            case 1:
4432
                gen_op_mftc0_tcstatus();
4433
                break;
4434
            case 2:
4435
                gen_op_mftc0_tcbind();
4436
                break;
4437
            case 3:
4438
                gen_op_mftc0_tcrestart();
4439
                break;
4440
            case 4:
4441
                gen_op_mftc0_tchalt();
4442
                break;
4443
            case 5:
4444
                gen_op_mftc0_tccontext();
4445
                break;
4446
            case 6:
4447
                gen_op_mftc0_tcschedule();
4448
                break;
4449
            case 7:
4450
                gen_op_mftc0_tcschefback();
4451
                break;
4452
            default:
4453
                gen_mfc0(env, ctx, rt, sel);
4454
                break;
4455
            }
4456
            break;
4457
        case 10:
4458
            switch (sel) {
4459
            case 0:
4460
                gen_op_mftc0_entryhi();
4461
                break;
4462
            default:
4463
                gen_mfc0(env, ctx, rt, sel);
4464
                break;
4465
            }
4466
        case 12:
4467
            switch (sel) {
4468
            case 0:
4469
                gen_op_mftc0_status();
4470
                break;
4471
            default:
4472
                gen_mfc0(env, ctx, rt, sel);
4473
                break;
4474
            }
4475
        case 23:
4476
            switch (sel) {
4477
            case 0:
4478
                gen_op_mftc0_debug();
4479
                break;
4480
            default:
4481
                gen_mfc0(env, ctx, rt, sel);
4482
                break;
4483
            }
4484
            break;
4485
        default:
4486
            gen_mfc0(env, ctx, rt, sel);
4487
        }
4488
    } else switch (sel) {
4489
    /* GPR registers. */
4490
    case 0:
4491
        gen_op_mftgpr(rt);
4492
        break;
4493
    /* Auxiliary CPU registers */
4494
    case 1:
4495
        switch (rt) {
4496
        case 0:
4497
            gen_op_mftlo(0);
4498
            break;
4499
        case 1:
4500
            gen_op_mfthi(0);
4501
            break;
4502
        case 2:
4503
            gen_op_mftacx(0);
4504
            break;
4505
        case 4:
4506
            gen_op_mftlo(1);
4507
            break;
4508
        case 5:
4509
            gen_op_mfthi(1);
4510
            break;
4511
        case 6:
4512
            gen_op_mftacx(1);
4513
            break;
4514
        case 8:
4515
            gen_op_mftlo(2);
4516
            break;
4517
        case 9:
4518
            gen_op_mfthi(2);
4519
            break;
4520
        case 10:
4521
            gen_op_mftacx(2);
4522
            break;
4523
        case 12:
4524
            gen_op_mftlo(3);
4525
            break;
4526
        case 13:
4527
            gen_op_mfthi(3);
4528
            break;
4529
        case 14:
4530
            gen_op_mftacx(3);
4531
            break;
4532
        case 16:
4533
            gen_op_mftdsp();
4534
            break;
4535
        default:
4536
            goto die;
4537
        }
4538
        break;
4539
    /* Floating point (COP1). */
4540
    case 2:
4541
        /* XXX: For now we support only a single FPU context. */
4542
        if (h == 0) {
4543
            GEN_LOAD_FREG_FTN(WT0, rt);
4544
            gen_op_mfc1();
4545
        } else {
4546
            GEN_LOAD_FREG_FTN(WTH0, rt);
4547
            gen_op_mfhc1();
4548
        }
4549
        break;
4550
    case 3:
4551
        /* XXX: For now we support only a single FPU context. */
4552
        gen_op_cfc1(rt);
4553
        break;
4554
    /* COP2: Not implemented. */
4555
    case 4:
4556
    case 5:
4557
        /* fall through */
4558
    default:
4559
        goto die;
4560
    }
4561
#if defined MIPS_DEBUG_DISAS
4562
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4563
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4564
                rt, u, sel, h);
4565
    }
4566
#endif
4567
    return;
4568

    
4569
die:
4570
#if defined MIPS_DEBUG_DISAS
4571
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4572
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4573
                rt, u, sel, h);
4574
    }
4575
#endif
4576
    generate_exception(ctx, EXCP_RI);
4577
}
4578

    
4579
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4580
                     int u, int sel, int h)
4581
{
4582
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4583

    
4584
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4585
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4586
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4587
        /* NOP */ ;
4588
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4589
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4590
        /* NOP */ ;
4591
    else if (u == 0) {
4592
        switch (rd) {
4593
        case 2:
4594
            switch (sel) {
4595
            case 1:
4596
                gen_op_mttc0_tcstatus();
4597
                break;
4598
            case 2:
4599
                gen_op_mttc0_tcbind();
4600
                break;
4601
            case 3:
4602
                gen_op_mttc0_tcrestart();
4603
                break;
4604
            case 4:
4605
                gen_op_mttc0_tchalt();
4606
                break;
4607
            case 5:
4608
                gen_op_mttc0_tccontext();
4609
                break;
4610
            case 6:
4611
                gen_op_mttc0_tcschedule();
4612
                break;
4613
            case 7:
4614
                gen_op_mttc0_tcschefback();
4615
                break;
4616
            default:
4617
                gen_mtc0(env, ctx, rd, sel);
4618
                break;
4619
            }
4620
            break;
4621
        case 10:
4622
            switch (sel) {
4623
            case 0:
4624
                gen_op_mttc0_entryhi();
4625
                break;
4626
            default:
4627
                gen_mtc0(env, ctx, rd, sel);
4628
                break;
4629
            }
4630
        case 12:
4631
            switch (sel) {
4632
            case 0:
4633
                gen_op_mttc0_status();
4634
                break;
4635
            default:
4636
                gen_mtc0(env, ctx, rd, sel);
4637
                break;
4638
            }
4639
        case 23:
4640
            switch (sel) {
4641
            case 0:
4642
                gen_op_mttc0_debug();
4643
                break;
4644
            default:
4645
                gen_mtc0(env, ctx, rd, sel);
4646
                break;
4647
            }
4648
            break;
4649
        default:
4650
            gen_mtc0(env, ctx, rd, sel);
4651
        }
4652
    } else switch (sel) {
4653
    /* GPR registers. */
4654
    case 0:
4655
        gen_op_mttgpr(rd);
4656
        break;
4657
    /* Auxiliary CPU registers */
4658
    case 1:
4659
        switch (rd) {
4660
        case 0:
4661
            gen_op_mttlo(0);
4662
            break;
4663
        case 1:
4664
            gen_op_mtthi(0);
4665
            break;
4666
        case 2:
4667
            gen_op_mttacx(0);
4668
            break;
4669
        case 4:
4670
            gen_op_mttlo(1);
4671
            break;
4672
        case 5:
4673
            gen_op_mtthi(1);
4674
            break;
4675
        case 6:
4676
            gen_op_mttacx(1);
4677
            break;
4678
        case 8:
4679
            gen_op_mttlo(2);
4680
            break;
4681
        case 9:
4682
            gen_op_mtthi(2);
4683
            break;
4684
        case 10:
4685
            gen_op_mttacx(2);
4686
            break;
4687
        case 12:
4688
            gen_op_mttlo(3);
4689
            break;
4690
        case 13:
4691
            gen_op_mtthi(3);
4692
            break;
4693
        case 14:
4694
            gen_op_mttacx(3);
4695
            break;
4696
        case 16:
4697
            gen_op_mttdsp();
4698
            break;
4699
        default:
4700
            goto die;
4701
        }
4702
        break;
4703
    /* Floating point (COP1). */
4704
    case 2:
4705
        /* XXX: For now we support only a single FPU context. */
4706
        if (h == 0) {
4707
            gen_op_mtc1();
4708
            GEN_STORE_FTN_FREG(rd, WT0);
4709
        } else {
4710
            gen_op_mthc1();
4711
            GEN_STORE_FTN_FREG(rd, WTH0);
4712
        }
4713
        break;
4714
    case 3:
4715
        /* XXX: For now we support only a single FPU context. */
4716
        gen_op_ctc1(rd);
4717
        break;
4718
    /* COP2: Not implemented. */
4719
    case 4:
4720
    case 5:
4721
        /* fall through */
4722
    default:
4723
        goto die;
4724
    }
4725
#if defined MIPS_DEBUG_DISAS
4726
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4727
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4728
                rd, u, sel, h);
4729
    }
4730
#endif
4731
    return;
4732

    
4733
die:
4734
#if defined MIPS_DEBUG_DISAS
4735
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4736
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4737
                rd, u, sel, h);
4738
    }
4739
#endif
4740
    generate_exception(ctx, EXCP_RI);
4741
}
4742

    
4743
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4744
{
4745
    const char *opn = "ldst";
4746

    
4747
    switch (opc) {
4748
    case OPC_MFC0:
4749
        if (rt == 0) {
4750
            /* Treat as NOP. */
4751
            return;
4752
        }
4753
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4754
        gen_op_store_gpr_T0(rt);
4755
        opn = "mfc0";
4756
        break;
4757
    case OPC_MTC0:
4758
        GEN_LOAD_REG_T0(rt);
4759
        save_cpu_state(ctx, 1);
4760
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4761
        opn = "mtc0";
4762
        break;
4763
#if defined(TARGET_MIPS64)
4764
    case OPC_DMFC0:
4765
        check_insn(env, ctx, ISA_MIPS3);
4766
        if (rt == 0) {
4767
            /* Treat as NOP. */
4768
            return;
4769
        }
4770
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4771
        gen_op_store_gpr_T0(rt);
4772
        opn = "dmfc0";
4773
        break;
4774
    case OPC_DMTC0:
4775
        check_insn(env, ctx, ISA_MIPS3);
4776
        GEN_LOAD_REG_T0(rt);
4777
        save_cpu_state(ctx, 1);
4778
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4779
        opn = "dmtc0";
4780
        break;
4781
#endif
4782
    case OPC_MFTR:
4783
        check_insn(env, ctx, ASE_MT);
4784
        if (rd == 0) {
4785
            /* Treat as NOP. */
4786
            return;
4787
        }
4788
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4789
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4790
        gen_op_store_gpr_T0(rd);
4791
        opn = "mftr";
4792
        break;
4793
    case OPC_MTTR:
4794
        check_insn(env, ctx, ASE_MT);
4795
        GEN_LOAD_REG_T0(rt);
4796
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4797
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4798
        opn = "mttr";
4799
        break;
4800
    case OPC_TLBWI:
4801
        opn = "tlbwi";
4802
        if (!env->tlb->do_tlbwi)
4803
            goto die;
4804
        gen_op_tlbwi();
4805
        break;
4806
    case OPC_TLBWR:
4807
        opn = "tlbwr";
4808
        if (!env->tlb->do_tlbwr)
4809
            goto die;
4810
        gen_op_tlbwr();
4811
        break;
4812
    case OPC_TLBP:
4813
        opn = "tlbp";
4814
        if (!env->tlb->do_tlbp)
4815
            goto die;
4816
        gen_op_tlbp();
4817
        break;
4818
    case OPC_TLBR:
4819
        opn = "tlbr";
4820
        if (!env->tlb->do_tlbr)
4821
            goto die;
4822
        gen_op_tlbr();
4823
        break;
4824
    case OPC_ERET:
4825
        opn = "eret";
4826
        check_insn(env, ctx, ISA_MIPS2);
4827
        save_cpu_state(ctx, 1);
4828
        gen_op_eret();
4829
        ctx->bstate = BS_EXCP;
4830
        break;
4831
    case OPC_DERET:
4832
        opn = "deret";
4833
        check_insn(env, ctx, ISA_MIPS32);
4834
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4835
            MIPS_INVAL(opn);
4836
            generate_exception(ctx, EXCP_RI);
4837
        } else {
4838
            save_cpu_state(ctx, 1);
4839
            gen_op_deret();
4840
            ctx->bstate = BS_EXCP;
4841
        }
4842
        break;
4843
    case OPC_WAIT:
4844
        opn = "wait";
4845
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4846
        /* If we get an exception, we want to restart at next instruction */
4847
        ctx->pc += 4;
4848
        save_cpu_state(ctx, 1);
4849
        ctx->pc -= 4;
4850
        gen_op_wait();
4851
        ctx->bstate = BS_EXCP;
4852
        break;
4853
    default:
4854
 die:
4855
        MIPS_INVAL(opn);
4856
        generate_exception(ctx, EXCP_RI);
4857
        return;
4858
    }
4859
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4860
}
4861

    
4862
/* CP1 Branches (before delay slot) */
4863
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4864
                                 int32_t cc, int32_t offset)
4865
{
4866
    target_ulong btarget;
4867
    const char *opn = "cp1 cond branch";
4868

    
4869
    if (cc != 0)
4870
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4871

    
4872
    btarget = ctx->pc + 4 + offset;
4873

    
4874
    switch (op) {
4875
    case OPC_BC1F:
4876
        gen_op_bc1f(cc);
4877
        opn = "bc1f";
4878
        goto not_likely;
4879
    case OPC_BC1FL:
4880
        gen_op_bc1f(cc);
4881
        opn = "bc1fl";
4882
        goto likely;
4883
    case OPC_BC1T:
4884
        gen_op_bc1t(cc);
4885
        opn = "bc1t";
4886
        goto not_likely;
4887
    case OPC_BC1TL:
4888
        gen_op_bc1t(cc);
4889
        opn = "bc1tl";
4890
    likely:
4891
        ctx->hflags |= MIPS_HFLAG_BL;
4892
        tcg_gen_set_bcond();
4893
        break;
4894
    case OPC_BC1FANY2:
4895
        gen_op_bc1any2f(cc);
4896
        opn = "bc1any2f";
4897
        goto not_likely;
4898
    case OPC_BC1TANY2:
4899
        gen_op_bc1any2t(cc);
4900
        opn = "bc1any2t";
4901
        goto not_likely;
4902
    case OPC_BC1FANY4:
4903
        gen_op_bc1any4f(cc);
4904
        opn = "bc1any4f";
4905
        goto not_likely;
4906
    case OPC_BC1TANY4:
4907
        gen_op_bc1any4t(cc);
4908
        opn = "bc1any4t";
4909
    not_likely:
4910
        ctx->hflags |= MIPS_HFLAG_BC;
4911
        tcg_gen_set_bcond();
4912
        break;
4913
    default:
4914
        MIPS_INVAL(opn);
4915
        generate_exception (ctx, EXCP_RI);
4916
        return;
4917
    }
4918
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4919
               ctx->hflags, btarget);
4920
    ctx->btarget = btarget;
4921
}
4922

    
4923
/* Coprocessor 1 (FPU) */
4924

    
4925
#define FOP(func, fmt) (((fmt) << 21) | (func))
4926

    
4927
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4928
{
4929
    const char *opn = "cp1 move";
4930

    
4931
    switch (opc) {
4932
    case OPC_MFC1:
4933
        GEN_LOAD_FREG_FTN(WT0, fs);
4934
        gen_op_mfc1();
4935
        GEN_STORE_T0_REG(rt);
4936
        opn = "mfc1";
4937
        break;
4938
    case OPC_MTC1:
4939
        GEN_LOAD_REG_T0(rt);
4940
        gen_op_mtc1();
4941
        GEN_STORE_FTN_FREG(fs, WT0);
4942
        opn = "mtc1";
4943
        break;
4944
    case OPC_CFC1:
4945
        gen_op_cfc1(fs);
4946
        GEN_STORE_T0_REG(rt);
4947
        opn = "cfc1";
4948
        break;
4949
    case OPC_CTC1:
4950
        GEN_LOAD_REG_T0(rt);
4951
        gen_op_ctc1(fs);
4952
        opn = "ctc1";
4953
        break;
4954
    case OPC_DMFC1:
4955
        GEN_LOAD_FREG_FTN(DT0, fs);
4956
        gen_op_dmfc1();
4957
        GEN_STORE_T0_REG(rt);
4958
        opn = "dmfc1";
4959
        break;
4960
    case OPC_DMTC1:
4961
        GEN_LOAD_REG_T0(rt);
4962
        gen_op_dmtc1();
4963
        GEN_STORE_FTN_FREG(fs, DT0);
4964
        opn = "dmtc1";
4965
        break;
4966
    case OPC_MFHC1:
4967
        GEN_LOAD_FREG_FTN(WTH0, fs);
4968
        gen_op_mfhc1();
4969
        GEN_STORE_T0_REG(rt);
4970
        opn = "mfhc1";
4971
        break;
4972
    case OPC_MTHC1:
4973
        GEN_LOAD_REG_T0(rt);
4974
        gen_op_mthc1();
4975
        GEN_STORE_FTN_FREG(fs, WTH0);
4976
        opn = "mthc1";
4977
        break;
4978
    default:
4979
        MIPS_INVAL(opn);
4980
        generate_exception (ctx, EXCP_RI);
4981
        return;
4982
    }
4983
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4984
}
4985

    
4986
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4987
{
4988
    uint32_t ccbit;
4989

    
4990
    GEN_LOAD_REG_T0(rd);
4991
    GEN_LOAD_REG_T1(rs);
4992
    if (cc) {
4993
        ccbit = 1 << (24 + cc);
4994
    } else
4995
        ccbit = 1 << 23;
4996
    if (!tf)
4997
        gen_op_movf(ccbit);
4998
    else
4999
        gen_op_movt(ccbit);
5000
    GEN_STORE_T0_REG(rd);
5001
}
5002

    
5003
#define GEN_MOVCF(fmt)                                                \
5004
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5005
{                                                                     \
5006
    uint32_t ccbit;                                                   \
5007
                                                                      \
5008
    if (cc) {                                                         \
5009
        ccbit = 1 << (24 + cc);                                       \
5010
    } else                                                            \
5011
        ccbit = 1 << 23;                                              \
5012
    if (!tf)                                                          \
5013
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5014
    else                                                              \
5015
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5016
}
5017
GEN_MOVCF(d);
5018
GEN_MOVCF(s);
5019
GEN_MOVCF(ps);
5020
#undef GEN_MOVCF
5021

    
5022
static void gen_farith (DisasContext *ctx, uint32_t op1,
5023
                        int ft, int fs, int fd, int cc)
5024
{
5025
    const char *opn = "farith";
5026
    const char *condnames[] = {
5027
            "c.f",
5028
            "c.un",
5029
            "c.eq",
5030
            "c.ueq",
5031
            "c.olt",
5032
            "c.ult",
5033
            "c.ole",
5034
            "c.ule",
5035
            "c.sf",
5036
            "c.ngle",
5037
            "c.seq",
5038
            "c.ngl",
5039
            "c.lt",
5040
            "c.nge",
5041
            "c.le",
5042
            "c.ngt",
5043
    };
5044
    const char *condnames_abs[] = {
5045
            "cabs.f",
5046
            "cabs.un",
5047
            "cabs.eq",
5048
            "cabs.ueq",
5049
            "cabs.olt",
5050
            "cabs.ult",
5051
            "cabs.ole",
5052
            "cabs.ule",
5053
            "cabs.sf",
5054
            "cabs.ngle",
5055
            "cabs.seq",
5056
            "cabs.ngl",
5057
            "cabs.lt",
5058
            "cabs.nge",
5059
            "cabs.le",
5060
            "cabs.ngt",
5061
    };
5062
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5063
    uint32_t func = ctx->opcode & 0x3f;
5064

    
5065
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5066
    case FOP(0, 16):
5067
        GEN_LOAD_FREG_FTN(WT0, fs);
5068
        GEN_LOAD_FREG_FTN(WT1, ft);
5069
        gen_op_float_add_s();
5070
        GEN_STORE_FTN_FREG(fd, WT2);
5071
        opn = "add.s";
5072
        optype = BINOP;
5073
        break;
5074
    case FOP(1, 16):
5075
        GEN_LOAD_FREG_FTN(WT0, fs);
5076
        GEN_LOAD_FREG_FTN(WT1, ft);
5077
        gen_op_float_sub_s();
5078
        GEN_STORE_FTN_FREG(fd, WT2);
5079
        opn = "sub.s";
5080
        optype = BINOP;
5081
        break;
5082
    case FOP(2, 16):
5083
        GEN_LOAD_FREG_FTN(WT0, fs);
5084
        GEN_LOAD_FREG_FTN(WT1, ft);
5085
        gen_op_float_mul_s();
5086
        GEN_STORE_FTN_FREG(fd, WT2);
5087
        opn = "mul.s";
5088
        optype = BINOP;
5089
        break;
5090
    case FOP(3, 16):
5091
        GEN_LOAD_FREG_FTN(WT0, fs);
5092
        GEN_LOAD_FREG_FTN(WT1, ft);
5093
        gen_op_float_div_s();
5094
        GEN_STORE_FTN_FREG(fd, WT2);
5095
        opn = "div.s";
5096
        optype = BINOP;
5097
        break;
5098
    case FOP(4, 16):
5099
        GEN_LOAD_FREG_FTN(WT0, fs);
5100
        gen_op_float_sqrt_s();
5101
        GEN_STORE_FTN_FREG(fd, WT2);
5102
        opn = "sqrt.s";
5103
        break;
5104
    case FOP(5, 16):
5105
        GEN_LOAD_FREG_FTN(WT0, fs);
5106
        gen_op_float_abs_s();
5107
        GEN_STORE_FTN_FREG(fd, WT2);
5108
        opn = "abs.s";
5109
        break;
5110
    case FOP(6, 16):
5111
        GEN_LOAD_FREG_FTN(WT0, fs);
5112
        gen_op_float_mov_s();
5113
        GEN_STORE_FTN_FREG(fd, WT2);
5114
        opn = "mov.s";
5115
        break;
5116
    case FOP(7, 16):
5117
        GEN_LOAD_FREG_FTN(WT0, fs);
5118
        gen_op_float_chs_s();
5119
        GEN_STORE_FTN_FREG(fd, WT2);
5120
        opn = "neg.s";
5121
        break;
5122
    case FOP(8, 16):
5123
        check_cp1_64bitmode(ctx);
5124
        GEN_LOAD_FREG_FTN(WT0, fs);
5125
        gen_op_float_roundl_s();
5126
        GEN_STORE_FTN_FREG(fd, DT2);
5127
        opn = "round.l.s";
5128
        break;
5129
    case FOP(9, 16):
5130
        check_cp1_64bitmode(ctx);
5131
        GEN_LOAD_FREG_FTN(WT0, fs);
5132
        gen_op_float_truncl_s();
5133
        GEN_STORE_FTN_FREG(fd, DT2);
5134
        opn = "trunc.l.s";
5135
        break;
5136
    case FOP(10, 16):
5137
        check_cp1_64bitmode(ctx);
5138
        GEN_LOAD_FREG_FTN(WT0, fs);
5139
        gen_op_float_ceill_s();
5140
        GEN_STORE_FTN_FREG(fd, DT2);
5141
        opn = "ceil.l.s";
5142
        break;
5143
    case FOP(11, 16):
5144
        check_cp1_64bitmode(ctx);
5145
        GEN_LOAD_FREG_FTN(WT0, fs);
5146
        gen_op_float_floorl_s();
5147
        GEN_STORE_FTN_FREG(fd, DT2);
5148
        opn = "floor.l.s";
5149
        break;
5150
    case FOP(12, 16):
5151
        GEN_LOAD_FREG_FTN(WT0, fs);
5152
        gen_op_float_roundw_s();
5153
        GEN_STORE_FTN_FREG(fd, WT2);
5154
        opn = "round.w.s";
5155
        break;
5156
    case FOP(13, 16):
5157
        GEN_LOAD_FREG_FTN(WT0, fs);
5158
        gen_op_float_truncw_s();
5159
        GEN_STORE_FTN_FREG(fd, WT2);
5160
        opn = "trunc.w.s";
5161
        break;
5162
    case FOP(14, 16):
5163
        GEN_LOAD_FREG_FTN(WT0, fs);
5164
        gen_op_float_ceilw_s();
5165
        GEN_STORE_FTN_FREG(fd, WT2);
5166
        opn = "ceil.w.s";
5167
        break;
5168
    case FOP(15, 16):
5169
        GEN_LOAD_FREG_FTN(WT0, fs);
5170
        gen_op_float_floorw_s();
5171
        GEN_STORE_FTN_FREG(fd, WT2);
5172
        opn = "floor.w.s";
5173
        break;
5174
    case FOP(17, 16):
5175
        GEN_LOAD_REG_T0(ft);
5176
        GEN_LOAD_FREG_FTN(WT0, fs);
5177
        GEN_LOAD_FREG_FTN(WT2, fd);
5178
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5179
        GEN_STORE_FTN_FREG(fd, WT2);
5180
        opn = "movcf.s";
5181
        break;
5182
    case FOP(18, 16):
5183
        GEN_LOAD_REG_T0(ft);
5184
        GEN_LOAD_FREG_FTN(WT0, fs);
5185
        GEN_LOAD_FREG_FTN(WT2, fd);
5186
        gen_op_float_movz_s();
5187
        GEN_STORE_FTN_FREG(fd, WT2);
5188
        opn = "movz.s";
5189
        break;
5190
    case FOP(19, 16):
5191
        GEN_LOAD_REG_T0(ft);
5192
        GEN_LOAD_FREG_FTN(WT0, fs);
5193
        GEN_LOAD_FREG_FTN(WT2, fd);
5194
        gen_op_float_movn_s();
5195
        GEN_STORE_FTN_FREG(fd, WT2);
5196
        opn = "movn.s";
5197
        break;
5198
    case FOP(21, 16):
5199
        check_cop1x(ctx);
5200
        GEN_LOAD_FREG_FTN(WT0, fs);
5201
        gen_op_float_recip_s();
5202
        GEN_STORE_FTN_FREG(fd, WT2);
5203
        opn = "recip.s";
5204
        break;
5205
    case FOP(22, 16):
5206
        check_cop1x(ctx);
5207
        GEN_LOAD_FREG_FTN(WT0, fs);
5208
        gen_op_float_rsqrt_s();
5209
        GEN_STORE_FTN_FREG(fd, WT2);
5210
        opn = "rsqrt.s";
5211
        break;
5212
    case FOP(28, 16):
5213
        check_cp1_64bitmode(ctx);
5214
        GEN_LOAD_FREG_FTN(WT0, fs);
5215
        GEN_LOAD_FREG_FTN(WT2, fd);
5216
        gen_op_float_recip2_s();
5217
        GEN_STORE_FTN_FREG(fd, WT2);
5218
        opn = "recip2.s";
5219
        break;
5220
    case FOP(29, 16):
5221
        check_cp1_64bitmode(ctx);
5222
        GEN_LOAD_FREG_FTN(WT0, fs);
5223
        gen_op_float_recip1_s();
5224
        GEN_STORE_FTN_FREG(fd, WT2);
5225
        opn = "recip1.s";
5226
        break;
5227
    case FOP(30, 16):
5228
        check_cp1_64bitmode(ctx);
5229
        GEN_LOAD_FREG_FTN(WT0, fs);
5230
        gen_op_float_rsqrt1_s();
5231
        GEN_STORE_FTN_FREG(fd, WT2);
5232
        opn = "rsqrt1.s";
5233
        break;
5234
    case FOP(31, 16):
5235
        check_cp1_64bitmode(ctx);
5236
        GEN_LOAD_FREG_FTN(WT0, fs);
5237
        GEN_LOAD_FREG_FTN(WT2, ft);
5238
        gen_op_float_rsqrt2_s();
5239
        GEN_STORE_FTN_FREG(fd, WT2);
5240
        opn = "rsqrt2.s";
5241
        break;
5242
    case FOP(33, 16):
5243
        check_cp1_registers(ctx, fd);
5244
        GEN_LOAD_FREG_FTN(WT0, fs);
5245
        gen_op_float_cvtd_s();
5246
        GEN_STORE_FTN_FREG(fd, DT2);
5247
        opn = "cvt.d.s";
5248
        break;
5249
    case FOP(36, 16):
5250
        GEN_LOAD_FREG_FTN(WT0, fs);
5251
        gen_op_float_cvtw_s();
5252
        GEN_STORE_FTN_FREG(fd, WT2);
5253
        opn = "cvt.w.s";
5254
        break;
5255
    case FOP(37, 16):
5256
        check_cp1_64bitmode(ctx);
5257
        GEN_LOAD_FREG_FTN(WT0, fs);
5258
        gen_op_float_cvtl_s();
5259
        GEN_STORE_FTN_FREG(fd, DT2);
5260
        opn = "cvt.l.s";
5261
        break;
5262
    case FOP(38, 16):
5263
        check_cp1_64bitmode(ctx);
5264
        GEN_LOAD_FREG_FTN(WT1, fs);
5265
        GEN_LOAD_FREG_FTN(WT0, ft);
5266
        gen_op_float_cvtps_s();
5267
        GEN_STORE_FTN_FREG(fd, DT2);
5268
        opn = "cvt.ps.s";
5269
        break;
5270
    case FOP(48, 16):
5271
    case FOP(49, 16):
5272
    case FOP(50, 16):
5273
    case FOP(51, 16):
5274
    case FOP(52, 16):
5275
    case FOP(53, 16):
5276
    case FOP(54, 16):
5277
    case FOP(55, 16):
5278
    case FOP(56, 16):
5279
    case FOP(57, 16):
5280
    case FOP(58, 16):
5281
    case FOP(59, 16):
5282
    case FOP(60, 16):
5283
    case FOP(61, 16):
5284
    case FOP(62, 16):
5285
    case FOP(63, 16):
5286
        GEN_LOAD_FREG_FTN(WT0, fs);
5287
        GEN_LOAD_FREG_FTN(WT1, ft);
5288
        if (ctx->opcode & (1 << 6)) {
5289
            check_cop1x(ctx);
5290
            gen_cmpabs_s(func-48, cc);
5291
            opn = condnames_abs[func-48];
5292
        } else {
5293
            gen_cmp_s(func-48, cc);
5294
            opn = condnames[func-48];
5295
        }
5296
        break;
5297
    case FOP(0, 17):
5298
        check_cp1_registers(ctx, fs | ft | fd);
5299
        GEN_LOAD_FREG_FTN(DT0, fs);
5300
        GEN_LOAD_FREG_FTN(DT1, ft);
5301
        gen_op_float_add_d();
5302
        GEN_STORE_FTN_FREG(fd, DT2);
5303
        opn = "add.d";
5304
        optype = BINOP;
5305
        break;
5306
    case FOP(1, 17):
5307
        check_cp1_registers(ctx, fs | ft | fd);
5308
        GEN_LOAD_FREG_FTN(DT0, fs);
5309
        GEN_LOAD_FREG_FTN(DT1, ft);
5310
        gen_op_float_sub_d();
5311
        GEN_STORE_FTN_FREG(fd, DT2);
5312
        opn = "sub.d";
5313
        optype = BINOP;
5314
        break;
5315
    case FOP(2, 17):
5316
        check_cp1_registers(ctx, fs | ft | fd);
5317
        GEN_LOAD_FREG_FTN(DT0, fs);
5318
        GEN_LOAD_FREG_FTN(DT1, ft);
5319
        gen_op_float_mul_d();
5320
        GEN_STORE_FTN_FREG(fd, DT2);
5321
        opn = "mul.d";
5322
        optype = BINOP;
5323
        break;
5324
    case FOP(3, 17):
5325
        check_cp1_registers(ctx, fs | ft | fd);
5326
        GEN_LOAD_FREG_FTN(DT0, fs);
5327
        GEN_LOAD_FREG_FTN(DT1, ft);
5328
        gen_op_float_div_d();
5329
        GEN_STORE_FTN_FREG(fd, DT2);
5330
        opn = "div.d";
5331
        optype = BINOP;
5332
        break;
5333
    case FOP(4, 17):
5334
        check_cp1_registers(ctx, fs | fd);
5335
        GEN_LOAD_FREG_FTN(DT0, fs);
5336
        gen_op_float_sqrt_d();
5337
        GEN_STORE_FTN_FREG(fd, DT2);
5338
        opn = "sqrt.d";
5339
        break;
5340
    case FOP(5, 17):
5341
        check_cp1_registers(ctx, fs | fd);
5342
        GEN_LOAD_FREG_FTN(DT0, fs);
5343
        gen_op_float_abs_d();
5344
        GEN_STORE_FTN_FREG(fd, DT2);
5345
        opn = "abs.d";
5346
        break;
5347
    case FOP(6, 17):
5348
        check_cp1_registers(ctx, fs | fd);
5349
        GEN_LOAD_FREG_FTN(DT0, fs);
5350
        gen_op_float_mov_d();
5351
        GEN_STORE_FTN_FREG(fd, DT2);
5352
        opn = "mov.d";
5353
        break;
5354
    case FOP(7, 17):
5355
        check_cp1_registers(ctx, fs | fd);
5356
        GEN_LOAD_FREG_FTN(DT0, fs);
5357
        gen_op_float_chs_d();
5358
        GEN_STORE_FTN_FREG(fd, DT2);
5359
        opn = "neg.d";
5360
        break;
5361
    case FOP(8, 17):
5362
        check_cp1_64bitmode(ctx);
5363
        GEN_LOAD_FREG_FTN(DT0, fs);
5364
        gen_op_float_roundl_d();
5365
        GEN_STORE_FTN_FREG(fd, DT2);
5366
        opn = "round.l.d";
5367
        break;
5368
    case FOP(9, 17):
5369
        check_cp1_64bitmode(ctx);
5370
        GEN_LOAD_FREG_FTN(DT0, fs);
5371
        gen_op_float_truncl_d();
5372
        GEN_STORE_FTN_FREG(fd, DT2);
5373
        opn = "trunc.l.d";
5374
        break;
5375
    case FOP(10, 17):
5376
        check_cp1_64bitmode(ctx);
5377
        GEN_LOAD_FREG_FTN(DT0, fs);
5378
        gen_op_float_ceill_d();
5379
        GEN_STORE_FTN_FREG(fd, DT2);
5380
        opn = "ceil.l.d";
5381
        break;
5382
    case FOP(11, 17):
5383
        check_cp1_64bitmode(ctx);
5384
        GEN_LOAD_FREG_FTN(DT0, fs);
5385
        gen_op_float_floorl_d();
5386
        GEN_STORE_FTN_FREG(fd, DT2);
5387
        opn = "floor.l.d";
5388
        break;
5389
    case FOP(12, 17):
5390
        check_cp1_registers(ctx, fs);
5391
        GEN_LOAD_FREG_FTN(DT0, fs);
5392
        gen_op_float_roundw_d();
5393
        GEN_STORE_FTN_FREG(fd, WT2);
5394
        opn = "round.w.d";
5395
        break;
5396
    case FOP(13, 17):
5397
        check_cp1_registers(ctx, fs);
5398
        GEN_LOAD_FREG_FTN(DT0, fs);
5399
        gen_op_float_truncw_d();
5400
        GEN_STORE_FTN_FREG(fd, WT2);
5401
        opn = "trunc.w.d";
5402
        break;
5403
    case FOP(14, 17):
5404
        check_cp1_registers(ctx, fs);
5405
        GEN_LOAD_FREG_FTN(DT0, fs);
5406
        gen_op_float_ceilw_d();
5407
        GEN_STORE_FTN_FREG(fd, WT2);
5408
        opn = "ceil.w.d";
5409
        break;
5410
    case FOP(15, 17):
5411
        check_cp1_registers(ctx, fs);
5412
        GEN_LOAD_FREG_FTN(DT0, fs);
5413
        gen_op_float_floorw_d();
5414
        GEN_STORE_FTN_FREG(fd, WT2);
5415
        opn = "floor.w.d";
5416
        break;
5417
    case FOP(17, 17):
5418
        GEN_LOAD_REG_T0(ft);
5419
        GEN_LOAD_FREG_FTN(DT0, fs);
5420
        GEN_LOAD_FREG_FTN(DT2, fd);
5421
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5422
        GEN_STORE_FTN_FREG(fd, DT2);
5423
        opn = "movcf.d";
5424
        break;
5425
    case FOP(18, 17):
5426
        GEN_LOAD_REG_T0(ft);
5427
        GEN_LOAD_FREG_FTN(DT0, fs);
5428
        GEN_LOAD_FREG_FTN(DT2, fd);
5429
        gen_op_float_movz_d();
5430
        GEN_STORE_FTN_FREG(fd, DT2);
5431
        opn = "movz.d";
5432
        break;
5433
    case FOP(19, 17):
5434
        GEN_LOAD_REG_T0(ft);
5435
        GEN_LOAD_FREG_FTN(DT0, fs);
5436
        GEN_LOAD_FREG_FTN(DT2, fd);
5437
        gen_op_float_movn_d();
5438
        GEN_STORE_FTN_FREG(fd, DT2);
5439
        opn = "movn.d";
5440
        break;
5441
    case FOP(21, 17):
5442
        check_cp1_64bitmode(ctx);
5443
        GEN_LOAD_FREG_FTN(DT0, fs);
5444
        gen_op_float_recip_d();
5445
        GEN_STORE_FTN_FREG(fd, DT2);
5446
        opn = "recip.d";
5447
        break;
5448
    case FOP(22, 17):
5449
        check_cp1_64bitmode(ctx);
5450
        GEN_LOAD_FREG_FTN(DT0, fs);
5451
        gen_op_float_rsqrt_d();
5452
        GEN_STORE_FTN_FREG(fd, DT2);
5453
        opn = "rsqrt.d";
5454
        break;
5455
    case FOP(28, 17):
5456
        check_cp1_64bitmode(ctx);
5457
        GEN_LOAD_FREG_FTN(DT0, fs);
5458
        GEN_LOAD_FREG_FTN(DT2, ft);
5459
        gen_op_float_recip2_d();
5460
        GEN_STORE_FTN_FREG(fd, DT2);
5461
        opn = "recip2.d";
5462
        break;
5463
    case FOP(29, 17):
5464
        check_cp1_64bitmode(ctx);
5465
        GEN_LOAD_FREG_FTN(DT0, fs);
5466
        gen_op_float_recip1_d();
5467
        GEN_STORE_FTN_FREG(fd, DT2);
5468
        opn = "recip1.d";
5469
        break;
5470
    case FOP(30, 17):
5471
        check_cp1_64bitmode(ctx);
5472
        GEN_LOAD_FREG_FTN(DT0, fs);
5473
        gen_op_float_rsqrt1_d();
5474
        GEN_STORE_FTN_FREG(fd, DT2);
5475
        opn = "rsqrt1.d";
5476
        break;
5477
    case FOP(31, 17):
5478
        check_cp1_64bitmode(ctx);
5479
        GEN_LOAD_FREG_FTN(DT0, fs);
5480
        GEN_LOAD_FREG_FTN(DT2, ft);
5481
        gen_op_float_rsqrt2_d();
5482
        GEN_STORE_FTN_FREG(fd, DT2);
5483
        opn = "rsqrt2.d";
5484
        break;
5485
    case FOP(48, 17):
5486
    case FOP(49, 17):
5487
    case FOP(50, 17):
5488
    case FOP(51, 17):
5489
    case FOP(52, 17):
5490
    case FOP(53, 17):
5491
    case FOP(54, 17):
5492
    case FOP(55, 17):
5493
    case FOP(56, 17):
5494
    case FOP(57, 17):
5495
    case FOP(58, 17):
5496
    case FOP(59, 17):
5497
    case FOP(60, 17):
5498
    case FOP(61, 17):
5499
    case FOP(62, 17):
5500
    case FOP(63, 17):
5501
        GEN_LOAD_FREG_FTN(DT0, fs);
5502
        GEN_LOAD_FREG_FTN(DT1, ft);
5503
        if (ctx->opcode & (1 << 6)) {
5504
            check_cop1x(ctx);
5505
            check_cp1_registers(ctx, fs | ft);
5506
            gen_cmpabs_d(func-48, cc);
5507
            opn = condnames_abs[func-48];
5508
        } else {
5509
            check_cp1_registers(ctx, fs | ft);
5510
            gen_cmp_d(func-48, cc);
5511
            opn = condnames[func-48];
5512
        }
5513
        break;
5514
    case FOP(32, 17):
5515
        check_cp1_registers(ctx, fs);
5516
        GEN_LOAD_FREG_FTN(DT0, fs);
5517
        gen_op_float_cvts_d();
5518
        GEN_STORE_FTN_FREG(fd, WT2);
5519
        opn = "cvt.s.d";
5520
        break;
5521
    case FOP(36, 17):
5522
        check_cp1_registers(ctx, fs);
5523
        GEN_LOAD_FREG_FTN(DT0, fs);
5524
        gen_op_float_cvtw_d();
5525
        GEN_STORE_FTN_FREG(fd, WT2);
5526
        opn = "cvt.w.d";
5527
        break;
5528
    case FOP(37, 17):
5529
        check_cp1_64bitmode(ctx);
5530
        GEN_LOAD_FREG_FTN(DT0, fs);
5531
        gen_op_float_cvtl_d();
5532
        GEN_STORE_FTN_FREG(fd, DT2);
5533
        opn = "cvt.l.d";
5534
        break;
5535
    case FOP(32, 20):
5536
        GEN_LOAD_FREG_FTN(WT0, fs);
5537
        gen_op_float_cvts_w();
5538
        GEN_STORE_FTN_FREG(fd, WT2);
5539
        opn = "cvt.s.w";
5540
        break;
5541
    case FOP(33, 20):
5542
        check_cp1_registers(ctx, fd);
5543
        GEN_LOAD_FREG_FTN(WT0, fs);
5544
        gen_op_float_cvtd_w();
5545
        GEN_STORE_FTN_FREG(fd, DT2);
5546
        opn = "cvt.d.w";
5547
        break;
5548
    case FOP(32, 21):
5549
        check_cp1_64bitmode(ctx);
5550
        GEN_LOAD_FREG_FTN(DT0, fs);
5551
        gen_op_float_cvts_l();
5552
        GEN_STORE_FTN_FREG(fd, WT2);
5553
        opn = "cvt.s.l";
5554
        break;
5555
    case FOP(33, 21):
5556
        check_cp1_64bitmode(ctx);
5557
        GEN_LOAD_FREG_FTN(DT0, fs);
5558
        gen_op_float_cvtd_l();
5559
        GEN_STORE_FTN_FREG(fd, DT2);
5560
        opn = "cvt.d.l";
5561
        break;
5562
    case FOP(38, 20):
5563
        check_cp1_64bitmode(ctx);
5564
        GEN_LOAD_FREG_FTN(WT0, fs);
5565
        GEN_LOAD_FREG_FTN(WTH0, fs);
5566
        gen_op_float_cvtps_pw();
5567
        GEN_STORE_FTN_FREG(fd, WT2);
5568
        GEN_STORE_FTN_FREG(fd, WTH2);
5569
        opn = "cvt.ps.pw";
5570
        break;
5571
    case FOP(0, 22):
5572
        check_cp1_64bitmode(ctx);
5573
        GEN_LOAD_FREG_FTN(WT0, fs);
5574
        GEN_LOAD_FREG_FTN(WTH0, fs);
5575
        GEN_LOAD_FREG_FTN(WT1, ft);
5576
        GEN_LOAD_FREG_FTN(WTH1, ft);
5577
        gen_op_float_add_ps();
5578
        GEN_STORE_FTN_FREG(fd, WT2);
5579
        GEN_STORE_FTN_FREG(fd, WTH2);
5580
        opn = "add.ps";
5581
        break;
5582
    case FOP(1, 22):
5583
        check_cp1_64bitmode(ctx);
5584
        GEN_LOAD_FREG_FTN(WT0, fs);
5585
        GEN_LOAD_FREG_FTN(WTH0, fs);
5586
        GEN_LOAD_FREG_FTN(WT1, ft);
5587
        GEN_LOAD_FREG_FTN(WTH1, ft);
5588
        gen_op_float_sub_ps();
5589
        GEN_STORE_FTN_FREG(fd, WT2);
5590
        GEN_STORE_FTN_FREG(fd, WTH2);
5591
        opn = "sub.ps";
5592
        break;
5593
    case FOP(2, 22):
5594
        check_cp1_64bitmode(ctx);
5595
        GEN_LOAD_FREG_FTN(WT0, fs);
5596
        GEN_LOAD_FREG_FTN(WTH0, fs);
5597
        GEN_LOAD_FREG_FTN(WT1, ft);
5598
        GEN_LOAD_FREG_FTN(WTH1, ft);
5599
        gen_op_float_mul_ps();
5600
        GEN_STORE_FTN_FREG(fd, WT2);
5601
        GEN_STORE_FTN_FREG(fd, WTH2);
5602
        opn = "mul.ps";
5603
        break;
5604
    case FOP(5, 22):
5605
        check_cp1_64bitmode(ctx);
5606
        GEN_LOAD_FREG_FTN(WT0, fs);
5607
        GEN_LOAD_FREG_FTN(WTH0, fs);
5608
        gen_op_float_abs_ps();
5609
        GEN_STORE_FTN_FREG(fd, WT2);
5610
        GEN_STORE_FTN_FREG(fd, WTH2);
5611
        opn = "abs.ps";
5612
        break;
5613
    case FOP(6, 22):
5614
        check_cp1_64bitmode(ctx);
5615
        GEN_LOAD_FREG_FTN(WT0, fs);
5616
        GEN_LOAD_FREG_FTN(WTH0, fs);
5617
        gen_op_float_mov_ps();
5618
        GEN_STORE_FTN_FREG(fd, WT2);
5619
        GEN_STORE_FTN_FREG(fd, WTH2);
5620
        opn = "mov.ps";
5621
        break;
5622
    case FOP(7, 22):
5623
        check_cp1_64bitmode(ctx);
5624
        GEN_LOAD_FREG_FTN(WT0, fs);
5625
        GEN_LOAD_FREG_FTN(WTH0, fs);
5626
        gen_op_float_chs_ps();
5627
        GEN_STORE_FTN_FREG(fd, WT2);
5628
        GEN_STORE_FTN_FREG(fd, WTH2);
5629
        opn = "neg.ps";
5630
        break;
5631
    case FOP(17, 22):
5632
        check_cp1_64bitmode(ctx);
5633
        GEN_LOAD_REG_T0(ft);
5634
        GEN_LOAD_FREG_FTN(WT0, fs);
5635
        GEN_LOAD_FREG_FTN(WTH0, fs);
5636
        GEN_LOAD_FREG_FTN(WT2, fd);
5637
        GEN_LOAD_FREG_FTN(WTH2, fd);
5638
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5639
        GEN_STORE_FTN_FREG(fd, WT2);
5640
        GEN_STORE_FTN_FREG(fd, WTH2);
5641
        opn = "movcf.ps";
5642
        break;
5643
    case FOP(18, 22):
5644
        check_cp1_64bitmode(ctx);
5645
        GEN_LOAD_REG_T0(ft);
5646
        GEN_LOAD_FREG_FTN(WT0, fs);
5647
        GEN_LOAD_FREG_FTN(WTH0, fs);
5648
        GEN_LOAD_FREG_FTN(WT2, fd);
5649
        GEN_LOAD_FREG_FTN(WTH2, fd);
5650
        gen_op_float_movz_ps();
5651
        GEN_STORE_FTN_FREG(fd, WT2);
5652
        GEN_STORE_FTN_FREG(fd, WTH2);
5653
        opn = "movz.ps";
5654
        break;
5655
    case FOP(19, 22):
5656
        check_cp1_64bitmode(ctx);
5657
        GEN_LOAD_REG_T0(ft);
5658
        GEN_LOAD_FREG_FTN(WT0, fs);
5659
        GEN_LOAD_FREG_FTN(WTH0, fs);
5660
        GEN_LOAD_FREG_FTN(WT2, fd);
5661
        GEN_LOAD_FREG_FTN(WTH2, fd);
5662
        gen_op_float_movn_ps();
5663
        GEN_STORE_FTN_FREG(fd, WT2);
5664
        GEN_STORE_FTN_FREG(fd, WTH2);
5665
        opn = "movn.ps";
5666
        break;
5667
    case FOP(24, 22):
5668
        check_cp1_64bitmode(ctx);
5669
        GEN_LOAD_FREG_FTN(WT0, ft);
5670
        GEN_LOAD_FREG_FTN(WTH0, ft);
5671
        GEN_LOAD_FREG_FTN(WT1, fs);
5672
        GEN_LOAD_FREG_FTN(WTH1, fs);
5673
        gen_op_float_addr_ps();
5674
        GEN_STORE_FTN_FREG(fd, WT2);
5675
        GEN_STORE_FTN_FREG(fd, WTH2);
5676
        opn = "addr.ps";
5677
        break;
5678
    case FOP(26, 22):
5679
        check_cp1_64bitmode(ctx);
5680
        GEN_LOAD_FREG_FTN(WT0, ft);
5681
        GEN_LOAD_FREG_FTN(WTH0, ft);
5682
        GEN_LOAD_FREG_FTN(WT1, fs);
5683
        GEN_LOAD_FREG_FTN(WTH1, fs);
5684
        gen_op_float_mulr_ps();
5685
        GEN_STORE_FTN_FREG(fd, WT2);
5686
        GEN_STORE_FTN_FREG(fd, WTH2);
5687
        opn = "mulr.ps";
5688
        break;
5689
    case FOP(28, 22):
5690
        check_cp1_64bitmode(ctx);
5691
        GEN_LOAD_FREG_FTN(WT0, fs);
5692
        GEN_LOAD_FREG_FTN(WTH0, fs);
5693
        GEN_LOAD_FREG_FTN(WT2, fd);
5694
        GEN_LOAD_FREG_FTN(WTH2, fd);
5695
        gen_op_float_recip2_ps();
5696
        GEN_STORE_FTN_FREG(fd, WT2);
5697
        GEN_STORE_FTN_FREG(fd, WTH2);
5698
        opn = "recip2.ps";
5699
        break;
5700
    case FOP(29, 22):
5701
        check_cp1_64bitmode(ctx);
5702
        GEN_LOAD_FREG_FTN(WT0, fs);
5703
        GEN_LOAD_FREG_FTN(WTH0, fs);
5704
        gen_op_float_recip1_ps();
5705
        GEN_STORE_FTN_FREG(fd, WT2);
5706
        GEN_STORE_FTN_FREG(fd, WTH2);
5707
        opn = "recip1.ps";
5708
        break;
5709
    case FOP(30, 22):
5710
        check_cp1_64bitmode(ctx);
5711
        GEN_LOAD_FREG_FTN(WT0, fs);
5712
        GEN_LOAD_FREG_FTN(WTH0, fs);
5713
        gen_op_float_rsqrt1_ps();
5714
        GEN_STORE_FTN_FREG(fd, WT2);
5715
        GEN_STORE_FTN_FREG(fd, WTH2);
5716
        opn = "rsqrt1.ps";
5717
        break;
5718
    case FOP(31, 22):
5719
        check_cp1_64bitmode(ctx);
5720
        GEN_LOAD_FREG_FTN(WT0, fs);
5721
        GEN_LOAD_FREG_FTN(WTH0, fs);
5722
        GEN_LOAD_FREG_FTN(WT2, ft);
5723
        GEN_LOAD_FREG_FTN(WTH2, ft);
5724
        gen_op_float_rsqrt2_ps();
5725
        GEN_STORE_FTN_FREG(fd, WT2);
5726
        GEN_STORE_FTN_FREG(fd, WTH2);
5727
        opn = "rsqrt2.ps";
5728
        break;
5729
    case FOP(32, 22):
5730
        check_cp1_64bitmode(ctx);
5731
        GEN_LOAD_FREG_FTN(WTH0, fs);
5732
        gen_op_float_cvts_pu();
5733
        GEN_STORE_FTN_FREG(fd, WT2);
5734
        opn = "cvt.s.pu";
5735
        break;
5736
    case FOP(36, 22):
5737
        check_cp1_64bitmode(ctx);
5738
        GEN_LOAD_FREG_FTN(WT0, fs);
5739
        GEN_LOAD_FREG_FTN(WTH0, fs);
5740
        gen_op_float_cvtpw_ps();
5741
        GEN_STORE_FTN_FREG(fd, WT2);
5742
        GEN_STORE_FTN_FREG(fd, WTH2);
5743
        opn = "cvt.pw.ps";
5744
        break;
5745
    case FOP(40, 22):
5746
        check_cp1_64bitmode(ctx);
5747
        GEN_LOAD_FREG_FTN(WT0, fs);
5748
        gen_op_float_cvts_pl();
5749
        GEN_STORE_FTN_FREG(fd, WT2);
5750
        opn = "cvt.s.pl";
5751
        break;
5752
    case FOP(44, 22):
5753
        check_cp1_64bitmode(ctx);
5754
        GEN_LOAD_FREG_FTN(WT0, fs);
5755
        GEN_LOAD_FREG_FTN(WT1, ft);
5756
        gen_op_float_pll_ps();
5757
        GEN_STORE_FTN_FREG(fd, DT2);
5758
        opn = "pll.ps";
5759
        break;
5760
    case FOP(45, 22):
5761
        check_cp1_64bitmode(ctx);
5762
        GEN_LOAD_FREG_FTN(WT0, fs);
5763
        GEN_LOAD_FREG_FTN(WTH1, ft);
5764
        gen_op_float_plu_ps();
5765
        GEN_STORE_FTN_FREG(fd, DT2);
5766
        opn = "plu.ps";
5767
        break;
5768
    case FOP(46, 22):
5769
        check_cp1_64bitmode(ctx);
5770
        GEN_LOAD_FREG_FTN(WTH0, fs);
5771
        GEN_LOAD_FREG_FTN(WT1, ft);
5772
        gen_op_float_pul_ps();
5773
        GEN_STORE_FTN_FREG(fd, DT2);
5774
        opn = "pul.ps";
5775
        break;
5776
    case FOP(47, 22):
5777
        check_cp1_64bitmode(ctx);
5778
        GEN_LOAD_FREG_FTN(WTH0, fs);
5779
        GEN_LOAD_FREG_FTN(WTH1, ft);
5780
        gen_op_float_puu_ps();
5781
        GEN_STORE_FTN_FREG(fd, DT2);
5782
        opn = "puu.ps";
5783
        break;
5784
    case FOP(48, 22):
5785
    case FOP(49, 22):
5786
    case FOP(50, 22):
5787
    case FOP(51, 22):
5788
    case FOP(52, 22):
5789
    case FOP(53, 22):
5790
    case FOP(54, 22):
5791
    case FOP(55, 22):
5792
    case FOP(56, 22):
5793
    case FOP(57, 22):
5794
    case FOP(58, 22):
5795
    case FOP(59, 22):
5796
    case FOP(60, 22):
5797
    case FOP(61, 22):
5798
    case FOP(62, 22):
5799
    case FOP(63, 22):
5800
        check_cp1_64bitmode(ctx);
5801
        GEN_LOAD_FREG_FTN(WT0, fs);
5802
        GEN_LOAD_FREG_FTN(WTH0, fs);
5803
        GEN_LOAD_FREG_FTN(WT1, ft);
5804
        GEN_LOAD_FREG_FTN(WTH1, ft);
5805
        if (ctx->opcode & (1 << 6)) {
5806
            gen_cmpabs_ps(func-48, cc);
5807
            opn = condnames_abs[func-48];
5808
        } else {
5809
            gen_cmp_ps(func-48, cc);
5810
            opn = condnames[func-48];
5811
        }
5812
        break;
5813
    default:
5814
        MIPS_INVAL(opn);
5815
        generate_exception (ctx, EXCP_RI);
5816
        return;
5817
    }
5818
    switch (optype) {
5819
    case BINOP:
5820
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5821
        break;
5822
    case CMPOP:
5823
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5824
        break;
5825
    default:
5826
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5827
        break;
5828
    }
5829
}
5830

    
5831
/* Coprocessor 3 (FPU) */
5832
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5833
                           int fd, int fs, int base, int index)
5834
{
5835
    const char *opn = "extended float load/store";
5836
    int store = 0;
5837

    
5838
    if (base == 0) {
5839
        if (index == 0)
5840
            gen_op_reset_T0();
5841
        else
5842
            GEN_LOAD_REG_T0(index);
5843
    } else if (index == 0) {
5844
        GEN_LOAD_REG_T0(base);
5845
    } else {
5846
        GEN_LOAD_REG_T0(base);
5847
        GEN_LOAD_REG_T1(index);
5848
        gen_op_addr_add();
5849
    }
5850
    /* Don't do NOP if destination is zero: we must perform the actual
5851
       memory access. */
5852
    switch (opc) {
5853
    case OPC_LWXC1:
5854
        check_cop1x(ctx);
5855
        op_ldst(lwc1);
5856
        GEN_STORE_FTN_FREG(fd, WT0);
5857
        opn = "lwxc1";
5858
        break;
5859
    case OPC_LDXC1:
5860
        check_cop1x(ctx);
5861
        check_cp1_registers(ctx, fd);
5862
        op_ldst(ldc1);
5863
        GEN_STORE_FTN_FREG(fd, DT0);
5864
        opn = "ldxc1";
5865
        break;
5866
    case OPC_LUXC1:
5867
        check_cp1_64bitmode(ctx);
5868
        op_ldst(luxc1);
5869
        GEN_STORE_FTN_FREG(fd, DT0);
5870
        opn = "luxc1";
5871
        break;
5872
    case OPC_SWXC1:
5873
        check_cop1x(ctx);
5874
        GEN_LOAD_FREG_FTN(WT0, fs);
5875
        op_ldst(swc1);
5876
        opn = "swxc1";
5877
        store = 1;
5878
        break;
5879
    case OPC_SDXC1:
5880
        check_cop1x(ctx);
5881
        check_cp1_registers(ctx, fs);
5882
        GEN_LOAD_FREG_FTN(DT0, fs);
5883
        op_ldst(sdc1);
5884
        opn = "sdxc1";
5885
        store = 1;
5886
        break;
5887
    case OPC_SUXC1:
5888
        check_cp1_64bitmode(ctx);
5889
        GEN_LOAD_FREG_FTN(DT0, fs);
5890
        op_ldst(suxc1);
5891
        opn = "suxc1";
5892
        store = 1;
5893
        break;
5894
    default:
5895
        MIPS_INVAL(opn);
5896
        generate_exception(ctx, EXCP_RI);
5897
        return;
5898
    }
5899
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5900
               regnames[index], regnames[base]);
5901
}
5902

    
5903
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5904
                            int fd, int fr, int fs, int ft)
5905
{
5906
    const char *opn = "flt3_arith";
5907

    
5908
    switch (opc) {
5909
    case OPC_ALNV_PS:
5910
        check_cp1_64bitmode(ctx);
5911
        GEN_LOAD_REG_T0(fr);
5912
        GEN_LOAD_FREG_FTN(DT0, fs);
5913
        GEN_LOAD_FREG_FTN(DT1, ft);
5914
        gen_op_float_alnv_ps();
5915
        GEN_STORE_FTN_FREG(fd, DT2);
5916
        opn = "alnv.ps";
5917
        break;
5918
    case OPC_MADD_S:
5919
        check_cop1x(ctx);
5920
        GEN_LOAD_FREG_FTN(WT0, fs);
5921
        GEN_LOAD_FREG_FTN(WT1, ft);
5922
        GEN_LOAD_FREG_FTN(WT2, fr);
5923
        gen_op_float_muladd_s();
5924
        GEN_STORE_FTN_FREG(fd, WT2);
5925
        opn = "madd.s";
5926
        break;
5927
    case OPC_MADD_D:
5928
        check_cop1x(ctx);
5929
        check_cp1_registers(ctx, fd | fs | ft | fr);
5930
        GEN_LOAD_FREG_FTN(DT0, fs);
5931
        GEN_LOAD_FREG_FTN(DT1, ft);
5932
        GEN_LOAD_FREG_FTN(DT2, fr);
5933
        gen_op_float_muladd_d();
5934
        GEN_STORE_FTN_FREG(fd, DT2);
5935
        opn = "madd.d";
5936
        break;
5937
    case OPC_MADD_PS:
5938
        check_cp1_64bitmode(ctx);
5939
        GEN_LOAD_FREG_FTN(WT0, fs);
5940
        GEN_LOAD_FREG_FTN(WTH0, fs);
5941
        GEN_LOAD_FREG_FTN(WT1, ft);
5942
        GEN_LOAD_FREG_FTN(WTH1, ft);
5943
        GEN_LOAD_FREG_FTN(WT2, fr);
5944
        GEN_LOAD_FREG_FTN(WTH2, fr);
5945
        gen_op_float_muladd_ps();
5946
        GEN_STORE_FTN_FREG(fd, WT2);
5947
        GEN_STORE_FTN_FREG(fd, WTH2);
5948
        opn = "madd.ps";
5949
        break;
5950
    case OPC_MSUB_S:
5951
        check_cop1x(ctx);
5952
        GEN_LOAD_FREG_FTN(WT0, fs);
5953
        GEN_LOAD_FREG_FTN(WT1, ft);
5954
        GEN_LOAD_FREG_FTN(WT2, fr);
5955
        gen_op_float_mulsub_s();
5956
        GEN_STORE_FTN_FREG(fd, WT2);
5957
        opn = "msub.s";
5958
        break;
5959
    case OPC_MSUB_D:
5960
        check_cop1x(ctx);
5961
        check_cp1_registers(ctx, fd | fs | ft | fr);
5962
        GEN_LOAD_FREG_FTN(DT0, fs);
5963
        GEN_LOAD_FREG_FTN(DT1, ft);
5964
        GEN_LOAD_FREG_FTN(DT2, fr);
5965
        gen_op_float_mulsub_d();
5966
        GEN_STORE_FTN_FREG(fd, DT2);
5967
        opn = "msub.d";
5968
        break;
5969
    case OPC_MSUB_PS:
5970
        check_cp1_64bitmode(ctx);
5971
        GEN_LOAD_FREG_FTN(WT0, fs);
5972
        GEN_LOAD_FREG_FTN(WTH0, fs);
5973
        GEN_LOAD_FREG_FTN(WT1, ft);
5974
        GEN_LOAD_FREG_FTN(WTH1, ft);
5975
        GEN_LOAD_FREG_FTN(WT2, fr);
5976
        GEN_LOAD_FREG_FTN(WTH2, fr);
5977
        gen_op_float_mulsub_ps();
5978
        GEN_STORE_FTN_FREG(fd, WT2);
5979
        GEN_STORE_FTN_FREG(fd, WTH2);
5980
        opn = "msub.ps";
5981
        break;
5982
    case OPC_NMADD_S:
5983
        check_cop1x(ctx);
5984
        GEN_LOAD_FREG_FTN(WT0, fs);
5985
        GEN_LOAD_FREG_FTN(WT1, ft);
5986
        GEN_LOAD_FREG_FTN(WT2, fr);
5987
        gen_op_float_nmuladd_s();
5988
        GEN_STORE_FTN_FREG(fd, WT2);
5989
        opn = "nmadd.s";
5990
        break;
5991
    case OPC_NMADD_D:
5992
        check_cop1x(ctx);
5993
        check_cp1_registers(ctx, fd | fs | ft | fr);
5994
        GEN_LOAD_FREG_FTN(DT0, fs);
5995
        GEN_LOAD_FREG_FTN(DT1, ft);
5996
        GEN_LOAD_FREG_FTN(DT2, fr);
5997
        gen_op_float_nmuladd_d();
5998
        GEN_STORE_FTN_FREG(fd, DT2);
5999
        opn = "nmadd.d";
6000
        break;
6001
    case OPC_NMADD_PS:
6002
        check_cp1_64bitmode(ctx);
6003
        GEN_LOAD_FREG_FTN(WT0, fs);
6004
        GEN_LOAD_FREG_FTN(WTH0, fs);
6005
        GEN_LOAD_FREG_FTN(WT1, ft);
6006
        GEN_LOAD_FREG_FTN(WTH1, ft);
6007
        GEN_LOAD_FREG_FTN(WT2, fr);
6008
        GEN_LOAD_FREG_FTN(WTH2, fr);
6009
        gen_op_float_nmuladd_ps();
6010
        GEN_STORE_FTN_FREG(fd, WT2);
6011
        GEN_STORE_FTN_FREG(fd, WTH2);
6012
        opn = "nmadd.ps";
6013
        break;
6014
    case OPC_NMSUB_S:
6015
        check_cop1x(ctx);
6016
        GEN_LOAD_FREG_FTN(WT0, fs);
6017
        GEN_LOAD_FREG_FTN(WT1, ft);
6018
        GEN_LOAD_FREG_FTN(WT2, fr);
6019
        gen_op_float_nmulsub_s();
6020
        GEN_STORE_FTN_FREG(fd, WT2);
6021
        opn = "nmsub.s";
6022
        break;
6023
    case OPC_NMSUB_D:
6024
        check_cop1x(ctx);
6025
        check_cp1_registers(ctx, fd | fs | ft | fr);
6026
        GEN_LOAD_FREG_FTN(DT0, fs);
6027
        GEN_LOAD_FREG_FTN(DT1, ft);
6028
        GEN_LOAD_FREG_FTN(DT2, fr);
6029
        gen_op_float_nmulsub_d();
6030
        GEN_STORE_FTN_FREG(fd, DT2);
6031
        opn = "nmsub.d";
6032
        break;
6033
    case OPC_NMSUB_PS:
6034
        check_cp1_64bitmode(ctx);
6035
        GEN_LOAD_FREG_FTN(WT0, fs);
6036
        GEN_LOAD_FREG_FTN(WTH0, fs);
6037
        GEN_LOAD_FREG_FTN(WT1, ft);
6038
        GEN_LOAD_FREG_FTN(WTH1, ft);
6039
        GEN_LOAD_FREG_FTN(WT2, fr);
6040
        GEN_LOAD_FREG_FTN(WTH2, fr);
6041
        gen_op_float_nmulsub_ps();
6042
        GEN_STORE_FTN_FREG(fd, WT2);
6043
        GEN_STORE_FTN_FREG(fd, WTH2);
6044
        opn = "nmsub.ps";
6045
        break;
6046
    default:
6047
        MIPS_INVAL(opn);
6048
        generate_exception (ctx, EXCP_RI);
6049
        return;
6050
    }
6051
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6052
               fregnames[fs], fregnames[ft]);
6053
}
6054

    
6055
/* ISA extensions (ASEs) */
6056
/* MIPS16 extension to MIPS32 */
6057
/* SmartMIPS extension to MIPS32 */
6058

    
6059
#if defined(TARGET_MIPS64)
6060

    
6061
/* MDMX extension to MIPS64 */
6062

    
6063
#endif
6064

    
6065
static void decode_opc (CPUState *env, DisasContext *ctx)
6066
{
6067
    int32_t offset;
6068
    int rs, rt, rd, sa;
6069
    uint32_t op, op1, op2;
6070
    int16_t imm;
6071

    
6072
    /* make sure instructions are on a word boundary */
6073
    if (ctx->pc & 0x3) {
6074
        env->CP0_BadVAddr = ctx->pc;
6075
        generate_exception(ctx, EXCP_AdEL);
6076
        return;
6077
    }
6078

    
6079
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6080
        int l1;
6081
        /* Handle blikely not taken case */
6082
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6083
        l1 = gen_new_label();
6084
        tcg_gen_jnz_bcond(l1);
6085
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6086
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6087
        gen_set_label(l1);
6088
    }
6089
    op = MASK_OP_MAJOR(ctx->opcode);
6090
    rs = (ctx->opcode >> 21) & 0x1f;
6091
    rt = (ctx->opcode >> 16) & 0x1f;
6092
    rd = (ctx->opcode >> 11) & 0x1f;
6093
    sa = (ctx->opcode >> 6) & 0x1f;
6094
    imm = (int16_t)ctx->opcode;
6095
    switch (op) {
6096
    case OPC_SPECIAL:
6097
        op1 = MASK_SPECIAL(ctx->opcode);
6098
        switch (op1) {
6099
        case OPC_SLL:          /* Arithmetic with immediate */
6100
        case OPC_SRL ... OPC_SRA:
6101
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6102
            break;
6103
        case OPC_MOVZ ... OPC_MOVN:
6104
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6105
        case OPC_SLLV:         /* Arithmetic */
6106
        case OPC_SRLV ... OPC_SRAV:
6107
        case OPC_ADD ... OPC_NOR:
6108
        case OPC_SLT ... OPC_SLTU:
6109
            gen_arith(env, ctx, op1, rd, rs, rt);
6110
            break;
6111
        case OPC_MULT ... OPC_DIVU:
6112
            if (sa) {
6113
                check_insn(env, ctx, INSN_VR54XX);
6114
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6115
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6116
            } else
6117
                gen_muldiv(ctx, op1, rs, rt);
6118
            break;
6119
        case OPC_JR ... OPC_JALR:
6120
            gen_compute_branch(ctx, op1, rs, rd, sa);
6121
            return;
6122
        case OPC_TGE ... OPC_TEQ: /* Traps */
6123
        case OPC_TNE:
6124
            gen_trap(ctx, op1, rs, rt, -1);
6125
            break;
6126
        case OPC_MFHI:          /* Move from HI/LO */
6127
        case OPC_MFLO:
6128
            gen_HILO(ctx, op1, rd);
6129
            break;
6130
        case OPC_MTHI:
6131
        case OPC_MTLO:          /* Move to HI/LO */
6132
            gen_HILO(ctx, op1, rs);
6133
            break;
6134
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6135
#ifdef MIPS_STRICT_STANDARD
6136
            MIPS_INVAL("PMON / selsl");
6137
            generate_exception(ctx, EXCP_RI);
6138
#else
6139
            gen_op_pmon(sa);
6140
#endif
6141
            break;
6142
        case OPC_SYSCALL:
6143
            generate_exception(ctx, EXCP_SYSCALL);
6144
            break;
6145
        case OPC_BREAK:
6146
            generate_exception(ctx, EXCP_BREAK);
6147
            break;
6148
        case OPC_SPIM:
6149
#ifdef MIPS_STRICT_STANDARD
6150
            MIPS_INVAL("SPIM");
6151
            generate_exception(ctx, EXCP_RI);
6152
#else
6153
           /* Implemented as RI exception for now. */
6154
            MIPS_INVAL("spim (unofficial)");
6155
            generate_exception(ctx, EXCP_RI);
6156
#endif
6157
            break;
6158
        case OPC_SYNC:
6159
            /* Treat as NOP. */
6160
            break;
6161

    
6162
        case OPC_MOVCI:
6163
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6164
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6165
                save_cpu_state(ctx, 1);
6166
                check_cp1_enabled(ctx);
6167
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6168
                          (ctx->opcode >> 16) & 1);
6169
            } else {
6170
                generate_exception_err(ctx, EXCP_CpU, 1);
6171
            }
6172
            break;
6173

    
6174
#if defined(TARGET_MIPS64)
6175
       /* MIPS64 specific opcodes */
6176
        case OPC_DSLL:
6177
        case OPC_DSRL ... OPC_DSRA:
6178
        case OPC_DSLL32:
6179
        case OPC_DSRL32 ... OPC_DSRA32:
6180
            check_insn(env, ctx, ISA_MIPS3);
6181
            check_mips_64(ctx);
6182
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6183
            break;
6184
        case OPC_DSLLV:
6185
        case OPC_DSRLV ... OPC_DSRAV:
6186
        case OPC_DADD ... OPC_DSUBU:
6187
            check_insn(env, ctx, ISA_MIPS3);
6188
            check_mips_64(ctx);
6189
            gen_arith(env, ctx, op1, rd, rs, rt);
6190
            break;
6191
        case OPC_DMULT ... OPC_DDIVU:
6192
            check_insn(env, ctx, ISA_MIPS3);
6193
            check_mips_64(ctx);
6194
            gen_muldiv(ctx, op1, rs, rt);
6195
            break;
6196
#endif
6197
        default:            /* Invalid */
6198
            MIPS_INVAL("special");
6199
            generate_exception(ctx, EXCP_RI);
6200
            break;
6201
        }
6202
        break;
6203
    case OPC_SPECIAL2:
6204
        op1 = MASK_SPECIAL2(ctx->opcode);
6205
        switch (op1) {
6206
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6207
        case OPC_MSUB ... OPC_MSUBU:
6208
            check_insn(env, ctx, ISA_MIPS32);
6209
            gen_muldiv(ctx, op1, rs, rt);
6210
            break;
6211
        case OPC_MUL:
6212
            gen_arith(env, ctx, op1, rd, rs, rt);
6213
            break;
6214
        case OPC_CLZ ... OPC_CLO:
6215
            check_insn(env, ctx, ISA_MIPS32);
6216
            gen_cl(ctx, op1, rd, rs);
6217
            break;
6218
        case OPC_SDBBP:
6219
            /* XXX: not clear which exception should be raised
6220
             *      when in debug mode...
6221
             */
6222
            check_insn(env, ctx, ISA_MIPS32);
6223
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6224
                generate_exception(ctx, EXCP_DBp);
6225
            } else {
6226
                generate_exception(ctx, EXCP_DBp);
6227
            }
6228
            /* Treat as NOP. */
6229
            break;
6230
#if defined(TARGET_MIPS64)
6231
        case OPC_DCLZ ... OPC_DCLO:
6232
            check_insn(env, ctx, ISA_MIPS64);
6233
            check_mips_64(ctx);
6234
            gen_cl(ctx, op1, rd, rs);
6235
            break;
6236
#endif
6237
        default:            /* Invalid */
6238
            MIPS_INVAL("special2");
6239
            generate_exception(ctx, EXCP_RI);
6240
            break;
6241
        }
6242
        break;
6243
    case OPC_SPECIAL3:
6244
         op1 = MASK_SPECIAL3(ctx->opcode);
6245
         switch (op1) {
6246
         case OPC_EXT:
6247
         case OPC_INS:
6248
             check_insn(env, ctx, ISA_MIPS32R2);
6249
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6250
             break;
6251
         case OPC_BSHFL:
6252
             check_insn(env, ctx, ISA_MIPS32R2);
6253
             op2 = MASK_BSHFL(ctx->opcode);
6254
             switch (op2) {
6255
             case OPC_WSBH:
6256
                 GEN_LOAD_REG_T1(rt);
6257
                 gen_op_wsbh();
6258
                 break;
6259
             case OPC_SEB:
6260
                 GEN_LOAD_REG_T1(rt);
6261
                 gen_op_seb();
6262
                 break;
6263
             case OPC_SEH:
6264
                 GEN_LOAD_REG_T1(rt);
6265
                 gen_op_seh();
6266
                 break;
6267
             default:            /* Invalid */
6268
                 MIPS_INVAL("bshfl");
6269
                 generate_exception(ctx, EXCP_RI);
6270
                 break;
6271
            }
6272
            GEN_STORE_T0_REG(rd);
6273
            break;
6274
        case OPC_RDHWR:
6275
            check_insn(env, ctx, ISA_MIPS32R2);
6276
            switch (rd) {
6277
            case 0:
6278
                save_cpu_state(ctx, 1);
6279
                gen_op_rdhwr_cpunum();
6280
                break;
6281
            case 1:
6282
                save_cpu_state(ctx, 1);
6283
                gen_op_rdhwr_synci_step();
6284
                break;
6285
            case 2:
6286
                save_cpu_state(ctx, 1);
6287
                gen_op_rdhwr_cc();
6288
                break;
6289
            case 3:
6290
                save_cpu_state(ctx, 1);
6291
                gen_op_rdhwr_ccres();
6292
                break;
6293
            case 29:
6294
#if defined (CONFIG_USER_ONLY)
6295
                gen_op_tls_value();
6296
                break;
6297
#endif
6298
            default:            /* Invalid */
6299
                MIPS_INVAL("rdhwr");
6300
                generate_exception(ctx, EXCP_RI);
6301
                break;
6302
            }
6303
            GEN_STORE_T0_REG(rt);
6304
            break;
6305
        case OPC_FORK:
6306
            check_insn(env, ctx, ASE_MT);
6307
            GEN_LOAD_REG_T0(rt);
6308
            GEN_LOAD_REG_T1(rs);
6309
            gen_op_fork();
6310
            break;
6311
        case OPC_YIELD:
6312
            check_insn(env, ctx, ASE_MT);
6313
            GEN_LOAD_REG_T0(rs);
6314
            gen_op_yield();
6315
            GEN_STORE_T0_REG(rd);
6316
            break;
6317
#if defined(TARGET_MIPS64)
6318
        case OPC_DEXTM ... OPC_DEXT:
6319
        case OPC_DINSM ... OPC_DINS:
6320
            check_insn(env, ctx, ISA_MIPS64R2);
6321
            check_mips_64(ctx);
6322
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6323
            break;
6324
        case OPC_DBSHFL:
6325
            check_insn(env, ctx, ISA_MIPS64R2);
6326
            check_mips_64(ctx);
6327
            op2 = MASK_DBSHFL(ctx->opcode);
6328
            switch (op2) {
6329
            case OPC_DSBH:
6330
                GEN_LOAD_REG_T1(rt);
6331
                gen_op_dsbh();
6332
                break;
6333
            case OPC_DSHD:
6334
                GEN_LOAD_REG_T1(rt);
6335
                gen_op_dshd();
6336
                break;
6337
            default:            /* Invalid */
6338
                MIPS_INVAL("dbshfl");
6339
                generate_exception(ctx, EXCP_RI);
6340
                break;
6341
            }
6342
            GEN_STORE_T0_REG(rd);
6343
            break;
6344
#endif
6345
        default:            /* Invalid */
6346
            MIPS_INVAL("special3");
6347
            generate_exception(ctx, EXCP_RI);
6348
            break;
6349
        }
6350
        break;
6351
    case OPC_REGIMM:
6352
        op1 = MASK_REGIMM(ctx->opcode);
6353
        switch (op1) {
6354
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6355
        case OPC_BLTZAL ... OPC_BGEZALL:
6356
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6357
            return;
6358
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6359
        case OPC_TNEI:
6360
            gen_trap(ctx, op1, rs, -1, imm);
6361
            break;
6362
        case OPC_SYNCI:
6363
            check_insn(env, ctx, ISA_MIPS32R2);
6364
            /* Treat as NOP. */
6365
            break;
6366
        default:            /* Invalid */
6367
            MIPS_INVAL("regimm");
6368
            generate_exception(ctx, EXCP_RI);
6369
            break;
6370
        }
6371
        break;
6372
    case OPC_CP0:
6373
        check_cp0_enabled(ctx);
6374
        op1 = MASK_CP0(ctx->opcode);
6375
        switch (op1) {
6376
        case OPC_MFC0:
6377
        case OPC_MTC0:
6378
        case OPC_MFTR:
6379
        case OPC_MTTR:
6380
#if defined(TARGET_MIPS64)
6381
        case OPC_DMFC0:
6382
        case OPC_DMTC0:
6383
#endif
6384
            gen_cp0(env, ctx, op1, rt, rd);
6385
            break;
6386
        case OPC_C0_FIRST ... OPC_C0_LAST:
6387
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6388
            break;
6389
        case OPC_MFMC0:
6390
            op2 = MASK_MFMC0(ctx->opcode);
6391
            switch (op2) {
6392
            case OPC_DMT:
6393
                check_insn(env, ctx, ASE_MT);
6394
                gen_op_dmt();
6395
                break;
6396
            case OPC_EMT:
6397
                check_insn(env, ctx, ASE_MT);
6398
                gen_op_emt();
6399
                break;
6400
            case OPC_DVPE:
6401
                check_insn(env, ctx, ASE_MT);
6402
                gen_op_dvpe();
6403
                break;
6404
            case OPC_EVPE:
6405
                check_insn(env, ctx, ASE_MT);
6406
                gen_op_evpe();
6407
                break;
6408
            case OPC_DI:
6409
                check_insn(env, ctx, ISA_MIPS32R2);
6410
                save_cpu_state(ctx, 1);
6411
                gen_op_di();
6412
                /* Stop translation as we may have switched the execution mode */
6413
                ctx->bstate = BS_STOP;
6414
                break;
6415
            case OPC_EI:
6416
                check_insn(env, ctx, ISA_MIPS32R2);
6417
                save_cpu_state(ctx, 1);
6418
                gen_op_ei();
6419
                /* Stop translation as we may have switched the execution mode */
6420
                ctx->bstate = BS_STOP;
6421
                break;
6422
            default:            /* Invalid */
6423
                MIPS_INVAL("mfmc0");
6424
                generate_exception(ctx, EXCP_RI);
6425
                break;
6426
            }
6427
            GEN_STORE_T0_REG(rt);
6428
            break;
6429
        case OPC_RDPGPR:
6430
            check_insn(env, ctx, ISA_MIPS32R2);
6431
            GEN_LOAD_SRSREG_TN(T0, rt);
6432
            GEN_STORE_T0_REG(rd);
6433
            break;
6434
        case OPC_WRPGPR:
6435
            check_insn(env, ctx, ISA_MIPS32R2);
6436
            GEN_LOAD_REG_T0(rt);
6437
            GEN_STORE_TN_SRSREG(rd, T0);
6438
            break;
6439
        default:
6440
            MIPS_INVAL("cp0");
6441
            generate_exception(ctx, EXCP_RI);
6442
            break;
6443
        }
6444
        break;
6445
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6446
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6447
         break;
6448
    case OPC_J ... OPC_JAL: /* Jump */
6449
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6450
         gen_compute_branch(ctx, op, rs, rt, offset);
6451
         return;
6452
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6453
    case OPC_BEQL ... OPC_BGTZL:
6454
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6455
         return;
6456
    case OPC_LB ... OPC_LWR: /* Load and stores */
6457
    case OPC_SB ... OPC_SW:
6458
    case OPC_SWR:
6459
    case OPC_LL:
6460
    case OPC_SC:
6461
         gen_ldst(ctx, op, rt, rs, imm);
6462
         break;
6463
    case OPC_CACHE:
6464
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6465
        /* Treat as NOP. */
6466
        break;
6467
    case OPC_PREF:
6468
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6469
        /* Treat as NOP. */
6470
        break;
6471

    
6472
    /* Floating point (COP1). */
6473
    case OPC_LWC1:
6474
    case OPC_LDC1:
6475
    case OPC_SWC1:
6476
    case OPC_SDC1:
6477
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6478
            save_cpu_state(ctx, 1);
6479
            check_cp1_enabled(ctx);
6480
            gen_flt_ldst(ctx, op, rt, rs, imm);
6481
        } else {
6482
            generate_exception_err(ctx, EXCP_CpU, 1);
6483
        }
6484
        break;
6485

    
6486
    case OPC_CP1:
6487
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6488
            save_cpu_state(ctx, 1);
6489
            check_cp1_enabled(ctx);
6490
            op1 = MASK_CP1(ctx->opcode);
6491
            switch (op1) {
6492
            case OPC_MFHC1:
6493
            case OPC_MTHC1:
6494
                check_insn(env, ctx, ISA_MIPS32R2);
6495
            case OPC_MFC1:
6496
            case OPC_CFC1:
6497
            case OPC_MTC1:
6498
            case OPC_CTC1:
6499
                gen_cp1(ctx, op1, rt, rd);
6500
                break;
6501
#if defined(TARGET_MIPS64)
6502
            case OPC_DMFC1:
6503
            case OPC_DMTC1:
6504
                check_insn(env, ctx, ISA_MIPS3);
6505
                gen_cp1(ctx, op1, rt, rd);
6506
                break;
6507
#endif
6508
            case OPC_BC1ANY2:
6509
            case OPC_BC1ANY4:
6510
                check_cop1x(ctx);
6511
                check_insn(env, ctx, ASE_MIPS3D);
6512
                /* fall through */
6513
            case OPC_BC1:
6514
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6515
                                    (rt >> 2) & 0x7, imm << 2);
6516
                return;
6517
            case OPC_S_FMT:
6518
            case OPC_D_FMT:
6519
            case OPC_W_FMT:
6520
            case OPC_L_FMT:
6521
            case OPC_PS_FMT:
6522
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6523
                           (imm >> 8) & 0x7);
6524
                break;
6525
            default:
6526
                MIPS_INVAL("cp1");
6527
                generate_exception (ctx, EXCP_RI);
6528
                break;
6529
            }
6530
        } else {
6531
            generate_exception_err(ctx, EXCP_CpU, 1);
6532
        }
6533
        break;
6534

    
6535
    /* COP2.  */
6536
    case OPC_LWC2:
6537
    case OPC_LDC2:
6538
    case OPC_SWC2:
6539
    case OPC_SDC2:
6540
    case OPC_CP2:
6541
        /* COP2: Not implemented. */
6542
        generate_exception_err(ctx, EXCP_CpU, 2);
6543
        break;
6544

    
6545
    case OPC_CP3:
6546
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6547
            save_cpu_state(ctx, 1);
6548
            check_cp1_enabled(ctx);
6549
            op1 = MASK_CP3(ctx->opcode);
6550
            switch (op1) {
6551
            case OPC_LWXC1:
6552
            case OPC_LDXC1:
6553
            case OPC_LUXC1:
6554
            case OPC_SWXC1:
6555
            case OPC_SDXC1:
6556
            case OPC_SUXC1:
6557
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6558
                break;
6559
            case OPC_PREFX:
6560
                /* Treat as NOP. */
6561
                break;
6562
            case OPC_ALNV_PS:
6563
            case OPC_MADD_S:
6564
            case OPC_MADD_D:
6565
            case OPC_MADD_PS:
6566
            case OPC_MSUB_S:
6567
            case OPC_MSUB_D:
6568
            case OPC_MSUB_PS:
6569
            case OPC_NMADD_S:
6570
            case OPC_NMADD_D:
6571
            case OPC_NMADD_PS:
6572
            case OPC_NMSUB_S:
6573
            case OPC_NMSUB_D:
6574
            case OPC_NMSUB_PS:
6575
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6576
                break;
6577
            default:
6578
                MIPS_INVAL("cp3");
6579
                generate_exception (ctx, EXCP_RI);
6580
                break;
6581
            }
6582
        } else {
6583
            generate_exception_err(ctx, EXCP_CpU, 1);
6584
        }
6585
        break;
6586

    
6587
#if defined(TARGET_MIPS64)
6588
    /* MIPS64 opcodes */
6589
    case OPC_LWU:
6590
    case OPC_LDL ... OPC_LDR:
6591
    case OPC_SDL ... OPC_SDR:
6592
    case OPC_LLD:
6593
    case OPC_LD:
6594
    case OPC_SCD:
6595
    case OPC_SD:
6596
        check_insn(env, ctx, ISA_MIPS3);
6597
        check_mips_64(ctx);
6598
        gen_ldst(ctx, op, rt, rs, imm);
6599
        break;
6600
    case OPC_DADDI ... OPC_DADDIU:
6601
        check_insn(env, ctx, ISA_MIPS3);
6602
        check_mips_64(ctx);
6603
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6604
        break;
6605
#endif
6606
    case OPC_JALX:
6607
        check_insn(env, ctx, ASE_MIPS16);
6608
        /* MIPS16: Not implemented. */
6609
    case OPC_MDMX:
6610
        check_insn(env, ctx, ASE_MDMX);
6611
        /* MDMX: Not implemented. */
6612
    default:            /* Invalid */
6613
        MIPS_INVAL("major opcode");
6614
        generate_exception(ctx, EXCP_RI);
6615
        break;
6616
    }
6617
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6618
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6619
        /* Branches completion */
6620
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6621
        ctx->bstate = BS_BRANCH;
6622
        save_cpu_state(ctx, 0);
6623
        switch (hflags) {
6624
        case MIPS_HFLAG_B:
6625
            /* unconditional branch */
6626
            MIPS_DEBUG("unconditional branch");
6627
            gen_goto_tb(ctx, 0, ctx->btarget);
6628
            break;
6629
        case MIPS_HFLAG_BL:
6630
            /* blikely taken case */
6631
            MIPS_DEBUG("blikely branch taken");
6632
            gen_goto_tb(ctx, 0, ctx->btarget);
6633
            break;
6634
        case MIPS_HFLAG_BC:
6635
            /* Conditional branch */
6636
            MIPS_DEBUG("conditional branch");
6637
            {
6638
              int l1;
6639
              l1 = gen_new_label();
6640
              tcg_gen_jnz_bcond(l1);
6641
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6642
              gen_set_label(l1);
6643
              gen_goto_tb(ctx, 0, ctx->btarget);
6644
            }
6645
            break;
6646
        case MIPS_HFLAG_BR:
6647
            /* unconditional branch to register */
6648
            MIPS_DEBUG("branch to register");
6649
            gen_op_breg();
6650
            tcg_gen_exit_tb(0);
6651
            break;
6652
        default:
6653
            MIPS_DEBUG("unknown branch");
6654
            break;
6655
        }
6656
    }
6657
}
6658

    
6659
static always_inline int
6660
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6661
                                int search_pc)
6662
{
6663
    DisasContext ctx;
6664
    target_ulong pc_start;
6665
    uint16_t *gen_opc_end;
6666
    int j, lj = -1;
6667

    
6668
    if (search_pc && loglevel)
6669
        fprintf (logfile, "search pc %d\n", search_pc);
6670

    
6671
    pc_start = tb->pc;
6672
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6673
    ctx.pc = pc_start;
6674
    ctx.saved_pc = -1;
6675
    ctx.tb = tb;
6676
    ctx.bstate = BS_NONE;
6677
    /* Restore delay slot state from the tb context.  */
6678
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6679
    restore_cpu_state(env, &ctx);
6680
#if defined(CONFIG_USER_ONLY)
6681
    ctx.mem_idx = MIPS_HFLAG_UM;
6682
#else
6683
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6684
#endif
6685
#ifdef DEBUG_DISAS
6686
    if (loglevel & CPU_LOG_TB_CPU) {
6687
        fprintf(logfile, "------------------------------------------------\n");
6688
        /* FIXME: This may print out stale hflags from env... */
6689
        cpu_dump_state(env, logfile, fprintf, 0);
6690
    }
6691
#endif
6692
#ifdef MIPS_DEBUG_DISAS
6693
    if (loglevel & CPU_LOG_TB_IN_ASM)
6694
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6695
                tb, ctx.mem_idx, ctx.hflags);
6696
#endif
6697
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6698
        if (env->nb_breakpoints > 0) {
6699
            for(j = 0; j < env->nb_breakpoints; j++) {
6700
                if (env->breakpoints[j] == ctx.pc) {
6701
                    save_cpu_state(&ctx, 1);
6702
                    ctx.bstate = BS_BRANCH;
6703
                    gen_op_debug();
6704
                    /* Include the breakpoint location or the tb won't
6705
                     * be flushed when it must be.  */
6706
                    ctx.pc += 4;
6707
                    goto done_generating;
6708
                }
6709
            }
6710
        }
6711

    
6712
        if (search_pc) {
6713
            j = gen_opc_ptr - gen_opc_buf;
6714
            if (lj < j) {
6715
                lj++;
6716
                while (lj < j)
6717
                    gen_opc_instr_start[lj++] = 0;
6718
            }
6719
            gen_opc_pc[lj] = ctx.pc;
6720
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6721
            gen_opc_instr_start[lj] = 1;
6722
        }
6723
        ctx.opcode = ldl_code(ctx.pc);
6724
        decode_opc(env, &ctx);
6725
        ctx.pc += 4;
6726

    
6727
        if (env->singlestep_enabled)
6728
            break;
6729

    
6730
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6731
            break;
6732

    
6733
#if defined (MIPS_SINGLE_STEP)
6734
        break;
6735
#endif
6736
    }
6737
    if (env->singlestep_enabled) {
6738
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6739
        gen_op_debug();
6740
    } else {
6741
        switch (ctx.bstate) {
6742
        case BS_STOP:
6743
            gen_op_interrupt_restart();
6744
            gen_goto_tb(&ctx, 0, ctx.pc);
6745
            break;
6746
        case BS_NONE:
6747
            save_cpu_state(&ctx, 0);
6748
            gen_goto_tb(&ctx, 0, ctx.pc);
6749
            break;
6750
        case BS_EXCP:
6751
            gen_op_interrupt_restart();
6752
            tcg_gen_exit_tb(0);
6753
            break;
6754
        case BS_BRANCH:
6755
        default:
6756
            break;
6757
        }
6758
    }
6759
done_generating:
6760
    ctx.last_T0_store = NULL;
6761
    *gen_opc_ptr = INDEX_op_end;
6762
    if (search_pc) {
6763
        j = gen_opc_ptr - gen_opc_buf;
6764
        lj++;
6765
        while (lj <= j)
6766
            gen_opc_instr_start[lj++] = 0;
6767
    } else {
6768
        tb->size = ctx.pc - pc_start;
6769
    }
6770
#ifdef DEBUG_DISAS
6771
#if defined MIPS_DEBUG_DISAS
6772
    if (loglevel & CPU_LOG_TB_IN_ASM)
6773
        fprintf(logfile, "\n");
6774
#endif
6775
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6776
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6777
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6778
        fprintf(logfile, "\n");
6779
    }
6780
    if (loglevel & CPU_LOG_TB_CPU) {
6781
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6782
    }
6783
#endif
6784

    
6785
    return 0;
6786
}
6787

    
6788
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6789
{
6790
    return gen_intermediate_code_internal(env, tb, 0);
6791
}
6792

    
6793
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6794
{
6795
    return gen_intermediate_code_internal(env, tb, 1);
6796
}
6797

    
6798
void fpu_dump_state(CPUState *env, FILE *f,
6799
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6800
                    int flags)
6801
{
6802
    int i;
6803
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6804

    
6805
#define printfpr(fp)                                                        \
6806
    do {                                                                    \
6807
        if (is_fpu64)                                                       \
6808
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6809
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6810
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6811
        else {                                                              \
6812
            fpr_t tmp;                                                      \
6813
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6814
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6815
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6816
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6817
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6818
        }                                                                   \
6819
    } while(0)
6820

    
6821

    
6822
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6823
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6824
                get_float_exception_flags(&env->fpu->fp_status));
6825
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6826
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6827
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6828
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6829
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6830
        printfpr(&env->fpu->fpr[i]);
6831
    }
6832

    
6833
#undef printfpr
6834
}
6835

    
6836
void dump_fpu (CPUState *env)
6837
{
6838
    if (loglevel) {
6839
        fprintf(logfile,
6840
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
6841
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
6842
                " %04x\n",
6843
                env->PC[env->current_tc], env->HI[env->current_tc][0],
6844
                env->LO[env->current_tc][0], env->hflags, env->btarget,
6845
                env->bcond);
6846
       fpu_dump_state(env, logfile, fprintf, 0);
6847
    }
6848
}
6849

    
6850
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6851
/* Debug help: The architecture requires 32bit code to maintain proper
6852
   sign-extened values on 64bit machines.  */
6853

    
6854
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6855

    
6856
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6857
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6858
                     int flags)
6859
{
6860
    int i;
6861

    
6862
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6863
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6864
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
6865
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
6866
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
6867
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
6868
    if (!SIGN_EXT_P(env->btarget))
6869
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6870

    
6871
    for (i = 0; i < 32; i++) {
6872
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
6873
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
6874
    }
6875

    
6876
    if (!SIGN_EXT_P(env->CP0_EPC))
6877
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6878
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6879
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6880
}
6881
#endif
6882

    
6883
void cpu_dump_state (CPUState *env, FILE *f,
6884
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6885
                     int flags)
6886
{
6887
    int i;
6888

    
6889
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6890
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6891
    for (i = 0; i < 32; i++) {
6892
        if ((i & 3) == 0)
6893
            cpu_fprintf(f, "GPR%02d:", i);
6894
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
6895
        if ((i & 3) == 3)
6896
            cpu_fprintf(f, "\n");
6897
    }
6898

    
6899
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6900
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6901
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6902
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6903
    if (env->hflags & MIPS_HFLAG_FPU)
6904
        fpu_dump_state(env, f, cpu_fprintf, flags);
6905
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6906
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6907
#endif
6908
}
6909

    
6910
static void mips_tcg_init(void)
6911
{
6912
    static int inited;
6913

    
6914
    /* Initialize various static tables. */
6915
    if (inited)
6916
        return;
6917

    
6918
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
6919
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
6920
                                         TCG_AREG0,
6921
                                         offsetof(CPUState, current_tc_gprs),
6922
                                         "current_tc_gprs");
6923
#if TARGET_LONG_BITS > HOST_LONG_BITS
6924
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
6925
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
6926
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
6927
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
6928
#else
6929
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
6930
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
6931
#endif
6932

    
6933
    inited = 1;
6934
}
6935

    
6936
#include "translate_init.c"
6937

    
6938
CPUMIPSState *cpu_mips_init (const char *cpu_model)
6939
{
6940
    CPUMIPSState *env;
6941
    const mips_def_t *def;
6942

    
6943
    def = cpu_mips_find_by_name(cpu_model);
6944
    if (!def)
6945
        return NULL;
6946
    env = qemu_mallocz(sizeof(CPUMIPSState));
6947
    if (!env)
6948
        return NULL;
6949
    env->cpu_model = def;
6950

    
6951
    cpu_exec_init(env);
6952
    env->cpu_model_str = cpu_model;
6953
    mips_tcg_init();
6954
    cpu_reset(env);
6955
    return env;
6956
}
6957

    
6958
void cpu_reset (CPUMIPSState *env)
6959
{
6960
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6961

    
6962
    tlb_flush(env, 1);
6963

    
6964
    /* Minimal init */
6965
#if !defined(CONFIG_USER_ONLY)
6966
    if (env->hflags & MIPS_HFLAG_BMASK) {
6967
        /* If the exception was raised from a delay slot,
6968
         * come back to the jump.  */
6969
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6970
    } else {
6971
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6972
    }
6973
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6974
    env->CP0_Wired = 0;
6975
    /* SMP not implemented */
6976
    env->CP0_EBase = 0x80000000;
6977
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6978
    /* vectored interrupts not implemented, timer on int 7,
6979
       no performance counters. */
6980
    env->CP0_IntCtl = 0xe0000000;
6981
    {
6982
        int i;
6983

    
6984
        for (i = 0; i < 7; i++) {
6985
            env->CP0_WatchLo[i] = 0;
6986
            env->CP0_WatchHi[i] = 0x80000000;
6987
        }
6988
        env->CP0_WatchLo[7] = 0;
6989
        env->CP0_WatchHi[7] = 0;
6990
    }
6991
    /* Count register increments in debug mode, EJTAG version 1 */
6992
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6993
#endif
6994
    env->exception_index = EXCP_NONE;
6995
#if defined(CONFIG_USER_ONLY)
6996
    env->hflags = MIPS_HFLAG_UM;
6997
    env->user_mode_only = 1;
6998
#else
6999
    env->hflags = MIPS_HFLAG_CP0;
7000
#endif
7001
    cpu_mips_register(env, env->cpu_model);
7002
}
7003

    
7004
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7005
                unsigned long searched_pc, int pc_pos, void *puc)
7006
{
7007
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7008
    env->hflags &= ~MIPS_HFLAG_BMASK;
7009
    env->hflags |= gen_opc_hflags[pc_pos];
7010
}