Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a4a99d71

History | View | Annotate | Download (219.8 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
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 "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
428
/* The code generator doesn't like lots of temporaries, so maintain our own
429
   cache for reuse within a function.  */
430
#define MAX_TEMPS 4
431
static int num_temps;
432
static TCGv temps[MAX_TEMPS];
433

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

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

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

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

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

    
468
typedef struct DisasContext {
469
    struct TranslationBlock *tb;
470
    target_ulong pc, saved_pc;
471
    uint32_t opcode;
472
    uint32_t fp_status;
473
    /* Routine used to access memory */
474
    int mem_idx;
475
    uint32_t hflags, saved_hflags;
476
    int bstate;
477
    target_ulong btarget;
478
} DisasContext;
479

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

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

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

    
501
#ifdef MIPS_DEBUG_DISAS
502
#define MIPS_DEBUG(fmt, args...)                                              \
503
do {                                                                          \
504
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
505
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
506
                ctx->pc, ctx->opcode , ##args);                               \
507
    }                                                                         \
508
} while (0)
509
#else
510
#define MIPS_DEBUG(fmt, args...) do { } while(0)
511
#endif
512

    
513
#define MIPS_INVAL(op)                                                        \
514
do {                                                                          \
515
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
516
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
517
} while (0)
518

    
519
/* General purpose registers moves. */
520
static inline void gen_load_gpr (TCGv t, int reg)
521
{
522
    if (reg == 0)
523
        tcg_gen_movi_tl(t, 0);
524
    else
525
        tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
526
}
527

    
528
static inline void gen_store_gpr (TCGv t, int reg)
529
{
530
    if (reg != 0)
531
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
532
}
533

    
534
/* Moves to/from HI and LO registers.  */
535
static inline void gen_load_LO (TCGv t, int reg)
536
{
537
    tcg_gen_ld_tl(t, current_tc_hi,
538
                  offsetof(CPUState, LO)
539
                  - offsetof(CPUState, HI)
540
                  + sizeof(target_ulong) * reg);
541
}
542

    
543
static inline void gen_store_LO (TCGv t, int reg)
544
{
545
    tcg_gen_st_tl(t, current_tc_hi,
546
                  offsetof(CPUState, LO)
547
                  - offsetof(CPUState, HI)
548
                  + sizeof(target_ulong) * reg);
549
}
550

    
551
static inline void gen_load_HI (TCGv t, int reg)
552
{
553
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
554
}
555

    
556
static inline void gen_store_HI (TCGv t, int reg)
557
{
558
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
559
}
560

    
561
/* Moves to/from shadow registers. */
562
static inline void gen_load_srsgpr (TCGv t, int reg)
563
{
564
    if (reg == 0)
565
        tcg_gen_movi_tl(t, 0);
566
    else {
567
        TCGv r_tmp = new_tmp();
568

    
569
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
570
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
571
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
572
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
573
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
574

    
575
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
576
        dead_tmp(r_tmp);
577
    }
578
}
579

    
580
static inline void gen_store_srsgpr (TCGv t, int reg)
581
{
582
    if (reg != 0) {
583
        TCGv r_tmp = new_tmp();
584

    
585
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
586
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
587
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
588
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
589
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
590

    
591
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
592
        dead_tmp(r_tmp);
593
    }
594
}
595

    
596
/* Floating point register moves. */
597
#define FGEN32(func, NAME)                       \
598
static GenOpFunc *NAME ## _table [32] = {        \
599
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
600
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
601
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
602
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
603
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
604
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
605
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
606
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
607
};                                               \
608
static always_inline void func(int n)            \
609
{                                                \
610
    NAME ## _table[n]();                         \
611
}
612

    
613
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
614
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
615

    
616
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
617
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
618

    
619
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
620
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
621

    
622
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
623
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
624

    
625
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
626
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
627

    
628
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
629
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
630

    
631
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
632
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
633

    
634
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
635
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
636

    
637
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
638
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
639

    
640
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
641
do {                                                                          \
642
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
643
} while (0)
644

    
645
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
646
do {                                                                          \
647
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
648
} while (0)
649

    
650
#define FOP_CONDS(type, fmt)                                            \
651
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
652
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
653
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
654
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
655
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
656
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
657
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
658
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
659
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
660
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
661
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
662
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
663
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
664
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
665
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
666
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
667
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
668
};                                                                      \
669
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
670
{                                                                       \
671
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
672
}
673

    
674
FOP_CONDS(, d)
675
FOP_CONDS(abs, d)
676
FOP_CONDS(, s)
677
FOP_CONDS(abs, s)
678
FOP_CONDS(, ps)
679
FOP_CONDS(abs, ps)
680

    
681
/* Tests */
682
#define OP_COND(name, cond)                                   \
683
void glue(gen_op_, name) (void)                               \
684
{                                                             \
685
    int l1 = gen_new_label();                                 \
686
    int l2 = gen_new_label();                                 \
687
                                                              \
688
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
689
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
690
    tcg_gen_br(l2);                                           \
691
    gen_set_label(l1);                                        \
692
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
693
    gen_set_label(l2);                                        \
694
}
695
OP_COND(eq, TCG_COND_EQ);
696
OP_COND(ne, TCG_COND_NE);
697
OP_COND(ge, TCG_COND_GE);
698
OP_COND(geu, TCG_COND_GEU);
699
OP_COND(lt, TCG_COND_LT);
700
OP_COND(ltu, TCG_COND_LTU);
701
#undef OP_COND
702

    
703
#define OP_CONDI(name, cond)                                  \
704
void glue(gen_op_, name) (target_ulong val)                   \
705
{                                                             \
706
    int l1 = gen_new_label();                                 \
707
    int l2 = gen_new_label();                                 \
708
                                                              \
709
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
710
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
711
    tcg_gen_br(l2);                                           \
712
    gen_set_label(l1);                                        \
713
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
714
    gen_set_label(l2);                                        \
715
}
716
OP_CONDI(lti, TCG_COND_LT);
717
OP_CONDI(ltiu, TCG_COND_LTU);
718
#undef OP_CONDI
719

    
720
#define OP_CONDZ(name, cond)                                  \
721
void glue(gen_op_, name) (void)                               \
722
{                                                             \
723
    int l1 = gen_new_label();                                 \
724
    int l2 = gen_new_label();                                 \
725
                                                              \
726
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
727
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
728
    tcg_gen_br(l2);                                           \
729
    gen_set_label(l1);                                        \
730
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
731
    gen_set_label(l2);                                        \
732
}
733
OP_CONDZ(gez, TCG_COND_GE);
734
OP_CONDZ(gtz, TCG_COND_GT);
735
OP_CONDZ(lez, TCG_COND_LE);
736
OP_CONDZ(ltz, TCG_COND_LT);
737
#undef OP_CONDZ
738

    
739
static inline void gen_save_pc(target_ulong pc)
740
{
741
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
742
    TCGv r_tc_off = new_tmp();
743
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
744
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
745

    
746
    tcg_gen_movi_tl(r_tmp, pc);
747
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
748
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
749
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
750
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
751
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
752
    dead_tmp(r_tc_off);
753
}
754

    
755
static inline void gen_breg_pc(void)
756
{
757
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
758
    TCGv r_tc_off = new_tmp();
759
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
760
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
761

    
762
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
763
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
764
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
765
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
766
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
767
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
768
    dead_tmp(r_tc_off);
769
}
770

    
771
static inline void gen_save_btarget(target_ulong btarget)
772
{
773
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
774

    
775
    tcg_gen_movi_tl(r_tmp, btarget);
776
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
777
}
778

    
779
static always_inline void gen_save_breg_target(int reg)
780
{
781
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
782

    
783
    gen_load_gpr(r_tmp, reg);
784
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
785
}
786

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

    
814
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
815
{
816
    ctx->saved_hflags = ctx->hflags;
817
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
818
    case MIPS_HFLAG_BR:
819
        break;
820
    case MIPS_HFLAG_BC:
821
    case MIPS_HFLAG_BL:
822
    case MIPS_HFLAG_B:
823
        ctx->btarget = env->btarget;
824
        break;
825
    }
826
}
827

    
828
static always_inline void
829
generate_exception_err (DisasContext *ctx, int excp, int err)
830
{
831
    save_cpu_state(ctx, 1);
832
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
833
    tcg_gen_helper_0_0(do_interrupt_restart);
834
    tcg_gen_exit_tb(0);
835
}
836

    
837
static always_inline void
838
generate_exception (DisasContext *ctx, int excp)
839
{
840
    save_cpu_state(ctx, 1);
841
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
842
    tcg_gen_helper_0_0(do_interrupt_restart);
843
    tcg_gen_exit_tb(0);
844
}
845

    
846
/* Addresses computation */
847
static inline void gen_op_addr_add (void)
848
{
849
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
850

    
851
#if defined(TARGET_MIPS64)
852
    /* For compatibility with 32-bit code, data reference in user mode
853
       with Status_UX = 0 should be casted to 32-bit and sign extended.
854
       See the MIPS64 PRA manual, section 4.10. */
855
    {
856
        TCGv r_tmp = new_tmp();
857
        int l1 = gen_new_label();
858

    
859
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
860
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
861
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
862
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
863
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
864
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
865
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
866
        gen_set_label(l1);
867
        dead_tmp(r_tmp);
868
    }
869
#endif
870
}
871

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1268
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1269
        /* If no destination, treat it as a NOP.
1270
           For addi, we must generate the overflow exception when needed. */
1271
        MIPS_DEBUG("NOP");
1272
        return;
1273
    }
1274
    uimm = (uint16_t)imm;
1275
    switch (opc) {
1276
    case OPC_ADDI:
1277
    case OPC_ADDIU:
1278
#if defined(TARGET_MIPS64)
1279
    case OPC_DADDI:
1280
    case OPC_DADDIU:
1281
#endif
1282
    case OPC_SLTI:
1283
    case OPC_SLTIU:
1284
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1285
        tcg_gen_movi_tl(cpu_T[1], uimm);
1286
        /* Fall through. */
1287
    case OPC_ANDI:
1288
    case OPC_ORI:
1289
    case OPC_XORI:
1290
        gen_load_gpr(cpu_T[0], rs);
1291
        break;
1292
    case OPC_LUI:
1293
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1294
        break;
1295
    case OPC_SLL:
1296
    case OPC_SRA:
1297
    case OPC_SRL:
1298
#if defined(TARGET_MIPS64)
1299
    case OPC_DSLL:
1300
    case OPC_DSRA:
1301
    case OPC_DSRL:
1302
    case OPC_DSLL32:
1303
    case OPC_DSRA32:
1304
    case OPC_DSRL32:
1305
#endif
1306
        uimm &= 0x1f;
1307
        gen_load_gpr(cpu_T[0], rs);
1308
        break;
1309
    }
1310
    switch (opc) {
1311
    case OPC_ADDI:
1312
        {
1313
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1314
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1315
            int l1 = gen_new_label();
1316

    
1317
            save_cpu_state(ctx, 1);
1318
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1319
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1320

    
1321
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1322
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1323
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1324
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1325
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1326
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1327
            /* operands of same sign, result different sign */
1328
            generate_exception(ctx, EXCP_OVERFLOW);
1329
            gen_set_label(l1);
1330

    
1331
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1332
        }
1333
        opn = "addi";
1334
        break;
1335
    case OPC_ADDIU:
1336
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1337
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1338
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1339
        opn = "addiu";
1340
        break;
1341
#if defined(TARGET_MIPS64)
1342
    case OPC_DADDI:
1343
        {
1344
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1345
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1346
            int l1 = gen_new_label();
1347

    
1348
            save_cpu_state(ctx, 1);
1349
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1350
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1351

    
1352
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1353
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1354
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1355
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1356
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1357
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1358
            /* operands of same sign, result different sign */
1359
            generate_exception(ctx, EXCP_OVERFLOW);
1360
            gen_set_label(l1);
1361
        }
1362
        opn = "daddi";
1363
        break;
1364
    case OPC_DADDIU:
1365
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1366
        opn = "daddiu";
1367
        break;
1368
#endif
1369
    case OPC_SLTI:
1370
        gen_op_lti(uimm);
1371
        opn = "slti";
1372
        break;
1373
    case OPC_SLTIU:
1374
        gen_op_ltiu(uimm);
1375
        opn = "sltiu";
1376
        break;
1377
    case OPC_ANDI:
1378
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1379
        opn = "andi";
1380
        break;
1381
    case OPC_ORI:
1382
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1383
        opn = "ori";
1384
        break;
1385
    case OPC_XORI:
1386
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1387
        opn = "xori";
1388
        break;
1389
    case OPC_LUI:
1390
        opn = "lui";
1391
        break;
1392
    case OPC_SLL:
1393
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1394
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1395
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1396
        opn = "sll";
1397
        break;
1398
    case OPC_SRA:
1399
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1400
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1401
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1402
        opn = "sra";
1403
        break;
1404
    case OPC_SRL:
1405
        switch ((ctx->opcode >> 21) & 0x1f) {
1406
        case 0:
1407
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1408
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1409
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1410
            opn = "srl";
1411
            break;
1412
        case 1:
1413
            /* rotr is decoded as srl on non-R2 CPUs */
1414
            if (env->insn_flags & ISA_MIPS32R2) {
1415
                if (uimm != 0) {
1416
                    TCGv r_tmp1 = new_tmp();
1417
                    TCGv r_tmp2 = new_tmp();
1418

    
1419
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1420
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1421
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1422
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1423
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1424
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1425
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1426
                    dead_tmp(r_tmp1);
1427
                    dead_tmp(r_tmp2);
1428
                }
1429
                opn = "rotr";
1430
            } else {
1431
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1432
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1433
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1434
                opn = "srl";
1435
            }
1436
            break;
1437
        default:
1438
            MIPS_INVAL("invalid srl flag");
1439
            generate_exception(ctx, EXCP_RI);
1440
            break;
1441
        }
1442
        break;
1443
#if defined(TARGET_MIPS64)
1444
    case OPC_DSLL:
1445
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1446
        opn = "dsll";
1447
        break;
1448
    case OPC_DSRA:
1449
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1450
        opn = "dsra";
1451
        break;
1452
    case OPC_DSRL:
1453
        switch ((ctx->opcode >> 21) & 0x1f) {
1454
        case 0:
1455
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1456
            opn = "dsrl";
1457
            break;
1458
        case 1:
1459
            /* drotr is decoded as dsrl on non-R2 CPUs */
1460
            if (env->insn_flags & ISA_MIPS32R2) {
1461
                if (uimm != 0) {
1462
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1463

    
1464
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1465
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1466
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1467
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1468
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1469
                }
1470
                opn = "drotr";
1471
            } else {
1472
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1473
                opn = "dsrl";
1474
            }
1475
            break;
1476
        default:
1477
            MIPS_INVAL("invalid dsrl flag");
1478
            generate_exception(ctx, EXCP_RI);
1479
            break;
1480
        }
1481
        break;
1482
    case OPC_DSLL32:
1483
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1484
        opn = "dsll32";
1485
        break;
1486
    case OPC_DSRA32:
1487
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1488
        opn = "dsra32";
1489
        break;
1490
    case OPC_DSRL32:
1491
        switch ((ctx->opcode >> 21) & 0x1f) {
1492
        case 0:
1493
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1494
            opn = "dsrl32";
1495
            break;
1496
        case 1:
1497
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1498
            if (env->insn_flags & ISA_MIPS32R2) {
1499
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1500
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1501

    
1502
                tcg_gen_movi_tl(r_tmp1, 0x40);
1503
                tcg_gen_movi_tl(r_tmp2, 32);
1504
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1505
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1506
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1507
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1508
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1509
                opn = "drotr32";
1510
            } else {
1511
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1512
                opn = "dsrl32";
1513
            }
1514
            break;
1515
        default:
1516
            MIPS_INVAL("invalid dsrl32 flag");
1517
            generate_exception(ctx, EXCP_RI);
1518
            break;
1519
        }
1520
        break;
1521
#endif
1522
    default:
1523
        MIPS_INVAL(opn);
1524
        generate_exception(ctx, EXCP_RI);
1525
        return;
1526
    }
1527
    gen_store_gpr(cpu_T[0], rt);
1528
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1529
}
1530

    
1531
/* Arithmetic */
1532
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1533
                       int rd, int rs, int rt)
1534
{
1535
    const char *opn = "arith";
1536

    
1537
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1538
       && opc != OPC_DADD && opc != OPC_DSUB) {
1539
        /* If no destination, treat it as a NOP.
1540
           For add & sub, we must generate the overflow exception when needed. */
1541
        MIPS_DEBUG("NOP");
1542
        return;
1543
    }
1544
    gen_load_gpr(cpu_T[0], rs);
1545
    /* Specialcase the conventional move operation. */
1546
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1547
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1548
        gen_store_gpr(cpu_T[0], rd);
1549
        return;
1550
    }
1551
    gen_load_gpr(cpu_T[1], rt);
1552
    switch (opc) {
1553
    case OPC_ADD:
1554
        {
1555
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1556
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1557
            int l1 = gen_new_label();
1558

    
1559
            save_cpu_state(ctx, 1);
1560
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1561
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1562
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1563

    
1564
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1565
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1566
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1567
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1568
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1569
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1570
            /* operands of same sign, result different sign */
1571
            generate_exception(ctx, EXCP_OVERFLOW);
1572
            gen_set_label(l1);
1573

    
1574
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1575
        }
1576
        opn = "add";
1577
        break;
1578
    case OPC_ADDU:
1579
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1580
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1581
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1582
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1583
        opn = "addu";
1584
        break;
1585
    case OPC_SUB:
1586
        {
1587
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1588
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1589
            int l1 = gen_new_label();
1590

    
1591
            save_cpu_state(ctx, 1);
1592
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1593
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1594
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1595

    
1596
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1597
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1598
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1599
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1600
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1601
            /* operands of different sign, first operand and result different sign */
1602
            generate_exception(ctx, EXCP_OVERFLOW);
1603
            gen_set_label(l1);
1604

    
1605
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1606
        }
1607
        opn = "sub";
1608
        break;
1609
    case OPC_SUBU:
1610
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1611
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1612
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1613
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1614
        opn = "subu";
1615
        break;
1616
#if defined(TARGET_MIPS64)
1617
    case OPC_DADD:
1618
        {
1619
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1620
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1621
            int l1 = gen_new_label();
1622

    
1623
            save_cpu_state(ctx, 1);
1624
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1625
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1626

    
1627
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1628
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1629
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1630
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1631
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1632
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1633
            /* operands of same sign, result different sign */
1634
            generate_exception(ctx, EXCP_OVERFLOW);
1635
            gen_set_label(l1);
1636
        }
1637
        opn = "dadd";
1638
        break;
1639
    case OPC_DADDU:
1640
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1641
        opn = "daddu";
1642
        break;
1643
    case OPC_DSUB:
1644
        {
1645
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1646
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1647
            int l1 = gen_new_label();
1648

    
1649
            save_cpu_state(ctx, 1);
1650
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1651
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1652

    
1653
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1654
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1655
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1656
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1657
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1658
            /* operands of different sign, first operand and result different sign */
1659
            generate_exception(ctx, EXCP_OVERFLOW);
1660
            gen_set_label(l1);
1661
        }
1662
        opn = "dsub";
1663
        break;
1664
    case OPC_DSUBU:
1665
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1666
        opn = "dsubu";
1667
        break;
1668
#endif
1669
    case OPC_SLT:
1670
        gen_op_lt();
1671
        opn = "slt";
1672
        break;
1673
    case OPC_SLTU:
1674
        gen_op_ltu();
1675
        opn = "sltu";
1676
        break;
1677
    case OPC_AND:
1678
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1679
        opn = "and";
1680
        break;
1681
    case OPC_NOR:
1682
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1683
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1684
        opn = "nor";
1685
        break;
1686
    case OPC_OR:
1687
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1688
        opn = "or";
1689
        break;
1690
    case OPC_XOR:
1691
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1692
        opn = "xor";
1693
        break;
1694
    case OPC_MUL:
1695
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1696
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1697
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1698
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1699
        opn = "mul";
1700
        break;
1701
    case OPC_MOVN:
1702
        {
1703
            int l1 = gen_new_label();
1704

    
1705
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1706
            gen_store_gpr(cpu_T[0], rd);
1707
            gen_set_label(l1);
1708
        }
1709
        opn = "movn";
1710
        goto print;
1711
    case OPC_MOVZ:
1712
        {
1713
            int l1 = gen_new_label();
1714

    
1715
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1716
            gen_store_gpr(cpu_T[0], rd);
1717
            gen_set_label(l1);
1718
        }
1719
        opn = "movz";
1720
        goto print;
1721
    case OPC_SLLV:
1722
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1723
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1724
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1725
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1726
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1727
        opn = "sllv";
1728
        break;
1729
    case OPC_SRAV:
1730
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1731
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1732
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1733
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1734
        opn = "srav";
1735
        break;
1736
    case OPC_SRLV:
1737
        switch ((ctx->opcode >> 6) & 0x1f) {
1738
        case 0:
1739
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1740
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1741
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1742
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1743
            opn = "srlv";
1744
            break;
1745
        case 1:
1746
            /* rotrv is decoded as srlv on non-R2 CPUs */
1747
            if (env->insn_flags & ISA_MIPS32R2) {
1748
                int l1 = gen_new_label();
1749
                int l2 = gen_new_label();
1750

    
1751
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1752
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1753
                {
1754
                    TCGv r_tmp1 = new_tmp();
1755
                    TCGv r_tmp2 = new_tmp();
1756
                    TCGv r_tmp3 = new_tmp();
1757

    
1758
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1759
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1760
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1761
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1762
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1763
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1764
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1765
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1766
                    dead_tmp(r_tmp1);
1767
                    dead_tmp(r_tmp2);
1768
                    dead_tmp(r_tmp3);
1769
                    tcg_gen_br(l2);
1770
                }
1771
                gen_set_label(l1);
1772
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1773
                gen_set_label(l2);
1774
                opn = "rotrv";
1775
            } else {
1776
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1777
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1778
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1779
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1780
                opn = "srlv";
1781
            }
1782
            break;
1783
        default:
1784
            MIPS_INVAL("invalid srlv flag");
1785
            generate_exception(ctx, EXCP_RI);
1786
            break;
1787
        }
1788
        break;
1789
#if defined(TARGET_MIPS64)
1790
    case OPC_DSLLV:
1791
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1792
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1793
        opn = "dsllv";
1794
        break;
1795
    case OPC_DSRAV:
1796
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1797
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1798
        opn = "dsrav";
1799
        break;
1800
    case OPC_DSRLV:
1801
        switch ((ctx->opcode >> 6) & 0x1f) {
1802
        case 0:
1803
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1804
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1805
            opn = "dsrlv";
1806
            break;
1807
        case 1:
1808
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1809
            if (env->insn_flags & ISA_MIPS32R2) {
1810
                int l1 = gen_new_label();
1811
                int l2 = gen_new_label();
1812

    
1813
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1814
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1815
                {
1816
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1817

    
1818
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1819
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1820
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1821
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1822
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1823
                    tcg_gen_br(l2);
1824
                }
1825
                gen_set_label(l1);
1826
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1827
                gen_set_label(l2);
1828
                opn = "drotrv";
1829
            } else {
1830
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1831
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1832
                opn = "dsrlv";
1833
            }
1834
            break;
1835
        default:
1836
            MIPS_INVAL("invalid dsrlv flag");
1837
            generate_exception(ctx, EXCP_RI);
1838
            break;
1839
        }
1840
        break;
1841
#endif
1842
    default:
1843
        MIPS_INVAL(opn);
1844
        generate_exception(ctx, EXCP_RI);
1845
        return;
1846
    }
1847
    gen_store_gpr(cpu_T[0], rd);
1848
 print:
1849
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1850
}
1851

    
1852
/* Arithmetic on HI/LO registers */
1853
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1854
{
1855
    const char *opn = "hilo";
1856

    
1857
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1858
        /* Treat as NOP. */
1859
        MIPS_DEBUG("NOP");
1860
        return;
1861
    }
1862
    switch (opc) {
1863
    case OPC_MFHI:
1864
        gen_load_HI(cpu_T[0], 0);
1865
        gen_store_gpr(cpu_T[0], reg);
1866
        opn = "mfhi";
1867
        break;
1868
    case OPC_MFLO:
1869
        gen_load_LO(cpu_T[0], 0);
1870
        gen_store_gpr(cpu_T[0], reg);
1871
        opn = "mflo";
1872
        break;
1873
    case OPC_MTHI:
1874
        gen_load_gpr(cpu_T[0], reg);
1875
        gen_store_HI(cpu_T[0], 0);
1876
        opn = "mthi";
1877
        break;
1878
    case OPC_MTLO:
1879
        gen_load_gpr(cpu_T[0], reg);
1880
        gen_store_LO(cpu_T[0], 0);
1881
        opn = "mtlo";
1882
        break;
1883
    default:
1884
        MIPS_INVAL(opn);
1885
        generate_exception(ctx, EXCP_RI);
1886
        return;
1887
    }
1888
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1889
}
1890

    
1891
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1892
                        int rs, int rt)
