Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 8c99506c

History | View | Annotate | Download (196.1 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
/* The code generator doesn't like lots of temporaries, so maintain our own
428
   cache for reuse within a function.  */
429
#define MAX_TEMPS 4
430
static int num_temps;
431
static TCGv temps[MAX_TEMPS];
432

    
433
/* Allocate a temporary variable.  */
434
static TCGv new_tmp(void)
435
{
436
    TCGv tmp;
437
    if (num_temps == MAX_TEMPS)
438
        abort();
439

    
440
    if (GET_TCGV(temps[num_temps]))
441
      return temps[num_temps++];
442

    
443
    tmp = tcg_temp_new(TCG_TYPE_I32);
444
    temps[num_temps++] = tmp;
445
    return tmp;
446
}
447

    
448
/* Release a temporary variable.  */
449
static void dead_tmp(TCGv tmp)
450
{
451
    int i;
452
    num_temps--;
453
    i = num_temps;
454
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
455
        return;
456

    
457
    /* Shuffle this temp to the last slot.  */
458
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
459
        i--;
460
    while (i < num_temps) {
461
        temps[i] = temps[i + 1];
462
        i++;
463
    }
464
    temps[i] = tmp;
465
}
466

    
467
/* General purpose registers moves */
468
const unsigned char *regnames[] =
469
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
470
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
471
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
472
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
473

    
474
static inline void gen_op_load_gpr_TN(int t_index, int reg)
475
{
476
    tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
477
}
478

    
479
static inline void gen_op_load_gpr_T0(int reg)
480
{
481
    gen_op_load_gpr_TN(0, reg);
482
}
483

    
484
static inline void gen_op_load_gpr_T1(int reg)
485
{
486
    gen_op_load_gpr_TN(1, reg);
487
}
488

    
489
static inline void gen_op_store_gpr_TN(int t_index, int reg)
490
{
491
    tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
492
}
493

    
494
static inline void gen_op_store_gpr_T0(int reg)
495
{
496
    gen_op_store_gpr_TN(0, reg);
497
}
498

    
499
static inline void gen_op_store_gpr_T1(int reg)
500
{
501
    gen_op_store_gpr_TN(1, reg);
502
}
503

    
504
/* Moves to/from shadow registers */
505
static inline void gen_op_load_srsgpr_T0(int reg)
506
{
507
    TCGv r_tmp = new_tmp();
508

    
509
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
510
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
511
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
512
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
513
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
514

    
515
    tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
516
    dead_tmp(r_tmp);
517
}
518

    
519
static inline void gen_op_store_srsgpr_T0(int reg)
520
{
521
    TCGv r_tmp = new_tmp();
522

    
523
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
524
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
525
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
526
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
527
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
528

    
529
    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
530
    dead_tmp(r_tmp);
531
}
532

    
533
/* Load immediates, zero being a special case. */
534
static inline void gen_op_set_T0(target_ulong arg)
535
{
536
    tcg_gen_movi_tl(cpu_T[0], arg);
537
}
538

    
539
static inline void gen_op_set_T1(target_ulong arg)
540
{
541
    tcg_gen_movi_tl(cpu_T[1], arg);
542
}
543

    
544
static inline void gen_op_reset_T0(void)
545
{
546
    tcg_gen_movi_tl(cpu_T[0], 0);
547
}
548

    
549
static inline void gen_op_reset_T1(void)
550
{
551
    tcg_gen_movi_tl(cpu_T[1], 0);
552
}
553

    
554
/* Moves to/from HI/LO registers. */
555
static inline void gen_op_load_HI(int reg)
556
{
557
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
558
}
559

    
560
static inline void gen_op_store_HI(int reg)
561
{
562
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
563
}
564

    
565
static inline void gen_op_load_LO(int reg)
566
{
567
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
568
}
569

    
570
static inline void gen_op_store_LO(int reg)
571
{
572
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
573
}
574

    
575

    
576
/* Floating point register moves. */
577
static const char *fregnames[] =
578
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
579
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
580
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
581
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
582

    
583
#define FGEN32(func, NAME)                       \
584
static GenOpFunc *NAME ## _table [32] = {        \
585
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
586
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
587
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
588
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
589
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
590
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
591
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
592
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
593
};                                               \
594
static always_inline void func(int n)            \
595
{                                                \
596
    NAME ## _table[n]();                         \
597
}
598

    
599
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
600
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
601

    
602
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
603
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
604

    
605
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
606
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
607

    
608
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
609
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
610

    
611
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
612
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
613

    
614
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
615
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
616

    
617
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
618
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
619

    
620
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
621
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
622

    
623
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
624
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
625

    
626
#define FOP_CONDS(type, fmt)                                            \
627
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
628
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
629
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
630
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
631
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
632
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
633
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
634
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
635
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
636
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
637
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
638
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
639
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
640
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
641
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
642
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
643
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
644
};                                                                      \
645
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
646
{                                                                       \
647
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
648
}
649

    
650
FOP_CONDS(, d)
651
FOP_CONDS(abs, d)
652
FOP_CONDS(, s)
653
FOP_CONDS(abs, s)
654
FOP_CONDS(, ps)
655
FOP_CONDS(abs, ps)
656

    
657
typedef struct DisasContext {
658
    struct TranslationBlock *tb;
659
    target_ulong pc, saved_pc;
660
    uint32_t opcode;
661
    uint32_t fp_status;
662
    /* Routine used to access memory */
663
    int mem_idx;
664
    uint32_t hflags, saved_hflags;
665
    int bstate;
666
    target_ulong btarget;
667
    void *last_T0_store;
668
    int last_T0_gpr;
669
} DisasContext;
670

    
671
enum {
672
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
673
                      * exception condition
674
                      */
675
    BS_STOP     = 1, /* We want to stop translation for any reason */
676
    BS_BRANCH   = 2, /* We reached a branch condition     */
677
    BS_EXCP     = 3, /* We reached an exception condition */
678
};
679

    
680
#ifdef MIPS_DEBUG_DISAS
681
#define MIPS_DEBUG(fmt, args...)                                              \
682
do {                                                                          \
683
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
684
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
685
                ctx->pc, ctx->opcode , ##args);                               \
686
    }                                                                         \
687
} while (0)
688
#else
689
#define MIPS_DEBUG(fmt, args...) do { } while(0)
690
#endif
691

    
692
#define MIPS_INVAL(op)                                                        \
693
do {                                                                          \
694
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
695
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
696
} while (0)
697

    
698
#define GEN_LOAD_REG_T0(Rn)                                                   \
699
do {                                                                          \
700
    if (Rn == 0) {                                                            \
701
        gen_op_reset_T0();                                                    \
702
    } else {                                                                  \
703
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
704
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
705
                gen_op_load_gpr_T0(Rn);                                       \
706
        }                                                                     \
707
    }                                                                         \
708
} while (0)
709

    
710
#define GEN_LOAD_REG_T1(Rn)                                                   \
711
do {                                                                          \
712
    if (Rn == 0) {                                                            \
713
        gen_op_reset_T1();                                                    \
714
    } else {                                                                  \
715
        gen_op_load_gpr_T1(Rn);                                               \
716
    }                                                                         \
717
} while (0)
718

    
719
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
720
do {                                                                          \
721
    if (Rn == 0) {                                                            \
722
        glue(gen_op_reset_, Tn)();                                            \
723
    } else {                                                                  \
724
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
725
    }                                                                         \
726
} while (0)
727

    
728
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
729
do {                                                                          \
730
    if (Imm == 0) {                                                           \
731
        glue(gen_op_reset_, Tn)();                                            \
732
    } else {                                                                  \
733
        glue(gen_op_set_, Tn)(Imm);                                           \
734
    }                                                                         \
735
} while (0)
736

    
737
#define GEN_STORE_T0_REG(Rn)                                                  \
738
do {                                                                          \
739
    if (Rn != 0) {                                                            \
740
        gen_op_store_gpr_T0(Rn);                                              \
741
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
742
        ctx->glue(last_T0,_gpr) = Rn;                                         \
743
    }                                                                         \
744
} while (0)
745

    
746
#define GEN_STORE_T1_REG(Rn)                                                  \
747
do {                                                                          \
748
    if (Rn != 0)                                                              \
749
        gen_op_store_gpr_T1(Rn);                                              \
750
} while (0)
751

    
752
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
753
do {                                                                          \
754
    if (Rn != 0)                                                              \
755
        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \
756
} while (0)
757

    
758
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
759
do {                                                                          \
760
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
761
} while (0)
762

    
763
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
764
do {                                                                          \
765
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
766
} while (0)
767

    
768
static always_inline void gen_save_pc(target_ulong pc)
769
{
770
#if defined(TARGET_MIPS64)
771
    if (pc == (int32_t)pc) {
772
        gen_op_save_pc(pc);
773
    } else {
774
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
775
    }
776
#else
777
    gen_op_save_pc(pc);
778
#endif
779
}
780

    
781
static always_inline void gen_save_btarget(target_ulong btarget)
782
{
783
#if defined(TARGET_MIPS64)
784
    if (btarget == (int32_t)btarget) {
785
        gen_op_save_btarget(btarget);
786
    } else {
787
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
788
    }
789
#else
790
    gen_op_save_btarget(btarget);
791
#endif
792
}
793

    
794
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
795
{
796
#if defined MIPS_DEBUG_DISAS
797
    if (loglevel & CPU_LOG_TB_IN_ASM) {
798
            fprintf(logfile, "hflags %08x saved %08x\n",
799
                    ctx->hflags, ctx->saved_hflags);
800
    }
801
#endif
802
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
803
        gen_save_pc(ctx->pc);
804
        ctx->saved_pc = ctx->pc;
805
    }
806
    if (ctx->hflags != ctx->saved_hflags) {
807
        gen_op_save_state(ctx->hflags);
808
        ctx->saved_hflags = ctx->hflags;
809
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
810
        case MIPS_HFLAG_BR:
811
            break;
812
        case MIPS_HFLAG_BC:
813
        case MIPS_HFLAG_BL:
814
        case MIPS_HFLAG_B:
815
            gen_save_btarget(ctx->btarget);
816
            break;
817
        }
818
    }
819
}
820

    
821
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
822
{
823
    ctx->saved_hflags = ctx->hflags;
824
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
825
    case MIPS_HFLAG_BR:
826
        break;
827
    case MIPS_HFLAG_BC:
828
    case MIPS_HFLAG_BL:
829
    case MIPS_HFLAG_B:
830
        ctx->btarget = env->btarget;
831
        break;
832
    }
833
}
834

    
835
static always_inline void
836
generate_tcg_exception_err (DisasContext *ctx, int excp, int err)
837
{
838
    save_cpu_state(ctx, 1);
839
    if (err == 0)
840
        gen_op_raise_exception(excp);
841
    else
842
        gen_op_raise_exception_err(excp, err);
843
    gen_op_interrupt_restart();
844
    tcg_gen_exit_tb(0);
845
}
846

    
847
static always_inline void
848
generate_tcg_exception (DisasContext *ctx, int excp)
849
{
850
    generate_tcg_exception_err (ctx, excp, 0);
851
}
852

    
853
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
854
{
855
#if defined MIPS_DEBUG_DISAS
856
    if (loglevel & CPU_LOG_TB_IN_ASM)
857
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
858
#endif
859
    save_cpu_state(ctx, 1);
860
    if (err == 0)
861
        gen_op_raise_exception(excp);
862
    else
863
        gen_op_raise_exception_err(excp, err);
864
    ctx->bstate = BS_EXCP;
865
}
866

    
867
static always_inline void generate_exception (DisasContext *ctx, int excp)
868
{
869
    generate_exception_err (ctx, excp, 0);
870
}
871

    
872
static always_inline void check_cp0_enabled(DisasContext *ctx)
873
{
874
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
875
        generate_exception_err(ctx, EXCP_CpU, 1);
876
}
877

    
878
static always_inline void check_cp1_enabled(DisasContext *ctx)
879
{
880
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
881
        generate_exception_err(ctx, EXCP_CpU, 1);
882
}
883

    
884
/* Verify that the processor is running with COP1X instructions enabled.
885
   This is associated with the nabla symbol in the MIPS32 and MIPS64
886
   opcode tables.  */
887

    
888
static always_inline void check_cop1x(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

    
894
/* Verify that the processor is running with 64-bit floating-point
895
   operations enabled.  */
896

    
897
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
898
{
899
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
900
        generate_exception(ctx, EXCP_RI);
901
}
902

    
903
/*
904
 * Verify if floating point register is valid; an operation is not defined
905
 * if bit 0 of any register specification is set and the FR bit in the
906
 * Status register equals zero, since the register numbers specify an
907
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
908
 * in the Status register equals one, both even and odd register numbers
909
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
910
 *
911
 * Multiple 64 bit wide registers can be checked by calling
912
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
913
 */
914
void check_cp1_registers(DisasContext *ctx, int regs)
915
{
916
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
917
        generate_exception(ctx, EXCP_RI);
918
}
919

    
920
/* This code generates a "reserved instruction" exception if the
921
   CPU does not support the instruction set corresponding to flags. */
922
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
923
{
924
    if (unlikely(!(env->insn_flags & flags)))
925
        generate_exception(ctx, EXCP_RI);
926
}
927

    
928
/* This code generates a "reserved instruction" exception if 64-bit
929
   instructions are not enabled. */
930
static always_inline void check_mips_64(DisasContext *ctx)
931
{
932
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
933
        generate_exception(ctx, EXCP_RI);
934
}
935

    
936
/* load/store instructions. */
937
#if defined(CONFIG_USER_ONLY)
938
#define op_ldst(name)        gen_op_##name##_raw()
939
#define OP_LD_TABLE(width)
940
#define OP_ST_TABLE(width)
941
#else
942
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
943
#define OP_LD_TABLE(width)                                                    \
944
static GenOpFunc *gen_op_l##width[] = {                                       \
945
    &gen_op_l##width##_kernel,                                                \
946
    &gen_op_l##width##_super,                                                 \
947
    &gen_op_l##width##_user,                                                  \
948
}
949
#define OP_ST_TABLE(width)                                                    \
950
static GenOpFunc *gen_op_s##width[] = {                                       \
951
    &gen_op_s##width##_kernel,                                                \
952
    &gen_op_s##width##_super,                                                 \
953
    &gen_op_s##width##_user,                                                  \
954
}
955
#endif
956

    
957
#if defined(TARGET_MIPS64)
958
OP_LD_TABLE(dl);
959
OP_LD_TABLE(dr);
960
OP_ST_TABLE(dl);
961
OP_ST_TABLE(dr);
962
#endif
963
OP_LD_TABLE(wl);
964
OP_LD_TABLE(wr);
965
OP_ST_TABLE(wl);
966
OP_ST_TABLE(wr);
967
OP_LD_TABLE(wc1);
968
OP_ST_TABLE(wc1);
969
OP_LD_TABLE(dc1);
970
OP_ST_TABLE(dc1);
971
OP_LD_TABLE(uxc1);
972
OP_ST_TABLE(uxc1);
973

    
974
#define OP_LD(insn,fname)                                        \
975
void inline op_ldst_##insn(DisasContext *ctx)                    \
976
{                                                                \
977
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
978
}
979
OP_LD(lb,ld8s);
980
OP_LD(lbu,ld8u);
981
OP_LD(lh,ld16s);
982
OP_LD(lhu,ld16u);
983
OP_LD(lw,ld32s);
984
#if defined(TARGET_MIPS64)
985
OP_LD(lwu,ld32u);
986
OP_LD(ld,ld64);
987
#endif
988
#undef OP_LD
989

    
990
#define OP_ST(insn,fname)                                        \
991
void inline op_ldst_##insn(DisasContext *ctx)                    \
992
{                                                                \
993
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
994
}
995
OP_ST(sb,st8);
996
OP_ST(sh,st16);
997
OP_ST(sw,st32);
998
#if defined(TARGET_MIPS64)
999
OP_ST(sd,st64);
1000
#endif
1001
#undef OP_ST
1002

    
1003
#define OP_LD_ATOMIC(insn,fname)                                        \
1004
void inline op_ldst_##insn(DisasContext *ctx)                           \
1005
{                                                                       \
1006
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
1007
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1008
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1009
}
1010
OP_LD_ATOMIC(ll,ld32s);
1011
#if defined(TARGET_MIPS64)
1012
OP_LD_ATOMIC(lld,ld64);
1013
#endif
1014
#undef OP_LD_ATOMIC
1015

    
1016
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1017
void inline op_ldst_##insn(DisasContext *ctx)                           \
1018
{                                                                       \
1019
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
1020
    int l1 = gen_new_label();                                           \
1021
    int l2 = gen_new_label();                                           \
1022
    int l3 = gen_new_label();                                           \
1023
                                                                        \
1024
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1025
    tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1);         \
1026
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1027
    generate_tcg_exception(ctx, EXCP_AdES);                             \
1028
    gen_set_label(l1);                                                  \
1029
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1030
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1031
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1032
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1033
    tcg_gen_br(l3);                                                     \
1034
    gen_set_label(l2);                                                  \
1035
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1036
    gen_set_label(l3);                                                  \
1037
}
1038
OP_ST_ATOMIC(sc,st32,0x3);
1039
#if defined(TARGET_MIPS64)
1040
OP_ST_ATOMIC(scd,st64,0x7);
1041
#endif
1042
#undef OP_ST_ATOMIC
1043

    
1044
void inline op_ldst_lwc1(DisasContext *ctx)
1045
{
1046
    op_ldst(lwc1);
1047
}
1048

    
1049
void inline op_ldst_ldc1(DisasContext *ctx)
1050
{
1051
    op_ldst(ldc1);
1052
}
1053

    
1054
void inline op_ldst_swc1(DisasContext *ctx)
1055
{
1056
    op_ldst(swc1);
1057
}
1058

    
1059
void inline op_ldst_sdc1(DisasContext *ctx)
1060
{
1061
    op_ldst(sdc1);
1062
}
1063

    
1064
/* Load and store */
1065
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1066
                      int base, int16_t offset)
1067
{
1068
    const char *opn = "ldst";
1069

    
1070
    if (base == 0) {
1071
        GEN_LOAD_IMM_TN(T0, offset);
1072
    } else if (offset == 0) {
1073
        gen_op_load_gpr_T0(base);
1074
    } else {
1075
        gen_op_load_gpr_T0(base);
1076
        gen_op_set_T1(offset);
1077
        gen_op_addr_add();
1078
    }
1079
    /* Don't do NOP if destination is zero: we must perform the actual
1080
       memory access. */
1081
    switch (opc) {
1082
#if defined(TARGET_MIPS64)
1083
    case OPC_LWU:
1084
        op_ldst_lwu(ctx);
1085
        GEN_STORE_T0_REG(rt);
1086
        opn = "lwu";
1087
        break;
1088
    case OPC_LD:
1089
        op_ldst_ld(ctx);
1090
        GEN_STORE_T0_REG(rt);
1091
        opn = "ld";
1092
        break;
1093
    case OPC_LLD:
1094
        op_ldst_lld(ctx);
1095
        GEN_STORE_T0_REG(rt);
1096
        opn = "lld";
1097
        break;
1098
    case OPC_SD:
1099
        GEN_LOAD_REG_T1(rt);
1100
        op_ldst_sd(ctx);
1101
        opn = "sd";
1102
        break;
1103
    case OPC_SCD:
1104
        save_cpu_state(ctx, 1);
1105
        GEN_LOAD_REG_T1(rt);
1106
        op_ldst_scd(ctx);
1107
        GEN_STORE_T0_REG(rt);
1108
        opn = "scd";
1109
        break;
1110
    case OPC_LDL:
1111
        GEN_LOAD_REG_T1(rt);
1112
        op_ldst(ldl);
1113
        GEN_STORE_T1_REG(rt);
1114
        opn = "ldl";
1115
        break;
1116
    case OPC_SDL:
1117
        GEN_LOAD_REG_T1(rt);
1118
        op_ldst(sdl);
1119
        opn = "sdl";
1120
        break;
1121
    case OPC_LDR:
1122
        GEN_LOAD_REG_T1(rt);
1123
        op_ldst(ldr);
1124
        GEN_STORE_T1_REG(rt);
1125
        opn = "ldr";
1126
        break;
1127
    case OPC_SDR:
1128
        GEN_LOAD_REG_T1(rt);
1129
        op_ldst(sdr);
1130
        opn = "sdr";
1131
        break;
1132
#endif
1133
    case OPC_LW:
1134
        op_ldst_lw(ctx);
1135
        GEN_STORE_T0_REG(rt);
1136
        opn = "lw";
1137
        break;
1138
    case OPC_SW:
1139
        GEN_LOAD_REG_T1(rt);
1140
        op_ldst_sw(ctx);
1141
        opn = "sw";
1142
        break;
1143
    case OPC_LH:
1144
        op_ldst_lh(ctx);
1145
        GEN_STORE_T0_REG(rt);
1146
        opn = "lh";
1147
        break;
1148
    case OPC_SH:
1149
        GEN_LOAD_REG_T1(rt);
1150
        op_ldst_sh(ctx);
1151
        opn = "sh";
1152
        break;
1153
    case OPC_LHU:
1154
        op_ldst_lhu(ctx);
1155
        GEN_STORE_T0_REG(rt);
1156
        opn = "lhu";
1157
        break;
1158
    case OPC_LB:
1159
        op_ldst_lb(ctx);
1160
        GEN_STORE_T0_REG(rt);
1161
        opn = "lb";
1162
        break;
1163
    case OPC_SB:
1164
        GEN_LOAD_REG_T1(rt);
1165
        op_ldst_sb(ctx);
1166
        opn = "sb";
1167
        break;
1168
    case OPC_LBU:
1169
        op_ldst_lbu(ctx);
1170
        GEN_STORE_T0_REG(rt);
1171
        opn = "lbu";
1172
        break;
1173
    case OPC_LWL:
1174
        GEN_LOAD_REG_T1(rt);
1175
        op_ldst(lwl);
1176
        GEN_STORE_T1_REG(rt);
1177
        opn = "lwl";
1178
        break;
1179
    case OPC_SWL:
1180
        GEN_LOAD_REG_T1(rt);
1181
        op_ldst(swl);
1182
        opn = "swr";
1183
        break;
1184
    case OPC_LWR:
1185
        GEN_LOAD_REG_T1(rt);
1186
        op_ldst(lwr);
1187
        GEN_STORE_T1_REG(rt);
1188
        opn = "lwr";
1189
        break;
1190
    case OPC_SWR:
1191
        GEN_LOAD_REG_T1(rt);
1192
        op_ldst(swr);
1193
        opn = "swr";
1194
        break;
1195
    case OPC_LL:
1196
        op_ldst_ll(ctx);
1197
        GEN_STORE_T0_REG(rt);
1198
        opn = "ll";
1199
        break;
1200
    case OPC_SC:
1201
        save_cpu_state(ctx, 1);
1202
        GEN_LOAD_REG_T1(rt);
1203
        op_ldst_sc(ctx);
1204
        GEN_STORE_T0_REG(rt);
1205
        opn = "sc";
1206
        break;
1207
    default:
1208
        MIPS_INVAL(opn);
1209
        generate_exception(ctx, EXCP_RI);
1210
        return;
1211
    }
1212
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1213
}
1214

    
1215
/* Load and store */
1216
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1217
                      int base, int16_t offset)
1218
{
1219
    const char *opn = "flt_ldst";
1220

    
1221
    if (base == 0) {
1222
        GEN_LOAD_IMM_TN(T0, offset);
1223
    } else if (offset == 0) {
1224
        gen_op_load_gpr_T0(base);
1225
    } else {
1226
        gen_op_load_gpr_T0(base);
1227
        gen_op_set_T1(offset);
1228
        gen_op_addr_add();
1229
    }
1230
    /* Don't do NOP if destination is zero: we must perform the actual
1231
       memory access. */
1232
    switch (opc) {
1233
    case OPC_LWC1:
1234
        op_ldst_lwc1(ctx);
1235
        GEN_STORE_FTN_FREG(ft, WT0);
1236
        opn = "lwc1";
1237
        break;
1238
    case OPC_SWC1:
1239
        GEN_LOAD_FREG_FTN(WT0, ft);
1240
        op_ldst_swc1(ctx);
1241
        opn = "swc1";
1242
        break;
1243
    case OPC_LDC1:
1244
        op_ldst_ldc1(ctx);
1245
        GEN_STORE_FTN_FREG(ft, DT0);
1246
        opn = "ldc1";
1247
        break;
1248
    case OPC_SDC1:
1249
        GEN_LOAD_FREG_FTN(DT0, ft);
1250
        op_ldst_sdc1(ctx);
1251
        opn = "sdc1";
1252
        break;
1253
    default:
1254
        MIPS_INVAL(opn);
1255
        generate_exception(ctx, EXCP_RI);
1256
        return;
1257
    }
1258
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1259
}
1260

    
1261
/* Arithmetic with immediate operand */
1262
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1263
                           int rt, int rs, int16_t imm)
1264
{
1265
    target_ulong uimm;
1266
    const char *opn = "imm arith";
1267

    
1268
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1269
        /* If no destination, treat it as a NOP.
1270
           For addi, we must generate the overflow exception when needed. */
1271
        MIPS_DEBUG("NOP");
1272
        return;
1273
    }
1274
    uimm = (uint16_t)imm;
1275
    switch (opc) {
1276
    case OPC_ADDI:
1277
    case OPC_ADDIU:
1278
#if defined(TARGET_MIPS64)
1279
    case OPC_DADDI:
1280
    case OPC_DADDIU:
1281
#endif
1282
    case OPC_SLTI:
1283
    case OPC_SLTIU:
1284
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1285
        /* Fall through. */
1286
    case OPC_ANDI:
1287
    case OPC_ORI:
1288
    case OPC_XORI:
1289
        GEN_LOAD_REG_T0(rs);
1290
        GEN_LOAD_IMM_TN(T1, uimm);
1291
        break;
1292
    case OPC_LUI:
1293
        GEN_LOAD_IMM_TN(T0, imm << 16);
1294
        break;
1295
    case OPC_SLL:
1296
    case OPC_SRA:
1297
    case OPC_SRL:
1298
#if defined(TARGET_MIPS64)
1299
    case OPC_DSLL:
1300
    case OPC_DSRA:
1301
    case OPC_DSRL:
1302
    case OPC_DSLL32:
1303
    case OPC_DSRA32:
1304
    case OPC_DSRL32:
1305
#endif
1306
        uimm &= 0x1f;
1307
        GEN_LOAD_REG_T0(rs);
1308
        GEN_LOAD_IMM_TN(T1, uimm);
1309
        break;
1310
    }
