Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d2856f1a

History | View | Annotate | Download (190.6 kB)

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

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

    
431
/* Warning: no function for r0 register (hard wired to zero) */
432
#define GEN32(func, NAME)                        \
433
static GenOpFunc *NAME ## _table [32] = {        \
434
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
435
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
436
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
437
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
438
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
439
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
440
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
441
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
442
};                                               \
443
static always_inline void func(int n)            \
444
{                                                \
445
    NAME ## _table[n]();                         \
446
}
447

    
448
/* General purpose registers moves */
449
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
450
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
451
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
452

    
453
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
454
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
455

    
456
/* Moves to/from shadow registers */
457
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
458
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
459

    
460
static const char *fregnames[] =
461
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
462
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
463
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
464
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
465

    
466
#define FGEN32(func, NAME)                       \
467
static GenOpFunc *NAME ## _table [32] = {        \
468
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
469
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
470
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
471
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
472
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
473
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
474
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
475
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
476
};                                               \
477
static always_inline void func(int n)            \
478
{                                                \
479
    NAME ## _table[n]();                         \
480
}
481

    
482
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
483
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
484

    
485
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
486
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
487

    
488
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
489
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
490

    
491
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
492
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
493

    
494
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
495
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
496

    
497
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
498
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
499

    
500
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
501
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
502

    
503
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
504
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
505

    
506
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
507
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
508

    
509
#define FOP_CONDS(type, fmt)                                            \
510
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
511
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
512
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
513
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
514
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
515
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
516
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
517
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
518
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
519
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
520
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
521
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
522
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
523
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
524
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
525
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
526
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
527
};                                                                      \
528
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
529
{                                                                       \
530
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
531
}
532

    
533
FOP_CONDS(, d)
534
FOP_CONDS(abs, d)
535
FOP_CONDS(, s)
536
FOP_CONDS(abs, s)
537
FOP_CONDS(, ps)
538
FOP_CONDS(abs, ps)
539

    
540
typedef struct DisasContext {
541
    struct TranslationBlock *tb;
542
    target_ulong pc, saved_pc;
543
    uint32_t opcode;
544
    uint32_t fp_status;
545
    /* Routine used to access memory */
546
    int mem_idx;
547
    uint32_t hflags, saved_hflags;
548
    int bstate;
549
    target_ulong btarget;
550
    void *last_T0_store;
551
    int last_T0_gpr;
552
} DisasContext;
553

    
554
enum {
555
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
556
                      * exception condition
557
                      */
558
    BS_STOP     = 1, /* We want to stop translation for any reason */
559
    BS_BRANCH   = 2, /* We reached a branch condition     */
560
    BS_EXCP     = 3, /* We reached an exception condition */
561
};
562

    
563
#ifdef MIPS_DEBUG_DISAS
564
#define MIPS_DEBUG(fmt, args...)                                              \
565
do {                                                                          \
566
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
567
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
568
                ctx->pc, ctx->opcode , ##args);                               \
569
    }                                                                         \
570
} while (0)
571
#else
572
#define MIPS_DEBUG(fmt, args...) do { } while(0)
573
#endif
574

    
575
#define MIPS_INVAL(op)                                                        \
576
do {                                                                          \
577
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
578
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
579
} while (0)
580

    
581
#define GEN_LOAD_REG_T0(Rn)                                                   \
582
do {                                                                          \
583
    if (Rn == 0) {                                                            \
584
        gen_op_reset_T0();                                                    \
585
    } else {                                                                  \
586
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
587
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
588
                gen_op_load_gpr_T0(Rn);                                       \
589
        }                                                                     \
590
    }                                                                         \
591
} while (0)
592

    
593
#define GEN_LOAD_REG_T1(Rn)                                                   \
594
do {                                                                          \
595
    if (Rn == 0) {                                                            \
596
        gen_op_reset_T1();                                                    \
597
    } else {                                                                  \
598
        gen_op_load_gpr_T1(Rn);                                               \
599
    }                                                                         \
600
} while (0)
601

    
602
#define GEN_LOAD_REG_T2(Rn)                                                   \
603
do {                                                                          \
604
    if (Rn == 0) {                                                            \
605
        gen_op_reset_T2();                                                    \
606
    } else {                                                                  \
607
        gen_op_load_gpr_T2(Rn);                                               \
608
    }                                                                         \
609
} while (0)
610

    
611
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
612
do {                                                                          \
613
    if (Rn == 0) {                                                            \
614
        glue(gen_op_reset_, Tn)();                                            \
615
    } else {                                                                  \
616
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
617
    }                                                                         \
618
} while (0)
619

    
620
#if defined(TARGET_MIPS64)
621
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
622
do {                                                                          \
623
    if (Imm == 0) {                                                           \
624
        glue(gen_op_reset_, Tn)();                                            \
625
    } else if ((int32_t)Imm == Imm) {                                         \
626
        glue(gen_op_set_, Tn)(Imm);                                           \
627
    } else {                                                                  \
628
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
629
    }                                                                         \
630
} while (0)
631
#else
632
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
633
do {                                                                          \
634
    if (Imm == 0) {                                                           \
635
        glue(gen_op_reset_, Tn)();                                            \
636
    } else {                                                                  \
637
        glue(gen_op_set_, Tn)(Imm);                                           \
638
    }                                                                         \
639
} while (0)
640
#endif
641

    
642
#define GEN_STORE_T0_REG(Rn)                                                  \
643
do {                                                                          \
644
    if (Rn != 0) {                                                            \
645
        glue(gen_op_store_T0,_gpr)(Rn);                                       \
646
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
647
        ctx->glue(last_T0,_gpr) = Rn;                                         \
648
    }                                                                         \
649
} while (0)
650

    
651
#define GEN_STORE_T1_REG(Rn)                                                  \
652
do {                                                                          \
653
    if (Rn != 0)                                                              \
654
        glue(gen_op_store_T1,_gpr)(Rn);                                       \
655
} while (0)
656

    
657
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
658
do {                                                                          \
659
    if (Rn != 0) {                                                            \
660
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
661
    }                                                                         \
662
} while (0)
663

    
664
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
665
do {                                                                          \
666
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
667
} while (0)
668

    
669
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
670
do {                                                                          \
671
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
672
} while (0)
673

    
674
static always_inline void gen_save_pc(target_ulong pc)
675
{
676
#if defined(TARGET_MIPS64)
677
    if (pc == (int32_t)pc) {
678
        gen_op_save_pc(pc);
679
    } else {
680
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
681
    }
682
#else
683
    gen_op_save_pc(pc);
684
#endif
685
}
686

    
687
static always_inline void gen_save_btarget(target_ulong btarget)
688
{
689
#if defined(TARGET_MIPS64)
690
    if (btarget == (int32_t)btarget) {
691
        gen_op_save_btarget(btarget);
692
    } else {
693
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
694
    }
695
#else
696
    gen_op_save_btarget(btarget);
697
#endif
698
}
699

    
700
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
701
{
702
#if defined MIPS_DEBUG_DISAS
703
    if (loglevel & CPU_LOG_TB_IN_ASM) {
704
            fprintf(logfile, "hflags %08x saved %08x\n",
705
                    ctx->hflags, ctx->saved_hflags);
706
    }
707
#endif
708
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
709
        gen_save_pc(ctx->pc);
710
        ctx->saved_pc = ctx->pc;
711
    }