1893
{
1894
    const char *opn = "mul/div";
1895

    
1896
    gen_load_gpr(cpu_T[0], rs);
1897
    gen_load_gpr(cpu_T[1], rt);
1898
    switch (opc) {
1899
    case OPC_DIV:
1900
        {
1901
            int l1 = gen_new_label();
1902

    
1903
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1904
            {
1905
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1906
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1907
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1908

    
1909
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1910
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1911
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1912
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1913
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1914
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1915
                gen_store_LO(cpu_T[0], 0);
1916
                gen_store_HI(cpu_T[1], 0);
1917
            }
1918
            gen_set_label(l1);
1919
        }
1920
        opn = "div";
1921
        break;
1922
    case OPC_DIVU:
1923
        {
1924
            int l1 = gen_new_label();
1925

    
1926
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1927
            {
1928
                TCGv r_tmp1 = new_tmp();
1929
                TCGv r_tmp2 = new_tmp();
1930
                TCGv r_tmp3 = new_tmp();
1931

    
1932
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1933
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1934
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1935
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1936
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1937
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1938
                gen_store_LO(cpu_T[0], 0);
1939
                gen_store_HI(cpu_T[1], 0);
1940
                dead_tmp(r_tmp1);
1941
                dead_tmp(r_tmp2);
1942
                dead_tmp(r_tmp3);
1943
            }
1944
            gen_set_label(l1);
1945
        }
1946
        opn = "divu";
1947
        break;
1948
    case OPC_MULT:
1949
        gen_op_mult();
1950
        opn = "mult";
1951
        break;
1952
    case OPC_MULTU:
1953
        gen_op_multu();
1954
        opn = "multu";
1955
        break;
1956
#if defined(TARGET_MIPS64)
1957
    case OPC_DDIV:
1958
        {
1959
            int l1 = gen_new_label();
1960

    
1961
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1962
            {
1963
                int l2 = gen_new_label();
1964

    
1965
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1966
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1967
                {
1968
                    tcg_gen_movi_tl(cpu_T[1], 0);
1969
                    gen_store_LO(cpu_T[0], 0);
1970
                    gen_store_HI(cpu_T[1], 0);
1971
                    tcg_gen_br(l1);
1972
                }
1973
                gen_set_label(l2);
1974
                {
1975
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1976
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1977

    
1978
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1979
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1980
                    gen_store_LO(r_tmp1, 0);
1981
                    gen_store_HI(r_tmp2, 0);
1982
                }
1983
            }
1984
            gen_set_label(l1);
1985
        }
1986
        opn = "ddiv";
1987
        break;
1988
    case OPC_DDIVU:
1989
        {
1990
            int l1 = gen_new_label();
1991

    
1992
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1993
            {
1994
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1995
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1996

    
1997
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1998
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1999
                gen_store_LO(r_tmp1, 0);
2000
                gen_store_HI(r_tmp2, 0);
2001
            }
2002
            gen_set_label(l1);
2003
        }
2004
        opn = "ddivu";
2005
        break;
2006
    case OPC_DMULT:
2007
        gen_op_dmult();
2008
        opn = "dmult";
2009
        break;
2010
    case OPC_DMULTU:
2011
        gen_op_dmultu();
2012
        opn = "dmultu";
2013
        break;
2014
#endif
2015
    case OPC_MADD:
2016
        gen_op_madd();
2017
        opn = "madd";
2018
        break;
2019
    case OPC_MADDU:
2020
        gen_op_maddu();
2021
        opn = "maddu";
2022
        break;
2023
    case OPC_MSUB:
2024
        gen_op_msub();
2025
        opn = "msub";
2026
        break;
2027
    case OPC_MSUBU:
2028
        gen_op_msubu();
2029
        opn = "msubu";
2030
        break;
2031
    default:
2032
        MIPS_INVAL(opn);
2033
        generate_exception(ctx, EXCP_RI);
2034
        return;
2035
    }
2036
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2037
}
2038

    
2039
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2040
                            int rd, int rs, int rt)
2041
{
2042
    const char *opn = "mul vr54xx";
2043

    
2044
    gen_load_gpr(cpu_T[0], rs);
2045
    gen_load_gpr(cpu_T[1], rt);
2046

    
2047
    switch (opc) {
2048
    case OPC_VR54XX_MULS:
2049
        gen_op_muls();
2050
        opn = "muls";
2051
        break;
2052
    case OPC_VR54XX_MULSU:
2053
        gen_op_mulsu();
2054
        opn = "mulsu";
2055
        break;
2056
    case OPC_VR54XX_MACC:
2057
        gen_op_macc();
2058
        opn = "macc";
2059
        break;
2060
    case OPC_VR54XX_MACCU:
2061
        gen_op_maccu();
2062
        opn = "maccu";
2063
        break;
2064
    case OPC_VR54XX_MSAC:
2065
        gen_op_msac();
2066
        opn = "msac";
2067
        break;
2068
    case OPC_VR54XX_MSACU:
2069
        gen_op_msacu();
2070
        opn = "msacu";
2071
        break;
2072
    case OPC_VR54XX_MULHI:
2073
        gen_op_mulhi();
2074
        opn = "mulhi";
2075
        break;
2076
    case OPC_VR54XX_MULHIU:
2077
        gen_op_mulhiu();
2078
        opn = "mulhiu";
2079
        break;
2080
    case OPC_VR54XX_MULSHI:
2081
        gen_op_mulshi();
2082
        opn = "mulshi";
2083
        break;
2084
    case OPC_VR54XX_MULSHIU:
2085
        gen_op_mulshiu();
2086
        opn = "mulshiu";
2087
        break;
2088
    case OPC_VR54XX_MACCHI:
2089
        gen_op_macchi();
2090
        opn = "macchi";
2091
        break;
2092
    case OPC_VR54XX_MACCHIU:
2093
        gen_op_macchiu();
2094
        opn = "macchiu";
2095
        break;
2096
    case OPC_VR54XX_MSACHI:
2097
        gen_op_msachi();
2098
        opn = "msachi";
2099
        break;
2100
    case OPC_VR54XX_MSACHIU:
2101
        gen_op_msachiu();
2102
        opn = "msachiu";
2103
        break;
2104
    default:
2105
        MIPS_INVAL("mul vr54xx");
2106
        generate_exception(ctx, EXCP_RI);
2107
        return;
2108
    }
2109
    gen_store_gpr(cpu_T[0], rd);
2110
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2111
}
2112

    
2113
static void gen_cl (DisasContext *ctx, uint32_t opc,
2114
                    int rd, int rs)
2115
{
2116
    const char *opn = "CLx";
2117
    if (rd == 0) {
2118
        /* Treat as NOP. */
2119
        MIPS_DEBUG("NOP");
2120
        return;
2121
    }
2122
    gen_load_gpr(cpu_T[0], rs);
2123
    switch (opc) {
2124
    case OPC_CLO:
2125
        tcg_gen_helper_0_0(do_clo);
2126
        opn = "clo";
2127
        break;
2128
    case OPC_CLZ:
2129
        tcg_gen_helper_0_0(do_clz);
2130
        opn = "clz";
2131
        break;
2132
#if defined(TARGET_MIPS64)
2133
    case OPC_DCLO:
2134
        tcg_gen_helper_0_0(do_dclo);
2135
        opn = "dclo";
2136
        break;
2137
    case OPC_DCLZ:
2138
        tcg_gen_helper_0_0(do_dclz);
2139
        opn = "dclz";
2140
        break;
2141
#endif
2142
    default:
2143
        MIPS_INVAL(opn);
2144
        generate_exception(ctx, EXCP_RI);
2145
        return;
2146
    }
2147
    gen_store_gpr(cpu_T[0], rd);
2148
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2149
}
2150

    
2151
/* Traps */
2152
static void gen_trap (DisasContext *ctx, uint32_t opc,
2153
                      int rs, int rt, int16_t imm)
2154
{
2155
    int cond;
2156

    
2157
    cond = 0;
2158
    /* Load needed operands */
2159
    switch (opc) {
2160
    case OPC_TEQ:
2161
    case OPC_TGE:
2162
    case OPC_TGEU:
2163
    case OPC_TLT:
2164
    case OPC_TLTU:
2165
    case OPC_TNE:
2166
        /* Compare two registers */
2167
        if (rs != rt) {
2168
            gen_load_gpr(cpu_T[0], rs);
2169
            gen_load_gpr(cpu_T[1], rt);
2170
            cond = 1;
2171
        }
2172
        break;
2173
    case OPC_TEQI:
2174
    case OPC_TGEI:
2175
    case OPC_TGEIU:
2176
    case OPC_TLTI:
2177
    case OPC_TLTIU:
2178
    case OPC_TNEI:
2179
        /* Compare register to immediate */
2180
        if (rs != 0 || imm != 0) {
2181
            gen_load_gpr(cpu_T[0], rs);
2182
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2183
            cond = 1;
2184
        }
2185
        break;
2186
    }
2187
    if (cond == 0) {
2188
        switch (opc) {
2189
        case OPC_TEQ:   /* rs == rs */
2190
        case OPC_TEQI:  /* r0 == 0  */
2191
        case OPC_TGE:   /* rs >= rs */
2192
        case OPC_TGEI:  /* r0 >= 0  */
2193
        case OPC_TGEU:  /* rs >= rs unsigned */
2194
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2195
            /* Always trap */
2196
            tcg_gen_movi_tl(cpu_T[0], 1);
2197
            break;
2198
        case OPC_TLT:   /* rs < rs           */
2199
        case OPC_TLTI:  /* r0 < 0            */
2200
        case OPC_TLTU:  /* rs < rs unsigned  */
2201
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2202
        case OPC_TNE:   /* rs != rs          */
2203
        case OPC_TNEI:  /* r0 != 0           */
2204
            /* Never trap: treat as NOP. */
2205
            return;
2206
        default:
2207
            MIPS_INVAL("trap");
2208
            generate_exception(ctx, EXCP_RI);
2209
            return;
2210
        }
2211
    } else {
2212
        switch (opc) {
2213
        case OPC_TEQ:
2214
        case OPC_TEQI:
2215
            gen_op_eq();
2216
            break;
2217
        case OPC_TGE:
2218
        case OPC_TGEI:
2219
            gen_op_ge();
2220
            break;
2221
        case OPC_TGEU:
2222
        case OPC_TGEIU:
2223
            gen_op_geu();
2224
            break;
2225
        case OPC_TLT:
2226
        case OPC_TLTI:
2227
            gen_op_lt();
2228
            break;
2229
        case OPC_TLTU:
2230
        case OPC_TLTIU:
2231
            gen_op_ltu();
2232
            break;
2233
        case OPC_TNE:
2234
        case OPC_TNEI:
2235
            gen_op_ne();
2236
            break;
2237
        default:
2238
            MIPS_INVAL("trap");
2239
            generate_exception(ctx, EXCP_RI);
2240
            return;
2241
        }
2242
    }
2243
    save_cpu_state(ctx, 1);
2244
    gen_op_trap();
2245
    ctx->bstate = BS_STOP;
2246
}
2247

    
2248
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2249
{
2250
    TranslationBlock *tb;
2251
    tb = ctx->tb;
2252
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2253
        tcg_gen_goto_tb(n);
2254
        gen_save_pc(dest);
2255
        tcg_gen_exit_tb((long)tb + n);
2256
    } else {
2257
        gen_save_pc(dest);
2258
        tcg_gen_exit_tb(0);
2259
    }
2260
}
2261

    
2262
/* Branches (before delay slot) */
2263
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2264
                                int rs, int rt, int32_t offset)
2265
{
2266
    target_ulong btarget = -1;
2267
    int blink = 0;
2268
    int bcond = 0;
2269

    
2270
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2271
#ifdef MIPS_DEBUG_DISAS
2272
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2273
            fprintf(logfile,
2274
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2275
                    ctx->pc);
2276
        }
2277
#endif
2278
        generate_exception(ctx, EXCP_RI);
2279
        return;
2280
    }
2281

    
2282
    /* Load needed operands */
2283
    switch (opc) {
2284
    case OPC_BEQ:
2285
    case OPC_BEQL:
2286
    case OPC_BNE:
2287
    case OPC_BNEL:
2288
        /* Compare two registers */
2289
        if (rs != rt) {
2290
            gen_load_gpr(cpu_T[0], rs);
2291
            gen_load_gpr(cpu_T[1], rt);
2292
            bcond = 1;
2293
        }
2294
        btarget = ctx->pc + 4 + offset;
2295
        break;
2296
    case OPC_BGEZ:
2297
    case OPC_BGEZAL:
2298
    case OPC_BGEZALL:
2299
    case OPC_BGEZL:
2300
    case OPC_BGTZ:
2301
    case OPC_BGTZL:
2302
    case OPC_BLEZ:
2303
    case OPC_BLEZL:
2304
    case OPC_BLTZ:
2305
    case OPC_BLTZAL:
2306
    case OPC_BLTZALL:
2307
    case OPC_BLTZL:
2308
        /* Compare to zero */
2309
        if (rs != 0) {
2310
            gen_load_gpr(cpu_T[0], rs);
2311
            bcond = 1;
2312
        }
2313
        btarget = ctx->pc + 4 + offset;
2314
        break;
2315
    case OPC_J:
2316
    case OPC_JAL:
2317
        /* Jump to immediate */
2318
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2319
        break;
2320
    case OPC_JR:
2321
    case OPC_JALR:
2322
        /* Jump to register */
2323
        if (offset != 0 && offset != 16) {
2324
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2325
               others are reserved. */
2326
            MIPS_INVAL("jump hint");
2327
            generate_exception(ctx, EXCP_RI);
2328
            return;
2329
        }
2330
        gen_save_breg_target(rs);
2331
        break;
2332
    default:
2333
        MIPS_INVAL("branch/jump");
2334
        generate_exception(ctx, EXCP_RI);
2335
        return;
2336
    }
2337
    if (bcond == 0) {
2338
        /* No condition to be computed */
2339
        switch (opc) {
2340
        case OPC_BEQ:     /* rx == rx        */
2341
        case OPC_BEQL:    /* rx == rx likely */
2342
        case OPC_BGEZ:    /* 0 >= 0          */
2343
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2344
        case OPC_BLEZ:    /* 0 <= 0          */
2345
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2346
            /* Always take */
2347
            ctx->hflags |= MIPS_HFLAG_B;
2348
            MIPS_DEBUG("balways");
2349
            break;
2350
        case OPC_BGEZAL:  /* 0 >= 0          */
2351
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2352
            /* Always take and link */
2353
            blink = 31;
2354
            ctx->hflags |= MIPS_HFLAG_B;
2355
            MIPS_DEBUG("balways and link");
2356
            break;
2357
        case OPC_BNE:     /* rx != rx        */
2358
        case OPC_BGTZ:    /* 0 > 0           */
2359
        case OPC_BLTZ:    /* 0 < 0           */
2360
            /* Treat as NOP. */
2361
            MIPS_DEBUG("bnever (NOP)");
2362
            return;
2363
        case OPC_BLTZAL:  /* 0 < 0           */
2364
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2365
            gen_store_gpr(cpu_T[0], 31);
2366
            MIPS_DEBUG("bnever and link");
2367
            return;
2368
        case OPC_BLTZALL: /* 0 < 0 likely */
2369
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2370
            gen_store_gpr(cpu_T[0], 31);
2371
            /* Skip the instruction in the delay slot */
2372
            MIPS_DEBUG("bnever, link and skip");
2373
            ctx->pc += 4;
2374
            return;
2375
        case OPC_BNEL:    /* rx != rx likely */
2376
        case OPC_BGTZL:   /* 0 > 0 likely */
2377
        case OPC_BLTZL:   /* 0 < 0 likely */
2378
            /* Skip the instruction in the delay slot */
2379
            MIPS_DEBUG("bnever and skip");
2380
            ctx->pc += 4;
2381
            return;
2382
        case OPC_J:
2383
            ctx->hflags |= MIPS_HFLAG_B;
2384
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2385
            break;
2386
        case OPC_JAL:
2387
            blink = 31;
2388
            ctx->hflags |= MIPS_HFLAG_B;
2389
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2390
            break;
2391
        case OPC_JR:
2392
            ctx->hflags |= MIPS_HFLAG_BR;
2393
            MIPS_DEBUG("jr %s", regnames[rs]);
2394
            break;
2395
        case OPC_JALR:
2396
            blink = rt;
2397
            ctx->hflags |= MIPS_HFLAG_BR;
2398
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2399
            break;
2400
        default:
2401
            MIPS_INVAL("branch/jump");
2402
            generate_exception(ctx, EXCP_RI);
2403
            return;
2404
        }
2405
    } else {
2406
        switch (opc) {
2407
        case OPC_BEQ:
2408
            gen_op_eq();
2409
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2410
                       regnames[rs], regnames[rt], btarget);
2411
            goto not_likely;
2412
        case OPC_BEQL:
2413
            gen_op_eq();
2414
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2415
                       regnames[rs], regnames[rt], btarget);
2416
            goto likely;
2417
        case OPC_BNE:
2418
            gen_op_ne();
2419
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2420
                       regnames[rs], regnames[rt], btarget);
2421
            goto not_likely;
2422
        case OPC_BNEL:
2423
            gen_op_ne();
2424
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2425
                       regnames[rs], regnames[rt], btarget);
2426
            goto likely;
2427
        case OPC_BGEZ:
2428
            gen_op_gez();
2429
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2430
            goto not_likely;
2431
        case OPC_BGEZL:
2432
            gen_op_gez();
2433
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2434
            goto likely;
2435
        case OPC_BGEZAL:
2436
            gen_op_gez();
2437
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2438
            blink = 31;
2439
            goto not_likely;
2440
        case OPC_BGEZALL:
2441
            gen_op_gez();
2442
            blink = 31;
2443
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2444
            goto likely;
2445
        case OPC_BGTZ:
2446
            gen_op_gtz();
2447
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2448
            goto not_likely;
2449
        case OPC_BGTZL:
2450
            gen_op_gtz();
2451
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2452
            goto likely;
2453
        case OPC_BLEZ:
2454
            gen_op_lez();
2455
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2456
            goto not_likely;
2457
        case OPC_BLEZL:
2458
            gen_op_lez();
2459
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2460
            goto likely;
2461
        case OPC_BLTZ:
2462
            gen_op_ltz();
2463
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2464
            goto not_likely;
2465
        case OPC_BLTZL:
2466
            gen_op_ltz();
2467
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2468
            goto likely;
2469
        case OPC_BLTZAL:
2470
            gen_op_ltz();
2471
            blink = 31;
2472
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2473
        not_likely:
2474
            ctx->hflags |= MIPS_HFLAG_BC;
2475
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2476
            break;
2477
        case OPC_BLTZALL:
2478
            gen_op_ltz();
2479
            blink = 31;
2480
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2481
        likely:
2482
            ctx->hflags |= MIPS_HFLAG_BL;
2483
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2484
            break;
2485
        default:
2486
            MIPS_INVAL("conditional branch/jump");
2487
            generate_exception(ctx, EXCP_RI);
2488
            return;
2489
        }
2490
    }
2491
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2492
               blink, ctx->hflags, btarget);
2493

    
2494
    ctx->btarget = btarget;
2495
    if (blink > 0) {
2496
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2497
        gen_store_gpr(cpu_T[0], blink);
2498
    }
2499
}
2500

    
2501
/* special3 bitfield operations */
2502
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2503
                       int rs, int lsb, int msb)
2504
{
2505
    gen_load_gpr(cpu_T[1], rs);
2506
    switch (opc) {
2507
    case OPC_EXT:
2508
        if (lsb + msb > 31)
2509
            goto fail;
2510
        gen_op_ext(lsb, msb + 1);
2511
        break;
2512
#if defined(TARGET_MIPS64)
2513
    case OPC_DEXTM:
2514
        if (lsb + msb > 63)
2515
            goto fail;
2516
        gen_op_dext(lsb, msb + 1 + 32);
2517
        break;
2518
    case OPC_DEXTU:
2519
        if (lsb + msb > 63)
2520
            goto fail;
2521
        gen_op_dext(lsb + 32, msb + 1);
2522
        break;
2523
    case OPC_DEXT:
2524
        if (lsb + msb > 63)
2525
            goto fail;
2526
        gen_op_dext(lsb, msb + 1);
2527
        break;
2528
#endif
2529
    case OPC_INS:
2530
        if (lsb > msb)
2531
            goto fail;
2532
        gen_load_gpr(cpu_T[0], rt);
2533
        gen_op_ins(lsb, msb - lsb + 1);
2534
        break;
2535
#if defined(TARGET_MIPS64)
2536
    case OPC_DINSM:
2537
        if (lsb > msb)
2538
            goto fail;
2539
        gen_load_gpr(cpu_T[0], rt);
2540
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2541
        break;
2542
    case OPC_DINSU:
2543
        if (lsb > msb)
2544
            goto fail;
2545
        gen_load_gpr(cpu_T[0], rt);
2546
        gen_op_dins(lsb + 32, msb - lsb + 1);
2547
        break;
2548
    case OPC_DINS:
2549
        if (lsb > msb)
2550
            goto fail;
2551
        gen_load_gpr(cpu_T[0], rt);
2552
        gen_op_dins(lsb, msb - lsb + 1);
2553
        break;
2554
#endif
2555
    default:
2556
fail:
2557
        MIPS_INVAL("bitops");
2558
        generate_exception(ctx, EXCP_RI);
2559
        return;
2560
    }
2561
    gen_store_gpr(cpu_T[0], rt);
2562
}
2563

    
2564
/* CP0 (MMU and control) */
2565
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2566
{
2567
    const char *rn = "invalid";
2568
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2569
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2570

    
2571
    if (sel != 0)
2572
        check_insn(env, ctx, ISA_MIPS32);
2573

    
2574
    switch (reg) {
2575
    case 0:
2576
        switch (sel) {
2577
        case 0:
2578
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
2579
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2580
            rn = "Index";
2581
            break;
2582
        case 1:
2583
            check_insn(env, ctx, ASE_MT);
2584
            gen_op_mfc0_mvpcontrol();
2585
            rn = "MVPControl";
2586
            break;
2587
        case 2:
2588
            check_insn(env, ctx, ASE_MT);
2589
            gen_op_mfc0_mvpconf0();
2590
            rn = "MVPConf0";
2591
            break;
2592
        case 3:
2593
            check_insn(env, ctx, ASE_MT);
2594
            gen_op_mfc0_mvpconf1();
2595
            rn = "MVPConf1";
2596
            break;
2597
        default:
2598
            goto die;
2599
        }
2600
        break;
2601
    case 1:
2602
        switch (sel) {
2603
        case 0:
2604
            gen_op_mfc0_random();
2605
            rn = "Random";
2606
            break;
2607
        case 1:
2608
            check_insn(env, ctx, ASE_MT);
2609
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
2610
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2611
            rn = "VPEControl";
2612
            break;
2613
        case 2:
2614
            check_insn(env, ctx, ASE_MT);
2615
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
2616
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2617
            rn = "VPEConf0";
2618
            break;
2619
        case 3:
2620
            check_insn(env, ctx, ASE_MT);
2621
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
2622
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2623
            rn = "VPEConf1";
2624
            break;
2625
        case 4:
2626
            check_insn(env, ctx, ASE_MT);
2627
            tcg_gen_ld_i64(r_tmp64, cpu_env, offsetof(CPUState, CP0_YQMask));
2628
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2629
            rn = "YQMask";
2630
            break;
2631
        case 5:
2632
            check_insn(env, ctx, ASE_MT);
2633
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPESchedule));
2634
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2635
            rn = "VPESchedule";
2636
            break;
2637
        case 6:
2638
            check_insn(env, ctx, ASE_MT);
2639
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
2640
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2641
            rn = "VPEScheFBack";
2642
            break;
2643
        case 7:
2644
            check_insn(env, ctx, ASE_MT);
2645
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
2646
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2647
            rn = "VPEOpt";
2648
            break;
2649
        default:
2650
            goto die;
2651
        }
2652
        break;
2653
    case 2:
2654
        switch (sel) {
2655
        case 0:
2656
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2657
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2658
            rn = "EntryLo0";
2659
            break;
2660
        case 1:
2661
            check_insn(env, ctx, ASE_MT);
2662
            gen_op_mfc0_tcstatus();
2663
            rn = "TCStatus";
2664
            break;
2665
        case 2:
2666
            check_insn(env, ctx, ASE_MT);
2667
            gen_op_mfc0_tcbind();
2668
            rn = "TCBind";
2669
            break;
2670
        case 3:
2671
            check_insn(env, ctx, ASE_MT);
2672
            gen_op_mfc0_tcrestart();
2673
            rn = "TCRestart";
2674
            break;
2675
        case 4:
2676
            check_insn(env, ctx, ASE_MT);
2677
            gen_op_mfc0_tchalt();
2678
            rn = "TCHalt";
2679
            break;
2680
        case 5:
2681
            check_insn(env, ctx, ASE_MT);
2682
            gen_op_mfc0_tccontext();
2683
            rn = "TCContext";
2684
            break;
2685
        case 6:
2686
            check_insn(env, ctx, ASE_MT);
2687
            gen_op_mfc0_tcschedule();
2688
            rn = "TCSchedule";
2689
            break;
2690
        case 7:
2691
            check_insn(env, ctx, ASE_MT);
2692
            gen_op_mfc0_tcschefback();
2693
            rn = "TCScheFBack";
2694
            break;
2695
        default:
2696
            goto die;
2697
        }
2698
        break;
2699
    case 3:
2700
        switch (sel) {
2701
        case 0:
2702
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2703
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2704
            rn = "EntryLo1";
2705
            break;
2706
        default:
2707
            goto die;
2708
        }
2709
        break;
2710
    case 4:
2711
        switch (sel) {
2712
        case 0:
2713
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2714
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2715
            rn = "Context";
2716
            break;
2717
        case 1:
2718
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2719
            rn = "ContextConfig";
2720
//            break;
2721
        default:
2722
            goto die;
2723
        }
2724
        break;
2725
    case 5:
2726
        switch (sel) {
2727
        case 0:
2728
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
2729
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2730
            rn = "PageMask";
2731
            break;
2732
        case 1:
2733
            check_insn(env, ctx, ISA_MIPS32R2);
2734
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
2735
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2736
            rn = "PageGrain";
2737
            break;
2738
        default:
2739
            goto die;
2740
        }
2741
        break;
2742
    case 6:
2743
        switch (sel) {
2744
        case 0:
2745
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
2746
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2747
            rn = "Wired";
2748
            break;
2749
        case 1:
2750
            check_insn(env, ctx, ISA_MIPS32R2);
2751
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
2752
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2753
            rn = "SRSConf0";
2754
            break;
2755
        case 2:
2756
            check_insn(env, ctx, ISA_MIPS32R2);
2757
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
2758
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2759
            rn = "SRSConf1";
2760
            break;
2761
        case 3:
2762
            check_insn(env, ctx, ISA_MIPS32R2);
2763
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
2764
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2765
            rn = "SRSConf2";
2766
            break;
2767
        case 4:
2768
            check_insn(env, ctx, ISA_MIPS32R2);
2769
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
2770
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2771
            rn = "SRSConf3";
2772
            break;
2773
        case 5:
2774
            check_insn(env, ctx, ISA_MIPS32R2);
2775
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
2776
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2777
            rn = "SRSConf4";
2778
            break;
2779
        default:
2780
            goto die;
2781
        }
2782
        break;
2783
    case 7:
2784
        switch (sel) {
2785
        case 0:
2786
            check_insn(env, ctx, ISA_MIPS32R2);
2787
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
2788
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2789
            rn = "HWREna";
2790
            break;
2791
        default:
2792
            goto die;
2793
        }
2794
        break;
2795
    case 8:
2796
        switch (sel) {
2797
        case 0:
2798
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2799
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2800
            rn = "BadVAddr";
2801
            break;
2802
        default:
2803
            goto die;
2804
       }