1311
    switch (opc) {
1312
    case OPC_ADDI:
1313
        save_cpu_state(ctx, 1);
1314
        gen_op_addo();
1315
        opn = "addi";
1316
        break;
1317
    case OPC_ADDIU:
1318
        gen_op_add();
1319
        opn = "addiu";
1320
        break;
1321
#if defined(TARGET_MIPS64)
1322
    case OPC_DADDI:
1323
        save_cpu_state(ctx, 1);
1324
        gen_op_daddo();
1325
        opn = "daddi";
1326
        break;
1327
    case OPC_DADDIU:
1328
        gen_op_dadd();
1329
        opn = "daddiu";
1330
        break;
1331
#endif
1332
    case OPC_SLTI:
1333
        gen_op_lt();
1334
        opn = "slti";
1335
        break;
1336
    case OPC_SLTIU:
1337
        gen_op_ltu();
1338
        opn = "sltiu";
1339
        break;
1340
    case OPC_ANDI:
1341
        gen_op_and();
1342
        opn = "andi";
1343
        break;
1344
    case OPC_ORI:
1345
        gen_op_or();
1346
        opn = "ori";
1347
        break;
1348
    case OPC_XORI:
1349
        gen_op_xor();
1350
        opn = "xori";
1351
        break;
1352
    case OPC_LUI:
1353
        opn = "lui";
1354
        break;
1355
    case OPC_SLL:
1356
        gen_op_sll();
1357
        opn = "sll";
1358
        break;
1359
    case OPC_SRA:
1360
        gen_op_sra();
1361
        opn = "sra";
1362
        break;
1363
    case OPC_SRL:
1364
        switch ((ctx->opcode >> 21) & 0x1f) {
1365
        case 0:
1366
            gen_op_srl();
1367
            opn = "srl";
1368
            break;
1369
        case 1:
1370
            /* rotr is decoded as srl on non-R2 CPUs */
1371
            if (env->insn_flags & ISA_MIPS32R2) {
1372
                gen_op_rotr();
1373
                opn = "rotr";
1374
            } else {
1375
                gen_op_srl();
1376
                opn = "srl";
1377
            }
1378
            break;
1379
        default:
1380
            MIPS_INVAL("invalid srl flag");
1381
            generate_exception(ctx, EXCP_RI);
1382
            break;
1383
        }
1384
        break;
1385
#if defined(TARGET_MIPS64)
1386
    case OPC_DSLL:
1387
        gen_op_dsll();
1388
        opn = "dsll";
1389
        break;
1390
    case OPC_DSRA:
1391
        gen_op_dsra();
1392
        opn = "dsra";
1393
        break;
1394
    case OPC_DSRL:
1395
        switch ((ctx->opcode >> 21) & 0x1f) {
1396
        case 0:
1397
            gen_op_dsrl();
1398
            opn = "dsrl";
1399
            break;
1400
        case 1:
1401
            /* drotr is decoded as dsrl on non-R2 CPUs */
1402
            if (env->insn_flags & ISA_MIPS32R2) {
1403
                gen_op_drotr();
1404
                opn = "drotr";
1405
            } else {
1406
                gen_op_dsrl();
1407
                opn = "dsrl";
1408
            }
1409
            break;
1410
        default:
1411
            MIPS_INVAL("invalid dsrl flag");
1412
            generate_exception(ctx, EXCP_RI);
1413
            break;
1414
        }
1415
        break;
1416
    case OPC_DSLL32:
1417
        gen_op_dsll32();
1418
        opn = "dsll32";
1419
        break;
1420
    case OPC_DSRA32:
1421
        gen_op_dsra32();
1422
        opn = "dsra32";
1423
        break;
1424
    case OPC_DSRL32:
1425
        switch ((ctx->opcode >> 21) & 0x1f) {
1426
        case 0:
1427
            gen_op_dsrl32();
1428
            opn = "dsrl32";
1429
            break;
1430
        case 1:
1431
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1432
            if (env->insn_flags & ISA_MIPS32R2) {
1433
                gen_op_drotr32();
1434
                opn = "drotr32";
1435
            } else {
1436
                gen_op_dsrl32();
1437
                opn = "dsrl32";
1438
            }
1439
            break;
1440
        default:
1441
            MIPS_INVAL("invalid dsrl32 flag");
1442
            generate_exception(ctx, EXCP_RI);
1443
            break;
1444
        }
1445
        break;
1446
#endif
1447
    default:
1448
        MIPS_INVAL(opn);
1449
        generate_exception(ctx, EXCP_RI);
1450
        return;
1451
    }
1452
    GEN_STORE_T0_REG(rt);
1453
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1454
}
1455

    
1456
/* Arithmetic */
1457
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1458
                       int rd, int rs, int rt)
1459
{
1460
    const char *opn = "arith";
1461

    
1462
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1463
       && opc != OPC_DADD && opc != OPC_DSUB) {
1464
        /* If no destination, treat it as a NOP.
1465
           For add & sub, we must generate the overflow exception when needed. */
1466
        MIPS_DEBUG("NOP");
1467
        return;
1468
    }
1469
    GEN_LOAD_REG_T0(rs);
1470
    /* Specialcase the conventional move operation. */
1471
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1472
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1473
        GEN_STORE_T0_REG(rd);
1474
        return;
1475
    }
1476
    GEN_LOAD_REG_T1(rt);
1477
    switch (opc) {
1478
    case OPC_ADD:
1479
        save_cpu_state(ctx, 1);
1480
        gen_op_addo();
1481
        opn = "add";
1482
        break;
1483
    case OPC_ADDU:
1484
        gen_op_add();
1485
        opn = "addu";
1486
        break;
1487
    case OPC_SUB:
1488
        save_cpu_state(ctx, 1);
1489
        gen_op_subo();
1490
        opn = "sub";
1491
        break;
1492
    case OPC_SUBU:
1493
        gen_op_sub();
1494
        opn = "subu";
1495
        break;
1496
#if defined(TARGET_MIPS64)
1497
    case OPC_DADD:
1498
        save_cpu_state(ctx, 1);
1499
        gen_op_daddo();
1500
        opn = "dadd";
1501
        break;
1502
    case OPC_DADDU:
1503
        gen_op_dadd();
1504
        opn = "daddu";
1505
        break;
1506
    case OPC_DSUB:
1507
        save_cpu_state(ctx, 1);
1508
        gen_op_dsubo();
1509
        opn = "dsub";
1510
        break;
1511
    case OPC_DSUBU:
1512
        gen_op_dsub();
1513
        opn = "dsubu";
1514
        break;
1515
#endif
1516
    case OPC_SLT:
1517
        gen_op_lt();
1518
        opn = "slt";
1519
        break;
1520
    case OPC_SLTU:
1521
        gen_op_ltu();
1522
        opn = "sltu";
1523
        break;
1524
    case OPC_AND:
1525
        gen_op_and();
1526
        opn = "and";
1527
        break;
1528
    case OPC_NOR:
1529
        gen_op_nor();
1530
        opn = "nor";
1531
        break;
1532
    case OPC_OR:
1533
        gen_op_or();
1534
        opn = "or";
1535
        break;
1536
    case OPC_XOR:
1537
        gen_op_xor();
1538
        opn = "xor";
1539
        break;
1540
    case OPC_MUL:
1541
        gen_op_mul();
1542
        opn = "mul";
1543
        break;
1544
    case OPC_MOVN:
1545
        gen_op_movn(rd);
1546
        opn = "movn";
1547
        goto print;
1548
    case OPC_MOVZ:
1549
        gen_op_movz(rd);
1550
        opn = "movz";
1551
        goto print;
1552
    case OPC_SLLV:
1553
        gen_op_sllv();
1554
        opn = "sllv";
1555
        break;
1556
    case OPC_SRAV:
1557
        gen_op_srav();
1558
        opn = "srav";
1559
        break;
1560
    case OPC_SRLV:
1561
        switch ((ctx->opcode >> 6) & 0x1f) {
1562
        case 0:
1563
            gen_op_srlv();
1564
            opn = "srlv";
1565
            break;
1566
        case 1:
1567
            /* rotrv is decoded as srlv on non-R2 CPUs */
1568
            if (env->insn_flags & ISA_MIPS32R2) {
1569
                gen_op_rotrv();
1570
                opn = "rotrv";
1571
            } else {
1572
                gen_op_srlv();
1573
                opn = "srlv";
1574
            }
1575
            break;
1576
        default:
1577
            MIPS_INVAL("invalid srlv flag");
1578
            generate_exception(ctx, EXCP_RI);
1579
            break;
1580
        }
1581
        break;
1582
#if defined(TARGET_MIPS64)
1583
    case OPC_DSLLV:
1584
        gen_op_dsllv();
1585
        opn = "dsllv";
1586
        break;
1587
    case OPC_DSRAV:
1588
        gen_op_dsrav();
1589
        opn = "dsrav";
1590
        break;
1591
    case OPC_DSRLV:
1592
        switch ((ctx->opcode >> 6) & 0x1f) {
1593
        case 0:
1594
            gen_op_dsrlv();
1595
            opn = "dsrlv";
1596
            break;
1597
        case 1:
1598
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1599
            if (env->insn_flags & ISA_MIPS32R2) {
1600
                gen_op_drotrv();
1601
                opn = "drotrv";
1602
            } else {
1603
                gen_op_dsrlv();
1604
                opn = "dsrlv";
1605
            }
1606
            break;
1607
        default:
1608
            MIPS_INVAL("invalid dsrlv flag");
1609
            generate_exception(ctx, EXCP_RI);
1610
            break;
1611
        }
1612
        break;
1613
#endif
1614
    default:
1615
        MIPS_INVAL(opn);
1616
        generate_exception(ctx, EXCP_RI);
1617
        return;
1618
    }
1619
    GEN_STORE_T0_REG(rd);
1620
 print:
1621
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1622
}
1623

    
1624
/* Arithmetic on HI/LO registers */
1625
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1626
{
1627
    const char *opn = "hilo";
1628

    
1629
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1630
        /* Treat as NOP. */
1631
        MIPS_DEBUG("NOP");
1632
        return;
1633
    }
1634
    switch (opc) {
1635
    case OPC_MFHI:
1636
        gen_op_load_HI(0);
1637
        GEN_STORE_T0_REG(reg);
1638
        opn = "mfhi";
1639
        break;
1640
    case OPC_MFLO:
1641
        gen_op_load_LO(0);
1642
        GEN_STORE_T0_REG(reg);
1643
        opn = "mflo";
1644
        break;
1645
    case OPC_MTHI:
1646
        GEN_LOAD_REG_T0(reg);
1647
        gen_op_store_HI(0);
1648
        opn = "mthi";
1649
        break;
1650
    case OPC_MTLO:
1651
        GEN_LOAD_REG_T0(reg);
1652
        gen_op_store_LO(0);
1653
        opn = "mtlo";
1654
        break;
1655
    default:
1656
        MIPS_INVAL(opn);
1657
        generate_exception(ctx, EXCP_RI);
1658
        return;
1659
    }
1660
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1661
}
1662

    
1663
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1664
                        int rs, int rt)
1665
{
1666
    const char *opn = "mul/div";
1667

    
1668
    GEN_LOAD_REG_T0(rs);
1669
    GEN_LOAD_REG_T1(rt);
1670
    switch (opc) {
1671
    case OPC_DIV:
1672
        gen_op_div();
1673
        opn = "div";
1674
        break;
1675
    case OPC_DIVU:
1676
        gen_op_divu();
1677
        opn = "divu";
1678
        break;
1679
    case OPC_MULT:
1680
        gen_op_mult();
1681
        opn = "mult";
1682
        break;
1683
    case OPC_MULTU:
1684
        gen_op_multu();
1685
        opn = "multu";
1686
        break;
1687
#if defined(TARGET_MIPS64)
1688
    case OPC_DDIV:
1689
        gen_op_ddiv();
1690
        opn = "ddiv";
1691
        break;
1692
    case OPC_DDIVU:
1693
        gen_op_ddivu();
1694
        opn = "ddivu";
1695
        break;
1696
    case OPC_DMULT:
1697
        gen_op_dmult();
1698
        opn = "dmult";
1699
        break;
1700
    case OPC_DMULTU:
1701
        gen_op_dmultu();
1702
        opn = "dmultu";
1703
        break;
1704
#endif
1705
    case OPC_MADD:
1706
        gen_op_madd();
1707
        opn = "madd";
1708
        break;
1709
    case OPC_MADDU:
1710
        gen_op_maddu();
1711
        opn = "maddu";
1712
        break;
1713
    case OPC_MSUB:
1714
        gen_op_msub();
1715
        opn = "msub";
1716
        break;
1717
    case OPC_MSUBU:
1718
        gen_op_msubu();
1719
        opn = "msubu";
1720
        break;
1721
    default:
1722
        MIPS_INVAL(opn);
1723
        generate_exception(ctx, EXCP_RI);
1724
        return;
1725
    }
1726
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1727
}
1728

    
1729
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1730
                            int rd, int rs, int rt)
1731
{
1732
    const char *opn = "mul vr54xx";
1733

    
1734
    GEN_LOAD_REG_T0(rs);
1735
    GEN_LOAD_REG_T1(rt);
1736

    
1737
    switch (opc) {
1738
    case OPC_VR54XX_MULS:
1739
        gen_op_muls();
1740
        opn = "muls";
1741
        break;
1742
    case OPC_VR54XX_MULSU:
1743
        gen_op_mulsu();
1744
        opn = "mulsu";
1745
        break;
1746
    case OPC_VR54XX_MACC:
1747
        gen_op_macc();
1748
        opn = "macc";
1749
        break;
1750
    case OPC_VR54XX_MACCU:
1751
        gen_op_maccu();
1752
        opn = "maccu";
1753
        break;
1754
    case OPC_VR54XX_MSAC:
1755
        gen_op_msac();
1756
        opn = "msac";
1757
        break;
1758
    case OPC_VR54XX_MSACU:
1759
        gen_op_msacu();
1760
        opn = "msacu";
1761
        break;
1762
    case OPC_VR54XX_MULHI:
1763
        gen_op_mulhi();
1764
        opn = "mulhi";
1765
        break;
1766
    case OPC_VR54XX_MULHIU:
1767
        gen_op_mulhiu();
1768
        opn = "mulhiu";
1769
        break;
1770
    case OPC_VR54XX_MULSHI:
1771
        gen_op_mulshi();
1772
        opn = "mulshi";
1773
        break;
1774
    case OPC_VR54XX_MULSHIU:
1775
        gen_op_mulshiu();
1776
        opn = "mulshiu";
1777
        break;
1778
    case OPC_VR54XX_MACCHI:
1779
        gen_op_macchi();
1780
        opn = "macchi";
1781
        break;
1782
    case OPC_VR54XX_MACCHIU:
1783
        gen_op_macchiu();
1784
        opn = "macchiu";
1785
        break;
1786
    case OPC_VR54XX_MSACHI:
1787
        gen_op_msachi();
1788
        opn = "msachi";
1789
        break;
1790
    case OPC_VR54XX_MSACHIU:
1791
        gen_op_msachiu();
1792
        opn = "msachiu";
1793
        break;
1794
    default:
1795
        MIPS_INVAL("mul vr54xx");
1796
        generate_exception(ctx, EXCP_RI);
1797
        return;
1798
    }
1799
    GEN_STORE_T0_REG(rd);
1800
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1801
}
1802

    
1803
static void gen_cl (DisasContext *ctx, uint32_t opc,
1804
                    int rd, int rs)
1805
{
1806
    const char *opn = "CLx";
1807
    if (rd == 0) {
1808
        /* Treat as NOP. */
1809
        MIPS_DEBUG("NOP");
1810
        return;
1811
    }
1812
    GEN_LOAD_REG_T0(rs);
1813
    switch (opc) {
1814
    case OPC_CLO:
1815
        gen_op_clo();
1816
        opn = "clo";
1817
        break;
1818
    case OPC_CLZ:
1819
        gen_op_clz();
1820
        opn = "clz";
1821
        break;
1822
#if defined(TARGET_MIPS64)
1823
    case OPC_DCLO:
1824
        gen_op_dclo();
1825
        opn = "dclo";
1826
        break;
1827
    case OPC_DCLZ:
1828
        gen_op_dclz();
1829
        opn = "dclz";
1830
        break;
1831
#endif
1832
    default:
1833
        MIPS_INVAL(opn);
1834
        generate_exception(ctx, EXCP_RI);
1835
        return;
1836
    }
1837
    gen_op_store_gpr_T0(rd);
1838
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1839
}
1840

    
1841
/* Traps */
1842
static void gen_trap (DisasContext *ctx, uint32_t opc,
1843
                      int rs, int rt, int16_t imm)
1844
{
1845
    int cond;
1846

    
1847
    cond = 0;
1848
    /* Load needed operands */
1849
    switch (opc) {
1850
    case OPC_TEQ:
1851
    case OPC_TGE:
1852
    case OPC_TGEU:
1853
    case OPC_TLT:
1854
    case OPC_TLTU:
1855
    case OPC_TNE:
1856
        /* Compare two registers */
1857
        if (rs != rt) {
1858
            GEN_LOAD_REG_T0(rs);
1859
            GEN_LOAD_REG_T1(rt);
1860
            cond = 1;
1861
        }
1862
        break;
1863
    case OPC_TEQI:
1864
    case OPC_TGEI:
1865
    case OPC_TGEIU:
1866
    case OPC_TLTI:
1867
    case OPC_TLTIU:
1868
    case OPC_TNEI:
1869
        /* Compare register to immediate */
1870
        if (rs != 0 || imm != 0) {
1871
            GEN_LOAD_REG_T0(rs);
1872
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1873
            cond = 1;
1874
        }
1875
        break;
1876
    }
1877
    if (cond == 0) {
1878
        switch (opc) {
1879
        case OPC_TEQ:   /* rs == rs */
1880
        case OPC_TEQI:  /* r0 == 0  */
1881
        case OPC_TGE:   /* rs >= rs */
1882
        case OPC_TGEI:  /* r0 >= 0  */
1883
        case OPC_TGEU:  /* rs >= rs unsigned */
1884
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1885
            /* Always trap */
1886
            gen_op_set_T0(1);
1887
            break;
1888
        case OPC_TLT:   /* rs < rs           */
1889
        case OPC_TLTI:  /* r0 < 0            */
1890
        case OPC_TLTU:  /* rs < rs unsigned  */
1891
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1892
        case OPC_TNE:   /* rs != rs          */
1893
        case OPC_TNEI:  /* r0 != 0           */
1894
            /* Never trap: treat as NOP. */
1895
            return;
1896
        default:
1897
            MIPS_INVAL("trap");
1898
            generate_exception(ctx, EXCP_RI);
1899
            return;
1900
        }
1901
    } else {
1902
        switch (opc) {
1903
        case OPC_TEQ:
1904
        case OPC_TEQI:
1905
            gen_op_eq();
1906
            break;
1907
        case OPC_TGE:
1908
        case OPC_TGEI:
1909
            gen_op_ge();
1910
            break;
1911
        case OPC_TGEU:
1912
        case OPC_TGEIU:
1913
            gen_op_geu();
1914
            break;
1915
        case OPC_TLT:
1916
        case OPC_TLTI:
1917
            gen_op_lt();
1918
            break;
1919
        case OPC_TLTU:
1920
        case OPC_TLTIU:
1921
            gen_op_ltu();
1922
            break;
1923
        case OPC_TNE:
1924
        case OPC_TNEI:
1925
            gen_op_ne();
1926
            break;
1927
        default:
1928
            MIPS_INVAL("trap");
1929
            generate_exception(ctx, EXCP_RI);
1930
            return;
1931
        }
1932
    }
1933
    save_cpu_state(ctx, 1);
1934
    gen_op_trap();
1935
    ctx->bstate = BS_STOP;
1936
}
1937

    
1938
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1939
{
1940
    TranslationBlock *tb;
1941
    tb = ctx->tb;
1942
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1943
        tcg_gen_goto_tb(n);
1944
        gen_save_pc(dest);
1945
        tcg_gen_exit_tb((long)tb + n);
1946
    } else {
1947
        gen_save_pc(dest);
1948
        tcg_gen_exit_tb(0);
1949
    }
1950
}
1951

    
1952
static inline void tcg_gen_set_bcond(void)
1953
{
1954
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
1955
}
1956

    
1957
static inline void tcg_gen_jnz_bcond(int label)
1958
{
1959
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
1960

    
1961
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
1962
    tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);
1963
}
1964

    
1965
/* Branches (before delay slot) */
1966
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1967
                                int rs, int rt, int32_t offset)
1968
{
1969
    target_ulong btarget = -1;
1970
    int blink = 0;
1971
    int bcond = 0;
1972

    
1973
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1974
#ifdef MIPS_DEBUG_DISAS
1975
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1976
            fprintf(logfile,
1977
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1978
                    ctx->pc);
1979
        }
1980
#endif
1981
        generate_exception(ctx, EXCP_RI);
1982
        return;
1983
    }
1984

    
1985
    /* Load needed operands */
1986
    switch (opc) {
1987
    case OPC_BEQ:
1988
    case OPC_BEQL:
1989
    case OPC_BNE:
1990
    case OPC_BNEL:
1991
        /* Compare two registers */
1992
        if (rs != rt) {
1993
            GEN_LOAD_REG_T0(rs);
1994
            GEN_LOAD_REG_T1(rt);
1995
            bcond = 1;
1996
        }
1997
        btarget = ctx->pc + 4 + offset;
1998
        break;
1999
    case OPC_BGEZ:
2000
    case OPC_BGEZAL:
2001
    case OPC_BGEZALL:
2002
    case OPC_BGEZL:
2003
    case OPC_BGTZ:
2004
    case OPC_BGTZL:
2005
    case OPC_BLEZ:
2006
    case OPC_BLEZL:
2007
    case OPC_BLTZ:
2008
    case OPC_BLTZAL:
2009
    case OPC_BLTZALL:
2010
    case OPC_BLTZL:
2011
        /* Compare to zero */
2012
        if (rs != 0) {
2013
            gen_op_load_gpr_T0(rs);
2014
            bcond = 1;
2015
        }
2016
        btarget = ctx->pc + 4 + offset;
2017
        break;
2018
    case OPC_J:
2019
    case OPC_JAL:
2020
        /* Jump to immediate */
2021
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2022
        break;
2023
    case OPC_JR:
2024
    case OPC_JALR:
2025
        /* Jump to register */
2026
        if (offset != 0 && offset != 16) {
2027
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2028
               others are reserved. */
2029
            MIPS_INVAL("jump hint");
2030
            generate_exception(ctx, EXCP_RI);
2031
            return;
2032
        }
2033
        GEN_LOAD_REG_T1(rs);
2034
        gen_op_save_breg_target();
2035
        break;
2036
    default:
2037
        MIPS_INVAL("branch/jump");
2038
        generate_exception(ctx, EXCP_RI);
2039
        return;
2040
    }
2041
    if (bcond == 0) {
2042
        /* No condition to be computed */
2043
        switch (opc) {
2044
        case OPC_BEQ:     /* rx == rx        */
2045
        case OPC_BEQL:    /* rx == rx likely */
2046
        case OPC_BGEZ:    /* 0 >= 0          */
2047
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2048
        case OPC_BLEZ:    /* 0 <= 0          */
2049
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2050
            /* Always take */
2051
            ctx->hflags |= MIPS_HFLAG_B;
2052
            MIPS_DEBUG("balways");
2053
            break;
2054
        case OPC_BGEZAL:  /* 0 >= 0          */
2055
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2056
            /* Always take and link */
2057
            blink = 31;
2058
            ctx->hflags |= MIPS_HFLAG_B;
2059
            MIPS_DEBUG("balways and link");
2060
            break;
2061
        case OPC_BNE:     /* rx != rx        */
2062
        case OPC_BGTZ:    /* 0 > 0           */
2063
        case OPC_BLTZ:    /* 0 < 0           */
2064
            /* Treat as NOP. */
2065
            MIPS_DEBUG("bnever (NOP)");
2066
            return;
2067
        case OPC_BLTZAL:  /* 0 < 0           */
2068
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2069
            gen_op_store_gpr_T0(31);
2070
            MIPS_DEBUG("bnever and link");
2071
            return;
2072
        case OPC_BLTZALL: /* 0 < 0 likely */
2073
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2074
            gen_op_store_gpr_T0(31);
2075
            /* Skip the instruction in the delay slot */
2076
            MIPS_DEBUG("bnever, link and skip");
2077
            ctx->pc += 4;
2078
            return;
2079
        case OPC_BNEL:    /* rx != rx likely */
2080
        case OPC_BGTZL:   /* 0 > 0 likely */
2081
        case OPC_BLTZL:   /* 0 < 0 likely */
2082
            /* Skip the instruction in the delay slot */
2083
            MIPS_DEBUG("bnever and skip");
2084
            ctx->pc += 4;
2085
            return;
2086
        case OPC_J:
2087
            ctx->hflags |= MIPS_HFLAG_B;
2088
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2089
            break;
2090
        case OPC_JAL:
2091
            blink = 31;
2092
            ctx->hflags |= MIPS_HFLAG_B;
2093
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2094
            break;
2095
        case OPC_JR:
2096
            ctx->hflags |= MIPS_HFLAG_BR;
2097
            MIPS_DEBUG("jr %s", regnames[rs]);
2098
            break;
2099
        case OPC_JALR:
2100
            blink = rt;
2101
            ctx->hflags |= MIPS_HFLAG_BR;
2102
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2103
            break;
2104
        default:
2105
            MIPS_INVAL("branch/jump");
2106
            generate_exception(ctx, EXCP_RI);
2107
            return;
2108
        }
2109
    } else {
2110
        switch (opc) {
2111
        case OPC_BEQ:
2112
            gen_op_eq();
2113
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2114
                       regnames[rs], regnames[rt], btarget);
2115
            goto not_likely;
2116
        case OPC_BEQL:
2117
            gen_op_eq();
2118
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2119
                       regnames[rs], regnames[rt], btarget);
2120
            goto likely;
2121
        case OPC_BNE:
2122
            gen_op_ne();
2123
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2124
                       regnames[rs], regnames[rt], btarget);
2125
            goto not_likely;
2126
        case OPC_BNEL:
2127
            gen_op_ne();
2128
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2129
                       regnames[rs], regnames[rt], btarget);
2130
            goto likely;
2131
        case OPC_BGEZ:
2132
            gen_op_gez();
2133
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2134
            goto not_likely;
2135
        case OPC_BGEZL:
2136
            gen_op_gez();
2137
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2138
            goto likely;
2139
        case OPC_BGEZAL:
2140
            gen_op_gez();
2141
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2142
            blink = 31;
2143
            goto not_likely;
2144
        case OPC_BGEZALL:
2145
            gen_op_gez();
2146
            blink = 31;
2147
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2148
            goto likely;
2149
        case OPC_BGTZ:
2150
            gen_op_gtz();
2151
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2152
            goto not_likely;
2153
        case OPC_BGTZL:
2154
            gen_op_gtz();
2155
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2156
            goto likely;
2157
        case OPC_BLEZ:
2158
            gen_op_lez();
2159
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2160
            goto not_likely;
2161
        case OPC_BLEZL:
2162
            gen_op_lez();
2163
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2164
            goto likely;
2165
        case OPC_BLTZ:
2166
            gen_op_ltz();
2167
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2168
            goto not_likely;
2169
        case OPC_BLTZL:
2170
            gen_op_ltz();
2171
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2172
            goto likely;
2173
        case OPC_BLTZAL:
2174
            gen_op_ltz();
2175
            blink = 31;
2176
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2177
        not_likely:
2178
            ctx->hflags |= MIPS_HFLAG_BC;
2179
            tcg_gen_set_bcond();
2180
            break;
2181
        case OPC_BLTZALL:
2182
            gen_op_ltz();
2183
            blink = 31;
2184
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2185
        likely:
2186
            ctx->hflags |= MIPS_HFLAG_BL;
2187
            tcg_gen_set_bcond();
2188
            break;
2189
        default:
2190
            MIPS_INVAL("conditional branch/jump");
2191
            generate_exception(ctx, EXCP_RI);
2192
            return;
2193
        }
2194
    }
2195
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2196
               blink, ctx->hflags, btarget);
2197

    
2198
    ctx->btarget = btarget;
