Statistics
| Branch: | Revision:

root / target-mips / translate.c @ aaa9128a

History | View | Annotate | Download (195 kB)

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

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

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

    
35
//#define MIPS_DEBUG_DISAS
36
//#define MIPS_DEBUG_SIGN_EXTENSIONS
37
//#define MIPS_SINGLE_STEP
38

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

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

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

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

    
183
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
184

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
491
/* Load immediates, zero being a special case. */
492
static inline void gen_op_set_T0(target_ulong arg)
493
{
494
    tcg_gen_movi_tl(cpu_T[0], arg);
495
}
496

    
497
static inline void gen_op_set_T1(target_ulong arg)
498
{
499
    tcg_gen_movi_tl(cpu_T[1], arg);
500
}
501

    
502
static inline void gen_op_reset_T0(void)
503
{
504
    tcg_gen_movi_tl(cpu_T[0], 0);
505
}
506

    
507
static inline void gen_op_reset_T1(void)
508
{
509
    tcg_gen_movi_tl(cpu_T[1], 0);
510
}
511

    
512
/* Moves to/from HI/LO registers. */
513
static inline void gen_op_load_HI(int reg)
514
{
515
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
516
}
517

    
518
static inline void gen_op_store_HI(int reg)
519
{
520
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
521
}
522

    
523
static inline void gen_op_load_LO(int reg)
524
{
525
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
526
}
527

    
528
static inline void gen_op_store_LO(int reg)
529
{
530
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
531
}
532

    
533

    
534
/* Floating point register moves. */
535
static const char *fregnames[] =
536
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
537
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
538
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
539
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
540

    
541
#define FGEN32(func, NAME)                       \
542
static GenOpFunc *NAME ## _table [32] = {        \
543
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
544
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
545
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
546
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
547
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
548
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
549
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
550
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
551
};                                               \
552
static always_inline void func(int n)            \
553
{                                                \
554
    NAME ## _table[n]();                         \
555
}
556

    
557
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
558
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
559

    
560
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
561
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
562

    
563
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
564
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
565

    
566
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
567
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
568

    
569
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
570
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
571

    
572
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
573
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
574

    
575
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
576
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
577

    
578
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
579
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
580

    
581
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
582
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
583

    
584
#define FOP_CONDS(type, fmt)                                            \
585
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
586
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
587
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
588
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
589
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
590
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
591
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
592
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
593
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
594
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
595
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
596
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
597
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
598
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
599
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
600
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
601
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
602
};                                                                      \
603
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
604
{                                                                       \
605
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
606
}
607

    
608
FOP_CONDS(, d)
609
FOP_CONDS(abs, d)
610
FOP_CONDS(, s)
611
FOP_CONDS(abs, s)
612
FOP_CONDS(, ps)
613
FOP_CONDS(abs, ps)
614

    
615
typedef struct DisasContext {
616
    struct TranslationBlock *tb;
617
    target_ulong pc, saved_pc;
618
    uint32_t opcode;
619
    uint32_t fp_status;
620
    /* Routine used to access memory */
621
    int mem_idx;
622
    uint32_t hflags, saved_hflags;
623
    int bstate;
624
    target_ulong btarget;
625
    void *last_T0_store;
626
    int last_T0_gpr;
627
} DisasContext;
628

    
629
enum {
630
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
631
                      * exception condition
632
                      */
633
    BS_STOP     = 1, /* We want to stop translation for any reason */
634
    BS_BRANCH   = 2, /* We reached a branch condition     */
635
    BS_EXCP     = 3, /* We reached an exception condition */
636
};
637

    
638
#ifdef MIPS_DEBUG_DISAS
639
#define MIPS_DEBUG(fmt, args...)                                              \
640
do {                                                                          \
641
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
642
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
643
                ctx->pc, ctx->opcode , ##args);                               \
644
    }                                                                         \
645
} while (0)
646
#else
647
#define MIPS_DEBUG(fmt, args...) do { } while(0)
648
#endif
649

    
650
#define MIPS_INVAL(op)                                                        \
651
do {                                                                          \
652
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
653
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
654
} while (0)
655

    
656
#define GEN_LOAD_REG_T0(Rn)                                                   \
657
do {                                                                          \
658
    if (Rn == 0) {                                                            \
659
        gen_op_reset_T0();                                                    \
660
    } else {                                                                  \
661
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
662
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
663
                gen_op_load_gpr_T0(Rn);                                       \
664
        }                                                                     \
665
    }                                                                         \
666
} while (0)
667

    
668
#define GEN_LOAD_REG_T1(Rn)                                                   \
669
do {                                                                          \
670
    if (Rn == 0) {                                                            \
671
        gen_op_reset_T1();                                                    \
672
    } else {                                                                  \
673
        gen_op_load_gpr_T1(Rn);                                               \
674
    }                                                                         \
675
} while (0)
676

    
677
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
678
do {                                                                          \
679
    if (Rn == 0) {                                                            \
680
        glue(gen_op_reset_, Tn)();                                            \
681
    } else {                                                                  \
682
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
683
    }                                                                         \
684
} while (0)
685

    
686
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
687
do {                                                                          \
688
    if (Imm == 0) {                                                           \
689
        glue(gen_op_reset_, Tn)();                                            \
690
    } else {                                                                  \
691
        glue(gen_op_set_, Tn)(Imm);                                           \
692
    }                                                                         \
693
} while (0)
694

    
695
#define GEN_STORE_T0_REG(Rn)                                                  \
696
do {                                                                          \
697
    if (Rn != 0) {                                                            \
698
        gen_op_store_gpr_T0(Rn);                                              \
699
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
700
        ctx->glue(last_T0,_gpr) = Rn;                                         \
701
    }                                                                         \
702
} while (0)
703

    
704
#define GEN_STORE_T1_REG(Rn)                                                  \
705
do {                                                                          \
706
    if (Rn != 0)                                                              \
707
        gen_op_store_gpr_T1(Rn);                                              \
708
} while (0)
709

    
710
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
711
do {                                                                          \
712
    if (Rn != 0)                                                              \
713
        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \
714
} while (0)
715

    
716
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
717
do {                                                                          \
718
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
719
} while (0)
720

    
721
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
722
do {                                                                          \
723
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
724
} while (0)
725

    
726
static always_inline void gen_save_pc(target_ulong pc)
727
{
728
#if defined(TARGET_MIPS64)
729
    if (pc == (int32_t)pc) {
730
        gen_op_save_pc(pc);
731
    } else {
732
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
733
    }
734
#else
735
    gen_op_save_pc(pc);
736
#endif
737
}
738

    
739
static always_inline void gen_save_btarget(target_ulong btarget)
740
{
741
#if defined(TARGET_MIPS64)
742
    if (btarget == (int32_t)btarget) {
743
        gen_op_save_btarget(btarget);
744
    } else {
745
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
746
    }
747
#else
748
    gen_op_save_btarget(btarget);
749
#endif
750
}
751

    
752
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
753
{
754
#if defined MIPS_DEBUG_DISAS
755
    if (loglevel & CPU_LOG_TB_IN_ASM) {
756
            fprintf(logfile, "hflags %08x saved %08x\n",
757
                    ctx->hflags, ctx->saved_hflags);
758
    }
759
#endif
760
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
761
        gen_save_pc(ctx->pc);
762
        ctx->saved_pc = ctx->pc;
763
    }
764
    if (ctx->hflags != ctx->saved_hflags) {
765
        gen_op_save_state(ctx->hflags);
766
        ctx->saved_hflags = ctx->hflags;
767
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
768
        case MIPS_HFLAG_BR:
769
            break;
770
        case MIPS_HFLAG_BC:
771
        case MIPS_HFLAG_BL:
772
        case MIPS_HFLAG_B:
773
            gen_save_btarget(ctx->btarget);
774
            break;
775
        }
776
    }
777
}
778

    
779
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
780
{
781
    ctx->saved_hflags = ctx->hflags;
782
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
783
    case MIPS_HFLAG_BR:
784
        break;
785
    case MIPS_HFLAG_BC:
786
    case MIPS_HFLAG_BL:
787
    case MIPS_HFLAG_B:
788
        ctx->btarget = env->btarget;
789
        break;
790
    }
791
}
792

    
793
static always_inline void
794
generate_tcg_exception_err (DisasContext *ctx, int excp, int err)
795
{
796
    save_cpu_state(ctx, 1);
797
    if (err == 0)
798
        gen_op_raise_exception(excp);
799
    else
800
        gen_op_raise_exception_err(excp, err);
801
    gen_op_interrupt_restart();
802
    tcg_gen_exit_tb(0);
803
}
804

    
805
static always_inline void
806
generate_tcg_exception (DisasContext *ctx, int excp)
807
{
808
    generate_tcg_exception_err (ctx, excp, 0);
809
}
810

    
811
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
812
{
813
#if defined MIPS_DEBUG_DISAS
814
    if (loglevel & CPU_LOG_TB_IN_ASM)
815
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
816
#endif
817
    save_cpu_state(ctx, 1);
818
    if (err == 0)
819
        gen_op_raise_exception(excp);
820
    else
821
        gen_op_raise_exception_err(excp, err);
822
    ctx->bstate = BS_EXCP;
823
}
824

    
825
static always_inline void generate_exception (DisasContext *ctx, int excp)
826
{
827
    generate_exception_err (ctx, excp, 0);
828
}
829

    
830
static always_inline void check_cp0_enabled(DisasContext *ctx)
831
{
832
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
833
        generate_exception_err(ctx, EXCP_CpU, 1);
834
}
835

    
836
static always_inline void check_cp1_enabled(DisasContext *ctx)
837
{
838
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
839
        generate_exception_err(ctx, EXCP_CpU, 1);
840
}
841

    
842
/* Verify that the processor is running with COP1X instructions enabled.
843
   This is associated with the nabla symbol in the MIPS32 and MIPS64
844
   opcode tables.  */
845

    
846
static always_inline void check_cop1x(DisasContext *ctx)
847
{
848
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/* Verify that the processor is running with 64-bit floating-point
853
   operations enabled.  */
854

    
855
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
856
{
857
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
858
        generate_exception(ctx, EXCP_RI);
859
}
860

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

    
878
/* This code generates a "reserved instruction" exception if the
879
   CPU does not support the instruction set corresponding to flags. */
880
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
881
{
882
    if (unlikely(!(env->insn_flags & flags)))
883
        generate_exception(ctx, EXCP_RI);
884
}
885

    
886
/* This code generates a "reserved instruction" exception if 64-bit
887
   instructions are not enabled. */
888
static always_inline void check_mips_64(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

    
894
/* load/store instructions. */
895
#if defined(CONFIG_USER_ONLY)
896
#define op_ldst(name)        gen_op_##name##_raw()
897
#define OP_LD_TABLE(width)
898
#define OP_ST_TABLE(width)
899
#else
900
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
901
#define OP_LD_TABLE(width)                                                    \
902
static GenOpFunc *gen_op_l##width[] = {                                       \
903
    &gen_op_l##width##_kernel,                                                \
904
    &gen_op_l##width##_super,                                                 \
905
    &gen_op_l##width##_user,                                                  \
906
}
907
#define OP_ST_TABLE(width)                                                    \
908
static GenOpFunc *gen_op_s##width[] = {                                       \
909
    &gen_op_s##width##_kernel,                                                \
910
    &gen_op_s##width##_super,                                                 \
911
    &gen_op_s##width##_user,                                                  \
912
}
913
#endif
914

    
915
#if defined(TARGET_MIPS64)
916
OP_LD_TABLE(dl);
917
OP_LD_TABLE(dr);
918
OP_ST_TABLE(dl);
919
OP_ST_TABLE(dr);
920
#endif
921
OP_LD_TABLE(wl);
922
OP_LD_TABLE(wr);
923
OP_ST_TABLE(wl);
924
OP_ST_TABLE(wr);
925
OP_LD_TABLE(wc1);
926
OP_ST_TABLE(wc1);
927
OP_LD_TABLE(dc1);
928
OP_ST_TABLE(dc1);
929
OP_LD_TABLE(uxc1);
930
OP_ST_TABLE(uxc1);
931

    
932
#define OP_LD(insn,fname)                                        \
933
void inline op_ldst_##insn(DisasContext *ctx)                    \
934
{                                                                \
935
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
936
}
937
OP_LD(lb,ld8s);
938
OP_LD(lbu,ld8u);
939
OP_LD(lh,ld16s);
940
OP_LD(lhu,ld16u);
941
OP_LD(lw,ld32s);
942
#if defined(TARGET_MIPS64)
943
OP_LD(lwu,ld32u);
944
OP_LD(ld,ld64);
945
#endif
946
#undef OP_LD
947

    
948
#define OP_ST(insn,fname)                                        \
949
void inline op_ldst_##insn(DisasContext *ctx)                    \
950
{                                                                \
951
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
952
}
953
OP_ST(sb,st8);
954
OP_ST(sh,st16);
955
OP_ST(sw,st32);
956
#if defined(TARGET_MIPS64)
957
OP_ST(sd,st64);
958
#endif
959
#undef OP_ST
960

    
961
#define OP_LD_ATOMIC(insn,fname)                                        \
962
void inline op_ldst_##insn(DisasContext *ctx)                           \
963
{                                                                       \
964
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
965
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
966
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
967
}
968
OP_LD_ATOMIC(ll,ld32s);
969
#if defined(TARGET_MIPS64)
970
OP_LD_ATOMIC(lld,ld64);
971
#endif
972
#undef OP_LD_ATOMIC
973

    
974
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
975
void inline op_ldst_##insn(DisasContext *ctx)                           \
976
{                                                                       \
977
    int r_tmp = tcg_temp_new(TCG_TYPE_TL);                              \
978
    int l1 = gen_new_label();                                           \
979
    int l2 = gen_new_label();                                           \
980
    int l3 = gen_new_label();                                           \
981
                                                                        \
982
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
983
    tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1);         \