2805
        break;
2806
    case 9:
2807
        switch (sel) {
2808
        case 0:
2809
            gen_op_mfc0_count();
2810
            rn = "Count";
2811
            break;
2812
        /* 6,7 are implementation dependent */
2813
        default:
2814
            goto die;
2815
        }
2816
        break;
2817
    case 10:
2818
        switch (sel) {
2819
        case 0:
2820
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2821
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2822
            rn = "EntryHi";
2823
            break;
2824
        default:
2825
            goto die;
2826
        }
2827
        break;
2828
    case 11:
2829
        switch (sel) {
2830
        case 0:
2831
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
2832
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2833
            rn = "Compare";
2834
            break;
2835
        /* 6,7 are implementation dependent */
2836
        default:
2837
            goto die;
2838
        }
2839
        break;
2840
    case 12:
2841
        switch (sel) {
2842
        case 0:
2843
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
2844
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2845
            rn = "Status";
2846
            break;
2847
        case 1:
2848
            check_insn(env, ctx, ISA_MIPS32R2);
2849
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
2850
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2851
            rn = "IntCtl";
2852
            break;
2853
        case 2:
2854
            check_insn(env, ctx, ISA_MIPS32R2);
2855
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
2856
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2857
            rn = "SRSCtl";
2858
            break;
2859
        case 3:
2860
            check_insn(env, ctx, ISA_MIPS32R2);
2861
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
2862
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2863
            rn = "SRSMap";
2864
            break;
2865
        default:
2866
            goto die;
2867
       }
2868
        break;
2869
    case 13:
2870
        switch (sel) {
2871
        case 0:
2872
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
2873
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2874
            rn = "Cause";
2875
            break;
2876
        default:
2877
            goto die;
2878
       }
2879
        break;
2880
    case 14:
2881
        switch (sel) {
2882
        case 0:
2883
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2884
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2885
            rn = "EPC";
2886
            break;
2887
        default:
2888
            goto die;
2889
        }
2890
        break;
2891
    case 15:
2892
        switch (sel) {
2893
        case 0:
2894
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
2895
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2896
            rn = "PRid";
2897
            break;
2898
        case 1:
2899
            check_insn(env, ctx, ISA_MIPS32R2);
2900
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
2901
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2902
            rn = "EBase";
2903
            break;
2904
        default:
2905
            goto die;
2906
       }
2907
        break;
2908
    case 16:
2909
        switch (sel) {
2910
        case 0:
2911
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
2912
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2913
            rn = "Config";
2914
            break;
2915
        case 1:
2916
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
2917
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2918
            rn = "Config1";
2919
            break;
2920
        case 2:
2921
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
2922
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2923
            rn = "Config2";
2924
            break;
2925
        case 3:
2926
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
2927
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2928
            rn = "Config3";
2929
            break;
2930
        /* 4,5 are reserved */
2931
        /* 6,7 are implementation dependent */
2932
        case 6:
2933
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
2934
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2935
            rn = "Config6";
2936
            break;
2937
        case 7:
2938
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
2939
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2940
            rn = "Config7";
2941
            break;
2942
        default:
2943
            goto die;
2944
        }
2945
        break;
2946
    case 17:
2947
        switch (sel) {
2948
        case 0:
2949
            gen_op_mfc0_lladdr();
2950
            rn = "LLAddr";
2951
            break;
2952
        default:
2953
            goto die;
2954
        }
2955
        break;
2956
    case 18:
2957
        switch (sel) {
2958
        case 0 ... 7:
2959
            gen_op_mfc0_watchlo(sel);
2960
            rn = "WatchLo";
2961
            break;
2962
        default:
2963
            goto die;
2964
        }
2965
        break;
2966
    case 19:
2967
        switch (sel) {
2968
        case 0 ...7:
2969
            gen_op_mfc0_watchhi(sel);
2970
            rn = "WatchHi";
2971
            break;
2972
        default:
2973
            goto die;
2974
        }
2975
        break;
2976
    case 20:
2977
        switch (sel) {
2978
        case 0:
2979
#if defined(TARGET_MIPS64)
2980
            check_insn(env, ctx, ISA_MIPS3);
2981
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2982
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2983
            rn = "XContext";
2984
            break;
2985
#endif
2986
        default:
2987
            goto die;
2988
        }
2989
        break;
2990
    case 21:
2991
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2992
        switch (sel) {
2993
        case 0:
2994
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
2995
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2996
            rn = "Framemask";
2997
            break;
2998
        default:
2999
            goto die;
3000
        }
3001
        break;
3002
    case 22:
3003
        /* ignored */
3004
        rn = "'Diagnostic"; /* implementation dependent */
3005
        break;
3006
    case 23:
3007
        switch (sel) {
3008
        case 0:
3009
            gen_op_mfc0_debug(); /* EJTAG support */
3010
            rn = "Debug";
3011
            break;
3012
        case 1:
3013
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3014
            rn = "TraceControl";
3015
//            break;
3016
        case 2:
3017
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3018
            rn = "TraceControl2";
3019
//            break;
3020
        case 3:
3021
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3022
            rn = "UserTraceData";
3023
//            break;
3024
        case 4:
3025
//            gen_op_mfc0_debug(); /* PDtrace support */
3026
            rn = "TraceBPC";
3027
//            break;
3028
        default:
3029
            goto die;
3030
        }
3031
        break;
3032
    case 24:
3033
        switch (sel) {
3034
        case 0:
3035
            /* EJTAG support */
3036
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3037
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3038
            rn = "DEPC";
3039
            break;
3040
        default:
3041
            goto die;
3042
        }
3043
        break;
3044
    case 25:
3045
        switch (sel) {
3046
        case 0:
3047
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
3048
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3049
            rn = "Performance0";
3050
            break;
3051
        case 1:
3052
//            gen_op_mfc0_performance1();
3053
            rn = "Performance1";
3054
//            break;
3055
        case 2:
3056
//            gen_op_mfc0_performance2();
3057
            rn = "Performance2";
3058
//            break;
3059
        case 3:
3060
//            gen_op_mfc0_performance3();
3061
            rn = "Performance3";
3062
//            break;
3063
        case 4:
3064
//            gen_op_mfc0_performance4();
3065
            rn = "Performance4";
3066
//            break;
3067
        case 5:
3068
//            gen_op_mfc0_performance5();
3069
            rn = "Performance5";
3070
//            break;
3071
        case 6:
3072
//            gen_op_mfc0_performance6();
3073
            rn = "Performance6";
3074
//            break;
3075
        case 7:
3076
//            gen_op_mfc0_performance7();
3077
            rn = "Performance7";
3078
//            break;
3079
        default:
3080
            goto die;
3081
        }
3082
        break;
3083
    case 26:
3084
       rn = "ECC";
3085
       break;
3086
    case 27:
3087
        switch (sel) {
3088
        /* ignored */
3089
        case 0 ... 3:
3090
            rn = "CacheErr";
3091
            break;
3092
        default:
3093
            goto die;
3094
        }
3095
        break;
3096
    case 28:
3097
        switch (sel) {
3098
        case 0:
3099
        case 2:
3100
        case 4:
3101
        case 6:
3102
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
3103
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3104
            rn = "TagLo";
3105
            break;
3106
        case 1:
3107
        case 3:
3108
        case 5:
3109
        case 7:
3110
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
3111
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3112
            rn = "DataLo";
3113
            break;
3114
        default:
3115
            goto die;
3116
        }
3117
        break;
3118
    case 29:
3119
        switch (sel) {
3120
        case 0:
3121
        case 2:
3122
        case 4:
3123
        case 6:
3124
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
3125
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3126
            rn = "TagHi";
3127
            break;
3128
        case 1:
3129
        case 3:
3130
        case 5:
3131
        case 7:
3132
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
3133
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3134
            rn = "DataHi";
3135
            break;
3136
        default:
3137
            goto die;
3138
        }
3139
        break;
3140
    case 30:
3141
        switch (sel) {
3142
        case 0:
3143
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3144
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3145
            rn = "ErrorEPC";
3146
            break;
3147
        default:
3148
            goto die;
3149
        }
3150
        break;
3151
    case 31:
3152
        switch (sel) {
3153
        case 0:
3154
            /* EJTAG support */
3155
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
3156
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3157
            rn = "DESAVE";
3158
            break;
3159
        default:
3160
            goto die;
3161
        }
3162
        break;
3163
    default:
3164
       goto die;
3165
    }
3166
#if defined MIPS_DEBUG_DISAS
3167
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3168
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3169
                rn, reg, sel);
3170
    }
3171
#endif
3172
    return;
3173

    
3174
die:
3175
#if defined MIPS_DEBUG_DISAS
3176
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3177
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3178
                rn, reg, sel);
3179
    }
3180
#endif
3181
    generate_exception(ctx, EXCP_RI);
3182
}
3183

    
3184
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3185
{
3186
    const char *rn = "invalid";
3187

    
3188
    if (sel != 0)
3189
        check_insn(env, ctx, ISA_MIPS32);
3190

    
3191
    switch (reg) {
3192
    case 0:
3193
        switch (sel) {
3194
        case 0:
3195
            gen_op_mtc0_index();
3196
            rn = "Index";
3197
            break;
3198
        case 1:
3199
            check_insn(env, ctx, ASE_MT);
3200
            gen_op_mtc0_mvpcontrol();
3201
            rn = "MVPControl";
3202
            break;
3203
        case 2:
3204
            check_insn(env, ctx, ASE_MT);
3205
            /* ignored */
3206
            rn = "MVPConf0";
3207
            break;
3208
        case 3:
3209
            check_insn(env, ctx, ASE_MT);
3210
            /* ignored */
3211
            rn = "MVPConf1";
3212
            break;
3213
        default:
3214
            goto die;
3215
        }
3216
        break;
3217
    case 1:
3218
        switch (sel) {
3219
        case 0:
3220
            /* ignored */
3221
            rn = "Random";
3222
            break;
3223
        case 1:
3224
            check_insn(env, ctx, ASE_MT);
3225
            gen_op_mtc0_vpecontrol();
3226
            rn = "VPEControl";
3227
            break;
3228
        case 2:
3229
            check_insn(env, ctx, ASE_MT);
3230
            gen_op_mtc0_vpeconf0();
3231
            rn = "VPEConf0";
3232
            break;
3233
        case 3:
3234
            check_insn(env, ctx, ASE_MT);
3235
            gen_op_mtc0_vpeconf1();
3236
            rn = "VPEConf1";
3237
            break;
3238
        case 4:
3239
            check_insn(env, ctx, ASE_MT);
3240
            gen_op_mtc0_yqmask();
3241
            rn = "YQMask";
3242
            break;
3243
        case 5:
3244
            check_insn(env, ctx, ASE_MT);
3245
            gen_op_mtc0_vpeschedule();
3246
            rn = "VPESchedule";
3247
            break;
3248
        case 6:
3249
            check_insn(env, ctx, ASE_MT);
3250
            gen_op_mtc0_vpeschefback();
3251
            rn = "VPEScheFBack";
3252
            break;
3253
        case 7:
3254
            check_insn(env, ctx, ASE_MT);
3255
            gen_op_mtc0_vpeopt();
3256
            rn = "VPEOpt";
3257
            break;
3258
        default:
3259
            goto die;
3260
        }
3261
        break;
3262
    case 2:
3263
        switch (sel) {
3264
        case 0:
3265
            gen_op_mtc0_entrylo0();
3266
            rn = "EntryLo0";
3267
            break;
3268
        case 1:
3269
            check_insn(env, ctx, ASE_MT);
3270
            gen_op_mtc0_tcstatus();
3271
            rn = "TCStatus";
3272
            break;
3273
        case 2:
3274
            check_insn(env, ctx, ASE_MT);
3275
            gen_op_mtc0_tcbind();
3276
            rn = "TCBind";
3277
            break;
3278
        case 3:
3279
            check_insn(env, ctx, ASE_MT);
3280
            gen_op_mtc0_tcrestart();
3281
            rn = "TCRestart";
3282
            break;
3283
        case 4:
3284
            check_insn(env, ctx, ASE_MT);
3285
            gen_op_mtc0_tchalt();
3286
            rn = "TCHalt";
3287
            break;
3288
        case 5:
3289
            check_insn(env, ctx, ASE_MT);
3290
            gen_op_mtc0_tccontext();
3291
            rn = "TCContext";
3292
            break;
3293
        case 6:
3294
            check_insn(env, ctx, ASE_MT);
3295
            gen_op_mtc0_tcschedule();
3296
            rn = "TCSchedule";
3297
            break;
3298
        case 7:
3299
            check_insn(env, ctx, ASE_MT);
3300
            gen_op_mtc0_tcschefback();
3301
            rn = "TCScheFBack";
3302
            break;
3303
        default:
3304
            goto die;
3305
        }
3306
        break;
3307
    case 3:
3308
        switch (sel) {
3309
        case 0:
3310
            gen_op_mtc0_entrylo1();
3311
            rn = "EntryLo1";
3312
            break;
3313
        default:
3314
            goto die;
3315
        }
3316
        break;
3317
    case 4:
3318
        switch (sel) {
3319
        case 0:
3320
            gen_op_mtc0_context();
3321
            rn = "Context";
3322
            break;
3323
        case 1:
3324
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3325
            rn = "ContextConfig";
3326
//            break;
3327
        default:
3328
            goto die;
3329
        }
3330
        break;
3331
    case 5:
3332
        switch (sel) {
3333
        case 0:
3334
            gen_op_mtc0_pagemask();
3335
            rn = "PageMask";
3336
            break;
3337
        case 1:
3338
            check_insn(env, ctx, ISA_MIPS32R2);
3339
            gen_op_mtc0_pagegrain();
3340
            rn = "PageGrain";
3341
            break;
3342
        default:
3343
            goto die;
3344
        }
3345
        break;
3346
    case 6:
3347
        switch (sel) {
3348
        case 0:
3349
            gen_op_mtc0_wired();
3350
            rn = "Wired";
3351
            break;
3352
        case 1:
3353
            check_insn(env, ctx, ISA_MIPS32R2);
3354
            gen_op_mtc0_srsconf0();
3355
            rn = "SRSConf0";
3356
            break;
3357
        case 2:
3358
            check_insn(env, ctx, ISA_MIPS32R2);
3359
            gen_op_mtc0_srsconf1();
3360
            rn = "SRSConf1";
3361
            break;
3362
        case 3:
3363
            check_insn(env, ctx, ISA_MIPS32R2);
3364
            gen_op_mtc0_srsconf2();
3365
            rn = "SRSConf2";
3366
            break;
3367
        case 4:
3368
            check_insn(env, ctx, ISA_MIPS32R2);
3369
            gen_op_mtc0_srsconf3();
3370
            rn = "SRSConf3";
3371
            break;
3372
        case 5:
3373
            check_insn(env, ctx, ISA_MIPS32R2);
3374
            gen_op_mtc0_srsconf4();
3375
            rn = "SRSConf4";
3376
            break;
3377
        default:
3378
            goto die;
3379
        }
3380
        break;
3381
    case 7:
3382
        switch (sel) {
3383
        case 0:
3384
            check_insn(env, ctx, ISA_MIPS32R2);
3385
            gen_op_mtc0_hwrena();
3386
            rn = "HWREna";
3387
            break;
3388
        default:
3389
            goto die;
3390
        }
3391
        break;
3392
    case 8:
3393
        /* ignored */
3394
        rn = "BadVAddr";
3395
        break;
3396
    case 9:
3397
        switch (sel) {
3398
        case 0:
3399
            gen_op_mtc0_count();
3400
            rn = "Count";
3401
            break;
3402
        /* 6,7 are implementation dependent */
3403
        default:
3404
            goto die;
3405
        }
3406
        /* Stop translation as we may have switched the execution mode */
3407
        ctx->bstate = BS_STOP;
3408
        break;
3409
    case 10:
3410
        switch (sel) {
3411
        case 0:
3412
            gen_op_mtc0_entryhi();
3413
            rn = "EntryHi";
3414
            break;
3415
        default:
3416
            goto die;
3417
        }
3418
        break;
3419
    case 11:
3420
        switch (sel) {
3421
        case 0:
3422
            gen_op_mtc0_compare();
3423
            rn = "Compare";
3424
            break;
3425
        /* 6,7 are implementation dependent */
3426
        default:
3427
            goto die;
3428
        }
3429
        /* Stop translation as we may have switched the execution mode */
3430
        ctx->bstate = BS_STOP;
3431
        break;
3432
    case 12:
3433
        switch (sel) {
3434
        case 0:
3435
            gen_op_mtc0_status();
3436
            /* BS_STOP isn't good enough here, hflags may have changed. */
3437
            gen_save_pc(ctx->pc + 4);
3438
            ctx->bstate = BS_EXCP;
3439
            rn = "Status";
3440
            break;
3441
        case 1:
3442
            check_insn(env, ctx, ISA_MIPS32R2);
3443
            gen_op_mtc0_intctl();
3444
            /* Stop translation as we may have switched the execution mode */
3445
            ctx->bstate = BS_STOP;
3446
            rn = "IntCtl";
3447
            break;
3448
        case 2:
3449
            check_insn(env, ctx, ISA_MIPS32R2);
3450
            gen_op_mtc0_srsctl();
3451
            /* Stop translation as we may have switched the execution mode */
3452
            ctx->bstate = BS_STOP;
3453
            rn = "SRSCtl";
3454
            break;
3455
        case 3:
3456
            check_insn(env, ctx, ISA_MIPS32R2);
3457
            gen_op_mtc0_srsmap();
3458
            /* Stop translation as we may have switched the execution mode */
3459
            ctx->bstate = BS_STOP;
3460
            rn = "SRSMap";
3461
            break;
3462
        default:
3463
            goto die;
3464
        }
3465
        break;
3466
    case 13:
3467
        switch (sel) {
3468
        case 0:
3469
            gen_op_mtc0_cause();
3470
            rn = "Cause";
3471
            break;
3472
        default:
3473
            goto die;
3474
        }
3475
        /* Stop translation as we may have switched the execution mode */
3476
        ctx->bstate = BS_STOP;
3477
        break;
3478
    case 14:
3479
        switch (sel) {
3480
        case 0:
3481
            gen_op_mtc0_epc();
3482
            rn = "EPC";
3483
            break;
3484
        default:
3485
            goto die;
3486
        }
3487
        break;
3488
    case 15:
3489
        switch (sel) {
3490
        case 0:
3491
            /* ignored */
3492
            rn = "PRid";
3493
            break;
3494
        case 1:
3495
            check_insn(env, ctx, ISA_MIPS32R2);
3496
            gen_op_mtc0_ebase();
3497
            rn = "EBase";
3498
            break;
3499
        default:
3500
            goto die;
3501
        }
3502
        break;
3503
    case 16:
3504
        switch (sel) {
3505
        case 0:
3506
            gen_op_mtc0_config0();
3507
            rn = "Config";
3508
            /* Stop translation as we may have switched the execution mode */
3509
            ctx->bstate = BS_STOP;
3510
            break;
3511
        case 1:
3512
            /* ignored, read only */
3513
            rn = "Config1";
3514
            break;
3515
        case 2:
3516
            gen_op_mtc0_config2();
3517
            rn = "Config2";
3518
            /* Stop translation as we may have switched the execution mode */
3519
            ctx->bstate = BS_STOP;
3520
            break;
3521
        case 3:
3522
            /* ignored, read only */
3523
            rn = "Config3";
3524
            break;
3525
        /* 4,5 are reserved */
3526
        /* 6,7 are implementation dependent */
3527
        case 6:
3528
            /* ignored */
3529
            rn = "Config6";
3530
            break;
3531
        case 7:
3532
            /* ignored */
3533
            rn = "Config7";
3534
            break;
3535
        default:
3536
            rn = "Invalid config selector";
3537
            goto die;
3538
        }
3539
        break;
3540
    case 17:
3541
        switch (sel) {
3542
        case 0:
3543
            /* ignored */
3544
            rn = "LLAddr";
3545
            break;
3546
        default:
3547
            goto die;
3548
        }
3549
        break;
3550
    case 18:
3551
        switch (sel) {
3552
        case 0 ... 7:
3553
            gen_op_mtc0_watchlo(sel);
3554
            rn = "WatchLo";
3555
            break;
3556
        default:
3557
            goto die;
3558
        }
3559
        break;
3560
    case 19:
3561
        switch (sel) {
3562
        case 0 ... 7:
3563
            gen_op_mtc0_watchhi(sel);
3564
            rn = "WatchHi";
3565
            break;
3566
        default:
3567
            goto die;
3568
        }
3569
        break;
3570
    case 20:
3571
        switch (sel) {
3572
        case 0:
3573
#if defined(TARGET_MIPS64)
3574
            check_insn(env, ctx, ISA_MIPS3);
3575
            gen_op_mtc0_xcontext();
3576
            rn = "XContext";
3577
            break;
3578
#endif
3579
        default:
3580
            goto die;
3581
        }
3582
        break;
3583
    case 21:
3584
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3585
        switch (sel) {
3586
        case 0:
3587
            gen_op_mtc0_framemask();
3588
            rn = "Framemask";
3589
            break;
3590
        default:
3591
            goto die;
3592
        }
3593
        break;
3594
    case 22:
3595
        /* ignored */
3596
        rn = "Diagnostic"; /* implementation dependent */
3597
        break;
3598
    case 23:
3599
        switch (sel) {
3600
        case 0:
3601
            gen_op_mtc0_debug(); /* EJTAG support */
3602
            /* BS_STOP isn't good enough here, hflags may have changed. */
3603
            gen_save_pc(ctx->pc + 4);
3604
            ctx->bstate = BS_EXCP;
3605
            rn = "Debug";
3606
            break;
3607
        case 1:
3608
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3609
            rn = "TraceControl";
3610
            /* Stop translation as we may have switched the execution mode */
3611
            ctx->bstate = BS_STOP;
3612
//            break;
3613
        case 2:
3614
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3615
            rn = "TraceControl2";
3616
            /* Stop translation as we may have switched the execution mode */
3617
            ctx->bstate = BS_STOP;
3618
//            break;
3619
        case 3:
3620
            /* Stop translation as we may have switched the execution mode */
3621
            ctx->bstate = BS_STOP;
3622
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3623
            rn = "UserTraceData";
3624
            /* Stop translation as we may have switched the execution mode */
3625
            ctx->bstate = BS_STOP;
3626
//            break;
3627
        case 4:
3628
//            gen_op_mtc0_debug(); /* PDtrace support */
3629
            /* Stop translation as we may have switched the execution mode */
3630
            ctx->bstate = BS_STOP;
3631
            rn = "TraceBPC";
3632
//            break;
3633
        default:
3634
            goto die;
3635
        }
3636
        break;
3637
    case 24:
3638
        switch (sel) {
3639
        case 0:
3640
            gen_op_mtc0_depc(); /* EJTAG support */
3641
            rn = "DEPC";
3642
            break;
3643
        default:
3644
            goto die;
3645
        }
3646
        break;
3647
    case 25:
3648
        switch (sel) {
3649
        case 0:
3650
            gen_op_mtc0_performance0();
3651
            rn = "Performance0";
3652
            break;
3653
        case 1:
3654
//            gen_op_mtc0_performance1();
3655
            rn = "Performance1";
3656
//            break;
3657
        case 2:
3658
//            gen_op_mtc0_performance2();
3659
            rn = "Performance2";
3660
//            break;
3661
        case 3:
3662
//            gen_op_mtc0_performance3();
3663
            rn = "Performance3";
3664
//            break;
3665
        case 4:
3666
//            gen_op_mtc0_performance4();
3667
            rn = "Performance4";
3668
//            break;
3669
        case 5:
3670
//            gen_op_mtc0_performance5();
3671
            rn = "Performance5";
3672
//            break;
3673
        case 6:
3674
//            gen_op_mtc0_performance6();
3675
            rn = "Performance6";
3676
//            break;
3677
        case 7:
3678
//            gen_op_mtc0_performance7();
3679
            rn = "Performance7";
3680
//            break;
3681
        default:
3682
            goto die;
3683
        }
3684
       break;
3685
    case 26:
3686
        /* ignored */
3687
        rn = "ECC";
3688
        break;
3689
    case 27:
3690
        switch (sel) {
3691
        case 0 ... 3:
3692
            /* ignored */
3693
            rn = "CacheErr";
3694
            break;
3695
        default:
3696
            goto die;
3697
        }
3698
       break;
3699
    case 28:
3700
        switch (sel) {
3701
        case 0:
3702
        case 2:
3703
        case 4:
3704
        case 6:
3705
            gen_op_mtc0_taglo();
3706
            rn = "TagLo";
3707
            break;
3708
        case 1:
3709
        case 3:
3710
        case 5:
3711
        case 7:
3712
            gen_op_mtc0_datalo();
3713
            rn = "DataLo";
3714
            break;
3715
        default:
3716
            goto die;
3717
        }
3718
        break;
3719
    case 29:
3720
        switch (sel) {
3721
        case 0:
3722
        case 2:
3723
        case 4:
3724
        case 6:
3725
            gen_op_mtc0_taghi();
3726
            rn = "TagHi";
3727
            break;
3728
        case 1:
3729
        case 3:
3730
        case 5:
3731
        case 7:
3732
            gen_op_mtc0_datahi();
3733
            rn = "DataHi";
3734
            break;
3735
        default:
3736
            rn = "invalid sel";
3737
            goto die;
3738
        }
3739
       break;
3740
    case 30:
3741
        switch (sel) {
3742
        case 0:
3743
            gen_op_mtc0_errorepc();
3744
            rn = "ErrorEPC";
3745
            break;
3746
        default:
3747
            goto die;
3748
        }
3749
        break;
3750
    case 31:
3751
        switch (sel) {
3752
        case 0:
3753
            gen_op_mtc0_desave(); /* EJTAG support */
3754
            rn = "DESAVE";
3755
            break;
3756
        default:
3757
            goto die;
3758
        }
3759
        /* Stop translation as we may have switched the execution mode */
3760
        ctx->bstate = BS_STOP;
3761
        break;
3762
    default:
3763
       goto die;
3764
    }
3765
#if defined MIPS_DEBUG_DISAS
3766
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3767
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3768
                rn, reg, sel);
3769
    }
3770
#endif
3771
    return;
3772

    
3773
die:
3774
#if defined MIPS_DEBUG_DISAS
3775
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3776
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3777
                rn, reg, sel);
3778
    }
3779
#endif
3780
    generate_exception(ctx, EXCP_RI);