2199
    if (blink > 0) {
2200
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2201
        gen_op_store_gpr_T0(blink);
2202
    }
2203
}
2204

    
2205
/* special3 bitfield operations */
2206
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2207
                       int rs, int lsb, int msb)
2208
{
2209
    GEN_LOAD_REG_T1(rs);
2210
    switch (opc) {
2211
    case OPC_EXT:
2212
        if (lsb + msb > 31)
2213
            goto fail;
2214
        gen_op_ext(lsb, msb + 1);
2215
        break;
2216
#if defined(TARGET_MIPS64)
2217
    case OPC_DEXTM:
2218
        if (lsb + msb > 63)
2219
            goto fail;
2220
        gen_op_dext(lsb, msb + 1 + 32);
2221
        break;
2222
    case OPC_DEXTU:
2223
        if (lsb + msb > 63)
2224
            goto fail;
2225
        gen_op_dext(lsb + 32, msb + 1);
2226
        break;
2227
    case OPC_DEXT:
2228
        if (lsb + msb > 63)
2229
            goto fail;
2230
        gen_op_dext(lsb, msb + 1);
2231
        break;
2232
#endif
2233
    case OPC_INS:
2234
        if (lsb > msb)
2235
            goto fail;
2236
        GEN_LOAD_REG_T0(rt);
2237
        gen_op_ins(lsb, msb - lsb + 1);
2238
        break;
2239
#if defined(TARGET_MIPS64)
2240
    case OPC_DINSM:
2241
        if (lsb > msb)
2242
            goto fail;
2243
        GEN_LOAD_REG_T0(rt);
2244
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2245
        break;
2246
    case OPC_DINSU:
2247
        if (lsb > msb)
2248
            goto fail;
2249
        GEN_LOAD_REG_T0(rt);
2250
        gen_op_dins(lsb + 32, msb - lsb + 1);
2251
        break;
2252
    case OPC_DINS:
2253
        if (lsb > msb)
2254
            goto fail;
2255
        GEN_LOAD_REG_T0(rt);
2256
        gen_op_dins(lsb, msb - lsb + 1);
2257
        break;
2258
#endif
2259
    default:
2260
fail:
2261
        MIPS_INVAL("bitops");
2262
        generate_exception(ctx, EXCP_RI);
2263
        return;
2264
    }
2265
    GEN_STORE_T0_REG(rt);
2266
}
2267

    
2268
/* CP0 (MMU and control) */
2269
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2270
{
2271
    const char *rn = "invalid";
2272

    
2273
    if (sel != 0)
2274
        check_insn(env, ctx, ISA_MIPS32);
2275

    
2276
    switch (reg) {
2277
    case 0:
2278
        switch (sel) {
2279
        case 0:
2280
            gen_op_mfc0_index();
2281
            rn = "Index";
2282
            break;
2283
        case 1:
2284
            check_insn(env, ctx, ASE_MT);
2285
            gen_op_mfc0_mvpcontrol();
2286
            rn = "MVPControl";
2287
            break;
2288
        case 2:
2289
            check_insn(env, ctx, ASE_MT);
2290
            gen_op_mfc0_mvpconf0();
2291
            rn = "MVPConf0";
2292
            break;
2293
        case 3:
2294
            check_insn(env, ctx, ASE_MT);
2295
            gen_op_mfc0_mvpconf1();
2296
            rn = "MVPConf1";
2297
            break;
2298
        default:
2299
            goto die;
2300
        }
2301
        break;
2302
    case 1:
2303
        switch (sel) {
2304
        case 0:
2305
            gen_op_mfc0_random();
2306
            rn = "Random";
2307
            break;
2308
        case 1:
2309
            check_insn(env, ctx, ASE_MT);
2310
            gen_op_mfc0_vpecontrol();
2311
            rn = "VPEControl";
2312
            break;
2313
        case 2:
2314
            check_insn(env, ctx, ASE_MT);
2315
            gen_op_mfc0_vpeconf0();
2316
            rn = "VPEConf0";
2317
            break;
2318
        case 3:
2319
            check_insn(env, ctx, ASE_MT);
2320
            gen_op_mfc0_vpeconf1();
2321
            rn = "VPEConf1";
2322
            break;
2323
        case 4:
2324
            check_insn(env, ctx, ASE_MT);
2325
            gen_op_mfc0_yqmask();
2326
            rn = "YQMask";
2327
            break;
2328
        case 5:
2329
            check_insn(env, ctx, ASE_MT);
2330
            gen_op_mfc0_vpeschedule();
2331
            rn = "VPESchedule";
2332
            break;
2333
        case 6:
2334
            check_insn(env, ctx, ASE_MT);
2335
            gen_op_mfc0_vpeschefback();
2336
            rn = "VPEScheFBack";
2337
            break;
2338
        case 7:
2339
            check_insn(env, ctx, ASE_MT);
2340
            gen_op_mfc0_vpeopt();
2341
            rn = "VPEOpt";
2342
            break;
2343
        default:
2344
            goto die;
2345
        }
2346
        break;
2347
    case 2:
2348
        switch (sel) {
2349
        case 0:
2350
            gen_op_mfc0_entrylo0();
2351
            rn = "EntryLo0";
2352
            break;
2353
        case 1:
2354
            check_insn(env, ctx, ASE_MT);
2355
            gen_op_mfc0_tcstatus();
2356
            rn = "TCStatus";
2357
            break;
2358
        case 2:
2359
            check_insn(env, ctx, ASE_MT);
2360
            gen_op_mfc0_tcbind();
2361
            rn = "TCBind";
2362
            break;
2363
        case 3:
2364
            check_insn(env, ctx, ASE_MT);
2365
            gen_op_mfc0_tcrestart();
2366
            rn = "TCRestart";
2367
            break;
2368
        case 4:
2369
            check_insn(env, ctx, ASE_MT);
2370
            gen_op_mfc0_tchalt();
2371
            rn = "TCHalt";
2372
            break;
2373
        case 5:
2374
            check_insn(env, ctx, ASE_MT);
2375
            gen_op_mfc0_tccontext();
2376
            rn = "TCContext";
2377
            break;
2378
        case 6:
2379
            check_insn(env, ctx, ASE_MT);
2380
            gen_op_mfc0_tcschedule();
2381
            rn = "TCSchedule";
2382
            break;
2383
        case 7:
2384
            check_insn(env, ctx, ASE_MT);
2385
            gen_op_mfc0_tcschefback();
2386
            rn = "TCScheFBack";
2387
            break;
2388
        default:
2389
            goto die;
2390
        }
2391
        break;
2392
    case 3:
2393
        switch (sel) {
2394
        case 0:
2395
            gen_op_mfc0_entrylo1();
2396
            rn = "EntryLo1";
2397
            break;
2398
        default:
2399
            goto die;
2400
        }
2401
        break;
2402
    case 4:
2403
        switch (sel) {
2404
        case 0:
2405
            gen_op_mfc0_context();
2406
            rn = "Context";
2407
            break;
2408
        case 1:
2409
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2410
            rn = "ContextConfig";
2411
//            break;
2412
        default:
2413
            goto die;
2414
        }
2415
        break;
2416
    case 5:
2417
        switch (sel) {
2418
        case 0:
2419
            gen_op_mfc0_pagemask();
2420
            rn = "PageMask";
2421
            break;
2422
        case 1:
2423
            check_insn(env, ctx, ISA_MIPS32R2);
2424
            gen_op_mfc0_pagegrain();
2425
            rn = "PageGrain";
2426
            break;
2427
        default:
2428
            goto die;
2429
        }
2430
        break;
2431
    case 6:
2432
        switch (sel) {
2433
        case 0:
2434
            gen_op_mfc0_wired();
2435
            rn = "Wired";
2436
            break;
2437
        case 1:
2438
            check_insn(env, ctx, ISA_MIPS32R2);
2439
            gen_op_mfc0_srsconf0();
2440
            rn = "SRSConf0";
2441
            break;
2442
        case 2:
2443
            check_insn(env, ctx, ISA_MIPS32R2);
2444
            gen_op_mfc0_srsconf1();
2445
            rn = "SRSConf1";
2446
            break;
2447
        case 3:
2448
            check_insn(env, ctx, ISA_MIPS32R2);
2449
            gen_op_mfc0_srsconf2();
2450
            rn = "SRSConf2";
2451
            break;
2452
        case 4:
2453
            check_insn(env, ctx, ISA_MIPS32R2);
2454
            gen_op_mfc0_srsconf3();
2455
            rn = "SRSConf3";
2456
            break;
2457
        case 5:
2458
            check_insn(env, ctx, ISA_MIPS32R2);
2459
            gen_op_mfc0_srsconf4();
2460
            rn = "SRSConf4";
2461
            break;
2462
        default:
2463
            goto die;
2464
        }
2465
        break;
2466
    case 7:
2467
        switch (sel) {
2468
        case 0:
2469
            check_insn(env, ctx, ISA_MIPS32R2);
2470
            gen_op_mfc0_hwrena();
2471
            rn = "HWREna";
2472
            break;
2473
        default:
2474
            goto die;
2475
        }
2476
        break;
2477
    case 8:
2478
        switch (sel) {
2479
        case 0:
2480
            gen_op_mfc0_badvaddr();
2481
            rn = "BadVaddr";
2482
            break;
2483
        default:
2484
            goto die;
2485
       }
2486
        break;
2487
    case 9:
2488
        switch (sel) {
2489
        case 0:
2490
            gen_op_mfc0_count();
2491
            rn = "Count";
2492
            break;
2493
        /* 6,7 are implementation dependent */
2494
        default:
2495
            goto die;
2496
        }
2497
        break;
2498
    case 10:
2499
        switch (sel) {
2500
        case 0:
2501
            gen_op_mfc0_entryhi();
2502
            rn = "EntryHi";
2503
            break;
2504
        default:
2505
            goto die;
2506
        }
2507
        break;
2508
    case 11:
2509
        switch (sel) {
2510
        case 0:
2511
            gen_op_mfc0_compare();
2512
            rn = "Compare";
2513
            break;
2514
        /* 6,7 are implementation dependent */
2515
        default:
2516
            goto die;
2517
        }
2518
        break;
2519
    case 12:
2520
        switch (sel) {
2521
        case 0:
2522
            gen_op_mfc0_status();
2523
            rn = "Status";
2524
            break;
2525
        case 1:
2526
            check_insn(env, ctx, ISA_MIPS32R2);
2527
            gen_op_mfc0_intctl();
2528
            rn = "IntCtl";
2529
            break;
2530
        case 2:
2531
            check_insn(env, ctx, ISA_MIPS32R2);
2532
            gen_op_mfc0_srsctl();
2533
            rn = "SRSCtl";
2534
            break;
2535
        case 3:
2536
            check_insn(env, ctx, ISA_MIPS32R2);
2537
            gen_op_mfc0_srsmap();
2538
            rn = "SRSMap";
2539
            break;
2540
        default:
2541
            goto die;
2542
       }
2543
        break;
2544
    case 13:
2545
        switch (sel) {
2546
        case 0:
2547
            gen_op_mfc0_cause();
2548
            rn = "Cause";
2549
            break;
2550
        default:
2551
            goto die;
2552
       }
2553
        break;
2554
    case 14:
2555
        switch (sel) {
2556
        case 0:
2557
            gen_op_mfc0_epc();
2558
            rn = "EPC";
2559
            break;
2560
        default:
2561
            goto die;
2562
        }
2563
        break;
2564
    case 15:
2565
        switch (sel) {
2566
        case 0:
2567
            gen_op_mfc0_prid();
2568
            rn = "PRid";
2569
            break;
2570
        case 1:
2571
            check_insn(env, ctx, ISA_MIPS32R2);
2572
            gen_op_mfc0_ebase();
2573
            rn = "EBase";
2574
            break;
2575
        default:
2576
            goto die;
2577
       }
2578
        break;
2579
    case 16:
2580
        switch (sel) {
2581
        case 0:
2582
            gen_op_mfc0_config0();
2583
            rn = "Config";
2584
            break;
2585
        case 1:
2586
            gen_op_mfc0_config1();
2587
            rn = "Config1";
2588
            break;
2589
        case 2:
2590
            gen_op_mfc0_config2();
2591
            rn = "Config2";
2592
            break;
2593
        case 3:
2594
            gen_op_mfc0_config3();
2595
            rn = "Config3";
2596
            break;
2597
        /* 4,5 are reserved */
2598
        /* 6,7 are implementation dependent */
2599
        case 6:
2600
            gen_op_mfc0_config6();
2601
            rn = "Config6";
2602
            break;
2603
        case 7:
2604
            gen_op_mfc0_config7();
2605
            rn = "Config7";
2606
            break;
2607
        default:
2608
            goto die;
2609
        }
2610
        break;
2611
    case 17:
2612
        switch (sel) {
2613
        case 0:
2614
            gen_op_mfc0_lladdr();
2615
            rn = "LLAddr";
2616
            break;
2617
        default:
2618
            goto die;
2619
        }
2620
        break;
2621
    case 18:
2622
        switch (sel) {
2623
        case 0 ... 7:
2624
            gen_op_mfc0_watchlo(sel);
2625
            rn = "WatchLo";
2626
            break;
2627
        default:
2628
            goto die;
2629
        }
2630
        break;
2631
    case 19:
2632
        switch (sel) {
2633
        case 0 ...7:
2634
            gen_op_mfc0_watchhi(sel);
2635
            rn = "WatchHi";
2636
            break;
2637
        default:
2638
            goto die;
2639
        }
2640
        break;
2641
    case 20:
2642
        switch (sel) {
2643
        case 0:
2644
#if defined(TARGET_MIPS64)
2645
            check_insn(env, ctx, ISA_MIPS3);
2646
            gen_op_mfc0_xcontext();
2647
            rn = "XContext";
2648
            break;
2649
#endif
2650
        default:
2651
            goto die;
2652
        }
2653
        break;
2654
    case 21:
2655
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2656
        switch (sel) {
2657
        case 0:
2658
            gen_op_mfc0_framemask();
2659
            rn = "Framemask";
2660
            break;
2661
        default:
2662
            goto die;
2663
        }
2664
        break;
2665
    case 22:
2666
        /* ignored */
2667
        rn = "'Diagnostic"; /* implementation dependent */
2668
        break;
2669
    case 23:
2670
        switch (sel) {
2671
        case 0:
2672
            gen_op_mfc0_debug(); /* EJTAG support */
2673
            rn = "Debug";
2674
            break;
2675
        case 1:
2676
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2677
            rn = "TraceControl";
2678
//            break;
2679
        case 2:
2680
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2681
            rn = "TraceControl2";
2682
//            break;
2683
        case 3:
2684
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2685
            rn = "UserTraceData";
2686
//            break;
2687
        case 4:
2688
//            gen_op_mfc0_debug(); /* PDtrace support */
2689
            rn = "TraceBPC";
2690
//            break;
2691
        default:
2692
            goto die;
2693
        }
2694
        break;
2695
    case 24:
2696
        switch (sel) {
2697
        case 0:
2698
            gen_op_mfc0_depc(); /* EJTAG support */
2699
            rn = "DEPC";
2700
            break;
2701
        default:
2702
            goto die;
2703
        }
2704
        break;
2705
    case 25:
2706
        switch (sel) {
2707
        case 0:
2708
            gen_op_mfc0_performance0();
2709
            rn = "Performance0";
2710
            break;
2711
        case 1:
2712
//            gen_op_mfc0_performance1();
2713
            rn = "Performance1";
2714
//            break;
2715
        case 2:
2716
//            gen_op_mfc0_performance2();
2717
            rn = "Performance2";
2718
//            break;
2719
        case 3:
2720
//            gen_op_mfc0_performance3();
2721
            rn = "Performance3";
2722
//            break;
2723
        case 4:
2724
//            gen_op_mfc0_performance4();
2725
            rn = "Performance4";
2726
//            break;
2727
        case 5:
2728
//            gen_op_mfc0_performance5();
2729
            rn = "Performance5";
2730
//            break;
2731
        case 6:
2732
//            gen_op_mfc0_performance6();
2733
            rn = "Performance6";
2734
//            break;
2735
        case 7:
2736
//            gen_op_mfc0_performance7();
2737
            rn = "Performance7";
2738
//            break;
2739
        default:
2740
            goto die;
2741
        }
2742
        break;
2743
    case 26:
2744
       rn = "ECC";
2745
       break;
2746
    case 27:
2747
        switch (sel) {
2748
        /* ignored */
2749
        case 0 ... 3:
2750
            rn = "CacheErr";
2751
            break;
2752
        default:
2753
            goto die;
2754
        }
2755
        break;
2756
    case 28:
2757
        switch (sel) {
2758
        case 0:
2759
        case 2:
2760
        case 4:
2761
        case 6:
2762
            gen_op_mfc0_taglo();
2763
            rn = "TagLo";
2764
            break;
2765
        case 1:
2766
        case 3:
2767
        case 5:
2768
        case 7:
2769
            gen_op_mfc0_datalo();
2770
            rn = "DataLo";
2771
            break;
2772
        default:
2773
            goto die;
2774
        }
2775
        break;
2776
    case 29:
2777
        switch (sel) {
2778
        case 0:
2779
        case 2:
2780
        case 4:
2781
        case 6:
2782
            gen_op_mfc0_taghi();
2783
            rn = "TagHi";
2784
            break;
2785
        case 1:
2786
        case 3:
2787
        case 5:
2788
        case 7:
2789
            gen_op_mfc0_datahi();
2790
            rn = "DataHi";
2791
            break;
2792
        default:
2793
            goto die;
2794
        }
2795
        break;
2796
    case 30:
2797
        switch (sel) {
2798
        case 0:
2799
            gen_op_mfc0_errorepc();
2800
            rn = "ErrorEPC";
2801
            break;
2802
        default:
2803
            goto die;
2804
        }
2805
        break;
2806
    case 31:
2807
        switch (sel) {
2808
        case 0:
2809
            gen_op_mfc0_desave(); /* EJTAG support */
2810
            rn = "DESAVE";
2811
            break;
2812
        default:
2813
            goto die;
2814
        }
2815
        break;
2816
    default:
2817
       goto die;
2818
    }
2819
#if defined MIPS_DEBUG_DISAS
2820
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2821
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2822
                rn, reg, sel);
2823
    }
2824
#endif
2825
    return;
2826

    
2827
die:
2828
#if defined MIPS_DEBUG_DISAS
2829
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2830
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2831
                rn, reg, sel);
2832
    }
2833
#endif
2834
    generate_exception(ctx, EXCP_RI);
2835
}
2836

    
2837
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2838
{
2839
    const char *rn = "invalid";
2840

    
2841
    if (sel != 0)
2842
        check_insn(env, ctx, ISA_MIPS32);
2843

    
2844
    switch (reg) {
2845
    case 0:
2846
        switch (sel) {
2847
        case 0:
2848
            gen_op_mtc0_index();
2849
            rn = "Index";
2850
            break;
2851
        case 1:
2852
            check_insn(env, ctx, ASE_MT);
2853
            gen_op_mtc0_mvpcontrol();
2854
            rn = "MVPControl";
2855
            break;
2856
        case 2:
2857
            check_insn(env, ctx, ASE_MT);
2858
            /* ignored */
2859
            rn = "MVPConf0";
2860
            break;
2861
        case 3:
2862
            check_insn(env, ctx, ASE_MT);
2863
            /* ignored */
2864
            rn = "MVPConf1";
2865
            break;
2866
        default:
2867
            goto die;
2868
        }
2869
        break;
2870
    case 1:
2871
        switch (sel) {
2872
        case 0:
2873
            /* ignored */
2874
            rn = "Random";
2875
            break;
2876
        case 1:
2877
            check_insn(env, ctx, ASE_MT);
2878
            gen_op_mtc0_vpecontrol();
2879
            rn = "VPEControl";
2880
            break;
2881
        case 2:
2882
            check_insn(env, ctx, ASE_MT);
2883
            gen_op_mtc0_vpeconf0();
2884
            rn = "VPEConf0";
2885
            break;
2886
        case 3:
2887
            check_insn(env, ctx, ASE_MT);
2888
            gen_op_mtc0_vpeconf1();
2889
            rn = "VPEConf1";
2890
            break;
2891
        case 4:
2892
            check_insn(env, ctx, ASE_MT);
2893
            gen_op_mtc0_yqmask();
2894
            rn = "YQMask";
2895
            break;
2896
        case 5:
2897
            check_insn(env, ctx, ASE_MT);
2898
            gen_op_mtc0_vpeschedule();
2899
            rn = "VPESchedule";
2900
            break;
2901
        case 6:
2902
            check_insn(env, ctx, ASE_MT);
2903
            gen_op_mtc0_vpeschefback();
2904
            rn = "VPEScheFBack";
2905
            break;
2906
        case 7:
2907
            check_insn(env, ctx, ASE_MT);
2908
            gen_op_mtc0_vpeopt();
2909
            rn = "VPEOpt";
2910
            break;
2911
        default:
2912
            goto die;
2913
        }
2914
        break;
2915
    case 2:
2916
        switch (sel) {
2917
        case 0:
2918
            gen_op_mtc0_entrylo0();
2919
            rn = "EntryLo0";
2920
            break;
2921
        case 1:
2922
            check_insn(env, ctx, ASE_MT);
2923
            gen_op_mtc0_tcstatus();
2924
            rn = "TCStatus";
2925
            break;
2926
        case 2:
2927
            check_insn(env, ctx, ASE_MT);
2928
            gen_op_mtc0_tcbind();
2929
            rn = "TCBind";
2930
            break;
2931
        case 3:
2932
            check_insn(env, ctx, ASE_MT);
2933
            gen_op_mtc0_tcrestart();
2934
            rn = "TCRestart";
2935
            break;
2936
        case 4:
2937
            check_insn(env, ctx, ASE_MT);
2938
            gen_op_mtc0_tchalt();
2939
            rn = "TCHalt";
2940
            break;
2941
        case 5:
2942
            check_insn(env, ctx, ASE_MT);
2943
            gen_op_mtc0_tccontext();
2944
            rn = "TCContext";
2945
            break;
2946
        case 6:
2947
            check_insn(env, ctx, ASE_MT);
2948
            gen_op_mtc0_tcschedule();
2949
            rn = "TCSchedule";
2950
            break;
2951
        case 7:
2952
            check_insn(env, ctx, ASE_MT);
2953
            gen_op_mtc0_tcschefback();
2954
            rn = "TCScheFBack";
2955
            break;
2956
        default:
2957
            goto die;
2958
        }
2959
        break;
2960
    case 3:
2961
        switch (sel) {
2962
        case 0:
2963
            gen_op_mtc0_entrylo1();
2964
            rn = "EntryLo1";
2965
            break;
2966
        default:
2967
            goto die;
2968
        }
2969
        break;
2970
    case 4:
2971
        switch (sel) {
2972
        case 0:
2973
            gen_op_mtc0_context();
2974
            rn = "Context";
2975
            break;
2976
        case 1:
2977
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2978
            rn = "ContextConfig";
2979
//            break;
2980
        default:
2981
            goto die;
2982
        }
2983
        break;
2984
    case 5:
2985
        switch (sel) {
2986
        case 0:
2987
            gen_op_mtc0_pagemask();
2988
            rn = "PageMask";
2989
            break;
2990
        case 1:
2991
            check_insn(env, ctx, ISA_MIPS32R2);
2992
            gen_op_mtc0_pagegrain();
2993
            rn = "PageGrain";
2994
            break;
2995
        default:
2996
            goto die;
2997
        }
2998
        break;
2999
    case 6:
3000
        switch (sel) {
3001
        case 0:
3002
            gen_op_mtc0_wired();
3003
            rn = "Wired";
3004
            break;
3005
        case 1:
3006
            check_insn(env, ctx, ISA_MIPS32R2);
3007
            gen_op_mtc0_srsconf0();
3008
            rn = "SRSConf0";
3009
            break;
3010
        case 2:
3011
            check_insn(env, ctx, ISA_MIPS32R2);
3012
            gen_op_mtc0_srsconf1();
3013
            rn = "SRSConf1";
3014
            break;
3015
        case 3:
3016
            check_insn(env, ctx, ISA_MIPS32R2);
3017
            gen_op_mtc0_srsconf2();
3018
            rn = "SRSConf2";
3019
            break;
3020
        case 4:
3021
            check_insn(env, ctx, ISA_MIPS32R2);
3022
            gen_op_mtc0_srsconf3();
3023
            rn = "SRSConf3";
3024
            break;
3025
        case 5:
3026
            check_insn(env, ctx, ISA_MIPS32R2);
3027
            gen_op_mtc0_srsconf4();
3028
            rn = "SRSConf4";
3029
            break;
3030
        default:
3031
            goto die;
3032
        }
3033
        break;
3034
    case 7:
3035
        switch (sel) {
3036
        case 0:
3037
            check_insn(env, ctx, ISA_MIPS32R2);
3038
            gen_op_mtc0_hwrena();
3039
            rn = "HWREna";
3040
            break;
3041
        default:
3042
            goto die;
3043
        }
3044
        break;
3045
    case 8:
3046
        /* ignored */
3047
        rn = "BadVaddr";
3048
        break;
3049
    case 9:
3050
        switch (sel) {
3051
        case 0:
3052
            gen_op_mtc0_count();
3053
            rn = "Count";
3054
            break;
3055
        /* 6,7 are implementation dependent */
3056
        default:
3057
            goto die;
3058
        }
3059
        /* Stop translation as we may have switched the execution mode */
3060
        ctx->bstate = BS_STOP;
3061
        break;
3062
    case 10:
3063
        switch (sel) {
3064
        case 0:
3065
            gen_op_mtc0_entryhi();
3066
            rn = "EntryHi";
3067
            break;
3068
        default:
3069
            goto die;
3070
        }
3071
        break;
3072
    case 11:
3073
        switch (sel) {
3074
        case 0:
3075
            gen_op_mtc0_compare();
3076
            rn = "Compare";
3077
            break;
3078
        /* 6,7 are implementation dependent */
3079
        default:
3080
            goto die;
3081
        }
3082
        /* Stop translation as we may have switched the execution mode */
3083
        ctx->bstate = BS_STOP;
3084
        break;
3085
    case 12:
3086
        switch (sel) {
3087
        case 0:
3088
            gen_op_mtc0_status();
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 = "Status";
3093
            break;
3094
        case 1:
3095
            check_insn(env, ctx, ISA_MIPS32R2);
3096
            gen_op_mtc0_intctl();
3097
            /* Stop translation as we may have switched the execution mode */
3098
            ctx->bstate = BS_STOP;
3099
            rn = "IntCtl";
3100
            break;
3101
        case 2:
3102
            check_insn(env, ctx, ISA_MIPS32R2);
3103
            gen_op_mtc0_srsctl();
3104
            /* Stop translation as we may have switched the execution mode */
3105
            ctx->bstate = BS_STOP;
3106
            rn = "SRSCtl";
3107
            break;
3108
        case 3:
3109
            check_insn(env, ctx, ISA_MIPS32R2);
3110
            gen_op_mtc0_srsmap();
3111
            /* Stop translation as we may have switched the execution mode */
3112
            ctx->bstate = BS_STOP;
3113
            rn = "SRSMap";
3114
            break;
3115
        default:
3116
            goto die;
3117
        }
3118
        break;
3119
    case 13:
3120
        switch (sel) {
3121
        case 0:
3122
            gen_op_mtc0_cause();
3123
            rn = "Cause";
3124
            break;
3125
        default:
3126
            goto die;
3127
        }
3128
        /* Stop translation as we may have switched the execution mode */
3129
        ctx->bstate = BS_STOP;
3130
        break;
3131
    case 14:
3132
        switch (sel) {
3133
        case 0:
3134
            gen_op_mtc0_epc();
3135
            rn = "EPC";
3136
            break;
3137
        default:
3138
            goto die;
3139
        }
3140
        break;
3141
    case 15:
3142
        switch (sel) {
3143
        case 0:
3144
            /* ignored */
3145
            rn = "PRid";
3146
            break;
3147
        case 1:
3148
            check_insn(env, ctx, ISA_MIPS32R2);
3149
            gen_op_mtc0_ebase();
3150
            rn = "EBase";
3151
            break;
3152
        default:
3153
            goto die;
3154
        }
3155
        break;
3156
    case 16:
3157
        switch (sel) {
3158
        case 0:
3159
            gen_op_mtc0_config0();
3160
            rn = "Config";
3161
            /* Stop translation as we may have switched the execution mode */
3162
            ctx->bstate = BS_STOP;
3163
            break;
3164
        case 1:
3165
            /* ignored, read only */
3166
            rn = "Config1";
3167
            break;
3168
        case 2:
3169
            gen_op_mtc0_config2();
3170
            rn = "Config2";
3171
            /* Stop translation as we may have switched the execution mode */
3172
            ctx->bstate = BS_STOP;
3173
            break;
3174
        case 3:
3175
            /* ignored, read only */
3176
            rn = "Config3";
3177
            break;
3178
        /* 4,5 are reserved */
3179
        /* 6,7 are implementation dependent */
3180
        case 6:
3181
            /* ignored */
3182
            rn = "Config6";
3183
            break;
3184
        case 7:
3185
            /* ignored */
3186
            rn = "Config7";
3187
            break;
3188
        default:
3189
            rn = "Invalid config selector";
3190
            goto die;
3191
        }
3192
        break;
3193
    case 17:
3194
        switch (sel) {
3195
        case 0:
3196
            /* ignored */
3197
            rn = "LLAddr";
3198
            break;
3199
        default:
3200
            goto die;
3201
        }
3202
        break;
3203
    case 18:
3204
        switch (sel) {
3205
        case 0 ... 7:
3206
            gen_op_mtc0_watchlo(sel);
3207
            rn = "WatchLo";
3208
            break;
3209
        default:
3210
            goto die;
3211
        }
3212
        break;
3213
    case 19:
3214
        switch (sel) {
3215
        case 0 ... 7:
3216
            gen_op_mtc0_watchhi(sel);
3217
            rn = "WatchHi";
3218
            break;
3219
        default:
3220
            goto die;
3221
        }
3222
        break;
3223
    case 20:
3224
        switch (sel) {
3225
        case 0:
3226
#if defined(TARGET_MIPS64)
3227
            check_insn(env, ctx, ISA_MIPS3);
3228
            gen_op_mtc0_xcontext();
3229
            rn = "XContext";
3230
            break;
3231
#endif
3232
        default:
3233
            goto die;
3234
        }
3235
        break;
3236
    case 21:
3237
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3238
        switch (sel) {
3239
        case 0:
3240
            gen_op_mtc0_framemask();
3241
            rn = "Framemask";
3242
            break;
3243
        default:
3244
            goto die;
3245
        }
3246
        break;
3247
    case 22:
3248
        /* ignored */
3249
        rn = "Diagnostic"; /* implementation dependent */
3250
        break;
3251
    case 23:
3252
        switch (sel) {
3253
        case 0:
3254
            gen_op_mtc0_debug(); /* EJTAG support */
3255
            /* BS_STOP isn't good enough here, hflags may have changed. */
3256
            gen_save_pc(ctx->pc + 4);
3257
            ctx->bstate = BS_EXCP;
3258
            rn = "Debug";
3259
            break;
3260
        case 1:
3261
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3262
            rn = "TraceControl";
3263
            /* Stop translation as we may have switched the execution mode */
3264
            ctx->bstate = BS_STOP;
3265
//            break;
3266
        case 2:
3267
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3268
            rn = "TraceControl2";
3269
            /* Stop translation as we may have switched the execution mode */
3270
            ctx->bstate = BS_STOP;
3271
//            break;
3272
        case 3:
3273
            /* Stop translation as we may have switched the execution mode */
3274
            ctx->bstate = BS_STOP;
3275
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3276
            rn = "UserTraceData";
3277
            /* Stop translation as we may have switched the execution mode */
3278
            ctx->bstate = BS_STOP;
3279
//            break;
3280
        case 4:
3281
//            gen_op_mtc0_debug(); /* PDtrace support */
3282
            /* Stop translation as we may have switched the execution mode */
3283
            ctx->bstate = BS_STOP;
3284
            rn = "TraceBPC";
3285
//            break;
3286
        default:
3287
            goto die;
3288
        }
3289
        break;
3290
    case 24:
3291
        switch (sel) {
3292
        case 0:
3293
            gen_op_mtc0_depc(); /* EJTAG support */
3294
            rn = "DEPC";
3295
            break;
3296
        default:
3297
            goto die;
3298
        }
3299
        break;
3300
    case 25:
3301
        switch (sel) {
3302
        case 0:
3303
            gen_op_mtc0_performance0();
3304
            rn = "Performance0";
3305
            break;
3306
        case 1:
3307
//            gen_op_mtc0_performance1();
3308
            rn = "Performance1";
3309
//            break;
3310
        case 2:
3311
//            gen_op_mtc0_performance2();
3312
            rn = "Performance2";
3313
//            break;
3314
        case 3:
3315
//            gen_op_mtc0_performance3();
3316
            rn = "Performance3";
3317
//            break;
3318
        case 4:
3319
//            gen_op_mtc0_performance4();
3320
            rn = "Performance4";
3321
//            break;
3322
        case 5:
3323
//            gen_op_mtc0_performance5();
3324
            rn = "Performance5";
3325
//            break;
3326
        case 6:
3327
//            gen_op_mtc0_performance6();
3328
            rn = "Performance6";
3329
//            break;
3330
        case 7:
3331
//            gen_op_mtc0_performance7();
3332
            rn = "Performance7";
3333
//            break;
3334
        default:
3335
            goto die;
3336
        }
3337
       break;
3338
    case 26:
3339
        /* ignored */
3340
        rn = "ECC";
3341
        break;
3342
    case 27:
3343
        switch (sel) {
3344
        case 0 ... 3:
3345
            /* ignored */
3346
            rn = "CacheErr";
3347
            break;
3348
        default:
3349
            goto die;
3350
        }
3351
       break;
3352
    case 28:
3353
        switch (sel) {
3354
        case 0:
3355
        case 2:
3356
        case 4:
3357
        case 6:
3358
            gen_op_mtc0_taglo();
3359
            rn = "TagLo";
3360
            break;
3361
        case 1:
3362
        case 3:
3363
        case 5:
3364
        case 7:
3365
            gen_op_mtc0_datalo();
3366
            rn = "DataLo";
3367
            break;
3368
        default:
3369
            goto die;
3370
        }
3371
        break;
3372
    case 29:
3373
        switch (sel) {
3374
        case 0:
3375
        case 2:
3376
        case 4:
3377
        case 6:
3378
            gen_op_mtc0_taghi();
3379
            rn = "TagHi";
3380
            break;
3381
        case 1:
3382
        case 3:
3383
        case 5:
3384
        case 7:
3385
            gen_op_mtc0_datahi();
3386
            rn = "DataHi";
3387
            break;
3388
        default:
3389
            rn = "invalid sel";
3390
            goto die;
3391
        }
3392
       break;
3393
    case 30:
3394
        switch (sel) {
3395
        case 0:
3396
            gen_op_mtc0_errorepc();
3397
            rn = "ErrorEPC";
3398
            break;
3399
        default:
3400
            goto die;
3401
        }
3402
        break;
3403
    case 31:
3404
        switch (sel) {
3405
        case 0:
3406
            gen_op_mtc0_desave(); /* EJTAG support */
3407
            rn = "DESAVE";
3408
            break;
3409
        default:
3410
            goto die;
3411
        }
3412
        /* Stop translation as we may have switched the execution mode */
3413
        ctx->bstate = BS_STOP;
3414
        break;
3415
    default:
3416
       goto die;
3417
    }
3418
#if defined MIPS_DEBUG_DISAS
3419
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3420
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3421
                rn, reg, sel);