984
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
985
    generate_tcg_exception(ctx, EXCP_AdES);                             \
986
    gen_set_label(l1);                                                  \
987
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
988
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
989
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
990
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
991
    tcg_gen_br(l3);                                                     \
992
    gen_set_label(l2);                                                  \
993
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
994
    gen_set_label(l3);                                                  \
995
}
996
OP_ST_ATOMIC(sc,st32,0x3);
997
#if defined(TARGET_MIPS64)
998
OP_ST_ATOMIC(scd,st64,0x7);
999
#endif
1000
#undef OP_ST_ATOMIC
1001

    
1002
void inline op_ldst_lwc1(DisasContext *ctx)
1003
{
1004
    op_ldst(lwc1);
1005
}
1006

    
1007
void inline op_ldst_ldc1(DisasContext *ctx)
1008
{
1009
    op_ldst(ldc1);
1010
}
1011

    
1012
void inline op_ldst_swc1(DisasContext *ctx)
1013
{
1014
    op_ldst(swc1);
1015
}
1016

    
1017
void inline op_ldst_sdc1(DisasContext *ctx)
1018
{
1019
    op_ldst(sdc1);
1020
}
1021

    
1022
/* Load and store */
1023
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1024
                      int base, int16_t offset)
1025
{
1026
    const char *opn = "ldst";
1027

    
1028
    if (base == 0) {
1029
        GEN_LOAD_IMM_TN(T0, offset);
1030
    } else if (offset == 0) {
1031
        gen_op_load_gpr_T0(base);
1032
    } else {
1033
        gen_op_load_gpr_T0(base);
1034
        gen_op_set_T1(offset);
1035
        gen_op_addr_add();
1036
    }
1037
    /* Don't do NOP if destination is zero: we must perform the actual
1038
       memory access. */
1039
    switch (opc) {
1040
#if defined(TARGET_MIPS64)
1041
    case OPC_LWU:
1042
        op_ldst_lwu(ctx);
1043
        GEN_STORE_T0_REG(rt);
1044
        opn = "lwu";
1045
        break;
1046
    case OPC_LD:
1047
        op_ldst_ld(ctx);
1048
        GEN_STORE_T0_REG(rt);
1049
        opn = "ld";
1050
        break;
1051
    case OPC_LLD:
1052
        op_ldst_lld(ctx);
1053
        GEN_STORE_T0_REG(rt);
1054
        opn = "lld";
1055
        break;
1056
    case OPC_SD:
1057
        GEN_LOAD_REG_T1(rt);
1058
        op_ldst_sd(ctx);
1059
        opn = "sd";
1060
        break;
1061
    case OPC_SCD:
1062
        save_cpu_state(ctx, 1);
1063
        GEN_LOAD_REG_T1(rt);
1064
        op_ldst_scd(ctx);
1065
        GEN_STORE_T0_REG(rt);
1066
        opn = "scd";
1067
        break;
1068
    case OPC_LDL:
1069
        GEN_LOAD_REG_T1(rt);
1070
        op_ldst(ldl);
1071
        GEN_STORE_T1_REG(rt);
1072
        opn = "ldl";
1073
        break;
1074
    case OPC_SDL:
1075
        GEN_LOAD_REG_T1(rt);
1076
        op_ldst(sdl);
1077
        opn = "sdl";
1078
        break;
1079
    case OPC_LDR:
1080
        GEN_LOAD_REG_T1(rt);
1081
        op_ldst(ldr);
1082
        GEN_STORE_T1_REG(rt);
1083
        opn = "ldr";
1084
        break;
1085
    case OPC_SDR:
1086
        GEN_LOAD_REG_T1(rt);
1087
        op_ldst(sdr);
1088
        opn = "sdr";
1089
        break;
1090
#endif
1091
    case OPC_LW:
1092
        op_ldst_lw(ctx);
1093
        GEN_STORE_T0_REG(rt);
1094
        opn = "lw";
1095
        break;
1096
    case OPC_SW:
1097
        GEN_LOAD_REG_T1(rt);
1098
        op_ldst_sw(ctx);
1099
        opn = "sw";
1100
        break;
1101
    case OPC_LH:
1102
        op_ldst_lh(ctx);
1103
        GEN_STORE_T0_REG(rt);
1104
        opn = "lh";
1105
        break;
1106
    case OPC_SH:
1107
        GEN_LOAD_REG_T1(rt);
1108
        op_ldst_sh(ctx);
1109
        opn = "sh";
1110
        break;
1111
    case OPC_LHU:
1112
        op_ldst_lhu(ctx);
1113
        GEN_STORE_T0_REG(rt);
1114
        opn = "lhu";
1115
        break;
1116
    case OPC_LB:
1117
        op_ldst_lb(ctx);
1118
        GEN_STORE_T0_REG(rt);
1119
        opn = "lb";
1120
        break;
1121
    case OPC_SB:
1122
        GEN_LOAD_REG_T1(rt);
1123
        op_ldst_sb(ctx);
1124
        opn = "sb";
1125
        break;
1126
    case OPC_LBU:
1127
        op_ldst_lbu(ctx);
1128
        GEN_STORE_T0_REG(rt);
1129
        opn = "lbu";
1130
        break;
1131
    case OPC_LWL:
1132
        GEN_LOAD_REG_T1(rt);
1133
        op_ldst(lwl);
1134
        GEN_STORE_T1_REG(rt);
1135
        opn = "lwl";
1136
        break;
1137
    case OPC_SWL:
1138
        GEN_LOAD_REG_T1(rt);
1139
        op_ldst(swl);
1140
        opn = "swr";
1141
        break;
1142
    case OPC_LWR:
1143
        GEN_LOAD_REG_T1(rt);
1144
        op_ldst(lwr);
1145
        GEN_STORE_T1_REG(rt);
1146
        opn = "lwr";
1147
        break;
1148
    case OPC_SWR:
1149
        GEN_LOAD_REG_T1(rt);
1150
        op_ldst(swr);
1151
        opn = "swr";
1152
        break;
1153
    case OPC_LL:
1154
        op_ldst_ll(ctx);
1155
        GEN_STORE_T0_REG(rt);
1156
        opn = "ll";
1157
        break;
1158
    case OPC_SC:
1159
        save_cpu_state(ctx, 1);
1160
        GEN_LOAD_REG_T1(rt);
1161
        op_ldst_sc(ctx);
1162
        GEN_STORE_T0_REG(rt);
1163
        opn = "sc";
1164
        break;
1165
    default:
1166
        MIPS_INVAL(opn);
1167
        generate_exception(ctx, EXCP_RI);
1168
        return;
1169
    }
1170
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1171
}
1172

    
1173
/* Load and store */
1174
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1175
                      int base, int16_t offset)
1176
{
1177
    const char *opn = "flt_ldst";
1178

    
1179
    if (base == 0) {
1180
        GEN_LOAD_IMM_TN(T0, offset);
1181
    } else if (offset == 0) {
1182
        gen_op_load_gpr_T0(base);
1183
    } else {
1184
        gen_op_load_gpr_T0(base);
1185
        gen_op_set_T1(offset);
1186
        gen_op_addr_add();
1187
    }
1188
    /* Don't do NOP if destination is zero: we must perform the actual
1189
       memory access. */
1190
    switch (opc) {
1191
    case OPC_LWC1:
1192
        op_ldst_lwc1(ctx);
1193
        GEN_STORE_FTN_FREG(ft, WT0);
1194
        opn = "lwc1";
1195
        break;
1196
    case OPC_SWC1:
1197
        GEN_LOAD_FREG_FTN(WT0, ft);
1198
        op_ldst_swc1(ctx);
1199
        opn = "swc1";
1200
        break;
1201
    case OPC_LDC1:
1202
        op_ldst_ldc1(ctx);
1203
        GEN_STORE_FTN_FREG(ft, DT0);
1204
        opn = "ldc1";
1205
        break;
1206
    case OPC_SDC1:
1207
        GEN_LOAD_FREG_FTN(DT0, ft);
1208
        op_ldst_sdc1(ctx);
1209
        opn = "sdc1";
1210
        break;
1211
    default:
1212
        MIPS_INVAL(opn);
1213
        generate_exception(ctx, EXCP_RI);
1214
        return;
1215
    }
1216
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1217
}
1218

    
1219
/* Arithmetic with immediate operand */
1220
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1221
                           int rt, int rs, int16_t imm)
1222
{
1223
    target_ulong uimm;
1224
    const char *opn = "imm arith";
1225

    
1226
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1227
        /* If no destination, treat it as a NOP.
1228
           For addi, we must generate the overflow exception when needed. */
1229
        MIPS_DEBUG("NOP");
1230
        return;
1231
    }
1232
    uimm = (uint16_t)imm;
1233
    switch (opc) {
1234
    case OPC_ADDI:
1235
    case OPC_ADDIU:
1236
#if defined(TARGET_MIPS64)
1237
    case OPC_DADDI:
1238
    case OPC_DADDIU:
1239
#endif
1240
    case OPC_SLTI:
1241
    case OPC_SLTIU:
1242
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1243
        /* Fall through. */
1244
    case OPC_ANDI:
1245
    case OPC_ORI:
1246
    case OPC_XORI:
1247
        GEN_LOAD_REG_T0(rs);
1248
        GEN_LOAD_IMM_TN(T1, uimm);
1249
        break;
1250
    case OPC_LUI:
1251
        GEN_LOAD_IMM_TN(T0, imm << 16);
1252
        break;
1253
    case OPC_SLL:
1254
    case OPC_SRA:
1255
    case OPC_SRL:
1256
#if defined(TARGET_MIPS64)
1257
    case OPC_DSLL:
1258
    case OPC_DSRA:
1259
    case OPC_DSRL:
1260
    case OPC_DSLL32:
1261
    case OPC_DSRA32:
1262
    case OPC_DSRL32:
1263
#endif
1264
        uimm &= 0x1f;
1265
        GEN_LOAD_REG_T0(rs);
1266
        GEN_LOAD_IMM_TN(T1, uimm);
1267
        break;
1268
    }