3781
}
3782

    
3783
#if defined(TARGET_MIPS64)
3784
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3785
{
3786
    const char *rn = "invalid";
3787
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3788

    
3789
    if (sel != 0)
3790
        check_insn(env, ctx, ISA_MIPS64);
3791

    
3792
    switch (reg) {
3793
    case 0:
3794
        switch (sel) {
3795
        case 0:
3796
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
3797
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3798
            rn = "Index";
3799
            break;
3800
        case 1:
3801
            check_insn(env, ctx, ASE_MT);
3802
            gen_op_mfc0_mvpcontrol();
3803
            rn = "MVPControl";
3804
            break;
3805
        case 2:
3806
            check_insn(env, ctx, ASE_MT);
3807
            gen_op_mfc0_mvpconf0();
3808
            rn = "MVPConf0";
3809
            break;
3810
        case 3:
3811
            check_insn(env, ctx, ASE_MT);
3812
            gen_op_mfc0_mvpconf1();
3813
            rn = "MVPConf1";
3814
            break;
3815
        default:
3816
            goto die;
3817
        }
3818
        break;
3819
    case 1:
3820
        switch (sel) {
3821
        case 0:
3822
            gen_op_mfc0_random();
3823
            rn = "Random";
3824
            break;
3825
        case 1:
3826
            check_insn(env, ctx, ASE_MT);
3827
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
3828
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3829
            rn = "VPEControl";
3830
            break;
3831
        case 2:
3832
            check_insn(env, ctx, ASE_MT);
3833
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
3834
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3835
            rn = "VPEConf0";
3836
            break;
3837
        case 3:
3838
            check_insn(env, ctx, ASE_MT);
3839
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
3840
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3841
            rn = "VPEConf1";
3842
            break;
3843
        case 4:
3844
            check_insn(env, ctx, ASE_MT);
3845
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3846
            rn = "YQMask";
3847
            break;
3848
        case 5:
3849
            check_insn(env, ctx, ASE_MT);
3850
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3851
            rn = "VPESchedule";
3852
            break;
3853
        case 6:
3854
            check_insn(env, ctx, ASE_MT);
3855
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3856
            rn = "VPEScheFBack";
3857
            break;
3858
        case 7:
3859
            check_insn(env, ctx, ASE_MT);
3860
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
3861
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3862
            rn = "VPEOpt";
3863
            break;
3864
        default:
3865
            goto die;
3866
        }
3867
        break;
3868
    case 2:
3869
        switch (sel) {
3870
        case 0:
3871
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3872
            rn = "EntryLo0";
3873
            break;
3874
        case 1:
3875
            check_insn(env, ctx, ASE_MT);
3876
            gen_op_mfc0_tcstatus();
3877
            rn = "TCStatus";
3878
            break;
3879
        case 2:
3880
            check_insn(env, ctx, ASE_MT);
3881
            gen_op_mfc0_tcbind();
3882
            rn = "TCBind";
3883
            break;
3884
        case 3:
3885
            check_insn(env, ctx, ASE_MT);
3886
            gen_op_dmfc0_tcrestart();
3887
            rn = "TCRestart";
3888
            break;
3889
        case 4:
3890
            check_insn(env, ctx, ASE_MT);
3891
            gen_op_dmfc0_tchalt();
3892
            rn = "TCHalt";
3893
            break;
3894
        case 5:
3895
            check_insn(env, ctx, ASE_MT);
3896
            gen_op_dmfc0_tccontext();
3897
            rn = "TCContext";
3898
            break;
3899
        case 6:
3900
            check_insn(env, ctx, ASE_MT);
3901
            gen_op_dmfc0_tcschedule();
3902
            rn = "TCSchedule";
3903
            break;
3904
        case 7:
3905
            check_insn(env, ctx, ASE_MT);
3906
            gen_op_dmfc0_tcschefback();
3907
            rn = "TCScheFBack";
3908
            break;
3909
        default:
3910
            goto die;
3911
        }
3912
        break;
3913
    case 3:
3914
        switch (sel) {
3915
        case 0:
3916
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3917
            rn = "EntryLo1";
3918
            break;
3919
        default:
3920
            goto die;
3921
        }
3922
        break;
3923
    case 4:
3924
        switch (sel) {
3925
        case 0:
3926
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3927
            rn = "Context";
3928
            break;
3929
        case 1:
3930
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3931
            rn = "ContextConfig";
3932
//            break;
3933
        default:
3934
            goto die;
3935
        }
3936
        break;
3937
    case 5:
3938
        switch (sel) {
3939
        case 0:
3940
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
3941
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3942
            rn = "PageMask";
3943
            break;
3944
        case 1:
3945
            check_insn(env, ctx, ISA_MIPS32R2);
3946
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
3947
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3948
            rn = "PageGrain";
3949
            break;
3950
        default:
3951
            goto die;
3952
        }
3953
        break;
3954
    case 6:
3955
        switch (sel) {
3956
        case 0:
3957
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
3958
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3959
            rn = "Wired";
3960
            break;
3961
        case 1:
3962
            check_insn(env, ctx, ISA_MIPS32R2);
3963
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
3964
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3965
            rn = "SRSConf0";
3966
            break;
3967
        case 2:
3968
            check_insn(env, ctx, ISA_MIPS32R2);
3969
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
3970
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3971
            rn = "SRSConf1";
3972
            break;
3973
        case 3:
3974
            check_insn(env, ctx, ISA_MIPS32R2);
3975
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
3976
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3977
            rn = "SRSConf2";
3978
            break;
3979
        case 4:
3980
            check_insn(env, ctx, ISA_MIPS32R2);
3981
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
3982
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3983
            rn = "SRSConf3";
3984
            break;
3985
        case 5:
3986
            check_insn(env, ctx, ISA_MIPS32R2);
3987
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
3988
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3989
            rn = "SRSConf4";
3990
            break;
3991
        default:
3992
            goto die;
3993
        }
3994
        break;
3995
    case 7:
3996
        switch (sel) {
3997
        case 0:
3998
            check_insn(env, ctx, ISA_MIPS32R2);
3999
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
4000
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4001
            rn = "HWREna";
4002
            break;
4003
        default:
4004
            goto die;
4005
        }
4006
        break;
4007
    case 8:
4008
        switch (sel) {
4009
        case 0:
4010
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4011
            rn = "BadVAddr";
4012
            break;
4013
        default:
4014
            goto die;
4015
        }
4016
        break;
4017
    case 9:
4018
        switch (sel) {
4019
        case 0:
4020
            gen_op_mfc0_count();
4021
            rn = "Count";
4022
            break;
4023
        /* 6,7 are implementation dependent */
4024
        default:
4025
            goto die;
4026
        }
4027
        break;
4028
    case 10:
4029
        switch (sel) {
4030
        case 0:
4031
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4032
            rn = "EntryHi";
4033
            break;
4034
        default:
4035
            goto die;
4036
        }
4037
        break;
4038
    case 11:
4039
        switch (sel) {
4040
        case 0:
4041
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
4042
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4043
            rn = "Compare";
4044
            break;
4045
        /* 6,7 are implementation dependent */
4046
        default:
4047
            goto die;
4048
        }
4049
        break;
4050
    case 12:
4051
        switch (sel) {
4052
        case 0:
4053
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
4054
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4055
            rn = "Status";
4056
            break;
4057
        case 1:
4058
            check_insn(env, ctx, ISA_MIPS32R2);
4059
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
4060
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4061
            rn = "IntCtl";
4062
            break;
4063
        case 2:
4064
            check_insn(env, ctx, ISA_MIPS32R2);
4065
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
4066
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4067
            rn = "SRSCtl";
4068
            break;
4069
        case 3:
4070
            check_insn(env, ctx, ISA_MIPS32R2);
4071
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
4072
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4073
            rn = "SRSMap";
4074
            break;
4075
        default:
4076
            goto die;
4077
        }
4078
        break;
4079
    case 13:
4080
        switch (sel) {
4081
        case 0:
4082
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
4083
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4084
            rn = "Cause";
4085
            break;
4086
        default:
4087
            goto die;
4088
        }
4089
        break;
4090
    case 14:
4091
        switch (sel) {
4092
        case 0:
4093
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4094
            rn = "EPC";
4095
            break;
4096
        default:
4097
            goto die;
4098
        }
4099
        break;
4100
    case 15:
4101
        switch (sel) {
4102
        case 0:
4103
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
4104
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4105
            rn = "PRid";
4106
            break;
4107
        case 1:
4108
            check_insn(env, ctx, ISA_MIPS32R2);
4109
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
4110
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4111
            rn = "EBase";
4112
            break;
4113
        default:
4114
            goto die;
4115
        }
4116
        break;
4117
    case 16:
4118
        switch (sel) {
4119
        case 0:
4120
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
4121
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4122
            rn = "Config";
4123
            break;
4124
        case 1:
4125
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
4126
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4127
            rn = "Config1";
4128
            break;
4129
        case 2:
4130
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
4131
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4132
            rn = "Config2";
4133
            break;
4134
        case 3:
4135
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
4136
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4137
            rn = "Config3";
4138
            break;
4139
       /* 6,7 are implementation dependent */
4140
        case 6:
4141
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
4142
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4143
            rn = "Config6";
4144
            break;
4145
        case 7:
4146
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
4147
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4148
            rn = "Config7";
4149
            break;
4150
        default:
4151
            goto die;
4152
        }
4153
        break;
4154
    case 17:
4155
        switch (sel) {
4156
        case 0:
4157
            gen_op_dmfc0_lladdr();
4158
            rn = "LLAddr";
4159
            break;
4160
        default:
4161
            goto die;
4162
        }
4163
        break;
4164
    case 18:
4165
        switch (sel) {
4166
        case 0 ... 7:
4167
            gen_op_dmfc0_watchlo(sel);
4168
            rn = "WatchLo";
4169
            break;
4170
        default:
4171
            goto die;
4172
        }
4173
        break;
4174
    case 19:
4175
        switch (sel) {
4176
        case 0 ... 7:
4177
            gen_op_mfc0_watchhi(sel);
4178
            rn = "WatchHi";
4179
            break;
4180
        default:
4181
            goto die;
4182
        }
4183
        break;
4184
    case 20:
4185
        switch (sel) {
4186
        case 0:
4187
            check_insn(env, ctx, ISA_MIPS3);
4188
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4189
            rn = "XContext";
4190
            break;
4191
        default:
4192
            goto die;
4193
        }
4194
        break;
4195
    case 21:
4196
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4197
        switch (sel) {
4198
        case 0:
4199
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
4200
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4201
            rn = "Framemask";
4202
            break;
4203
        default:
4204
            goto die;
4205
        }
4206
        break;
4207
    case 22:
4208
        /* ignored */
4209
        rn = "'Diagnostic"; /* implementation dependent */
4210
        break;
4211
    case 23:
4212
        switch (sel) {
4213
        case 0:
4214
            gen_op_mfc0_debug(); /* EJTAG support */
4215
            rn = "Debug";
4216
            break;
4217
        case 1:
4218
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4219
            rn = "TraceControl";
4220
//            break;
4221
        case 2:
4222
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4223
            rn = "TraceControl2";
4224
//            break;
4225
        case 3:
4226
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4227
            rn = "UserTraceData";
4228
//            break;
4229
        case 4:
4230
//            gen_op_dmfc0_debug(); /* PDtrace support */
4231
            rn = "TraceBPC";
4232
//            break;
4233
        default:
4234
            goto die;
4235
        }
4236
        break;
4237
    case 24:
4238
        switch (sel) {
4239
        case 0:
4240
            /* EJTAG support */
4241
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4242
            rn = "DEPC";
4243
            break;
4244
        default:
4245
            goto die;
4246
        }
4247
        break;
4248
    case 25:
4249
        switch (sel) {
4250
        case 0:
4251
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
4252
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4253
            rn = "Performance0";
4254
            break;
4255
        case 1:
4256
//            gen_op_dmfc0_performance1();
4257
            rn = "Performance1";
4258
//            break;
4259
        case 2:
4260
//            gen_op_dmfc0_performance2();
4261
            rn = "Performance2";
4262
//            break;
4263
        case 3:
4264
//            gen_op_dmfc0_performance3();
4265
            rn = "Performance3";
4266
//            break;
4267
        case 4:
4268
//            gen_op_dmfc0_performance4();
4269
            rn = "Performance4";
4270
//            break;
4271
        case 5:
4272
//            gen_op_dmfc0_performance5();
4273
            rn = "Performance5";
4274
//            break;
4275
        case 6:
4276
//            gen_op_dmfc0_performance6();
4277
            rn = "Performance6";
4278
//            break;
4279
        case 7:
4280
//            gen_op_dmfc0_performance7();
4281
            rn = "Performance7";
4282
//            break;
4283
        default:
4284
            goto die;
4285
        }
4286
        break;
4287
    case 26:
4288
       rn = "ECC";
4289
       break;
4290
    case 27:
4291
        switch (sel) {
4292
        /* ignored */
4293
        case 0 ... 3:
4294
            rn = "CacheErr";
4295
            break;
4296
        default:
4297
            goto die;
4298
        }
4299
        break;
4300
    case 28:
4301
        switch (sel) {
4302
        case 0:
4303
        case 2:
4304
        case 4:
4305
        case 6:
4306
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
4307
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4308
            rn = "TagLo";
4309
            break;
4310
        case 1:
4311
        case 3:
4312
        case 5:
4313
        case 7:
4314
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
4315
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4316
            rn = "DataLo";
4317
            break;
4318
        default:
4319
            goto die;
4320
        }
4321
        break;
4322
    case 29:
4323
        switch (sel) {
4324
        case 0:
4325
        case 2:
4326
        case 4:
4327
        case 6:
4328
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
4329
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4330
            rn = "TagHi";
4331
            break;
4332
        case 1:
4333
        case 3:
4334
        case 5:
4335
        case 7:
4336
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
4337
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4338
            rn = "DataHi";
4339
            break;
4340
        default:
4341
            goto die;
4342
        }
4343
        break;
4344
    case 30:
4345
        switch (sel) {
4346
        case 0:
4347
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4348
            rn = "ErrorEPC";
4349
            break;
4350
        default:
4351
            goto die;
4352
        }
4353
        break;
4354
    case 31:
4355
        switch (sel) {
4356
        case 0:
4357
            /* EJTAG support */
4358
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
4359
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4360
            rn = "DESAVE";
4361
            break;
4362
        default:
4363
            goto die;
4364
        }
4365
        break;
4366
    default:
4367
        goto die;
4368
    }
4369
#if defined MIPS_DEBUG_DISAS
4370
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4371
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4372
                rn, reg, sel);
4373
    }
4374
#endif
4375
    return;
4376

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

    
4387
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4388
{
4389
    const char *rn = "invalid";
4390

    
4391
    if (sel != 0)
4392
        check_insn(env, ctx, ISA_MIPS64);
4393

    
4394
    switch (reg) {
4395
    case 0:
4396
        switch (sel) {
4397
        case 0:
4398
            gen_op_mtc0_index();
4399
            rn = "Index";
4400
            break;
4401
        case 1:
4402
            check_insn(env, ctx, ASE_MT);
4403
            gen_op_mtc0_mvpcontrol();
4404
            rn = "MVPControl";
4405
            break;
4406
        case 2:
4407
            check_insn(env, ctx, ASE_MT);
4408
            /* ignored */
4409
            rn = "MVPConf0";
4410
            break;
4411
        case 3:
4412
            check_insn(env, ctx, ASE_MT);
4413
            /* ignored */
4414
            rn = "MVPConf1";
4415
            break;
4416
        default:
4417
            goto die;
4418
        }
4419
        break;
4420
    case 1:
4421
        switch (sel) {
4422
        case 0:
4423
            /* ignored */
4424
            rn = "Random";
4425
            break;
4426
        case 1:
4427
            check_insn(env, ctx, ASE_MT);
4428
            gen_op_mtc0_vpecontrol();
4429
            rn = "VPEControl";
4430
            break;
4431
        case 2:
4432
            check_insn(env, ctx, ASE_MT);
4433
            gen_op_mtc0_vpeconf0();
4434
            rn = "VPEConf0";
4435
            break;
4436
        case 3:
4437
            check_insn(env, ctx, ASE_MT);
4438
            gen_op_mtc0_vpeconf1();
4439
            rn = "VPEConf1";
4440
            break;
4441
        case 4:
4442
            check_insn(env, ctx, ASE_MT);
4443
            gen_op_mtc0_yqmask();
4444
            rn = "YQMask";
4445
            break;
4446
        case 5:
4447
            check_insn(env, ctx, ASE_MT);
4448
            gen_op_mtc0_vpeschedule();
4449
            rn = "VPESchedule";
4450
            break;
4451
        case 6:
4452
            check_insn(env, ctx, ASE_MT);
4453
            gen_op_mtc0_vpeschefback();
4454
            rn = "VPEScheFBack";
4455
            break;
4456
        case 7:
4457
            check_insn(env, ctx, ASE_MT);
4458
            gen_op_mtc0_vpeopt();
4459
            rn = "VPEOpt";
4460
            break;
4461
        default:
4462
            goto die;
4463
        }
4464
        break;
4465
    case 2:
4466
        switch (sel) {
4467
        case 0:
4468
            gen_op_mtc0_entrylo0();
4469
            rn = "EntryLo0";
4470
            break;
4471
        case 1:
4472
            check_insn(env, ctx, ASE_MT);
4473
            gen_op_mtc0_tcstatus();
4474
            rn = "TCStatus";
4475
            break;
4476
        case 2:
4477
            check_insn(env, ctx, ASE_MT);
4478
            gen_op_mtc0_tcbind();
4479
            rn = "TCBind";
4480
            break;
4481
        case 3:
4482
            check_insn(env, ctx, ASE_MT);
4483
            gen_op_mtc0_tcrestart();
4484
            rn = "TCRestart";
4485
            break;
4486
        case 4:
4487
            check_insn(env, ctx, ASE_MT);
4488
            gen_op_mtc0_tchalt();
4489
            rn = "TCHalt";
4490
            break;
4491
        case 5:
4492
            check_insn(env, ctx, ASE_MT);
4493
            gen_op_mtc0_tccontext();
4494
            rn = "TCContext";
4495
            break;
4496
        case 6:
4497
            check_insn(env, ctx, ASE_MT);
4498
            gen_op_mtc0_tcschedule();
4499
            rn = "TCSchedule";
4500
            break;
4501
        case 7:
4502
            check_insn(env, ctx, ASE_MT);
4503
            gen_op_mtc0_tcschefback();
4504
            rn = "TCScheFBack";
4505
            break;
4506
        default:
4507
            goto die;
4508
        }
4509
        break;
4510
    case 3:
4511
        switch (sel) {
4512
        case 0:
4513
            gen_op_mtc0_entrylo1();
4514
            rn = "EntryLo1";
4515
            break;
4516
        default:
4517
            goto die;
4518
        }
4519
        break;
4520
    case 4:
4521
        switch (sel) {
4522
        case 0:
4523
            gen_op_mtc0_context();
4524
            rn = "Context";
4525
            break;
4526
        case 1:
4527
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4528
            rn = "ContextConfig";
4529
//           break;
4530
        default:
4531
            goto die;
4532
        }
4533
        break;
4534
    case 5:
4535
        switch (sel) {
4536
        case 0:
4537
            gen_op_mtc0_pagemask();
4538
            rn = "PageMask";
4539
            break;
4540
        case 1:
4541
            check_insn(env, ctx, ISA_MIPS32R2);
4542
            gen_op_mtc0_pagegrain();
4543
            rn = "PageGrain";
4544
            break;
4545
        default:
4546
            goto die;
4547
        }
4548
        break;
4549
    case 6:
4550
        switch (sel) {
4551
        case 0:
4552
            gen_op_mtc0_wired();
4553
            rn = "Wired";
4554
            break;
4555
        case 1:
4556
            check_insn(env, ctx, ISA_MIPS32R2);
4557
            gen_op_mtc0_srsconf0();
4558
            rn = "SRSConf0";
4559
            break;
4560
        case 2:
4561
            check_insn(env, ctx, ISA_MIPS32R2);
4562
            gen_op_mtc0_srsconf1();
4563
            rn = "SRSConf1";
4564
            break;
4565
        case 3:
4566
            check_insn(env, ctx, ISA_MIPS32R2);
4567
            gen_op_mtc0_srsconf2();
4568
            rn = "SRSConf2";
4569
            break;
4570
        case 4:
4571
            check_insn(env, ctx, ISA_MIPS32R2);
4572
            gen_op_mtc0_srsconf3();
4573
            rn = "SRSConf3";
4574
            break;
4575
        case 5:
4576
            check_insn(env, ctx, ISA_MIPS32R2);
4577
            gen_op_mtc0_srsconf4();
4578
            rn = "SRSConf4";
4579
            break;
4580
        default:
4581
            goto die;
4582
        }
4583
        break;
4584
    case 7:
4585
        switch (sel) {
4586
        case 0:
4587
            check_insn(env, ctx, ISA_MIPS32R2);
4588
            gen_op_mtc0_hwrena();
4589
            rn = "HWREna";
4590
            break;
4591
        default:
4592
            goto die;
4593
        }
4594
        break;
4595
    case 8:
4596
        /* ignored */
4597
        rn = "BadVAddr";
4598
        break;
4599
    case 9:
4600
        switch (sel) {
4601
        case 0:
4602
            gen_op_mtc0_count();
4603
            rn = "Count";
4604
            break;
4605
        /* 6,7 are implementation dependent */
4606
        default:
4607
            goto die;
4608
        }
4609
        /* Stop translation as we may have switched the execution mode */
4610
        ctx->bstate = BS_STOP;
4611
        break;
4612
    case 10:
4613
        switch (sel) {
4614
        case 0:
4615
            gen_op_mtc0_entryhi();
4616
            rn = "EntryHi";
4617
            break;
4618
        default:
4619
            goto die;
4620
        }
4621
        break;
4622
    case 11:
4623
        switch (sel) {
4624
        case 0:
4625
            gen_op_mtc0_compare();
4626
            rn = "Compare";
4627
            break;
4628
        /* 6,7 are implementation dependent */
4629
        default:
4630
            goto die;
4631
        }
4632
        /* Stop translation as we may have switched the execution mode */
4633
        ctx->bstate = BS_STOP;
4634
        break;
4635
    case 12:
4636
        switch (sel) {
4637
        case 0:
4638
            gen_op_mtc0_status();
4639
            /* BS_STOP isn't good enough here, hflags may have changed. */
4640
            gen_save_pc(ctx->pc + 4);
4641
            ctx->bstate = BS_EXCP;
4642
            rn = "Status";
4643
            break;
4644
        case 1:
4645
            check_insn(env, ctx, ISA_MIPS32R2);
4646
            gen_op_mtc0_intctl();
4647
            /* Stop translation as we may have switched the execution mode */
4648
            ctx->bstate = BS_STOP;
4649
            rn = "IntCtl";
4650
            break;
4651
        case 2:
4652
            check_insn(env, ctx, ISA_MIPS32R2);
4653
            gen_op_mtc0_srsctl();
4654
            /* Stop translation as we may have switched the execution mode */
4655
            ctx->bstate = BS_STOP;
4656
            rn = "SRSCtl";
4657
            break;
4658
        case 3:
4659
            check_insn(env, ctx, ISA_MIPS32R2);
4660
            gen_op_mtc0_srsmap();
4661
            /* Stop translation as we may have switched the execution mode */
4662
            ctx->bstate = BS_STOP;
4663
            rn = "SRSMap";
4664
            break;
4665
        default:
4666
            goto die;
4667
        }
4668
        break;
4669
    case 13:
4670
        switch (sel) {
4671
        case 0:
4672
            gen_op_mtc0_cause();
4673
            rn = "Cause";
4674
            break;
4675
        default:
4676
            goto die;
4677
        }
4678
        /* Stop translation as we may have switched the execution mode */
4679
        ctx->bstate = BS_STOP;
4680
        break;
4681
    case 14:
4682
        switch (sel) {
4683
        case 0:
4684
            gen_op_mtc0_epc();
4685
            rn = "EPC";
4686
            break;
4687
        default:
4688
            goto die;
4689
        }
4690
        break;
4691
    case 15:
4692
        switch (sel) {
4693
        case 0:
4694
            /* ignored */
4695
            rn = "PRid";
4696
            break;
4697
        case 1:
4698
            check_insn(env, ctx, ISA_MIPS32R2);
4699
            gen_op_mtc0_ebase();
4700
            rn = "EBase";
4701
            break;
4702
        default:
4703
            goto die;
4704
        }
4705
        break;
4706
    case 16:
4707
        switch (sel) {
4708
        case 0:
4709
            gen_op_mtc0_config0();
4710
            rn = "Config";
4711
            /* Stop translation as we may have switched the execution mode */
4712
            ctx->bstate = BS_STOP;
4713
            break;
4714
        case 1:
4715
            /* ignored */
4716
            rn = "Config1";
4717
            break;
4718
        case 2:
4719
            gen_op_mtc0_config2();
4720
            rn = "Config2";
4721
            /* Stop translation as we may have switched the execution mode */
4722
            ctx->bstate = BS_STOP;
4723
            break;
4724
        case 3:
4725
            /* ignored */
4726
            rn = "Config3";
4727
            break;
4728
        /* 6,7 are implementation dependent */
4729
        default:
4730
            rn = "Invalid config selector";
4731
            goto die;
4732
        }
4733
        break;
4734
    case 17:
4735
        switch (sel) {
4736
        case 0:
4737
            /* ignored */
4738
            rn = "LLAddr";
4739
            break;
4740
        default:
4741
            goto die;
4742
        }
4743
        break;
4744
    case 18:
4745
        switch (sel) {
4746
        case 0 ... 7:
4747
            gen_op_mtc0_watchlo(sel);
4748
            rn = "WatchLo";
4749
            break;
4750
        default:
4751
            goto die;
4752
        }
4753
        break;
4754
    case 19:
4755
        switch (sel) {
4756
        case 0 ... 7:
4757
            gen_op_mtc0_watchhi(sel);
4758
            rn = "WatchHi";
4759
            break;
4760
        default:
4761
            goto die;
4762
        }
4763
        break;
4764
    case 20:
4765
        switch (sel) {
4766
        case 0:
4767
            check_insn(env, ctx, ISA_MIPS3);
4768
            gen_op_mtc0_xcontext();
4769
            rn = "XContext";
4770
            break;
4771
        default:
4772
            goto die;
4773
        }
4774
        break;
4775
    case 21:
4776
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4777
        switch (sel) {
4778
        case 0:
4779
            gen_op_mtc0_framemask();
4780
            rn = "Framemask";
4781
            break;
4782
        default:
4783
            goto die;
4784
        }
4785
        break;
4786
    case 22:
4787
        /* ignored */
4788
        rn = "Diagnostic"; /* implementation dependent */
4789
        break;
4790
    case 23:
4791
        switch (sel) {
4792
        case 0:
4793
            gen_op_mtc0_debug(); /* EJTAG support */
4794
            /* BS_STOP isn't good enough here, hflags may have changed. */
4795
            gen_save_pc(ctx->pc + 4);
4796
            ctx->bstate = BS_EXCP;
4797
            rn = "Debug";
4798
            break;
4799
        case 1:
4800
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4801
            /* Stop translation as we may have switched the execution mode */
4802
            ctx->bstate = BS_STOP;
4803
            rn = "TraceControl";
4804
//            break;
4805
        case 2:
4806
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4807
            /* Stop translation as we may have switched the execution mode */
4808
            ctx->bstate = BS_STOP;
4809
            rn = "TraceControl2";
4810
//            break;
4811
        case 3:
4812
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4813
            /* Stop translation as we may have switched the execution mode */
4814
            ctx->bstate = BS_STOP;
4815
            rn = "UserTraceData";
4816
//            break;
4817
        case 4:
4818
//            gen_op_mtc0_debug(); /* PDtrace support */
4819
            /* Stop translation as we may have switched the execution mode */
4820
            ctx->bstate = BS_STOP;
4821
            rn = "TraceBPC";
4822
//            break;
4823
        default:
4824
            goto die;
4825
        }
4826
        break;
4827
    case 24:
4828
        switch (sel) {
4829
        case 0:
4830
            gen_op_mtc0_depc(); /* EJTAG support */
4831
            rn = "DEPC";
4832
            break;
4833
        default:
4834
            goto die;
4835
        }
4836
        break;
4837
    case 25:
4838
        switch (sel) {
4839
        case 0:
4840
            gen_op_mtc0_performance0();
4841
            rn = "Performance0";
4842
            break;
4843
        case 1:
4844
//            gen_op_mtc0_performance1();
4845
            rn = "Performance1";
4846
//            break;
4847
        case 2:
4848
//            gen_op_mtc0_performance2();
4849
            rn = "Performance2";
4850
//            break;
4851
        case 3:
4852
//            gen_op_mtc0_performance3();
4853
            rn = "Performance3";
4854
//            break;
4855
        case 4:
4856
//            gen_op_mtc0_performance4();
4857
            rn = "Performance4";
4858
//            break;
4859
        case 5:
4860
//            gen_op_mtc0_performance5();
4861
            rn = "Performance5";
4862
//            break;
4863
        case 6:
4864
//            gen_op_mtc0_performance6();
4865
            rn = "Performance6";
4866
//            break;
4867
        case 7:
4868
//            gen_op_mtc0_performance7();
4869
            rn = "Performance7";
4870
//            break;
4871
        default:
4872
            goto die;
4873
        }
4874
        break;
4875
    case 26:
4876
        /* ignored */
4877
        rn = "ECC";
4878
        break;
4879
    case 27:
4880
        switch (sel) {
4881
        case 0 ... 3:
4882
            /* ignored */
4883
            rn = "CacheErr";
4884
            break;
4885
        default:
4886
            goto die;
4887
        }
4888
        break;
4889
    case 28:
4890
        switch (sel) {
4891
        case 0:
4892
        case 2:
4893
        case 4:
4894
        case 6:
4895
            gen_op_mtc0_taglo();
4896
            rn = "TagLo";
4897
            break;
4898
        case 1:
4899
        case 3:
4900
        case 5:
4901
        case 7:
4902
            gen_op_mtc0_datalo();
4903
            rn = "DataLo";
4904
            break;
4905
        default:
4906
            goto die;
4907
        }
4908
        break;
4909
    case 29:
4910
        switch (sel) {
4911
        case 0:
4912
        case 2:
4913
        case 4:
4914
        case 6:
4915
            gen_op_mtc0_taghi();
4916
            rn = "TagHi";
4917
            break;
4918
        case 1:
4919
        case 3:
4920
        case 5:
4921
        case 7:
4922
            gen_op_mtc0_datahi();
4923
            rn = "DataHi";
4924
            break;
4925
        default:
4926
            rn = "invalid sel";
4927
            goto die;
4928
        }
4929
        break;
4930
    case 30:
4931
        switch (sel) {
4932
        case 0:
4933
            gen_op_mtc0_errorepc();
4934
            rn = "ErrorEPC";
4935
            break;
4936
        default:
4937
            goto die;
4938
        }
4939
        break;
4940
    case 31:
4941
        switch (sel) {
4942
        case 0:
4943
            gen_op_mtc0_desave(); /* EJTAG support */
4944
            rn = "DESAVE";
4945
            break;
4946
        default:
4947
            goto die;
4948
        }
4949
        /* Stop translation as we may have switched the execution mode */
4950
        ctx->bstate = BS_STOP;
4951
        break;
4952
    default:
4953
        goto die;
4954
    }
4955
#if defined MIPS_DEBUG_DISAS
4956
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4957
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4958
                rn, reg, sel);