3422
    }
3423
#endif
3424
    return;
3425

    
3426
die:
3427
#if defined MIPS_DEBUG_DISAS
3428
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3429
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3430
                rn, reg, sel);
3431
    }
3432
#endif
3433
    generate_exception(ctx, EXCP_RI);
3434
}
3435

    
3436
#if defined(TARGET_MIPS64)
3437
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3438
{
3439
    const char *rn = "invalid";
3440

    
3441
    if (sel != 0)
3442
        check_insn(env, ctx, ISA_MIPS64);
3443

    
3444
    switch (reg) {
3445
    case 0:
3446
        switch (sel) {
3447
        case 0:
3448
            gen_op_mfc0_index();
3449
            rn = "Index";
3450
            break;
3451
        case 1:
3452
            check_insn(env, ctx, ASE_MT);
3453
            gen_op_mfc0_mvpcontrol();
3454
            rn = "MVPControl";
3455
            break;
3456
        case 2:
3457
            check_insn(env, ctx, ASE_MT);
3458
            gen_op_mfc0_mvpconf0();
3459
            rn = "MVPConf0";
3460
            break;
3461
        case 3:
3462
            check_insn(env, ctx, ASE_MT);
3463
            gen_op_mfc0_mvpconf1();
3464
            rn = "MVPConf1";
3465
            break;
3466
        default:
3467
            goto die;
3468
        }
3469
        break;
3470
    case 1:
3471
        switch (sel) {
3472
        case 0:
3473
            gen_op_mfc0_random();
3474
            rn = "Random";
3475
            break;
3476
        case 1:
3477
            check_insn(env, ctx, ASE_MT);
3478
            gen_op_mfc0_vpecontrol();
3479
            rn = "VPEControl";
3480
            break;
3481
        case 2:
3482
            check_insn(env, ctx, ASE_MT);
3483
            gen_op_mfc0_vpeconf0();
3484
            rn = "VPEConf0";
3485
            break;
3486
        case 3:
3487
            check_insn(env, ctx, ASE_MT);
3488
            gen_op_mfc0_vpeconf1();
3489
            rn = "VPEConf1";
3490
            break;
3491
        case 4:
3492
            check_insn(env, ctx, ASE_MT);
3493
            gen_op_dmfc0_yqmask();
3494
            rn = "YQMask";
3495
            break;
3496
        case 5:
3497
            check_insn(env, ctx, ASE_MT);
3498
            gen_op_dmfc0_vpeschedule();
3499
            rn = "VPESchedule";
3500
            break;
3501
        case 6:
3502
            check_insn(env, ctx, ASE_MT);
3503
            gen_op_dmfc0_vpeschefback();
3504
            rn = "VPEScheFBack";
3505
            break;
3506
        case 7:
3507
            check_insn(env, ctx, ASE_MT);
3508
            gen_op_mfc0_vpeopt();
3509
            rn = "VPEOpt";
3510
            break;
3511
        default:
3512
            goto die;
3513
        }
3514
        break;
3515
    case 2:
3516
        switch (sel) {
3517
        case 0:
3518
            gen_op_dmfc0_entrylo0();
3519
            rn = "EntryLo0";
3520
            break;
3521
        case 1:
3522
            check_insn(env, ctx, ASE_MT);
3523
            gen_op_mfc0_tcstatus();
3524
            rn = "TCStatus";
3525
            break;
3526
        case 2:
3527
            check_insn(env, ctx, ASE_MT);
3528
            gen_op_mfc0_tcbind();
3529
            rn = "TCBind";
3530
            break;
3531
        case 3:
3532
            check_insn(env, ctx, ASE_MT);
3533
            gen_op_dmfc0_tcrestart();
3534
            rn = "TCRestart";
3535
            break;
3536
        case 4:
3537
            check_insn(env, ctx, ASE_MT);
3538
            gen_op_dmfc0_tchalt();
3539
            rn = "TCHalt";
3540
            break;
3541
        case 5:
3542
            check_insn(env, ctx, ASE_MT);
3543
            gen_op_dmfc0_tccontext();
3544
            rn = "TCContext";
3545
            break;
3546
        case 6:
3547
            check_insn(env, ctx, ASE_MT);
3548
            gen_op_dmfc0_tcschedule();
3549
            rn = "TCSchedule";
3550
            break;
3551
        case 7:
3552
            check_insn(env, ctx, ASE_MT);
3553
            gen_op_dmfc0_tcschefback();
3554
            rn = "TCScheFBack";
3555
            break;
3556
        default:
3557
            goto die;
3558
        }
3559
        break;
3560
    case 3:
3561
        switch (sel) {
3562
        case 0:
3563
            gen_op_dmfc0_entrylo1();
3564
            rn = "EntryLo1";
3565
            break;
3566
        default:
3567
            goto die;
3568
        }
3569
        break;
3570
    case 4:
3571
        switch (sel) {
3572
        case 0:
3573
            gen_op_dmfc0_context();
3574
            rn = "Context";
3575
            break;
3576
        case 1:
3577
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3578
            rn = "ContextConfig";
3579
//            break;
3580
        default:
3581
            goto die;
3582
        }
3583
        break;
3584
    case 5:
3585
        switch (sel) {
3586
        case 0:
3587
            gen_op_mfc0_pagemask();
3588
            rn = "PageMask";
3589
            break;
3590
        case 1:
3591
            check_insn(env, ctx, ISA_MIPS32R2);
3592
            gen_op_mfc0_pagegrain();
3593
            rn = "PageGrain";
3594
            break;
3595
        default:
3596
            goto die;
3597
        }
3598
        break;
3599
    case 6:
3600
        switch (sel) {
3601
        case 0:
3602
            gen_op_mfc0_wired();
3603
            rn = "Wired";
3604
            break;
3605
        case 1:
3606
            check_insn(env, ctx, ISA_MIPS32R2);
3607
            gen_op_mfc0_srsconf0();
3608
            rn = "SRSConf0";
3609
            break;
3610
        case 2:
3611
            check_insn(env, ctx, ISA_MIPS32R2);
3612
            gen_op_mfc0_srsconf1();
3613
            rn = "SRSConf1";
3614
            break;
3615
        case 3:
3616
            check_insn(env, ctx, ISA_MIPS32R2);
3617
            gen_op_mfc0_srsconf2();
3618
            rn = "SRSConf2";
3619
            break;
3620
        case 4:
3621
            check_insn(env, ctx, ISA_MIPS32R2);
3622
            gen_op_mfc0_srsconf3();
3623
            rn = "SRSConf3";
3624
            break;
3625
        case 5:
3626
            check_insn(env, ctx, ISA_MIPS32R2);
3627
            gen_op_mfc0_srsconf4();
3628
            rn = "SRSConf4";
3629
            break;
3630
        default:
3631
            goto die;
3632
        }
3633
        break;
3634
    case 7:
3635
        switch (sel) {
3636
        case 0:
3637
            check_insn(env, ctx, ISA_MIPS32R2);
3638
            gen_op_mfc0_hwrena();
3639
            rn = "HWREna";
3640
            break;
3641
        default:
3642
            goto die;
3643
        }
3644
        break;
3645
    case 8:
3646
        switch (sel) {
3647
        case 0:
3648
            gen_op_dmfc0_badvaddr();
3649
            rn = "BadVaddr";
3650
            break;
3651
        default:
3652
            goto die;
3653
        }
3654
        break;
3655
    case 9:
3656
        switch (sel) {
3657
        case 0:
3658
            gen_op_mfc0_count();
3659
            rn = "Count";
3660
            break;
3661
        /* 6,7 are implementation dependent */
3662
        default:
3663
            goto die;
3664
        }
3665
        break;
3666
    case 10:
3667
        switch (sel) {
3668
        case 0:
3669
            gen_op_dmfc0_entryhi();
3670
            rn = "EntryHi";
3671
            break;
3672
        default:
3673
            goto die;
3674
        }
3675
        break;
3676
    case 11:
3677
        switch (sel) {
3678
        case 0:
3679
            gen_op_mfc0_compare();
3680
            rn = "Compare";
3681
            break;
3682
        /* 6,7 are implementation dependent */
3683
        default:
3684
            goto die;
3685
        }
3686
        break;
3687
    case 12:
3688
        switch (sel) {
3689
        case 0:
3690
            gen_op_mfc0_status();
3691
            rn = "Status";
3692
            break;
3693
        case 1:
3694
            check_insn(env, ctx, ISA_MIPS32R2);
3695
            gen_op_mfc0_intctl();
3696
            rn = "IntCtl";
3697
            break;
3698
        case 2:
3699
            check_insn(env, ctx, ISA_MIPS32R2);
3700
            gen_op_mfc0_srsctl();
3701
            rn = "SRSCtl";
3702
            break;
3703
        case 3:
3704
            check_insn(env, ctx, ISA_MIPS32R2);
3705
            gen_op_mfc0_srsmap();
3706
            rn = "SRSMap";
3707
            break;
3708
        default:
3709
            goto die;
3710
        }
3711
        break;
3712
    case 13:
3713
        switch (sel) {
3714
        case 0:
3715
            gen_op_mfc0_cause();
3716
            rn = "Cause";
3717
            break;
3718
        default:
3719
            goto die;
3720
        }
3721
        break;
3722
    case 14:
3723
        switch (sel) {
3724
        case 0:
3725
            gen_op_dmfc0_epc();
3726
            rn = "EPC";
3727
            break;
3728
        default:
3729
            goto die;
3730
        }
3731
        break;
3732
    case 15:
3733
        switch (sel) {
3734
        case 0:
3735
            gen_op_mfc0_prid();
3736
            rn = "PRid";
3737
            break;
3738
        case 1:
3739
            check_insn(env, ctx, ISA_MIPS32R2);
3740
            gen_op_mfc0_ebase();
3741
            rn = "EBase";
3742
            break;
3743
        default:
3744
            goto die;
3745
        }
3746
        break;
3747
    case 16:
3748
        switch (sel) {
3749
        case 0:
3750
            gen_op_mfc0_config0();
3751
            rn = "Config";
3752
            break;
3753
        case 1:
3754
            gen_op_mfc0_config1();
3755
            rn = "Config1";
3756
            break;
3757
        case 2:
3758
            gen_op_mfc0_config2();
3759
            rn = "Config2";
3760
            break;
3761
        case 3:
3762
            gen_op_mfc0_config3();
3763
            rn = "Config3";
3764
            break;
3765
       /* 6,7 are implementation dependent */
3766
        default:
3767
            goto die;
3768
        }
3769
        break;
3770
    case 17:
3771
        switch (sel) {
3772
        case 0:
3773
            gen_op_dmfc0_lladdr();
3774
            rn = "LLAddr";
3775
            break;
3776
        default:
3777
            goto die;
3778
        }
3779
        break;
3780
    case 18:
3781
        switch (sel) {
3782
        case 0 ... 7:
3783
            gen_op_dmfc0_watchlo(sel);
3784
            rn = "WatchLo";
3785
            break;
3786
        default:
3787
            goto die;
3788
        }
3789
        break;
3790
    case 19:
3791
        switch (sel) {
3792
        case 0 ... 7:
3793
            gen_op_mfc0_watchhi(sel);
3794
            rn = "WatchHi";
3795
            break;
3796
        default:
3797
            goto die;
3798
        }
3799
        break;
3800
    case 20:
3801
        switch (sel) {
3802
        case 0:
3803
            check_insn(env, ctx, ISA_MIPS3);
3804
            gen_op_dmfc0_xcontext();
3805
            rn = "XContext";
3806
            break;
3807
        default:
3808
            goto die;
3809
        }
3810
        break;
3811
    case 21:
3812
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3813
        switch (sel) {
3814
        case 0:
3815
            gen_op_mfc0_framemask();
3816
            rn = "Framemask";
3817
            break;
3818
        default:
3819
            goto die;
3820
        }
3821
        break;
3822
    case 22:
3823
        /* ignored */
3824
        rn = "'Diagnostic"; /* implementation dependent */
3825
        break;
3826
    case 23:
3827
        switch (sel) {
3828
        case 0:
3829
            gen_op_mfc0_debug(); /* EJTAG support */
3830
            rn = "Debug";
3831
            break;
3832
        case 1:
3833
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3834
            rn = "TraceControl";
3835
//            break;
3836
        case 2:
3837
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3838
            rn = "TraceControl2";
3839
//            break;
3840
        case 3:
3841
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3842
            rn = "UserTraceData";
3843
//            break;
3844
        case 4:
3845
//            gen_op_dmfc0_debug(); /* PDtrace support */
3846
            rn = "TraceBPC";
3847
//            break;
3848
        default:
3849
            goto die;
3850
        }
3851
        break;
3852
    case 24:
3853
        switch (sel) {
3854
        case 0:
3855
            gen_op_dmfc0_depc(); /* EJTAG support */
3856
            rn = "DEPC";
3857
            break;
3858
        default:
3859
            goto die;
3860
        }
3861
        break;
3862
    case 25:
3863
        switch (sel) {
3864
        case 0:
3865
            gen_op_mfc0_performance0();
3866
            rn = "Performance0";
3867
            break;
3868
        case 1:
3869
//            gen_op_dmfc0_performance1();
3870
            rn = "Performance1";
3871
//            break;
3872
        case 2:
3873
//            gen_op_dmfc0_performance2();
3874
            rn = "Performance2";
3875
//            break;
3876
        case 3:
3877
//            gen_op_dmfc0_performance3();
3878
            rn = "Performance3";
3879
//            break;
3880
        case 4:
3881
//            gen_op_dmfc0_performance4();
3882
            rn = "Performance4";
3883
//            break;
3884
        case 5:
3885
//            gen_op_dmfc0_performance5();
3886
            rn = "Performance5";
3887
//            break;
3888
        case 6:
3889
//            gen_op_dmfc0_performance6();
3890
            rn = "Performance6";
3891
//            break;
3892
        case 7:
3893
//            gen_op_dmfc0_performance7();
3894
            rn = "Performance7";
3895
//            break;
3896
        default:
3897
            goto die;
3898
        }
3899
        break;
3900
    case 26:
3901
       rn = "ECC";
3902
       break;
3903
    case 27:
3904
        switch (sel) {
3905
        /* ignored */
3906
        case 0 ... 3:
3907
            rn = "CacheErr";
3908
            break;
3909
        default:
3910
            goto die;
3911
        }
3912
        break;
3913
    case 28:
3914
        switch (sel) {
3915
        case 0:
3916
        case 2:
3917
        case 4:
3918
        case 6:
3919
            gen_op_mfc0_taglo();
3920
            rn = "TagLo";
3921
            break;
3922
        case 1:
3923
        case 3:
3924
        case 5:
3925
        case 7:
3926
            gen_op_mfc0_datalo();
3927
            rn = "DataLo";
3928
            break;
3929
        default:
3930
            goto die;
3931
        }
3932
        break;
3933
    case 29:
3934
        switch (sel) {
3935
        case 0:
3936
        case 2:
3937
        case 4:
3938
        case 6:
3939
            gen_op_mfc0_taghi();
3940
            rn = "TagHi";
3941
            break;
3942
        case 1:
3943
        case 3:
3944
        case 5:
3945
        case 7:
3946
            gen_op_mfc0_datahi();
3947
            rn = "DataHi";
3948
            break;
3949
        default:
3950
            goto die;
3951
        }
3952
        break;
3953
    case 30:
3954
        switch (sel) {
3955
        case 0:
3956
            gen_op_dmfc0_errorepc();
3957
            rn = "ErrorEPC";
3958
            break;
3959
        default:
3960
            goto die;
3961
        }
3962
        break;
3963
    case 31:
3964
        switch (sel) {
3965
        case 0:
3966
            gen_op_mfc0_desave(); /* EJTAG support */
3967
            rn = "DESAVE";
3968
            break;
3969
        default:
3970
            goto die;
3971
        }
3972
        break;
3973
    default:
3974
        goto die;
3975
    }
3976
#if defined MIPS_DEBUG_DISAS
3977
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3978
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3979
                rn, reg, sel);
3980
    }
3981
#endif
3982
    return;
3983

    
3984
die:
3985
#if defined MIPS_DEBUG_DISAS
3986
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3987
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3988
                rn, reg, sel);
3989
    }
3990
#endif
3991
    generate_exception(ctx, EXCP_RI);
