Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a569557f

History | View | Annotate | Download (220 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(cpu_T[0], r_tmp1);
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(cpu_T[0], r_tmp1);
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_ext32s_tl(cpu_T[0], cpu_T[0]);
1904
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1905
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1906
            {
1907
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1908
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1909
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1910

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

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

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

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

    
1970
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
1971
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
1972
                {
1973
                    tcg_gen_movi_tl(cpu_T[1], 0);
1974
                    gen_store_LO(cpu_T[0], 0);
1975
                    gen_store_HI(cpu_T[1], 0);
1976
                    tcg_gen_br(l1);
1977
                }
1978
                gen_set_label(l2);
1979
                {
1980
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1981
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1982

    
1983
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1984
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1985
                    gen_store_LO(r_tmp1, 0);
1986
                    gen_store_HI(r_tmp2, 0);
1987
                }
1988
            }
1989
            gen_set_label(l1);
1990
        }
1991
        opn = "ddiv";
1992
        break;
1993
    case OPC_DDIVU:
1994
        {
1995
            int l1 = gen_new_label();
1996

    
1997
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1998
            {
1999
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2000
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2001

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

    
2044
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2045
                            int rd, int rs, int rt)
2046
{
2047
    const char *opn = "mul vr54xx";
2048

    
2049
    gen_load_gpr(cpu_T[0], rs);
2050
    gen_load_gpr(cpu_T[1], rt);
2051

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

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

    
2156
/* Traps */
2157
static void gen_trap (DisasContext *ctx, uint32_t opc,
2158
                      int rs, int rt, int16_t imm)
2159
{
2160
    int cond;
2161

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

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

    
2267
/* Branches (before delay slot) */
2268
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2269
                                int rs, int rt, int32_t offset)
2270
{
2271
    target_ulong btarget = -1;
2272
    int blink = 0;
2273
    int bcond = 0;
2274

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

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

    
2499
    ctx->btarget = btarget;
2500
    if (blink > 0) {
2501
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2502
        gen_store_gpr(cpu_T[0], blink);
2503
    }
2504
}
2505

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

    
2569
/* CP0 (MMU and control) */
2570
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2571
{
2572
    const char *rn = "invalid";
2573
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2574
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2575

    
2576
    if (sel != 0)
2577
        check_insn(env, ctx, ISA_MIPS32);
2578

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

    
3179
die:
3180
#if defined MIPS_DEBUG_DISAS
3181
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3182
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3183
                rn, reg, sel);
3184
    }
3185
#endif
3186
    generate_exception(ctx, EXCP_RI);
3187
}
3188

    
3189
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3190
{
3191
    const char *rn = "invalid";
3192

    
3193
    if (sel != 0)
3194
        check_insn(env, ctx, ISA_MIPS32);
3195

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

    
3778
die:
3779
#if defined MIPS_DEBUG_DISAS
3780
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3781
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3782
                rn, reg, sel);
3783
    }
3784
#endif
3785
    generate_exception(ctx, EXCP_RI);
3786
}
3787

    
3788
#if defined(TARGET_MIPS64)
3789
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3790
{
3791
    const char *rn = "invalid";
3792
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3793

    
3794
    if (sel != 0)
3795
        check_insn(env, ctx, ISA_MIPS64);
3796

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

    
4382
die:
4383
#if defined MIPS_DEBUG_DISAS
4384
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4385
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4386
                rn, reg, sel);
4387
    }
4388
#endif
4389
    generate_exception(ctx, EXCP_RI);
4390
}
4391

    
4392
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4393
{
4394
    const char *rn = "invalid";
4395

    
4396
    if (sel != 0)
4397
        check_insn(env, ctx, ISA_MIPS64);
4398

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

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

    
4979
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4980
                     int u, int sel, int h)
4981
{
4982
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4983

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

    
5133
die:
5134
#if defined MIPS_DEBUG_DISAS
5135
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5136
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5137
                rt, u, sel, h);
5138
    }
5139
#endif
5140
    generate_exception(ctx, EXCP_RI);
5141
}
5142

    
5143
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5144
                     int u, int sel, int h)
5145
{
5146
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5147

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

    
5297
die:
5298
#if defined MIPS_DEBUG_DISAS
5299
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5300
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5301
                rd, u, sel, h);
5302
    }
5303
#endif
5304
    generate_exception(ctx, EXCP_RI);
5305
}
5306

    
5307
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5308
{
5309
    const char *opn = "ldst";
5310

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

    
5426
/* CP1 Branches (before delay slot) */
5427
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5428
                                 int32_t cc, int32_t offset)