712
    if (ctx->hflags != ctx->saved_hflags) {
713
        gen_op_save_state(ctx->hflags);
714
        ctx->saved_hflags = ctx->hflags;
715
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
716
        case MIPS_HFLAG_BR:
717
            gen_op_save_breg_target();
718
            break;
719
        case MIPS_HFLAG_BC:
720
            gen_op_save_bcond();
721
            /* fall through */
722
        case MIPS_HFLAG_BL:
723
            /* bcond was already saved by the BL insn */
724
            /* fall through */
725
        case MIPS_HFLAG_B:
726
            gen_save_btarget(ctx->btarget);
727
            break;
728
        }
729
    }
730
}
731

    
732
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
733
{
734
    ctx->saved_hflags = ctx->hflags;
735
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
736
    case MIPS_HFLAG_BR:
737
        gen_op_restore_breg_target();
738
        break;
739
    case MIPS_HFLAG_B:
740
        ctx->btarget = env->btarget;
741
        break;
742
    case MIPS_HFLAG_BC:
743
    case MIPS_HFLAG_BL:
744
        ctx->btarget = env->btarget;
745
        gen_op_restore_bcond();
746
        break;
747
    }
748
}
749

    
750
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
751
{
752
#if defined MIPS_DEBUG_DISAS
753
    if (loglevel & CPU_LOG_TB_IN_ASM)
754
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
755
#endif
756
    save_cpu_state(ctx, 1);
757
    if (err == 0)
758
        gen_op_raise_exception(excp);
759
    else
760
        gen_op_raise_exception_err(excp, err);
761
    ctx->bstate = BS_EXCP;
762
}
763

    
764
static always_inline void generate_exception (DisasContext *ctx, int excp)
765
{
766
    generate_exception_err (ctx, excp, 0);
767
}
768

    
769
static always_inline void check_cp0_enabled(DisasContext *ctx)
770
{
771
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
772
        generate_exception_err(ctx, EXCP_CpU, 1);
773
}
774

    
775
static always_inline void check_cp1_enabled(DisasContext *ctx)
776
{
777
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
778
        generate_exception_err(ctx, EXCP_CpU, 1);
779
}
780

    
781
/* Verify that the processor is running with COP1X instructions enabled.
782
   This is associated with the nabla symbol in the MIPS32 and MIPS64
783
   opcode tables.  */
784

    
785
static always_inline void check_cop1x(DisasContext *ctx)
786
{
787
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
788
        generate_exception(ctx, EXCP_RI);
789
}
790

    
791
/* Verify that the processor is running with 64-bit floating-point
792
   operations enabled.  */
793

    
794
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
795
{
796
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
797
        generate_exception(ctx, EXCP_RI);
798
}
799

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

    
817
/* This code generates a "reserved instruction" exception if the
818
   CPU does not support the instruction set corresponding to flags. */
819
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
820
{
821
    if (unlikely(!(env->insn_flags & flags)))
822
        generate_exception(ctx, EXCP_RI);
823
}
824

    
825
/* This code generates a "reserved instruction" exception if 64-bit
826
   instructions are not enabled. */
827
static always_inline void check_mips_64(DisasContext *ctx)
828
{
829
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
830
        generate_exception(ctx, EXCP_RI);
831
}
832

    
833
#if defined(CONFIG_USER_ONLY)
834
#define op_ldst(name)        gen_op_##name##_raw()
835
#define OP_LD_TABLE(width)
836
#define OP_ST_TABLE(width)
837
#else
838
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
839
#define OP_LD_TABLE(width)                                                    \
840
static GenOpFunc *gen_op_l##width[] = {                                       \
841
    &gen_op_l##width##_kernel,                                                \
842
    &gen_op_l##width##_super,                                                 \
843
    &gen_op_l##width##_user,                                                  \
844
}
845
#define OP_ST_TABLE(width)                                                    \
846
static GenOpFunc *gen_op_s##width[] = {                                       \
847
    &gen_op_s##width##_kernel,                                                \
848
    &gen_op_s##width##_super,                                                 \
849
    &gen_op_s##width##_user,                                                  \
850
}
851
#endif
852

    
853
#if defined(TARGET_MIPS64)
854
OP_LD_TABLE(d);
855
OP_LD_TABLE(dl);
856
OP_LD_TABLE(dr);
857
OP_ST_TABLE(d);
858
OP_ST_TABLE(dl);
859
OP_ST_TABLE(dr);
860
OP_LD_TABLE(ld);
861
OP_ST_TABLE(cd);
862
OP_LD_TABLE(wu);
863
#endif
864
OP_LD_TABLE(w);
865
OP_LD_TABLE(wl);
866
OP_LD_TABLE(wr);
867
OP_ST_TABLE(w);
868
OP_ST_TABLE(wl);
869
OP_ST_TABLE(wr);
870
OP_LD_TABLE(h);
871
OP_LD_TABLE(hu);
872
OP_ST_TABLE(h);
873
OP_LD_TABLE(b);
874
OP_LD_TABLE(bu);
875
OP_ST_TABLE(b);
876
OP_LD_TABLE(l);
877
OP_ST_TABLE(c);
878
OP_LD_TABLE(wc1);
879
OP_ST_TABLE(wc1);
880
OP_LD_TABLE(dc1);
881
OP_ST_TABLE(dc1);
882
OP_LD_TABLE(uxc1);
883
OP_ST_TABLE(uxc1);
884

    
885
/* Load and store */
886
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
887
                      int base, int16_t offset)
888
{
889
    const char *opn = "ldst";
890

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

    
1036
/* Load and store */
1037
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1038
                      int base, int16_t offset)
1039
{
1040
    const char *opn = "flt_ldst";
1041

    
1042
    if (base == 0) {
1043
        GEN_LOAD_IMM_TN(T0, offset);
1044
    } else if (offset == 0) {
1045
        gen_op_load_gpr_T0(base);
1046
    } else {
1047
        gen_op_load_gpr_T0(base);
1048
        gen_op_set_T1(offset);
1049
        gen_op_addr_add();
1050
    }
1051
    /* Don't do NOP if destination is zero: we must perform the actual
1052
       memory access. */
1053
    switch (opc) {
1054
    case OPC_LWC1:
1055
        op_ldst(lwc1);
1056
        GEN_STORE_FTN_FREG(ft, WT0);
1057
        opn = "lwc1";
1058
        break;
1059
    case OPC_SWC1:
1060
        GEN_LOAD_FREG_FTN(WT0, ft);
1061
        op_ldst(swc1);
1062
        opn = "swc1";
1063
        break;
1064
    case OPC_LDC1:
1065
        op_ldst(ldc1);
1066
        GEN_STORE_FTN_FREG(ft, DT0);
1067
        opn = "ldc1";
1068
        break;
1069
    case OPC_SDC1:
1070
        GEN_LOAD_FREG_FTN(DT0, ft);
1071
        op_ldst(sdc1);
1072
        opn = "sdc1";
1073
        break;
1074
    default:
1075
        MIPS_INVAL(opn);
1076
        generate_exception(ctx, EXCP_RI);
1077
        return;
1078
    }
1079
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1080
}
1081

    
1082
/* Arithmetic with immediate operand */
1083
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1084
                           int rt, int rs, int16_t imm)
1085
{
1086
    target_ulong uimm;
1087
    const char *opn = "imm arith";
1088

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

    
1277
/* Arithmetic */
1278
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1279
                       int rd, int rs, int rt)