3992
}
3993

    
3994
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3995
{
3996
    const char *rn = "invalid";
3997

    
3998
    if (sel != 0)
3999
        check_insn(env, ctx, ISA_MIPS64);
4000

    
4001
    switch (reg) {
4002
    case 0:
4003
        switch (sel) {
4004
        case 0:
4005
            gen_op_mtc0_index();
4006
            rn = "Index";
4007
            break;
4008
        case 1:
4009
            check_insn(env, ctx, ASE_MT);
4010
            gen_op_mtc0_mvpcontrol();
4011
            rn = "MVPControl";
4012
            break;
4013
        case 2:
4014
            check_insn(env, ctx, ASE_MT);
4015
            /* ignored */
4016
            rn = "MVPConf0";
4017
            break;
4018
        case 3:
4019
            check_insn(env, ctx, ASE_MT);
4020
            /* ignored */
4021
            rn = "MVPConf1";
4022
            break;
4023
        default:
4024
            goto die;
4025
        }
4026
        break;
4027
    case 1:
4028
        switch (sel) {
4029
        case 0:
4030
            /* ignored */
4031
            rn = "Random";
4032
            break;
4033
        case 1:
4034
            check_insn(env, ctx, ASE_MT);
4035
            gen_op_mtc0_vpecontrol();
4036
            rn = "VPEControl";
4037
            break;
4038
        case 2:
4039
            check_insn(env, ctx, ASE_MT);
4040
            gen_op_mtc0_vpeconf0();
4041
            rn = "VPEConf0";
4042
            break;
4043
        case 3:
4044
            check_insn(env, ctx, ASE_MT);
4045
            gen_op_mtc0_vpeconf1();
4046
            rn = "VPEConf1";
4047
            break;
4048
        case 4:
4049
            check_insn(env, ctx, ASE_MT);
4050
            gen_op_mtc0_yqmask();
4051
            rn = "YQMask";
4052
            break;
4053
        case 5:
4054
            check_insn(env, ctx, ASE_MT);
4055
            gen_op_mtc0_vpeschedule();
4056
            rn = "VPESchedule";
4057
            break;
4058
        case 6:
4059
            check_insn(env, ctx, ASE_MT);
4060
            gen_op_mtc0_vpeschefback();
4061
            rn = "VPEScheFBack";
4062
            break;
4063
        case 7:
4064
            check_insn(env, ctx, ASE_MT);
4065
            gen_op_mtc0_vpeopt();
4066
            rn = "VPEOpt";
4067
            break;
4068
        default:
4069
            goto die;
4070
        }
4071
        break;
4072
    case 2:
4073
        switch (sel) {
4074
        case 0:
4075
            gen_op_mtc0_entrylo0();
4076
            rn = "EntryLo0";
4077
            break;
4078
        case 1:
4079
            check_insn(env, ctx, ASE_MT);
4080
            gen_op_mtc0_tcstatus();
4081
            rn = "TCStatus";
4082
            break;
4083
        case 2:
4084
            check_insn(env, ctx, ASE_MT);
4085
            gen_op_mtc0_tcbind();
4086
            rn = "TCBind";
4087
            break;
4088
        case 3:
4089
            check_insn(env, ctx, ASE_MT);
4090
            gen_op_mtc0_tcrestart();
4091
            rn = "TCRestart";
4092
            break;
4093
        case 4:
4094
            check_insn(env, ctx, ASE_MT);
4095
            gen_op_mtc0_tchalt();
4096
            rn = "TCHalt";
4097
            break;
4098
        case 5:
4099
            check_insn(env, ctx, ASE_MT);
4100
            gen_op_mtc0_tccontext();
4101
            rn = "TCContext";
4102
            break;
4103
        case 6:
4104
            check_insn(env, ctx, ASE_MT);
4105
            gen_op_mtc0_tcschedule();
4106
            rn = "TCSchedule";
4107
            break;
4108
        case 7:
4109
            check_insn(env, ctx, ASE_MT);
4110
            gen_op_mtc0_tcschefback();
4111
            rn = "TCScheFBack";
4112
            break;
4113
        default:
4114
            goto die;
4115
        }
4116
        break;
4117
    case 3:
4118
        switch (sel) {
4119
        case 0:
4120
            gen_op_mtc0_entrylo1();
4121
            rn = "EntryLo1";
4122
            break;
4123
        default:
4124
            goto die;
4125
        }
4126
        break;
4127
    case 4:
4128
        switch (sel) {
4129
        case 0:
4130
            gen_op_mtc0_context();
4131
            rn = "Context";
4132
            break;
4133
        case 1:
4134
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4135
            rn = "ContextConfig";
4136
//           break;
4137
        default:
4138
            goto die;
4139
        }
4140
        break;
4141
    case 5:
4142
        switch (sel) {
4143
        case 0:
4144
            gen_op_mtc0_pagemask();
4145
            rn = "PageMask";
4146
            break;
4147
        case 1:
4148
            check_insn(env, ctx, ISA_MIPS32R2);
4149
            gen_op_mtc0_pagegrain();
4150
            rn = "PageGrain";
4151
            break;
4152
        default:
4153
            goto die;
4154
        }
4155
        break;
4156
    case 6:
4157
        switch (sel) {
4158
        case 0:
4159
            gen_op_mtc0_wired();
4160
            rn = "Wired";
4161
            break;
4162
        case 1:
4163
            check_insn(env, ctx, ISA_MIPS32R2);
4164
            gen_op_mtc0_srsconf0();
4165
            rn = "SRSConf0";
4166
            break;
4167
        case 2:
4168
            check_insn(env, ctx, ISA_MIPS32R2);
4169
            gen_op_mtc0_srsconf1();
4170
            rn = "SRSConf1";
4171
            break;
4172
        case 3:
4173
            check_insn(env, ctx, ISA_MIPS32R2);
4174
            gen_op_mtc0_srsconf2();
4175
            rn = "SRSConf2";
4176
            break;
4177
        case 4:
4178
            check_insn(env, ctx, ISA_MIPS32R2);
4179
            gen_op_mtc0_srsconf3();
4180
            rn = "SRSConf3";
4181
            break;
4182
        case 5:
4183
            check_insn(env, ctx, ISA_MIPS32R2);
4184
            gen_op_mtc0_srsconf4();
4185
            rn = "SRSConf4";
4186
            break;
4187
        default:
4188
            goto die;
4189
        }
4190
        break;
4191
    case 7:
4192
        switch (sel) {
4193
        case 0:
4194
            check_insn(env, ctx, ISA_MIPS32R2);
4195
            gen_op_mtc0_hwrena();
4196
            rn = "HWREna";
4197
            break;
4198
        default:
4199
            goto die;
4200
        }
4201
        break;
4202
    case 8:
4203
        /* ignored */
4204
        rn = "BadVaddr";
4205
        break;
4206
    case 9:
4207
        switch (sel) {
4208
        case 0:
4209
            gen_op_mtc0_count();
4210
            rn = "Count";
4211
            break;
4212
        /* 6,7 are implementation dependent */
4213
        default:
4214
            goto die;
4215
        }
4216
        /* Stop translation as we may have switched the execution mode */
4217
        ctx->bstate = BS_STOP;
4218
        break;
4219
    case 10:
4220
        switch (sel) {
4221
        case 0:
4222
            gen_op_mtc0_entryhi();
4223
            rn = "EntryHi";
4224
            break;
4225
        default:
4226
            goto die;
4227
        }
4228
        break;
4229
    case 11:
4230
        switch (sel) {
4231
        case 0:
4232
            gen_op_mtc0_compare();
4233
            rn = "Compare";
4234
            break;
4235
        /* 6,7 are implementation dependent */
4236
        default:
4237
            goto die;
4238
        }
4239
        /* Stop translation as we may have switched the execution mode */
4240
        ctx->bstate = BS_STOP;
4241
        break;
4242
    case 12:
4243
        switch (sel) {
4244
        case 0:
4245
            gen_op_mtc0_status();
4246
            /* BS_STOP isn't good enough here, hflags may have changed. */
4247
            gen_save_pc(ctx->pc + 4);
4248
            ctx->bstate = BS_EXCP;
4249
            rn = "Status";
4250
            break;
4251
        case 1:
4252
            check_insn(env, ctx, ISA_MIPS32R2);
4253
            gen_op_mtc0_intctl();
4254
            /* Stop translation as we may have switched the execution mode */
4255
            ctx->bstate = BS_STOP;
4256
            rn = "IntCtl";
4257
            break;
4258
        case 2:
4259
            check_insn(env, ctx, ISA_MIPS32R2);
4260
            gen_op_mtc0_srsctl();
4261
            /* Stop translation as we may have switched the execution mode */
4262
            ctx->bstate = BS_STOP;
4263
            rn = "SRSCtl";
4264
            break;
4265
        case 3:
4266
            check_insn(env, ctx, ISA_MIPS32R2);
4267
            gen_op_mtc0_srsmap();
4268
            /* Stop translation as we may have switched the execution mode */
4269
            ctx->bstate = BS_STOP;
4270
            rn = "SRSMap";
4271
            break;
4272
        default:
4273
            goto die;
4274
        }
4275
        break;
4276
    case 13:
4277
        switch (sel) {
4278
        case 0:
4279
            gen_op_mtc0_cause();
4280
            rn = "Cause";
4281
            break;
4282
        default:
4283
            goto die;
4284
        }
4285
        /* Stop translation as we may have switched the execution mode */
4286
        ctx->bstate = BS_STOP;
4287
        break;
4288
    case 14:
4289
        switch (sel) {
4290
        case 0:
4291
            gen_op_mtc0_epc();
4292
            rn = "EPC";
4293
            break;
4294
        default:
4295
            goto die;
4296
        }
4297
        break;
4298
    case 15:
4299
        switch (sel) {
4300
        case 0:
4301
            /* ignored */
4302
            rn = "PRid";
4303
            break;
4304
        case 1:
4305
            check_insn(env, ctx, ISA_MIPS32R2);
4306
            gen_op_mtc0_ebase();
4307
            rn = "EBase";
4308
            break;
4309
        default:
4310
            goto die;
4311
        }
4312
        break;
4313
    case 16:
4314
        switch (sel) {
4315
        case 0:
4316
            gen_op_mtc0_config0();
4317
            rn = "Config";
4318
            /* Stop translation as we may have switched the execution mode */
4319
            ctx->bstate = BS_STOP;
4320
            break;
4321
        case 1:
4322
            /* ignored */
4323
            rn = "Config1";
4324
            break;
4325
        case 2:
4326
            gen_op_mtc0_config2();
4327
            rn = "Config2";
4328
            /* Stop translation as we may have switched the execution mode */
4329
            ctx->bstate = BS_STOP;
4330
            break;
4331
        case 3:
4332
            /* ignored */
4333
            rn = "Config3";
4334
            break;
4335
        /* 6,7 are implementation dependent */
4336
        default:
4337
            rn = "Invalid config selector";
4338
            goto die;
4339
        }
4340
        break;
4341
    case 17:
4342
        switch (sel) {
4343
        case 0:
4344
            /* ignored */
4345
            rn = "LLAddr";
4346
            break;
4347
        default:
4348
            goto die;
4349
        }
4350
        break;
4351
    case 18:
4352
        switch (sel) {
4353
        case 0 ... 7:
4354
            gen_op_mtc0_watchlo(sel);
4355
            rn = "WatchLo";
4356
            break;
4357
        default:
4358
            goto die;
4359
        }
4360
        break;
4361
    case 19:
4362
        switch (sel) {
4363
        case 0 ... 7:
4364
            gen_op_mtc0_watchhi(sel);
4365
            rn = "WatchHi";
4366
            break;
4367
        default:
4368
            goto die;
4369
        }
4370
        break;
4371
    case 20:
4372
        switch (sel) {
4373
        case 0:
4374
            check_insn(env, ctx, ISA_MIPS3);
4375
            gen_op_mtc0_xcontext();
4376
            rn = "XContext";
4377
            break;
4378
        default:
4379
            goto die;
4380
        }
4381
        break;
4382
    case 21:
4383
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4384
        switch (sel) {
4385
        case 0:
4386
            gen_op_mtc0_framemask();
4387
            rn = "Framemask";
4388
            break;
4389
        default:
4390
            goto die;
4391
        }
4392
        break;
4393
    case 22:
4394
        /* ignored */
4395
        rn = "Diagnostic"; /* implementation dependent */
4396
        break;
4397
    case 23:
4398
        switch (sel) {
4399
        case 0:
4400
            gen_op_mtc0_debug(); /* EJTAG support */
4401
            /* BS_STOP isn't good enough here, hflags may have changed. */
4402
            gen_save_pc(ctx->pc + 4);
4403
            ctx->bstate = BS_EXCP;
4404
            rn = "Debug";
4405
            break;
4406
        case 1:
4407
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4408
            /* Stop translation as we may have switched the execution mode */
4409
            ctx->bstate = BS_STOP;
4410
            rn = "TraceControl";
4411
//            break;
4412
        case 2:
4413
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4414
            /* Stop translation as we may have switched the execution mode */
4415
            ctx->bstate = BS_STOP;
4416
            rn = "TraceControl2";
4417
//            break;
4418
        case 3:
4419
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4420
            /* Stop translation as we may have switched the execution mode */
4421
            ctx->bstate = BS_STOP;
4422
            rn = "UserTraceData";
4423
//            break;
4424
        case 4:
4425
//            gen_op_mtc0_debug(); /* PDtrace support */
4426
            /* Stop translation as we may have switched the execution mode */
4427
            ctx->bstate = BS_STOP;
4428
            rn = "TraceBPC";
4429
//            break;
4430
        default:
4431
            goto die;
4432
        }
4433
        break;
4434
    case 24:
4435
        switch (sel) {
4436
        case 0:
4437
            gen_op_mtc0_depc(); /* EJTAG support */
4438
            rn = "DEPC";
4439
            break;
4440
        default:
4441
            goto die;
4442
        }
4443
        break;
4444
    case 25:
4445
        switch (sel) {
4446
        case 0:
4447
            gen_op_mtc0_performance0();
4448
            rn = "Performance0";
4449
            break;
4450
        case 1:
4451
//            gen_op_mtc0_performance1();
4452
            rn = "Performance1";
4453
//            break;
4454
        case 2:
4455
//            gen_op_mtc0_performance2();
4456
            rn = "Performance2";
4457
//            break;
4458
        case 3:
4459
//            gen_op_mtc0_performance3();
4460
            rn = "Performance3";
4461
//            break;
4462
        case 4:
4463
//            gen_op_mtc0_performance4();
4464
            rn = "Performance4";
4465
//            break;
4466
        case 5:
4467
//            gen_op_mtc0_performance5();
4468
            rn = "Performance5";
4469
//            break;
4470
        case 6:
4471
//            gen_op_mtc0_performance6();
4472
            rn = "Performance6";
4473
//            break;
4474
        case 7:
4475
//            gen_op_mtc0_performance7();
4476
            rn = "Performance7";
4477
//            break;
4478
        default:
4479
            goto die;
4480
        }
4481
        break;
4482
    case 26:
4483
        /* ignored */
4484
        rn = "ECC";
4485
        break;
4486
    case 27:
4487
        switch (sel) {
4488
        case 0 ... 3:
4489
            /* ignored */
4490
            rn = "CacheErr";
4491
            break;
4492
        default:
4493
            goto die;
4494
        }
4495
        break;
4496
    case 28:
4497
        switch (sel) {
4498
        case 0:
4499
        case 2:
4500
        case 4:
4501
        case 6:
4502
            gen_op_mtc0_taglo();
4503
            rn = "TagLo";
4504
            break;
4505
        case 1:
4506
        case 3:
4507
        case 5:
4508
        case 7:
4509
            gen_op_mtc0_datalo();
4510
            rn = "DataLo";
4511
            break;
4512
        default:
4513
            goto die;
4514
        }
4515
        break;
4516
    case 29:
4517
        switch (sel) {
4518
        case 0:
4519
        case 2:
4520
        case 4:
4521
        case 6:
4522
            gen_op_mtc0_taghi();
4523
            rn = "TagHi";
4524
            break;
4525
        case 1:
4526
        case 3:
4527
        case 5:
4528
        case 7:
4529
            gen_op_mtc0_datahi();
4530
            rn = "DataHi";
4531
            break;
4532
        default:
4533
            rn = "invalid sel";
4534
            goto die;
4535
        }
4536
        break;
4537
    case 30:
4538
        switch (sel) {
4539
        case 0:
4540
            gen_op_mtc0_errorepc();
4541
            rn = "ErrorEPC";
4542
            break;
4543
        default:
4544
            goto die;
4545
        }
4546
        break;
4547
    case 31:
4548
        switch (sel) {
4549
        case 0:
4550
            gen_op_mtc0_desave(); /* EJTAG support */
4551
            rn = "DESAVE";
4552
            break;
4553
        default:
4554
            goto die;
4555
        }
4556
        /* Stop translation as we may have switched the execution mode */
4557
        ctx->bstate = BS_STOP;
4558
        break;
4559
    default:
4560
        goto die;
4561
    }
4562
#if defined MIPS_DEBUG_DISAS
4563
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4564
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4565
                rn, reg, sel);
4566
    }
4567
#endif
4568
    return;
4569

    
4570
die:
4571
#if defined MIPS_DEBUG_DISAS
4572
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4573
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4574
                rn, reg, sel);
4575
    }
4576
#endif
4577
    generate_exception(ctx, EXCP_RI);
4578
}
4579
#endif /* TARGET_MIPS64 */
4580

    
4581
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4582
                     int u, int sel, int h)
4583
{
4584
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4585

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

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

    
4745
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4746
                     int u, int sel, int h)
4747
{
4748
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4749

    
4750
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4751
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4752
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4753
        /* NOP */ ;
4754
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4755
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4756
        /* NOP */ ;
4757
    else if (u == 0) {
4758
        switch (rd) {
4759
        case 2:
4760
            switch (sel) {
4761
            case 1:
4762
                gen_op_mttc0_tcstatus();
4763
                break;
4764
            case 2:
4765
                gen_op_mttc0_tcbind();
4766
                break;
4767
            case 3:
4768
                gen_op_mttc0_tcrestart();
4769
                break;
4770
            case 4:
4771
                gen_op_mttc0_tchalt();
4772
                break;
4773
            case 5:
4774
                gen_op_mttc0_tccontext();
4775
                break;
4776
            case 6:
4777
                gen_op_mttc0_tcschedule();
4778
                break;
4779
            case 7:
4780
                gen_op_mttc0_tcschefback();
4781
                break;
4782
            default:
4783
                gen_mtc0(env, ctx, rd, sel);
4784
                break;
4785
            }
4786
            break;
4787
        case 10:
4788
            switch (sel) {
4789
            case 0:
4790
                gen_op_mttc0_entryhi();
4791
                break;
4792
            default:
4793
                gen_mtc0(env, ctx, rd, sel);
4794
                break;
4795
            }
4796
        case 12:
4797
            switch (sel) {
4798
            case 0:
4799
                gen_op_mttc0_status();
4800
                break;
4801
            default:
4802
                gen_mtc0(env, ctx, rd, sel);
4803
                break;
4804
            }
4805
        case 23:
4806
            switch (sel) {
4807
            case 0:
4808
                gen_op_mttc0_debug();
4809
                break;
4810
            default:
4811
                gen_mtc0(env, ctx, rd, sel);
4812
                break;
4813
            }
4814
            break;
4815
        default:
4816
            gen_mtc0(env, ctx, rd, sel);
4817
        }
4818
    } else switch (sel) {
4819
    /* GPR registers. */
4820
    case 0:
4821
        gen_op_mttgpr(rd);
4822
        break;
4823
    /* Auxiliary CPU registers */
4824
    case 1:
4825
        switch (rd) {
4826
        case 0:
4827
            gen_op_mttlo(0);
4828
            break;
4829
        case 1:
4830
            gen_op_mtthi(0);
4831
            break;
4832
        case 2:
4833
            gen_op_mttacx(0);
4834
            break;
4835
        case 4:
4836
            gen_op_mttlo(1);
4837
            break;
4838
        case 5:
4839
            gen_op_mtthi(1);
4840
            break;
4841
        case 6:
4842
            gen_op_mttacx(1);
4843
            break;
4844
        case 8:
4845
            gen_op_mttlo(2);
4846
            break;
4847
        case 9:
4848
            gen_op_mtthi(2);
4849
            break;
4850
        case 10:
4851
            gen_op_mttacx(2);
4852
            break;
4853
        case 12:
4854
            gen_op_mttlo(3);
4855
            break;
4856
        case 13:
4857
            gen_op_mtthi(3);
4858
            break;
4859
        case 14:
4860
            gen_op_mttacx(3);
4861
            break;
4862
        case 16:
4863
            gen_op_mttdsp();
4864
            break;
4865
        default:
4866
            goto die;
4867
        }
4868
        break;
4869
    /* Floating point (COP1). */
4870
    case 2:
4871
        /* XXX: For now we support only a single FPU context. */
4872
        if (h == 0) {
4873
            gen_op_mtc1();
4874
            GEN_STORE_FTN_FREG(rd, WT0);
4875
        } else {
4876
            gen_op_mthc1();
4877
            GEN_STORE_FTN_FREG(rd, WTH0);
4878
        }
4879
        break;
4880
    case 3:
4881
        /* XXX: For now we support only a single FPU context. */
4882
        gen_op_ctc1(rd);
4883
        break;
4884
    /* COP2: Not implemented. */
4885
    case 4:
4886
    case 5:
4887
        /* fall through */
4888
    default:
4889
        goto die;
4890
    }
4891
#if defined MIPS_DEBUG_DISAS
4892
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4893
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4894
                rd, u, sel, h);
4895
    }
4896
#endif
4897
    return;
4898

    
4899
die:
4900
#if defined MIPS_DEBUG_DISAS
4901
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4902
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4903
                rd, u, sel, h);
4904
    }
4905
#endif
4906
    generate_exception(ctx, EXCP_RI);
4907
}
4908

    
4909
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4910
{
4911
    const char *opn = "ldst";
4912

    
4913
    switch (opc) {
4914
    case OPC_MFC0:
4915
        if (rt == 0) {
4916
            /* Treat as NOP. */
4917
            return;
4918
        }
4919
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4920
        gen_op_store_gpr_T0(rt);
4921
        opn = "mfc0";
4922
        break;
4923
    case OPC_MTC0:
4924
        GEN_LOAD_REG_T0(rt);
4925
        save_cpu_state(ctx, 1);
4926
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4927
        opn = "mtc0";
4928
        break;
4929
#if defined(TARGET_MIPS64)
4930
    case OPC_DMFC0:
4931
        check_insn(env, ctx, ISA_MIPS3);
4932
        if (rt == 0) {
4933
            /* Treat as NOP. */
4934
            return;
4935
        }
4936
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4937
        gen_op_store_gpr_T0(rt);
4938
        opn = "dmfc0";
4939
        break;
4940
    case OPC_DMTC0:
4941
        check_insn(env, ctx, ISA_MIPS3);
4942
        GEN_LOAD_REG_T0(rt);
4943
        save_cpu_state(ctx, 1);
4944
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4945
        opn = "dmtc0";
4946
        break;
4947
#endif
4948
    case OPC_MFTR:
4949
        check_insn(env, ctx, ASE_MT);
4950
        if (rd == 0) {
4951
            /* Treat as NOP. */
4952
            return;
4953
        }
4954
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4955
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4956
        gen_op_store_gpr_T0(rd);
4957
        opn = "mftr";
4958
        break;
4959
    case OPC_MTTR:
4960
        check_insn(env, ctx, ASE_MT);
4961
        GEN_LOAD_REG_T0(rt);
4962
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4963
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4964
        opn = "mttr";
4965
        break;
4966
    case OPC_TLBWI:
4967
        opn = "tlbwi";
4968
        if (!env->tlb->do_tlbwi)
4969
            goto die;
4970
        gen_op_tlbwi();
4971
        break;
4972
    case OPC_TLBWR:
4973
        opn = "tlbwr";
4974
        if (!env->tlb->do_tlbwr)
4975
            goto die;
4976
        gen_op_tlbwr();
4977
        break;
4978
    case OPC_TLBP:
4979
        opn = "tlbp";
4980
        if (!env->tlb->do_tlbp)
4981
            goto die;
4982
        gen_op_tlbp();
4983
        break;
4984
    case OPC_TLBR:
4985
        opn = "tlbr";
4986
        if (!env->tlb->do_tlbr)
4987
            goto die;
4988
        gen_op_tlbr();
4989
        break;
4990
    case OPC_ERET:
4991
        opn = "eret";
4992
        check_insn(env, ctx, ISA_MIPS2);
4993
        save_cpu_state(ctx, 1);
4994
        gen_op_eret();
4995
        ctx->bstate = BS_EXCP;
4996
        break;
4997
    case OPC_DERET:
4998
        opn = "deret";
4999
        check_insn(env, ctx, ISA_MIPS32);
5000
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5001
            MIPS_INVAL(opn);
5002
            generate_exception(ctx, EXCP_RI);
5003
        } else {
5004
            save_cpu_state(ctx, 1);
5005
            gen_op_deret();
5006
            ctx->bstate = BS_EXCP;
5007
        }
5008
        break;
5009
    case OPC_WAIT:
5010
        opn = "wait";
5011
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5012
        /* If we get an exception, we want to restart at next instruction */
5013
        ctx->pc += 4;
5014
        save_cpu_state(ctx, 1);
5015
        ctx->pc -= 4;
5016
        gen_op_wait();
5017
        ctx->bstate = BS_EXCP;
5018
        break;
5019
    default:
5020
 die:
5021
        MIPS_INVAL(opn);
5022
        generate_exception(ctx, EXCP_RI);
5023
        return;
5024
    }
5025
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5026
}
5027

    
5028
/* CP1 Branches (before delay slot) */
5029
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5030
                                 int32_t cc, int32_t offset)
5031
{
5032
    target_ulong btarget;
5033
    const char *opn = "cp1 cond branch";
5034

    
5035
    if (cc != 0)
5036
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5037

    
5038
    btarget = ctx->pc + 4 + offset;
5039

    
5040
    switch (op) {
5041
    case OPC_BC1F:
5042
        gen_op_bc1f(cc);
5043
        opn = "bc1f";
5044
        goto not_likely;
5045
    case OPC_BC1FL:
5046
        gen_op_bc1f(cc);
5047
        opn = "bc1fl";
5048
        goto likely;
5049
    case OPC_BC1T:
5050
        gen_op_bc1t(cc);
5051
        opn = "bc1t";
5052
        goto not_likely;
5053
    case OPC_BC1TL:
5054
        gen_op_bc1t(cc);
5055
        opn = "bc1tl";
5056
    likely:
5057
        ctx->hflags |= MIPS_HFLAG_BL;
5058
        tcg_gen_set_bcond();
5059
        break;
5060
    case OPC_BC1FANY2:
5061
        gen_op_bc1any2f(cc);
5062
        opn = "bc1any2f";
5063
        goto not_likely;
5064
    case OPC_BC1TANY2:
5065
        gen_op_bc1any2t(cc);
5066
        opn = "bc1any2t";
5067
        goto not_likely;
5068
    case OPC_BC1FANY4:
5069
        gen_op_bc1any4f(cc);
5070
        opn = "bc1any4f";
5071
        goto not_likely;
5072
    case OPC_BC1TANY4:
5073
        gen_op_bc1any4t(cc);
5074
        opn = "bc1any4t";
5075
    not_likely:
5076
        ctx->hflags |= MIPS_HFLAG_BC;
5077
        tcg_gen_set_bcond();
5078
        break;
5079
    default:
5080
        MIPS_INVAL(opn);
5081
        generate_exception (ctx, EXCP_RI);
5082
        return;
5083
    }
5084
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5085
               ctx->hflags, btarget);
5086
    ctx->btarget = btarget;
5087
}
5088

    
5089
/* Coprocessor 1 (FPU) */
5090

    
5091
#define FOP(func, fmt) (((fmt) << 21) | (func))
5092

    
5093
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5094
{
5095
    const char *opn = "cp1 move";
5096

    
5097
    switch (opc) {
5098
    case OPC_MFC1:
5099
        GEN_LOAD_FREG_FTN(WT0, fs);
5100
        gen_op_mfc1();
5101
        GEN_STORE_T0_REG(rt);
5102
        opn = "mfc1";
5103
        break;
5104
    case OPC_MTC1:
5105
        GEN_LOAD_REG_T0(rt);
5106
        gen_op_mtc1();
5107
        GEN_STORE_FTN_FREG(fs, WT0);
5108
        opn = "mtc1";
5109
        break;
5110
    case OPC_CFC1:
5111
        gen_op_cfc1(fs);
5112
        GEN_STORE_T0_REG(rt);
5113
        opn = "cfc1";
5114
        break;
5115
    case OPC_CTC1:
5116
        GEN_LOAD_REG_T0(rt);
5117
        gen_op_ctc1(fs);
5118
        opn = "ctc1";
5119
        break;
5120
    case OPC_DMFC1:
5121
        GEN_LOAD_FREG_FTN(DT0, fs);
5122
        gen_op_dmfc1();
5123
        GEN_STORE_T0_REG(rt);
5124
        opn = "dmfc1";
5125
        break;
5126
    case OPC_DMTC1:
5127
        GEN_LOAD_REG_T0(rt);
5128
        gen_op_dmtc1();
5129
        GEN_STORE_FTN_FREG(fs, DT0);
5130
        opn = "dmtc1";
5131
        break;
5132
    case OPC_MFHC1:
5133
        GEN_LOAD_FREG_FTN(WTH0, fs);
5134
        gen_op_mfhc1();
5135
        GEN_STORE_T0_REG(rt);
5136
        opn = "mfhc1";
5137
        break;
5138
    case OPC_MTHC1:
5139
        GEN_LOAD_REG_T0(rt);
5140
        gen_op_mthc1();
5141
        GEN_STORE_FTN_FREG(fs, WTH0);
5142
        opn = "mthc1";
5143
        break;
5144
    default:
5145
        MIPS_INVAL(opn);
5146
        generate_exception (ctx, EXCP_RI);
5147
        return;
5148
    }
5149
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5150
}
5151

    
5152
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5153
{
5154
    uint32_t ccbit;
5155

    
5156
    GEN_LOAD_REG_T0(rd);
5157
    GEN_LOAD_REG_T1(rs);
5158
    if (cc) {
5159
        ccbit = 1 << (24 + cc);
5160
    } else
5161
        ccbit = 1 << 23;
5162
    if (!tf)
5163
        gen_op_movf(ccbit);
5164
    else
5165
        gen_op_movt(ccbit);
5166
    GEN_STORE_T0_REG(rd);
5167
}
5168

    
5169
#define GEN_MOVCF(fmt)                                                \
5170
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5171
{                                                                     \
5172
    uint32_t ccbit;                                                   \
5173
                                                                      \
5174
    if (cc) {                                                         \
5175
        ccbit = 1 << (24 + cc);                                       \
5176
    } else                                                            \
5177
        ccbit = 1 << 23;                                              \
5178
    if (!tf)                                                          \
5179
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5180
    else                                                              \
5181
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5182
}
5183
GEN_MOVCF(d);
5184
GEN_MOVCF(s);
5185
GEN_MOVCF(ps);
5186
#undef GEN_MOVCF
5187

    
5188
static void gen_farith (DisasContext *ctx, uint32_t op1,
5189
                        int ft, int fs, int fd, int cc)