1269
    switch (opc) {
1270
    case OPC_ADDI:
1271
        save_cpu_state(ctx, 1);
1272
        gen_op_addo();
1273
        opn = "addi";
1274
        break;
1275
    case OPC_ADDIU:
1276
        gen_op_add();
1277
        opn = "addiu";
1278
        break;
1279
#if defined(TARGET_MIPS64)
1280
    case OPC_DADDI:
1281
        save_cpu_state(ctx, 1);
1282
        gen_op_daddo();
1283
        opn = "daddi";
1284
        break;
1285
    case OPC_DADDIU:
1286
        gen_op_dadd();
1287
        opn = "daddiu";
1288
        break;
1289
#endif
1290
    case OPC_SLTI:
1291
        gen_op_lt();
1292
        opn = "slti";
1293
        break;
1294
    case OPC_SLTIU:
1295
        gen_op_ltu();
1296
        opn = "sltiu";
1297
        break;
1298
    case OPC_ANDI:
1299
        gen_op_and();
1300
        opn = "andi";
1301
        break;
1302
    case OPC_ORI:
1303
        gen_op_or();
1304
        opn = "ori";
1305
        break;
1306
    case OPC_XORI:
1307
        gen_op_xor();
1308
        opn = "xori";
1309
        break;
1310
    case OPC_LUI:
1311
        opn = "lui";
1312
        break;
1313
    case OPC_SLL:
1314
        gen_op_sll();
1315
        opn = "sll";
1316
        break;
1317
    case OPC_SRA:
1318
        gen_op_sra();
1319
        opn = "sra";
1320
        break;
1321
    case OPC_SRL:
1322
        switch ((ctx->opcode >> 21) & 0x1f) {
1323
        case 0:
1324
            gen_op_srl();
1325
            opn = "srl";
1326
            break;
1327
        case 1:
1328
            /* rotr is decoded as srl on non-R2 CPUs */
1329
            if (env->insn_flags & ISA_MIPS32R2) {
1330
                gen_op_rotr();
1331
                opn = "rotr";
1332
            } else {
1333
                gen_op_srl();
1334
                opn = "srl";
1335
            }
1336
            break;
1337
        default:
1338
            MIPS_INVAL("invalid srl flag");
1339
            generate_exception(ctx, EXCP_RI);
1340
            break;
1341
        }
1342
        break;
1343
#if defined(TARGET_MIPS64)
1344
    case OPC_DSLL:
1345
        gen_op_dsll();
1346
        opn = "dsll";
1347
        break;
1348
    case OPC_DSRA:
1349
        gen_op_dsra();
1350
        opn = "dsra";
1351
        break;
1352
    case OPC_DSRL:
1353
        switch ((ctx->opcode >> 21) & 0x1f) {
1354
        case 0:
1355
            gen_op_dsrl();
1356
            opn = "dsrl";
1357
            break;
1358
        case 1:
1359
            /* drotr is decoded as dsrl on non-R2 CPUs */
1360
            if (env->insn_flags & ISA_MIPS32R2) {
1361
                gen_op_drotr();
1362
                opn = "drotr";
1363
            } else {
1364
                gen_op_dsrl();
1365
                opn = "dsrl";
1366
            }
1367
            break;
1368
        default:
1369
            MIPS_INVAL("invalid dsrl flag");
1370
            generate_exception(ctx, EXCP_RI);
1371
            break;
1372
        }
1373
        break;
1374
    case OPC_DSLL32:
1375
        gen_op_dsll32();
1376
        opn = "dsll32";
1377
        break;
1378
    case OPC_DSRA32:
1379
        gen_op_dsra32();
1380
        opn = "dsra32";
1381
        break;
1382
    case OPC_DSRL32:
1383
        switch ((ctx->opcode >> 21) & 0x1f) {
1384
        case 0:
1385
            gen_op_dsrl32();
1386
            opn = "dsrl32";
1387
            break;
1388
        case 1:
1389
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1390
            if (env->insn_flags & ISA_MIPS32R2) {
1391
                gen_op_drotr32();
1392
                opn = "drotr32";
1393
            } else {
1394
                gen_op_dsrl32();
1395
                opn = "dsrl32";
1396
            }
1397
            break;
1398
        default:
1399
            MIPS_INVAL("invalid dsrl32 flag");
1400
            generate_exception(ctx, EXCP_RI);
1401
            break;
1402
        }
1403
        break;
1404
#endif
1405
    default:
1406
        MIPS_INVAL(opn);
1407
        generate_exception(ctx, EXCP_RI);
1408
        return;
1409
    }
1410
    GEN_STORE_T0_REG(rt);
1411
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1412
}
1413

    
1414
/* Arithmetic */
1415
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1416
                       int rd, int rs, int rt)
1417
{
1418
    const char *opn = "arith";
1419

    
1420
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1421
       && opc != OPC_DADD && opc != OPC_DSUB) {
1422
        /* If no destination, treat it as a NOP.
1423
           For add & sub, we must generate the overflow exception when needed. */
1424
        MIPS_DEBUG("NOP");
1425
        return;
1426
    }
1427
    GEN_LOAD_REG_T0(rs);
1428
    /* Specialcase the conventional move operation. */
1429
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1430
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1431
        GEN_STORE_T0_REG(rd);
1432
        return;
1433
    }
1434
    GEN_LOAD_REG_T1(rt);
1435
    switch (opc) {
1436
    case OPC_ADD:
1437
        save_cpu_state(ctx, 1);
1438
        gen_op_addo();
1439
        opn = "add";
1440
        break;
1441
    case OPC_ADDU:
1442
        gen_op_add();
1443
        opn = "addu";
1444
        break;
1445
    case OPC_SUB:
1446
        save_cpu_state(ctx, 1);
1447
        gen_op_subo();
1448
        opn = "sub";
1449
        break;
1450
    case OPC_SUBU:
1451
        gen_op_sub();
1452
        opn = "subu";
1453
        break;
1454
#if defined(TARGET_MIPS64)
1455
    case OPC_DADD:
1456
        save_cpu_state(ctx, 1);
1457
        gen_op_daddo();
1458
        opn = "dadd";
1459
        break;
1460
    case OPC_DADDU:
1461
        gen_op_dadd();
1462
        opn = "daddu";
1463
        break;
1464
    case OPC_DSUB:
1465
        save_cpu_state(ctx, 1);
1466
        gen_op_dsubo();
1467
        opn = "dsub";
1468
        break;
1469
    case OPC_DSUBU:
1470
        gen_op_dsub();
1471
        opn = "dsubu";
1472
        break;
1473
#endif
1474
    case OPC_SLT:
1475
        gen_op_lt();
1476
        opn = "slt";
1477
        break;
1478
    case OPC_SLTU:
1479
        gen_op_ltu();
1480
        opn = "sltu";
1481
        break;
1482
    case OPC_AND:
1483
        gen_op_and();
1484
        opn = "and";
1485
        break;
1486
    case OPC_NOR:
1487
        gen_op_nor();
1488
        opn = "nor";
1489
        break;
1490
    case OPC_OR:
1491
        gen_op_or();
1492
        opn = "or";
1493
        break;
1494
    case OPC_XOR:
1495
        gen_op_xor();
1496
        opn = "xor";
1497
        break;
1498
    case OPC_MUL:
1499
        gen_op_mul();
1500
        opn = "mul";
1501
        break;
1502
    case OPC_MOVN:
1503
        gen_op_movn(rd);
1504
        opn = "movn";
1505
        goto print;
1506
    case OPC_MOVZ:
1507
        gen_op_movz(rd);
1508
        opn = "movz";
1509
        goto print;
1510
    case OPC_SLLV:
1511
        gen_op_sllv();
1512
        opn = "sllv";
1513
        break;
1514
    case OPC_SRAV:
1515
        gen_op_srav();
1516
        opn = "srav";
1517
        break;
1518
    case OPC_SRLV:
1519
        switch ((ctx->opcode >> 6) & 0x1f) {
1520
        case 0:
1521
            gen_op_srlv();
1522
            opn = "srlv";
1523
            break;
1524
        case 1:
1525
            /* rotrv is decoded as srlv on non-R2 CPUs */
1526
            if (env->insn_flags & ISA_MIPS32R2) {
1527
                gen_op_rotrv();
1528
                opn = "rotrv";
1529
            } else {
1530
                gen_op_srlv();
1531
                opn = "srlv";
1532
            }
1533
            break;
1534
        default:
1535
            MIPS_INVAL("invalid srlv flag");
1536
            generate_exception(ctx, EXCP_RI);
1537
            break;
1538
        }
1539
        break;
1540
#if defined(TARGET_MIPS64)
1541
    case OPC_DSLLV:
1542
        gen_op_dsllv();
1543
        opn = "dsllv";
1544
        break;
1545
    case OPC_DSRAV:
1546
        gen_op_dsrav();
1547
        opn = "dsrav";
1548
        break;
1549
    case OPC_DSRLV:
1550
        switch ((ctx->opcode >> 6) & 0x1f) {
1551
        case 0:
1552
            gen_op_dsrlv();
1553
            opn = "dsrlv";
1554
            break;
1555
        case 1:
1556
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1557
            if (env->insn_flags & ISA_MIPS32R2) {
1558
                gen_op_drotrv();
1559
                opn = "drotrv";
1560
            } else {
1561
                gen_op_dsrlv();
1562
                opn = "dsrlv";
1563
            }
1564
            break;
1565
        default:
1566
            MIPS_INVAL("invalid dsrlv flag");
1567
            generate_exception(ctx, EXCP_RI);
1568
            break;
1569
        }
1570
        break;
1571
#endif
1572
    default:
1573
        MIPS_INVAL(opn);
1574
        generate_exception(ctx, EXCP_RI);
1575
        return;
1576
    }
1577
    GEN_STORE_T0_REG(rd);
1578
 print:
1579
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1580
}
1581

    
1582
/* Arithmetic on HI/LO registers */
1583
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1584
{
1585
    const char *opn = "hilo";
1586

    
1587
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1588
        /* Treat as NOP. */
1589
        MIPS_DEBUG("NOP");
1590
        return;
1591
    }
1592
    switch (opc) {
1593
    case OPC_MFHI:
1594
        gen_op_load_HI(0);
1595
        GEN_STORE_T0_REG(reg);
1596
        opn = "mfhi";
1597
        break;
1598
    case OPC_MFLO:
1599
        gen_op_load_LO(0);
1600
        GEN_STORE_T0_REG(reg);
1601
        opn = "mflo";
1602
        break;
1603
    case OPC_MTHI:
1604
        GEN_LOAD_REG_T0(reg);
1605
        gen_op_store_HI(0);
1606
        opn = "mthi";
1607
        break;
1608
    case OPC_MTLO:
1609
        GEN_LOAD_REG_T0(reg);
1610
        gen_op_store_LO(0);
1611
        opn = "mtlo";
1612
        break;
1613
    default:
1614
        MIPS_INVAL(opn);
1615
        generate_exception(ctx, EXCP_RI);
1616
        return;
1617
    }
1618
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1619
}
1620

    
1621
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1622
                        int rs, int rt)
1623
{
1624
    const char *opn = "mul/div";
1625

    
1626
    GEN_LOAD_REG_T0(rs);
1627
    GEN_LOAD_REG_T1(rt);
1628
    switch (opc) {
1629
    case OPC_DIV:
1630
        gen_op_div();
1631
        opn = "div";
1632
        break;
1633
    case OPC_DIVU:
1634
        gen_op_divu();
1635
        opn = "divu";
1636
        break;
1637
    case OPC_MULT:
1638
        gen_op_mult();
1639
        opn = "mult";
1640
        break;
1641
    case OPC_MULTU:
1642
        gen_op_multu();
1643
        opn = "multu";
1644
        break;
1645
#if defined(TARGET_MIPS64)
1646
    case OPC_DDIV:
1647
        gen_op_ddiv();
1648
        opn = "ddiv";
1649
        break;
1650
    case OPC_DDIVU:
1651
        gen_op_ddivu();
1652
        opn = "ddivu";
1653
        break;
1654
    case OPC_DMULT:
1655
        gen_op_dmult();
1656
        opn = "dmult";
1657
        break;
1658
    case OPC_DMULTU:
1659
        gen_op_dmultu();
1660
        opn = "dmultu";
1661
        break;
1662
#endif
1663
    case OPC_MADD:
1664
        gen_op_madd();
1665
        opn = "madd";
1666
        break;
1667
    case OPC_MADDU:
1668
        gen_op_maddu();
1669
        opn = "maddu";
1670
        break;
1671
    case OPC_MSUB:
1672
        gen_op_msub();
1673
        opn = "msub";
1674
        break;
1675
    case OPC_MSUBU:
1676
        gen_op_msubu();
1677
        opn = "msubu";
1678
        break;
1679
    default:
1680
        MIPS_INVAL(opn);
1681
        generate_exception(ctx, EXCP_RI);
1682
        return;
1683
    }
1684
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1685
}
1686

    
1687
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1688
                            int rd, int rs, int rt)