1280
{
1281
    const char *opn = "arith";
1282

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

    
1445
/* Arithmetic on HI/LO registers */
1446
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1447
{
1448
    const char *opn = "hilo";
1449

    
1450
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1451
        /* Treat as NOP. */
1452
        MIPS_DEBUG("NOP");
1453
        return;
1454
    }
1455
    switch (opc) {
1456
    case OPC_MFHI:
1457
        gen_op_load_HI(0);
1458
        GEN_STORE_T0_REG(reg);
1459
        opn = "mfhi";
1460
        break;
1461
    case OPC_MFLO:
1462
        gen_op_load_LO(0);
1463
        GEN_STORE_T0_REG(reg);
1464
        opn = "mflo";
1465
        break;
1466
    case OPC_MTHI:
1467
        GEN_LOAD_REG_T0(reg);
1468
        gen_op_store_HI(0);
1469
        opn = "mthi";
1470
        break;
1471
    case OPC_MTLO:
1472
        GEN_LOAD_REG_T0(reg);
1473
        gen_op_store_LO(0);
1474
        opn = "mtlo";
1475
        break;
1476
    default:
1477
        MIPS_INVAL(opn);
1478
        generate_exception(ctx, EXCP_RI);
1479
        return;
1480
    }
1481
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1482
}
1483

    
1484
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1485
                        int rs, int rt)
1486
{
1487
    const char *opn = "mul/div";
1488

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

    
1550
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1551
                            int rd, int rs, int rt)
1552
{
1553
    const char *opn = "mul vr54xx";
1554

    
1555
    GEN_LOAD_REG_T0(rs);
1556
    GEN_LOAD_REG_T1(rt);
1557

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

    
1624
static void gen_cl (DisasContext *ctx, uint32_t opc,
1625
                    int rd, int rs)
1626
{
1627
    const char *opn = "CLx";
1628
    if (rd == 0) {
1629
        /* Treat as NOP. */
1630
        MIPS_DEBUG("NOP");
1631
        return;
1632
    }
1633
    GEN_LOAD_REG_T0(rs);
1634
    switch (opc) {
1635
    case OPC_CLO:
1636
        gen_op_clo();
1637
        opn = "clo";
1638
        break;
1639
    case OPC_CLZ:
1640
        gen_op_clz();
1641
        opn = "clz";
1642
        break;
1643
#if defined(TARGET_MIPS64)
1644
    case OPC_DCLO:
1645
        gen_op_dclo();
1646
        opn = "dclo";
1647
        break;
1648
    case OPC_DCLZ:
1649
        gen_op_dclz();
1650
        opn = "dclz";
1651
        break;
1652
#endif
1653
    default:
1654
        MIPS_INVAL(opn);
1655
        generate_exception(ctx, EXCP_RI);
1656
        return;
1657
    }
1658
    gen_op_store_T0_gpr(rd);
1659
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1660
}
1661

    
1662
/* Traps */
1663
static void gen_trap (DisasContext *ctx, uint32_t opc,
1664
                      int rs, int rt, int16_t imm)
1665
{
1666
    int cond;
1667

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

    
1759
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1760
{
1761
    TranslationBlock *tb;
1762
    tb = ctx->tb;
1763
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1764
        tcg_gen_goto_tb(n);
1765
        gen_save_pc(dest);
1766
        tcg_gen_exit_tb((long)tb + n);
1767
    } else {
1768
        gen_save_pc(dest);
1769
        tcg_gen_exit_tb(0);
1770
    }
1771
}
1772

    
1773
/* Branches (before delay slot) */
1774
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1775
                                int rs, int rt, int32_t offset)
1776
{
1777
    target_ulong btarget = -1;
1778
    int blink = 0;
1779
    int bcond = 0;
1780

    
1781
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1782
#ifdef MIPS_DEBUG_DISAS
1783
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1784
            fprintf(logfile,
1785
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1786
                    ctx->pc);
1787
        }
1788
#endif
1789
        generate_exception(ctx, EXCP_RI);
1790
        return;
1791
    }
1792

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

    
2006
    ctx->btarget = btarget;
2007
    if (blink > 0) {
2008
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2009
        gen_op_store_T0_gpr(blink);
2010
    }
2011
}
2012

    
2013
/* special3 bitfield operations */
2014
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2015
                       int rs, int lsb, int msb)
2016
{
2017
    GEN_LOAD_REG_T1(rs);
2018
    switch (opc) {
2019
    case OPC_EXT:
2020
        if (lsb + msb > 31)
2021
            goto fail;
2022
        gen_op_ext(lsb, msb + 1);
2023
        break;
2024
#if defined(TARGET_MIPS64)
2025
    case OPC_DEXTM:
2026
        if (lsb + msb > 63)
2027
            goto fail;
2028
        gen_op_dext(lsb, msb + 1 + 32);
2029
        break;
2030
    case OPC_DEXTU:
2031
        if (lsb + msb > 63)
2032
            goto fail;
2033
        gen_op_dext(lsb + 32, msb + 1);
2034
        break;
2035
    case OPC_DEXT:
2036
        if (lsb + msb > 63)
2037
            goto fail;
2038
        gen_op_dext(lsb, msb + 1);
2039
        break;
2040
#endif
2041
    case OPC_INS:
2042
        if (lsb > msb)
2043
            goto fail;
2044
        GEN_LOAD_REG_T0(rt);
2045
        gen_op_ins(lsb, msb - lsb + 1);
2046
        break;
2047
#if defined(TARGET_MIPS64)
2048
    case OPC_DINSM:
2049
        if (lsb > msb)
2050
            goto fail;
2051
        GEN_LOAD_REG_T0(rt);
2052
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2053
        break;
2054
    case OPC_DINSU:
2055
        if (lsb > msb)
2056
            goto fail;
2057
        GEN_LOAD_REG_T0(rt);
2058
        gen_op_dins(lsb + 32, msb - lsb + 1);
2059
        break;
2060
    case OPC_DINS:
2061
        if (lsb > msb)
2062
            goto fail;
2063
        GEN_LOAD_REG_T0(rt);
2064
        gen_op_dins(lsb, msb - lsb + 1);
2065
        break;
2066
#endif
2067
    default:
2068
fail:
2069
        MIPS_INVAL("bitops");
2070
        generate_exception(ctx, EXCP_RI);
2071
        return;
2072
    }
2073
    GEN_STORE_T0_REG(rt);
2074
}
2075

    
2076
/* CP0 (MMU and control) */
2077
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2078
{
2079
    const char *rn = "invalid";
2080

    
2081
    if (sel != 0)
2082
        check_insn(env, ctx, ISA_MIPS32);
2083

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

    
2635
die:
2636
#if defined MIPS_DEBUG_DISAS
2637
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2638
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2639
                rn, reg, sel);
2640
    }
2641
#endif
2642
    generate_exception(ctx, EXCP_RI);
2643
}
2644

    
2645
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2646
{
2647
    const char *rn = "invalid";
2648

    
2649
    if (sel != 0)
2650
        check_insn(env, ctx, ISA_MIPS32);
2651

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

    
3234
die:
3235
#if defined MIPS_DEBUG_DISAS
3236
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3237
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3238
                rn, reg, sel);
3239
    }
3240
#endif
3241
    generate_exception(ctx, EXCP_RI);