5190
{
5191
    const char *opn = "farith";
5192
    const char *condnames[] = {
5193
            "c.f",
5194
            "c.un",
5195
            "c.eq",
5196
            "c.ueq",
5197
            "c.olt",
5198
            "c.ult",
5199
            "c.ole",
5200
            "c.ule",
5201
            "c.sf",
5202
            "c.ngle",
5203
            "c.seq",
5204
            "c.ngl",
5205
            "c.lt",
5206
            "c.nge",
5207
            "c.le",
5208
            "c.ngt",
5209
    };
5210
    const char *condnames_abs[] = {
5211
            "cabs.f",
5212
            "cabs.un",
5213
            "cabs.eq",
5214
            "cabs.ueq",
5215
            "cabs.olt",
5216
            "cabs.ult",
5217
            "cabs.ole",
5218
            "cabs.ule",
5219
            "cabs.sf",
5220
            "cabs.ngle",
5221
            "cabs.seq",
5222
            "cabs.ngl",
5223
            "cabs.lt",
5224
            "cabs.nge",
5225
            "cabs.le",
5226
            "cabs.ngt",
5227
    };
5228
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5229
    uint32_t func = ctx->opcode & 0x3f;
5230

    
5231
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5232
    case FOP(0, 16):
5233
        GEN_LOAD_FREG_FTN(WT0, fs);
5234
        GEN_LOAD_FREG_FTN(WT1, ft);
5235
        gen_op_float_add_s();
5236
        GEN_STORE_FTN_FREG(fd, WT2);
5237
        opn = "add.s";
5238
        optype = BINOP;
5239
        break;
5240
    case FOP(1, 16):
5241
        GEN_LOAD_FREG_FTN(WT0, fs);
5242
        GEN_LOAD_FREG_FTN(WT1, ft);
5243
        gen_op_float_sub_s();
5244
        GEN_STORE_FTN_FREG(fd, WT2);
5245
        opn = "sub.s";
5246
        optype = BINOP;
5247
        break;
5248
    case FOP(2, 16):
5249
        GEN_LOAD_FREG_FTN(WT0, fs);
5250
        GEN_LOAD_FREG_FTN(WT1, ft);
5251
        gen_op_float_mul_s();
5252
        GEN_STORE_FTN_FREG(fd, WT2);
5253
        opn = "mul.s";
5254
        optype = BINOP;
5255
        break;
5256
    case FOP(3, 16):
5257
        GEN_LOAD_FREG_FTN(WT0, fs);
5258
        GEN_LOAD_FREG_FTN(WT1, ft);
5259
        gen_op_float_div_s();
5260
        GEN_STORE_FTN_FREG(fd, WT2);
5261
        opn = "div.s";
5262
        optype = BINOP;
5263
        break;
5264
    case FOP(4, 16):
5265
        GEN_LOAD_FREG_FTN(WT0, fs);
5266
        gen_op_float_sqrt_s();
5267
        GEN_STORE_FTN_FREG(fd, WT2);
5268
        opn = "sqrt.s";
5269
        break;
5270
    case FOP(5, 16):
5271
        GEN_LOAD_FREG_FTN(WT0, fs);
5272
        gen_op_float_abs_s();
5273
        GEN_STORE_FTN_FREG(fd, WT2);
5274
        opn = "abs.s";
5275
        break;
5276
    case FOP(6, 16):
5277
        GEN_LOAD_FREG_FTN(WT0, fs);
5278
        gen_op_float_mov_s();
5279
        GEN_STORE_FTN_FREG(fd, WT2);
5280
        opn = "mov.s";
5281
        break;
5282
    case FOP(7, 16):
5283
        GEN_LOAD_FREG_FTN(WT0, fs);
5284
        gen_op_float_chs_s();
5285
        GEN_STORE_FTN_FREG(fd, WT2);
5286
        opn = "neg.s";
5287
        break;
5288
    case FOP(8, 16):
5289
        check_cp1_64bitmode(ctx);
5290
        GEN_LOAD_FREG_FTN(WT0, fs);
5291
        gen_op_float_roundl_s();
5292
        GEN_STORE_FTN_FREG(fd, DT2);
5293
        opn = "round.l.s";
5294
        break;
5295
    case FOP(9, 16):
5296
        check_cp1_64bitmode(ctx);
5297
        GEN_LOAD_FREG_FTN(WT0, fs);
5298
        gen_op_float_truncl_s();
5299
        GEN_STORE_FTN_FREG(fd, DT2);
5300
        opn = "trunc.l.s";
5301
        break;
5302
    case FOP(10, 16):
5303
        check_cp1_64bitmode(ctx);
5304
        GEN_LOAD_FREG_FTN(WT0, fs);
5305
        gen_op_float_ceill_s();
5306
        GEN_STORE_FTN_FREG(fd, DT2);
5307
        opn = "ceil.l.s";
5308
        break;
5309
    case FOP(11, 16):
5310
        check_cp1_64bitmode(ctx);
5311
        GEN_LOAD_FREG_FTN(WT0, fs);
5312
        gen_op_float_floorl_s();
5313
        GEN_STORE_FTN_FREG(fd, DT2);
5314
        opn = "floor.l.s";
5315
        break;
5316
    case FOP(12, 16):
5317
        GEN_LOAD_FREG_FTN(WT0, fs);
5318
        gen_op_float_roundw_s();
5319
        GEN_STORE_FTN_FREG(fd, WT2);
5320
        opn = "round.w.s";
5321
        break;
5322
    case FOP(13, 16):
5323
        GEN_LOAD_FREG_FTN(WT0, fs);
5324
        gen_op_float_truncw_s();
5325
        GEN_STORE_FTN_FREG(fd, WT2);
5326
        opn = "trunc.w.s";
5327
        break;
5328
    case FOP(14, 16):
5329
        GEN_LOAD_FREG_FTN(WT0, fs);
5330
        gen_op_float_ceilw_s();
5331
        GEN_STORE_FTN_FREG(fd, WT2);
5332
        opn = "ceil.w.s";
5333
        break;
5334
    case FOP(15, 16):
5335
        GEN_LOAD_FREG_FTN(WT0, fs);
5336
        gen_op_float_floorw_s();
5337
        GEN_STORE_FTN_FREG(fd, WT2);
5338
        opn = "floor.w.s";
5339
        break;
5340
    case FOP(17, 16):
5341
        GEN_LOAD_REG_T0(ft);
5342
        GEN_LOAD_FREG_FTN(WT0, fs);
5343
        GEN_LOAD_FREG_FTN(WT2, fd);
5344
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5345
        GEN_STORE_FTN_FREG(fd, WT2);
5346
        opn = "movcf.s";
5347
        break;
5348
    case FOP(18, 16):
5349
        GEN_LOAD_REG_T0(ft);
5350
        GEN_LOAD_FREG_FTN(WT0, fs);
5351
        GEN_LOAD_FREG_FTN(WT2, fd);
5352
        gen_op_float_movz_s();
5353
        GEN_STORE_FTN_FREG(fd, WT2);
5354
        opn = "movz.s";
5355
        break;
5356
    case FOP(19, 16):
5357
        GEN_LOAD_REG_T0(ft);
5358
        GEN_LOAD_FREG_FTN(WT0, fs);
5359
        GEN_LOAD_FREG_FTN(WT2, fd);
5360
        gen_op_float_movn_s();
5361
        GEN_STORE_FTN_FREG(fd, WT2);
5362
        opn = "movn.s";
5363
        break;
5364
    case FOP(21, 16):
5365
        check_cop1x(ctx);
5366
        GEN_LOAD_FREG_FTN(WT0, fs);
5367
        gen_op_float_recip_s();
5368
        GEN_STORE_FTN_FREG(fd, WT2);
5369
        opn = "recip.s";
5370
        break;
5371
    case FOP(22, 16):
5372
        check_cop1x(ctx);
5373
        GEN_LOAD_FREG_FTN(WT0, fs);
5374
        gen_op_float_rsqrt_s();
5375
        GEN_STORE_FTN_FREG(fd, WT2);
5376
        opn = "rsqrt.s";
5377
        break;
5378
    case FOP(28, 16):
5379
        check_cp1_64bitmode(ctx);
5380
        GEN_LOAD_FREG_FTN(WT0, fs);
5381
        GEN_LOAD_FREG_FTN(WT2, fd);
5382
        gen_op_float_recip2_s();
5383
        GEN_STORE_FTN_FREG(fd, WT2);
5384
        opn = "recip2.s";
5385
        break;
5386
    case FOP(29, 16):
5387
        check_cp1_64bitmode(ctx);
5388
        GEN_LOAD_FREG_FTN(WT0, fs);
5389
        gen_op_float_recip1_s();
5390
        GEN_STORE_FTN_FREG(fd, WT2);
5391
        opn = "recip1.s";
5392
        break;
5393
    case FOP(30, 16):
5394
        check_cp1_64bitmode(ctx);
5395
        GEN_LOAD_FREG_FTN(WT0, fs);
5396
        gen_op_float_rsqrt1_s();
5397
        GEN_STORE_FTN_FREG(fd, WT2);
5398
        opn = "rsqrt1.s";
5399
        break;
5400
    case FOP(31, 16):
5401
        check_cp1_64bitmode(ctx);
5402
        GEN_LOAD_FREG_FTN(WT0, fs);
5403
        GEN_LOAD_FREG_FTN(WT2, ft);
5404
        gen_op_float_rsqrt2_s();
5405
        GEN_STORE_FTN_FREG(fd, WT2);
5406
        opn = "rsqrt2.s";
5407
        break;
5408
    case FOP(33, 16):
5409
        check_cp1_registers(ctx, fd);
5410
        GEN_LOAD_FREG_FTN(WT0, fs);
5411
        gen_op_float_cvtd_s();
5412
        GEN_STORE_FTN_FREG(fd, DT2);
5413
        opn = "cvt.d.s";
5414
        break;
5415
    case FOP(36, 16):
5416
        GEN_LOAD_FREG_FTN(WT0, fs);
5417
        gen_op_float_cvtw_s();
5418
        GEN_STORE_FTN_FREG(fd, WT2);
5419
        opn = "cvt.w.s";
5420
        break;
5421
    case FOP(37, 16):
5422
        check_cp1_64bitmode(ctx);
5423
        GEN_LOAD_FREG_FTN(WT0, fs);
5424
        gen_op_float_cvtl_s();
5425
        GEN_STORE_FTN_FREG(fd, DT2);
5426
        opn = "cvt.l.s";
5427
        break;
5428
    case FOP(38, 16):
5429
        check_cp1_64bitmode(ctx);
5430
        GEN_LOAD_FREG_FTN(WT1, fs);
5431
        GEN_LOAD_FREG_FTN(WT0, ft);
5432
        gen_op_float_cvtps_s();
5433
        GEN_STORE_FTN_FREG(fd, DT2);
5434
        opn = "cvt.ps.s";
5435
        break;
5436
    case FOP(48, 16):
5437
    case FOP(49, 16):
5438
    case FOP(50, 16):
5439
    case FOP(51, 16):
5440
    case FOP(52, 16):
5441
    case FOP(53, 16):
5442
    case FOP(54, 16):
5443
    case FOP(55, 16):
5444
    case FOP(56, 16):
5445
    case FOP(57, 16):
5446
    case FOP(58, 16):
5447
    case FOP(59, 16):
5448
    case FOP(60, 16):
5449
    case FOP(61, 16):
5450
    case FOP(62, 16):
5451
    case FOP(63, 16):
5452
        GEN_LOAD_FREG_FTN(WT0, fs);
5453
        GEN_LOAD_FREG_FTN(WT1, ft);
5454
        if (ctx->opcode & (1 << 6)) {
5455
            check_cop1x(ctx);
5456
            gen_cmpabs_s(func-48, cc);
5457
            opn = condnames_abs[func-48];
5458
        } else {
5459
            gen_cmp_s(func-48, cc);
5460
            opn = condnames[func-48];
5461
        }
5462
        break;
5463
    case FOP(0, 17):
5464
        check_cp1_registers(ctx, fs | ft | fd);
5465
        GEN_LOAD_FREG_FTN(DT0, fs);
5466
        GEN_LOAD_FREG_FTN(DT1, ft);
5467
        gen_op_float_add_d();
5468
        GEN_STORE_FTN_FREG(fd, DT2);
5469
        opn = "add.d";
5470
        optype = BINOP;
5471
        break;
5472
    case FOP(1, 17):
5473
        check_cp1_registers(ctx, fs | ft | fd);
5474
        GEN_LOAD_FREG_FTN(DT0, fs);
5475
        GEN_LOAD_FREG_FTN(DT1, ft);
5476
        gen_op_float_sub_d();
5477
        GEN_STORE_FTN_FREG(fd, DT2);
5478
        opn = "sub.d";
5479
        optype = BINOP;
5480
        break;
5481
    case FOP(2, 17):
5482
        check_cp1_registers(ctx, fs | ft | fd);
5483
        GEN_LOAD_FREG_FTN(DT0, fs);
5484
        GEN_LOAD_FREG_FTN(DT1, ft);
5485
        gen_op_float_mul_d();
5486
        GEN_STORE_FTN_FREG(fd, DT2);
5487
        opn = "mul.d";
5488
        optype = BINOP;
5489
        break;
5490
    case FOP(3, 17):
5491
        check_cp1_registers(ctx, fs | ft | fd);
5492
        GEN_LOAD_FREG_FTN(DT0, fs);
5493
        GEN_LOAD_FREG_FTN(DT1, ft);
5494
        gen_op_float_div_d();
5495
        GEN_STORE_FTN_FREG(fd, DT2);
5496
        opn = "div.d";
5497
        optype = BINOP;
5498
        break;
5499
    case FOP(4, 17):
5500
        check_cp1_registers(ctx, fs | fd);
5501
        GEN_LOAD_FREG_FTN(DT0, fs);
5502
        gen_op_float_sqrt_d();
5503
        GEN_STORE_FTN_FREG(fd, DT2);
5504
        opn = "sqrt.d";
5505
        break;
5506
    case FOP(5, 17):
5507
        check_cp1_registers(ctx, fs | fd);
5508
        GEN_LOAD_FREG_FTN(DT0, fs);
5509
        gen_op_float_abs_d();
5510
        GEN_STORE_FTN_FREG(fd, DT2);
5511
        opn = "abs.d";
5512
        break;
5513
    case FOP(6, 17):
5514
        check_cp1_registers(ctx, fs | fd);
5515
        GEN_LOAD_FREG_FTN(DT0, fs);
5516
        gen_op_float_mov_d();
5517
        GEN_STORE_FTN_FREG(fd, DT2);
5518
        opn = "mov.d";
5519
        break;
5520
    case FOP(7, 17):
5521
        check_cp1_registers(ctx, fs | fd);
5522
        GEN_LOAD_FREG_FTN(DT0, fs);
5523
        gen_op_float_chs_d();
5524
        GEN_STORE_FTN_FREG(fd, DT2);
5525
        opn = "neg.d";
5526
        break;
5527
    case FOP(8, 17):
5528
        check_cp1_64bitmode(ctx);
5529
        GEN_LOAD_FREG_FTN(DT0, fs);
5530
        gen_op_float_roundl_d();
5531
        GEN_STORE_FTN_FREG(fd, DT2);
5532
        opn = "round.l.d";
5533
        break;
5534
    case FOP(9, 17):
5535
        check_cp1_64bitmode(ctx);
5536
        GEN_LOAD_FREG_FTN(DT0, fs);
5537
        gen_op_float_truncl_d();
5538
        GEN_STORE_FTN_FREG(fd, DT2);
5539
        opn = "trunc.l.d";
5540
        break;
5541
    case FOP(10, 17):
5542
        check_cp1_64bitmode(ctx);
5543
        GEN_LOAD_FREG_FTN(DT0, fs);
5544
        gen_op_float_ceill_d();
5545
        GEN_STORE_FTN_FREG(fd, DT2);
5546
        opn = "ceil.l.d";
5547
        break;
5548
    case FOP(11, 17):
5549
        check_cp1_64bitmode(ctx);
5550
        GEN_LOAD_FREG_FTN(DT0, fs);
5551
        gen_op_float_floorl_d();
5552
        GEN_STORE_FTN_FREG(fd, DT2);
5553
        opn = "floor.l.d";
5554
        break;
5555
    case FOP(12, 17):
5556
        check_cp1_registers(ctx, fs);
5557
        GEN_LOAD_FREG_FTN(DT0, fs);
5558
        gen_op_float_roundw_d();
5559
        GEN_STORE_FTN_FREG(fd, WT2);
5560
        opn = "round.w.d";
5561
        break;
5562
    case FOP(13, 17):
5563
        check_cp1_registers(ctx, fs);
5564
        GEN_LOAD_FREG_FTN(DT0, fs);
5565
        gen_op_float_truncw_d();
5566
        GEN_STORE_FTN_FREG(fd, WT2);
5567
        opn = "trunc.w.d";
5568
        break;
5569
    case FOP(14, 17):
5570
        check_cp1_registers(ctx, fs);
5571
        GEN_LOAD_FREG_FTN(DT0, fs);
5572
        gen_op_float_ceilw_d();
5573
        GEN_STORE_FTN_FREG(fd, WT2);
5574
        opn = "ceil.w.d";
5575
        break;
5576
    case FOP(15, 17):
5577
        check_cp1_registers(ctx, fs);
5578
        GEN_LOAD_FREG_FTN(DT0, fs);
5579
        gen_op_float_floorw_d();
5580
        GEN_STORE_FTN_FREG(fd, WT2);
5581
        opn = "floor.w.d";
5582
        break;
5583
    case FOP(17, 17):
5584
        GEN_LOAD_REG_T0(ft);
5585
        GEN_LOAD_FREG_FTN(DT0, fs);
5586
        GEN_LOAD_FREG_FTN(DT2, fd);
5587
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5588
        GEN_STORE_FTN_FREG(fd, DT2);
5589
        opn = "movcf.d";
5590
        break;
5591
    case FOP(18, 17):
5592
        GEN_LOAD_REG_T0(ft);
5593
        GEN_LOAD_FREG_FTN(DT0, fs);
5594
        GEN_LOAD_FREG_FTN(DT2, fd);
5595
        gen_op_float_movz_d();
5596
        GEN_STORE_FTN_FREG(fd, DT2);
5597
        opn = "movz.d";
5598
        break;
5599
    case FOP(19, 17):
5600
        GEN_LOAD_REG_T0(ft);
5601
        GEN_LOAD_FREG_FTN(DT0, fs);
5602
        GEN_LOAD_FREG_FTN(DT2, fd);
5603
        gen_op_float_movn_d();
5604
        GEN_STORE_FTN_FREG(fd, DT2);
5605
        opn = "movn.d";
5606
        break;
5607
    case FOP(21, 17):
5608
        check_cp1_64bitmode(ctx);
5609
        GEN_LOAD_FREG_FTN(DT0, fs);
5610
        gen_op_float_recip_d();
5611
        GEN_STORE_FTN_FREG(fd, DT2);
5612
        opn = "recip.d";
5613
        break;
5614
    case FOP(22, 17):
5615
        check_cp1_64bitmode(ctx);
5616
        GEN_LOAD_FREG_FTN(DT0, fs);
5617
        gen_op_float_rsqrt_d();
5618
        GEN_STORE_FTN_FREG(fd, DT2);
5619
        opn = "rsqrt.d";
5620
        break;
5621
    case FOP(28, 17):
5622
        check_cp1_64bitmode(ctx);
5623
        GEN_LOAD_FREG_FTN(DT0, fs);
5624
        GEN_LOAD_FREG_FTN(DT2, ft);
5625
        gen_op_float_recip2_d();
5626
        GEN_STORE_FTN_FREG(fd, DT2);
5627
        opn = "recip2.d";
5628
        break;
5629
    case FOP(29, 17):
5630
        check_cp1_64bitmode(ctx);
5631
        GEN_LOAD_FREG_FTN(DT0, fs);
5632
        gen_op_float_recip1_d();
5633
        GEN_STORE_FTN_FREG(fd, DT2);
5634
        opn = "recip1.d";
5635
        break;
5636
    case FOP(30, 17):
5637
        check_cp1_64bitmode(ctx);
5638
        GEN_LOAD_FREG_FTN(DT0, fs);
5639
        gen_op_float_rsqrt1_d();
5640
        GEN_STORE_FTN_FREG(fd, DT2);
5641
        opn = "rsqrt1.d";
5642
        break;
5643
    case FOP(31, 17):
5644
        check_cp1_64bitmode(ctx);
5645
        GEN_LOAD_FREG_FTN(DT0, fs);
5646
        GEN_LOAD_FREG_FTN(DT2, ft);
5647
        gen_op_float_rsqrt2_d();
5648
        GEN_STORE_FTN_FREG(fd, DT2);
5649
        opn = "rsqrt2.d";
5650
        break;
5651
    case FOP(48, 17):
5652
    case FOP(49, 17):
5653
    case FOP(50, 17):
5654
    case FOP(51, 17):
5655
    case FOP(52, 17):
5656
    case FOP(53, 17):
5657
    case FOP(54, 17):
5658
    case FOP(55, 17):
5659
    case FOP(56, 17):
5660
    case FOP(57, 17):
5661
    case FOP(58, 17):
5662
    case FOP(59, 17):
5663
    case FOP(60, 17):
5664
    case FOP(61, 17):
5665
    case FOP(62, 17):
5666
    case FOP(63, 17):
5667
        GEN_LOAD_FREG_FTN(DT0, fs);
5668
        GEN_LOAD_FREG_FTN(DT1, ft);
5669
        if (ctx->opcode & (1 << 6)) {
5670
            check_cop1x(ctx);
5671
            check_cp1_registers(ctx, fs | ft);
5672
            gen_cmpabs_d(func-48, cc);
5673
            opn = condnames_abs[func-48];
5674
        } else {
5675
            check_cp1_registers(ctx, fs | ft);
5676
            gen_cmp_d(func-48, cc);
5677
            opn = condnames[func-48];
5678
        }
5679
        break;
5680
    case FOP(32, 17):
5681
        check_cp1_registers(ctx, fs);
5682
        GEN_LOAD_FREG_FTN(DT0, fs);
5683
        gen_op_float_cvts_d();
5684
        GEN_STORE_FTN_FREG(fd, WT2);
5685
        opn = "cvt.s.d";
5686
        break;
5687
    case FOP(36, 17):
5688
        check_cp1_registers(ctx, fs);
5689
        GEN_LOAD_FREG_FTN(DT0, fs);
5690
        gen_op_float_cvtw_d();
5691
        GEN_STORE_FTN_FREG(fd, WT2);
5692
        opn = "cvt.w.d";
5693
        break;
5694
    case FOP(37, 17):
5695
        check_cp1_64bitmode(ctx);
5696
        GEN_LOAD_FREG_FTN(DT0, fs);
5697
        gen_op_float_cvtl_d();
5698
        GEN_STORE_FTN_FREG(fd, DT2);
5699
        opn = "cvt.l.d";
5700
        break;
5701
    case FOP(32, 20):
5702
        GEN_LOAD_FREG_FTN(WT0, fs);
5703
        gen_op_float_cvts_w();
5704
        GEN_STORE_FTN_FREG(fd, WT2);
5705
        opn = "cvt.s.w";
5706
        break;
5707
    case FOP(33, 20):
5708
        check_cp1_registers(ctx, fd);
5709
        GEN_LOAD_FREG_FTN(WT0, fs);
5710
        gen_op_float_cvtd_w();
5711
        GEN_STORE_FTN_FREG(fd, DT2);
5712
        opn = "cvt.d.w";
5713
        break;
5714
    case FOP(32, 21):
5715
        check_cp1_64bitmode(ctx);
5716
        GEN_LOAD_FREG_FTN(DT0, fs);
5717
        gen_op_float_cvts_l();
5718
        GEN_STORE_FTN_FREG(fd, WT2);
5719
        opn = "cvt.s.l";
5720
        break;
5721
    case FOP(33, 21):
5722
        check_cp1_64bitmode(ctx);
5723
        GEN_LOAD_FREG_FTN(DT0, fs);
5724
        gen_op_float_cvtd_l();
5725
        GEN_STORE_FTN_FREG(fd, DT2);
5726
        opn = "cvt.d.l";
5727
        break;
5728
    case FOP(38, 20):
5729
        check_cp1_64bitmode(ctx);
5730
        GEN_LOAD_FREG_FTN(WT0, fs);
5731
        GEN_LOAD_FREG_FTN(WTH0, fs);
5732
        gen_op_float_cvtps_pw();
5733
        GEN_STORE_FTN_FREG(fd, WT2);
5734
        GEN_STORE_FTN_FREG(fd, WTH2);
5735
        opn = "cvt.ps.pw";
5736
        break;
5737
    case FOP(0, 22):
5738
        check_cp1_64bitmode(ctx);
5739
        GEN_LOAD_FREG_FTN(WT0, fs);
5740
        GEN_LOAD_FREG_FTN(WTH0, fs);
5741
        GEN_LOAD_FREG_FTN(WT1, ft);
5742
        GEN_LOAD_FREG_FTN(WTH1, ft);
5743
        gen_op_float_add_ps();
5744
        GEN_STORE_FTN_FREG(fd, WT2);
5745
        GEN_STORE_FTN_FREG(fd, WTH2);
5746
        opn = "add.ps";
5747
        break;
5748
    case FOP(1, 22):
5749
        check_cp1_64bitmode(ctx);
5750
        GEN_LOAD_FREG_FTN(WT0, fs);
5751
        GEN_LOAD_FREG_FTN(WTH0, fs);
5752
        GEN_LOAD_FREG_FTN(WT1, ft);
5753
        GEN_LOAD_FREG_FTN(WTH1, ft);
5754
        gen_op_float_sub_ps();
5755
        GEN_STORE_FTN_FREG(fd, WT2);
5756
        GEN_STORE_FTN_FREG(fd, WTH2);
5757
        opn = "sub.ps";
5758
        break;
5759
    case FOP(2, 22):
5760
        check_cp1_64bitmode(ctx);
5761
        GEN_LOAD_FREG_FTN(WT0, fs);
5762
        GEN_LOAD_FREG_FTN(WTH0, fs);
5763
        GEN_LOAD_FREG_FTN(WT1, ft);
5764
        GEN_LOAD_FREG_FTN(WTH1, ft);
5765
        gen_op_float_mul_ps();
5766
        GEN_STORE_FTN_FREG(fd, WT2);
5767
        GEN_STORE_FTN_FREG(fd, WTH2);
5768
        opn = "mul.ps";
5769
        break;
5770
    case FOP(5, 22):
5771
        check_cp1_64bitmode(ctx);
5772
        GEN_LOAD_FREG_FTN(WT0, fs);
5773
        GEN_LOAD_FREG_FTN(WTH0, fs);
5774
        gen_op_float_abs_ps();
5775
        GEN_STORE_FTN_FREG(fd, WT2);
5776
        GEN_STORE_FTN_FREG(fd, WTH2);
5777
        opn = "abs.ps";
5778
        break;
5779
    case FOP(6, 22):
5780
        check_cp1_64bitmode(ctx);
5781
        GEN_LOAD_FREG_FTN(WT0, fs);
5782
        GEN_LOAD_FREG_FTN(WTH0, fs);
5783
        gen_op_float_mov_ps();
5784
        GEN_STORE_FTN_FREG(fd, WT2);
5785
        GEN_STORE_FTN_FREG(fd, WTH2);
5786
        opn = "mov.ps";
5787
        break;
5788
    case FOP(7, 22):
5789
        check_cp1_64bitmode(ctx);
5790
        GEN_LOAD_FREG_FTN(WT0, fs);
5791
        GEN_LOAD_FREG_FTN(WTH0, fs);
5792
        gen_op_float_chs_ps();
5793
        GEN_STORE_FTN_FREG(fd, WT2);
5794
        GEN_STORE_FTN_FREG(fd, WTH2);
5795
        opn = "neg.ps";
5796
        break;
5797
    case FOP(17, 22):
5798
        check_cp1_64bitmode(ctx);
5799
        GEN_LOAD_REG_T0(ft);
5800
        GEN_LOAD_FREG_FTN(WT0, fs);
5801
        GEN_LOAD_FREG_FTN(WTH0, fs);
5802
        GEN_LOAD_FREG_FTN(WT2, fd);
5803
        GEN_LOAD_FREG_FTN(WTH2, fd);
5804
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5805
        GEN_STORE_FTN_FREG(fd, WT2);
5806
        GEN_STORE_FTN_FREG(fd, WTH2);
5807
        opn = "movcf.ps";
5808
        break;
5809
    case FOP(18, 22):
5810
        check_cp1_64bitmode(ctx);
5811
        GEN_LOAD_REG_T0(ft);
5812
        GEN_LOAD_FREG_FTN(WT0, fs);
5813
        GEN_LOAD_FREG_FTN(WTH0, fs);
5814
        GEN_LOAD_FREG_FTN(WT2, fd);
5815
        GEN_LOAD_FREG_FTN(WTH2, fd);
5816
        gen_op_float_movz_ps();
5817
        GEN_STORE_FTN_FREG(fd, WT2);
5818
        GEN_STORE_FTN_FREG(fd, WTH2);
5819
        opn = "movz.ps";
5820
        break;
5821
    case FOP(19, 22):
5822
        check_cp1_64bitmode(ctx);
5823
        GEN_LOAD_REG_T0(ft);
5824
        GEN_LOAD_FREG_FTN(WT0, fs);
5825
        GEN_LOAD_FREG_FTN(WTH0, fs);
5826
        GEN_LOAD_FREG_FTN(WT2, fd);
5827
        GEN_LOAD_FREG_FTN(WTH2, fd);
5828
        gen_op_float_movn_ps();
5829
        GEN_STORE_FTN_FREG(fd, WT2);
5830
        GEN_STORE_FTN_FREG(fd, WTH2);
5831
        opn = "movn.ps";
5832
        break;
5833
    case FOP(24, 22):
5834
        check_cp1_64bitmode(ctx);
5835
        GEN_LOAD_FREG_FTN(WT0, ft);
5836
        GEN_LOAD_FREG_FTN(WTH0, ft);
5837
        GEN_LOAD_FREG_FTN(WT1, fs);
5838
        GEN_LOAD_FREG_FTN(WTH1, fs);
5839
        gen_op_float_addr_ps();
5840
        GEN_STORE_FTN_FREG(fd, WT2);
5841
        GEN_STORE_FTN_FREG(fd, WTH2);
5842
        opn = "addr.ps";
5843
        break;
5844
    case FOP(26, 22):
5845
        check_cp1_64bitmode(ctx);
5846
        GEN_LOAD_FREG_FTN(WT0, ft);
5847
        GEN_LOAD_FREG_FTN(WTH0, ft);
5848
        GEN_LOAD_FREG_FTN(WT1, fs);
5849
        GEN_LOAD_FREG_FTN(WTH1, fs);
5850
        gen_op_float_mulr_ps();
5851
        GEN_STORE_FTN_FREG(fd, WT2);
5852
        GEN_STORE_FTN_FREG(fd, WTH2);
5853
        opn = "mulr.ps";
5854
        break;
5855
    case FOP(28, 22):
5856
        check_cp1_64bitmode(ctx);
5857
        GEN_LOAD_FREG_FTN(WT0, fs);
5858
        GEN_LOAD_FREG_FTN(WTH0, fs);
5859
        GEN_LOAD_FREG_FTN(WT2, fd);
5860
        GEN_LOAD_FREG_FTN(WTH2, fd);
5861
        gen_op_float_recip2_ps();
5862
        GEN_STORE_FTN_FREG(fd, WT2);
5863
        GEN_STORE_FTN_FREG(fd, WTH2);
5864
        opn = "recip2.ps";
5865
        break;
5866
    case FOP(29, 22):
5867
        check_cp1_64bitmode(ctx);
5868
        GEN_LOAD_FREG_FTN(WT0, fs);
5869
        GEN_LOAD_FREG_FTN(WTH0, fs);
5870
        gen_op_float_recip1_ps();
5871
        GEN_STORE_FTN_FREG(fd, WT2);
5872
        GEN_STORE_FTN_FREG(fd, WTH2);
5873
        opn = "recip1.ps";
5874
        break;
5875
    case FOP(30, 22):
5876
        check_cp1_64bitmode(ctx);
5877
        GEN_LOAD_FREG_FTN(WT0, fs);
5878
        GEN_LOAD_FREG_FTN(WTH0, fs);
5879
        gen_op_float_rsqrt1_ps();
5880
        GEN_STORE_FTN_FREG(fd, WT2);
5881
        GEN_STORE_FTN_FREG(fd, WTH2);
5882
        opn = "rsqrt1.ps";
5883
        break;
5884
    case FOP(31, 22):
5885
        check_cp1_64bitmode(ctx);
5886
        GEN_LOAD_FREG_FTN(WT0, fs);
5887
        GEN_LOAD_FREG_FTN(WTH0, fs);
5888
        GEN_LOAD_FREG_FTN(WT2, ft);
5889
        GEN_LOAD_FREG_FTN(WTH2, ft);
5890
        gen_op_float_rsqrt2_ps();
5891
        GEN_STORE_FTN_FREG(fd, WT2);
5892
        GEN_STORE_FTN_FREG(fd, WTH2);
5893
        opn = "rsqrt2.ps";
5894
        break;
5895
    case FOP(32, 22):
5896
        check_cp1_64bitmode(ctx);
5897
        GEN_LOAD_FREG_FTN(WTH0, fs);
5898
        gen_op_float_cvts_pu();
5899
        GEN_STORE_FTN_FREG(fd, WT2);
5900
        opn = "cvt.s.pu";
5901
        break;
5902
    case FOP(36, 22):
5903
        check_cp1_64bitmode(ctx);
5904
        GEN_LOAD_FREG_FTN(WT0, fs);
5905
        GEN_LOAD_FREG_FTN(WTH0, fs);
5906
        gen_op_float_cvtpw_ps();
5907
        GEN_STORE_FTN_FREG(fd, WT2);
5908
        GEN_STORE_FTN_FREG(fd, WTH2);
5909
        opn = "cvt.pw.ps";
5910
        break;
5911
    case FOP(40, 22):
5912
        check_cp1_64bitmode(ctx);
5913
        GEN_LOAD_FREG_FTN(WT0, fs);
5914
        gen_op_float_cvts_pl();
5915
        GEN_STORE_FTN_FREG(fd, WT2);
5916
        opn = "cvt.s.pl";
5917
        break;
5918
    case FOP(44, 22):
5919
        check_cp1_64bitmode(ctx);
5920
        GEN_LOAD_FREG_FTN(WT0, fs);
5921
        GEN_LOAD_FREG_FTN(WT1, ft);
5922
        gen_op_float_pll_ps();
5923
        GEN_STORE_FTN_FREG(fd, DT2);
5924
        opn = "pll.ps";
5925
        break;
5926
    case FOP(45, 22):
5927
        check_cp1_64bitmode(ctx);
5928
        GEN_LOAD_FREG_FTN(WT0, fs);
5929
        GEN_LOAD_FREG_FTN(WTH1, ft);
5930
        gen_op_float_plu_ps();
5931
        GEN_STORE_FTN_FREG(fd, DT2);
5932
        opn = "plu.ps";
5933
        break;
5934
    case FOP(46, 22):
5935
        check_cp1_64bitmode(ctx);
5936
        GEN_LOAD_FREG_FTN(WTH0, fs);
5937
        GEN_LOAD_FREG_FTN(WT1, ft);
5938
        gen_op_float_pul_ps();
5939
        GEN_STORE_FTN_FREG(fd, DT2);
5940
        opn = "pul.ps";
5941
        break;
5942
    case FOP(47, 22):
5943
        check_cp1_64bitmode(ctx);
5944
        GEN_LOAD_FREG_FTN(WTH0, fs);
5945
        GEN_LOAD_FREG_FTN(WTH1, ft);
5946
        gen_op_float_puu_ps();
5947
        GEN_STORE_FTN_FREG(fd, DT2);
5948
        opn = "puu.ps";
5949
        break;
5950
    case FOP(48, 22):
5951
    case FOP(49, 22):
5952
    case FOP(50, 22):
5953
    case FOP(51, 22):
5954
    case FOP(52, 22):
5955
    case FOP(53, 22):
5956
    case FOP(54, 22):
5957
    case FOP(55, 22):
5958
    case FOP(56, 22):
5959
    case FOP(57, 22):
5960
    case FOP(58, 22):
5961
    case FOP(59, 22):
5962
    case FOP(60, 22):
5963
    case FOP(61, 22):
5964
    case FOP(62, 22):
5965
    case FOP(63, 22):
5966
        check_cp1_64bitmode(ctx);
5967
        GEN_LOAD_FREG_FTN(WT0, fs);
5968
        GEN_LOAD_FREG_FTN(WTH0, fs);
5969
        GEN_LOAD_FREG_FTN(WT1, ft);
5970
        GEN_LOAD_FREG_FTN(WTH1, ft);
5971
        if (ctx->opcode & (1 << 6)) {
5972
            gen_cmpabs_ps(func-48, cc);
5973
            opn = condnames_abs[func-48];
5974
        } else {
5975
            gen_cmp_ps(func-48, cc);
5976
            opn = condnames[func-48];
5977
        }
5978
        break;
5979
    default:
5980
        MIPS_INVAL(opn);
5981
        generate_exception (ctx, EXCP_RI);
5982
        return;
5983
    }