4959
    }
4960
#endif
4961
    return;
4962

    
4963
die:
4964
#if defined MIPS_DEBUG_DISAS
4965
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4966
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4967
                rn, reg, sel);
4968
    }
4969
#endif
4970
    generate_exception(ctx, EXCP_RI);
4971
}
4972
#endif /* TARGET_MIPS64 */
4973

    
4974
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4975
                     int u, int sel, int h)
4976
{
4977
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4978

    
4979
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4980
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4981
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4982
        tcg_gen_movi_tl(cpu_T[0], -1);
4983
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4984
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4985
        tcg_gen_movi_tl(cpu_T[0], -1);
4986
    else if (u == 0) {
4987
        switch (rt) {
4988
        case 2:
4989
            switch (sel) {
4990
            case 1:
4991
                gen_op_mftc0_tcstatus();
4992
                break;
4993
            case 2:
4994
                gen_op_mftc0_tcbind();
4995
                break;
4996
            case 3:
4997
                gen_op_mftc0_tcrestart();
4998
                break;
4999
            case 4:
5000
                gen_op_mftc0_tchalt();
5001
                break;
5002
            case 5:
5003
                gen_op_mftc0_tccontext();
5004
                break;
5005
            case 6:
5006
                gen_op_mftc0_tcschedule();
5007
                break;
5008
            case 7:
5009
                gen_op_mftc0_tcschefback();
5010
                break;
5011
            default:
5012
                gen_mfc0(env, ctx, rt, sel);
5013
                break;
5014
            }
5015
            break;
5016
        case 10:
5017
            switch (sel) {
5018
            case 0:
5019
                gen_op_mftc0_entryhi();
5020
                break;
5021
            default:
5022
                gen_mfc0(env, ctx, rt, sel);
5023
                break;
5024
            }
5025
        case 12:
5026
            switch (sel) {
5027
            case 0:
5028
                gen_op_mftc0_status();
5029
                break;
5030
            default:
5031
                gen_mfc0(env, ctx, rt, sel);
5032
                break;
5033
            }
5034
        case 23:
5035
            switch (sel) {
5036
            case 0:
5037
                gen_op_mftc0_debug();
5038
                break;
5039
            default:
5040
                gen_mfc0(env, ctx, rt, sel);
5041
                break;
5042
            }
5043
            break;
5044
        default:
5045
            gen_mfc0(env, ctx, rt, sel);
5046
        }
5047
    } else switch (sel) {
5048
    /* GPR registers. */
5049
    case 0:
5050
        gen_op_mftgpr(rt);
5051
        break;
5052
    /* Auxiliary CPU registers */
5053
    case 1:
5054
        switch (rt) {
5055
        case 0:
5056
            gen_op_mftlo(0);
5057
            break;
5058
        case 1:
5059
            gen_op_mfthi(0);
5060
            break;
5061
        case 2:
5062
            gen_op_mftacx(0);
5063
            break;
5064
        case 4:
5065
            gen_op_mftlo(1);
5066
            break;
5067
        case 5:
5068
            gen_op_mfthi(1);
5069
            break;
5070
        case 6:
5071
            gen_op_mftacx(1);
5072
            break;
5073
        case 8:
5074
            gen_op_mftlo(2);
5075
            break;
5076
        case 9:
5077
            gen_op_mfthi(2);
5078
            break;
5079
        case 10:
5080
            gen_op_mftacx(2);
5081
            break;
5082
        case 12:
5083
            gen_op_mftlo(3);
5084
            break;
5085
        case 13:
5086
            gen_op_mfthi(3);
5087
            break;
5088
        case 14:
5089
            gen_op_mftacx(3);
5090
            break;
5091
        case 16:
5092
            gen_op_mftdsp();
5093
            break;
5094
        default:
5095
            goto die;
5096
        }
5097
        break;
5098
    /* Floating point (COP1). */
5099
    case 2:
5100
        /* XXX: For now we support only a single FPU context. */
5101
        if (h == 0) {
5102
            GEN_LOAD_FREG_FTN(WT0, rt);
5103
            gen_op_mfc1();
5104
        } else {
5105
            GEN_LOAD_FREG_FTN(WTH0, rt);
5106
            gen_op_mfhc1();
5107
        }
5108
        break;
5109
    case 3:
5110
        /* XXX: For now we support only a single FPU context. */
5111
        gen_op_cfc1(rt);
5112
        break;
5113
    /* COP2: Not implemented. */
5114
    case 4:
5115
    case 5:
5116
        /* fall through */
5117
    default:
5118
        goto die;
5119
    }
5120
#if defined MIPS_DEBUG_DISAS
5121
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5122
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5123
                rt, u, sel, h);
5124
    }
5125
#endif
5126
    return;
5127

    
5128
die:
5129
#if defined MIPS_DEBUG_DISAS
5130
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5131
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5132
                rt, u, sel, h);
5133
    }
5134
#endif
5135
    generate_exception(ctx, EXCP_RI);
5136
}
5137

    
5138
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5139
                     int u, int sel, int h)
5140
{
5141
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5142

    
5143
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5144
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5145
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5146
        /* NOP */ ;
5147
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5148
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5149
        /* NOP */ ;
5150
    else if (u == 0) {
5151
        switch (rd) {
5152
        case 2:
5153
            switch (sel) {
5154
            case 1:
5155
                gen_op_mttc0_tcstatus();
5156
                break;
5157
            case 2:
5158
                gen_op_mttc0_tcbind();
5159
                break;
5160
            case 3:
5161
                gen_op_mttc0_tcrestart();
5162
                break;
5163
            case 4:
5164
                gen_op_mttc0_tchalt();
5165
                break;
5166
            case 5:
5167
                gen_op_mttc0_tccontext();
5168
                break;
5169
            case 6:
5170
                gen_op_mttc0_tcschedule();
5171
                break;
5172
            case 7:
5173
                gen_op_mttc0_tcschefback();
5174
                break;
5175
            default:
5176
                gen_mtc0(env, ctx, rd, sel);
5177
                break;
5178
            }
5179
            break;
5180
        case 10:
5181
            switch (sel) {
5182
            case 0:
5183
                gen_op_mttc0_entryhi();
5184
                break;
5185
            default:
5186
                gen_mtc0(env, ctx, rd, sel);
5187
                break;
5188
            }
5189
        case 12:
5190
            switch (sel) {
5191
            case 0:
5192
                gen_op_mttc0_status();
5193
                break;
5194
            default:
5195
                gen_mtc0(env, ctx, rd, sel);
5196
                break;
5197
            }
5198
        case 23:
5199
            switch (sel) {
5200
            case 0:
5201
                gen_op_mttc0_debug();
5202
                break;
5203
            default:
5204
                gen_mtc0(env, ctx, rd, sel);
5205
                break;
5206
            }
5207
            break;
5208
        default:
5209
            gen_mtc0(env, ctx, rd, sel);
5210
        }
5211
    } else switch (sel) {
5212
    /* GPR registers. */
5213
    case 0:
5214
        gen_op_mttgpr(rd);
5215
        break;
5216
    /* Auxiliary CPU registers */
5217
    case 1:
5218
        switch (rd) {
5219
        case 0:
5220
            gen_op_mttlo(0);
5221
            break;
5222
        case 1:
5223
            gen_op_mtthi(0);
5224
            break;
5225
        case 2:
5226
            gen_op_mttacx(0);
5227
            break;
5228
        case 4:
5229
            gen_op_mttlo(1);
5230
            break;
5231
        case 5:
5232
            gen_op_mtthi(1);
5233
            break;
5234
        case 6:
5235
            gen_op_mttacx(1);
5236
            break;
5237
        case 8:
5238
            gen_op_mttlo(2);
5239
            break;
5240
        case 9:
5241
            gen_op_mtthi(2);
5242
            break;
5243
        case 10:
5244
            gen_op_mttacx(2);
5245
            break;
5246
        case 12:
5247
            gen_op_mttlo(3);
5248
            break;
5249
        case 13:
5250
            gen_op_mtthi(3);
5251
            break;
5252
        case 14:
5253
            gen_op_mttacx(3);
5254
            break;
5255
        case 16:
5256
            gen_op_mttdsp();
5257
            break;
5258
        default:
5259
            goto die;
5260
        }
5261
        break;
5262
    /* Floating point (COP1). */
5263
    case 2:
5264
        /* XXX: For now we support only a single FPU context. */
5265
        if (h == 0) {
5266
            gen_op_mtc1();
5267
            GEN_STORE_FTN_FREG(rd, WT0);
5268
        } else {
5269
            gen_op_mthc1();
5270
            GEN_STORE_FTN_FREG(rd, WTH0);
5271
        }
5272
        break;
5273
    case 3:
5274
        /* XXX: For now we support only a single FPU context. */
5275
        gen_op_ctc1(rd);
5276
        break;
5277
    /* COP2: Not implemented. */
5278
    case 4:
5279
    case 5:
5280
        /* fall through */
5281
    default:
5282
        goto die;
5283
    }
5284
#if defined MIPS_DEBUG_DISAS
5285
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5286
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5287
                rd, u, sel, h);
5288
    }
5289
#endif
5290
    return;
5291

    
5292
die:
5293
#if defined MIPS_DEBUG_DISAS
5294
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5295
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5296
                rd, u, sel, h);
5297
    }
5298
#endif
5299
    generate_exception(ctx, EXCP_RI);
5300
}
5301

    
5302
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5303
{
5304
    const char *opn = "ldst";
5305

    
5306
    switch (opc) {
5307
    case OPC_MFC0:
5308
        if (rt == 0) {
5309
            /* Treat as NOP. */
5310
            return;
5311
        }
5312
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5313
        gen_store_gpr(cpu_T[0], rt);
5314
        opn = "mfc0";
5315
        break;
5316
    case OPC_MTC0:
5317
        gen_load_gpr(cpu_T[0], rt);
5318
        save_cpu_state(ctx, 1);
5319
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5320
        opn = "mtc0";
5321
        break;
5322
#if defined(TARGET_MIPS64)
5323
    case OPC_DMFC0:
5324
        check_insn(env, ctx, ISA_MIPS3);
5325
        if (rt == 0) {
5326
            /* Treat as NOP. */
5327
            return;
5328
        }
5329
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5330
        gen_store_gpr(cpu_T[0], rt);
5331
        opn = "dmfc0";
5332
        break;
5333
    case OPC_DMTC0:
5334
        check_insn(env, ctx, ISA_MIPS3);
5335
        gen_load_gpr(cpu_T[0], rt);
5336
        save_cpu_state(ctx, 1);
5337
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5338
        opn = "dmtc0";
5339
        break;
5340
#endif
5341
    case OPC_MFTR:
5342
        check_insn(env, ctx, ASE_MT);
5343
        if (rd == 0) {
5344
            /* Treat as NOP. */
5345
            return;
5346
        }
5347
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5348
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5349
        gen_store_gpr(cpu_T[0], rd);
5350
        opn = "mftr";
5351
        break;
5352
    case OPC_MTTR:
5353
        check_insn(env, ctx, ASE_MT);
5354
        gen_load_gpr(cpu_T[0], rt);
5355
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5356
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5357
        opn = "mttr";
5358
        break;
5359
    case OPC_TLBWI:
5360
        opn = "tlbwi";
5361
        if (!env->tlb->do_tlbwi)
5362
            goto die;
5363
        gen_op_tlbwi();
5364
        break;
5365
    case OPC_TLBWR:
5366
        opn = "tlbwr";
5367
        if (!env->tlb->do_tlbwr)
5368
            goto die;
5369
        gen_op_tlbwr();
5370
        break;
5371
    case OPC_TLBP:
5372
        opn = "tlbp";
5373
        if (!env->tlb->do_tlbp)
5374
            goto die;
5375
        gen_op_tlbp();
5376
        break;
5377
    case OPC_TLBR:
5378
        opn = "tlbr";
5379
        if (!env->tlb->do_tlbr)
5380
            goto die;
5381
        gen_op_tlbr();
5382
        break;
5383
    case OPC_ERET:
5384
        opn = "eret";
5385
        check_insn(env, ctx, ISA_MIPS2);
5386
        save_cpu_state(ctx, 1);
5387
        gen_op_eret();
5388
        ctx->bstate = BS_EXCP;
5389
        break;
5390
    case OPC_DERET:
5391
        opn = "deret";
5392
        check_insn(env, ctx, ISA_MIPS32);
5393
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5394
            MIPS_INVAL(opn);
5395
            generate_exception(ctx, EXCP_RI);
5396
        } else {
5397
            save_cpu_state(ctx, 1);
5398
            gen_op_deret();
5399
            ctx->bstate = BS_EXCP;
5400
        }
5401
        break;
5402
    case OPC_WAIT:
5403
        opn = "wait";
5404
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5405
        /* If we get an exception, we want to restart at next instruction */
5406
        ctx->pc += 4;
5407
        save_cpu_state(ctx, 1);
5408
        ctx->pc -= 4;
5409
        gen_op_wait();
5410
        ctx->bstate = BS_EXCP;
5411
        break;
5412
    default:
5413
 die:
5414
        MIPS_INVAL(opn);
5415
        generate_exception(ctx, EXCP_RI);
5416
        return;
5417
    }
5418
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5419
}
5420

    
5421
/* CP1 Branches (before delay slot) */
5422
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5423
                                 int32_t cc, int32_t offset)
5424
{
5425
    target_ulong btarget;
5426
    const char *opn = "cp1 cond branch";
5427

    
5428
    if (cc != 0)
5429
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5430

    
5431
    btarget = ctx->pc + 4 + offset;
5432

    
5433
    switch (op) {
5434
    case OPC_BC1F:
5435
        gen_op_bc1f(cc);
5436
        opn = "bc1f";
5437
        goto not_likely;
5438
    case OPC_BC1FL:
5439
        gen_op_bc1f(cc);
5440
        opn = "bc1fl";
5441
        goto likely;
5442
    case OPC_BC1T:
5443
        gen_op_bc1t(cc);
5444
        opn = "bc1t";
5445
        goto not_likely;
5446
    case OPC_BC1TL:
5447
        gen_op_bc1t(cc);
5448
        opn = "bc1tl";
5449
    likely:
5450
        ctx->hflags |= MIPS_HFLAG_BL;
5451
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5452
        break;
5453
    case OPC_BC1FANY2:
5454
        gen_op_bc1any2f(cc);
5455
        opn = "bc1any2f";
5456
        goto not_likely;
5457
    case OPC_BC1TANY2:
5458
        gen_op_bc1any2t(cc);
5459
        opn = "bc1any2t";
5460
        goto not_likely;
5461
    case OPC_BC1FANY4:
5462
        gen_op_bc1any4f(cc);
5463
        opn = "bc1any4f";
5464
        goto not_likely;
5465
    case OPC_BC1TANY4:
5466
        gen_op_bc1any4t(cc);
5467
        opn = "bc1any4t";
5468
    not_likely:
5469
        ctx->hflags |= MIPS_HFLAG_BC;
5470
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5471
        break;
5472
    default:
5473
        MIPS_INVAL(opn);
5474
        generate_exception (ctx, EXCP_RI);
5475
        return;
5476
    }
5477
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5478
               ctx->hflags, btarget);
5479
    ctx->btarget = btarget;
5480
}
5481

    
5482
/* Coprocessor 1 (FPU) */
5483

    
5484
#define FOP(func, fmt) (((fmt) << 21) | (func))
5485

    
5486
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5487
{
5488
    const char *opn = "cp1 move";
5489

    
5490
    switch (opc) {
5491
    case OPC_MFC1:
5492
        GEN_LOAD_FREG_FTN(WT0, fs);
5493
        gen_op_mfc1();
5494
        gen_store_gpr(cpu_T[0], rt);
5495
        opn = "mfc1";
5496
        break;
5497
    case OPC_MTC1:
5498
        gen_load_gpr(cpu_T[0], rt);
5499
        gen_op_mtc1();
5500
        GEN_STORE_FTN_FREG(fs, WT0);
5501
        opn = "mtc1";
5502
        break;
5503
    case OPC_CFC1:
5504
        gen_op_cfc1(fs);
5505
        gen_store_gpr(cpu_T[0], rt);
5506
        opn = "cfc1";
5507
        break;
5508
    case OPC_CTC1:
5509
        gen_load_gpr(cpu_T[0], rt);
5510
        gen_op_ctc1(fs);
5511
        opn = "ctc1";
5512
        break;
5513
    case OPC_DMFC1:
5514
        GEN_LOAD_FREG_FTN(DT0, fs);
5515
        gen_op_dmfc1();
5516
        gen_store_gpr(cpu_T[0], rt);
5517
        opn = "dmfc1";
5518
        break;
5519
    case OPC_DMTC1:
5520
        gen_load_gpr(cpu_T[0], rt);
5521
        gen_op_dmtc1();
5522
        GEN_STORE_FTN_FREG(fs, DT0);
5523
        opn = "dmtc1";
5524
        break;
5525
    case OPC_MFHC1:
5526
        GEN_LOAD_FREG_FTN(WTH0, fs);
5527
        gen_op_mfhc1();
5528
        gen_store_gpr(cpu_T[0], rt);
5529
        opn = "mfhc1";
5530
        break;
5531
    case OPC_MTHC1:
5532
        gen_load_gpr(cpu_T[0], rt);
5533
        gen_op_mthc1();
5534
        GEN_STORE_FTN_FREG(fs, WTH0);
5535
        opn = "mthc1";
5536
        break;
5537
    default:
5538
        MIPS_INVAL(opn);
5539
        generate_exception (ctx, EXCP_RI);
5540
        return;
5541
    }
5542
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5543
}
5544

    
5545
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5546
{
5547
    int l1 = gen_new_label();
5548
    uint32_t ccbit;
5549
    TCGCond cond;
5550

    
5551
    if (cc)
5552
        ccbit = 1 << (24 + cc);
5553
    else
5554
        ccbit = 1 << 23;
5555
    if (tf)
5556
        cond = TCG_COND_EQ;
5557
    else
5558
        cond = TCG_COND_NE;
5559

    
5560
    gen_load_gpr(cpu_T[0], rd);
5561
    gen_load_gpr(cpu_T[1], rs);
5562
    {
5563
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5564
        TCGv r_tmp = new_tmp();
5565

    
5566
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5567
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5568
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5569
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5570
        dead_tmp(r_tmp);
5571
    }
5572
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5573

    
5574
    gen_set_label(l1);
5575
    gen_store_gpr(cpu_T[0], rd);
5576
}
5577

    
5578
#define GEN_MOVCF(fmt)                                                \
5579
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5580
{                                                                     \
5581
    uint32_t ccbit;                                                   \
5582
                                                                      \
5583
    if (cc) {                                                         \
5584
        ccbit = 1 << (24 + cc);                                       \
5585
    } else                                                            \
5586
        ccbit = 1 << 23;                                              \
5587
    if (!tf)                                                          \
5588
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5589
    else                                                              \
5590
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5591
}
5592
GEN_MOVCF(d);
5593
GEN_MOVCF(s);
5594
#undef GEN_MOVCF
5595

    
5596
static void gen_farith (DisasContext *ctx, uint32_t op1,
5597
                        int ft, int fs, int fd, int cc)