3242
}
3243

    
3244
#if defined(TARGET_MIPS64)
3245
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3246
{
3247
    const char *rn = "invalid";
3248

    
3249
    if (sel != 0)
3250
        check_insn(env, ctx, ISA_MIPS64);
3251

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

    
3792
die:
3793
#if defined MIPS_DEBUG_DISAS
3794
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3795
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3796
                rn, reg, sel);
3797
    }
3798
#endif
3799
    generate_exception(ctx, EXCP_RI);
3800
}
3801

    
3802
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3803
{
3804
    const char *rn = "invalid";
3805

    
3806
    if (sel != 0)
3807
        check_insn(env, ctx, ISA_MIPS64);
3808

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

    
4378
die:
4379
#if defined MIPS_DEBUG_DISAS
4380
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4381
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4382
                rn, reg, sel);
4383
    }
4384
#endif
4385
    generate_exception(ctx, EXCP_RI);
4386
}
4387
#endif /* TARGET_MIPS64 */
4388

    
4389
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4390
                     int u, int sel, int h)
4391
{
4392
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4393

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

    
4543
die:
4544
#if defined MIPS_DEBUG_DISAS
4545
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4546
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4547
                rt, u, sel, h);
4548
    }
4549
#endif
4550
    generate_exception(ctx, EXCP_RI);
4551
}
4552

    
4553
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4554
                     int u, int sel, int h)
4555
{
4556
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4557

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

    
4707
die:
4708
#if defined MIPS_DEBUG_DISAS
4709
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4710
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4711
                rd, u, sel, h);
4712
    }
4713
#endif
4714
    generate_exception(ctx, EXCP_RI);
4715
}
4716

    
4717
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4718
{
4719
    const char *opn = "ldst";
4720

    
4721
    switch (opc) {
4722
    case OPC_MFC0:
4723
        if (rt == 0) {
4724
            /* Treat as NOP. */
4725
            return;
4726
        }
4727
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4728
        gen_op_store_T0_gpr(rt);
4729
        opn = "mfc0";
4730
        break;
4731
    case OPC_MTC0:
4732
        GEN_LOAD_REG_T0(rt);
4733
        save_cpu_state(ctx, 1);
4734
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4735
        opn = "mtc0";
4736
        break;
4737
#if defined(TARGET_MIPS64)
4738
    case OPC_DMFC0:
4739
        check_insn(env, ctx, ISA_MIPS3);
4740
        if (rt == 0) {
4741
            /* Treat as NOP. */
4742
            return;
4743
        }
4744
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4745
        gen_op_store_T0_gpr(rt);
4746
        opn = "dmfc0";
4747
        break;
4748
    case OPC_DMTC0:
4749
        check_insn(env, ctx, ISA_MIPS3);
4750
        GEN_LOAD_REG_T0(rt);
4751
        save_cpu_state(ctx, 1);
4752
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4753
        opn = "dmtc0";
4754
        break;
4755
#endif
4756
    case OPC_MFTR:
4757
        check_insn(env, ctx, ASE_MT);
4758
        if (rd == 0) {
4759
            /* Treat as NOP. */
4760
            return;
4761
        }
4762
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4763
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4764
        gen_op_store_T0_gpr(rd);
4765
        opn = "mftr";
4766
        break;
4767
    case OPC_MTTR:
4768
        check_insn(env, ctx, ASE_MT);
4769
        GEN_LOAD_REG_T0(rt);
4770
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4771
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4772
        opn = "mttr";
4773
        break;
4774
    case OPC_TLBWI:
4775
        opn = "tlbwi";
4776
        if (!env->tlb->do_tlbwi)
4777
            goto die;
4778
        gen_op_tlbwi();
4779
        break;
4780
    case OPC_TLBWR:
4781
        opn = "tlbwr";
4782
        if (!env->tlb->do_tlbwr)
4783
            goto die;
4784
        gen_op_tlbwr();
4785
        break;
4786
    case OPC_TLBP:
4787
        opn = "tlbp";
4788
        if (!env->tlb->do_tlbp)
4789
            goto die;
4790
        gen_op_tlbp();
4791
        break;
4792
    case OPC_TLBR:
4793
        opn = "tlbr";
4794
        if (!env->tlb->do_tlbr)
4795
            goto die;
4796
        gen_op_tlbr();
4797
        break;
4798
    case OPC_ERET:
4799
        opn = "eret";
4800
        check_insn(env, ctx, ISA_MIPS2);
4801
        save_cpu_state(ctx, 1);
4802
        gen_op_eret();
4803
        ctx->bstate = BS_EXCP;
4804
        break;
4805
    case OPC_DERET:
4806
        opn = "deret";
4807
        check_insn(env, ctx, ISA_MIPS32);
4808
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4809
            MIPS_INVAL(opn);
4810
            generate_exception(ctx, EXCP_RI);
4811
        } else {
4812
            save_cpu_state(ctx, 1);
4813
            gen_op_deret();
4814
            ctx->bstate = BS_EXCP;
4815
        }
4816
        break;
4817
    case OPC_WAIT:
4818
        opn = "wait";
4819
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4820
        /* If we get an exception, we want to restart at next instruction */
4821
        ctx->pc += 4;
4822
        save_cpu_state(ctx, 1);
4823
        ctx->pc -= 4;
4824
        gen_op_wait();
4825
        ctx->bstate = BS_EXCP;
4826
        break;
4827
    default:
4828
 die:
4829
        MIPS_INVAL(opn);
4830
        generate_exception(ctx, EXCP_RI);
4831
        return;
4832
    }
4833
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4834
}
4835

    
4836
/* CP1 Branches (before delay slot) */
4837
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4838
                                 int32_t cc, int32_t offset)
4839
{
4840
    target_ulong btarget;
4841
    const char *opn = "cp1 cond branch";
4842

    
4843
    if (cc != 0)
4844
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4845

    
4846
    btarget = ctx->pc + 4 + offset;
4847

    
4848
    switch (op) {
4849
    case OPC_BC1F:
4850
        gen_op_bc1f(cc);
4851
        opn = "bc1f";
4852
        goto not_likely;
4853
    case OPC_BC1FL:
4854
        gen_op_bc1f(cc);
4855
        opn = "bc1fl";
4856
        goto likely;
4857
    case OPC_BC1T:
4858
        gen_op_bc1t(cc);
4859
        opn = "bc1t";
4860
        goto not_likely;
4861
    case OPC_BC1TL:
4862
        gen_op_bc1t(cc);
4863
        opn = "bc1tl";
4864
    likely:
4865
        ctx->hflags |= MIPS_HFLAG_BL;
4866
        gen_op_set_bcond();
4867
        gen_op_save_bcond();
4868
        break;
4869
    case OPC_BC1FANY2:
4870
        gen_op_bc1any2f(cc);
4871
        opn = "bc1any2f";
4872
        goto not_likely;
4873
    case OPC_BC1TANY2:
4874
        gen_op_bc1any2t(cc);
4875
        opn = "bc1any2t";
4876
        goto not_likely;
4877
    case OPC_BC1FANY4:
4878
        gen_op_bc1any4f(cc);
4879
        opn = "bc1any4f";
4880
        goto not_likely;
4881
    case OPC_BC1TANY4:
4882
        gen_op_bc1any4t(cc);
4883
        opn = "bc1any4t";
4884
    not_likely:
4885
        ctx->hflags |= MIPS_HFLAG_BC;
4886
        gen_op_set_bcond();
4887
        break;
4888
    default:
4889
        MIPS_INVAL(opn);
4890
        generate_exception (ctx, EXCP_RI);
4891
        return;
4892
    }
4893
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4894
               ctx->hflags, btarget);