5984
    switch (optype) {
5985
    case BINOP:
5986
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5987
        break;
5988
    case CMPOP:
5989
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5990
        break;
5991
    default:
5992
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5993
        break;
5994
    }
5995
}
5996

    
5997
/* Coprocessor 3 (FPU) */
5998
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5999
                           int fd, int fs, int base, int index)
6000
{
6001
    const char *opn = "extended float load/store";
6002
    int store = 0;
6003

    
6004
    if (base == 0) {
6005
        if (index == 0)
6006
            gen_op_reset_T0();
6007
        else
6008
            GEN_LOAD_REG_T0(index);
6009
    } else if (index == 0) {
6010
        GEN_LOAD_REG_T0(base);
6011
    } else {
6012
        GEN_LOAD_REG_T0(base);
6013
        GEN_LOAD_REG_T1(index);
6014
        gen_op_addr_add();
6015
    }
6016
    /* Don't do NOP if destination is zero: we must perform the actual
6017
       memory access. */
6018
    switch (opc) {
6019
    case OPC_LWXC1:
6020
        check_cop1x(ctx);
6021
        op_ldst_lwc1(ctx);
6022
        GEN_STORE_FTN_FREG(fd, WT0);
6023
        opn = "lwxc1";
6024
        break;
6025
    case OPC_LDXC1:
6026
        check_cop1x(ctx);
6027
        check_cp1_registers(ctx, fd);
6028
        op_ldst_ldc1(ctx);
6029
        GEN_STORE_FTN_FREG(fd, DT0);
6030
        opn = "ldxc1";
6031
        break;
6032
    case OPC_LUXC1:
6033
        check_cp1_64bitmode(ctx);
6034
        op_ldst(luxc1);
6035
        GEN_STORE_FTN_FREG(fd, DT0);
6036
        opn = "luxc1";
6037
        break;
6038
    case OPC_SWXC1:
6039
        check_cop1x(ctx);
6040
        GEN_LOAD_FREG_FTN(WT0, fs);
6041
        op_ldst_swc1(ctx);
6042
        opn = "swxc1";
6043
        store = 1;
6044
        break;
6045
    case OPC_SDXC1:
6046
        check_cop1x(ctx);
6047
        check_cp1_registers(ctx, fs);
6048
        GEN_LOAD_FREG_FTN(DT0, fs);
6049
        op_ldst_sdc1(ctx);
6050
        opn = "sdxc1";
6051
        store = 1;
6052
        break;
6053
    case OPC_SUXC1:
6054
        check_cp1_64bitmode(ctx);
6055
        GEN_LOAD_FREG_FTN(DT0, fs);
6056
        op_ldst(suxc1);
6057
        opn = "suxc1";
6058
        store = 1;
6059
        break;
6060
    default:
6061
        MIPS_INVAL(opn);
6062
        generate_exception(ctx, EXCP_RI);
6063
        return;
6064
    }
6065
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6066
               regnames[index], regnames[base]);
6067
}
6068

    
6069
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6070
                            int fd, int fr, int fs, int ft)
6071
{
6072
    const char *opn = "flt3_arith";
6073

    
6074
    switch (opc) {
6075
    case OPC_ALNV_PS:
6076
        check_cp1_64bitmode(ctx);
6077
        GEN_LOAD_REG_T0(fr);
6078
        GEN_LOAD_FREG_FTN(DT0, fs);
6079
        GEN_LOAD_FREG_FTN(DT1, ft);
6080
        gen_op_float_alnv_ps();
6081
        GEN_STORE_FTN_FREG(fd, DT2);
6082
        opn = "alnv.ps";
6083
        break;
6084
    case OPC_MADD_S:
6085
        check_cop1x(ctx);
6086
        GEN_LOAD_FREG_FTN(WT0, fs);
6087
        GEN_LOAD_FREG_FTN(WT1, ft);
6088
        GEN_LOAD_FREG_FTN(WT2, fr);
6089
        gen_op_float_muladd_s();
6090
        GEN_STORE_FTN_FREG(fd, WT2);
6091
        opn = "madd.s";
6092
        break;
6093
    case OPC_MADD_D:
6094
        check_cop1x(ctx);
6095
        check_cp1_registers(ctx, fd | fs | ft | fr);
6096
        GEN_LOAD_FREG_FTN(DT0, fs);
6097
        GEN_LOAD_FREG_FTN(DT1, ft);
6098
        GEN_LOAD_FREG_FTN(DT2, fr);
6099
        gen_op_float_muladd_d();
6100
        GEN_STORE_FTN_FREG(fd, DT2);
6101
        opn = "madd.d";
6102
        break;
6103
    case OPC_MADD_PS:
6104
        check_cp1_64bitmode(ctx);
6105
        GEN_LOAD_FREG_FTN(WT0, fs);
6106
        GEN_LOAD_FREG_FTN(WTH0, fs);
6107
        GEN_LOAD_FREG_FTN(WT1, ft);
6108
        GEN_LOAD_FREG_FTN(WTH1, ft);
6109
        GEN_LOAD_FREG_FTN(WT2, fr);
6110
        GEN_LOAD_FREG_FTN(WTH2, fr);
6111
        gen_op_float_muladd_ps();
6112
        GEN_STORE_FTN_FREG(fd, WT2);
6113
        GEN_STORE_FTN_FREG(fd, WTH2);
6114
        opn = "madd.ps";
6115
        break;
6116
    case OPC_MSUB_S:
6117
        check_cop1x(ctx);
6118
        GEN_LOAD_FREG_FTN(WT0, fs);
6119
        GEN_LOAD_FREG_FTN(WT1, ft);
6120
        GEN_LOAD_FREG_FTN(WT2, fr);
6121
        gen_op_float_mulsub_s();
6122
        GEN_STORE_FTN_FREG(fd, WT2);
6123
        opn = "msub.s";
6124
        break;
6125
    case OPC_MSUB_D:
6126
        check_cop1x(ctx);
6127
        check_cp1_registers(ctx, fd | fs | ft | fr);
6128
        GEN_LOAD_FREG_FTN(DT0, fs);
6129
        GEN_LOAD_FREG_FTN(DT1, ft);
6130
        GEN_LOAD_FREG_FTN(DT2, fr);
6131
        gen_op_float_mulsub_d();
6132
        GEN_STORE_FTN_FREG(fd, DT2);
6133
        opn = "msub.d";
6134
        break;
6135
    case OPC_MSUB_PS:
6136
        check_cp1_64bitmode(ctx);
6137
        GEN_LOAD_FREG_FTN(WT0, fs);
6138
        GEN_LOAD_FREG_FTN(WTH0, fs);
6139
        GEN_LOAD_FREG_FTN(WT1, ft);
6140
        GEN_LOAD_FREG_FTN(WTH1, ft);
6141
        GEN_LOAD_FREG_FTN(WT2, fr);
6142
        GEN_LOAD_FREG_FTN(WTH2, fr);
6143
        gen_op_float_mulsub_ps();
6144
        GEN_STORE_FTN_FREG(fd, WT2);
6145
        GEN_STORE_FTN_FREG(fd, WTH2);
6146
        opn = "msub.ps";
6147
        break;
6148
    case OPC_NMADD_S:
6149
        check_cop1x(ctx);
6150
        GEN_LOAD_FREG_FTN(WT0, fs);
6151
        GEN_LOAD_FREG_FTN(WT1, ft);
6152
        GEN_LOAD_FREG_FTN(WT2, fr);
6153
        gen_op_float_nmuladd_s();
6154
        GEN_STORE_FTN_FREG(fd, WT2);
6155
        opn = "nmadd.s";
6156
        break;
6157
    case OPC_NMADD_D:
6158
        check_cop1x(ctx);
6159
        check_cp1_registers(ctx, fd | fs | ft | fr);
6160
        GEN_LOAD_FREG_FTN(DT0, fs);
6161
        GEN_LOAD_FREG_FTN(DT1, ft);
6162
        GEN_LOAD_FREG_FTN(DT2, fr);
6163
        gen_op_float_nmuladd_d();
6164
        GEN_STORE_FTN_FREG(fd, DT2);
6165
        opn = "nmadd.d";
6166
        break;
6167
    case OPC_NMADD_PS:
6168
        check_cp1_64bitmode(ctx);
6169
        GEN_LOAD_FREG_FTN(WT0, fs);
6170
        GEN_LOAD_FREG_FTN(WTH0, fs);
6171
        GEN_LOAD_FREG_FTN(WT1, ft);
6172
        GEN_LOAD_FREG_FTN(WTH1, ft);
6173
        GEN_LOAD_FREG_FTN(WT2, fr);
6174
        GEN_LOAD_FREG_FTN(WTH2, fr);
6175
        gen_op_float_nmuladd_ps();
6176
        GEN_STORE_FTN_FREG(fd, WT2);
6177
        GEN_STORE_FTN_FREG(fd, WTH2);
6178
        opn = "nmadd.ps";
6179
        break;
6180
    case OPC_NMSUB_S:
6181
        check_cop1x(ctx);
6182
        GEN_LOAD_FREG_FTN(WT0, fs);
6183
        GEN_LOAD_FREG_FTN(WT1, ft);
6184
        GEN_LOAD_FREG_FTN(WT2, fr);
6185
        gen_op_float_nmulsub_s();
6186
        GEN_STORE_FTN_FREG(fd, WT2);
6187
        opn = "nmsub.s";
6188
        break;
6189
    case OPC_NMSUB_D:
6190
        check_cop1x(ctx);
6191
        check_cp1_registers(ctx, fd | fs | ft | fr);
6192
        GEN_LOAD_FREG_FTN(DT0, fs);
6193
        GEN_LOAD_FREG_FTN(DT1, ft);
6194
        GEN_LOAD_FREG_FTN(DT2, fr);
6195
        gen_op_float_nmulsub_d();
6196
        GEN_STORE_FTN_FREG(fd, DT2);
6197
        opn = "nmsub.d";
6198
        break;
6199
    case OPC_NMSUB_PS:
6200
        check_cp1_64bitmode(ctx);
6201
        GEN_LOAD_FREG_FTN(WT0, fs);
6202
        GEN_LOAD_FREG_FTN(WTH0, fs);
6203
        GEN_LOAD_FREG_FTN(WT1, ft);
6204
        GEN_LOAD_FREG_FTN(WTH1, ft);
6205
        GEN_LOAD_FREG_FTN(WT2, fr);
6206
        GEN_LOAD_FREG_FTN(WTH2, fr);
6207
        gen_op_float_nmulsub_ps();
6208
        GEN_STORE_FTN_FREG(fd, WT2);
6209
        GEN_STORE_FTN_FREG(fd, WTH2);
6210
        opn = "nmsub.ps";
6211
        break;
6212
    default:
6213
        MIPS_INVAL(opn);
6214
        generate_exception (ctx, EXCP_RI);
6215
        return;
6216
    }
6217
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6218
               fregnames[fs], fregnames[ft]);
6219
}
6220

    
6221
/* ISA extensions (ASEs) */
6222
/* MIPS16 extension to MIPS32 */
6223
/* SmartMIPS extension to MIPS32 */
6224

    
6225
#if defined(TARGET_MIPS64)
6226

    
6227
/* MDMX extension to MIPS64 */
6228

    
6229
#endif
6230

    
6231
static void decode_opc (CPUState *env, DisasContext *ctx)
6232
{
6233
    int32_t offset;
6234
    int rs, rt, rd, sa;
6235
    uint32_t op, op1, op2;
6236
    int16_t imm;
6237

    
6238
    /* make sure instructions are on a word boundary */
6239
    if (ctx->pc & 0x3) {
6240
        env->CP0_BadVAddr = ctx->pc;
6241
        generate_exception(ctx, EXCP_AdEL);
6242
        return;
6243
    }
6244

    
6245
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6246
        int l1;
6247
        /* Handle blikely not taken case */
6248
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6249
        l1 = gen_new_label();
6250
        tcg_gen_jnz_bcond(l1);
6251
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6252
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6253
        gen_set_label(l1);
6254
    }
6255
    op = MASK_OP_MAJOR(ctx->opcode);
6256
    rs = (ctx->opcode >> 21) & 0x1f;
6257
    rt = (ctx->opcode >> 16) & 0x1f;
6258
    rd = (ctx->opcode >> 11) & 0x1f;
6259
    sa = (ctx->opcode >> 6) & 0x1f;
6260
    imm = (int16_t)ctx->opcode;
6261
    switch (op) {
6262
    case OPC_SPECIAL:
6263
        op1 = MASK_SPECIAL(ctx->opcode);
6264
        switch (op1) {
6265
        case OPC_SLL:          /* Arithmetic with immediate */
6266
        case OPC_SRL ... OPC_SRA:
6267
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6268
            break;
6269
        case OPC_MOVZ ... OPC_MOVN:
6270
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6271
        case OPC_SLLV:         /* Arithmetic */
6272
        case OPC_SRLV ... OPC_SRAV:
6273
        case OPC_ADD ... OPC_NOR:
6274
        case OPC_SLT ... OPC_SLTU:
6275
            gen_arith(env, ctx, op1, rd, rs, rt);
6276
            break;
6277
        case OPC_MULT ... OPC_DIVU:
6278
            if (sa) {
6279
                check_insn(env, ctx, INSN_VR54XX);
6280
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6281
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6282
            } else
6283
                gen_muldiv(ctx, op1, rs, rt);
6284
            break;
6285
        case OPC_JR ... OPC_JALR:
6286
            gen_compute_branch(ctx, op1, rs, rd, sa);
6287
            return;
6288
        case OPC_TGE ... OPC_TEQ: /* Traps */
6289
        case OPC_TNE:
6290
            gen_trap(ctx, op1, rs, rt, -1);
6291
            break;
6292
        case OPC_MFHI:          /* Move from HI/LO */
6293
        case OPC_MFLO:
6294
            gen_HILO(ctx, op1, rd);
6295
            break;
6296
        case OPC_MTHI:
6297
        case OPC_MTLO:          /* Move to HI/LO */
6298
            gen_HILO(ctx, op1, rs);
6299
            break;
6300
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6301
#ifdef MIPS_STRICT_STANDARD
6302
            MIPS_INVAL("PMON / selsl");
6303
            generate_exception(ctx, EXCP_RI);
6304
#else
6305
            gen_op_pmon(sa);
6306
#endif
6307
            break;
6308
        case OPC_SYSCALL:
6309
            generate_exception(ctx, EXCP_SYSCALL);
6310
            break;
6311
        case OPC_BREAK:
6312
            generate_exception(ctx, EXCP_BREAK);
6313
            break;
6314
        case OPC_SPIM:
6315
#ifdef MIPS_STRICT_STANDARD
6316
            MIPS_INVAL("SPIM");
6317
            generate_exception(ctx, EXCP_RI);
6318
#else
6319
           /* Implemented as RI exception for now. */
6320
            MIPS_INVAL("spim (unofficial)");
6321
            generate_exception(ctx, EXCP_RI);
6322
#endif
6323
            break;
6324
        case OPC_SYNC:
6325
            /* Treat as NOP. */
6326
            break;
6327

    
6328
        case OPC_MOVCI:
6329
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6330
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6331
                save_cpu_state(ctx, 1);
6332
                check_cp1_enabled(ctx);
6333
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6334
                          (ctx->opcode >> 16) & 1);
6335
            } else {
6336
                generate_exception_err(ctx, EXCP_CpU, 1);
6337
            }
6338
            break;
6339

    
6340
#if defined(TARGET_MIPS64)
6341
       /* MIPS64 specific opcodes */
6342
        case OPC_DSLL:
6343
        case OPC_DSRL ... OPC_DSRA:
6344
        case OPC_DSLL32:
6345
        case OPC_DSRL32 ... OPC_DSRA32:
6346
            check_insn(env, ctx, ISA_MIPS3);
6347
            check_mips_64(ctx);
6348
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6349
            break;
6350
        case OPC_DSLLV:
6351
        case OPC_DSRLV ... OPC_DSRAV:
6352
        case OPC_DADD ... OPC_DSUBU:
6353
            check_insn(env, ctx, ISA_MIPS3);
6354
            check_mips_64(ctx);
6355
            gen_arith(env, ctx, op1, rd, rs, rt);
6356
            break;
6357
        case OPC_DMULT ... OPC_DDIVU:
6358
            check_insn(env, ctx, ISA_MIPS3);
6359
            check_mips_64(ctx);
6360
            gen_muldiv(ctx, op1, rs, rt);
6361
            break;
6362
#endif
6363
        default:            /* Invalid */