5429
{
5430
    target_ulong btarget;
5431
    const char *opn = "cp1 cond branch";
5432

    
5433
    if (cc != 0)
5434
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5435

    
5436
    btarget = ctx->pc + 4 + offset;
5437

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

    
5487
/* Coprocessor 1 (FPU) */
5488

    
5489
#define FOP(func, fmt) (((fmt) << 21) | (func))
5490

    
5491
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5492
{
5493
    const char *opn = "cp1 move";
5494

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

    
5550
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5551
{
5552
    int l1 = gen_new_label();
5553
    uint32_t ccbit;
5554
    TCGCond cond;
5555

    
5556
    if (cc)
5557
        ccbit = 1 << (24 + cc);
5558
    else
5559
        ccbit = 1 << 23;
5560
    if (tf)
5561
        cond = TCG_COND_EQ;
5562
    else
5563
        cond = TCG_COND_NE;
5564

    
5565
    gen_load_gpr(cpu_T[0], rd);
5566
    gen_load_gpr(cpu_T[1], rs);
5567
    {
5568
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5569
        TCGv r_tmp = new_tmp();
5570

    
5571
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5572
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5573
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5574
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5575
        dead_tmp(r_tmp);
5576
    }
5577
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5578

    
5579
    gen_set_label(l1);
5580
    gen_store_gpr(cpu_T[0], rd);
5581
}
5582

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

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

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

    
6413
/* Coprocessor 3 (FPU) */
6414
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6415
                           int fd, int fs, int base, int index)
6416
{
6417
    const char *opn = "extended float load/store";
6418
    int store = 0;
6419

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

    
6482
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6483
                            int fd, int fr, int fs, int ft)
6484
{
6485
    const char *opn = "flt3_arith";
6486

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

    
6634
/* ISA extensions (ASEs) */
6635
/* MIPS16 extension to MIPS32 */
6636
/* SmartMIPS extension to MIPS32 */
6637

    
6638
#if defined(TARGET_MIPS64)
6639

    
6640
/* MDMX extension to MIPS64 */
6641

    
6642
#endif
6643

    
6644
static void decode_opc (CPUState *env, DisasContext *ctx)
6645
{
6646
    int32_t offset;
6647
    int rs, rt, rd, sa;
6648
    uint32_t op, op1, op2;
6649
    int16_t imm;
6650

    
6651
    /* make sure instructions are on a word boundary */
6652
    if (ctx->pc & 0x3) {
6653
        env->CP0_BadVAddr = ctx->pc;
6654
        generate_exception(ctx, EXCP_AdEL);
6655
        return;
6656
    }
6657

    
6658
    /* Handle blikely not taken case */
6659
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6660
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6661
        int l1 = gen_new_label();
6662

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

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

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

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

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

    
7116
    /* COP2.  */
7117
    case OPC_LWC2:
7118
    case OPC_LDC2:
7119
    case OPC_SWC2:
7120
    case OPC_SDC2:
7121
    case OPC_CP2:
7122
        /* COP2: Not implemented. */
7123
        generate_exception_err(ctx, EXCP_CpU, 2);
7124
        break;
7125

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

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

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

    
7242
static always_inline int
7243
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7244
                                int search_pc)
7245
{
7246
    DisasContext ctx;
7247
    target_ulong pc_start;
7248
    uint16_t *gen_opc_end;
7249
    int j, lj = -1;
7250

    
7251
    if (search_pc && loglevel)
7252
        fprintf (logfile, "search pc %d\n", search_pc);
7253

    
7254
    num_temps = 0;
7255
    memset(temps, 0, sizeof(temps));
7256

    
7257
    num_temps = 0;
7258
    memset(temps, 0, sizeof(temps));
7259

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

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

    
7322
        if (env->singlestep_enabled)
7323
            break;
7324

    
7325
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7326
            break;
7327

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

    
7379
    return 0;
7380
}
7381

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

    
7387
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7388
{
7389
    return gen_intermediate_code_internal(env, tb, 1);
7390
}
7391

    
7392
void fpu_dump_state(CPUState *env, FILE *f,
7393
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7394
                    int flags)
7395
{
7396
    int i;
7397
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7398

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

    
7415

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

    
7427
#undef printfpr
7428
}
7429

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

    
7444
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7445
/* Debug help: The architecture requires 32bit code to maintain proper
7446
   sign-extened values on 64bit machines.  */
7447

    
7448
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7449

    
7450
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7451
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7452
                     int flags)
7453
{
7454
    int i;
7455

    
7456
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7457
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7458
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7459
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7460
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7461
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7462
    if (!SIGN_EXT_P(env->btarget))
7463
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7464

    
7465
    for (i = 0; i < 32; i++) {
7466
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7467
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7468
    }
7469

    
7470
    if (!SIGN_EXT_P(env->CP0_EPC))
7471
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7472
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7473
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7474
}
7475
#endif
7476

    
7477
void cpu_dump_state (CPUState *env, FILE *f,
7478
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7479
                     int flags)
7480
{
7481
    int i;
7482

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

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

    
7504
static void mips_tcg_init(void)
7505
{
7506
    static int inited;
7507

    
7508
    /* Initialize various static tables. */
7509
    if (inited)
7510
        return;
7511

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

    
7531
    inited = 1;
7532
}
7533

    
7534
#include "translate_init.c"
7535

    
7536
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7537
{
7538
    CPUMIPSState *env;
7539
    const mips_def_t *def;
7540

    
7541
    def = cpu_mips_find_by_name(cpu_model);
7542
    if (!def)
7543
        return NULL;
7544
    env = qemu_mallocz(sizeof(CPUMIPSState));
7545
    if (!env)
7546
        return NULL;
7547
    env->cpu_model = def;
7548

    
7549
    cpu_exec_init(env);
7550
    env->cpu_model_str = cpu_model;
7551
    mips_tcg_init();
7552
    cpu_reset(env);
7553
    return env;
7554
}
7555

    
7556
void cpu_reset (CPUMIPSState *env)
7557
{
7558
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7559

    
7560
    tlb_flush(env, 1);
7561

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

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

    
7602
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7603
                unsigned long searched_pc, int pc_pos, void *puc)
7604
{
7605
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7606
    env->hflags &= ~MIPS_HFLAG_BMASK;
7607
    env->hflags |= gen_opc_hflags[pc_pos];
7608
}