4895
    ctx->btarget = btarget;
4896
}
4897

    
4898
/* Coprocessor 1 (FPU) */
4899

    
4900
#define FOP(func, fmt) (((fmt) << 21) | (func))
4901

    
4902
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4903
{
4904
    const char *opn = "cp1 move";
4905

    
4906
    switch (opc) {
4907
    case OPC_MFC1:
4908
        GEN_LOAD_FREG_FTN(WT0, fs);
4909
        gen_op_mfc1();
4910
        GEN_STORE_T0_REG(rt);
4911
        opn = "mfc1";
4912
        break;
4913
    case OPC_MTC1:
4914
        GEN_LOAD_REG_T0(rt);
4915
        gen_op_mtc1();
4916
        GEN_STORE_FTN_FREG(fs, WT0);
4917
        opn = "mtc1";
4918
        break;
4919
    case OPC_CFC1:
4920
        gen_op_cfc1(fs);
4921
        GEN_STORE_T0_REG(rt);
4922
        opn = "cfc1";
4923
        break;
4924
    case OPC_CTC1:
4925
        GEN_LOAD_REG_T0(rt);
4926
        gen_op_ctc1(fs);
4927
        opn = "ctc1";
4928
        break;
4929
    case OPC_DMFC1:
4930
        GEN_LOAD_FREG_FTN(DT0, fs);
4931
        gen_op_dmfc1();
4932
        GEN_STORE_T0_REG(rt);
4933
        opn = "dmfc1";
4934
        break;
4935
    case OPC_DMTC1:
4936
        GEN_LOAD_REG_T0(rt);
4937
        gen_op_dmtc1();
4938
        GEN_STORE_FTN_FREG(fs, DT0);
4939
        opn = "dmtc1";
4940
        break;
4941
    case OPC_MFHC1:
4942
        GEN_LOAD_FREG_FTN(WTH0, fs);
4943
        gen_op_mfhc1();
4944
        GEN_STORE_T0_REG(rt);
4945
        opn = "mfhc1";
4946
        break;
4947
    case OPC_MTHC1:
4948
        GEN_LOAD_REG_T0(rt);
4949
        gen_op_mthc1();
4950
        GEN_STORE_FTN_FREG(fs, WTH0);
4951
        opn = "mthc1";
4952
        break;
4953
    default:
4954
        MIPS_INVAL(opn);
4955
        generate_exception (ctx, EXCP_RI);
4956
        return;
4957
    }
4958
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4959
}
4960

    
4961
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4962
{
4963
    uint32_t ccbit;
4964

    
4965
    GEN_LOAD_REG_T0(rd);
4966
    GEN_LOAD_REG_T1(rs);
4967
    if (cc) {
4968
        ccbit = 1 << (24 + cc);
4969
    } else
4970
        ccbit = 1 << 23;
4971
    if (!tf)
4972
        gen_op_movf(ccbit);
4973
    else
4974
        gen_op_movt(ccbit);
4975
    GEN_STORE_T0_REG(rd);
4976
}
4977

    
4978
#define GEN_MOVCF(fmt)                                                \
4979
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4980
{                                                                     \
4981
    uint32_t ccbit;                                                   \
4982
                                                                      \
4983
    if (cc) {                                                         \
4984
        ccbit = 1 << (24 + cc);                                       \
4985
    } else                                                            \
4986
        ccbit = 1 << 23;                                              \
4987
    if (!tf)                                                          \
4988
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4989
    else                                                              \
4990
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4991
}
4992
GEN_MOVCF(d);
4993
GEN_MOVCF(s);
4994
GEN_MOVCF(ps);
4995
#undef GEN_MOVCF
4996

    
4997
static void gen_farith (DisasContext *ctx, uint32_t op1,
4998
                        int ft, int fs, int fd, int cc)
4999
{
5000
    const char *opn = "farith";
5001
    const char *condnames[] = {
5002
            "c.f",
5003
            "c.un",
5004
            "c.eq",
5005
            "c.ueq",
5006
            "c.olt",
5007
            "c.ult",
5008
            "c.ole",
5009
            "c.ule",
5010
            "c.sf",
5011
            "c.ngle",
5012
            "c.seq",
5013
            "c.ngl",
5014
            "c.lt",
5015
            "c.nge",
5016
            "c.le",
5017
            "c.ngt",
5018
    };
5019
    const char *condnames_abs[] = {
5020
            "cabs.f",
5021
            "cabs.un",
5022
            "cabs.eq",
5023
            "cabs.ueq",
5024
            "cabs.olt",
5025
            "cabs.ult",
5026
            "cabs.ole",
5027
            "cabs.ule",
5028
            "cabs.sf",
5029
            "cabs.ngle",
5030
            "cabs.seq",
5031
            "cabs.ngl",
5032
            "cabs.lt",
5033
            "cabs.nge",
5034
            "cabs.le",
5035
            "cabs.ngt",
5036
    };
5037
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5038
    uint32_t func = ctx->opcode & 0x3f;
5039

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

    
5806
/* Coprocessor 3 (FPU) */
5807
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5808
                           int fd, int fs, int base, int index)
5809
{
5810
    const char *opn = "extended float load/store";
5811
    int store = 0;
5812

    
5813
    if (base == 0) {
5814
        if (index == 0)
5815
            gen_op_reset_T0();
5816
        else
5817
            GEN_LOAD_REG_T0(index);
5818
    } else if (index == 0) {
5819
        GEN_LOAD_REG_T0(base);
5820
    } else {
5821
        GEN_LOAD_REG_T0(base);
5822
        GEN_LOAD_REG_T1(index);
5823
        gen_op_addr_add();
5824
    }
5825
    /* Don't do NOP if destination is zero: we must perform the actual
5826
       memory access. */
5827
    switch (opc) {
5828
    case OPC_LWXC1:
5829
        check_cop1x(ctx);
5830
        op_ldst(lwc1);
5831
        GEN_STORE_FTN_FREG(fd, WT0);
5832
        opn = "lwxc1";
5833
        break;
5834
    case OPC_LDXC1:
5835
        check_cop1x(ctx);
5836
        check_cp1_registers(ctx, fd);
5837
        op_ldst(ldc1);
5838
        GEN_STORE_FTN_FREG(fd, DT0);
5839
        opn = "ldxc1";
5840
        break;
5841
    case OPC_LUXC1:
5842
        check_cp1_64bitmode(ctx);
5843
        op_ldst(luxc1);
5844
        GEN_STORE_FTN_FREG(fd, DT0);
5845
        opn = "luxc1";
5846
        break;
5847
    case OPC_SWXC1:
5848
        check_cop1x(ctx);
5849
        GEN_LOAD_FREG_FTN(WT0, fs);
5850
        op_ldst(swc1);
5851
        opn = "swxc1";
5852
        store = 1;
5853
        break;
5854
    case OPC_SDXC1:
5855
        check_cop1x(ctx);
5856
        check_cp1_registers(ctx, fs);
5857
        GEN_LOAD_FREG_FTN(DT0, fs);
5858
        op_ldst(sdc1);
5859
        opn = "sdxc1";
5860
        store = 1;
5861
        break;
5862
    case OPC_SUXC1:
5863
        check_cp1_64bitmode(ctx);
5864
        GEN_LOAD_FREG_FTN(DT0, fs);
5865
        op_ldst(suxc1);
5866
        opn = "suxc1";
5867
        store = 1;
5868
        break;
5869
    default:
5870
        MIPS_INVAL(opn);
5871
        generate_exception(ctx, EXCP_RI);
5872
        return;
5873
    }
5874
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5875
               regnames[index], regnames[base]);