6364
            MIPS_INVAL("special");
6365
            generate_exception(ctx, EXCP_RI);
6366
            break;
6367
        }
6368
        break;
6369
    case OPC_SPECIAL2:
6370
        op1 = MASK_SPECIAL2(ctx->opcode);
6371
        switch (op1) {
6372
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6373
        case OPC_MSUB ... OPC_MSUBU:
6374
            check_insn(env, ctx, ISA_MIPS32);
6375
            gen_muldiv(ctx, op1, rs, rt);
6376
            break;
6377
        case OPC_MUL:
6378
            gen_arith(env, ctx, op1, rd, rs, rt);
6379
            break;
6380
        case OPC_CLZ ... OPC_CLO:
6381
            check_insn(env, ctx, ISA_MIPS32);
6382
            gen_cl(ctx, op1, rd, rs);
6383
            break;
6384
        case OPC_SDBBP:
6385
            /* XXX: not clear which exception should be raised
6386
             *      when in debug mode...
6387
             */
6388
            check_insn(env, ctx, ISA_MIPS32);
6389
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6390
                generate_exception(ctx, EXCP_DBp);
6391
            } else {
6392
                generate_exception(ctx, EXCP_DBp);
6393
            }
6394
            /* Treat as NOP. */
6395
            break;
6396
#if defined(TARGET_MIPS64)
6397
        case OPC_DCLZ ... OPC_DCLO:
6398
            check_insn(env, ctx, ISA_MIPS64);
6399
            check_mips_64(ctx);
6400
            gen_cl(ctx, op1, rd, rs);
6401
            break;
6402
#endif
6403
        default:            /* Invalid */
6404
            MIPS_INVAL("special2");
6405
            generate_exception(ctx, EXCP_RI);
6406
            break;
6407
        }
6408
        break;
6409
    case OPC_SPECIAL3:
6410
         op1 = MASK_SPECIAL3(ctx->opcode);
6411
         switch (op1) {
6412
         case OPC_EXT:
6413
         case OPC_INS:
6414
             check_insn(env, ctx, ISA_MIPS32R2);
6415
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6416
             break;
6417
         case OPC_BSHFL:
6418
             check_insn(env, ctx, ISA_MIPS32R2);
6419
             op2 = MASK_BSHFL(ctx->opcode);
6420
             switch (op2) {
6421
             case OPC_WSBH:
6422
                 GEN_LOAD_REG_T1(rt);
6423
                 gen_op_wsbh();
6424
                 break;
6425
             case OPC_SEB:
6426
                 GEN_LOAD_REG_T1(rt);
6427
                 gen_op_seb();
6428
                 break;
6429
             case OPC_SEH:
6430
                 GEN_LOAD_REG_T1(rt);
6431
                 gen_op_seh();
6432
                 break;
6433
             default:            /* Invalid */
6434
                 MIPS_INVAL("bshfl");
6435
                 generate_exception(ctx, EXCP_RI);
6436
                 break;
6437
            }
6438
            GEN_STORE_T0_REG(rd);
6439
            break;
6440
        case OPC_RDHWR:
6441
            check_insn(env, ctx, ISA_MIPS32R2);
6442
            switch (rd) {
6443
            case 0:
6444
                save_cpu_state(ctx, 1);
6445
                gen_op_rdhwr_cpunum();
6446
                break;
6447
            case 1:
6448
                save_cpu_state(ctx, 1);
6449
                gen_op_rdhwr_synci_step();
6450
                break;
6451
            case 2:
6452
                save_cpu_state(ctx, 1);
6453
                gen_op_rdhwr_cc();
6454
                break;
6455
            case 3:
6456
                save_cpu_state(ctx, 1);
6457
                gen_op_rdhwr_ccres();
6458
                break;
6459
            case 29:
6460
#if defined (CONFIG_USER_ONLY)
6461
                gen_op_tls_value();
6462
                break;
6463
#endif
6464
            default:            /* Invalid */
6465
                MIPS_INVAL("rdhwr");
6466
                generate_exception(ctx, EXCP_RI);
6467
                break;
6468
            }
6469
            GEN_STORE_T0_REG(rt);
6470
            break;
6471
        case OPC_FORK:
6472
            check_insn(env, ctx, ASE_MT);
6473
            GEN_LOAD_REG_T0(rt);
6474
            GEN_LOAD_REG_T1(rs);
6475
            gen_op_fork();
6476
            break;
6477
        case OPC_YIELD:
6478
            check_insn(env, ctx, ASE_MT);
6479
            GEN_LOAD_REG_T0(rs);
6480
            gen_op_yield();
6481
            GEN_STORE_T0_REG(rd);
6482
            break;
6483
#if defined(TARGET_MIPS64)
6484
        case OPC_DEXTM ... OPC_DEXT:
6485
        case OPC_DINSM ... OPC_DINS:
6486
            check_insn(env, ctx, ISA_MIPS64R2);
6487
            check_mips_64(ctx);
6488
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6489
            break;
6490
        case OPC_DBSHFL:
6491
            check_insn(env, ctx, ISA_MIPS64R2);
6492
            check_mips_64(ctx);
6493
            op2 = MASK_DBSHFL(ctx->opcode);
6494
            switch (op2) {
6495
            case OPC_DSBH:
6496
                GEN_LOAD_REG_T1(rt);
6497
                gen_op_dsbh();
6498
                break;
6499
            case OPC_DSHD:
6500
                GEN_LOAD_REG_T1(rt);
6501
                gen_op_dshd();
6502
                break;
6503
            default:            /* Invalid */
6504
                MIPS_INVAL("dbshfl");
6505
                generate_exception(ctx, EXCP_RI);
6506
                break;
6507
            }
6508
            GEN_STORE_T0_REG(rd);
6509
            break;
6510
#endif
6511
        default:            /* Invalid */
6512
            MIPS_INVAL("special3");
6513
            generate_exception(ctx, EXCP_RI);
6514
            break;
6515
        }
6516
        break;
6517
    case OPC_REGIMM:
6518
        op1 = MASK_REGIMM(ctx->opcode);
6519
        switch (op1) {
6520
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6521
        case OPC_BLTZAL ... OPC_BGEZALL:
6522
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6523
            return;
6524
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6525
        case OPC_TNEI:
6526
            gen_trap(ctx, op1, rs, -1, imm);
6527
            break;
6528
        case OPC_SYNCI:
6529
            check_insn(env, ctx, ISA_MIPS32R2);
6530
            /* Treat as NOP. */
6531
            break;
6532
        default:            /* Invalid */
6533
            MIPS_INVAL("regimm");
6534
            generate_exception(ctx, EXCP_RI);
6535
            break;
6536
        }
6537
        break;
6538
    case OPC_CP0:
6539
        check_cp0_enabled(ctx);
6540
        op1 = MASK_CP0(ctx->opcode);
6541
        switch (op1) {
6542
        case OPC_MFC0:
6543
        case OPC_MTC0:
6544
        case OPC_MFTR:
6545
        case OPC_MTTR:
6546
#if defined(TARGET_MIPS64)
6547
        case OPC_DMFC0:
6548
        case OPC_DMTC0:
6549
#endif
6550
            gen_cp0(env, ctx, op1, rt, rd);
6551
            break;
6552
        case OPC_C0_FIRST ... OPC_C0_LAST:
6553
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6554
            break;
6555
        case OPC_MFMC0:
6556
            op2 = MASK_MFMC0(ctx->opcode);
6557
            switch (op2) {
6558
            case OPC_DMT:
6559
                check_insn(env, ctx, ASE_MT);
6560
                gen_op_dmt();
6561
                break;
6562
            case OPC_EMT:
6563
                check_insn(env, ctx, ASE_MT);
6564
                gen_op_emt();
6565
                break;
6566
            case OPC_DVPE:
6567
                check_insn(env, ctx, ASE_MT);
6568
                gen_op_dvpe();
6569
                break;
6570
            case OPC_EVPE:
6571
                check_insn(env, ctx, ASE_MT);
6572
                gen_op_evpe();
6573
                break;
6574
            case OPC_DI:
6575
                check_insn(env, ctx, ISA_MIPS32R2);
6576
                save_cpu_state(ctx, 1);
6577
                gen_op_di();
6578
                /* Stop translation as we may have switched the execution mode */
6579
                ctx->bstate = BS_STOP;
6580
                break;
6581
            case OPC_EI:
6582
                check_insn(env, ctx, ISA_MIPS32R2);
6583
                save_cpu_state(ctx, 1);
6584
                gen_op_ei();
6585
                /* Stop translation as we may have switched the execution mode */
6586
                ctx->bstate = BS_STOP;
6587
                break;
6588
            default:            /* Invalid */
6589
                MIPS_INVAL("mfmc0");
6590
                generate_exception(ctx, EXCP_RI);
6591
                break;
6592
            }
6593
            GEN_STORE_T0_REG(rt);
6594
            break;
6595
        case OPC_RDPGPR:
6596
            check_insn(env, ctx, ISA_MIPS32R2);
6597
            GEN_LOAD_SRSREG_TN(T0, rt);
6598
            GEN_STORE_T0_REG(rd);
6599
            break;
6600
        case OPC_WRPGPR:
6601
            check_insn(env, ctx, ISA_MIPS32R2);
6602
            GEN_LOAD_REG_T0(rt);
6603
            GEN_STORE_TN_SRSREG(rd, T0);
6604
            break;
6605
        default:
6606
            MIPS_INVAL("cp0");
6607
            generate_exception(ctx, EXCP_RI);
6608
            break;
6609
        }
6610
        break;
6611
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6612
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6613
         break;
6614
    case OPC_J ... OPC_JAL: /* Jump */
6615
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6616
         gen_compute_branch(ctx, op, rs, rt, offset);
6617
         return;
6618
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6619
    case OPC_BEQL ... OPC_BGTZL:
6620
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6621
         return;
6622
    case OPC_LB ... OPC_LWR: /* Load and stores */
6623
    case OPC_SB ... OPC_SW:
6624
    case OPC_SWR:
6625
    case OPC_LL:
6626
    case OPC_SC:
6627
         gen_ldst(ctx, op, rt, rs, imm);
6628
         break;
6629
    case OPC_CACHE:
6630
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6631
        /* Treat as NOP. */
6632
        break;
6633
    case OPC_PREF:
6634
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6635
        /* Treat as NOP. */
6636
        break;
6637

    
6638
    /* Floating point (COP1). */
6639
    case OPC_LWC1:
6640
    case OPC_LDC1:
6641
    case OPC_SWC1:
6642
    case OPC_SDC1:
6643
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6644
            save_cpu_state(ctx, 1);
6645
            check_cp1_enabled(ctx);
6646
            gen_flt_ldst(ctx, op, rt, rs, imm);
6647
        } else {
6648
            generate_exception_err(ctx, EXCP_CpU, 1);
6649
        }
6650
        break;
6651

    
6652
    case OPC_CP1:
6653
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6654
            save_cpu_state(ctx, 1);
6655
            check_cp1_enabled(ctx);
6656
            op1 = MASK_CP1(ctx->opcode);
6657
            switch (op1) {
6658
            case OPC_MFHC1:
6659
            case OPC_MTHC1:
6660
                check_insn(env, ctx, ISA_MIPS32R2);
6661
            case OPC_MFC1:
6662
            case OPC_CFC1:
6663
            case OPC_MTC1:
6664
            case OPC_CTC1:
6665
                gen_cp1(ctx, op1, rt, rd);
6666
                break;
6667
#if defined(TARGET_MIPS64)
6668
            case OPC_DMFC1:
6669
            case OPC_DMTC1:
6670
                check_insn(env, ctx, ISA_MIPS3);
6671
                gen_cp1(ctx, op1, rt, rd);
6672
                break;
6673
#endif
6674
            case OPC_BC1ANY2:
6675
            case OPC_BC1ANY4:
6676
                check_cop1x(ctx);
6677
                check_insn(env, ctx, ASE_MIPS3D);
6678
                /* fall through */
6679
            case OPC_BC1:
6680
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6681
                                    (rt >> 2) & 0x7, imm << 2);
6682
                return;
6683
            case OPC_S_FMT:
6684
            case OPC_D_FMT:
6685
            case OPC_W_FMT:
6686
            case OPC_L_FMT:
6687
            case OPC_PS_FMT:
6688
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6689
                           (imm >> 8) & 0x7);
6690
                break;
6691
            default:
6692
                MIPS_INVAL("cp1");
6693
                generate_exception (ctx, EXCP_RI);
6694
                break;
6695
            }
6696
        } else {
6697
            generate_exception_err(ctx, EXCP_CpU, 1);
6698
        }
6699
        break;
6700

    
6701
    /* COP2.  */
6702
    case OPC_LWC2:
6703
    case OPC_LDC2:
6704
    case OPC_SWC2:
6705
    case OPC_SDC2:
6706
    case OPC_CP2:
6707
        /* COP2: Not implemented. */
6708
        generate_exception_err(ctx, EXCP_CpU, 2);
6709
        break;
6710

    
6711
    case OPC_CP3:
6712
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6713
            save_cpu_state(ctx, 1);
6714
            check_cp1_enabled(ctx);
6715
            op1 = MASK_CP3(ctx->opcode);
6716
            switch (op1) {
6717
            case OPC_LWXC1:
6718
            case OPC_LDXC1:
6719
            case OPC_LUXC1:
6720
            case OPC_SWXC1:
6721
            case OPC_SDXC1:
6722
            case OPC_SUXC1:
6723
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6724
                break;
6725
            case OPC_PREFX:
6726
                /* Treat as NOP. */
6727
                break;
6728
            case OPC_ALNV_PS:
6729
            case OPC_MADD_S:
6730
            case OPC_MADD_D:
6731
            case OPC_MADD_PS:
6732
            case OPC_MSUB_S:
6733
            case OPC_MSUB_D:
6734
            case OPC_MSUB_PS:
6735
            case OPC_NMADD_S:
6736
            case OPC_NMADD_D:
6737
            case OPC_NMADD_PS:
6738
            case OPC_NMSUB_S:
6739
            case OPC_NMSUB_D:
6740
            case OPC_NMSUB_PS:
6741
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6742
                break;
6743
            default:
6744
                MIPS_INVAL("cp3");
6745
                generate_exception (ctx, EXCP_RI);
6746
                break;
6747
            }
6748
        } else {
6749
            generate_exception_err(ctx, EXCP_CpU, 1);
6750
        }
6751
        break;
6752

    
6753
#if defined(TARGET_MIPS64)
6754
    /* MIPS64 opcodes */
6755
    case OPC_LWU:
6756
    case OPC_LDL ... OPC_LDR:
6757
    case OPC_SDL ... OPC_SDR:
6758
    case OPC_LLD:
6759
    case OPC_LD:
6760
    case OPC_SCD:
6761
    case OPC_SD:
6762
        check_insn(env, ctx, ISA_MIPS3);
6763
        check_mips_64(ctx);
6764
        gen_ldst(ctx, op, rt, rs, imm);
6765
        break;
6766
    case OPC_DADDI ... OPC_DADDIU:
6767
        check_insn(env, ctx, ISA_MIPS3);
6768
        check_mips_64(ctx);
6769
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6770
        break;
6771
#endif
6772
    case OPC_JALX:
6773
        check_insn(env, ctx, ASE_MIPS16);
6774
        /* MIPS16: Not implemented. */
6775
    case OPC_MDMX:
6776
        check_insn(env, ctx, ASE_MDMX);
6777
        /* MDMX: Not implemented. */
6778
    default:            /* Invalid */
6779
        MIPS_INVAL("major opcode");
6780
        generate_exception(ctx, EXCP_RI);
6781
        break;
6782
    }
6783
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6784
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6785
        /* Branches completion */
6786
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6787
        ctx->bstate = BS_BRANCH;
6788
        save_cpu_state(ctx, 0);
6789
        switch (hflags) {
6790
        case MIPS_HFLAG_B:
6791
            /* unconditional branch */
6792
            MIPS_DEBUG("unconditional branch");
6793
            gen_goto_tb(ctx, 0, ctx->btarget);
6794
            break;
6795
        case MIPS_HFLAG_BL:
6796
            /* blikely taken case */
6797
            MIPS_DEBUG("blikely branch taken");
6798
            gen_goto_tb(ctx, 0, ctx->btarget);
6799
            break;
6800
        case MIPS_HFLAG_BC:
6801
            /* Conditional branch */
6802
            MIPS_DEBUG("conditional branch");
6803
            {
6804
              int l1;
6805
              l1 = gen_new_label();
6806
              tcg_gen_jnz_bcond(l1);
6807
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6808
              gen_set_label(l1);
6809
              gen_goto_tb(ctx, 0, ctx->btarget);
6810
            }
6811
            break;
6812
        case MIPS_HFLAG_BR:
6813
            /* unconditional branch to register */
6814
            MIPS_DEBUG("branch to register");
6815
            gen_op_breg();
6816
            tcg_gen_exit_tb(0);
6817
            break;
6818
        default:
6819
            MIPS_DEBUG("unknown branch");
6820
            break;
6821
        }
6822
    }
6823
}
6824

    
6825
static always_inline int
6826
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6827
                                int search_pc)
6828
{
6829
    DisasContext ctx;
6830
    target_ulong pc_start;
6831
    uint16_t *gen_opc_end;
6832
    int j, lj = -1;
6833

    
6834
    if (search_pc && loglevel)
6835
        fprintf (logfile, "search pc %d\n", search_pc);
6836

    
6837
    num_temps = 0;
6838
    memset(temps, 0, sizeof(temps));
6839

    
6840
    pc_start = tb->pc;
6841
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6842
    ctx.pc = pc_start;
6843
    ctx.saved_pc = -1;
6844
    ctx.tb = tb;
6845
    ctx.bstate = BS_NONE;
6846
    /* Restore delay slot state from the tb context.  */
6847
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6848
    restore_cpu_state(env, &ctx);
6849
#if defined(CONFIG_USER_ONLY)
6850
    ctx.mem_idx = MIPS_HFLAG_UM;
6851
#else
6852
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6853
#endif
6854
#ifdef DEBUG_DISAS
6855
    if (loglevel & CPU_LOG_TB_CPU) {
6856
        fprintf(logfile, "------------------------------------------------\n");
6857
        /* FIXME: This may print out stale hflags from env... */
6858
        cpu_dump_state(env, logfile, fprintf, 0);
6859
    }
6860
#endif
6861
#ifdef MIPS_DEBUG_DISAS
6862
    if (loglevel & CPU_LOG_TB_IN_ASM)
6863
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6864
                tb, ctx.mem_idx, ctx.hflags);
6865
#endif
6866
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6867
        if (env->nb_breakpoints > 0) {
6868
            for(j = 0; j < env->nb_breakpoints; j++) {
6869
                if (env->breakpoints[j] == ctx.pc) {
6870
                    save_cpu_state(&ctx, 1);
6871
                    ctx.bstate = BS_BRANCH;
6872
                    gen_op_debug();
6873
                    /* Include the breakpoint location or the tb won't
6874
                     * be flushed when it must be.  */
6875
                    ctx.pc += 4;
6876
                    goto done_generating;
6877
                }
6878
            }
6879
        }
6880

    
6881
        if (search_pc) {
6882
            j = gen_opc_ptr - gen_opc_buf;
6883
            if (lj < j) {
6884
                lj++;
6885
                while (lj < j)
6886
                    gen_opc_instr_start[lj++] = 0;
6887
            }
6888
            gen_opc_pc[lj] = ctx.pc;
6889
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6890
            gen_opc_instr_start[lj] = 1;
6891
        }
6892
        ctx.opcode = ldl_code(ctx.pc);
6893
        decode_opc(env, &ctx);
6894
        if (num_temps) {
6895
            fprintf(stderr,
6896
                    "Internal resource leak before " TARGET_FMT_lx "\n",
6897
                    ctx.pc);
6898
            num_temps = 0;
6899
        }
6900
        ctx.pc += 4;
6901

    
6902
        if (env->singlestep_enabled)
6903
            break;
6904

    
6905
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6906
            break;
6907

    
6908
#if defined (MIPS_SINGLE_STEP)
6909
        break;
6910
#endif
6911
    }
6912
    if (env->singlestep_enabled) {
6913
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6914
        gen_op_debug();
6915
    } else {
6916
        switch (ctx.bstate) {
6917
        case BS_STOP:
6918
            gen_op_interrupt_restart();
6919
            gen_goto_tb(&ctx, 0, ctx.pc);
6920
            break;
6921
        case BS_NONE:
6922
            save_cpu_state(&ctx, 0);
6923
            gen_goto_tb(&ctx, 0, ctx.pc);
6924
            break;
6925
        case BS_EXCP:
6926
            gen_op_interrupt_restart();
6927
            tcg_gen_exit_tb(0);
6928
            break;
6929
        case BS_BRANCH:
6930
        default:
6931
            break;
6932
        }
6933
    }
6934
done_generating:
6935
    ctx.last_T0_store = NULL;
6936
    *gen_opc_ptr = INDEX_op_end;
6937
    if (search_pc) {
6938
        j = gen_opc_ptr - gen_opc_buf;
6939
        lj++;
6940
        while (lj <= j)
6941
            gen_opc_instr_start[lj++] = 0;
6942
    } else {
6943
        tb->size = ctx.pc - pc_start;
6944
    }
6945
#ifdef DEBUG_DISAS
6946
#if defined MIPS_DEBUG_DISAS
6947
    if (loglevel & CPU_LOG_TB_IN_ASM)
6948
        fprintf(logfile, "\n");
6949
#endif
6950
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6951
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6952
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6953
        fprintf(logfile, "\n");
6954
    }
6955
    if (loglevel & CPU_LOG_TB_CPU) {
6956
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6957
    }
6958
#endif
6959

    
6960
    return 0;
6961
}
6962

    
6963
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6964
{
6965
    return gen_intermediate_code_internal(env, tb, 0);
6966
}
6967

    
6968
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6969
{
6970
    return gen_intermediate_code_internal(env, tb, 1);
6971
}
6972

    
6973
void fpu_dump_state(CPUState *env, FILE *f,
6974
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6975
                    int flags)
6976
{
6977
    int i;
6978
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6979

    
6980
#define printfpr(fp)                                                        \
6981
    do {                                                                    \
6982
        if (is_fpu64)                                                       \
6983
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6984
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6985
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6986
        else {                                                              \
6987
            fpr_t tmp;                                                      \
6988
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6989
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6990
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6991
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6992
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6993
        }                                                                   \
6994
    } while(0)
6995

    
6996

    
6997
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6998
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6999
                get_float_exception_flags(&env->fpu->fp_status));
7000
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7001
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7002
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7003
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7004
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7005
        printfpr(&env->fpu->fpr[i]);
7006
    }
7007

    
7008
#undef printfpr
7009
}
7010

    
7011
void dump_fpu (CPUState *env)
7012
{
7013
    if (loglevel) {
7014
        fprintf(logfile,
7015
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7016
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7017
                " %04x\n",
7018
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7019
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7020
                env->bcond);
7021
       fpu_dump_state(env, logfile, fprintf, 0);
7022
    }
7023
}
7024

    
7025
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7026
/* Debug help: The architecture requires 32bit code to maintain proper
7027
   sign-extened values on 64bit machines.  */
7028

    
7029
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7030

    
7031
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7032
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7033
                     int flags)
7034
{
7035
    int i;
7036

    
7037
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7038
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7039
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7040
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7041
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7042
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7043
    if (!SIGN_EXT_P(env->btarget))
7044
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7045

    
7046
    for (i = 0; i < 32; i++) {
7047
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7048
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7049
    }
7050

    
7051
    if (!SIGN_EXT_P(env->CP0_EPC))
7052
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7053
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7054
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7055
}
7056
#endif
7057

    
7058
void cpu_dump_state (CPUState *env, FILE *f,
7059
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7060
                     int flags)
7061
{
7062
    int i;
7063

    
7064
    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",
7065
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7066
    for (i = 0; i < 32; i++) {
7067
        if ((i & 3) == 0)
7068
            cpu_fprintf(f, "GPR%02d:", i);
7069
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7070
        if ((i & 3) == 3)
7071
            cpu_fprintf(f, "\n");
7072
    }
7073

    
7074
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7075
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7076
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7077
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7078
    if (env->hflags & MIPS_HFLAG_FPU)
7079
        fpu_dump_state(env, f, cpu_fprintf, flags);
7080
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7081
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7082
#endif
7083
}
7084

    
7085
static void mips_tcg_init(void)
7086
{
7087
    static int inited;
7088

    
7089
    /* Initialize various static tables. */
7090
    if (inited)
7091
        return;
7092

    
7093
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7094
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7095
                                         TCG_AREG0,
7096
                                         offsetof(CPUState, current_tc_gprs),
7097
                                         "current_tc_gprs");
7098
#if TARGET_LONG_BITS > HOST_LONG_BITS
7099
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7100
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7101
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7102
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7103
#else
7104
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7105
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7106
#endif
7107

    
7108
    inited = 1;
7109
}
7110

    
7111
#include "translate_init.c"
7112

    
7113
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7114
{
7115
    CPUMIPSState *env;
7116
    const mips_def_t *def;
7117

    
7118
    def = cpu_mips_find_by_name(cpu_model);
7119
    if (!def)
7120
        return NULL;
7121
    env = qemu_mallocz(sizeof(CPUMIPSState));
7122
    if (!env)
7123
        return NULL;
7124
    env->cpu_model = def;
7125

    
7126
    cpu_exec_init(env);
7127
    env->cpu_model_str = cpu_model;
7128
    mips_tcg_init();
7129
    cpu_reset(env);
7130
    return env;
7131
}
7132

    
7133
void cpu_reset (CPUMIPSState *env)
7134
{
7135
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7136

    
7137
    tlb_flush(env, 1);
7138

    
7139
    /* Minimal init */
7140
#if !defined(CONFIG_USER_ONLY)
7141
    if (env->hflags & MIPS_HFLAG_BMASK) {
7142
        /* If the exception was raised from a delay slot,
7143
         * come back to the jump.  */
7144
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7145
    } else {
7146
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7147
    }
7148
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7149
    env->CP0_Wired = 0;
7150
    /* SMP not implemented */
7151
    env->CP0_EBase = 0x80000000;
7152
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7153
    /* vectored interrupts not implemented, timer on int 7,
7154
       no performance counters. */
7155
    env->CP0_IntCtl = 0xe0000000;
7156
    {
7157
        int i;
7158

    
7159
        for (i = 0; i < 7; i++) {
7160
            env->CP0_WatchLo[i] = 0;
7161
            env->CP0_WatchHi[i] = 0x80000000;
7162
        }
7163
        env->CP0_WatchLo[7] = 0;
7164
        env->CP0_WatchHi[7] = 0;
7165
    }
7166
    /* Count register increments in debug mode, EJTAG version 1 */
7167
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7168
#endif
7169
    env->exception_index = EXCP_NONE;
7170
#if defined(CONFIG_USER_ONLY)
7171
    env->hflags = MIPS_HFLAG_UM;
7172
    env->user_mode_only = 1;
7173
#else
7174
    env->hflags = MIPS_HFLAG_CP0;
7175
#endif
7176
    cpu_mips_register(env, env->cpu_model);
7177
}
7178

    
7179
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7180
                unsigned long searched_pc, int pc_pos, void *puc)
7181
{
7182
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7183
    env->hflags &= ~MIPS_HFLAG_BMASK;
7184
    env->hflags |= gen_opc_hflags[pc_pos];
7185
}