5598
{
5599
    const char *opn = "farith";
5600
    const char *condnames[] = {
5601
            "c.f",
5602
            "c.un",
5603
            "c.eq",
5604
            "c.ueq",
5605
            "c.olt",
5606
            "c.ult",
5607
            "c.ole",
5608
            "c.ule",
5609
            "c.sf",
5610
            "c.ngle",
5611
            "c.seq",
5612
            "c.ngl",
5613
            "c.lt",
5614
            "c.nge",
5615
            "c.le",
5616
            "c.ngt",
5617
    };
5618
    const char *condnames_abs[] = {
5619
            "cabs.f",
5620
            "cabs.un",
5621
            "cabs.eq",
5622
            "cabs.ueq",
5623
            "cabs.olt",
5624
            "cabs.ult",
5625
            "cabs.ole",
5626
            "cabs.ule",
5627
            "cabs.sf",
5628
            "cabs.ngle",
5629
            "cabs.seq",
5630
            "cabs.ngl",
5631
            "cabs.lt",
5632
            "cabs.nge",
5633
            "cabs.le",
5634
            "cabs.ngt",
5635
    };
5636
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5637
    uint32_t func = ctx->opcode & 0x3f;
5638

    
5639
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5640
    case FOP(0, 16):
5641
        GEN_LOAD_FREG_FTN(WT0, fs);
5642
        GEN_LOAD_FREG_FTN(WT1, ft);
5643
        gen_op_float_add_s();
5644
        GEN_STORE_FTN_FREG(fd, WT2);
5645
        opn = "add.s";
5646
        optype = BINOP;
5647
        break;
5648
    case FOP(1, 16):
5649
        GEN_LOAD_FREG_FTN(WT0, fs);
5650
        GEN_LOAD_FREG_FTN(WT1, ft);
5651
        gen_op_float_sub_s();
5652
        GEN_STORE_FTN_FREG(fd, WT2);
5653
        opn = "sub.s";
5654
        optype = BINOP;
5655
        break;
5656
    case FOP(2, 16):
5657
        GEN_LOAD_FREG_FTN(WT0, fs);
5658
        GEN_LOAD_FREG_FTN(WT1, ft);
5659
        gen_op_float_mul_s();
5660
        GEN_STORE_FTN_FREG(fd, WT2);
5661
        opn = "mul.s";
5662
        optype = BINOP;
5663
        break;
5664
    case FOP(3, 16):
5665
        GEN_LOAD_FREG_FTN(WT0, fs);
5666
        GEN_LOAD_FREG_FTN(WT1, ft);
5667
        gen_op_float_div_s();
5668
        GEN_STORE_FTN_FREG(fd, WT2);
5669
        opn = "div.s";
5670
        optype = BINOP;
5671
        break;
5672
    case FOP(4, 16):
5673
        GEN_LOAD_FREG_FTN(WT0, fs);
5674
        gen_op_float_sqrt_s();
5675
        GEN_STORE_FTN_FREG(fd, WT2);
5676
        opn = "sqrt.s";
5677
        break;
5678
    case FOP(5, 16):
5679
        GEN_LOAD_FREG_FTN(WT0, fs);
5680
        gen_op_float_abs_s();
5681
        GEN_STORE_FTN_FREG(fd, WT2);
5682
        opn = "abs.s";
5683
        break;
5684
    case FOP(6, 16):
5685
        GEN_LOAD_FREG_FTN(WT0, fs);
5686
        gen_op_float_mov_s();
5687
        GEN_STORE_FTN_FREG(fd, WT2);
5688
        opn = "mov.s";
5689
        break;
5690
    case FOP(7, 16):
5691
        GEN_LOAD_FREG_FTN(WT0, fs);
5692
        gen_op_float_chs_s();
5693
        GEN_STORE_FTN_FREG(fd, WT2);
5694
        opn = "neg.s";
5695
        break;
5696
    case FOP(8, 16):
5697
        check_cp1_64bitmode(ctx);
5698
        GEN_LOAD_FREG_FTN(WT0, fs);
5699
        gen_op_float_roundl_s();
5700
        GEN_STORE_FTN_FREG(fd, DT2);
5701
        opn = "round.l.s";
5702
        break;
5703
    case FOP(9, 16):
5704
        check_cp1_64bitmode(ctx);
5705
        GEN_LOAD_FREG_FTN(WT0, fs);
5706
        gen_op_float_truncl_s();
5707
        GEN_STORE_FTN_FREG(fd, DT2);
5708
        opn = "trunc.l.s";
5709
        break;
5710
    case FOP(10, 16):
5711
        check_cp1_64bitmode(ctx);
5712
        GEN_LOAD_FREG_FTN(WT0, fs);
5713
        gen_op_float_ceill_s();
5714
        GEN_STORE_FTN_FREG(fd, DT2);
5715
        opn = "ceil.l.s";
5716
        break;
5717
    case FOP(11, 16):
5718
        check_cp1_64bitmode(ctx);
5719
        GEN_LOAD_FREG_FTN(WT0, fs);
5720
        gen_op_float_floorl_s();
5721
        GEN_STORE_FTN_FREG(fd, DT2);
5722
        opn = "floor.l.s";
5723
        break;
5724
    case FOP(12, 16):
5725
        GEN_LOAD_FREG_FTN(WT0, fs);
5726
        gen_op_float_roundw_s();
5727
        GEN_STORE_FTN_FREG(fd, WT2);
5728
        opn = "round.w.s";
5729
        break;
5730
    case FOP(13, 16):
5731
        GEN_LOAD_FREG_FTN(WT0, fs);
5732
        gen_op_float_truncw_s();
5733
        GEN_STORE_FTN_FREG(fd, WT2);
5734
        opn = "trunc.w.s";
5735
        break;
5736
    case FOP(14, 16):
5737
        GEN_LOAD_FREG_FTN(WT0, fs);
5738
        gen_op_float_ceilw_s();
5739
        GEN_STORE_FTN_FREG(fd, WT2);
5740
        opn = "ceil.w.s";
5741
        break;
5742
    case FOP(15, 16):
5743
        GEN_LOAD_FREG_FTN(WT0, fs);
5744
        gen_op_float_floorw_s();
5745
        GEN_STORE_FTN_FREG(fd, WT2);
5746
        opn = "floor.w.s";
5747
        break;
5748
    case FOP(17, 16):
5749
        gen_load_gpr(cpu_T[0], ft);
5750
        GEN_LOAD_FREG_FTN(WT0, fs);
5751
        GEN_LOAD_FREG_FTN(WT2, fd);
5752
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5753
        GEN_STORE_FTN_FREG(fd, WT2);
5754
        opn = "movcf.s";
5755
        break;
5756
    case FOP(18, 16):
5757
        gen_load_gpr(cpu_T[0], ft);
5758
        GEN_LOAD_FREG_FTN(WT0, fs);
5759
        GEN_LOAD_FREG_FTN(WT2, fd);
5760
        gen_op_float_movz_s();
5761
        GEN_STORE_FTN_FREG(fd, WT2);
5762
        opn = "movz.s";
5763
        break;
5764
    case FOP(19, 16):
5765
        gen_load_gpr(cpu_T[0], ft);
5766
        GEN_LOAD_FREG_FTN(WT0, fs);
5767
        GEN_LOAD_FREG_FTN(WT2, fd);
5768
        gen_op_float_movn_s();
5769
        GEN_STORE_FTN_FREG(fd, WT2);
5770
        opn = "movn.s";
5771
        break;
5772
    case FOP(21, 16):
5773
        check_cop1x(ctx);
5774
        GEN_LOAD_FREG_FTN(WT0, fs);
5775
        gen_op_float_recip_s();
5776
        GEN_STORE_FTN_FREG(fd, WT2);
5777
        opn = "recip.s";
5778
        break;
5779
    case FOP(22, 16):
5780
        check_cop1x(ctx);
5781
        GEN_LOAD_FREG_FTN(WT0, fs);
5782
        gen_op_float_rsqrt_s();
5783
        GEN_STORE_FTN_FREG(fd, WT2);
5784
        opn = "rsqrt.s";
5785
        break;
5786
    case FOP(28, 16):
5787
        check_cp1_64bitmode(ctx);
5788
        GEN_LOAD_FREG_FTN(WT0, fs);
5789
        GEN_LOAD_FREG_FTN(WT2, fd);
5790
        gen_op_float_recip2_s();
5791
        GEN_STORE_FTN_FREG(fd, WT2);
5792
        opn = "recip2.s";
5793
        break;
5794
    case FOP(29, 16):
5795
        check_cp1_64bitmode(ctx);
5796
        GEN_LOAD_FREG_FTN(WT0, fs);
5797
        gen_op_float_recip1_s();
5798
        GEN_STORE_FTN_FREG(fd, WT2);
5799
        opn = "recip1.s";
5800
        break;
5801
    case FOP(30, 16):
5802
        check_cp1_64bitmode(ctx);
5803
        GEN_LOAD_FREG_FTN(WT0, fs);
5804
        gen_op_float_rsqrt1_s();
5805
        GEN_STORE_FTN_FREG(fd, WT2);
5806
        opn = "rsqrt1.s";
5807
        break;
5808
    case FOP(31, 16):
5809
        check_cp1_64bitmode(ctx);
5810
        GEN_LOAD_FREG_FTN(WT0, fs);
5811
        GEN_LOAD_FREG_FTN(WT2, ft);
5812
        gen_op_float_rsqrt2_s();
5813
        GEN_STORE_FTN_FREG(fd, WT2);
5814
        opn = "rsqrt2.s";
5815
        break;
5816
    case FOP(33, 16):
5817
        check_cp1_registers(ctx, fd);
5818
        GEN_LOAD_FREG_FTN(WT0, fs);
5819
        gen_op_float_cvtd_s();
5820
        GEN_STORE_FTN_FREG(fd, DT2);
5821
        opn = "cvt.d.s";
5822
        break;
5823
    case FOP(36, 16):
5824
        GEN_LOAD_FREG_FTN(WT0, fs);
5825
        gen_op_float_cvtw_s();
5826
        GEN_STORE_FTN_FREG(fd, WT2);
5827
        opn = "cvt.w.s";
5828
        break;
5829
    case FOP(37, 16):
5830
        check_cp1_64bitmode(ctx);
5831
        GEN_LOAD_FREG_FTN(WT0, fs);
5832
        gen_op_float_cvtl_s();
5833
        GEN_STORE_FTN_FREG(fd, DT2);
5834
        opn = "cvt.l.s";
5835
        break;
5836
    case FOP(38, 16):
5837
        check_cp1_64bitmode(ctx);
5838
        GEN_LOAD_FREG_FTN(WT1, fs);
5839
        GEN_LOAD_FREG_FTN(WT0, ft);
5840
        gen_op_float_cvtps_s();
5841
        GEN_STORE_FTN_FREG(fd, DT2);
5842
        opn = "cvt.ps.s";
5843
        break;
5844
    case FOP(48, 16):
5845
    case FOP(49, 16):
5846
    case FOP(50, 16):
5847
    case FOP(51, 16):
5848
    case FOP(52, 16):
5849
    case FOP(53, 16):
5850
    case FOP(54, 16):
5851
    case FOP(55, 16):
5852
    case FOP(56, 16):
5853
    case FOP(57, 16):
5854
    case FOP(58, 16):
5855
    case FOP(59, 16):
5856
    case FOP(60, 16):
5857
    case FOP(61, 16):
5858
    case FOP(62, 16):
5859
    case FOP(63, 16):
5860
        GEN_LOAD_FREG_FTN(WT0, fs);
5861
        GEN_LOAD_FREG_FTN(WT1, ft);
5862
        if (ctx->opcode & (1 << 6)) {
5863
            check_cop1x(ctx);
5864
            gen_cmpabs_s(func-48, cc);
5865
            opn = condnames_abs[func-48];
5866
        } else {
5867
            gen_cmp_s(func-48, cc);
5868
            opn = condnames[func-48];
5869
        }
5870
        break;
5871
    case FOP(0, 17):
5872
        check_cp1_registers(ctx, fs | ft | fd);
5873
        GEN_LOAD_FREG_FTN(DT0, fs);
5874
        GEN_LOAD_FREG_FTN(DT1, ft);
5875
        gen_op_float_add_d();
5876
        GEN_STORE_FTN_FREG(fd, DT2);
5877
        opn = "add.d";
5878
        optype = BINOP;
5879
        break;
5880
    case FOP(1, 17):
5881
        check_cp1_registers(ctx, fs | ft | fd);
5882
        GEN_LOAD_FREG_FTN(DT0, fs);
5883
        GEN_LOAD_FREG_FTN(DT1, ft);
5884
        gen_op_float_sub_d();
5885
        GEN_STORE_FTN_FREG(fd, DT2);
5886
        opn = "sub.d";
5887
        optype = BINOP;
5888
        break;
5889
    case FOP(2, 17):
5890
        check_cp1_registers(ctx, fs | ft | fd);
5891
        GEN_LOAD_FREG_FTN(DT0, fs);
5892
        GEN_LOAD_FREG_FTN(DT1, ft);
5893
        gen_op_float_mul_d();
5894
        GEN_STORE_FTN_FREG(fd, DT2);
5895
        opn = "mul.d";
5896
        optype = BINOP;
5897
        break;
5898
    case FOP(3, 17):
5899
        check_cp1_registers(ctx, fs | ft | fd);
5900
        GEN_LOAD_FREG_FTN(DT0, fs);
5901
        GEN_LOAD_FREG_FTN(DT1, ft);
5902
        gen_op_float_div_d();
5903
        GEN_STORE_FTN_FREG(fd, DT2);
5904
        opn = "div.d";
5905
        optype = BINOP;
5906
        break;
5907
    case FOP(4, 17):
5908
        check_cp1_registers(ctx, fs | fd);
5909
        GEN_LOAD_FREG_FTN(DT0, fs);
5910
        gen_op_float_sqrt_d();
5911
        GEN_STORE_FTN_FREG(fd, DT2);
5912
        opn = "sqrt.d";
5913
        break;
5914
    case FOP(5, 17):
5915
        check_cp1_registers(ctx, fs | fd);
5916
        GEN_LOAD_FREG_FTN(DT0, fs);
5917
        gen_op_float_abs_d();
5918
        GEN_STORE_FTN_FREG(fd, DT2);
5919
        opn = "abs.d";
5920
        break;
5921
    case FOP(6, 17):
5922
        check_cp1_registers(ctx, fs | fd);
5923
        GEN_LOAD_FREG_FTN(DT0, fs);
5924
        gen_op_float_mov_d();
5925
        GEN_STORE_FTN_FREG(fd, DT2);
5926
        opn = "mov.d";
5927
        break;
5928
    case FOP(7, 17):
5929
        check_cp1_registers(ctx, fs | fd);
5930
        GEN_LOAD_FREG_FTN(DT0, fs);
5931
        gen_op_float_chs_d();
5932
        GEN_STORE_FTN_FREG(fd, DT2);
5933
        opn = "neg.d";
5934
        break;
5935
    case FOP(8, 17):
5936
        check_cp1_64bitmode(ctx);
5937
        GEN_LOAD_FREG_FTN(DT0, fs);
5938
        gen_op_float_roundl_d();
5939
        GEN_STORE_FTN_FREG(fd, DT2);
5940
        opn = "round.l.d";
5941
        break;
5942
    case FOP(9, 17):
5943
        check_cp1_64bitmode(ctx);
5944
        GEN_LOAD_FREG_FTN(DT0, fs);
5945
        gen_op_float_truncl_d();
5946
        GEN_STORE_FTN_FREG(fd, DT2);
5947
        opn = "trunc.l.d";
5948
        break;
5949
    case FOP(10, 17):
5950
        check_cp1_64bitmode(ctx);
5951
        GEN_LOAD_FREG_FTN(DT0, fs);
5952
        gen_op_float_ceill_d();
5953
        GEN_STORE_FTN_FREG(fd, DT2);
5954
        opn = "ceil.l.d";
5955
        break;
5956
    case FOP(11, 17):
5957
        check_cp1_64bitmode(ctx);
5958
        GEN_LOAD_FREG_FTN(DT0, fs);
5959
        gen_op_float_floorl_d();
5960
        GEN_STORE_FTN_FREG(fd, DT2);
5961
        opn = "floor.l.d";
5962
        break;
5963
    case FOP(12, 17):
5964
        check_cp1_registers(ctx, fs);
5965
        GEN_LOAD_FREG_FTN(DT0, fs);
5966
        gen_op_float_roundw_d();
5967
        GEN_STORE_FTN_FREG(fd, WT2);
5968
        opn = "round.w.d";
5969
        break;
5970
    case FOP(13, 17):
5971
        check_cp1_registers(ctx, fs);
5972
        GEN_LOAD_FREG_FTN(DT0, fs);
5973
        gen_op_float_truncw_d();
5974
        GEN_STORE_FTN_FREG(fd, WT2);
5975
        opn = "trunc.w.d";
5976
        break;
5977
    case FOP(14, 17):
5978
        check_cp1_registers(ctx, fs);
5979
        GEN_LOAD_FREG_FTN(DT0, fs);
5980
        gen_op_float_ceilw_d();
5981
        GEN_STORE_FTN_FREG(fd, WT2);
5982
        opn = "ceil.w.d";
5983
        break;
5984
    case FOP(15, 17):
5985
        check_cp1_registers(ctx, fs);
5986
        GEN_LOAD_FREG_FTN(DT0, fs);
5987
        gen_op_float_floorw_d();
5988
        GEN_STORE_FTN_FREG(fd, WT2);
5989
        opn = "floor.w.d";
5990
        break;
5991
    case FOP(17, 17):
5992
        gen_load_gpr(cpu_T[0], ft);
5993
        GEN_LOAD_FREG_FTN(DT0, fs);
5994
        GEN_LOAD_FREG_FTN(DT2, fd);
5995
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5996
        GEN_STORE_FTN_FREG(fd, DT2);
5997
        opn = "movcf.d";
5998
        break;
5999
    case FOP(18, 17):
6000
        gen_load_gpr(cpu_T[0], ft);
6001
        GEN_LOAD_FREG_FTN(DT0, fs);
6002
        GEN_LOAD_FREG_FTN(DT2, fd);
6003
        gen_op_float_movz_d();
6004
        GEN_STORE_FTN_FREG(fd, DT2);
6005
        opn = "movz.d";
6006
        break;
6007
    case FOP(19, 17):
6008
        gen_load_gpr(cpu_T[0], ft);
6009
        GEN_LOAD_FREG_FTN(DT0, fs);
6010
        GEN_LOAD_FREG_FTN(DT2, fd);
6011
        gen_op_float_movn_d();
6012
        GEN_STORE_FTN_FREG(fd, DT2);
6013
        opn = "movn.d";
6014
        break;
6015
    case FOP(21, 17):
6016
        check_cp1_64bitmode(ctx);
6017
        GEN_LOAD_FREG_FTN(DT0, fs);
6018
        gen_op_float_recip_d();
6019
        GEN_STORE_FTN_FREG(fd, DT2);
6020
        opn = "recip.d";
6021
        break;
6022
    case FOP(22, 17):
6023
        check_cp1_64bitmode(ctx);
6024
        GEN_LOAD_FREG_FTN(DT0, fs);
6025
        gen_op_float_rsqrt_d();
6026
        GEN_STORE_FTN_FREG(fd, DT2);
6027
        opn = "rsqrt.d";
6028
        break;
6029
    case FOP(28, 17):
6030
        check_cp1_64bitmode(ctx);
6031
        GEN_LOAD_FREG_FTN(DT0, fs);
6032
        GEN_LOAD_FREG_FTN(DT2, ft);
6033
        gen_op_float_recip2_d();
6034
        GEN_STORE_FTN_FREG(fd, DT2);
6035
        opn = "recip2.d";
6036
        break;
6037
    case FOP(29, 17):
6038
        check_cp1_64bitmode(ctx);
6039
        GEN_LOAD_FREG_FTN(DT0, fs);
6040
        gen_op_float_recip1_d();
6041
        GEN_STORE_FTN_FREG(fd, DT2);
6042
        opn = "recip1.d";
6043
        break;
6044
    case FOP(30, 17):
6045
        check_cp1_64bitmode(ctx);
6046
        GEN_LOAD_FREG_FTN(DT0, fs);
6047
        gen_op_float_rsqrt1_d();
6048
        GEN_STORE_FTN_FREG(fd, DT2);
6049
        opn = "rsqrt1.d";
6050
        break;
6051
    case FOP(31, 17):
6052
        check_cp1_64bitmode(ctx);
6053
        GEN_LOAD_FREG_FTN(DT0, fs);
6054
        GEN_LOAD_FREG_FTN(DT2, ft);
6055
        gen_op_float_rsqrt2_d();
6056
        GEN_STORE_FTN_FREG(fd, DT2);
6057
        opn = "rsqrt2.d";
6058
        break;
6059
    case FOP(48, 17):
6060
    case FOP(49, 17):
6061
    case FOP(50, 17):
6062
    case FOP(51, 17):
6063
    case FOP(52, 17):
6064
    case FOP(53, 17):
6065
    case FOP(54, 17):
6066
    case FOP(55, 17):
6067
    case FOP(56, 17):
6068
    case FOP(57, 17):
6069
    case FOP(58, 17):
6070
    case FOP(59, 17):
6071
    case FOP(60, 17):
6072
    case FOP(61, 17):
6073
    case FOP(62, 17):
6074
    case FOP(63, 17):
6075
        GEN_LOAD_FREG_FTN(DT0, fs);
6076
        GEN_LOAD_FREG_FTN(DT1, ft);
6077
        if (ctx->opcode & (1 << 6)) {
6078
            check_cop1x(ctx);
6079
            check_cp1_registers(ctx, fs | ft);
6080
            gen_cmpabs_d(func-48, cc);
6081
            opn = condnames_abs[func-48];
6082
        } else {
6083
            check_cp1_registers(ctx, fs | ft);
6084
            gen_cmp_d(func-48, cc);
6085
            opn = condnames[func-48];
6086
        }
6087
        break;
6088
    case FOP(32, 17):
6089
        check_cp1_registers(ctx, fs);
6090
        GEN_LOAD_FREG_FTN(DT0, fs);
6091
        gen_op_float_cvts_d();
6092
        GEN_STORE_FTN_FREG(fd, WT2);
6093
        opn = "cvt.s.d";
6094
        break;
6095
    case FOP(36, 17):
6096
        check_cp1_registers(ctx, fs);
6097
        GEN_LOAD_FREG_FTN(DT0, fs);
6098
        gen_op_float_cvtw_d();
6099
        GEN_STORE_FTN_FREG(fd, WT2);
6100
        opn = "cvt.w.d";
6101
        break;
6102
    case FOP(37, 17):
6103
        check_cp1_64bitmode(ctx);
6104
        GEN_LOAD_FREG_FTN(DT0, fs);
6105
        gen_op_float_cvtl_d();
6106
        GEN_STORE_FTN_FREG(fd, DT2);
6107
        opn = "cvt.l.d";
6108
        break;
6109
    case FOP(32, 20):
6110
        GEN_LOAD_FREG_FTN(WT0, fs);
6111
        gen_op_float_cvts_w();
6112
        GEN_STORE_FTN_FREG(fd, WT2);
6113
        opn = "cvt.s.w";
6114
        break;
6115
    case FOP(33, 20):
6116
        check_cp1_registers(ctx, fd);
6117
        GEN_LOAD_FREG_FTN(WT0, fs);
6118
        gen_op_float_cvtd_w();
6119
        GEN_STORE_FTN_FREG(fd, DT2);
6120
        opn = "cvt.d.w";
6121
        break;
6122
    case FOP(32, 21):
6123
        check_cp1_64bitmode(ctx);
6124
        GEN_LOAD_FREG_FTN(DT0, fs);
6125
        gen_op_float_cvts_l();
6126
        GEN_STORE_FTN_FREG(fd, WT2);
6127
        opn = "cvt.s.l";
6128
        break;
6129
    case FOP(33, 21):
6130
        check_cp1_64bitmode(ctx);
6131
        GEN_LOAD_FREG_FTN(DT0, fs);
6132
        gen_op_float_cvtd_l();
6133
        GEN_STORE_FTN_FREG(fd, DT2);
6134
        opn = "cvt.d.l";
6135
        break;
6136
    case FOP(38, 20):
6137
        check_cp1_64bitmode(ctx);
6138
        GEN_LOAD_FREG_FTN(WT0, fs);
6139
        GEN_LOAD_FREG_FTN(WTH0, fs);
6140
        gen_op_float_cvtps_pw();
6141
        GEN_STORE_FTN_FREG(fd, WT2);
6142
        GEN_STORE_FTN_FREG(fd, WTH2);
6143
        opn = "cvt.ps.pw";
6144
        break;
6145
    case FOP(0, 22):
6146
        check_cp1_64bitmode(ctx);
6147
        GEN_LOAD_FREG_FTN(WT0, fs);
6148
        GEN_LOAD_FREG_FTN(WTH0, fs);
6149
        GEN_LOAD_FREG_FTN(WT1, ft);
6150
        GEN_LOAD_FREG_FTN(WTH1, ft);
6151
        gen_op_float_add_ps();
6152
        GEN_STORE_FTN_FREG(fd, WT2);
6153
        GEN_STORE_FTN_FREG(fd, WTH2);
6154
        opn = "add.ps";
6155
        break;
6156
    case FOP(1, 22):
6157
        check_cp1_64bitmode(ctx);
6158
        GEN_LOAD_FREG_FTN(WT0, fs);
6159
        GEN_LOAD_FREG_FTN(WTH0, fs);
6160
        GEN_LOAD_FREG_FTN(WT1, ft);
6161
        GEN_LOAD_FREG_FTN(WTH1, ft);
6162
        gen_op_float_sub_ps();
6163
        GEN_STORE_FTN_FREG(fd, WT2);
6164
        GEN_STORE_FTN_FREG(fd, WTH2);
6165
        opn = "sub.ps";
6166
        break;
6167
    case FOP(2, 22):
6168
        check_cp1_64bitmode(ctx);
6169
        GEN_LOAD_FREG_FTN(WT0, fs);
6170
        GEN_LOAD_FREG_FTN(WTH0, fs);
6171
        GEN_LOAD_FREG_FTN(WT1, ft);
6172
        GEN_LOAD_FREG_FTN(WTH1, ft);
6173
        gen_op_float_mul_ps();
6174
        GEN_STORE_FTN_FREG(fd, WT2);
6175
        GEN_STORE_FTN_FREG(fd, WTH2);
6176
        opn = "mul.ps";
6177
        break;
6178
    case FOP(5, 22):
6179
        check_cp1_64bitmode(ctx);
6180
        GEN_LOAD_FREG_FTN(WT0, fs);
6181
        GEN_LOAD_FREG_FTN(WTH0, fs);
6182
        gen_op_float_abs_ps();
6183
        GEN_STORE_FTN_FREG(fd, WT2);
6184
        GEN_STORE_FTN_FREG(fd, WTH2);
6185
        opn = "abs.ps";
6186
        break;
6187
    case FOP(6, 22):
6188
        check_cp1_64bitmode(ctx);
6189
        GEN_LOAD_FREG_FTN(WT0, fs);
6190
        GEN_LOAD_FREG_FTN(WTH0, fs);
6191
        gen_op_float_mov_ps();
6192
        GEN_STORE_FTN_FREG(fd, WT2);
6193
        GEN_STORE_FTN_FREG(fd, WTH2);
6194
        opn = "mov.ps";
6195
        break;
6196
    case FOP(7, 22):
6197
        check_cp1_64bitmode(ctx);
6198
        GEN_LOAD_FREG_FTN(WT0, fs);
6199
        GEN_LOAD_FREG_FTN(WTH0, fs);
6200
        gen_op_float_chs_ps();
6201
        GEN_STORE_FTN_FREG(fd, WT2);
6202
        GEN_STORE_FTN_FREG(fd, WTH2);
6203
        opn = "neg.ps";
6204
        break;
6205
    case FOP(17, 22):
6206
        check_cp1_64bitmode(ctx);
6207
        gen_load_gpr(cpu_T[0], ft);
6208
        GEN_LOAD_FREG_FTN(WT0, fs);
6209
        GEN_LOAD_FREG_FTN(WTH0, fs);
6210
        GEN_LOAD_FREG_FTN(WT2, fd);
6211
        GEN_LOAD_FREG_FTN(WTH2, fd);
6212
        if (ft & 0x1)
6213
            gen_op_float_movt_ps ((ft >> 2) & 0x7);
6214
        else
6215
            gen_op_float_movf_ps ((ft >> 2) & 0x7);
6216
        GEN_STORE_FTN_FREG(fd, WT2);
6217
        GEN_STORE_FTN_FREG(fd, WTH2);
6218
        opn = "movcf.ps";
6219
        break;
6220
    case FOP(18, 22):
6221
        check_cp1_64bitmode(ctx);
6222
        gen_load_gpr(cpu_T[0], ft);
6223
        GEN_LOAD_FREG_FTN(WT0, fs);
6224
        GEN_LOAD_FREG_FTN(WTH0, fs);
6225
        GEN_LOAD_FREG_FTN(WT2, fd);
6226
        GEN_LOAD_FREG_FTN(WTH2, fd);
6227
        gen_op_float_movz_ps();
6228
        GEN_STORE_FTN_FREG(fd, WT2);
6229
        GEN_STORE_FTN_FREG(fd, WTH2);
6230
        opn = "movz.ps";
6231
        break;
6232
    case FOP(19, 22):
6233
        check_cp1_64bitmode(ctx);
6234
        gen_load_gpr(cpu_T[0], ft);
6235
        GEN_LOAD_FREG_FTN(WT0, fs);
6236
        GEN_LOAD_FREG_FTN(WTH0, fs);
6237
        GEN_LOAD_FREG_FTN(WT2, fd);
6238
        GEN_LOAD_FREG_FTN(WTH2, fd);
6239
        gen_op_float_movn_ps();
6240
        GEN_STORE_FTN_FREG(fd, WT2);
6241
        GEN_STORE_FTN_FREG(fd, WTH2);
6242
        opn = "movn.ps";
6243
        break;
6244
    case FOP(24, 22):
6245
        check_cp1_64bitmode(ctx);
6246
        GEN_LOAD_FREG_FTN(WT0, ft);
6247
        GEN_LOAD_FREG_FTN(WTH0, ft);
6248
        GEN_LOAD_FREG_FTN(WT1, fs);
6249
        GEN_LOAD_FREG_FTN(WTH1, fs);
6250
        gen_op_float_addr_ps();
6251
        GEN_STORE_FTN_FREG(fd, WT2);
6252
        GEN_STORE_FTN_FREG(fd, WTH2);
6253
        opn = "addr.ps";
6254
        break;
6255
    case FOP(26, 22):
6256
        check_cp1_64bitmode(ctx);
6257
        GEN_LOAD_FREG_FTN(WT0, ft);
6258
        GEN_LOAD_FREG_FTN(WTH0, ft);
6259
        GEN_LOAD_FREG_FTN(WT1, fs);
6260
        GEN_LOAD_FREG_FTN(WTH1, fs);
6261
        gen_op_float_mulr_ps();
6262
        GEN_STORE_FTN_FREG(fd, WT2);
6263
        GEN_STORE_FTN_FREG(fd, WTH2);
6264
        opn = "mulr.ps";
6265
        break;
6266
    case FOP(28, 22):
6267
        check_cp1_64bitmode(ctx);
6268
        GEN_LOAD_FREG_FTN(WT0, fs);
6269
        GEN_LOAD_FREG_FTN(WTH0, fs);
6270
        GEN_LOAD_FREG_FTN(WT2, fd);
6271
        GEN_LOAD_FREG_FTN(WTH2, fd);
6272
        gen_op_float_recip2_ps();
6273
        GEN_STORE_FTN_FREG(fd, WT2);
6274
        GEN_STORE_FTN_FREG(fd, WTH2);
6275
        opn = "recip2.ps";
6276
        break;
6277
    case FOP(29, 22):
6278
        check_cp1_64bitmode(ctx);
6279
        GEN_LOAD_FREG_FTN(WT0, fs);
6280
        GEN_LOAD_FREG_FTN(WTH0, fs);
6281
        gen_op_float_recip1_ps();
6282
        GEN_STORE_FTN_FREG(fd, WT2);
6283
        GEN_STORE_FTN_FREG(fd, WTH2);
6284
        opn = "recip1.ps";
6285
        break;
6286
    case FOP(30, 22):
6287
        check_cp1_64bitmode(ctx);
6288
        GEN_LOAD_FREG_FTN(WT0, fs);
6289
        GEN_LOAD_FREG_FTN(WTH0, fs);
6290
        gen_op_float_rsqrt1_ps();
6291
        GEN_STORE_FTN_FREG(fd, WT2);
6292
        GEN_STORE_FTN_FREG(fd, WTH2);
6293
        opn = "rsqrt1.ps";
6294
        break;
6295
    case FOP(31, 22):
6296
        check_cp1_64bitmode(ctx);
6297
        GEN_LOAD_FREG_FTN(WT0, fs);
6298
        GEN_LOAD_FREG_FTN(WTH0, fs);
6299
        GEN_LOAD_FREG_FTN(WT2, ft);
6300
        GEN_LOAD_FREG_FTN(WTH2, ft);
6301
        gen_op_float_rsqrt2_ps();
6302
        GEN_STORE_FTN_FREG(fd, WT2);
6303
        GEN_STORE_FTN_FREG(fd, WTH2);
6304
        opn = "rsqrt2.ps";
6305
        break;
6306
    case FOP(32, 22):
6307
        check_cp1_64bitmode(ctx);
6308
        GEN_LOAD_FREG_FTN(WTH0, fs);
6309
        gen_op_float_cvts_pu();
6310
        GEN_STORE_FTN_FREG(fd, WT2);
6311
        opn = "cvt.s.pu";
6312
        break;
6313
    case FOP(36, 22):
6314
        check_cp1_64bitmode(ctx);
6315
        GEN_LOAD_FREG_FTN(WT0, fs);
6316
        GEN_LOAD_FREG_FTN(WTH0, fs);
6317
        gen_op_float_cvtpw_ps();
6318
        GEN_STORE_FTN_FREG(fd, WT2);
6319
        GEN_STORE_FTN_FREG(fd, WTH2);
6320
        opn = "cvt.pw.ps";
6321
        break;
6322
    case FOP(40, 22):
6323
        check_cp1_64bitmode(ctx);
6324
        GEN_LOAD_FREG_FTN(WT0, fs);
6325
        gen_op_float_cvts_pl();
6326
        GEN_STORE_FTN_FREG(fd, WT2);
6327
        opn = "cvt.s.pl";
6328
        break;
6329
    case FOP(44, 22):
6330
        check_cp1_64bitmode(ctx);
6331
        GEN_LOAD_FREG_FTN(WT0, fs);
6332
        GEN_LOAD_FREG_FTN(WT1, ft);
6333
        gen_op_float_pll_ps();
6334
        GEN_STORE_FTN_FREG(fd, DT2);
6335
        opn = "pll.ps";
6336
        break;
6337
    case FOP(45, 22):
6338
        check_cp1_64bitmode(ctx);
6339
        GEN_LOAD_FREG_FTN(WT0, fs);
6340
        GEN_LOAD_FREG_FTN(WTH1, ft);
6341
        gen_op_float_plu_ps();
6342
        GEN_STORE_FTN_FREG(fd, DT2);
6343
        opn = "plu.ps";
6344
        break;
6345
    case FOP(46, 22):
6346
        check_cp1_64bitmode(ctx);
6347
        GEN_LOAD_FREG_FTN(WTH0, fs);
6348
        GEN_LOAD_FREG_FTN(WT1, ft);
6349
        gen_op_float_pul_ps();
6350
        GEN_STORE_FTN_FREG(fd, DT2);
6351
        opn = "pul.ps";
6352
        break;
6353
    case FOP(47, 22):
6354
        check_cp1_64bitmode(ctx);
6355
        GEN_LOAD_FREG_FTN(WTH0, fs);
6356
        GEN_LOAD_FREG_FTN(WTH1, ft);
6357
        gen_op_float_puu_ps();
6358
        GEN_STORE_FTN_FREG(fd, DT2);
6359
        opn = "puu.ps";
6360
        break;
6361
    case FOP(48, 22):
6362
    case FOP(49, 22):
6363
    case FOP(50, 22):
6364
    case FOP(51, 22):
6365
    case FOP(52, 22):
6366
    case FOP(53, 22):
6367
    case FOP(54, 22):
6368
    case FOP(55, 22):
6369
    case FOP(56, 22):
6370
    case FOP(57, 22):
6371
    case FOP(58, 22):
6372
    case FOP(59, 22):
6373
    case FOP(60, 22):
6374
    case FOP(61, 22):
6375
    case FOP(62, 22):
6376
    case FOP(63, 22):
6377
        check_cp1_64bitmode(ctx);
6378
        GEN_LOAD_FREG_FTN(WT0, fs);
6379
        GEN_LOAD_FREG_FTN(WTH0, fs);
6380
        GEN_LOAD_FREG_FTN(WT1, ft);
6381
        GEN_LOAD_FREG_FTN(WTH1, ft);
6382
        if (ctx->opcode & (1 << 6)) {
6383
            gen_cmpabs_ps(func-48, cc);
6384
            opn = condnames_abs[func-48];
6385
        } else {
6386
            gen_cmp_ps(func-48, cc);
6387
            opn = condnames[func-48];
6388
        }
6389
        break;
6390
    default:
6391
        MIPS_INVAL(opn);
6392
        generate_exception (ctx, EXCP_RI);
6393
        return;
6394
    }