5876
}
5877

    
5878
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5879
                            int fd, int fr, int fs, int ft)
5880
{
5881
    const char *opn = "flt3_arith";
5882

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

    
6030
/* ISA extensions (ASEs) */
6031
/* MIPS16 extension to MIPS32 */
6032
/* SmartMIPS extension to MIPS32 */
6033

    
6034
#if defined(TARGET_MIPS64)
6035

    
6036
/* MDMX extension to MIPS64 */
6037

    
6038
#endif
6039

    
6040
static void decode_opc (CPUState *env, DisasContext *ctx)
6041
{
6042
    int32_t offset;
6043
    int rs, rt, rd, sa;
6044
    uint32_t op, op1, op2;
6045
    int16_t imm;
6046

    
6047
    /* make sure instructions are on a word boundary */
6048
    if (ctx->pc & 0x3) {
6049
        env->CP0_BadVAddr = ctx->pc;
6050
        generate_exception(ctx, EXCP_AdEL);
6051
        return;
6052
    }
6053

    
6054
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6055
        int l1;
6056
        /* Handle blikely not taken case */
6057
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6058
        l1 = gen_new_label();
6059
        gen_op_jnz_T2(l1);
6060
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6061
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6062
        gen_set_label(l1);
6063
    }
6064
    op = MASK_OP_MAJOR(ctx->opcode);
6065
    rs = (ctx->opcode >> 21) & 0x1f;
6066
    rt = (ctx->opcode >> 16) & 0x1f;
6067
    rd = (ctx->opcode >> 11) & 0x1f;
6068
    sa = (ctx->opcode >> 6) & 0x1f;
6069
    imm = (int16_t)ctx->opcode;
6070
    switch (op) {
6071
    case OPC_SPECIAL:
6072
        op1 = MASK_SPECIAL(ctx->opcode);
6073
        switch (op1) {
6074
        case OPC_SLL:          /* Arithmetic with immediate */
6075
        case OPC_SRL ... OPC_SRA:
6076
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6077
            break;
6078
        case OPC_MOVZ ... OPC_MOVN:
6079
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6080
        case OPC_SLLV:         /* Arithmetic */
6081
        case OPC_SRLV ... OPC_SRAV:
6082
        case OPC_ADD ... OPC_NOR:
6083
        case OPC_SLT ... OPC_SLTU:
6084
            gen_arith(env, ctx, op1, rd, rs, rt);
6085
            break;
6086
        case OPC_MULT ... OPC_DIVU:
6087
            if (sa) {
6088
                check_insn(env, ctx, INSN_VR54XX);
6089
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6090
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6091
            } else
6092
                gen_muldiv(ctx, op1, rs, rt);
6093
            break;
6094
        case OPC_JR ... OPC_JALR:
6095
            gen_compute_branch(ctx, op1, rs, rd, sa);
6096
            return;
6097
        case OPC_TGE ... OPC_TEQ: /* Traps */
6098
        case OPC_TNE:
6099
            gen_trap(ctx, op1, rs, rt, -1);
6100
            break;
6101
        case OPC_MFHI:          /* Move from HI/LO */
6102
        case OPC_MFLO:
6103
            gen_HILO(ctx, op1, rd);
6104
            break;
6105
        case OPC_MTHI:
6106
        case OPC_MTLO:          /* Move to HI/LO */
6107
            gen_HILO(ctx, op1, rs);
6108
            break;
6109
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6110
#ifdef MIPS_STRICT_STANDARD
6111
            MIPS_INVAL("PMON / selsl");
6112
            generate_exception(ctx, EXCP_RI);
6113
#else
6114
            gen_op_pmon(sa);
6115
#endif
6116
            break;
6117
        case OPC_SYSCALL:
6118
            generate_exception(ctx, EXCP_SYSCALL);
6119
            break;
6120
        case OPC_BREAK:
6121
            generate_exception(ctx, EXCP_BREAK);
6122
            break;
6123
        case OPC_SPIM:
6124
#ifdef MIPS_STRICT_STANDARD
6125
            MIPS_INVAL("SPIM");
6126
            generate_exception(ctx, EXCP_RI);
6127
#else
6128
           /* Implemented as RI exception for now. */
6129
            MIPS_INVAL("spim (unofficial)");
6130
            generate_exception(ctx, EXCP_RI);
6131
#endif
6132
            break;
6133
        case OPC_SYNC:
6134
            /* Treat as NOP. */
6135
            break;
6136

    
6137
        case OPC_MOVCI:
6138
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6139
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6140
                save_cpu_state(ctx, 1);
6141
                check_cp1_enabled(ctx);
6142
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6143
                          (ctx->opcode >> 16) & 1);
6144
            } else {
6145
                generate_exception_err(ctx, EXCP_CpU, 1);
6146
            }
6147
            break;
6148

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

    
6447
    /* Floating point (COP1). */
6448
    case OPC_LWC1:
6449
    case OPC_LDC1:
6450
    case OPC_SWC1:
6451
    case OPC_SDC1:
6452
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6453
            save_cpu_state(ctx, 1);
6454
            check_cp1_enabled(ctx);
6455
            gen_flt_ldst(ctx, op, rt, rs, imm);
6456
        } else {
6457
            generate_exception_err(ctx, EXCP_CpU, 1);
6458
        }
6459
        break;
6460

    
6461
    case OPC_CP1:
6462
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6463
            save_cpu_state(ctx, 1);
6464
            check_cp1_enabled(ctx);
6465
            op1 = MASK_CP1(ctx->opcode);
6466
            switch (op1) {
6467
            case OPC_MFHC1:
6468
            case OPC_MTHC1:
6469
                check_insn(env, ctx, ISA_MIPS32R2);
6470
            case OPC_MFC1:
6471
            case OPC_CFC1:
6472
            case OPC_MTC1:
6473
            case OPC_CTC1:
6474
                gen_cp1(ctx, op1, rt, rd);
6475
                break;
6476
#if defined(TARGET_MIPS64)
6477
            case OPC_DMFC1:
6478
            case OPC_DMTC1:
6479
                check_insn(env, ctx, ISA_MIPS3);
6480
                gen_cp1(ctx, op1, rt, rd);
6481
                break;
6482
#endif
6483
            case OPC_BC1ANY2:
6484
            case OPC_BC1ANY4:
6485
                check_cop1x(ctx);
6486
                check_insn(env, ctx, ASE_MIPS3D);
6487
                /* fall through */
6488
            case OPC_BC1:
6489
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6490
                                    (rt >> 2) & 0x7, imm << 2);
6491
                return;
6492
            case OPC_S_FMT:
6493
            case OPC_D_FMT:
6494
            case OPC_W_FMT:
6495
            case OPC_L_FMT:
6496
            case OPC_PS_FMT:
6497
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6498
                           (imm >> 8) & 0x7);