1689
{
1690
    const char *opn = "mul vr54xx";
1691

    
1692
    GEN_LOAD_REG_T0(rs);
1693
    GEN_LOAD_REG_T1(rt);
1694

    
1695
    switch (opc) {
1696
    case OPC_VR54XX_MULS:
1697
        gen_op_muls();
1698
        opn = "muls";
1699
        break;
1700
    case OPC_VR54XX_MULSU:
1701
        gen_op_mulsu();
1702
        opn = "mulsu";
1703
        break;
1704
    case OPC_VR54XX_MACC:
1705
        gen_op_macc();
1706
        opn = "macc";
1707
        break;
1708
    case OPC_VR54XX_MACCU:
1709
        gen_op_maccu();
1710
        opn = "maccu";
1711
        break;
1712
    case OPC_VR54XX_MSAC:
1713
        gen_op_msac();
1714
        opn = "msac";
1715
        break;
1716
    case OPC_VR54XX_MSACU:
1717
        gen_op_msacu();
1718
        opn = "msacu";
1719
        break;
1720
    case OPC_VR54XX_MULHI:
1721
        gen_op_mulhi();
1722
        opn = "mulhi";
1723
        break;
1724
    case OPC_VR54XX_MULHIU:
1725
        gen_op_mulhiu();
1726
        opn = "mulhiu";
1727
        break;
1728
    case OPC_VR54XX_MULSHI:
1729
        gen_op_mulshi();
1730
        opn = "mulshi";
1731
        break;
1732
    case OPC_VR54XX_MULSHIU:
1733
        gen_op_mulshiu();
1734
        opn = "mulshiu";
1735
        break;
1736
    case OPC_VR54XX_MACCHI:
1737
        gen_op_macchi();
1738
        opn = "macchi";
1739
        break;
1740
    case OPC_VR54XX_MACCHIU:
1741
        gen_op_macchiu();
1742
        opn = "macchiu";
1743
        break;
1744
    case OPC_VR54XX_MSACHI:
1745
        gen_op_msachi();
1746
        opn = "msachi";
1747
        break;
1748
    case OPC_VR54XX_MSACHIU:
1749
        gen_op_msachiu();
1750
        opn = "msachiu";
1751
        break;
1752
    default:
1753
        MIPS_INVAL("mul vr54xx");
1754
        generate_exception(ctx, EXCP_RI);
1755
        return;
1756
    }
1757
    GEN_STORE_T0_REG(rd);
1758
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1759
}
1760

    
1761
static void gen_cl (DisasContext *ctx, uint32_t opc,
1762
                    int rd, int rs)
1763
{
1764
    const char *opn = "CLx";
1765
    if (rd == 0) {
1766
        /* Treat as NOP. */
1767
        MIPS_DEBUG("NOP");
1768
        return;
1769
    }
1770
    GEN_LOAD_REG_T0(rs);
1771
    switch (opc) {
1772
    case OPC_CLO:
1773
        gen_op_clo();
1774
        opn = "clo";
1775
        break;
1776
    case OPC_CLZ:
1777
        gen_op_clz();
1778
        opn = "clz";
1779
        break;
1780
#if defined(TARGET_MIPS64)
1781
    case OPC_DCLO:
1782
        gen_op_dclo();
1783
        opn = "dclo";
1784
        break;
1785
    case OPC_DCLZ:
1786
        gen_op_dclz();
1787
        opn = "dclz";
1788
        break;
1789
#endif
1790
    default:
1791
        MIPS_INVAL(opn);
1792
        generate_exception(ctx, EXCP_RI);
1793
        return;
1794
    }
1795
    gen_op_store_gpr_T0(rd);
1796
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1797
}
1798

    
1799
/* Traps */
1800
static void gen_trap (DisasContext *ctx, uint32_t opc,
1801
                      int rs, int rt, int16_t imm)
1802
{
1803
    int cond;
1804

    
1805
    cond = 0;
1806
    /* Load needed operands */
1807
    switch (opc) {
1808
    case OPC_TEQ:
1809
    case OPC_TGE:
1810
    case OPC_TGEU:
1811
    case OPC_TLT:
1812
    case OPC_TLTU:
1813
    case OPC_TNE:
1814
        /* Compare two registers */
1815
        if (rs != rt) {
1816
            GEN_LOAD_REG_T0(rs);
1817
            GEN_LOAD_REG_T1(rt);
1818
            cond = 1;
1819
        }
1820
        break;
1821
    case OPC_TEQI:
1822
    case OPC_TGEI:
1823
    case OPC_TGEIU:
1824
    case OPC_TLTI:
1825
    case OPC_TLTIU:
1826
    case OPC_TNEI:
1827
        /* Compare register to immediate */
1828
        if (rs != 0 || imm != 0) {
1829
            GEN_LOAD_REG_T0(rs);
1830
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1831
            cond = 1;
1832
        }
1833
        break;
1834
    }
1835
    if (cond == 0) {
1836
        switch (opc) {
1837
        case OPC_TEQ:   /* rs == rs */
1838
        case OPC_TEQI:  /* r0 == 0  */
1839
        case OPC_TGE:   /* rs >= rs */
1840
        case OPC_TGEI:  /* r0 >= 0  */
1841
        case OPC_TGEU:  /* rs >= rs unsigned */
1842
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1843
            /* Always trap */
1844
            gen_op_set_T0(1);
1845
            break;
1846
        case OPC_TLT:   /* rs < rs           */
1847
        case OPC_TLTI:  /* r0 < 0            */
1848
        case OPC_TLTU:  /* rs < rs unsigned  */
1849
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1850
        case OPC_TNE:   /* rs != rs          */
1851
        case OPC_TNEI:  /* r0 != 0           */
1852
            /* Never trap: treat as NOP. */
1853
            return;
1854
        default:
1855
            MIPS_INVAL("trap");
1856
            generate_exception(ctx, EXCP_RI);
1857
            return;
1858
        }
1859
    } else {
1860
        switch (opc) {
1861
        case OPC_TEQ:
1862
        case OPC_TEQI:
1863
            gen_op_eq();
1864
            break;
1865
        case OPC_TGE:
1866
        case OPC_TGEI:
1867
            gen_op_ge();
1868
            break;
1869
        case OPC_TGEU:
1870
        case OPC_TGEIU:
1871
            gen_op_geu();
1872
            break;
1873
        case OPC_TLT:
1874
        case OPC_TLTI:
1875
            gen_op_lt();
1876
            break;
1877
        case OPC_TLTU:
1878
        case OPC_TLTIU:
1879
            gen_op_ltu();
1880
            break;
1881
        case OPC_TNE:
1882
        case OPC_TNEI:
1883
            gen_op_ne();
1884
            break;
1885
        default:
1886
            MIPS_INVAL("trap");
1887
            generate_exception(ctx, EXCP_RI);
1888
            return;
1889
        }
1890
    }
1891
    save_cpu_state(ctx, 1);
1892
    gen_op_trap();
1893
    ctx->bstate = BS_STOP;
1894
}
1895

    
1896
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1897
{
1898
    TranslationBlock *tb;
1899
    tb = ctx->tb;
1900
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1901
        tcg_gen_goto_tb(n);
1902
        gen_save_pc(dest);
1903
        tcg_gen_exit_tb((long)tb + n);
1904
    } else {
1905
        gen_save_pc(dest);
1906
        tcg_gen_exit_tb(0);
1907
    }
1908
}
1909

    
1910
static inline void tcg_gen_set_bcond(void)
1911
{
1912
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
1913
}
1914

    
1915
static inline void tcg_gen_jnz_bcond(int label)
1916
{
1917
    int r_tmp = tcg_temp_new(TCG_TYPE_TL);
1918

    
1919
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
1920
    tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);
1921
}
1922

    
1923
/* Branches (before delay slot) */
1924
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1925
                                int rs, int rt, int32_t offset)
1926
{
1927
    target_ulong btarget = -1;
1928
    int blink = 0;
1929
    int bcond = 0;
1930

    
1931
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1932
#ifdef MIPS_DEBUG_DISAS
1933
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1934
            fprintf(logfile,
1935
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1936
                    ctx->pc);
1937
        }
1938
#endif
1939
        generate_exception(ctx, EXCP_RI);
1940
        return;
1941
    }
1942

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

    
2156
    ctx->btarget = btarget;
2157
    if (blink > 0) {
2158
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2159
        gen_op_store_gpr_T0(blink);
2160
    }
2161
}
2162

    
2163
/* special3 bitfield operations */
2164
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2165
                       int rs, int lsb, int msb)
2166
{
2167
    GEN_LOAD_REG_T1(rs);
2168
    switch (opc) {
2169
    case OPC_EXT:
2170
        if (lsb + msb > 31)
2171
            goto fail;
2172
        gen_op_ext(lsb, msb + 1);
2173
        break;
2174
#if defined(TARGET_MIPS64)
2175
    case OPC_DEXTM:
2176
        if (lsb + msb > 63)
2177
            goto fail;
2178
        gen_op_dext(lsb, msb + 1 + 32);
2179
        break;
2180
    case OPC_DEXTU:
2181
        if (lsb + msb > 63)
2182
            goto fail;
2183
        gen_op_dext(lsb + 32, msb + 1);
2184
        break;
2185
    case OPC_DEXT:
2186
        if (lsb + msb > 63)
2187
            goto fail;
2188
        gen_op_dext(lsb, msb + 1);
2189
        break;
2190
#endif
2191
    case OPC_INS:
2192
        if (lsb > msb)
2193
            goto fail;
2194
        GEN_LOAD_REG_T0(rt);
2195
        gen_op_ins(lsb, msb - lsb + 1);
2196
        break;
2197
#if defined(TARGET_MIPS64)
2198
    case OPC_DINSM:
2199
        if (lsb > msb)
2200
            goto fail;
2201
        GEN_LOAD_REG_T0(rt);
2202
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2203
        break;
2204
    case OPC_DINSU:
2205
        if (lsb > msb)
2206
            goto fail;
2207
        GEN_LOAD_REG_T0(rt);
2208
        gen_op_dins(lsb + 32, msb - lsb + 1);
2209
        break;
2210
    case OPC_DINS:
2211
        if (lsb > msb)
2212
            goto fail;
2213
        GEN_LOAD_REG_T0(rt);
2214
        gen_op_dins(lsb, msb - lsb + 1);
2215
        break;
2216
#endif
2217
    default:
2218
fail:
2219
        MIPS_INVAL("bitops");
2220
        generate_exception(ctx, EXCP_RI);
2221
        return;
2222
    }
2223
    GEN_STORE_T0_REG(rt);
2224
}
2225

    
2226
/* CP0 (MMU and control) */
2227
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2228
{
2229
    const char *rn = "invalid";
2230

    
2231
    if (sel != 0)
2232
        check_insn(env, ctx, ISA_MIPS32);
2233

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

    
2785
die:
2786
#if defined MIPS_DEBUG_DISAS
2787
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2788
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2789
                rn, reg, sel);
2790
    }
2791
#endif
2792
    generate_exception(ctx, EXCP_RI);
2793
}
2794

    
2795
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2796
{
2797
    const char *rn = "invalid";
2798

    
2799
    if (sel != 0)
2800
        check_insn(env, ctx, ISA_MIPS32);
2801

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

    
3384
die:
3385
#if defined MIPS_DEBUG_DISAS
3386
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3387
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3388
                rn, reg, sel);
3389
    }
3390
#endif
3391
    generate_exception(ctx, EXCP_RI);
3392
}
3393

    
3394
#if defined(TARGET_MIPS64)
3395
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3396
{
3397
    const char *rn = "invalid";
3398

    
3399
    if (sel != 0)
3400
        check_insn(env, ctx, ISA_MIPS64);
3401

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

    
3942
die:
3943
#if defined MIPS_DEBUG_DISAS
3944
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3945
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3946
                rn, reg, sel);
3947
    }
3948
#endif
3949
    generate_exception(ctx, EXCP_RI);
3950
}
3951

    
3952
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3953
{
3954
    const char *rn = "invalid";
3955

    
3956
    if (sel != 0)
3957
        check_insn(env, ctx, ISA_MIPS64);
3958

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

    
4528
die:
4529
#if defined MIPS_DEBUG_DISAS
4530
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4531
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4532
                rn, reg, sel);
4533
    }
4534
#endif
4535
    generate_exception(ctx, EXCP_RI);
4536
}
4537
#endif /* TARGET_MIPS64 */
4538

    
4539
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4540
                     int u, int sel, int h)