6395
    switch (optype) {
6396
    case BINOP:
6397
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6398
        break;
6399
    case CMPOP:
6400
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6401
        break;
6402
    default:
6403
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6404
        break;
6405
    }
6406
}
6407

    
6408
/* Coprocessor 3 (FPU) */
6409
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6410
                           int fd, int fs, int base, int index)
6411
{
6412
    const char *opn = "extended float load/store";
6413
    int store = 0;
6414

    
6415
    if (base == 0) {
6416
        gen_load_gpr(cpu_T[0], index);
6417
    } else if (index == 0) {
6418
        gen_load_gpr(cpu_T[0], base);
6419
    } else {
6420
        gen_load_gpr(cpu_T[0], base);
6421
        gen_load_gpr(cpu_T[1], index);
6422
        gen_op_addr_add();
6423
    }
6424
    /* Don't do NOP if destination is zero: we must perform the actual
6425
       memory access. */
6426
    switch (opc) {
6427
    case OPC_LWXC1:
6428
        check_cop1x(ctx);
6429
        op_ldst_lwc1(ctx);
6430
        GEN_STORE_FTN_FREG(fd, WT0);
6431
        opn = "lwxc1";
6432
        break;
6433
    case OPC_LDXC1:
6434
        check_cop1x(ctx);
6435
        check_cp1_registers(ctx, fd);
6436
        op_ldst_ldc1(ctx);
6437
        GEN_STORE_FTN_FREG(fd, DT0);
6438
        opn = "ldxc1";
6439
        break;
6440
    case OPC_LUXC1:
6441
        check_cp1_64bitmode(ctx);
6442
        op_ldst(luxc1);
6443
        GEN_STORE_FTN_FREG(fd, DT0);
6444
        opn = "luxc1";
6445
        break;
6446
    case OPC_SWXC1:
6447
        check_cop1x(ctx);
6448
        GEN_LOAD_FREG_FTN(WT0, fs);
6449
        op_ldst_swc1(ctx);
6450
        opn = "swxc1";
6451
        store = 1;
6452
        break;
6453
    case OPC_SDXC1:
6454
        check_cop1x(ctx);
6455
        check_cp1_registers(ctx, fs);
6456
        GEN_LOAD_FREG_FTN(DT0, fs);
6457
        op_ldst_sdc1(ctx);
6458
        opn = "sdxc1";
6459
        store = 1;
6460
        break;
6461
    case OPC_SUXC1:
6462
        check_cp1_64bitmode(ctx);
6463
        GEN_LOAD_FREG_FTN(DT0, fs);
6464
        op_ldst(suxc1);
6465
        opn = "suxc1";
6466
        store = 1;
6467
        break;
6468
    default:
6469
        MIPS_INVAL(opn);
6470
        generate_exception(ctx, EXCP_RI);
6471
        return;
6472
    }
6473
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6474
               regnames[index], regnames[base]);
6475
}
6476

    
6477
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6478
                            int fd, int fr, int fs, int ft)
6479
{
6480
    const char *opn = "flt3_arith";
6481

    
6482
    switch (opc) {
6483
    case OPC_ALNV_PS:
6484
        check_cp1_64bitmode(ctx);
6485
        gen_load_gpr(cpu_T[0], fr);
6486
        GEN_LOAD_FREG_FTN(DT0, fs);
6487
        GEN_LOAD_FREG_FTN(DT1, ft);
6488
        gen_op_float_alnv_ps();
6489
        GEN_STORE_FTN_FREG(fd, DT2);
6490
        opn = "alnv.ps";
6491
        break;
6492
    case OPC_MADD_S:
6493
        check_cop1x(ctx);
6494
        GEN_LOAD_FREG_FTN(WT0, fs);
6495
        GEN_LOAD_FREG_FTN(WT1, ft);
6496
        GEN_LOAD_FREG_FTN(WT2, fr);
6497
        gen_op_float_muladd_s();
6498
        GEN_STORE_FTN_FREG(fd, WT2);
6499
        opn = "madd.s";
6500
        break;
6501
    case OPC_MADD_D:
6502
        check_cop1x(ctx);
6503
        check_cp1_registers(ctx, fd | fs | ft | fr);
6504
        GEN_LOAD_FREG_FTN(DT0, fs);
6505
        GEN_LOAD_FREG_FTN(DT1, ft);
6506
        GEN_LOAD_FREG_FTN(DT2, fr);
6507
        gen_op_float_muladd_d();
6508
        GEN_STORE_FTN_FREG(fd, DT2);
6509
        opn = "madd.d";
6510
        break;
6511
    case OPC_MADD_PS:
6512
        check_cp1_64bitmode(ctx);
6513
        GEN_LOAD_FREG_FTN(WT0, fs);
6514
        GEN_LOAD_FREG_FTN(WTH0, fs);
6515
        GEN_LOAD_FREG_FTN(WT1, ft);
6516
        GEN_LOAD_FREG_FTN(WTH1, ft);
6517
        GEN_LOAD_FREG_FTN(WT2, fr);
6518
        GEN_LOAD_FREG_FTN(WTH2, fr);
6519
        gen_op_float_muladd_ps();
6520
        GEN_STORE_FTN_FREG(fd, WT2);
6521
        GEN_STORE_FTN_FREG(fd, WTH2);
6522
        opn = "madd.ps";
6523
        break;
6524
    case OPC_MSUB_S:
6525
        check_cop1x(ctx);
6526
        GEN_LOAD_FREG_FTN(WT0, fs);
6527
        GEN_LOAD_FREG_FTN(WT1, ft);
6528
        GEN_LOAD_FREG_FTN(WT2, fr);
6529
        gen_op_float_mulsub_s();
6530
        GEN_STORE_FTN_FREG(fd, WT2);
6531
        opn = "msub.s";
6532
        break;
6533
    case OPC_MSUB_D:
6534
        check_cop1x(ctx);
6535
        check_cp1_registers(ctx, fd | fs | ft | fr);
6536
        GEN_LOAD_FREG_FTN(DT0, fs);
6537
        GEN_LOAD_FREG_FTN(DT1, ft);
6538
        GEN_LOAD_FREG_FTN(DT2, fr);
6539
        gen_op_float_mulsub_d();
6540
        GEN_STORE_FTN_FREG(fd, DT2);
6541
        opn = "msub.d";
6542
        break;
6543
    case OPC_MSUB_PS:
6544
        check_cp1_64bitmode(ctx);
6545
        GEN_LOAD_FREG_FTN(WT0, fs);
6546
        GEN_LOAD_FREG_FTN(WTH0, fs);
6547
        GEN_LOAD_FREG_FTN(WT1, ft);
6548
        GEN_LOAD_FREG_FTN(WTH1, ft);
6549
        GEN_LOAD_FREG_FTN(WT2, fr);
6550
        GEN_LOAD_FREG_FTN(WTH2, fr);
6551
        gen_op_float_mulsub_ps();
6552
        GEN_STORE_FTN_FREG(fd, WT2);
6553
        GEN_STORE_FTN_FREG(fd, WTH2);
6554
        opn = "msub.ps";
6555
        break;
6556
    case OPC_NMADD_S:
6557
        check_cop1x(ctx);
6558
        GEN_LOAD_FREG_FTN(WT0, fs);
6559
        GEN_LOAD_FREG_FTN(WT1, ft);
6560
        GEN_LOAD_FREG_FTN(WT2, fr);
6561
        gen_op_float_nmuladd_s();
6562
        GEN_STORE_FTN_FREG(fd, WT2);
6563
        opn = "nmadd.s";
6564
        break;
6565
    case OPC_NMADD_D:
6566
        check_cop1x(ctx);
6567
        check_cp1_registers(ctx, fd | fs | ft | fr);
6568
        GEN_LOAD_FREG_FTN(DT0, fs);
6569
        GEN_LOAD_FREG_FTN(DT1, ft);
6570
        GEN_LOAD_FREG_FTN(DT2, fr);
6571
        gen_op_float_nmuladd_d();
6572
        GEN_STORE_FTN_FREG(fd, DT2);
6573
        opn = "nmadd.d";
6574
        break;
6575
    case OPC_NMADD_PS:
6576
        check_cp1_64bitmode(ctx);
6577
        GEN_LOAD_FREG_FTN(WT0, fs);
6578
        GEN_LOAD_FREG_FTN(WTH0, fs);
6579
        GEN_LOAD_FREG_FTN(WT1, ft);
6580
        GEN_LOAD_FREG_FTN(WTH1, ft);
6581
        GEN_LOAD_FREG_FTN(WT2, fr);
6582
        GEN_LOAD_FREG_FTN(WTH2, fr);
6583
        gen_op_float_nmuladd_ps();
6584
        GEN_STORE_FTN_FREG(fd, WT2);
6585
        GEN_STORE_FTN_FREG(fd, WTH2);
6586
        opn = "nmadd.ps";
6587
        break;
6588
    case OPC_NMSUB_S:
6589
        check_cop1x(ctx);
6590
        GEN_LOAD_FREG_FTN(WT0, fs);
6591
        GEN_LOAD_FREG_FTN(WT1, ft);
6592
        GEN_LOAD_FREG_FTN(WT2, fr);
6593
        gen_op_float_nmulsub_s();
6594
        GEN_STORE_FTN_FREG(fd, WT2);
6595
        opn = "nmsub.s";
6596
        break;
6597
    case OPC_NMSUB_D:
6598
        check_cop1x(ctx);
6599
        check_cp1_registers(ctx, fd | fs | ft | fr);
6600
        GEN_LOAD_FREG_FTN(DT0, fs);
6601
        GEN_LOAD_FREG_FTN(DT1, ft);
6602
        GEN_LOAD_FREG_FTN(DT2, fr);
6603
        gen_op_float_nmulsub_d();
6604
        GEN_STORE_FTN_FREG(fd, DT2);
6605
        opn = "nmsub.d";
6606
        break;
6607
    case OPC_NMSUB_PS:
6608
        check_cp1_64bitmode(ctx);
6609
        GEN_LOAD_FREG_FTN(WT0, fs);
6610
        GEN_LOAD_FREG_FTN(WTH0, fs);
6611
        GEN_LOAD_FREG_FTN(WT1, ft);
6612
        GEN_LOAD_FREG_FTN(WTH1, ft);
6613
        GEN_LOAD_FREG_FTN(WT2, fr);
6614
        GEN_LOAD_FREG_FTN(WTH2, fr);
6615
        gen_op_float_nmulsub_ps();
6616
        GEN_STORE_FTN_FREG(fd, WT2);
6617
        GEN_STORE_FTN_FREG(fd, WTH2);
6618
        opn = "nmsub.ps";
6619
        break;
6620
    default:
6621
        MIPS_INVAL(opn);
6622
        generate_exception (ctx, EXCP_RI);
6623
        return;
6624
    }
6625
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6626
               fregnames[fs], fregnames[ft]);
6627
}
6628

    
6629
/* ISA extensions (ASEs) */
6630
/* MIPS16 extension to MIPS32 */
6631
/* SmartMIPS extension to MIPS32 */
6632

    
6633
#if defined(TARGET_MIPS64)
6634

    
6635
/* MDMX extension to MIPS64 */
6636

    
6637
#endif
6638

    
6639
static void decode_opc (CPUState *env, DisasContext *ctx)
6640
{
6641
    int32_t offset;
6642
    int rs, rt, rd, sa;
6643
    uint32_t op, op1, op2;
6644
    int16_t imm;
6645

    
6646
    /* make sure instructions are on a word boundary */
6647
    if (ctx->pc & 0x3) {
6648
        env->CP0_BadVAddr = ctx->pc;
6649
        generate_exception(ctx, EXCP_AdEL);
6650
        return;
6651
    }
6652

    
6653
    /* Handle blikely not taken case */
6654
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6655
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6656
        int l1 = gen_new_label();
6657

    
6658
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6659
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6660
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6661
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6662
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6663
        gen_set_label(l1);
6664
    }
6665
    op = MASK_OP_MAJOR(ctx->opcode);
6666
    rs = (ctx->opcode >> 21) & 0x1f;
6667
    rt = (ctx->opcode >> 16) & 0x1f;
6668
    rd = (ctx->opcode >> 11) & 0x1f;
6669
    sa = (ctx->opcode >> 6) & 0x1f;
6670
    imm = (int16_t)ctx->opcode;
6671
    switch (op) {
6672
    case OPC_SPECIAL:
6673
        op1 = MASK_SPECIAL(ctx->opcode);
6674
        switch (op1) {
6675
        case OPC_SLL:          /* Arithmetic with immediate */
6676
        case OPC_SRL ... OPC_SRA:
6677
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6678
            break;
6679
        case OPC_MOVZ ... OPC_MOVN:
6680
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6681
        case OPC_SLLV:         /* Arithmetic */
6682
        case OPC_SRLV ... OPC_SRAV:
6683
        case OPC_ADD ... OPC_NOR:
6684
        case OPC_SLT ... OPC_SLTU:
6685
            gen_arith(env, ctx, op1, rd, rs, rt);
6686
            break;
6687
        case OPC_MULT ... OPC_DIVU:
6688
            if (sa) {
6689
                check_insn(env, ctx, INSN_VR54XX);
6690
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6691
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6692
            } else
6693
                gen_muldiv(ctx, op1, rs, rt);
6694
            break;
6695
        case OPC_JR ... OPC_JALR:
6696
            gen_compute_branch(ctx, op1, rs, rd, sa);
6697
            return;
6698
        case OPC_TGE ... OPC_TEQ: /* Traps */
6699
        case OPC_TNE:
6700
            gen_trap(ctx, op1, rs, rt, -1);
6701
            break;
6702
        case OPC_MFHI:          /* Move from HI/LO */
6703
        case OPC_MFLO:
6704
            gen_HILO(ctx, op1, rd);
6705
            break;
6706
        case OPC_MTHI:
6707
        case OPC_MTLO:          /* Move to HI/LO */
6708
            gen_HILO(ctx, op1, rs);
6709
            break;
6710
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6711
#ifdef MIPS_STRICT_STANDARD
6712
            MIPS_INVAL("PMON / selsl");
6713
            generate_exception(ctx, EXCP_RI);
6714
#else
6715
            gen_op_pmon(sa);
6716
#endif
6717
            break;
6718
        case OPC_SYSCALL:
6719
            generate_exception(ctx, EXCP_SYSCALL);
6720
            break;
6721
        case OPC_BREAK:
6722
            generate_exception(ctx, EXCP_BREAK);
6723
            break;
6724
        case OPC_SPIM:
6725
#ifdef MIPS_STRICT_STANDARD
6726
            MIPS_INVAL("SPIM");
6727
            generate_exception(ctx, EXCP_RI);
6728
#else
6729
           /* Implemented as RI exception for now. */
6730
            MIPS_INVAL("spim (unofficial)");
6731
            generate_exception(ctx, EXCP_RI);
6732
#endif
6733
            break;
6734
        case OPC_SYNC:
6735
            /* Treat as NOP. */
6736
            break;
6737

    
6738
        case OPC_MOVCI:
6739
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6740
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6741
                save_cpu_state(ctx, 1);
6742
                check_cp1_enabled(ctx);
6743
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6744
                          (ctx->opcode >> 16) & 1);
6745
            } else {
6746
                generate_exception_err(ctx, EXCP_CpU, 1);
6747
            }
6748
            break;
6749

    
6750
#if defined(TARGET_MIPS64)
6751
       /* MIPS64 specific opcodes */
6752
        case OPC_DSLL:
6753
        case OPC_DSRL ... OPC_DSRA:
6754
        case OPC_DSLL32:
6755
        case OPC_DSRL32 ... OPC_DSRA32:
6756
            check_insn(env, ctx, ISA_MIPS3);
6757
            check_mips_64(ctx);
6758
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6759
            break;
6760
        case OPC_DSLLV:
6761
        case OPC_DSRLV ... OPC_DSRAV:
6762
        case OPC_DADD ... OPC_DSUBU:
6763
            check_insn(env, ctx, ISA_MIPS3);
6764
            check_mips_64(ctx);
6765
            gen_arith(env, ctx, op1, rd, rs, rt);
6766
            break;
6767
        case OPC_DMULT ... OPC_DDIVU:
6768
            check_insn(env, ctx, ISA_MIPS3);
6769
            check_mips_64(ctx);
6770
            gen_muldiv(ctx, op1, rs, rt);
6771
            break;
6772
#endif
6773
        default:            /* Invalid */
6774
            MIPS_INVAL("special");
6775
            generate_exception(ctx, EXCP_RI);
6776
            break;
6777
        }
6778
        break;
6779
    case OPC_SPECIAL2:
6780
        op1 = MASK_SPECIAL2(ctx->opcode);
6781
        switch (op1) {
6782
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6783
        case OPC_MSUB ... OPC_MSUBU:
6784
            check_insn(env, ctx, ISA_MIPS32);
6785
            gen_muldiv(ctx, op1, rs, rt);
6786
            break;
6787
        case OPC_MUL:
6788
            gen_arith(env, ctx, op1, rd, rs, rt);
6789
            break;
6790
        case OPC_CLZ ... OPC_CLO:
6791
            check_insn(env, ctx, ISA_MIPS32);
6792
            gen_cl(ctx, op1, rd, rs);
6793
            break;
6794
        case OPC_SDBBP:
6795
            /* XXX: not clear which exception should be raised
6796
             *      when in debug mode...
6797
             */
6798
            check_insn(env, ctx, ISA_MIPS32);
6799
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6800
                generate_exception(ctx, EXCP_DBp);
6801
            } else {
6802
                generate_exception(ctx, EXCP_DBp);
6803
            }