6499
                break;
6500
            default:
6501
                MIPS_INVAL("cp1");
6502
                generate_exception (ctx, EXCP_RI);
6503
                break;
6504
            }
6505
        } else {
6506
            generate_exception_err(ctx, EXCP_CpU, 1);
6507
        }
6508
        break;
6509

    
6510
    /* COP2.  */
6511
    case OPC_LWC2:
6512
    case OPC_LDC2:
6513
    case OPC_SWC2:
6514
    case OPC_SDC2:
6515
    case OPC_CP2:
6516
        /* COP2: Not implemented. */
6517
        generate_exception_err(ctx, EXCP_CpU, 2);
6518
        break;
6519

    
6520
    case OPC_CP3:
6521
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6522
            save_cpu_state(ctx, 1);
6523
            check_cp1_enabled(ctx);
6524
            op1 = MASK_CP3(ctx->opcode);
6525
            switch (op1) {
6526
            case OPC_LWXC1:
6527
            case OPC_LDXC1:
6528
            case OPC_LUXC1:
6529
            case OPC_SWXC1:
6530
            case OPC_SDXC1:
6531
            case OPC_SUXC1:
6532
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6533
                break;
6534
            case OPC_PREFX:
6535
                /* Treat as NOP. */
6536
                break;
6537
            case OPC_ALNV_PS:
6538
            case OPC_MADD_S:
6539
            case OPC_MADD_D:
6540
            case OPC_MADD_PS:
6541
            case OPC_MSUB_S:
6542
            case OPC_MSUB_D:
6543
            case OPC_MSUB_PS:
6544
            case OPC_NMADD_S:
6545
            case OPC_NMADD_D:
6546
            case OPC_NMADD_PS:
6547
            case OPC_NMSUB_S:
6548
            case OPC_NMSUB_D:
6549
            case OPC_NMSUB_PS:
6550
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6551
                break;
6552
            default:
6553
                MIPS_INVAL("cp3");
6554
                generate_exception (ctx, EXCP_RI);
6555
                break;
6556
            }
6557
        } else {
6558
            generate_exception_err(ctx, EXCP_CpU, 1);
6559
        }
6560
        break;
6561

    
6562
#if defined(TARGET_MIPS64)
6563
    /* MIPS64 opcodes */
6564
    case OPC_LWU:
6565
    case OPC_LDL ... OPC_LDR:
6566
    case OPC_SDL ... OPC_SDR:
6567
    case OPC_LLD:
6568
    case OPC_LD:
6569
    case OPC_SCD:
6570
    case OPC_SD:
6571
        check_insn(env, ctx, ISA_MIPS3);
6572
        check_mips_64(ctx);
6573
        gen_ldst(ctx, op, rt, rs, imm);
6574
        break;
6575
    case OPC_DADDI ... OPC_DADDIU:
6576
        check_insn(env, ctx, ISA_MIPS3);
6577
        check_mips_64(ctx);
6578
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6579
        break;
6580
#endif
6581
    case OPC_JALX:
6582
        check_insn(env, ctx, ASE_MIPS16);
6583
        /* MIPS16: Not implemented. */
6584
    case OPC_MDMX:
6585
        check_insn(env, ctx, ASE_MDMX);
6586
        /* MDMX: Not implemented. */
6587
    default:            /* Invalid */
6588
        MIPS_INVAL("major opcode");
6589
        generate_exception(ctx, EXCP_RI);
6590
        break;
6591
    }
6592
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6593
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6594
        /* Branches completion */
6595
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6596
        ctx->bstate = BS_BRANCH;
6597
        save_cpu_state(ctx, 0);
6598
        switch (hflags) {
6599
        case MIPS_HFLAG_B:
6600
            /* unconditional branch */
6601
            MIPS_DEBUG("unconditional branch");
6602
            gen_goto_tb(ctx, 0, ctx->btarget);
6603
            break;
6604
        case MIPS_HFLAG_BL:
6605
            /* blikely taken case */
6606
            MIPS_DEBUG("blikely branch taken");
6607
            gen_goto_tb(ctx, 0, ctx->btarget);
6608
            break;
6609
        case MIPS_HFLAG_BC:
6610
            /* Conditional branch */
6611
            MIPS_DEBUG("conditional branch");
6612
            {
6613
              int l1;
6614
              l1 = gen_new_label();
6615
              gen_op_jnz_T2(l1);
6616
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6617
              gen_set_label(l1);
6618
              gen_goto_tb(ctx, 0, ctx->btarget);
6619
            }
6620
            break;
6621
        case MIPS_HFLAG_BR:
6622
            /* unconditional branch to register */
6623
            MIPS_DEBUG("branch to register");
6624
            gen_op_breg();
6625
            tcg_gen_exit_tb(0);
6626
            break;
6627
        default:
6628
            MIPS_DEBUG("unknown branch");
6629
            break;
6630
        }
6631
    }
6632
}
6633

    
6634
static always_inline int
6635
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6636
                                int search_pc)
6637
{
6638
    DisasContext ctx;
6639
    target_ulong pc_start;
6640
    uint16_t *gen_opc_end;
6641
    int j, lj = -1;
6642

    
6643
    if (search_pc && loglevel)
6644
        fprintf (logfile, "search pc %d\n", search_pc);
6645

    
6646
    pc_start = tb->pc;
6647
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6648
    ctx.pc = pc_start;
6649
    ctx.saved_pc = -1;
6650
    ctx.tb = tb;
6651
    ctx.bstate = BS_NONE;
6652
    /* Restore delay slot state from the tb context.  */
6653
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6654
    restore_cpu_state(env, &ctx);
6655
#if defined(CONFIG_USER_ONLY)
6656
    ctx.mem_idx = MIPS_HFLAG_UM;
6657
#else
6658
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6659
#endif
6660
#ifdef DEBUG_DISAS
6661
    if (loglevel & CPU_LOG_TB_CPU) {
6662
        fprintf(logfile, "------------------------------------------------\n");
6663
        /* FIXME: This may print out stale hflags from env... */
6664
        cpu_dump_state(env, logfile, fprintf, 0);
6665
    }
6666
#endif
6667
#ifdef MIPS_DEBUG_DISAS
6668
    if (loglevel & CPU_LOG_TB_IN_ASM)
6669
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6670
                tb, ctx.mem_idx, ctx.hflags);
6671
#endif
6672
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6673
        if (env->nb_breakpoints > 0) {
6674
            for(j = 0; j < env->nb_breakpoints; j++) {
6675
                if (env->breakpoints[j] == ctx.pc) {
6676
                    save_cpu_state(&ctx, 1);
6677
                    ctx.bstate = BS_BRANCH;
6678
                    gen_op_debug();
6679
                    /* Include the breakpoint location or the tb won't
6680
                     * be flushed when it must be.  */
6681
                    ctx.pc += 4;
6682
                    goto done_generating;
6683
                }
6684
            }
6685
        }
6686

    
6687
        if (search_pc) {
6688
            j = gen_opc_ptr - gen_opc_buf;
6689
            if (lj < j) {
6690
                lj++;
6691
                while (lj < j)
6692
                    gen_opc_instr_start[lj++] = 0;
6693
            }
6694
            gen_opc_pc[lj] = ctx.pc;
6695
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6696
            gen_opc_instr_start[lj] = 1;
6697
        }
6698
        ctx.opcode = ldl_code(ctx.pc);