4541
{
4542
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4543

    
4544
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4545
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4546
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4547
        gen_op_set_T0(-1);
4548
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4549
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4550
        gen_op_set_T0(-1);
4551
    else if (u == 0) {
4552
        switch (rt) {
4553
        case 2:
4554
            switch (sel) {
4555
            case 1:
4556
                gen_op_mftc0_tcstatus();
4557
                break;
4558
            case 2:
4559
                gen_op_mftc0_tcbind();
4560
                break;
4561
            case 3:
4562
                gen_op_mftc0_tcrestart();
4563
                break;
4564
            case 4:
4565
                gen_op_mftc0_tchalt();
4566
                break;
4567
            case 5:
4568
                gen_op_mftc0_tccontext();
4569
                break;
4570
            case 6:
4571
                gen_op_mftc0_tcschedule();
4572
                break;
4573
            case 7:
4574
                gen_op_mftc0_tcschefback();
4575
                break;
4576
            default:
4577
                gen_mfc0(env, ctx, rt, sel);
4578
                break;
4579
            }
4580
            break;
4581
        case 10:
4582
            switch (sel) {
4583
            case 0:
4584
                gen_op_mftc0_entryhi();
4585
                break;
4586
            default:
4587
                gen_mfc0(env, ctx, rt, sel);
4588
                break;
4589
            }
4590
        case 12:
4591
            switch (sel) {
4592
            case 0:
4593
                gen_op_mftc0_status();
4594
                break;
4595
            default:
4596
                gen_mfc0(env, ctx, rt, sel);
4597
                break;
4598
            }
4599
        case 23:
4600
            switch (sel) {
4601
            case 0:
4602
                gen_op_mftc0_debug();
4603
                break;
4604
            default:
4605
                gen_mfc0(env, ctx, rt, sel);
4606
                break;
4607
            }
4608
            break;
4609
        default:
4610
            gen_mfc0(env, ctx, rt, sel);
4611
        }
4612
    } else switch (sel) {
4613
    /* GPR registers. */
4614
    case 0:
4615
        gen_op_mftgpr(rt);
4616
        break;
4617
    /* Auxiliary CPU registers */
4618
    case 1:
4619
        switch (rt) {
4620
        case 0:
4621
            gen_op_mftlo(0);
4622
            break;
4623
        case 1:
4624
            gen_op_mfthi(0);
4625
            break;
4626
        case 2:
4627
            gen_op_mftacx(0);
4628
            break;
4629
        case 4:
4630
            gen_op_mftlo(1);
4631
            break;
4632
        case 5:
4633
            gen_op_mfthi(1);
4634
            break;
4635
        case 6:
4636
            gen_op_mftacx(1);
4637
            break;
4638
        case 8:
4639
            gen_op_mftlo(2);
4640
            break;
4641
        case 9:
4642
            gen_op_mfthi(2);
4643
            break;
4644
        case 10:
4645
            gen_op_mftacx(2);
4646
            break;
4647
        case 12:
4648
            gen_op_mftlo(3);
4649
            break;
4650
        case 13:
4651
            gen_op_mfthi(3);
4652
            break;
4653
        case 14:
4654
            gen_op_mftacx(3);
4655
            break;
4656
        case 16:
4657
            gen_op_mftdsp();
4658
            break;
4659
        default:
4660
            goto die;
4661
        }
4662
        break;
4663
    /* Floating point (COP1). */
4664
    case 2:
4665
        /* XXX: For now we support only a single FPU context. */
4666
        if (h == 0) {
4667
            GEN_LOAD_FREG_FTN(WT0, rt);
4668
            gen_op_mfc1();
4669
        } else {
4670
            GEN_LOAD_FREG_FTN(WTH0, rt);
4671
            gen_op_mfhc1();
4672
        }
4673
        break;
4674
    case 3:
4675
        /* XXX: For now we support only a single FPU context. */
4676
        gen_op_cfc1(rt);
4677
        break;
4678
    /* COP2: Not implemented. */
4679
    case 4:
4680
    case 5:
4681
        /* fall through */
4682
    default:
4683
        goto die;
4684
    }
4685
#if defined MIPS_DEBUG_DISAS
4686
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4687
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4688
                rt, u, sel, h);
4689
    }
4690
#endif
4691
    return;
4692

    
4693
die:
4694
#if defined MIPS_DEBUG_DISAS
4695
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4696
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4697
                rt, u, sel, h);
4698
    }
4699
#endif
4700
    generate_exception(ctx, EXCP_RI);
4701
}
4702

    
4703
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4704
                     int u, int sel, int h)
4705
{
4706
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4707

    
4708
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4709
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4710
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4711
        /* NOP */ ;
4712
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4713
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4714
        /* NOP */ ;
4715
    else if (u == 0) {
4716
        switch (rd) {
4717
        case 2:
4718
            switch (sel) {
4719
            case 1:
4720
                gen_op_mttc0_tcstatus();
4721
                break;
4722
            case 2:
4723
                gen_op_mttc0_tcbind();
4724
                break;
4725
            case 3:
4726
                gen_op_mttc0_tcrestart();
4727
                break;
4728
            case 4:
4729
                gen_op_mttc0_tchalt();
4730
                break;
4731
            case 5:
4732
                gen_op_mttc0_tccontext();
4733
                break;
4734
            case 6:
4735
                gen_op_mttc0_tcschedule();
4736
                break;
4737
            case 7:
4738
                gen_op_mttc0_tcschefback();
4739
                break;
4740
            default:
4741
                gen_mtc0(env, ctx, rd, sel);
4742
                break;
4743
            }
4744
            break;
4745
        case 10:
4746
            switch (sel) {
4747
            case 0:
4748
                gen_op_mttc0_entryhi();
4749
                break;
4750
            default:
4751
                gen_mtc0(env, ctx, rd, sel);
4752
                break;
4753
            }
4754
        case 12:
4755
            switch (sel) {
4756
            case 0:
4757
                gen_op_mttc0_status();
4758
                break;
4759
            default:
4760
                gen_mtc0(env, ctx, rd, sel);
4761
                break;
4762
            }
4763
        case 23:
4764
            switch (sel) {
4765
            case 0:
4766
                gen_op_mttc0_debug();
4767
                break;
4768
            default:
4769
                gen_mtc0(env, ctx, rd, sel);
4770
                break;
4771
            }
4772
            break;
4773
        default:
4774
            gen_mtc0(env, ctx, rd, sel);
4775
        }
4776
    } else switch (sel) {
4777
    /* GPR registers. */
4778
    case 0:
4779
        gen_op_mttgpr(rd);
4780
        break;
4781
    /* Auxiliary CPU registers */
4782
    case 1:
4783
        switch (rd) {
4784
        case 0:
4785
            gen_op_mttlo(0);
4786
            break;
4787
        case 1:
4788
            gen_op_mtthi(0);
4789
            break;
4790
        case 2:
4791
            gen_op_mttacx(0);
4792
            break;
4793
        case 4:
4794
            gen_op_mttlo(1);
4795
            break;
4796
        case 5:
4797
            gen_op_mtthi(1);
4798
            break;
4799
        case 6:
4800
            gen_op_mttacx(1);
4801
            break;
4802
        case 8:
4803
            gen_op_mttlo(2);
4804
            break;
4805
        case 9:
4806
            gen_op_mtthi(2);
4807
            break;
4808
        case 10:
4809
            gen_op_mttacx(2);
4810
            break;
4811
        case 12:
4812
            gen_op_mttlo(3);
4813
            break;
4814
        case 13:
4815
            gen_op_mtthi(3);
4816
            break;
4817
        case 14:
4818
            gen_op_mttacx(3);
4819
            break;
4820
        case 16:
4821
            gen_op_mttdsp();
4822
            break;
4823
        default:
4824
            goto die;
4825
        }
4826
        break;
4827
    /* Floating point (COP1). */
4828
    case 2:
4829
        /* XXX: For now we support only a single FPU context. */
4830
        if (h == 0) {
4831
            gen_op_mtc1();
4832
            GEN_STORE_FTN_FREG(rd, WT0);
4833
        } else {
4834
            gen_op_mthc1();
4835
            GEN_STORE_FTN_FREG(rd, WTH0);
4836
        }
4837
        break;
4838
    case 3:
4839
        /* XXX: For now we support only a single FPU context. */
4840
        gen_op_ctc1(rd);
4841
        break;
4842
    /* COP2: Not implemented. */
4843
    case 4:
4844
    case 5:
4845
        /* fall through */
4846
    default:
4847
        goto die;
4848
    }
4849
#if defined MIPS_DEBUG_DISAS
4850
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4851
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4852
                rd, u, sel, h);
4853
    }
4854
#endif
4855
    return;
4856

    
4857
die:
4858
#if defined MIPS_DEBUG_DISAS
4859
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4860
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4861
                rd, u, sel, h);
4862
    }
4863
#endif
4864
    generate_exception(ctx, EXCP_RI);
4865
}
4866

    
4867
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4868
{
4869
    const char *opn = "ldst";
4870

    
4871
    switch (opc) {
4872
    case OPC_MFC0:
4873
        if (rt == 0) {
4874
            /* Treat as NOP. */
4875
            return;
4876
        }
4877
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4878
        gen_op_store_gpr_T0(rt);
4879
        opn = "mfc0";
4880
        break;
4881
    case OPC_MTC0:
4882
        GEN_LOAD_REG_T0(rt);
4883
        save_cpu_state(ctx, 1);
4884
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4885
        opn = "mtc0";
4886
        break;
4887
#if defined(TARGET_MIPS64)
4888
    case OPC_DMFC0:
4889
        check_insn(env, ctx, ISA_MIPS3);
4890
        if (rt == 0) {
4891
            /* Treat as NOP. */
4892
            return;
4893
        }
4894
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4895
        gen_op_store_gpr_T0(rt);
4896
        opn = "dmfc0";
4897
        break;
4898
    case OPC_DMTC0:
4899
        check_insn(env, ctx, ISA_MIPS3);
4900
        GEN_LOAD_REG_T0(rt);
4901
        save_cpu_state(ctx, 1);
4902
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4903
        opn = "dmtc0";
4904
        break;
4905
#endif
4906
    case OPC_MFTR:
4907
        check_insn(env, ctx, ASE_MT);
4908
        if (rd == 0) {
4909
            /* Treat as NOP. */
4910
            return;
4911
        }
4912
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4913
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4914
        gen_op_store_gpr_T0(rd);
4915
        opn = "mftr";
4916
        break;
4917
    case OPC_MTTR:
4918
        check_insn(env, ctx, ASE_MT);
4919
        GEN_LOAD_REG_T0(rt);
4920
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4921
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4922
        opn = "mttr";
4923
        break;
4924
    case OPC_TLBWI:
4925
        opn = "tlbwi";
4926
        if (!env->tlb->do_tlbwi)
4927
            goto die;
4928
        gen_op_tlbwi();
4929
        break;
4930
    case OPC_TLBWR:
4931
        opn = "tlbwr";
4932
        if (!env->tlb->do_tlbwr)
4933
            goto die;
4934
        gen_op_tlbwr();
4935
        break;
4936
    case OPC_TLBP:
4937
        opn = "tlbp";
4938
        if (!env->tlb->do_tlbp)
4939
            goto die;
4940
        gen_op_tlbp();
4941
        break;
4942
    case OPC_TLBR:
4943
        opn = "tlbr";
4944
        if (!env->tlb->do_tlbr)
4945
            goto die;
4946
        gen_op_tlbr();
4947
        break;
4948
    case OPC_ERET:
4949
        opn = "eret";
4950
        check_insn(env, ctx, ISA_MIPS2);
4951
        save_cpu_state(ctx, 1);
4952
        gen_op_eret();
4953
        ctx->bstate = BS_EXCP;
4954
        break;
4955
    case OPC_DERET:
4956
        opn = "deret";
4957
        check_insn(env, ctx, ISA_MIPS32);
4958
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4959
            MIPS_INVAL(opn);
4960
            generate_exception(ctx, EXCP_RI);
4961
        } else {
4962
            save_cpu_state(ctx, 1);
4963
            gen_op_deret();
4964
            ctx->bstate = BS_EXCP;
4965
        }
4966
        break;
4967
    case OPC_WAIT:
4968
        opn = "wait";
4969
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4970
        /* If we get an exception, we want to restart at next instruction */
4971
        ctx->pc += 4;
4972
        save_cpu_state(ctx, 1);
4973
        ctx->pc -= 4;
4974
        gen_op_wait();
4975
        ctx->bstate = BS_EXCP;
4976
        break;
4977
    default:
4978
 die:
4979
        MIPS_INVAL(opn);
4980
        generate_exception(ctx, EXCP_RI);
4981
        return;
4982
    }
4983
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4984
}
4985

    
4986
/* CP1 Branches (before delay slot) */
4987
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4988
                                 int32_t cc, int32_t offset)
4989
{
4990
    target_ulong btarget;
4991
    const char *opn = "cp1 cond branch";
4992

    
4993
    if (cc != 0)
4994
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4995

    
4996
    btarget = ctx->pc + 4 + offset;
4997

    
4998
    switch (op) {
4999
    case OPC_BC1F:
5000
        gen_op_bc1f(cc);
5001
        opn = "bc1f";
5002
        goto not_likely;
5003
    case OPC_BC1FL:
5004
        gen_op_bc1f(cc);
5005
        opn = "bc1fl";
5006
        goto likely;
5007
    case OPC_BC1T:
5008
        gen_op_bc1t(cc);
5009
        opn = "bc1t";
5010
        goto not_likely;
5011
    case OPC_BC1TL:
5012
        gen_op_bc1t(cc);
5013
        opn = "bc1tl";
5014
    likely:
5015
        ctx->hflags |= MIPS_HFLAG_BL;
5016
        tcg_gen_set_bcond();
5017
        break;
5018
    case OPC_BC1FANY2:
5019
        gen_op_bc1any2f(cc);
5020
        opn = "bc1any2f";
5021
        goto not_likely;
5022
    case OPC_BC1TANY2:
5023
        gen_op_bc1any2t(cc);
5024
        opn = "bc1any2t";
5025
        goto not_likely;
5026
    case OPC_BC1FANY4:
5027
        gen_op_bc1any4f(cc);
5028
        opn = "bc1any4f";
5029
        goto not_likely;
5030
    case OPC_BC1TANY4:
5031
        gen_op_bc1any4t(cc);
5032
        opn = "bc1any4t";
5033
    not_likely:
5034
        ctx->hflags |= MIPS_HFLAG_BC;
5035
        tcg_gen_set_bcond();
5036
        break;
5037
    default:
5038
        MIPS_INVAL(opn);
5039
        generate_exception (ctx, EXCP_RI);
5040
        return;
5041
    }
5042
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5043
               ctx->hflags, btarget);