6804
            /* Treat as NOP. */
6805
            break;
6806
#if defined(TARGET_MIPS64)
6807
        case OPC_DCLZ ... OPC_DCLO:
6808
            check_insn(env, ctx, ISA_MIPS64);
6809
            check_mips_64(ctx);
6810
            gen_cl(ctx, op1, rd, rs);
6811
            break;
6812
#endif
6813
        default:            /* Invalid */
6814
            MIPS_INVAL("special2");
6815
            generate_exception(ctx, EXCP_RI);
6816
            break;
6817
        }
6818
        break;
6819
    case OPC_SPECIAL3:
6820
         op1 = MASK_SPECIAL3(ctx->opcode);
6821
         switch (op1) {
6822
         case OPC_EXT:
6823
         case OPC_INS:
6824
             check_insn(env, ctx, ISA_MIPS32R2);
6825
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6826
             break;
6827
         case OPC_BSHFL:
6828
             check_insn(env, ctx, ISA_MIPS32R2);
6829
             op2 = MASK_BSHFL(ctx->opcode);
6830
             switch (op2) {
6831
             case OPC_WSBH:
6832
                 gen_load_gpr(cpu_T[1], rt);
6833
                 gen_op_wsbh();
6834
                 break;
6835
             case OPC_SEB:
6836
                 gen_load_gpr(cpu_T[1], rt);
6837
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6838
                 break;
6839
             case OPC_SEH:
6840
                 gen_load_gpr(cpu_T[1], rt);
6841
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6842
                 break;
6843
             default:            /* Invalid */
6844
                 MIPS_INVAL("bshfl");
6845
                 generate_exception(ctx, EXCP_RI);
6846
                 break;
6847
            }
6848
            gen_store_gpr(cpu_T[0], rd);
6849
            break;
6850
        case OPC_RDHWR:
6851
            check_insn(env, ctx, ISA_MIPS32R2);
6852
            switch (rd) {
6853
            case 0:
6854
                save_cpu_state(ctx, 1);
6855
                gen_op_rdhwr_cpunum();
6856
                break;
6857
            case 1:
6858
                save_cpu_state(ctx, 1);
6859
                gen_op_rdhwr_synci_step();
6860
                break;
6861
            case 2:
6862
                save_cpu_state(ctx, 1);
6863
                gen_op_rdhwr_cc();
6864
                break;
6865
            case 3:
6866
                save_cpu_state(ctx, 1);
6867
                gen_op_rdhwr_ccres();
6868
                break;
6869
            case 29:
6870
#if defined (CONFIG_USER_ONLY)
6871
                gen_op_tls_value();
6872
                break;
6873
#endif
6874
            default:            /* Invalid */
6875
                MIPS_INVAL("rdhwr");
6876
                generate_exception(ctx, EXCP_RI);
6877
                break;
6878
            }
6879
            gen_store_gpr(cpu_T[0], rt);
6880
            break;
6881
        case OPC_FORK:
6882
            check_insn(env, ctx, ASE_MT);
6883
            gen_load_gpr(cpu_T[0], rt);
6884
            gen_load_gpr(cpu_T[1], rs);
6885
            gen_op_fork();
6886
            break;
6887
        case OPC_YIELD:
6888
            check_insn(env, ctx, ASE_MT);
6889
            gen_load_gpr(cpu_T[0], rs);
6890
            gen_op_yield();
6891
            gen_store_gpr(cpu_T[0], rd);
6892
            break;
6893
#if defined(TARGET_MIPS64)
6894
        case OPC_DEXTM ... OPC_DEXT:
6895
        case OPC_DINSM ... OPC_DINS:
6896
            check_insn(env, ctx, ISA_MIPS64R2);
6897
            check_mips_64(ctx);
6898
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6899
            break;
6900
        case OPC_DBSHFL:
6901
            check_insn(env, ctx, ISA_MIPS64R2);
6902
            check_mips_64(ctx);
6903
            op2 = MASK_DBSHFL(ctx->opcode);
6904
            switch (op2) {
6905
            case OPC_DSBH:
6906
                gen_load_gpr(cpu_T[1], rt);
6907
                gen_op_dsbh();
6908
                break;
6909
            case OPC_DSHD:
6910
                gen_load_gpr(cpu_T[1], rt);
6911
                gen_op_dshd();
6912
                break;
6913
            default:            /* Invalid */
6914
                MIPS_INVAL("dbshfl");
6915
                generate_exception(ctx, EXCP_RI);
6916
                break;
6917
            }
6918
            gen_store_gpr(cpu_T[0], rd);
6919
            break;
6920
#endif
6921
        default:            /* Invalid */
6922
            MIPS_INVAL("special3");
6923
            generate_exception(ctx, EXCP_RI);
6924
            break;
6925
        }
6926
        break;
6927
    case OPC_REGIMM:
6928
        op1 = MASK_REGIMM(ctx->opcode);
6929
        switch (op1) {
6930
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6931
        case OPC_BLTZAL ... OPC_BGEZALL:
6932
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6933
            return;
6934
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6935
        case OPC_TNEI:
6936
            gen_trap(ctx, op1, rs, -1, imm);
6937
            break;
6938
        case OPC_SYNCI:
6939
            check_insn(env, ctx, ISA_MIPS32R2);
6940
            /* Treat as NOP. */
6941
            break;
6942
        default:            /* Invalid */
6943
            MIPS_INVAL("regimm");
6944
            generate_exception(ctx, EXCP_RI);
6945
            break;
6946
        }
6947
        break;
6948
    case OPC_CP0:
6949
        check_cp0_enabled(ctx);
6950
        op1 = MASK_CP0(ctx->opcode);
6951
        switch (op1) {
6952
        case OPC_MFC0:
6953
        case OPC_MTC0:
6954
        case OPC_MFTR:
6955
        case OPC_MTTR:
6956
#if defined(TARGET_MIPS64)
6957
        case OPC_DMFC0:
6958
        case OPC_DMTC0:
6959
#endif
6960
            gen_cp0(env, ctx, op1, rt, rd);
6961
            break;
6962
        case OPC_C0_FIRST ... OPC_C0_LAST:
6963
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6964
            break;
6965
        case OPC_MFMC0:
6966
            op2 = MASK_MFMC0(ctx->opcode);
6967
            switch (op2) {
6968
            case OPC_DMT:
6969
                check_insn(env, ctx, ASE_MT);
6970
                gen_op_dmt();
6971
                break;
6972
            case OPC_EMT:
6973
                check_insn(env, ctx, ASE_MT);
6974
                gen_op_emt();
6975
                break;
6976
            case OPC_DVPE:
6977
                check_insn(env, ctx, ASE_MT);
6978
                gen_op_dvpe();
6979
                break;
6980
            case OPC_EVPE:
6981
                check_insn(env, ctx, ASE_MT);
6982
                gen_op_evpe();
6983
                break;
6984
            case OPC_DI:
6985
                check_insn(env, ctx, ISA_MIPS32R2);
6986
                save_cpu_state(ctx, 1);
6987
                gen_op_di();
6988
                /* Stop translation as we may have switched the execution mode */
6989
                ctx->bstate = BS_STOP;
6990
                break;
6991
            case OPC_EI:
6992
                check_insn(env, ctx, ISA_MIPS32R2);
6993
                save_cpu_state(ctx, 1);
6994
                gen_op_ei();
6995
                /* Stop translation as we may have switched the execution mode */
6996
                ctx->bstate = BS_STOP;
6997
                break;
6998
            default:            /* Invalid */
6999
                MIPS_INVAL("mfmc0");
7000
                generate_exception(ctx, EXCP_RI);
7001
                break;
7002
            }
7003
            gen_store_gpr(cpu_T[0], rt);
7004
            break;
7005
        case OPC_RDPGPR:
7006
            check_insn(env, ctx, ISA_MIPS32R2);
7007
            gen_load_srsgpr(cpu_T[0], rt);
7008
            gen_store_gpr(cpu_T[0], rd);
7009
            break;
7010
        case OPC_WRPGPR:
7011
            check_insn(env, ctx, ISA_MIPS32R2);
7012
            gen_load_gpr(cpu_T[0], rt);
7013
            gen_store_srsgpr(cpu_T[0], rd);
7014
            break;
7015
        default:
7016
            MIPS_INVAL("cp0");
7017
            generate_exception(ctx, EXCP_RI);
7018
            break;
7019
        }
7020
        break;
7021
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7022
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7023
         break;
7024
    case OPC_J ... OPC_JAL: /* Jump */
7025
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7026
         gen_compute_branch(ctx, op, rs, rt, offset);
7027
         return;
7028
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7029
    case OPC_BEQL ... OPC_BGTZL:
7030
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7031
         return;
7032
    case OPC_LB ... OPC_LWR: /* Load and stores */
7033
    case OPC_SB ... OPC_SW:
7034
    case OPC_SWR:
7035
    case OPC_LL:
7036
    case OPC_SC:
7037
         gen_ldst(ctx, op, rt, rs, imm);
7038
         break;
7039
    case OPC_CACHE:
7040
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7041
        /* Treat as NOP. */
7042
        break;
7043
    case OPC_PREF:
7044
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7045
        /* Treat as NOP. */
7046
        break;
7047

    
7048
    /* Floating point (COP1). */
7049
    case OPC_LWC1:
7050
    case OPC_LDC1:
7051
    case OPC_SWC1:
7052
    case OPC_SDC1:
7053
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7054
            save_cpu_state(ctx, 1);
7055
            check_cp1_enabled(ctx);
7056
            gen_flt_ldst(ctx, op, rt, rs, imm);
7057
        } else {
7058
            generate_exception_err(ctx, EXCP_CpU, 1);
7059
        }
7060
        break;
7061

    
7062
    case OPC_CP1:
7063
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7064
            save_cpu_state(ctx, 1);
7065
            check_cp1_enabled(ctx);
7066
            op1 = MASK_CP1(ctx->opcode);
7067
            switch (op1) {
7068
            case OPC_MFHC1:
7069
            case OPC_MTHC1:
7070
                check_insn(env, ctx, ISA_MIPS32R2);
7071
            case OPC_MFC1:
7072
            case OPC_CFC1:
7073
            case OPC_MTC1:
7074
            case OPC_CTC1:
7075
                gen_cp1(ctx, op1, rt, rd);
7076
                break;
7077
#if defined(TARGET_MIPS64)
7078
            case OPC_DMFC1:
7079
            case OPC_DMTC1:
7080
                check_insn(env, ctx, ISA_MIPS3);
7081
                gen_cp1(ctx, op1, rt, rd);
7082
                break;
7083
#endif
7084
            case OPC_BC1ANY2:
7085
            case OPC_BC1ANY4:
7086
                check_cop1x(ctx);
7087
                check_insn(env, ctx, ASE_MIPS3D);
7088
                /* fall through */
7089
            case OPC_BC1:
7090
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7091
                                    (rt >> 2) & 0x7, imm << 2);
7092
                return;
7093
            case OPC_S_FMT:
7094
            case OPC_D_FMT:
7095
            case OPC_W_FMT:
7096
            case OPC_L_FMT:
7097
            case OPC_PS_FMT:
7098
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7099
                           (imm >> 8) & 0x7);
7100
                break;
7101
            default:
7102
                MIPS_INVAL("cp1");
7103
                generate_exception (ctx, EXCP_RI);
7104
                break;
7105
            }
7106
        } else {
7107
            generate_exception_err(ctx, EXCP_CpU, 1);
7108
        }
7109
        break;
7110

    
7111
    /* COP2.  */
7112
    case OPC_LWC2:
7113
    case OPC_LDC2:
7114
    case OPC_SWC2:
7115
    case OPC_SDC2:
7116
    case OPC_CP2:
7117
        /* COP2: Not implemented. */
7118
        generate_exception_err(ctx, EXCP_CpU, 2);
7119
        break;
7120

    
7121
    case OPC_CP3:
7122
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7123
            save_cpu_state(ctx, 1);
7124
            check_cp1_enabled(ctx);
7125
            op1 = MASK_CP3(ctx->opcode);
7126
            switch (op1) {
7127
            case OPC_LWXC1:
7128
            case OPC_LDXC1:
7129
            case OPC_LUXC1:
7130
            case OPC_SWXC1:
7131
            case OPC_SDXC1:
7132
            case OPC_SUXC1:
7133
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7134
                break;
7135
            case OPC_PREFX:
7136
                /* Treat as NOP. */
7137
                break;
7138
            case OPC_ALNV_PS:
7139
            case OPC_MADD_S:
7140
            case OPC_MADD_D:
7141
            case OPC_MADD_PS:
7142
            case OPC_MSUB_S:
7143
            case OPC_MSUB_D:
7144
            case OPC_MSUB_PS:
7145
            case OPC_NMADD_S:
7146
            case OPC_NMADD_D:
7147
            case OPC_NMADD_PS:
7148
            case OPC_NMSUB_S:
7149
            case OPC_NMSUB_D:
7150
            case OPC_NMSUB_PS:
7151
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7152
                break;
7153
            default:
7154
                MIPS_INVAL("cp3");
7155
                generate_exception (ctx, EXCP_RI);
7156
                break;
7157
            }
7158
        } else {
7159
            generate_exception_err(ctx, EXCP_CpU, 1);
7160
        }
7161
        break;
7162

    
7163
#if defined(TARGET_MIPS64)
7164
    /* MIPS64 opcodes */
7165
    case OPC_LWU:
7166
    case OPC_LDL ... OPC_LDR:
7167
    case OPC_SDL ... OPC_SDR:
7168
    case OPC_LLD:
7169
    case OPC_LD:
7170
    case OPC_SCD:
7171
    case OPC_SD:
7172
        check_insn(env, ctx, ISA_MIPS3);
7173
        check_mips_64(ctx);
7174
        gen_ldst(ctx, op, rt, rs, imm);
7175
        break;
7176
    case OPC_DADDI ... OPC_DADDIU:
7177
        check_insn(env, ctx, ISA_MIPS3);
7178
        check_mips_64(ctx);
7179
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7180
        break;
7181
#endif
7182
    case OPC_JALX:
7183
        check_insn(env, ctx, ASE_MIPS16);
7184
        /* MIPS16: Not implemented. */
7185
    case OPC_MDMX:
7186
        check_insn(env, ctx, ASE_MDMX);
7187
        /* MDMX: Not implemented. */
7188
    default:            /* Invalid */
7189
        MIPS_INVAL("major opcode");
7190
        generate_exception(ctx, EXCP_RI);
7191
        break;
7192
    }
7193
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7194
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7195
        /* Branches completion */
7196
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7197
        ctx->bstate = BS_BRANCH;
7198
        save_cpu_state(ctx, 0);
7199
        switch (hflags) {
7200
        case MIPS_HFLAG_B:
7201
            /* unconditional branch */
7202
            MIPS_DEBUG("unconditional branch");
7203
            gen_goto_tb(ctx, 0, ctx->btarget);
7204
            break;
7205
        case MIPS_HFLAG_BL:
7206
            /* blikely taken case */
7207
            MIPS_DEBUG("blikely branch taken");
7208
            gen_goto_tb(ctx, 0, ctx->btarget);
7209
            break;
7210
        case MIPS_HFLAG_BC:
7211
            /* Conditional branch */
7212
            MIPS_DEBUG("conditional branch");
7213
            {
7214
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7215
                int l1 = gen_new_label();
7216

    
7217
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7218
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7219
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7220
                gen_set_label(l1);
7221
                gen_goto_tb(ctx, 0, ctx->btarget);
7222
            }
7223
            break;
7224
        case MIPS_HFLAG_BR:
7225
            /* unconditional branch to register */
7226
            MIPS_DEBUG("branch to register");
7227
            gen_breg_pc();
7228
            tcg_gen_exit_tb(0);
7229
            break;
7230
        default:
7231
            MIPS_DEBUG("unknown branch");
7232
            break;
7233
        }
7234
    }
7235
}
7236

    
7237
static always_inline int
7238
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7239
                                int search_pc)
7240
{
7241
    DisasContext ctx;
7242
    target_ulong pc_start;
7243
    uint16_t *gen_opc_end;
7244
    int j, lj = -1;
7245

    
7246
    if (search_pc && loglevel)
7247
        fprintf (logfile, "search pc %d\n", search_pc);
7248

    
7249
    num_temps = 0;
7250
    memset(temps, 0, sizeof(temps));
7251

    
7252
    num_temps = 0;
7253
    memset(temps, 0, sizeof(temps));
7254

    
7255
    pc_start = tb->pc;
7256
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7257
    ctx.pc = pc_start;
7258
    ctx.saved_pc = -1;
7259
    ctx.tb = tb;
7260
    ctx.bstate = BS_NONE;
7261
    /* Restore delay slot state from the tb context.  */
7262
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7263
    restore_cpu_state(env, &ctx);
7264
#if defined(CONFIG_USER_ONLY)
7265
    ctx.mem_idx = MIPS_HFLAG_UM;
7266
#else
7267
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7268
#endif
7269
#ifdef DEBUG_DISAS
7270
    if (loglevel & CPU_LOG_TB_CPU) {
7271
        fprintf(logfile, "------------------------------------------------\n");
7272
        /* FIXME: This may print out stale hflags from env... */
7273
        cpu_dump_state(env, logfile, fprintf, 0);
7274
    }
7275
#endif
7276
#ifdef MIPS_DEBUG_DISAS
7277
    if (loglevel & CPU_LOG_TB_IN_ASM)
7278
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7279
                tb, ctx.mem_idx, ctx.hflags);
7280
#endif
7281
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7282
        if (env->nb_breakpoints > 0) {
7283
            for(j = 0; j < env->nb_breakpoints; j++) {
7284
                if (env->breakpoints[j] == ctx.pc) {
7285
                    save_cpu_state(&ctx, 1);
7286
                    ctx.bstate = BS_BRANCH;
7287
                    gen_op_debug();
7288
                    /* Include the breakpoint location or the tb won't
7289
                     * be flushed when it must be.  */
7290
                    ctx.pc += 4;
7291
                    goto done_generating;
7292
                }
7293
            }
7294
        }
7295

    
7296
        if (search_pc) {
7297
            j = gen_opc_ptr - gen_opc_buf;
7298
            if (lj < j) {
7299
                lj++;
7300
                while (lj < j)
7301
                    gen_opc_instr_start[lj++] = 0;
7302
            }
7303
            gen_opc_pc[lj] = ctx.pc;
7304
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7305
            gen_opc_instr_start[lj] = 1;
7306
        }
7307
        ctx.opcode = ldl_code(ctx.pc);
7308
        decode_opc(env, &ctx);
7309
        if (num_temps) {
7310
            fprintf(stderr,
7311
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7312
                    ctx.pc);
7313
            num_temps = 0;
7314
        }
7315
        ctx.pc += 4;
7316

    
7317
        if (env->singlestep_enabled)
7318
            break;
7319

    
7320
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7321
            break;
7322

    
7323
#if defined (MIPS_SINGLE_STEP)
7324
        break;
7325
#endif
7326
    }
7327
    if (env->singlestep_enabled) {
7328
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7329
        gen_op_debug();
7330
    } else {
7331
        switch (ctx.bstate) {
7332
        case BS_STOP:
7333
            tcg_gen_helper_0_0(do_interrupt_restart);
7334
            gen_goto_tb(&ctx, 0, ctx.pc);
7335
            break;
7336
        case BS_NONE:
7337
            save_cpu_state(&ctx, 0);
7338
            gen_goto_tb(&ctx, 0, ctx.pc);
7339
            break;
7340
        case BS_EXCP:
7341
            tcg_gen_helper_0_0(do_interrupt_restart);
7342
            tcg_gen_exit_tb(0);
7343
            break;
7344
        case BS_BRANCH:
7345
        default:
7346
            break;
7347
        }
7348
    }
7349
done_generating:
7350
    *gen_opc_ptr = INDEX_op_end;
7351
    if (search_pc) {
7352
        j = gen_opc_ptr - gen_opc_buf;
7353
        lj++;
7354
        while (lj <= j)
7355
            gen_opc_instr_start[lj++] = 0;
7356
    } else {
7357
        tb->size = ctx.pc - pc_start;
7358
    }
7359
#ifdef DEBUG_DISAS
7360
#if defined MIPS_DEBUG_DISAS
7361
    if (loglevel & CPU_LOG_TB_IN_ASM)
7362
        fprintf(logfile, "\n");
7363
#endif
7364
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7365
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7366
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7367
        fprintf(logfile, "\n");
7368
    }
7369
    if (loglevel & CPU_LOG_TB_CPU) {
7370
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7371
    }
7372
#endif
7373

    
7374
    return 0;
7375
}
7376

    
7377
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7378
{
7379
    return gen_intermediate_code_internal(env, tb, 0);
7380
}
7381

    
7382
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7383
{
7384
    return gen_intermediate_code_internal(env, tb, 1);
7385
}
7386

    
7387
void fpu_dump_state(CPUState *env, FILE *f,
7388
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7389
                    int flags)
7390
{
7391
    int i;
7392
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7393

    
7394
#define printfpr(fp)                                                        \
7395
    do {                                                                    \
7396
        if (is_fpu64)                                                       \
7397
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7398
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7399
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7400
        else {                                                              \
7401
            fpr_t tmp;                                                      \
7402
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7403
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7404
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7405
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7406
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7407
        }                                                                   \
7408
    } while(0)
7409

    
7410

    
7411
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7412
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7413
                get_float_exception_flags(&env->fpu->fp_status));
7414
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7415
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7416
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7417
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7418
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7419
        printfpr(&env->fpu->fpr[i]);
7420
    }
7421

    
7422
#undef printfpr
7423
}
7424

    
7425
void dump_fpu (CPUState *env)
7426
{
7427
    if (loglevel) {
7428
        fprintf(logfile,
7429
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7430
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7431
                " %04x\n",
7432
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7433
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7434
                env->bcond);
7435
       fpu_dump_state(env, logfile, fprintf, 0);
7436
    }
7437
}
7438

    
7439
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7440
/* Debug help: The architecture requires 32bit code to maintain proper
7441
   sign-extened values on 64bit machines.  */
7442

    
7443
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7444

    
7445
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7446
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7447
                     int flags)
7448
{
7449
    int i;
7450

    
7451
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7452
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7453
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7454
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7455
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7456
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7457
    if (!SIGN_EXT_P(env->btarget))
7458
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7459

    
7460
    for (i = 0; i < 32; i++) {
7461
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7462
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7463
    }
7464

    
7465
    if (!SIGN_EXT_P(env->CP0_EPC))
7466
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7467
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7468
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7469
}
7470
#endif
7471

    
7472
void cpu_dump_state (CPUState *env, FILE *f,
7473
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7474
                     int flags)
7475
{
7476
    int i;
7477

    
7478
    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",
7479
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7480
    for (i = 0; i < 32; i++) {
7481
        if ((i & 3) == 0)
7482
            cpu_fprintf(f, "GPR%02d:", i);
7483
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7484
        if ((i & 3) == 3)
7485
            cpu_fprintf(f, "\n");
7486
    }
7487

    
7488
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7489
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7490
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7491
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7492
    if (env->hflags & MIPS_HFLAG_FPU)
7493
        fpu_dump_state(env, f, cpu_fprintf, flags);
7494
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7495
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7496
#endif
7497
}
7498

    
7499
static void mips_tcg_init(void)
7500
{
7501
    static int inited;
7502

    
7503
    /* Initialize various static tables. */
7504
    if (inited)
7505
        return;
7506

    
7507
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7508
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7509
                                         TCG_AREG0,
7510
                                         offsetof(CPUState, current_tc_gprs),
7511
                                         "current_tc_gprs");
7512
    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7513
                                       TCG_AREG0,
7514
                                       offsetof(CPUState, current_tc_hi),
7515
                                       "current_tc_hi");
7516
#if TARGET_LONG_BITS > HOST_LONG_BITS
7517
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7518
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7519
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7520
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7521
#else
7522
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7523
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7524
#endif
7525

    
7526
    inited = 1;
7527
}
7528

    
7529
#include "translate_init.c"
7530

    
7531
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7532
{
7533
    CPUMIPSState *env;
7534
    const mips_def_t *def;
7535

    
7536
    def = cpu_mips_find_by_name(cpu_model);
7537
    if (!def)
7538
        return NULL;
7539
    env = qemu_mallocz(sizeof(CPUMIPSState));
7540
    if (!env)
7541
        return NULL;
7542
    env->cpu_model = def;
7543

    
7544
    cpu_exec_init(env);
7545
    env->cpu_model_str = cpu_model;
7546
    mips_tcg_init();
7547
    cpu_reset(env);
7548
    return env;
7549
}
7550

    
7551
void cpu_reset (CPUMIPSState *env)
7552
{
7553
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7554

    
7555
    tlb_flush(env, 1);
7556

    
7557
    /* Minimal init */
7558
#if !defined(CONFIG_USER_ONLY)
7559
    if (env->hflags & MIPS_HFLAG_BMASK) {
7560
        /* If the exception was raised from a delay slot,
7561
         * come back to the jump.  */
7562
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7563
    } else {
7564
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7565
    }
7566
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7567
    env->CP0_Wired = 0;
7568
    /* SMP not implemented */
7569
    env->CP0_EBase = 0x80000000;
7570
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7571
    /* vectored interrupts not implemented, timer on int 7,
7572
       no performance counters. */
7573
    env->CP0_IntCtl = 0xe0000000;
7574
    {
7575
        int i;
7576

    
7577
        for (i = 0; i < 7; i++) {
7578
            env->CP0_WatchLo[i] = 0;
7579
            env->CP0_WatchHi[i] = 0x80000000;
7580
        }
7581
        env->CP0_WatchLo[7] = 0;
7582
        env->CP0_WatchHi[7] = 0;
7583
    }
7584
    /* Count register increments in debug mode, EJTAG version 1 */
7585
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7586
#endif
7587
    env->exception_index = EXCP_NONE;
7588
#if defined(CONFIG_USER_ONLY)
7589
    env->hflags = MIPS_HFLAG_UM;
7590
    env->user_mode_only = 1;
7591
#else
7592
    env->hflags = MIPS_HFLAG_CP0;
7593
#endif
7594
    cpu_mips_register(env, env->cpu_model);
7595
}
7596

    
7597
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7598
                unsigned long searched_pc, int pc_pos, void *puc)
7599
{
7600
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7601
    env->hflags &= ~MIPS_HFLAG_BMASK;
7602
    env->hflags |= gen_opc_hflags[pc_pos];
7603
}