6699
        decode_opc(env, &ctx);
6700
        ctx.pc += 4;
6701

    
6702
        if (env->singlestep_enabled)
6703
            break;
6704

    
6705
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6706
            break;
6707

    
6708
#if defined (MIPS_SINGLE_STEP)
6709
        break;
6710
#endif
6711
    }
6712
    if (env->singlestep_enabled) {
6713
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6714
        gen_op_debug();
6715
    } else {
6716
        switch (ctx.bstate) {
6717
        case BS_STOP:
6718
            gen_op_interrupt_restart();
6719
            gen_goto_tb(&ctx, 0, ctx.pc);
6720
            break;
6721
        case BS_NONE:
6722
            save_cpu_state(&ctx, 0);
6723
            gen_goto_tb(&ctx, 0, ctx.pc);
6724
            break;
6725
        case BS_EXCP:
6726
            gen_op_interrupt_restart();
6727
            tcg_gen_exit_tb(0);
6728
            break;
6729
        case BS_BRANCH:
6730
        default:
6731
            break;
6732
        }
6733
    }
6734
done_generating:
6735
    ctx.last_T0_store = NULL;
6736
    *gen_opc_ptr = INDEX_op_end;
6737
    if (search_pc) {
6738
        j = gen_opc_ptr - gen_opc_buf;
6739
        lj++;
6740
        while (lj <= j)
6741
            gen_opc_instr_start[lj++] = 0;
6742
    } else {
6743
        tb->size = ctx.pc - pc_start;
6744
    }
6745
#ifdef DEBUG_DISAS
6746
#if defined MIPS_DEBUG_DISAS
6747
    if (loglevel & CPU_LOG_TB_IN_ASM)
6748
        fprintf(logfile, "\n");
6749
#endif
6750
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6751
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6752
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6753
        fprintf(logfile, "\n");
6754
    }
6755
    if (loglevel & CPU_LOG_TB_CPU) {
6756
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6757
    }
6758
#endif
6759

    
6760
    return 0;
6761
}
6762

    
6763
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6764
{
6765
    return gen_intermediate_code_internal(env, tb, 0);
6766
}
6767

    
6768
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6769
{
6770
    return gen_intermediate_code_internal(env, tb, 1);
6771
}
6772

    
6773
void fpu_dump_state(CPUState *env, FILE *f,
6774
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6775
                    int flags)
6776
{
6777
    int i;
6778
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6779

    
6780
#define printfpr(fp)                                                        \
6781
    do {                                                                    \
6782
        if (is_fpu64)                                                       \
6783
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6784
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6785
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6786
        else {                                                              \
6787
            fpr_t tmp;                                                      \
6788
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6789
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6790
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6791
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6792
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6793
        }                                                                   \
6794
    } while(0)
6795

    
6796

    
6797
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6798
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6799
                get_float_exception_flags(&env->fpu->fp_status));
6800
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6801
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6802
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6803
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6804
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6805
        printfpr(&env->fpu->fpr[i]);
6806
    }
6807

    
6808
#undef printfpr
6809
}
6810

    
6811
void dump_fpu (CPUState *env)
6812
{
6813
    if (loglevel) {
6814
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6815
               env->PC[env->current_tc], env->HI[env->current_tc][0], env->LO[env->current_tc][0], env->hflags, env->btarget, env->bcond);
6816
       fpu_dump_state(env, logfile, fprintf, 0);
6817
    }
6818
}
6819

    
6820
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6821
/* Debug help: The architecture requires 32bit code to maintain proper
6822
   sign-extened values on 64bit machines.  */
6823

    
6824
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6825

    
6826
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6827
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6828
                     int flags)
6829
{
6830
    int i;
6831

    
6832
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6833
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6834
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
6835
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
6836
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
6837
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
6838
    if (!SIGN_EXT_P(env->btarget))
6839
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6840

    
6841
    for (i = 0; i < 32; i++) {
6842
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
6843
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
6844
    }
6845

    
6846
    if (!SIGN_EXT_P(env->CP0_EPC))
6847
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6848
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6849
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6850
}
6851
#endif
6852

    
6853
void cpu_dump_state (CPUState *env, FILE *f,
6854
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6855
                     int flags)
6856
{
6857
    int i;
6858

    
6859
    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",
6860
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6861
    for (i = 0; i < 32; i++) {
6862
        if ((i & 3) == 0)
6863
            cpu_fprintf(f, "GPR%02d:", i);
6864
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
6865
        if ((i & 3) == 3)
6866
            cpu_fprintf(f, "\n");
6867
    }
6868

    
6869
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6870
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6871
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6872
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6873
    if (env->hflags & MIPS_HFLAG_FPU)
6874
        fpu_dump_state(env, f, cpu_fprintf, flags);
6875
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6876
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6877
#endif
6878
}
6879

    
6880
#include "translate_init.c"
6881

    
6882
CPUMIPSState *cpu_mips_init (const char *cpu_model)
6883
{
6884
    CPUMIPSState *env;
6885
    const mips_def_t *def;
6886

    
6887
    def = cpu_mips_find_by_name(cpu_model);
6888
    if (!def)
6889
        return NULL;
6890
    env = qemu_mallocz(sizeof(CPUMIPSState));
6891
    if (!env)
6892
        return NULL;
6893
    env->cpu_model = def;
6894

    
6895
    cpu_exec_init(env);
6896
    env->cpu_model_str = cpu_model;
6897
    cpu_reset(env);
6898
    return env;
6899
}
6900

    
6901
void cpu_reset (CPUMIPSState *env)
6902
{
6903
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6904

    
6905
    tlb_flush(env, 1);
6906

    
6907
    /* Minimal init */
6908
#if !defined(CONFIG_USER_ONLY)
6909
    if (env->hflags & MIPS_HFLAG_BMASK) {
6910
        /* If the exception was raised from a delay slot,
6911
         * come back to the jump.  */
6912
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6913
    } else {
6914
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6915
    }
6916
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6917
    env->CP0_Wired = 0;
6918
    /* SMP not implemented */
6919
    env->CP0_EBase = 0x80000000;
6920
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6921
    /* vectored interrupts not implemented, timer on int 7,
6922
       no performance counters. */
6923
    env->CP0_IntCtl = 0xe0000000;
6924
    {
6925
        int i;
6926

    
6927
        for (i = 0; i < 7; i++) {
6928
            env->CP0_WatchLo[i] = 0;
6929
            env->CP0_WatchHi[i] = 0x80000000;
6930
        }
6931
        env->CP0_WatchLo[7] = 0;
6932
        env->CP0_WatchHi[7] = 0;
6933
    }
6934
    /* Count register increments in debug mode, EJTAG version 1 */
6935
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6936
#endif
6937
    env->exception_index = EXCP_NONE;
6938
#if defined(CONFIG_USER_ONLY)
6939
    env->hflags = MIPS_HFLAG_UM;
6940
    env->user_mode_only = 1;
6941
#else
6942
    env->hflags = MIPS_HFLAG_CP0;
6943
#endif
6944
    cpu_mips_register(env, env->cpu_model);
6945
}
6946

    
6947
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6948
                unsigned long searched_pc, int pc_pos, void *puc)
6949
{
6950
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
6951
    env->hflags &= ~MIPS_HFLAG_BMASK;
6952
    env->hflags |= gen_opc_hflags[pc_pos];
6953
}