5044
    ctx->btarget = btarget;
5045
}
5046

    
5047
/* Coprocessor 1 (FPU) */
5048

    
5049
#define FOP(func, fmt) (((fmt) << 21) | (func))
5050

    
5051
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5052
{
5053
    const char *opn = "cp1 move";
5054

    
5055
    switch (opc) {
5056
    case OPC_MFC1:
5057
        GEN_LOAD_FREG_FTN(WT0, fs);
5058
        gen_op_mfc1();
5059
        GEN_STORE_T0_REG(rt);
5060
        opn = "mfc1";
5061
        break;
5062
    case OPC_MTC1:
5063
        GEN_LOAD_REG_T0(rt);
5064
        gen_op_mtc1();
5065
        GEN_STORE_FTN_FREG(fs, WT0);
5066
        opn = "mtc1";
5067
        break;
5068
    case OPC_CFC1:
5069
        gen_op_cfc1(fs);
5070
        GEN_STORE_T0_REG(rt);
5071
        opn = "cfc1";
5072
        break;
5073
    case OPC_CTC1:
5074
        GEN_LOAD_REG_T0(rt);
5075
        gen_op_ctc1(fs);
5076
        opn = "ctc1";
5077
        break;
5078
    case OPC_DMFC1:
5079
        GEN_LOAD_FREG_FTN(DT0, fs);
5080
        gen_op_dmfc1();
5081
        GEN_STORE_T0_REG(rt);
5082
        opn = "dmfc1";
5083
        break;
5084
    case OPC_DMTC1:
5085
        GEN_LOAD_REG_T0(rt);
5086
        gen_op_dmtc1();
5087
        GEN_STORE_FTN_FREG(fs, DT0);
5088
        opn = "dmtc1";
5089
        break;
5090
    case OPC_MFHC1:
5091
        GEN_LOAD_FREG_FTN(WTH0, fs);
5092
        gen_op_mfhc1();
5093
        GEN_STORE_T0_REG(rt);
5094
        opn = "mfhc1";
5095
        break;
5096
    case OPC_MTHC1:
5097
        GEN_LOAD_REG_T0(rt);
5098
        gen_op_mthc1();
5099
        GEN_STORE_FTN_FREG(fs, WTH0);
5100
        opn = "mthc1";
5101
        break;
5102
    default:
5103
        MIPS_INVAL(opn);
5104
        generate_exception (ctx, EXCP_RI);
5105
        return;
5106
    }
5107
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5108
}
5109

    
5110
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5111
{
5112
    uint32_t ccbit;
5113

    
5114
    GEN_LOAD_REG_T0(rd);
5115
    GEN_LOAD_REG_T1(rs);
5116
    if (cc) {
5117
        ccbit = 1 << (24 + cc);
5118
    } else
5119
        ccbit = 1 << 23;
5120
    if (!tf)
5121
        gen_op_movf(ccbit);
5122
    else
5123
        gen_op_movt(ccbit);
5124
    GEN_STORE_T0_REG(rd);
5125
}
5126

    
5127
#define GEN_MOVCF(fmt)                                                \
5128
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5129
{                                                                     \
5130
    uint32_t ccbit;                                                   \
5131
                                                                      \
5132
    if (cc) {                                                         \
5133
        ccbit = 1 << (24 + cc);                                       \
5134
    } else                                                            \
5135
        ccbit = 1 << 23;                                              \
5136
    if (!tf)                                                          \
5137
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5138
    else                                                              \
5139
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5140
}
5141
GEN_MOVCF(d);
5142
GEN_MOVCF(s);
5143
GEN_MOVCF(ps);
5144
#undef GEN_MOVCF
5145

    
5146
static void gen_farith (DisasContext *ctx, uint32_t op1,
5147
                        int ft, int fs, int fd, int cc)
5148
{
5149
    const char *opn = "farith";
5150
    const char *condnames[] = {
5151
            "c.f",
5152
            "c.un",
5153
            "c.eq",
5154
            "c.ueq",
5155
            "c.olt",
5156
            "c.ult",
5157
            "c.ole",
5158
            "c.ule",
5159
            "c.sf",
5160
            "c.ngle",
5161
            "c.seq",
5162
            "c.ngl",
5163
            "c.lt",
5164
            "c.nge",
5165
            "c.le",
5166
            "c.ngt",
5167
    };
5168
    const char *condnames_abs[] = {
5169
            "cabs.f",
5170
            "cabs.un",
5171
            "cabs.eq",
5172
            "cabs.ueq",
5173
            "cabs.olt",
5174
            "cabs.ult",
5175
            "cabs.ole",
5176
            "cabs.ule",
5177
            "cabs.sf",
5178
            "cabs.ngle",
5179
            "cabs.seq",
5180
            "cabs.ngl",
5181
            "cabs.lt",
5182
            "cabs.nge",
5183
            "cabs.le",
5184
            "cabs.ngt",
5185
    };
5186
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5187
    uint32_t func = ctx->opcode & 0x3f;
5188

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

    
5955
/* Coprocessor 3 (FPU) */
5956
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5957
                           int fd, int fs, int base, int index)
5958
{
5959
    const char *opn = "extended float load/store";
5960
    int store = 0;
5961

    
5962
    if (base == 0) {
5963
        if (index == 0)
5964
            gen_op_reset_T0();
5965
        else
5966
            GEN_LOAD_REG_T0(index);
5967
    } else if (index == 0) {
5968
        GEN_LOAD_REG_T0(base);
5969
    } else {
5970
        GEN_LOAD_REG_T0(base);
5971
        GEN_LOAD_REG_T1(index);
5972
        gen_op_addr_add();
5973
    }
5974
    /* Don't do NOP if destination is zero: we must perform the actual
5975
       memory access. */
5976
    switch (opc) {
5977
    case OPC_LWXC1:
5978
        check_cop1x(ctx);
5979
        op_ldst_lwc1(ctx);
5980
        GEN_STORE_FTN_FREG(fd, WT0);
5981
        opn = "lwxc1";
5982
        break;
5983
    case OPC_LDXC1:
5984
        check_cop1x(ctx);
5985
        check_cp1_registers(ctx, fd);
5986
        op_ldst_ldc1(ctx);
5987
        GEN_STORE_FTN_FREG(fd, DT0);
5988
        opn = "ldxc1";
5989
        break;
5990
    case OPC_LUXC1:
5991
        check_cp1_64bitmode(ctx);
5992
        op_ldst(luxc1);
5993
        GEN_STORE_FTN_FREG(fd, DT0);
5994
        opn = "luxc1";
5995
        break;
5996
    case OPC_SWXC1:
5997
        check_cop1x(ctx);
5998
        GEN_LOAD_FREG_FTN(WT0, fs);
5999
        op_ldst_swc1(ctx);
6000
        opn = "swxc1";
6001
        store = 1;
6002
        break;
6003
    case OPC_SDXC1:
6004
        check_cop1x(ctx);
6005
        check_cp1_registers(ctx, fs);
6006
        GEN_LOAD_FREG_FTN(DT0, fs);
6007
        op_ldst_sdc1(ctx);
6008
        opn = "sdxc1";
6009
        store = 1;
6010
        break;
6011
    case OPC_SUXC1:
6012
        check_cp1_64bitmode(ctx);
6013
        GEN_LOAD_FREG_FTN(DT0, fs);
6014
        op_ldst(suxc1);
6015
        opn = "suxc1";
6016
        store = 1;
6017
        break;
6018
    default:
6019
        MIPS_INVAL(opn);
6020
        generate_exception(ctx, EXCP_RI);
6021
        return;
6022
    }
6023
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6024
               regnames[index], regnames[base]);
6025
}
6026

    
6027
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6028
                            int fd, int fr, int fs, int ft)
6029
{
6030
    const char *opn = "flt3_arith";
6031

    
6032
    switch (opc) {
6033
    case OPC_ALNV_PS:
6034
        check_cp1_64bitmode(ctx);
6035
        GEN_LOAD_REG_T0(fr);
6036
        GEN_LOAD_FREG_FTN(DT0, fs);
6037
        GEN_LOAD_FREG_FTN(DT1, ft);
6038
        gen_op_float_alnv_ps();
6039
        GEN_STORE_FTN_FREG(fd, DT2);
6040
        opn = "alnv.ps";
6041
        break;
6042
    case OPC_MADD_S:
6043
        check_cop1x(ctx);
6044
        GEN_LOAD_FREG_FTN(WT0, fs);
6045
        GEN_LOAD_FREG_FTN(WT1, ft);
6046
        GEN_LOAD_FREG_FTN(WT2, fr);
6047
        gen_op_float_muladd_s();
6048
        GEN_STORE_FTN_FREG(fd, WT2);
6049
        opn = "madd.s";
6050
        break;
6051
    case OPC_MADD_D:
6052
        check_cop1x(ctx);
6053
        check_cp1_registers(ctx, fd | fs | ft | fr);
6054
        GEN_LOAD_FREG_FTN(DT0, fs);
6055
        GEN_LOAD_FREG_FTN(DT1, ft);
6056
        GEN_LOAD_FREG_FTN(DT2, fr);
6057
        gen_op_float_muladd_d();
6058
        GEN_STORE_FTN_FREG(fd, DT2);
6059
        opn = "madd.d";
6060
        break;
6061
    case OPC_MADD_PS:
6062
        check_cp1_64bitmode(ctx);
6063
        GEN_LOAD_FREG_FTN(WT0, fs);
6064
        GEN_LOAD_FREG_FTN(WTH0, fs);
6065
        GEN_LOAD_FREG_FTN(WT1, ft);
6066
        GEN_LOAD_FREG_FTN(WTH1, ft);
6067
        GEN_LOAD_FREG_FTN(WT2, fr);
6068
        GEN_LOAD_FREG_FTN(WTH2, fr);
6069
        gen_op_float_muladd_ps();
6070
        GEN_STORE_FTN_FREG(fd, WT2);
6071
        GEN_STORE_FTN_FREG(fd, WTH2);
6072
        opn = "madd.ps";
6073
        break;
6074
    case OPC_MSUB_S:
6075
        check_cop1x(ctx);
6076
        GEN_LOAD_FREG_FTN(WT0, fs);
6077
        GEN_LOAD_FREG_FTN(WT1, ft);
6078
        GEN_LOAD_FREG_FTN(WT2, fr);
6079
        gen_op_float_mulsub_s();
6080
        GEN_STORE_FTN_FREG(fd, WT2);
6081
        opn = "msub.s";
6082
        break;
6083
    case OPC_MSUB_D:
6084
        check_cop1x(ctx);
6085
        check_cp1_registers(ctx, fd | fs | ft | fr);
6086
        GEN_LOAD_FREG_FTN(DT0, fs);
6087
        GEN_LOAD_FREG_FTN(DT1, ft);
6088
        GEN_LOAD_FREG_FTN(DT2, fr);
6089
        gen_op_float_mulsub_d();
6090
        GEN_STORE_FTN_FREG(fd, DT2);
6091
        opn = "msub.d";
6092
        break;
6093
    case OPC_MSUB_PS:
6094
        check_cp1_64bitmode(ctx);
6095
        GEN_LOAD_FREG_FTN(WT0, fs);
6096
        GEN_LOAD_FREG_FTN(WTH0, fs);
6097
        GEN_LOAD_FREG_FTN(WT1, ft);
6098
        GEN_LOAD_FREG_FTN(WTH1, ft);
6099
        GEN_LOAD_FREG_FTN(WT2, fr);
6100
        GEN_LOAD_FREG_FTN(WTH2, fr);
6101
        gen_op_float_mulsub_ps();
6102
        GEN_STORE_FTN_FREG(fd, WT2);
6103
        GEN_STORE_FTN_FREG(fd, WTH2);
6104
        opn = "msub.ps";
6105
        break;
6106
    case OPC_NMADD_S:
6107
        check_cop1x(ctx);
6108
        GEN_LOAD_FREG_FTN(WT0, fs);
6109
        GEN_LOAD_FREG_FTN(WT1, ft);
6110
        GEN_LOAD_FREG_FTN(WT2, fr);
6111
        gen_op_float_nmuladd_s();
6112
        GEN_STORE_FTN_FREG(fd, WT2);
6113
        opn = "nmadd.s";
6114
        break;
6115
    case OPC_NMADD_D:
6116
        check_cop1x(ctx);
6117
        check_cp1_registers(ctx, fd | fs | ft | fr);
6118
        GEN_LOAD_FREG_FTN(DT0, fs);
6119
        GEN_LOAD_FREG_FTN(DT1, ft);
6120
        GEN_LOAD_FREG_FTN(DT2, fr);
6121
        gen_op_float_nmuladd_d();
6122
        GEN_STORE_FTN_FREG(fd, DT2);
6123
        opn = "nmadd.d";
6124
        break;
6125
    case OPC_NMADD_PS:
6126
        check_cp1_64bitmode(ctx);
6127
        GEN_LOAD_FREG_FTN(WT0, fs);
6128
        GEN_LOAD_FREG_FTN(WTH0, fs);
6129
        GEN_LOAD_FREG_FTN(WT1, ft);
6130
        GEN_LOAD_FREG_FTN(WTH1, ft);
6131
        GEN_LOAD_FREG_FTN(WT2, fr);
6132
        GEN_LOAD_FREG_FTN(WTH2, fr);
6133
        gen_op_float_nmuladd_ps();
6134
        GEN_STORE_FTN_FREG(fd, WT2);
6135
        GEN_STORE_FTN_FREG(fd, WTH2);
6136
        opn = "nmadd.ps";
6137
        break;
6138
    case OPC_NMSUB_S:
6139
        check_cop1x(ctx);
6140
        GEN_LOAD_FREG_FTN(WT0, fs);
6141
        GEN_LOAD_FREG_FTN(WT1, ft);
6142
        GEN_LOAD_FREG_FTN(WT2, fr);
6143
        gen_op_float_nmulsub_s();
6144
        GEN_STORE_FTN_FREG(fd, WT2);
6145
        opn = "nmsub.s";
6146
        break;
6147
    case OPC_NMSUB_D:
6148
        check_cop1x(ctx);
6149
        check_cp1_registers(ctx, fd | fs | ft | fr);
6150
        GEN_LOAD_FREG_FTN(DT0, fs);
6151
        GEN_LOAD_FREG_FTN(DT1, ft);
6152
        GEN_LOAD_FREG_FTN(DT2, fr);
6153
        gen_op_float_nmulsub_d();
6154
        GEN_STORE_FTN_FREG(fd, DT2);
6155
        opn = "nmsub.d";
6156
        break;
6157
    case OPC_NMSUB_PS:
6158
        check_cp1_64bitmode(ctx);
6159
        GEN_LOAD_FREG_FTN(WT0, fs);
6160
        GEN_LOAD_FREG_FTN(WTH0, fs);
6161
        GEN_LOAD_FREG_FTN(WT1, ft);
6162
        GEN_LOAD_FREG_FTN(WTH1, ft);
6163
        GEN_LOAD_FREG_FTN(WT2, fr);
6164
        GEN_LOAD_FREG_FTN(WTH2, fr);
6165
        gen_op_float_nmulsub_ps();
6166
        GEN_STORE_FTN_FREG(fd, WT2);
6167
        GEN_STORE_FTN_FREG(fd, WTH2);
6168
        opn = "nmsub.ps";
6169
        break;
6170
    default:
6171
        MIPS_INVAL(opn);
6172
        generate_exception (ctx, EXCP_RI);
6173
        return;
6174
    }
6175
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6176
               fregnames[fs], fregnames[ft]);
