Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 893f9865

History | View | Annotate | Download (219.7 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 = new_tmp();
1906
                TCGv r_tmp2 = new_tmp();
1907
                TCGv r_tmp3 = new_tmp();
1908

    
1909
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1910
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1911
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1912
                tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
1913
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1914
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1915
                gen_store_LO(cpu_T[0], 0);
1916
                gen_store_HI(cpu_T[1], 0);
1917
                dead_tmp(r_tmp1);
1918
                dead_tmp(r_tmp2);
1919
                dead_tmp(r_tmp3);
1920
            }
1921
            gen_set_label(l1);
1922
        }
1923
        opn = "div";
1924
        break;
1925
    case OPC_DIVU:
1926
        {
1927
            int l1 = gen_new_label();
1928

    
1929
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1930
            {
1931
                TCGv r_tmp1 = new_tmp();
1932
                TCGv r_tmp2 = new_tmp();
1933
                TCGv r_tmp3 = new_tmp();
1934

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

    
1964
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1965
            {
1966
                int l2 = gen_new_label();
1967
                int l3 = gen_new_label();
1968

    
1969
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1970
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1971
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1972
                tcg_gen_movi_tl(cpu_T[1], 0);
1973
                tcg_gen_br(l3);
1974
                gen_set_label(l2);
1975
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1976
                tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
1977
                gen_set_label(l3);
1978

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

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

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

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

    
2042
    gen_load_gpr(cpu_T[0], rs);
2043
    gen_load_gpr(cpu_T[1], rt);
2044

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

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

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

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

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

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

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

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

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

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

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

    
2569
    if (sel != 0)
2570
        check_insn(env, ctx, ISA_MIPS32);
2571

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

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

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

    
3186
    if (sel != 0)
3187
        check_insn(env, ctx, ISA_MIPS32);
3188

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

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

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

    
3787
    if (sel != 0)
3788
        check_insn(env, ctx, ISA_MIPS64);
3789

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

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

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

    
4389
    if (sel != 0)
4390
        check_insn(env, ctx, ISA_MIPS64);
4391

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

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

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

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

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

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

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

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

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

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

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

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

    
5429
    btarget = ctx->pc + 4 + offset;
5430

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

    
5480
/* Coprocessor 1 (FPU) */
5481

    
5482
#define FOP(func, fmt) (((fmt) << 21) | (func))
5483

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

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

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

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

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

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

    
5572
    gen_set_label(l1);
5573
    gen_store_gpr(cpu_T[0], rd);
5574
}
5575

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

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

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

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

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

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

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

    
6627
/* ISA extensions (ASEs) */
6628
/* MIPS16 extension to MIPS32 */
6629
/* SmartMIPS extension to MIPS32 */
6630

    
6631
#if defined(TARGET_MIPS64)
6632

    
6633
/* MDMX extension to MIPS64 */
6634

    
6635
#endif
6636

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7247
    num_temps = 0;
7248
    memset(temps, 0, sizeof(temps));
7249

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

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

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

    
7315
        if (env->singlestep_enabled)
7316
            break;
7317

    
7318
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7319
            break;
7320

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

    
7372
    return 0;
7373
}
7374

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

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

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

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

    
7408

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

    
7420
#undef printfpr
7421
}
7422

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

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

    
7441
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7442

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

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

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

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

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

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

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

    
7497
static void mips_tcg_init(void)
7498
{
7499
    static int inited;
7500

    
7501
    /* Initialize various static tables. */
7502
    if (inited)
7503
        return;
7504

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

    
7524
    inited = 1;
7525
}
7526

    
7527
#include "translate_init.c"
7528

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

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

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

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

    
7553
    tlb_flush(env, 1);
7554

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

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

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