6177
}
6178

    
6179
/* ISA extensions (ASEs) */
6180
/* MIPS16 extension to MIPS32 */
6181
/* SmartMIPS extension to MIPS32 */
6182

    
6183
#if defined(TARGET_MIPS64)
6184

    
6185
/* MDMX extension to MIPS64 */
6186

    
6187
#endif
6188

    
6189
static void decode_opc (CPUState *env, DisasContext *ctx)
6190
{
6191
    int32_t offset;
6192
    int rs, rt, rd, sa;
6193
    uint32_t op, op1, op2;
6194
    int16_t imm;
6195

    
6196
    /* make sure instructions are on a word boundary */
6197
    if (ctx->pc & 0x3) {
6198
        env->CP0_BadVAddr = ctx->pc;
6199
        generate_exception(ctx, EXCP_AdEL);
6200
        return;
6201
    }
6202

    
6203
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6204
        int l1;
6205
        /* Handle blikely not taken case */
6206
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6207
        l1 = gen_new_label();
6208
        tcg_gen_jnz_bcond(l1);
6209
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6210
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6211
        gen_set_label(l1);
6212
    }
6213
    op = MASK_OP_MAJOR(ctx->opcode);
6214
    rs = (ctx->opcode >> 21) & 0x1f;
6215
    rt = (ctx->opcode >> 16) & 0x1f;
6216
    rd = (ctx->opcode >> 11) & 0x1f;
6217
    sa = (ctx->opcode >> 6) & 0x1f;
6218
    imm = (int16_t)ctx->opcode;
6219
    switch (op) {
6220
    case OPC_SPECIAL:
6221
        op1 = MASK_SPECIAL(ctx->opcode);
6222
        switch (op1) {
6223
        case OPC_SLL:          /* Arithmetic with immediate */
6224
        case OPC_SRL ... OPC_SRA:
6225
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6226
            break;
6227
        case OPC_MOVZ ... OPC_MOVN:
6228
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6229
        case OPC_SLLV:         /* Arithmetic */
6230
        case OPC_SRLV ... OPC_SRAV:
6231
        case OPC_ADD ... OPC_NOR:
6232
        case OPC_SLT ... OPC_SLTU:
6233
            gen_arith(env, ctx, op1, rd, rs, rt);
6234
            break;
6235
        case OPC_MULT ... OPC_DIVU:
6236
            if (sa) {
6237
                check_insn(env, ctx, INSN_VR54XX);
6238
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6239
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6240
            } else
6241
                gen_muldiv(ctx, op1, rs, rt);
6242
            break;
6243
        case OPC_JR ... OPC_JALR:
6244
            gen_compute_branch(ctx, op1, rs, rd, sa);
6245
            return;
6246
        case OPC_TGE ... OPC_TEQ: /* Traps */
6247
        case OPC_TNE:
6248
            gen_trap(ctx, op1, rs, rt, -1);
6249
            break;
6250
        case OPC_MFHI:          /* Move from HI/LO */
6251
        case OPC_MFLO:
6252
            gen_HILO(ctx, op1, rd);
6253
            break;
6254
        case OPC_MTHI:
6255
        case OPC_MTLO:          /* Move to HI/LO */
6256
            gen_HILO(ctx, op1, rs);
6257
            break;
6258
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6259
#ifdef MIPS_STRICT_STANDARD
6260
            MIPS_INVAL("PMON / selsl");
6261
            generate_exception(ctx, EXCP_RI);
6262
#else
6263
            gen_op_pmon(sa);
6264
#endif
6265
            break;
6266
        case OPC_SYSCALL:
6267
            generate_exception(ctx, EXCP_SYSCALL);
6268
            break;
6269
        case OPC_BREAK:
6270
            generate_exception(ctx, EXCP_BREAK);
6271
            break;
6272
        case OPC_SPIM:
6273
#ifdef MIPS_STRICT_STANDARD
6274
            MIPS_INVAL("SPIM");
6275
            generate_exception(ctx, EXCP_RI);
6276
#else
6277
           /* Implemented as RI exception for now. */
6278
            MIPS_INVAL("spim (unofficial)");
6279
            generate_exception(ctx, EXCP_RI);
6280
#endif
6281
            break;
6282
        case OPC_SYNC:
6283
            /* Treat as NOP. */
6284
            break;
6285

    
6286
        case OPC_MOVCI:
6287
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6288
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6289
                save_cpu_state(ctx, 1);
6290
                check_cp1_enabled(ctx);
6291
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6292
                          (ctx->opcode >> 16) & 1);
6293
            } else {
6294
                generate_exception_err(ctx, EXCP_CpU, 1);
6295
            }
6296
            break;
6297

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

    
6596
    /* Floating point (COP1). */
6597
    case OPC_LWC1:
6598
    case OPC_LDC1:
6599
    case OPC_SWC1:
6600
    case OPC_SDC1:
6601
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6602
            save_cpu_state(ctx, 1);
6603
            check_cp1_enabled(ctx);
6604
            gen_flt_ldst(ctx, op, rt, rs, imm);
6605
        } else {
6606
            generate_exception_err(ctx, EXCP_CpU, 1);
6607
        }
6608
        break;
6609

    
6610
    case OPC_CP1:
6611
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6612
            save_cpu_state(ctx, 1);
6613
            check_cp1_enabled(ctx);
6614
            op1 = MASK_CP1(ctx->opcode);
6615
            switch (op1) {
6616
            case OPC_MFHC1:
6617
            case OPC_MTHC1:
6618
                check_insn(env, ctx, ISA_MIPS32R2);
6619
            case OPC_MFC1:
6620
            case OPC_CFC1:
6621
            case OPC_MTC1:
6622
            case OPC_CTC1:
6623
                gen_cp1(ctx, op1, rt, rd);
6624
                break;
6625
#if defined(TARGET_MIPS64)
6626
            case OPC_DMFC1:
6627
            case OPC_DMTC1:
6628
                check_insn(env, ctx, ISA_MIPS3);
6629
                gen_cp1(ctx, op1, rt, rd);
6630
                break;
6631
#endif
6632
            case OPC_BC1ANY2:
6633
            case OPC_BC1ANY4:
6634
                check_cop1x(ctx);
6635
                check_insn(env, ctx, ASE_MIPS3D);
6636
                /* fall through */
6637
            case OPC_BC1:
6638
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6639
                                    (rt >> 2) & 0x7, imm << 2);
6640
                return;
6641
            case OPC_S_FMT:
6642
            case OPC_D_FMT:
6643
            case OPC_W_FMT:
6644
            case OPC_L_FMT:
6645
            case OPC_PS_FMT:
6646
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6647
                           (imm >> 8) & 0x7);
6648
                break;
6649
            default:
6650
                MIPS_INVAL("cp1");
6651
                generate_exception (ctx, EXCP_RI);
6652
                break;
6653
            }
6654
        } else {
6655
            generate_exception_err(ctx, EXCP_CpU, 1);
6656
        }
6657
        break;
6658

    
6659
    /* COP2.  */
6660
    case OPC_LWC2:
6661
    case OPC_LDC2:
6662
    case OPC_SWC2:
6663
    case OPC_SDC2:
6664
    case OPC_CP2:
6665
        /* COP2: Not implemented. */
6666
        generate_exception_err(ctx, EXCP_CpU, 2);
6667
        break;
6668

    
6669
    case OPC_CP3:
6670
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6671
            save_cpu_state(ctx, 1);
6672
            check_cp1_enabled(ctx);
6673
            op1 = MASK_CP3(ctx->opcode);
6674
            switch (op1) {
6675
            case OPC_LWXC1:
6676
            case OPC_LDXC1:
6677
            case OPC_LUXC1:
6678
            case OPC_SWXC1:
6679
            case OPC_SDXC1:
6680
            case OPC_SUXC1:
6681
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6682
                break;
6683
            case OPC_PREFX:
6684
                /* Treat as NOP. */
6685
                break;
6686
            case OPC_ALNV_PS:
6687
            case OPC_MADD_S:
6688
            case OPC_MADD_D:
6689
            case OPC_MADD_PS:
6690
            case OPC_MSUB_S:
6691
            case OPC_MSUB_D:
6692
            case OPC_MSUB_PS:
6693
            case OPC_NMADD_S:
6694
            case OPC_NMADD_D:
6695
            case OPC_NMADD_PS:
6696
            case OPC_NMSUB_S:
6697
            case OPC_NMSUB_D:
6698
            case OPC_NMSUB_PS:
6699
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6700
                break;
6701
            default:
6702
                MIPS_INVAL("cp3");
6703
                generate_exception (ctx, EXCP_RI);
6704
                break;
6705
            }
6706
        } else {
6707
            generate_exception_err(ctx, EXCP_CpU, 1);
6708
        }
6709
        break;
6710

    
6711
#if defined(TARGET_MIPS64)
6712
    /* MIPS64 opcodes */
6713
    case OPC_LWU:
6714
    case OPC_LDL ... OPC_LDR:
6715
    case OPC_SDL ... OPC_SDR:
6716
    case OPC_LLD:
6717
    case OPC_LD:
6718
    case OPC_SCD:
6719
    case OPC_SD:
6720
        check_insn(env, ctx, ISA_MIPS3);
6721
        check_mips_64(ctx);
6722
        gen_ldst(ctx, op, rt, rs, imm);
6723
        break;
6724
    case OPC_DADDI ... OPC_DADDIU:
6725
        check_insn(env, ctx, ISA_MIPS3);
6726
        check_mips_64(ctx);
6727
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6728
        break;
6729
#endif
6730
    case OPC_JALX:
6731
        check_insn(env, ctx, ASE_MIPS16);
6732
        /* MIPS16: Not implemented. */
6733
    case OPC_MDMX:
6734
        check_insn(env, ctx, ASE_MDMX);
6735
        /* MDMX: Not implemented. */
6736
    default:            /* Invalid */
6737
        MIPS_INVAL("major opcode");
6738
        generate_exception(ctx, EXCP_RI);
6739
        break;
6740
    }
6741
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6742
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6743
        /* Branches completion */
6744
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6745
        ctx->bstate = BS_BRANCH;
6746
        save_cpu_state(ctx, 0);
6747
        switch (hflags) {
6748
        case MIPS_HFLAG_B:
6749
            /* unconditional branch */
6750
            MIPS_DEBUG("unconditional branch");
6751
            gen_goto_tb(ctx, 0, ctx->btarget);
6752
            break;
6753
        case MIPS_HFLAG_BL:
6754
            /* blikely taken case */
6755
            MIPS_DEBUG("blikely branch taken");
6756
            gen_goto_tb(ctx, 0, ctx->btarget);
6757
            break;
6758
        case MIPS_HFLAG_BC:
6759
            /* Conditional branch */
6760
            MIPS_DEBUG("conditional branch");
6761
            {
6762
              int l1;
6763
              l1 = gen_new_label();
6764
              tcg_gen_jnz_bcond(l1);
6765
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6766
              gen_set_label(l1);
6767
              gen_goto_tb(ctx, 0, ctx->btarget);
6768
            }
6769
            break;
6770
        case MIPS_HFLAG_BR:
6771
            /* unconditional branch to register */
6772
            MIPS_DEBUG("branch to register");
6773
            gen_op_breg();
6774
            tcg_gen_exit_tb(0);
6775
            break;
6776
        default:
6777
            MIPS_DEBUG("unknown branch");
6778
            break;
6779
        }
6780
    }
6781
}
6782

    
6783
static always_inline int
6784
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6785
                                int search_pc)
6786
{
6787
    DisasContext ctx;
6788
    target_ulong pc_start;
6789
    uint16_t *gen_opc_end;
6790
    int j, lj = -1;
6791

    
6792
    if (search_pc && loglevel)
6793
        fprintf (logfile, "search pc %d\n", search_pc);
6794

    
6795
    pc_start = tb->pc;
6796
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6797
    ctx.pc = pc_start;
6798
    ctx.saved_pc = -1;
6799
    ctx.tb = tb;
6800
    ctx.bstate = BS_NONE;
6801
    /* Restore delay slot state from the tb context.  */
6802
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6803
    restore_cpu_state(env, &ctx);
6804
#if defined(CONFIG_USER_ONLY)
6805
    ctx.mem_idx = MIPS_HFLAG_UM;
6806
#else
6807
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6808
#endif
6809
#ifdef DEBUG_DISAS
6810
    if (loglevel & CPU_LOG_TB_CPU) {
6811
        fprintf(logfile, "------------------------------------------------\n");
6812
        /* FIXME: This may print out stale hflags from env... */
6813
        cpu_dump_state(env, logfile, fprintf, 0);
6814
    }
6815
#endif
6816
#ifdef MIPS_DEBUG_DISAS
6817
    if (loglevel & CPU_LOG_TB_IN_ASM)
6818
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6819
                tb, ctx.mem_idx, ctx.hflags);
6820
#endif
6821
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6822
        if (env->nb_breakpoints > 0) {
6823
            for(j = 0; j < env->nb_breakpoints; j++) {
6824
                if (env->breakpoints[j] == ctx.pc) {
6825
                    save_cpu_state(&ctx, 1);
6826
                    ctx.bstate = BS_BRANCH;
6827
                    gen_op_debug();
6828
                    /* Include the breakpoint location or the tb won't
6829
                     * be flushed when it must be.  */
6830
                    ctx.pc += 4;
6831
                    goto done_generating;
6832
                }
6833
            }
6834
        }
6835

    
6836
        if (search_pc) {
6837
            j = gen_opc_ptr - gen_opc_buf;
6838
            if (lj < j) {
6839
                lj++;
6840
                while (lj < j)
6841
                    gen_opc_instr_start[lj++] = 0;
6842
            }
6843
            gen_opc_pc[lj] = ctx.pc;
6844
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6845
            gen_opc_instr_start[lj] = 1;
6846
        }
6847
        ctx.opcode = ldl_code(ctx.pc);
6848
        decode_opc(env, &ctx);
6849
        ctx.pc += 4;
6850

    
6851
        if (env->singlestep_enabled)
6852
            break;
6853

    
6854
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6855
            break;
6856

    
6857
#if defined (MIPS_SINGLE_STEP)
6858
        break;
6859
#endif
6860
    }
6861
    if (env->singlestep_enabled) {
6862
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6863
        gen_op_debug();
6864
    } else {
6865
        switch (ctx.bstate) {
6866
        case BS_STOP:
6867
            gen_op_interrupt_restart();
6868
            gen_goto_tb(&ctx, 0, ctx.pc);
6869
            break;
6870
        case BS_NONE:
6871
            save_cpu_state(&ctx, 0);
6872
            gen_goto_tb(&ctx, 0, ctx.pc);
6873
            break;
6874
        case BS_EXCP:
6875
            gen_op_interrupt_restart();
6876
            tcg_gen_exit_tb(0);
6877
            break;
6878
        case BS_BRANCH:
6879
        default:
6880
            break;
6881
        }
6882
    }
6883
done_generating:
6884
    ctx.last_T0_store = NULL;
6885
    *gen_opc_ptr = INDEX_op_end;
6886
    if (search_pc) {
6887
        j = gen_opc_ptr - gen_opc_buf;
6888
        lj++;
6889
        while (lj <= j)
6890
            gen_opc_instr_start[lj++] = 0;
6891
    } else {
6892
        tb->size = ctx.pc - pc_start;
6893
    }
6894
#ifdef DEBUG_DISAS
6895
#if defined MIPS_DEBUG_DISAS
6896
    if (loglevel & CPU_LOG_TB_IN_ASM)
6897
        fprintf(logfile, "\n");
6898
#endif
6899
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6900
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6901
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6902
        fprintf(logfile, "\n");
6903
    }
6904
    if (loglevel & CPU_LOG_TB_CPU) {
6905
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6906
    }
6907
#endif
6908

    
6909
    return 0;
6910
}
6911

    
6912
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6913
{
6914
    return gen_intermediate_code_internal(env, tb, 0);
6915
}
6916

    
6917
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6918
{
6919
    return gen_intermediate_code_internal(env, tb, 1);
6920
}
6921

    
6922
void fpu_dump_state(CPUState *env, FILE *f,
6923
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6924
                    int flags)
6925
{
6926
    int i;
6927
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6928

    
6929
#define printfpr(fp)                                                        \
6930
    do {                                                                    \
6931
        if (is_fpu64)                                                       \
6932
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6933
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6934
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6935
        else {                                                              \
6936
            fpr_t tmp;                                                      \
6937
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6938
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6939
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6940
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6941
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6942
        }                                                                   \
6943
    } while(0)
6944

    
6945

    
6946
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6947
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6948
                get_float_exception_flags(&env->fpu->fp_status));
6949
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6950
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6951
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6952
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6953
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6954
        printfpr(&env->fpu->fpr[i]);
6955
    }
6956

    
6957
#undef printfpr
6958
}
6959

    
6960
void dump_fpu (CPUState *env)
6961
{
6962
    if (loglevel) {
6963
        fprintf(logfile,
6964
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
6965
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
6966
                " %04x\n",
6967
                env->PC[env->current_tc], env->HI[env->current_tc][0],
6968
                env->LO[env->current_tc][0], env->hflags, env->btarget,
6969
                env->bcond);
6970
       fpu_dump_state(env, logfile, fprintf, 0);
6971
    }
6972
}
6973

    
6974
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6975
/* Debug help: The architecture requires 32bit code to maintain proper
6976
   sign-extened values on 64bit machines.  */
6977

    
6978
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6979

    
6980
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6981
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6982
                     int flags)
6983
{
6984
    int i;
6985

    
6986
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6987
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6988
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
6989
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
6990
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
6991
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
6992
    if (!SIGN_EXT_P(env->btarget))
6993
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6994

    
6995
    for (i = 0; i < 32; i++) {
6996
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
6997
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
6998
    }
6999

    
7000
    if (!SIGN_EXT_P(env->CP0_EPC))
7001
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7002
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7003
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7004
}
7005
#endif
7006

    
7007
void cpu_dump_state (CPUState *env, FILE *f,
7008
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7009
                     int flags)
7010
{
7011
    int i;
7012

    
7013
    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",
7014
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7015
    for (i = 0; i < 32; i++) {
7016
        if ((i & 3) == 0)
7017
            cpu_fprintf(f, "GPR%02d:", i);
7018
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7019
        if ((i & 3) == 3)
7020
            cpu_fprintf(f, "\n");
7021
    }
7022

    
7023
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7024
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7025
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7026
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7027
    if (env->hflags & MIPS_HFLAG_FPU)
7028
        fpu_dump_state(env, f, cpu_fprintf, flags);
7029
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7030
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7031
#endif
7032
}
7033

    
7034
static void mips_tcg_init(void)
7035
{
7036
    static int inited;
7037

    
7038
    /* Initialize various static tables. */
7039
    if (inited)
7040
        return;
7041

    
7042
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7043
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7044
                                         TCG_AREG0,
7045
                                         offsetof(CPUState, current_tc_gprs),
7046
                                         "current_tc_gprs");
7047
#if TARGET_LONG_BITS > HOST_LONG_BITS
7048
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7049
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7050
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7051
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7052
#else
7053
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7054
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7055
#endif
7056

    
7057
    inited = 1;
7058
}
7059

    
7060
#include "translate_init.c"
7061

    
7062
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7063
{
7064
    CPUMIPSState *env;
7065
    const mips_def_t *def;
7066

    
7067
    def = cpu_mips_find_by_name(cpu_model);
7068
    if (!def)
7069
        return NULL;
7070
    env = qemu_mallocz(sizeof(CPUMIPSState));
7071
    if (!env)
7072
        return NULL;
7073
    env->cpu_model = def;
7074

    
7075
    cpu_exec_init(env);
7076
    env->cpu_model_str = cpu_model;
7077
    mips_tcg_init();
7078
    cpu_reset(env);
7079
    return env;
7080
}
7081

    
7082
void cpu_reset (CPUMIPSState *env)
7083
{
7084
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7085

    
7086
    tlb_flush(env, 1);
7087

    
7088
    /* Minimal init */
7089
#if !defined(CONFIG_USER_ONLY)
7090
    if (env->hflags & MIPS_HFLAG_BMASK) {
7091
        /* If the exception was raised from a delay slot,
7092
         * come back to the jump.  */
7093
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7094
    } else {
7095
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7096
    }
7097
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7098
    env->CP0_Wired = 0;
7099
    /* SMP not implemented */
7100
    env->CP0_EBase = 0x80000000;
7101
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7102
    /* vectored interrupts not implemented, timer on int 7,
7103
       no performance counters. */
7104
    env->CP0_IntCtl = 0xe0000000;
7105
    {
7106
        int i;
7107

    
7108
        for (i = 0; i < 7; i++) {
7109
            env->CP0_WatchLo[i] = 0;
7110
            env->CP0_WatchHi[i] = 0x80000000;
7111
        }
7112
        env->CP0_WatchLo[7] = 0;
7113
        env->CP0_WatchHi[7] = 0;
7114
    }
7115
    /* Count register increments in debug mode, EJTAG version 1 */
7116
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7117
#endif
7118
    env->exception_index = EXCP_NONE;
7119
#if defined(CONFIG_USER_ONLY)
7120
    env->hflags = MIPS_HFLAG_UM;
7121
    env->user_mode_only = 1;
7122
#else
7123
    env->hflags = MIPS_HFLAG_CP0;
7124
#endif
7125
    cpu_mips_register(env, env->cpu_model);
7126
}
7127

    
7128
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7129
                unsigned long searched_pc, int pc_pos, void *puc)
7130
{
7131
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7132
    env->hflags &= ~MIPS_HFLAG_BMASK;
7133
    env->hflags |= gen_opc_hflags[pc_pos];
7134
}