Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 95af5ce5

History | View | Annotate | Download (212.5 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, 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 shadow registers. */
535
static inline void gen_load_srsgpr (TCGv t, int reg)
536
{
537
    if (reg == 0)
538
        tcg_gen_movi_tl(t, 0);
539
    else {
540
        TCGv r_tmp = new_tmp();
541

    
542
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
543
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
544
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
545
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
546
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
547

    
548
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
549
        dead_tmp(r_tmp);
550
    }
551
}
552

    
553
static inline void gen_store_srsgpr (TCGv t, int reg)
554
{
555
    if (reg != 0) {
556
        TCGv r_tmp = new_tmp();
557

    
558
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
559
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
560
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
561
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
562
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
563

    
564
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
565
        dead_tmp(r_tmp);
566
    }
567
}
568

    
569
/* Floating point register moves. */
570
#define FGEN32(func, NAME)                       \
571
static GenOpFunc *NAME ## _table [32] = {        \
572
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
573
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
574
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
575
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
576
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
577
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
578
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
579
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
580
};                                               \
581
static always_inline void func(int n)            \
582
{                                                \
583
    NAME ## _table[n]();                         \
584
}
585

    
586
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
587
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
588

    
589
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
590
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
591

    
592
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
593
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
594

    
595
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
596
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
597

    
598
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
599
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
600

    
601
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
602
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
603

    
604
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
605
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
606

    
607
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
608
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
609

    
610
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
611
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
612

    
613
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
614
do {                                                                          \
615
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
616
} while (0)
617

    
618
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
619
do {                                                                          \
620
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
621
} while (0)
622

    
623
#define FOP_CONDS(type, fmt)                                            \
624
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
625
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
626
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
627
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
628
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
629
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
630
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
631
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
632
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
633
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
634
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
635
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
636
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
637
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
638
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
639
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
640
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
641
};                                                                      \
642
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
643
{                                                                       \
644
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
645
}
646

    
647
FOP_CONDS(, d)
648
FOP_CONDS(abs, d)
649
FOP_CONDS(, s)
650
FOP_CONDS(abs, s)
651
FOP_CONDS(, ps)
652
FOP_CONDS(abs, ps)
653

    
654
/* Tests */
655
#define OP_COND(name, cond)                                   \
656
void glue(gen_op_, name) (void)                               \
657
{                                                             \
658
    int l1 = gen_new_label();                                 \
659
    int l2 = gen_new_label();                                 \
660
                                                              \
661
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
662
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
663
    tcg_gen_br(l2);                                           \
664
    gen_set_label(l1);                                        \
665
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
666
    gen_set_label(l2);                                        \
667
}
668
OP_COND(eq, TCG_COND_EQ);
669
OP_COND(ne, TCG_COND_NE);
670
OP_COND(ge, TCG_COND_GE);
671
OP_COND(geu, TCG_COND_GEU);
672
OP_COND(lt, TCG_COND_LT);
673
OP_COND(ltu, TCG_COND_LTU);
674
#undef OP_COND
675

    
676
#define OP_CONDI(name, cond)                                  \
677
void glue(gen_op_, name) (target_ulong val)                   \
678
{                                                             \
679
    int l1 = gen_new_label();                                 \
680
    int l2 = gen_new_label();                                 \
681
                                                              \
682
    tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(val), l1); \
683
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
684
    tcg_gen_br(l2);                                           \
685
    gen_set_label(l1);                                        \
686
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
687
    gen_set_label(l2);                                        \
688
}
689
OP_CONDI(lti, TCG_COND_LT);
690
OP_CONDI(ltiu, TCG_COND_LTU);
691
#undef OP_CONDI
692

    
693
#define OP_CONDZ(name, cond)                                  \
694
void glue(gen_op_, name) (void)                               \
695
{                                                             \
696
    int l1 = gen_new_label();                                 \
697
    int l2 = gen_new_label();                                 \
698
                                                              \
699
    tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(0), l1);   \
700
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
701
    tcg_gen_br(l2);                                           \
702
    gen_set_label(l1);                                        \
703
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
704
    gen_set_label(l2);                                        \
705
}
706
OP_CONDZ(gez, TCG_COND_GE);
707
OP_CONDZ(gtz, TCG_COND_GT);
708
OP_CONDZ(lez, TCG_COND_LE);
709
OP_CONDZ(ltz, TCG_COND_LT);
710
#undef OP_CONDZ
711

    
712
static inline void gen_save_pc(target_ulong pc)
713
{
714
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
715
    TCGv r_tc_off = new_tmp();
716
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
717
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
718

    
719
    tcg_gen_movi_tl(r_tmp, pc);
720
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
721
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
722
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
723
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
724
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
725
    dead_tmp(r_tc_off);
726
}
727

    
728
static inline void gen_breg_pc(void)
729
{
730
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
731
    TCGv r_tc_off = new_tmp();
732
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
733
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
734

    
735
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
736
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
737
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
738
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
739
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
740
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
741
    dead_tmp(r_tc_off);
742
}
743

    
744
static inline void gen_save_btarget(target_ulong btarget)
745
{
746
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
747

    
748
    tcg_gen_movi_tl(r_tmp, btarget);
749
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
750
}
751

    
752
static always_inline void gen_save_breg_target(int reg)
753
{
754
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
755

    
756
    gen_load_gpr(r_tmp, reg);
757
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
758
}
759

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

    
787
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
788
{
789
    ctx->saved_hflags = ctx->hflags;
790
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
791
    case MIPS_HFLAG_BR:
792
        break;
793
    case MIPS_HFLAG_BC:
794
    case MIPS_HFLAG_BL:
795
    case MIPS_HFLAG_B:
796
        ctx->btarget = env->btarget;
797
        break;
798
    }
799
}
800

    
801
static always_inline void
802
generate_exception_err (DisasContext *ctx, int excp, int err)
803
{
804
    save_cpu_state(ctx, 1);
805
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
806
    tcg_gen_helper_0_0(do_interrupt_restart);
807
    tcg_gen_exit_tb(0);
808
}
809

    
810
static always_inline void
811
generate_exception (DisasContext *ctx, int excp)
812
{
813
    save_cpu_state(ctx, 1);
814
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
815
    tcg_gen_helper_0_0(do_interrupt_restart);
816
    tcg_gen_exit_tb(0);
817
}
818

    
819
/* Addresses computation */
820
static inline void gen_op_addr_add (void)
821
{
822
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
823

    
824
#if defined(TARGET_MIPS64)
825
    /* For compatibility with 32-bit code, data reference in user mode
826
       with Status_UX = 0 should be casted to 32-bit and sign extended.
827
       See the MIPS64 PRA manual, section 4.10. */
828
    {
829
        TCGv r_tmp = new_tmp();
830
        int l1 = gen_new_label();
831

    
832
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
833
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
834
        tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(MIPS_HFLAG_UM), l1);
835
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
836
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
837
        tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(0), l1);
838
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
839
        gen_set_label(l1);
840
        dead_tmp(r_tmp);
841
    }
842
#endif
843
}
844

    
845
static always_inline void check_cp0_enabled(DisasContext *ctx)
846
{
847
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
848
        generate_exception_err(ctx, EXCP_CpU, 1);
849
}
850

    
851
static always_inline void check_cp1_enabled(DisasContext *ctx)
852
{
853
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
854
        generate_exception_err(ctx, EXCP_CpU, 1);
855
}
856

    
857
/* Verify that the processor is running with COP1X instructions enabled.
858
   This is associated with the nabla symbol in the MIPS32 and MIPS64
859
   opcode tables.  */
860

    
861
static always_inline void check_cop1x(DisasContext *ctx)
862
{
863
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
864
        generate_exception(ctx, EXCP_RI);
865
}
866

    
867
/* Verify that the processor is running with 64-bit floating-point
868
   operations enabled.  */
869

    
870
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
871
{
872
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
873
        generate_exception(ctx, EXCP_RI);
874
}
875

    
876
/*
877
 * Verify if floating point register is valid; an operation is not defined
878
 * if bit 0 of any register specification is set and the FR bit in the
879
 * Status register equals zero, since the register numbers specify an
880
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
881
 * in the Status register equals one, both even and odd register numbers
882
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
883
 *
884
 * Multiple 64 bit wide registers can be checked by calling
885
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
886
 */
887
void check_cp1_registers(DisasContext *ctx, int regs)
888
{
889
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
890
        generate_exception(ctx, EXCP_RI);
891
}
892

    
893
/* This code generates a "reserved instruction" exception if the
894
   CPU does not support the instruction set corresponding to flags. */
895
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
896
{
897
    if (unlikely(!(env->insn_flags & flags)))
898
        generate_exception(ctx, EXCP_RI);
899
}
900

    
901
/* This code generates a "reserved instruction" exception if 64-bit
902
   instructions are not enabled. */
903
static always_inline void check_mips_64(DisasContext *ctx)
904
{
905
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
906
        generate_exception(ctx, EXCP_RI);
907
}
908

    
909
/* load/store instructions. */
910
#if defined(CONFIG_USER_ONLY)
911
#define op_ldst(name)        gen_op_##name##_raw()
912
#define OP_LD_TABLE(width)
913
#define OP_ST_TABLE(width)
914
#else
915
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
916
#define OP_LD_TABLE(width)                                                    \
917
static GenOpFunc *gen_op_l##width[] = {                                       \
918
    &gen_op_l##width##_kernel,                                                \
919
    &gen_op_l##width##_super,                                                 \
920
    &gen_op_l##width##_user,                                                  \
921
}
922
#define OP_ST_TABLE(width)                                                    \
923
static GenOpFunc *gen_op_s##width[] = {                                       \
924
    &gen_op_s##width##_kernel,                                                \
925
    &gen_op_s##width##_super,                                                 \
926
    &gen_op_s##width##_user,                                                  \
927
}
928
#endif
929

    
930
#if defined(TARGET_MIPS64)
931
OP_LD_TABLE(dl);
932
OP_LD_TABLE(dr);
933
OP_ST_TABLE(dl);
934
OP_ST_TABLE(dr);
935
#endif
936
OP_LD_TABLE(wl);
937
OP_LD_TABLE(wr);
938
OP_ST_TABLE(wl);
939
OP_ST_TABLE(wr);
940
OP_LD_TABLE(wc1);
941
OP_ST_TABLE(wc1);
942
OP_LD_TABLE(dc1);
943
OP_ST_TABLE(dc1);
944
OP_LD_TABLE(uxc1);
945
OP_ST_TABLE(uxc1);
946

    
947
#define OP_LD(insn,fname)                                        \
948
void inline op_ldst_##insn(DisasContext *ctx)                    \
949
{                                                                \
950
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
951
}
952
OP_LD(lb,ld8s);
953
OP_LD(lbu,ld8u);
954
OP_LD(lh,ld16s);
955
OP_LD(lhu,ld16u);
956
OP_LD(lw,ld32s);
957
#if defined(TARGET_MIPS64)
958
OP_LD(lwu,ld32u);
959
OP_LD(ld,ld64);
960
#endif
961
#undef OP_LD
962

    
963
#define OP_ST(insn,fname)                                        \
964
void inline op_ldst_##insn(DisasContext *ctx)                    \
965
{                                                                \
966
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
967
}
968
OP_ST(sb,st8);
969
OP_ST(sh,st16);
970
OP_ST(sw,st32);
971
#if defined(TARGET_MIPS64)
972
OP_ST(sd,st64);
973
#endif
974
#undef OP_ST
975

    
976
#define OP_LD_ATOMIC(insn,fname)                                        \
977
void inline op_ldst_##insn(DisasContext *ctx)                           \
978
{                                                                       \
979
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
980
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
981
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
982
}
983
OP_LD_ATOMIC(ll,ld32s);
984
#if defined(TARGET_MIPS64)
985
OP_LD_ATOMIC(lld,ld64);
986
#endif
987
#undef OP_LD_ATOMIC
988

    
989
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
990
void inline op_ldst_##insn(DisasContext *ctx)                           \
991
{                                                                       \
992
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
993
    int l1 = gen_new_label();                                           \
994
    int l2 = gen_new_label();                                           \
995
    int l3 = gen_new_label();                                           \
996
                                                                        \
997
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
998
    tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1);         \
999
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1000
    generate_exception(ctx, EXCP_AdES);                             \
1001
    gen_set_label(l1);                                                  \
1002
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1003
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1004
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1005
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1006
    tcg_gen_br(l3);                                                     \
1007
    gen_set_label(l2);                                                  \
1008
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1009
    gen_set_label(l3);                                                  \
1010
}
1011
OP_ST_ATOMIC(sc,st32,0x3);
1012
#if defined(TARGET_MIPS64)
1013
OP_ST_ATOMIC(scd,st64,0x7);
1014
#endif
1015
#undef OP_ST_ATOMIC
1016

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

    
1022
void inline op_ldst_ldc1(DisasContext *ctx)
1023
{
1024
    op_ldst(ldc1);
1025
}
1026

    
1027
void inline op_ldst_swc1(DisasContext *ctx)
1028
{
1029
    op_ldst(swc1);
1030
}
1031

    
1032
void inline op_ldst_sdc1(DisasContext *ctx)
1033
{
1034
    op_ldst(sdc1);
1035
}
1036

    
1037
/* Load and store */
1038
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1039
                      int base, int16_t offset)
1040
{
1041
    const char *opn = "ldst";
1042

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

    
1188
/* Load and store */
1189
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1190
                      int base, int16_t offset)
1191
{
1192
    const char *opn = "flt_ldst";
1193

    
1194
    if (base == 0) {
1195
        tcg_gen_movi_tl(cpu_T[0], offset);
1196
    } else if (offset == 0) {
1197
        gen_load_gpr(cpu_T[0], base);
1198
    } else {
1199
        gen_load_gpr(cpu_T[0], base);
1200
        tcg_gen_movi_tl(cpu_T[1], offset);
1201
        gen_op_addr_add();
1202
    }
1203
    /* Don't do NOP if destination is zero: we must perform the actual
1204
       memory access. */
1205
    switch (opc) {
1206
    case OPC_LWC1:
1207
        op_ldst_lwc1(ctx);
1208
        GEN_STORE_FTN_FREG(ft, WT0);
1209
        opn = "lwc1";
1210
        break;
1211
    case OPC_SWC1:
1212
        GEN_LOAD_FREG_FTN(WT0, ft);
1213
        op_ldst_swc1(ctx);
1214
        opn = "swc1";
1215
        break;
1216
    case OPC_LDC1:
1217
        op_ldst_ldc1(ctx);
1218
        GEN_STORE_FTN_FREG(ft, DT0);
1219
        opn = "ldc1";
1220
        break;
1221
    case OPC_SDC1:
1222
        GEN_LOAD_FREG_FTN(DT0, ft);
1223
        op_ldst_sdc1(ctx);
1224
        opn = "sdc1";
1225
        break;
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        return;
1230
    }
1231
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1232
}
1233

    
1234
/* Arithmetic with immediate operand */
1235
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1236
                           int rt, int rs, int16_t imm)
1237
{
1238
    target_ulong uimm;
1239
    const char *opn = "imm arith";
1240

    
1241
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1242
        /* If no destination, treat it as a NOP.
1243
           For addi, we must generate the overflow exception when needed. */
1244
        MIPS_DEBUG("NOP");
1245
        return;
1246
    }
1247
    uimm = (uint16_t)imm;
1248
    switch (opc) {
1249
    case OPC_ADDI:
1250
    case OPC_ADDIU:
1251
#if defined(TARGET_MIPS64)
1252
    case OPC_DADDI:
1253
    case OPC_DADDIU:
1254
#endif
1255
    case OPC_SLTI:
1256
    case OPC_SLTIU:
1257
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1258
        tcg_gen_movi_tl(cpu_T[1], uimm);
1259
        /* Fall through. */
1260
    case OPC_ANDI:
1261
    case OPC_ORI:
1262
    case OPC_XORI:
1263
        gen_load_gpr(cpu_T[0], rs);
1264
        break;
1265
    case OPC_LUI:
1266
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1267
        break;
1268
    case OPC_SLL:
1269
    case OPC_SRA:
1270
    case OPC_SRL:
1271
#if defined(TARGET_MIPS64)
1272
    case OPC_DSLL:
1273
    case OPC_DSRA:
1274
    case OPC_DSRL:
1275
    case OPC_DSLL32:
1276
    case OPC_DSRA32:
1277
    case OPC_DSRL32:
1278
#endif
1279
        uimm &= 0x1f;
1280
        gen_load_gpr(cpu_T[0], rs);
1281
        break;
1282
    }
1283
    switch (opc) {
1284
    case OPC_ADDI:
1285
        {
1286
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1287
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1288
            int l1 = gen_new_label();
1289

    
1290
            save_cpu_state(ctx, 1);
1291
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1292
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1293

    
1294
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1295
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1296
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1297
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1298
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1299
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1300
            /* operands of same sign, result different sign */
1301
            generate_exception(ctx, EXCP_OVERFLOW);
1302
            gen_set_label(l1);
1303

    
1304
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1305
        }
1306
        opn = "addi";
1307
        break;
1308
    case OPC_ADDIU:
1309
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1310
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1311
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1312
        opn = "addiu";
1313
        break;
1314
#if defined(TARGET_MIPS64)
1315
    case OPC_DADDI:
1316
        {
1317
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1318
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1319
            int l1 = gen_new_label();
1320

    
1321
            save_cpu_state(ctx, 1);
1322
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1323
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1324

    
1325
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1326
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1327
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1328
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1329
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1330
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1331
            /* operands of same sign, result different sign */
1332
            generate_exception(ctx, EXCP_OVERFLOW);
1333
            gen_set_label(l1);
1334
        }
1335
        opn = "daddi";
1336
        break;
1337
    case OPC_DADDIU:
1338
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1339
        opn = "daddiu";
1340
        break;
1341
#endif
1342
    case OPC_SLTI:
1343
        gen_op_lti(uimm);
1344
        opn = "slti";
1345
        break;
1346
    case OPC_SLTIU:
1347
        gen_op_ltiu(uimm);
1348
        opn = "sltiu";
1349
        break;
1350
    case OPC_ANDI:
1351
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1352
        opn = "andi";
1353
        break;
1354
    case OPC_ORI:
1355
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1356
        opn = "ori";
1357
        break;
1358
    case OPC_XORI:
1359
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1360
        opn = "xori";
1361
        break;
1362
    case OPC_LUI:
1363
        opn = "lui";
1364
        break;
1365
    case OPC_SLL:
1366
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1367
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1368
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1369
        opn = "sll";
1370
        break;
1371
    case OPC_SRA:
1372
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1373
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1374
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1375
        opn = "sra";
1376
        break;
1377
    case OPC_SRL:
1378
        switch ((ctx->opcode >> 21) & 0x1f) {
1379
        case 0:
1380
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1381
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1382
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1383
            opn = "srl";
1384
            break;
1385
        case 1:
1386
            /* rotr is decoded as srl on non-R2 CPUs */
1387
            if (env->insn_flags & ISA_MIPS32R2) {
1388
                if (uimm != 0) {
1389
                    TCGv r_tmp1 = new_tmp();
1390
                    TCGv r_tmp2 = new_tmp();
1391

    
1392
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1393
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1394
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1395
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1396
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1397
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1398
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1399
                    dead_tmp(r_tmp1);
1400
                    dead_tmp(r_tmp2);
1401
                }
1402
                opn = "rotr";
1403
            } else {
1404
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1405
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1406
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1407
                opn = "srl";
1408
            }
1409
            break;
1410
        default:
1411
            MIPS_INVAL("invalid srl flag");
1412
            generate_exception(ctx, EXCP_RI);
1413
            break;
1414
        }
1415
        break;
1416
#if defined(TARGET_MIPS64)
1417
    case OPC_DSLL:
1418
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1419
        opn = "dsll";
1420
        break;
1421
    case OPC_DSRA:
1422
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1423
        opn = "dsra";
1424
        break;
1425
    case OPC_DSRL:
1426
        switch ((ctx->opcode >> 21) & 0x1f) {
1427
        case 0:
1428
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1429
            opn = "dsrl";
1430
            break;
1431
        case 1:
1432
            /* drotr is decoded as dsrl on non-R2 CPUs */
1433
            if (env->insn_flags & ISA_MIPS32R2) {
1434
                if (uimm != 0) {
1435
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1436

    
1437
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1438
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1439
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1440
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1441
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1442
                }
1443
                opn = "drotr";
1444
            } else {
1445
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1446
                opn = "dsrl";
1447
            }
1448
            break;
1449
        default:
1450
            MIPS_INVAL("invalid dsrl flag");
1451
            generate_exception(ctx, EXCP_RI);
1452
            break;
1453
        }
1454
        break;
1455
    case OPC_DSLL32:
1456
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1457
        opn = "dsll32";
1458
        break;
1459
    case OPC_DSRA32:
1460
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1461
        opn = "dsra32";
1462
        break;
1463
    case OPC_DSRL32:
1464
        switch ((ctx->opcode >> 21) & 0x1f) {
1465
        case 0:
1466
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1467
            opn = "dsrl32";
1468
            break;
1469
        case 1:
1470
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1471
            if (env->insn_flags & ISA_MIPS32R2) {
1472
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1473
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1474

    
1475
                tcg_gen_movi_tl(r_tmp1, 0x40);
1476
                tcg_gen_movi_tl(r_tmp2, 32);
1477
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1478
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1479
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1480
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1481
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1482
                opn = "drotr32";
1483
            } else {
1484
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1485
                opn = "dsrl32";
1486
            }
1487
            break;
1488
        default:
1489
            MIPS_INVAL("invalid dsrl32 flag");
1490
            generate_exception(ctx, EXCP_RI);
1491
            break;
1492
        }
1493
        break;
1494
#endif
1495
    default:
1496
        MIPS_INVAL(opn);
1497
        generate_exception(ctx, EXCP_RI);
1498
        return;
1499
    }
1500
    gen_store_gpr(cpu_T[0], rt);
1501
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1502
}
1503

    
1504
/* Arithmetic */
1505
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1506
                       int rd, int rs, int rt)
1507
{
1508
    const char *opn = "arith";
1509

    
1510
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1511
       && opc != OPC_DADD && opc != OPC_DSUB) {
1512
        /* If no destination, treat it as a NOP.
1513
           For add & sub, we must generate the overflow exception when needed. */
1514
        MIPS_DEBUG("NOP");
1515
        return;
1516
    }
1517
    gen_load_gpr(cpu_T[0], rs);
1518
    /* Specialcase the conventional move operation. */
1519
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1520
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1521
        gen_store_gpr(cpu_T[0], rd);
1522
        return;
1523
    }
1524
    gen_load_gpr(cpu_T[1], rt);
1525
    switch (opc) {
1526
    case OPC_ADD:
1527
        {
1528
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1529
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1530
            int l1 = gen_new_label();
1531

    
1532
            save_cpu_state(ctx, 1);
1533
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1534
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1535
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1536

    
1537
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1538
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1539
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1540
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1541
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1542
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1543
            /* operands of same sign, result different sign */
1544
            generate_exception(ctx, EXCP_OVERFLOW);
1545
            gen_set_label(l1);
1546

    
1547
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1548
        }
1549
        opn = "add";
1550
        break;
1551
    case OPC_ADDU:
1552
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1553
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1554
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1555
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1556
        opn = "addu";
1557
        break;
1558
    case OPC_SUB:
1559
        {
1560
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1561
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1562
            int l1 = gen_new_label();
1563

    
1564
            save_cpu_state(ctx, 1);
1565
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1566
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1567
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1568

    
1569
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1570
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1571
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1572
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1573
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1574
            /* operands of different sign, first operand and result different sign */
1575
            generate_exception(ctx, EXCP_OVERFLOW);
1576
            gen_set_label(l1);
1577

    
1578
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1579
        }
1580
        opn = "sub";
1581
        break;
1582
    case OPC_SUBU:
1583
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1584
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1585
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1586
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1587
        opn = "subu";
1588
        break;
1589
#if defined(TARGET_MIPS64)
1590
    case OPC_DADD:
1591
        {
1592
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1593
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1594
            int l1 = gen_new_label();
1595

    
1596
            save_cpu_state(ctx, 1);
1597
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1598
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1599

    
1600
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1601
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1602
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1603
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1604
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1605
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1606
            /* operands of same sign, result different sign */
1607
            generate_exception(ctx, EXCP_OVERFLOW);
1608
            gen_set_label(l1);
1609
        }
1610
        opn = "dadd";
1611
        break;
1612
    case OPC_DADDU:
1613
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1614
        opn = "daddu";
1615
        break;
1616
    case OPC_DSUB:
1617
        {
1618
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1619
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1620
            int l1 = gen_new_label();
1621

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

    
1626
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1627
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1628
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1629
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1630
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1631
            /* operands of different sign, first operand and result different sign */
1632
            generate_exception(ctx, EXCP_OVERFLOW);
1633
            gen_set_label(l1);
1634
        }
1635
        opn = "dsub";
1636
        break;
1637
    case OPC_DSUBU:
1638
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1639
        opn = "dsubu";
1640
        break;
1641
#endif
1642
    case OPC_SLT:
1643
        gen_op_lt();
1644
        opn = "slt";
1645
        break;
1646
    case OPC_SLTU:
1647
        gen_op_ltu();
1648
        opn = "sltu";
1649
        break;
1650
    case OPC_AND:
1651
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1652
        opn = "and";
1653
        break;
1654
    case OPC_NOR:
1655
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1656
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1657
        opn = "nor";
1658
        break;
1659
    case OPC_OR:
1660
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1661
        opn = "or";
1662
        break;
1663
    case OPC_XOR:
1664
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1665
        opn = "xor";
1666
        break;
1667
    case OPC_MUL:
1668
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1669
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1670
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1671
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1672
        opn = "mul";
1673
        break;
1674
    case OPC_MOVN:
1675
        {
1676
            int l1 = gen_new_label();
1677

    
1678
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1679
            gen_store_gpr(cpu_T[0], rd);
1680
            gen_set_label(l1);
1681
        }
1682
        opn = "movn";
1683
        goto print;
1684
    case OPC_MOVZ:
1685
        {
1686
            int l1 = gen_new_label();
1687

    
1688
            tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(0), l1);
1689
            gen_store_gpr(cpu_T[0], rd);
1690
            gen_set_label(l1);
1691
        }
1692
        opn = "movz";
1693
        goto print;
1694
    case OPC_SLLV:
1695
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1696
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1697
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1698
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1699
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1700
        opn = "sllv";
1701
        break;
1702
    case OPC_SRAV:
1703
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1704
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1705
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1706
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1707
        opn = "srav";
1708
        break;
1709
    case OPC_SRLV:
1710
        switch ((ctx->opcode >> 6) & 0x1f) {
1711
        case 0:
1712
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1713
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1714
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1715
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1716
            opn = "srlv";
1717
            break;
1718
        case 1:
1719
            /* rotrv is decoded as srlv on non-R2 CPUs */
1720
            if (env->insn_flags & ISA_MIPS32R2) {
1721
                int l1 = gen_new_label();
1722
                int l2 = gen_new_label();
1723

    
1724
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1725
                tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
1726
                {
1727
                    TCGv r_tmp1 = new_tmp();
1728
                    TCGv r_tmp2 = new_tmp();
1729
                    TCGv r_tmp3 = new_tmp();
1730

    
1731
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1732
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1733
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1734
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1735
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1736
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1737
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1738
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1739
                    dead_tmp(r_tmp1);
1740
                    dead_tmp(r_tmp2);
1741
                    dead_tmp(r_tmp3);
1742
                    tcg_gen_br(l2);
1743
                }
1744
                gen_set_label(l1);
1745
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1746
                gen_set_label(l2);
1747
                opn = "rotrv";
1748
            } else {
1749
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1750
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1751
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1752
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1753
                opn = "srlv";
1754
            }
1755
            break;
1756
        default:
1757
            MIPS_INVAL("invalid srlv flag");
1758
            generate_exception(ctx, EXCP_RI);
1759
            break;
1760
        }
1761
        break;
1762
#if defined(TARGET_MIPS64)
1763
    case OPC_DSLLV:
1764
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1765
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1766
        opn = "dsllv";
1767
        break;
1768
    case OPC_DSRAV:
1769
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1770
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1771
        opn = "dsrav";
1772
        break;
1773
    case OPC_DSRLV:
1774
        switch ((ctx->opcode >> 6) & 0x1f) {
1775
        case 0:
1776
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1777
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1778
            opn = "dsrlv";
1779
            break;
1780
        case 1:
1781
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1782
            if (env->insn_flags & ISA_MIPS32R2) {
1783
                int l1 = gen_new_label();
1784
                int l2 = gen_new_label();
1785

    
1786
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1787
                tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
1788
                {
1789
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1790

    
1791
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1792
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1793
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1794
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1795
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1796
                    tcg_gen_br(l2);
1797
                }
1798
                gen_set_label(l1);
1799
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1800
                gen_set_label(l2);
1801
                opn = "drotrv";
1802
            } else {
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
            }
1807
            break;
1808
        default:
1809
            MIPS_INVAL("invalid dsrlv flag");
1810
            generate_exception(ctx, EXCP_RI);
1811
            break;
1812
        }
1813
        break;
1814
#endif
1815
    default:
1816
        MIPS_INVAL(opn);
1817
        generate_exception(ctx, EXCP_RI);
1818
        return;
1819
    }
1820
    gen_store_gpr(cpu_T[0], rd);
1821
 print:
1822
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1823
}
1824

    
1825
/* Arithmetic on HI/LO registers */
1826
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1827
{
1828
    const char *opn = "hilo";
1829

    
1830
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1831
        /* Treat as NOP. */
1832
        MIPS_DEBUG("NOP");
1833
        return;
1834
    }
1835
    switch (opc) {
1836
    case OPC_MFHI:
1837
        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
1838
        gen_store_gpr(cpu_T[0], reg);
1839
        opn = "mfhi";
1840
        break;
1841
    case OPC_MFLO:
1842
        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
1843
        gen_store_gpr(cpu_T[0], reg);
1844
        opn = "mflo";
1845
        break;
1846
    case OPC_MTHI:
1847
        gen_load_gpr(cpu_T[0], reg);
1848
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
1849
        opn = "mthi";
1850
        break;
1851
    case OPC_MTLO:
1852
        gen_load_gpr(cpu_T[0], reg);
1853
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
1854
        opn = "mtlo";
1855
        break;
1856
    default:
1857
        MIPS_INVAL(opn);
1858
        generate_exception(ctx, EXCP_RI);
1859
        return;
1860
    }
1861
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1862
}
1863

    
1864
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1865
                        int rs, int rt)
1866
{
1867
    const char *opn = "mul/div";
1868

    
1869
    gen_load_gpr(cpu_T[0], rs);
1870
    gen_load_gpr(cpu_T[1], rt);
1871
    switch (opc) {
1872
    case OPC_DIV:
1873
        {
1874
            int l1 = gen_new_label();
1875

    
1876
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1877
            {
1878
                TCGv r_tmp1 = new_tmp();
1879
                TCGv r_tmp2 = new_tmp();
1880
                TCGv r_tmp3 = new_tmp();
1881
                TCGv r_tc_off = new_tmp();
1882
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1883
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1884

    
1885
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1886
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1887
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1888
                tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
1889
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1890
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1891
                dead_tmp(r_tmp1);
1892
                dead_tmp(r_tmp2);
1893
                dead_tmp(r_tmp3);
1894
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1895
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1896
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1897
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1898
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1899
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1900
                dead_tmp(r_tc_off);
1901
            }
1902
            gen_set_label(l1);
1903
        }
1904
        opn = "div";
1905
        break;
1906
    case OPC_DIVU:
1907
        {
1908
            int l1 = gen_new_label();
1909

    
1910
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1911
            {
1912
                TCGv r_tmp1 = new_tmp();
1913
                TCGv r_tmp2 = new_tmp();
1914
                TCGv r_tmp3 = new_tmp();
1915
                TCGv r_tc_off = new_tmp();
1916
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1917
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1918

    
1919
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1920
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1921
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1922
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1923
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1924
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1925
                dead_tmp(r_tmp1);
1926
                dead_tmp(r_tmp2);
1927
                dead_tmp(r_tmp3);
1928
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1929
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1930
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1931
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1932
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1933
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1934
                dead_tmp(r_tc_off);
1935
            }
1936
            gen_set_label(l1);
1937
        }
1938
        opn = "divu";
1939
        break;
1940
    case OPC_MULT:
1941
        gen_op_mult();
1942
        opn = "mult";
1943
        break;
1944
    case OPC_MULTU:
1945
        gen_op_multu();
1946
        opn = "multu";
1947
        break;
1948
#if defined(TARGET_MIPS64)
1949
    case OPC_DDIV:
1950
        {
1951
            int l1 = gen_new_label();
1952

    
1953
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1954
            {
1955
                TCGv r_tc_off = new_tmp();
1956
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1957
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1958
                int l2 = gen_new_label();
1959
                int l3 = gen_new_label();
1960

    
1961
                tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], tcg_const_tl(1ULL << 63), l2);
1962
                tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(-1ULL), l2);
1963
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1964
                tcg_gen_movi_tl(cpu_T[1], 0);
1965
                tcg_gen_br(l3);
1966
                gen_set_label(l2);
1967
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1968
                tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
1969
                gen_set_label(l3);
1970

    
1971
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1972
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1973
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1974
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1975
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1976
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1977
                dead_tmp(r_tc_off);
1978
            }
1979
            gen_set_label(l1);
1980
        }
1981
        opn = "ddiv";
1982
        break;
1983
    case OPC_DDIVU:
1984
        {
1985
            int l1 = gen_new_label();
1986

    
1987
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1988
            {
1989
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1990
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1991
                TCGv r_tc_off = new_tmp();
1992
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1993
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1994

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

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

    
2047
    gen_load_gpr(cpu_T[0], rs);
2048
    gen_load_gpr(cpu_T[1], rt);
2049

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

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

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

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

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

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

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

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

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

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

    
2567
/* CP0 (MMU and control) */
2568
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2569
{
2570
    const char *rn = "invalid";
2571

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

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

    
3126
die:
3127
#if defined MIPS_DEBUG_DISAS
3128
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3129
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3130
                rn, reg, sel);
3131
    }
3132
#endif
3133
    generate_exception(ctx, EXCP_RI);
3134
}
3135

    
3136
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3137
{
3138
    const char *rn = "invalid";
3139

    
3140
    if (sel != 0)
3141
        check_insn(env, ctx, ISA_MIPS32);
3142

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

    
3725
die:
3726
#if defined MIPS_DEBUG_DISAS
3727
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3728
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3729
                rn, reg, sel);
3730
    }
3731
#endif
3732
    generate_exception(ctx, EXCP_RI);
3733
}
3734

    
3735
#if defined(TARGET_MIPS64)
3736
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3737
{
3738
    const char *rn = "invalid";
3739

    
3740
    if (sel != 0)
3741
        check_insn(env, ctx, ISA_MIPS64);
3742

    
3743
    switch (reg) {
3744
    case 0:
3745
        switch (sel) {
3746
        case 0:
3747
            gen_op_mfc0_index();
3748
            rn = "Index";
3749
            break;
3750
        case 1:
3751
            check_insn(env, ctx, ASE_MT);
3752
            gen_op_mfc0_mvpcontrol();
3753
            rn = "MVPControl";
3754
            break;
3755
        case 2:
3756
            check_insn(env, ctx, ASE_MT);
3757
            gen_op_mfc0_mvpconf0();
3758
            rn = "MVPConf0";
3759
            break;
3760
        case 3:
3761
            check_insn(env, ctx, ASE_MT);
3762
            gen_op_mfc0_mvpconf1();
3763
            rn = "MVPConf1";
3764
            break;
3765
        default:
3766
            goto die;
3767
        }
3768
        break;
3769
    case 1:
3770
        switch (sel) {
3771
        case 0:
3772
            gen_op_mfc0_random();
3773
            rn = "Random";
3774
            break;
3775
        case 1:
3776
            check_insn(env, ctx, ASE_MT);
3777
            gen_op_mfc0_vpecontrol();
3778
            rn = "VPEControl";
3779
            break;
3780
        case 2:
3781
            check_insn(env, ctx, ASE_MT);
3782
            gen_op_mfc0_vpeconf0();
3783
            rn = "VPEConf0";
3784
            break;
3785
        case 3:
3786
            check_insn(env, ctx, ASE_MT);
3787
            gen_op_mfc0_vpeconf1();
3788
            rn = "VPEConf1";
3789
            break;
3790
        case 4:
3791
            check_insn(env, ctx, ASE_MT);
3792
            gen_op_dmfc0_yqmask();
3793
            rn = "YQMask";
3794
            break;
3795
        case 5:
3796
            check_insn(env, ctx, ASE_MT);
3797
            gen_op_dmfc0_vpeschedule();
3798
            rn = "VPESchedule";
3799
            break;
3800
        case 6:
3801
            check_insn(env, ctx, ASE_MT);
3802
            gen_op_dmfc0_vpeschefback();
3803
            rn = "VPEScheFBack";
3804
            break;
3805
        case 7:
3806
            check_insn(env, ctx, ASE_MT);
3807
            gen_op_mfc0_vpeopt();
3808
            rn = "VPEOpt";
3809
            break;
3810
        default:
3811
            goto die;
3812
        }
3813
        break;
3814
    case 2:
3815
        switch (sel) {
3816
        case 0:
3817
            gen_op_dmfc0_entrylo0();
3818
            rn = "EntryLo0";
3819
            break;
3820
        case 1:
3821
            check_insn(env, ctx, ASE_MT);
3822
            gen_op_mfc0_tcstatus();
3823
            rn = "TCStatus";
3824
            break;
3825
        case 2:
3826
            check_insn(env, ctx, ASE_MT);
3827
            gen_op_mfc0_tcbind();
3828
            rn = "TCBind";
3829
            break;
3830
        case 3:
3831
            check_insn(env, ctx, ASE_MT);
3832
            gen_op_dmfc0_tcrestart();
3833
            rn = "TCRestart";
3834
            break;
3835
        case 4:
3836
            check_insn(env, ctx, ASE_MT);
3837
            gen_op_dmfc0_tchalt();
3838
            rn = "TCHalt";
3839
            break;
3840
        case 5:
3841
            check_insn(env, ctx, ASE_MT);
3842
            gen_op_dmfc0_tccontext();
3843
            rn = "TCContext";
3844
            break;
3845
        case 6:
3846
            check_insn(env, ctx, ASE_MT);
3847
            gen_op_dmfc0_tcschedule();
3848
            rn = "TCSchedule";
3849
            break;
3850
        case 7:
3851
            check_insn(env, ctx, ASE_MT);
3852
            gen_op_dmfc0_tcschefback();
3853
            rn = "TCScheFBack";
3854
            break;
3855
        default:
3856
            goto die;
3857
        }
3858
        break;
3859
    case 3:
3860
        switch (sel) {
3861
        case 0:
3862
            gen_op_dmfc0_entrylo1();
3863
            rn = "EntryLo1";
3864
            break;
3865
        default:
3866
            goto die;
3867
        }
3868
        break;
3869
    case 4:
3870
        switch (sel) {
3871
        case 0:
3872
            gen_op_dmfc0_context();
3873
            rn = "Context";
3874
            break;
3875
        case 1:
3876
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3877
            rn = "ContextConfig";
3878
//            break;
3879
        default:
3880
            goto die;
3881
        }
3882
        break;
3883
    case 5:
3884
        switch (sel) {
3885
        case 0:
3886
            gen_op_mfc0_pagemask();
3887
            rn = "PageMask";
3888
            break;
3889
        case 1:
3890
            check_insn(env, ctx, ISA_MIPS32R2);
3891
            gen_op_mfc0_pagegrain();
3892
            rn = "PageGrain";
3893
            break;
3894
        default:
3895
            goto die;
3896
        }
3897
        break;
3898
    case 6:
3899
        switch (sel) {
3900
        case 0:
3901
            gen_op_mfc0_wired();
3902
            rn = "Wired";
3903
            break;
3904
        case 1:
3905
            check_insn(env, ctx, ISA_MIPS32R2);
3906
            gen_op_mfc0_srsconf0();
3907
            rn = "SRSConf0";
3908
            break;
3909
        case 2:
3910
            check_insn(env, ctx, ISA_MIPS32R2);
3911
            gen_op_mfc0_srsconf1();
3912
            rn = "SRSConf1";
3913
            break;
3914
        case 3:
3915
            check_insn(env, ctx, ISA_MIPS32R2);
3916
            gen_op_mfc0_srsconf2();
3917
            rn = "SRSConf2";
3918
            break;
3919
        case 4:
3920
            check_insn(env, ctx, ISA_MIPS32R2);
3921
            gen_op_mfc0_srsconf3();
3922
            rn = "SRSConf3";
3923
            break;
3924
        case 5:
3925
            check_insn(env, ctx, ISA_MIPS32R2);
3926
            gen_op_mfc0_srsconf4();
3927
            rn = "SRSConf4";
3928
            break;
3929
        default:
3930
            goto die;
3931
        }
3932
        break;
3933
    case 7:
3934
        switch (sel) {
3935
        case 0:
3936
            check_insn(env, ctx, ISA_MIPS32R2);
3937
            gen_op_mfc0_hwrena();
3938
            rn = "HWREna";
3939
            break;
3940
        default:
3941
            goto die;
3942
        }
3943
        break;
3944
    case 8:
3945
        switch (sel) {
3946
        case 0:
3947
            gen_op_dmfc0_badvaddr();
3948
            rn = "BadVaddr";
3949
            break;
3950
        default:
3951
            goto die;
3952
        }
3953
        break;
3954
    case 9:
3955
        switch (sel) {
3956
        case 0:
3957
            gen_op_mfc0_count();
3958
            rn = "Count";
3959
            break;
3960
        /* 6,7 are implementation dependent */
3961
        default:
3962
            goto die;
3963
        }
3964
        break;
3965
    case 10:
3966
        switch (sel) {
3967
        case 0:
3968
            gen_op_dmfc0_entryhi();
3969
            rn = "EntryHi";
3970
            break;
3971
        default:
3972
            goto die;
3973
        }
3974
        break;
3975
    case 11:
3976
        switch (sel) {
3977
        case 0:
3978
            gen_op_mfc0_compare();
3979
            rn = "Compare";
3980
            break;
3981
        /* 6,7 are implementation dependent */
3982
        default:
3983
            goto die;
3984
        }
3985
        break;
3986
    case 12:
3987
        switch (sel) {
3988
        case 0:
3989
            gen_op_mfc0_status();
3990
            rn = "Status";
3991
            break;
3992
        case 1:
3993
            check_insn(env, ctx, ISA_MIPS32R2);
3994
            gen_op_mfc0_intctl();
3995
            rn = "IntCtl";
3996
            break;
3997
        case 2:
3998
            check_insn(env, ctx, ISA_MIPS32R2);
3999
            gen_op_mfc0_srsctl();
4000
            rn = "SRSCtl";
4001
            break;
4002
        case 3:
4003
            check_insn(env, ctx, ISA_MIPS32R2);
4004
            gen_op_mfc0_srsmap();
4005
            rn = "SRSMap";
4006
            break;
4007
        default:
4008
            goto die;
4009
        }
4010
        break;
4011
    case 13:
4012
        switch (sel) {
4013
        case 0:
4014
            gen_op_mfc0_cause();
4015
            rn = "Cause";
4016
            break;
4017
        default:
4018
            goto die;
4019
        }
4020
        break;
4021
    case 14:
4022
        switch (sel) {
4023
        case 0:
4024
            gen_op_dmfc0_epc();
4025
            rn = "EPC";
4026
            break;
4027
        default:
4028
            goto die;
4029
        }
4030
        break;
4031
    case 15:
4032
        switch (sel) {
4033
        case 0:
4034
            gen_op_mfc0_prid();
4035
            rn = "PRid";
4036
            break;
4037
        case 1:
4038
            check_insn(env, ctx, ISA_MIPS32R2);
4039
            gen_op_mfc0_ebase();
4040
            rn = "EBase";
4041
            break;
4042
        default:
4043
            goto die;
4044
        }
4045
        break;
4046
    case 16:
4047
        switch (sel) {
4048
        case 0:
4049
            gen_op_mfc0_config0();
4050
            rn = "Config";
4051
            break;
4052
        case 1:
4053
            gen_op_mfc0_config1();
4054
            rn = "Config1";
4055
            break;
4056
        case 2:
4057
            gen_op_mfc0_config2();
4058
            rn = "Config2";
4059
            break;
4060
        case 3:
4061
            gen_op_mfc0_config3();
4062
            rn = "Config3";
4063
            break;
4064
       /* 6,7 are implementation dependent */
4065
        default:
4066
            goto die;
4067
        }
4068
        break;
4069
    case 17:
4070
        switch (sel) {
4071
        case 0:
4072
            gen_op_dmfc0_lladdr();
4073
            rn = "LLAddr";
4074
            break;
4075
        default:
4076
            goto die;
4077
        }
4078
        break;
4079
    case 18:
4080
        switch (sel) {
4081
        case 0 ... 7:
4082
            gen_op_dmfc0_watchlo(sel);
4083
            rn = "WatchLo";
4084
            break;
4085
        default:
4086
            goto die;
4087
        }
4088
        break;
4089
    case 19:
4090
        switch (sel) {
4091
        case 0 ... 7:
4092
            gen_op_mfc0_watchhi(sel);
4093
            rn = "WatchHi";
4094
            break;
4095
        default:
4096
            goto die;
4097
        }
4098
        break;
4099
    case 20:
4100
        switch (sel) {
4101
        case 0:
4102
            check_insn(env, ctx, ISA_MIPS3);
4103
            gen_op_dmfc0_xcontext();
4104
            rn = "XContext";
4105
            break;
4106
        default:
4107
            goto die;
4108
        }
4109
        break;
4110
    case 21:
4111
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4112
        switch (sel) {
4113
        case 0:
4114
            gen_op_mfc0_framemask();
4115
            rn = "Framemask";
4116
            break;
4117
        default:
4118
            goto die;
4119
        }
4120
        break;
4121
    case 22:
4122
        /* ignored */
4123
        rn = "'Diagnostic"; /* implementation dependent */
4124
        break;
4125
    case 23:
4126
        switch (sel) {
4127
        case 0:
4128
            gen_op_mfc0_debug(); /* EJTAG support */
4129
            rn = "Debug";
4130
            break;
4131
        case 1:
4132
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4133
            rn = "TraceControl";
4134
//            break;
4135
        case 2:
4136
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4137
            rn = "TraceControl2";
4138
//            break;
4139
        case 3:
4140
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4141
            rn = "UserTraceData";
4142
//            break;
4143
        case 4:
4144
//            gen_op_dmfc0_debug(); /* PDtrace support */
4145
            rn = "TraceBPC";
4146
//            break;
4147
        default:
4148
            goto die;
4149
        }
4150
        break;
4151
    case 24:
4152
        switch (sel) {
4153
        case 0:
4154
            gen_op_dmfc0_depc(); /* EJTAG support */
4155
            rn = "DEPC";
4156
            break;
4157
        default:
4158
            goto die;
4159
        }
4160
        break;
4161
    case 25:
4162
        switch (sel) {
4163
        case 0:
4164
            gen_op_mfc0_performance0();
4165
            rn = "Performance0";
4166
            break;
4167
        case 1:
4168
//            gen_op_dmfc0_performance1();
4169
            rn = "Performance1";
4170
//            break;
4171
        case 2:
4172
//            gen_op_dmfc0_performance2();
4173
            rn = "Performance2";
4174
//            break;
4175
        case 3:
4176
//            gen_op_dmfc0_performance3();
4177
            rn = "Performance3";
4178
//            break;
4179
        case 4:
4180
//            gen_op_dmfc0_performance4();
4181
            rn = "Performance4";
4182
//            break;
4183
        case 5:
4184
//            gen_op_dmfc0_performance5();
4185
            rn = "Performance5";
4186
//            break;
4187
        case 6:
4188
//            gen_op_dmfc0_performance6();
4189
            rn = "Performance6";
4190
//            break;
4191
        case 7:
4192
//            gen_op_dmfc0_performance7();
4193
            rn = "Performance7";
4194
//            break;
4195
        default:
4196
            goto die;
4197
        }
4198
        break;
4199
    case 26:
4200
       rn = "ECC";
4201
       break;
4202
    case 27:
4203
        switch (sel) {
4204
        /* ignored */
4205
        case 0 ... 3:
4206
            rn = "CacheErr";
4207
            break;
4208
        default:
4209
            goto die;
4210
        }
4211
        break;
4212
    case 28:
4213
        switch (sel) {
4214
        case 0:
4215
        case 2:
4216
        case 4:
4217
        case 6:
4218
            gen_op_mfc0_taglo();
4219
            rn = "TagLo";
4220
            break;
4221
        case 1:
4222
        case 3:
4223
        case 5:
4224
        case 7:
4225
            gen_op_mfc0_datalo();
4226
            rn = "DataLo";
4227
            break;
4228
        default:
4229
            goto die;
4230
        }
4231
        break;
4232
    case 29:
4233
        switch (sel) {
4234
        case 0:
4235
        case 2:
4236
        case 4:
4237
        case 6:
4238
            gen_op_mfc0_taghi();
4239
            rn = "TagHi";
4240
            break;
4241
        case 1:
4242
        case 3:
4243
        case 5:
4244
        case 7:
4245
            gen_op_mfc0_datahi();
4246
            rn = "DataHi";
4247
            break;
4248
        default:
4249
            goto die;
4250
        }
4251
        break;
4252
    case 30:
4253
        switch (sel) {
4254
        case 0:
4255
            gen_op_dmfc0_errorepc();
4256
            rn = "ErrorEPC";
4257
            break;
4258
        default:
4259
            goto die;
4260
        }
4261
        break;
4262
    case 31:
4263
        switch (sel) {
4264
        case 0:
4265
            gen_op_mfc0_desave(); /* EJTAG support */
4266
            rn = "DESAVE";
4267
            break;
4268
        default:
4269
            goto die;
4270
        }
4271
        break;
4272
    default:
4273
        goto die;
4274
    }
4275
#if defined MIPS_DEBUG_DISAS
4276
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4277
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4278
                rn, reg, sel);
4279
    }
4280
#endif
4281
    return;
4282

    
4283
die:
4284
#if defined MIPS_DEBUG_DISAS
4285
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4286
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4287
                rn, reg, sel);
4288
    }
4289
#endif
4290
    generate_exception(ctx, EXCP_RI);
4291
}
4292

    
4293
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4294
{
4295
    const char *rn = "invalid";
4296

    
4297
    if (sel != 0)
4298
        check_insn(env, ctx, ISA_MIPS64);
4299

    
4300
    switch (reg) {
4301
    case 0:
4302
        switch (sel) {
4303
        case 0:
4304
            gen_op_mtc0_index();
4305
            rn = "Index";
4306
            break;
4307
        case 1:
4308
            check_insn(env, ctx, ASE_MT);
4309
            gen_op_mtc0_mvpcontrol();
4310
            rn = "MVPControl";
4311
            break;
4312
        case 2:
4313
            check_insn(env, ctx, ASE_MT);
4314
            /* ignored */
4315
            rn = "MVPConf0";
4316
            break;
4317
        case 3:
4318
            check_insn(env, ctx, ASE_MT);
4319
            /* ignored */
4320
            rn = "MVPConf1";
4321
            break;
4322
        default:
4323
            goto die;
4324
        }
4325
        break;
4326
    case 1:
4327
        switch (sel) {
4328
        case 0:
4329
            /* ignored */
4330
            rn = "Random";
4331
            break;
4332
        case 1:
4333
            check_insn(env, ctx, ASE_MT);
4334
            gen_op_mtc0_vpecontrol();
4335
            rn = "VPEControl";
4336
            break;
4337
        case 2:
4338
            check_insn(env, ctx, ASE_MT);
4339
            gen_op_mtc0_vpeconf0();
4340
            rn = "VPEConf0";
4341
            break;
4342
        case 3:
4343
            check_insn(env, ctx, ASE_MT);
4344
            gen_op_mtc0_vpeconf1();
4345
            rn = "VPEConf1";
4346
            break;
4347
        case 4:
4348
            check_insn(env, ctx, ASE_MT);
4349
            gen_op_mtc0_yqmask();
4350
            rn = "YQMask";
4351
            break;
4352
        case 5:
4353
            check_insn(env, ctx, ASE_MT);
4354
            gen_op_mtc0_vpeschedule();
4355
            rn = "VPESchedule";
4356
            break;
4357
        case 6:
4358
            check_insn(env, ctx, ASE_MT);
4359
            gen_op_mtc0_vpeschefback();
4360
            rn = "VPEScheFBack";
4361
            break;
4362
        case 7:
4363
            check_insn(env, ctx, ASE_MT);
4364
            gen_op_mtc0_vpeopt();
4365
            rn = "VPEOpt";
4366
            break;
4367
        default:
4368
            goto die;
4369
        }
4370
        break;
4371
    case 2:
4372
        switch (sel) {
4373
        case 0:
4374
            gen_op_mtc0_entrylo0();
4375
            rn = "EntryLo0";
4376
            break;
4377
        case 1:
4378
            check_insn(env, ctx, ASE_MT);
4379
            gen_op_mtc0_tcstatus();
4380
            rn = "TCStatus";
4381
            break;
4382
        case 2:
4383
            check_insn(env, ctx, ASE_MT);
4384
            gen_op_mtc0_tcbind();
4385
            rn = "TCBind";
4386
            break;
4387
        case 3:
4388
            check_insn(env, ctx, ASE_MT);
4389
            gen_op_mtc0_tcrestart();
4390
            rn = "TCRestart";
4391
            break;
4392
        case 4:
4393
            check_insn(env, ctx, ASE_MT);
4394
            gen_op_mtc0_tchalt();
4395
            rn = "TCHalt";
4396
            break;
4397
        case 5:
4398
            check_insn(env, ctx, ASE_MT);
4399
            gen_op_mtc0_tccontext();
4400
            rn = "TCContext";
4401
            break;
4402
        case 6:
4403
            check_insn(env, ctx, ASE_MT);
4404
            gen_op_mtc0_tcschedule();
4405
            rn = "TCSchedule";
4406
            break;
4407
        case 7:
4408
            check_insn(env, ctx, ASE_MT);
4409
            gen_op_mtc0_tcschefback();
4410
            rn = "TCScheFBack";
4411
            break;
4412
        default:
4413
            goto die;
4414
        }
4415
        break;
4416
    case 3:
4417
        switch (sel) {
4418
        case 0:
4419
            gen_op_mtc0_entrylo1();
4420
            rn = "EntryLo1";
4421
            break;
4422
        default:
4423
            goto die;
4424
        }
4425
        break;
4426
    case 4:
4427
        switch (sel) {
4428
        case 0:
4429
            gen_op_mtc0_context();
4430
            rn = "Context";
4431
            break;
4432
        case 1:
4433
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4434
            rn = "ContextConfig";
4435
//           break;
4436
        default:
4437
            goto die;
4438
        }
4439
        break;
4440
    case 5:
4441
        switch (sel) {
4442
        case 0:
4443
            gen_op_mtc0_pagemask();
4444
            rn = "PageMask";
4445
            break;
4446
        case 1:
4447
            check_insn(env, ctx, ISA_MIPS32R2);
4448
            gen_op_mtc0_pagegrain();
4449
            rn = "PageGrain";
4450
            break;
4451
        default:
4452
            goto die;
4453
        }
4454
        break;
4455
    case 6:
4456
        switch (sel) {
4457
        case 0:
4458
            gen_op_mtc0_wired();
4459
            rn = "Wired";
4460
            break;
4461
        case 1:
4462
            check_insn(env, ctx, ISA_MIPS32R2);
4463
            gen_op_mtc0_srsconf0();
4464
            rn = "SRSConf0";
4465
            break;
4466
        case 2:
4467
            check_insn(env, ctx, ISA_MIPS32R2);
4468
            gen_op_mtc0_srsconf1();
4469
            rn = "SRSConf1";
4470
            break;
4471
        case 3:
4472
            check_insn(env, ctx, ISA_MIPS32R2);
4473
            gen_op_mtc0_srsconf2();
4474
            rn = "SRSConf2";
4475
            break;
4476
        case 4:
4477
            check_insn(env, ctx, ISA_MIPS32R2);
4478
            gen_op_mtc0_srsconf3();
4479
            rn = "SRSConf3";
4480
            break;
4481
        case 5:
4482
            check_insn(env, ctx, ISA_MIPS32R2);
4483
            gen_op_mtc0_srsconf4();
4484
            rn = "SRSConf4";
4485
            break;
4486
        default:
4487
            goto die;
4488
        }
4489
        break;
4490
    case 7:
4491
        switch (sel) {
4492
        case 0:
4493
            check_insn(env, ctx, ISA_MIPS32R2);
4494
            gen_op_mtc0_hwrena();
4495
            rn = "HWREna";
4496
            break;
4497
        default:
4498
            goto die;
4499
        }
4500
        break;
4501
    case 8:
4502
        /* ignored */
4503
        rn = "BadVaddr";
4504
        break;
4505
    case 9:
4506
        switch (sel) {
4507
        case 0:
4508
            gen_op_mtc0_count();
4509
            rn = "Count";
4510
            break;
4511
        /* 6,7 are implementation dependent */
4512
        default:
4513
            goto die;
4514
        }
4515
        /* Stop translation as we may have switched the execution mode */
4516
        ctx->bstate = BS_STOP;
4517
        break;
4518
    case 10:
4519
        switch (sel) {
4520
        case 0:
4521
            gen_op_mtc0_entryhi();
4522
            rn = "EntryHi";
4523
            break;
4524
        default:
4525
            goto die;
4526
        }
4527
        break;
4528
    case 11:
4529
        switch (sel) {
4530
        case 0:
4531
            gen_op_mtc0_compare();
4532
            rn = "Compare";
4533
            break;
4534
        /* 6,7 are implementation dependent */
4535
        default:
4536
            goto die;
4537
        }
4538
        /* Stop translation as we may have switched the execution mode */
4539
        ctx->bstate = BS_STOP;
4540
        break;
4541
    case 12:
4542
        switch (sel) {
4543
        case 0:
4544
            gen_op_mtc0_status();
4545
            /* BS_STOP isn't good enough here, hflags may have changed. */
4546
            gen_save_pc(ctx->pc + 4);
4547
            ctx->bstate = BS_EXCP;
4548
            rn = "Status";
4549
            break;
4550
        case 1:
4551
            check_insn(env, ctx, ISA_MIPS32R2);
4552
            gen_op_mtc0_intctl();
4553
            /* Stop translation as we may have switched the execution mode */
4554
            ctx->bstate = BS_STOP;
4555
            rn = "IntCtl";
4556
            break;
4557
        case 2:
4558
            check_insn(env, ctx, ISA_MIPS32R2);
4559
            gen_op_mtc0_srsctl();
4560
            /* Stop translation as we may have switched the execution mode */
4561
            ctx->bstate = BS_STOP;
4562
            rn = "SRSCtl";
4563
            break;
4564
        case 3:
4565
            check_insn(env, ctx, ISA_MIPS32R2);
4566
            gen_op_mtc0_srsmap();
4567
            /* Stop translation as we may have switched the execution mode */
4568
            ctx->bstate = BS_STOP;
4569
            rn = "SRSMap";
4570
            break;
4571
        default:
4572
            goto die;
4573
        }
4574
        break;
4575
    case 13:
4576
        switch (sel) {
4577
        case 0:
4578
            gen_op_mtc0_cause();
4579
            rn = "Cause";
4580
            break;
4581
        default:
4582
            goto die;
4583
        }
4584
        /* Stop translation as we may have switched the execution mode */
4585
        ctx->bstate = BS_STOP;
4586
        break;
4587
    case 14:
4588
        switch (sel) {
4589
        case 0:
4590
            gen_op_mtc0_epc();
4591
            rn = "EPC";
4592
            break;
4593
        default:
4594
            goto die;
4595
        }
4596
        break;
4597
    case 15:
4598
        switch (sel) {
4599
        case 0:
4600
            /* ignored */
4601
            rn = "PRid";
4602
            break;
4603
        case 1:
4604
            check_insn(env, ctx, ISA_MIPS32R2);
4605
            gen_op_mtc0_ebase();
4606
            rn = "EBase";
4607
            break;
4608
        default:
4609
            goto die;
4610
        }
4611
        break;
4612
    case 16:
4613
        switch (sel) {
4614
        case 0:
4615
            gen_op_mtc0_config0();
4616
            rn = "Config";
4617
            /* Stop translation as we may have switched the execution mode */
4618
            ctx->bstate = BS_STOP;
4619
            break;
4620
        case 1:
4621
            /* ignored */
4622
            rn = "Config1";
4623
            break;
4624
        case 2:
4625
            gen_op_mtc0_config2();
4626
            rn = "Config2";
4627
            /* Stop translation as we may have switched the execution mode */
4628
            ctx->bstate = BS_STOP;
4629
            break;
4630
        case 3:
4631
            /* ignored */
4632
            rn = "Config3";
4633
            break;
4634
        /* 6,7 are implementation dependent */
4635
        default:
4636
            rn = "Invalid config selector";
4637
            goto die;
4638
        }
4639
        break;
4640
    case 17:
4641
        switch (sel) {
4642
        case 0:
4643
            /* ignored */
4644
            rn = "LLAddr";
4645
            break;
4646
        default:
4647
            goto die;
4648
        }
4649
        break;
4650
    case 18:
4651
        switch (sel) {
4652
        case 0 ... 7:
4653
            gen_op_mtc0_watchlo(sel);
4654
            rn = "WatchLo";
4655
            break;
4656
        default:
4657
            goto die;
4658
        }
4659
        break;
4660
    case 19:
4661
        switch (sel) {
4662
        case 0 ... 7:
4663
            gen_op_mtc0_watchhi(sel);
4664
            rn = "WatchHi";
4665
            break;
4666
        default:
4667
            goto die;
4668
        }
4669
        break;
4670
    case 20:
4671
        switch (sel) {
4672
        case 0:
4673
            check_insn(env, ctx, ISA_MIPS3);
4674
            gen_op_mtc0_xcontext();
4675
            rn = "XContext";
4676
            break;
4677
        default:
4678
            goto die;
4679
        }
4680
        break;
4681
    case 21:
4682
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4683
        switch (sel) {
4684
        case 0:
4685
            gen_op_mtc0_framemask();
4686
            rn = "Framemask";
4687
            break;
4688
        default:
4689
            goto die;
4690
        }
4691
        break;
4692
    case 22:
4693
        /* ignored */
4694
        rn = "Diagnostic"; /* implementation dependent */
4695
        break;
4696
    case 23:
4697
        switch (sel) {
4698
        case 0:
4699
            gen_op_mtc0_debug(); /* EJTAG support */
4700
            /* BS_STOP isn't good enough here, hflags may have changed. */
4701
            gen_save_pc(ctx->pc + 4);
4702
            ctx->bstate = BS_EXCP;
4703
            rn = "Debug";
4704
            break;
4705
        case 1:
4706
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4707
            /* Stop translation as we may have switched the execution mode */
4708
            ctx->bstate = BS_STOP;
4709
            rn = "TraceControl";
4710
//            break;
4711
        case 2:
4712
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4713
            /* Stop translation as we may have switched the execution mode */
4714
            ctx->bstate = BS_STOP;
4715
            rn = "TraceControl2";
4716
//            break;
4717
        case 3:
4718
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4719
            /* Stop translation as we may have switched the execution mode */
4720
            ctx->bstate = BS_STOP;
4721
            rn = "UserTraceData";
4722
//            break;
4723
        case 4:
4724
//            gen_op_mtc0_debug(); /* PDtrace support */
4725
            /* Stop translation as we may have switched the execution mode */
4726
            ctx->bstate = BS_STOP;
4727
            rn = "TraceBPC";
4728
//            break;
4729
        default:
4730
            goto die;
4731
        }
4732
        break;
4733
    case 24:
4734
        switch (sel) {
4735
        case 0:
4736
            gen_op_mtc0_depc(); /* EJTAG support */
4737
            rn = "DEPC";
4738
            break;
4739
        default:
4740
            goto die;
4741
        }
4742
        break;
4743
    case 25:
4744
        switch (sel) {
4745
        case 0:
4746
            gen_op_mtc0_performance0();
4747
            rn = "Performance0";
4748
            break;
4749
        case 1:
4750
//            gen_op_mtc0_performance1();
4751
            rn = "Performance1";
4752
//            break;
4753
        case 2:
4754
//            gen_op_mtc0_performance2();
4755
            rn = "Performance2";
4756
//            break;
4757
        case 3:
4758
//            gen_op_mtc0_performance3();
4759
            rn = "Performance3";
4760
//            break;
4761
        case 4:
4762
//            gen_op_mtc0_performance4();
4763
            rn = "Performance4";
4764
//            break;
4765
        case 5:
4766
//            gen_op_mtc0_performance5();
4767
            rn = "Performance5";
4768
//            break;
4769
        case 6:
4770
//            gen_op_mtc0_performance6();
4771
            rn = "Performance6";
4772
//            break;
4773
        case 7:
4774
//            gen_op_mtc0_performance7();
4775
            rn = "Performance7";
4776
//            break;
4777
        default:
4778
            goto die;
4779
        }
4780
        break;
4781
    case 26:
4782
        /* ignored */
4783
        rn = "ECC";
4784
        break;
4785
    case 27:
4786
        switch (sel) {
4787
        case 0 ... 3:
4788
            /* ignored */
4789
            rn = "CacheErr";
4790
            break;
4791
        default:
4792
            goto die;
4793
        }
4794
        break;
4795
    case 28:
4796
        switch (sel) {
4797
        case 0:
4798
        case 2:
4799
        case 4:
4800
        case 6:
4801
            gen_op_mtc0_taglo();
4802
            rn = "TagLo";
4803
            break;
4804
        case 1:
4805
        case 3:
4806
        case 5:
4807
        case 7:
4808
            gen_op_mtc0_datalo();
4809
            rn = "DataLo";
4810
            break;
4811
        default:
4812
            goto die;
4813
        }
4814
        break;
4815
    case 29:
4816
        switch (sel) {
4817
        case 0:
4818
        case 2:
4819
        case 4:
4820
        case 6:
4821
            gen_op_mtc0_taghi();
4822
            rn = "TagHi";
4823
            break;
4824
        case 1:
4825
        case 3:
4826
        case 5:
4827
        case 7:
4828
            gen_op_mtc0_datahi();
4829
            rn = "DataHi";
4830
            break;
4831
        default:
4832
            rn = "invalid sel";
4833
            goto die;
4834
        }
4835
        break;
4836
    case 30:
4837
        switch (sel) {
4838
        case 0:
4839
            gen_op_mtc0_errorepc();
4840
            rn = "ErrorEPC";
4841
            break;
4842
        default:
4843
            goto die;
4844
        }
4845
        break;
4846
    case 31:
4847
        switch (sel) {
4848
        case 0:
4849
            gen_op_mtc0_desave(); /* EJTAG support */
4850
            rn = "DESAVE";
4851
            break;
4852
        default:
4853
            goto die;
4854
        }
4855
        /* Stop translation as we may have switched the execution mode */
4856
        ctx->bstate = BS_STOP;
4857
        break;
4858
    default:
4859
        goto die;
4860
    }
4861
#if defined MIPS_DEBUG_DISAS
4862
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4863
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4864
                rn, reg, sel);
4865
    }
4866
#endif
4867
    return;
4868

    
4869
die:
4870
#if defined MIPS_DEBUG_DISAS
4871
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4872
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4873
                rn, reg, sel);
4874
    }
4875
#endif
4876
    generate_exception(ctx, EXCP_RI);
4877
}
4878
#endif /* TARGET_MIPS64 */
4879

    
4880
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4881
                     int u, int sel, int h)
4882
{
4883
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4884

    
4885
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4886
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4887
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4888
        tcg_gen_movi_tl(cpu_T[0], -1);
4889
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4890
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4891
        tcg_gen_movi_tl(cpu_T[0], -1);
4892
    else if (u == 0) {
4893
        switch (rt) {
4894
        case 2:
4895
            switch (sel) {
4896
            case 1:
4897
                gen_op_mftc0_tcstatus();
4898
                break;
4899
            case 2:
4900
                gen_op_mftc0_tcbind();
4901
                break;
4902
            case 3:
4903
                gen_op_mftc0_tcrestart();
4904
                break;
4905
            case 4:
4906
                gen_op_mftc0_tchalt();
4907
                break;
4908
            case 5:
4909
                gen_op_mftc0_tccontext();
4910
                break;
4911
            case 6:
4912
                gen_op_mftc0_tcschedule();
4913
                break;
4914
            case 7:
4915
                gen_op_mftc0_tcschefback();
4916
                break;
4917
            default:
4918
                gen_mfc0(env, ctx, rt, sel);
4919
                break;
4920
            }
4921
            break;
4922
        case 10:
4923
            switch (sel) {
4924
            case 0:
4925
                gen_op_mftc0_entryhi();
4926
                break;
4927
            default:
4928
                gen_mfc0(env, ctx, rt, sel);
4929
                break;
4930
            }
4931
        case 12:
4932
            switch (sel) {
4933
            case 0:
4934
                gen_op_mftc0_status();
4935
                break;
4936
            default:
4937
                gen_mfc0(env, ctx, rt, sel);
4938
                break;
4939
            }
4940
        case 23:
4941
            switch (sel) {
4942
            case 0:
4943
                gen_op_mftc0_debug();
4944
                break;
4945
            default:
4946
                gen_mfc0(env, ctx, rt, sel);
4947
                break;
4948
            }
4949
            break;
4950
        default:
4951
            gen_mfc0(env, ctx, rt, sel);
4952
        }
4953
    } else switch (sel) {
4954
    /* GPR registers. */
4955
    case 0:
4956
        gen_op_mftgpr(rt);
4957
        break;
4958
    /* Auxiliary CPU registers */
4959
    case 1:
4960
        switch (rt) {
4961
        case 0:
4962
            gen_op_mftlo(0);
4963
            break;
4964
        case 1:
4965
            gen_op_mfthi(0);
4966
            break;
4967
        case 2:
4968
            gen_op_mftacx(0);
4969
            break;
4970
        case 4:
4971
            gen_op_mftlo(1);
4972
            break;
4973
        case 5:
4974
            gen_op_mfthi(1);
4975
            break;
4976
        case 6:
4977
            gen_op_mftacx(1);
4978
            break;
4979
        case 8:
4980
            gen_op_mftlo(2);
4981
            break;
4982
        case 9:
4983
            gen_op_mfthi(2);
4984
            break;
4985
        case 10:
4986
            gen_op_mftacx(2);
4987
            break;
4988
        case 12:
4989
            gen_op_mftlo(3);
4990
            break;
4991
        case 13:
4992
            gen_op_mfthi(3);
4993
            break;
4994
        case 14:
4995
            gen_op_mftacx(3);
4996
            break;
4997
        case 16:
4998
            gen_op_mftdsp();
4999
            break;
5000
        default:
5001
            goto die;
5002
        }
5003
        break;
5004
    /* Floating point (COP1). */
5005
    case 2:
5006
        /* XXX: For now we support only a single FPU context. */
5007
        if (h == 0) {
5008
            GEN_LOAD_FREG_FTN(WT0, rt);
5009
            gen_op_mfc1();
5010
        } else {
5011
            GEN_LOAD_FREG_FTN(WTH0, rt);
5012
            gen_op_mfhc1();
5013
        }
5014
        break;
5015
    case 3:
5016
        /* XXX: For now we support only a single FPU context. */
5017
        gen_op_cfc1(rt);
5018
        break;
5019
    /* COP2: Not implemented. */
5020
    case 4:
5021
    case 5:
5022
        /* fall through */
5023
    default:
5024
        goto die;
5025
    }
5026
#if defined MIPS_DEBUG_DISAS
5027
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5028
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5029
                rt, u, sel, h);
5030
    }
5031
#endif
5032
    return;
5033

    
5034
die:
5035
#if defined MIPS_DEBUG_DISAS
5036
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5037
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5038
                rt, u, sel, h);
5039
    }
5040
#endif
5041
    generate_exception(ctx, EXCP_RI);
5042
}
5043

    
5044
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5045
                     int u, int sel, int h)
5046
{
5047
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5048

    
5049
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5050
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5051
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5052
        /* NOP */ ;
5053
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5054
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5055
        /* NOP */ ;
5056
    else if (u == 0) {
5057
        switch (rd) {
5058
        case 2:
5059
            switch (sel) {
5060
            case 1:
5061
                gen_op_mttc0_tcstatus();
5062
                break;
5063
            case 2:
5064
                gen_op_mttc0_tcbind();
5065
                break;
5066
            case 3:
5067
                gen_op_mttc0_tcrestart();
5068
                break;
5069
            case 4:
5070
                gen_op_mttc0_tchalt();
5071
                break;
5072
            case 5:
5073
                gen_op_mttc0_tccontext();
5074
                break;
5075
            case 6:
5076
                gen_op_mttc0_tcschedule();
5077
                break;
5078
            case 7:
5079
                gen_op_mttc0_tcschefback();
5080
                break;
5081
            default:
5082
                gen_mtc0(env, ctx, rd, sel);
5083
                break;
5084
            }
5085
            break;
5086
        case 10:
5087
            switch (sel) {
5088
            case 0:
5089
                gen_op_mttc0_entryhi();
5090
                break;
5091
            default:
5092
                gen_mtc0(env, ctx, rd, sel);
5093
                break;
5094
            }
5095
        case 12:
5096
            switch (sel) {
5097
            case 0:
5098
                gen_op_mttc0_status();
5099
                break;
5100
            default:
5101
                gen_mtc0(env, ctx, rd, sel);
5102
                break;
5103
            }
5104
        case 23:
5105
            switch (sel) {
5106
            case 0:
5107
                gen_op_mttc0_debug();
5108
                break;
5109
            default:
5110
                gen_mtc0(env, ctx, rd, sel);
5111
                break;
5112
            }
5113
            break;
5114
        default:
5115
            gen_mtc0(env, ctx, rd, sel);
5116
        }
5117
    } else switch (sel) {
5118
    /* GPR registers. */
5119
    case 0:
5120
        gen_op_mttgpr(rd);
5121
        break;
5122
    /* Auxiliary CPU registers */
5123
    case 1:
5124
        switch (rd) {
5125
        case 0:
5126
            gen_op_mttlo(0);
5127
            break;
5128
        case 1:
5129
            gen_op_mtthi(0);
5130
            break;
5131
        case 2:
5132
            gen_op_mttacx(0);
5133
            break;
5134
        case 4:
5135
            gen_op_mttlo(1);
5136
            break;
5137
        case 5:
5138
            gen_op_mtthi(1);
5139
            break;
5140
        case 6:
5141
            gen_op_mttacx(1);
5142
            break;
5143
        case 8:
5144
            gen_op_mttlo(2);
5145
            break;
5146
        case 9:
5147
            gen_op_mtthi(2);
5148
            break;
5149
        case 10:
5150
            gen_op_mttacx(2);
5151
            break;
5152
        case 12:
5153
            gen_op_mttlo(3);
5154
            break;
5155
        case 13:
5156
            gen_op_mtthi(3);
5157
            break;
5158
        case 14:
5159
            gen_op_mttacx(3);
5160
            break;
5161
        case 16:
5162
            gen_op_mttdsp();
5163
            break;
5164
        default:
5165
            goto die;
5166
        }
5167
        break;
5168
    /* Floating point (COP1). */
5169
    case 2:
5170
        /* XXX: For now we support only a single FPU context. */
5171
        if (h == 0) {
5172
            gen_op_mtc1();
5173
            GEN_STORE_FTN_FREG(rd, WT0);
5174
        } else {
5175
            gen_op_mthc1();
5176
            GEN_STORE_FTN_FREG(rd, WTH0);
5177
        }
5178
        break;
5179
    case 3:
5180
        /* XXX: For now we support only a single FPU context. */
5181
        gen_op_ctc1(rd);
5182
        break;
5183
    /* COP2: Not implemented. */
5184
    case 4:
5185
    case 5:
5186
        /* fall through */
5187
    default:
5188
        goto die;
5189
    }
5190
#if defined MIPS_DEBUG_DISAS
5191
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5192
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5193
                rd, u, sel, h);
5194
    }
5195
#endif
5196
    return;
5197

    
5198
die:
5199
#if defined MIPS_DEBUG_DISAS
5200
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5201
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5202
                rd, u, sel, h);
5203
    }
5204
#endif
5205
    generate_exception(ctx, EXCP_RI);
5206
}
5207

    
5208
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5209
{
5210
    const char *opn = "ldst";
5211

    
5212
    switch (opc) {
5213
    case OPC_MFC0:
5214
        if (rt == 0) {
5215
            /* Treat as NOP. */
5216
            return;
5217
        }
5218
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5219
        gen_store_gpr(cpu_T[0], rt);
5220
        opn = "mfc0";
5221
        break;
5222
    case OPC_MTC0:
5223
        gen_load_gpr(cpu_T[0], rt);
5224
        save_cpu_state(ctx, 1);
5225
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5226
        opn = "mtc0";
5227
        break;
5228
#if defined(TARGET_MIPS64)
5229
    case OPC_DMFC0:
5230
        check_insn(env, ctx, ISA_MIPS3);
5231
        if (rt == 0) {
5232
            /* Treat as NOP. */
5233
            return;
5234
        }
5235
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5236
        gen_store_gpr(cpu_T[0], rt);
5237
        opn = "dmfc0";
5238
        break;
5239
    case OPC_DMTC0:
5240
        check_insn(env, ctx, ISA_MIPS3);
5241
        gen_load_gpr(cpu_T[0], rt);
5242
        save_cpu_state(ctx, 1);
5243
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5244
        opn = "dmtc0";
5245
        break;
5246
#endif
5247
    case OPC_MFTR:
5248
        check_insn(env, ctx, ASE_MT);
5249
        if (rd == 0) {
5250
            /* Treat as NOP. */
5251
            return;
5252
        }
5253
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5254
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5255
        gen_store_gpr(cpu_T[0], rd);
5256
        opn = "mftr";
5257
        break;
5258
    case OPC_MTTR:
5259
        check_insn(env, ctx, ASE_MT);
5260
        gen_load_gpr(cpu_T[0], rt);
5261
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5262
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5263
        opn = "mttr";
5264
        break;
5265
    case OPC_TLBWI:
5266
        opn = "tlbwi";
5267
        if (!env->tlb->do_tlbwi)
5268
            goto die;
5269
        gen_op_tlbwi();
5270
        break;
5271
    case OPC_TLBWR:
5272
        opn = "tlbwr";
5273
        if (!env->tlb->do_tlbwr)
5274
            goto die;
5275
        gen_op_tlbwr();
5276
        break;
5277
    case OPC_TLBP:
5278
        opn = "tlbp";
5279
        if (!env->tlb->do_tlbp)
5280
            goto die;
5281
        gen_op_tlbp();
5282
        break;
5283
    case OPC_TLBR:
5284
        opn = "tlbr";
5285
        if (!env->tlb->do_tlbr)
5286
            goto die;
5287
        gen_op_tlbr();
5288
        break;
5289
    case OPC_ERET:
5290
        opn = "eret";
5291
        check_insn(env, ctx, ISA_MIPS2);
5292
        save_cpu_state(ctx, 1);
5293
        gen_op_eret();
5294
        ctx->bstate = BS_EXCP;
5295
        break;
5296
    case OPC_DERET:
5297
        opn = "deret";
5298
        check_insn(env, ctx, ISA_MIPS32);
5299
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5300
            MIPS_INVAL(opn);
5301
            generate_exception(ctx, EXCP_RI);
5302
        } else {
5303
            save_cpu_state(ctx, 1);
5304
            gen_op_deret();
5305
            ctx->bstate = BS_EXCP;
5306
        }
5307
        break;
5308
    case OPC_WAIT:
5309
        opn = "wait";
5310
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5311
        /* If we get an exception, we want to restart at next instruction */
5312
        ctx->pc += 4;
5313
        save_cpu_state(ctx, 1);
5314
        ctx->pc -= 4;
5315
        gen_op_wait();
5316
        ctx->bstate = BS_EXCP;
5317
        break;
5318
    default:
5319
 die:
5320
        MIPS_INVAL(opn);
5321
        generate_exception(ctx, EXCP_RI);
5322
        return;
5323
    }
5324
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5325
}
5326

    
5327
/* CP1 Branches (before delay slot) */
5328
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5329
                                 int32_t cc, int32_t offset)
5330
{
5331
    target_ulong btarget;
5332
    const char *opn = "cp1 cond branch";
5333

    
5334
    if (cc != 0)
5335
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5336

    
5337
    btarget = ctx->pc + 4 + offset;
5338

    
5339
    switch (op) {
5340
    case OPC_BC1F:
5341
        gen_op_bc1f(cc);
5342
        opn = "bc1f";
5343
        goto not_likely;
5344
    case OPC_BC1FL:
5345
        gen_op_bc1f(cc);
5346
        opn = "bc1fl";
5347
        goto likely;
5348
    case OPC_BC1T:
5349
        gen_op_bc1t(cc);
5350
        opn = "bc1t";
5351
        goto not_likely;
5352
    case OPC_BC1TL:
5353
        gen_op_bc1t(cc);
5354
        opn = "bc1tl";
5355
    likely:
5356
        ctx->hflags |= MIPS_HFLAG_BL;
5357
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5358
        break;
5359
    case OPC_BC1FANY2:
5360
        gen_op_bc1any2f(cc);
5361
        opn = "bc1any2f";
5362
        goto not_likely;
5363
    case OPC_BC1TANY2:
5364
        gen_op_bc1any2t(cc);
5365
        opn = "bc1any2t";
5366
        goto not_likely;
5367
    case OPC_BC1FANY4:
5368
        gen_op_bc1any4f(cc);
5369
        opn = "bc1any4f";
5370
        goto not_likely;
5371
    case OPC_BC1TANY4:
5372
        gen_op_bc1any4t(cc);
5373
        opn = "bc1any4t";
5374
    not_likely:
5375
        ctx->hflags |= MIPS_HFLAG_BC;
5376
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5377
        break;
5378
    default:
5379
        MIPS_INVAL(opn);
5380
        generate_exception (ctx, EXCP_RI);
5381
        return;
5382
    }
5383
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5384
               ctx->hflags, btarget);
5385
    ctx->btarget = btarget;
5386
}
5387

    
5388
/* Coprocessor 1 (FPU) */
5389

    
5390
#define FOP(func, fmt) (((fmt) << 21) | (func))
5391

    
5392
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5393
{
5394
    const char *opn = "cp1 move";
5395

    
5396
    switch (opc) {
5397
    case OPC_MFC1:
5398
        GEN_LOAD_FREG_FTN(WT0, fs);
5399
        gen_op_mfc1();
5400
        gen_store_gpr(cpu_T[0], rt);
5401
        opn = "mfc1";
5402
        break;
5403
    case OPC_MTC1:
5404
        gen_load_gpr(cpu_T[0], rt);
5405
        gen_op_mtc1();
5406
        GEN_STORE_FTN_FREG(fs, WT0);
5407
        opn = "mtc1";
5408
        break;
5409
    case OPC_CFC1:
5410
        gen_op_cfc1(fs);
5411
        gen_store_gpr(cpu_T[0], rt);
5412
        opn = "cfc1";
5413
        break;
5414
    case OPC_CTC1:
5415
        gen_load_gpr(cpu_T[0], rt);
5416
        gen_op_ctc1(fs);
5417
        opn = "ctc1";
5418
        break;
5419
    case OPC_DMFC1:
5420
        GEN_LOAD_FREG_FTN(DT0, fs);
5421
        gen_op_dmfc1();
5422
        gen_store_gpr(cpu_T[0], rt);
5423
        opn = "dmfc1";
5424
        break;
5425
    case OPC_DMTC1:
5426
        gen_load_gpr(cpu_T[0], rt);
5427
        gen_op_dmtc1();
5428
        GEN_STORE_FTN_FREG(fs, DT0);
5429
        opn = "dmtc1";
5430
        break;
5431
    case OPC_MFHC1:
5432
        GEN_LOAD_FREG_FTN(WTH0, fs);
5433
        gen_op_mfhc1();
5434
        gen_store_gpr(cpu_T[0], rt);
5435
        opn = "mfhc1";
5436
        break;
5437
    case OPC_MTHC1:
5438
        gen_load_gpr(cpu_T[0], rt);
5439
        gen_op_mthc1();
5440
        GEN_STORE_FTN_FREG(fs, WTH0);
5441
        opn = "mthc1";
5442
        break;
5443
    default:
5444
        MIPS_INVAL(opn);
5445
        generate_exception (ctx, EXCP_RI);
5446
        return;
5447
    }
5448
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5449
}
5450

    
5451
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5452
{
5453
    uint32_t ccbit;
5454

    
5455
    gen_load_gpr(cpu_T[0], rd);
5456
    gen_load_gpr(cpu_T[1], rs);
5457
    if (cc) {
5458
        ccbit = 1 << (24 + cc);
5459
    } else
5460
        ccbit = 1 << 23;
5461
    if (!tf)
5462
        gen_op_movf(ccbit);
5463
    else
5464
        gen_op_movt(ccbit);
5465
    gen_store_gpr(cpu_T[0], rd);
5466
}
5467

    
5468
#define GEN_MOVCF(fmt)                                                \
5469
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5470
{                                                                     \
5471
    uint32_t ccbit;                                                   \
5472
                                                                      \
5473
    if (cc) {                                                         \
5474
        ccbit = 1 << (24 + cc);                                       \
5475
    } else                                                            \
5476
        ccbit = 1 << 23;                                              \
5477
    if (!tf)                                                          \
5478
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5479
    else                                                              \
5480
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5481
}
5482
GEN_MOVCF(d);
5483
GEN_MOVCF(s);
5484
GEN_MOVCF(ps);
5485
#undef GEN_MOVCF
5486

    
5487
static void gen_farith (DisasContext *ctx, uint32_t op1,
5488
                        int ft, int fs, int fd, int cc)
5489
{
5490
    const char *opn = "farith";
5491
    const char *condnames[] = {
5492
            "c.f",
5493
            "c.un",
5494
            "c.eq",
5495
            "c.ueq",
5496
            "c.olt",
5497
            "c.ult",
5498
            "c.ole",
5499
            "c.ule",
5500
            "c.sf",
5501
            "c.ngle",
5502
            "c.seq",
5503
            "c.ngl",
5504
            "c.lt",
5505
            "c.nge",
5506
            "c.le",
5507
            "c.ngt",
5508
    };
5509
    const char *condnames_abs[] = {
5510
            "cabs.f",
5511
            "cabs.un",
5512
            "cabs.eq",
5513
            "cabs.ueq",
5514
            "cabs.olt",
5515
            "cabs.ult",
5516
            "cabs.ole",
5517
            "cabs.ule",
5518
            "cabs.sf",
5519
            "cabs.ngle",
5520
            "cabs.seq",
5521
            "cabs.ngl",
5522
            "cabs.lt",
5523
            "cabs.nge",
5524
            "cabs.le",
5525
            "cabs.ngt",
5526
    };
5527
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5528
    uint32_t func = ctx->opcode & 0x3f;
5529

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

    
6296
/* Coprocessor 3 (FPU) */
6297
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6298
                           int fd, int fs, int base, int index)
6299
{
6300
    const char *opn = "extended float load/store";
6301
    int store = 0;
6302

    
6303
    if (base == 0) {
6304
        gen_load_gpr(cpu_T[0], index);
6305
    } else if (index == 0) {
6306
        gen_load_gpr(cpu_T[0], base);
6307
    } else {
6308
        gen_load_gpr(cpu_T[0], base);
6309
        gen_load_gpr(cpu_T[1], index);
6310
        gen_op_addr_add();
6311
    }
6312
    /* Don't do NOP if destination is zero: we must perform the actual
6313
       memory access. */
6314
    switch (opc) {
6315
    case OPC_LWXC1:
6316
        check_cop1x(ctx);
6317
        op_ldst_lwc1(ctx);
6318
        GEN_STORE_FTN_FREG(fd, WT0);
6319
        opn = "lwxc1";
6320
        break;
6321
    case OPC_LDXC1:
6322
        check_cop1x(ctx);
6323
        check_cp1_registers(ctx, fd);
6324
        op_ldst_ldc1(ctx);
6325
        GEN_STORE_FTN_FREG(fd, DT0);
6326
        opn = "ldxc1";
6327
        break;
6328
    case OPC_LUXC1:
6329
        check_cp1_64bitmode(ctx);
6330
        op_ldst(luxc1);
6331
        GEN_STORE_FTN_FREG(fd, DT0);
6332
        opn = "luxc1";
6333
        break;
6334
    case OPC_SWXC1:
6335
        check_cop1x(ctx);
6336
        GEN_LOAD_FREG_FTN(WT0, fs);
6337
        op_ldst_swc1(ctx);
6338
        opn = "swxc1";
6339
        store = 1;
6340
        break;
6341
    case OPC_SDXC1:
6342
        check_cop1x(ctx);
6343
        check_cp1_registers(ctx, fs);
6344
        GEN_LOAD_FREG_FTN(DT0, fs);
6345
        op_ldst_sdc1(ctx);
6346
        opn = "sdxc1";
6347
        store = 1;
6348
        break;
6349
    case OPC_SUXC1:
6350
        check_cp1_64bitmode(ctx);
6351
        GEN_LOAD_FREG_FTN(DT0, fs);
6352
        op_ldst(suxc1);
6353
        opn = "suxc1";
6354
        store = 1;
6355
        break;
6356
    default:
6357
        MIPS_INVAL(opn);
6358
        generate_exception(ctx, EXCP_RI);
6359
        return;
6360
    }
6361
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6362
               regnames[index], regnames[base]);
6363
}
6364

    
6365
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6366
                            int fd, int fr, int fs, int ft)
6367
{
6368
    const char *opn = "flt3_arith";
6369

    
6370
    switch (opc) {
6371
    case OPC_ALNV_PS:
6372
        check_cp1_64bitmode(ctx);
6373
        gen_load_gpr(cpu_T[0], fr);
6374
        GEN_LOAD_FREG_FTN(DT0, fs);
6375
        GEN_LOAD_FREG_FTN(DT1, ft);
6376
        gen_op_float_alnv_ps();
6377
        GEN_STORE_FTN_FREG(fd, DT2);
6378
        opn = "alnv.ps";
6379
        break;
6380
    case OPC_MADD_S:
6381
        check_cop1x(ctx);
6382
        GEN_LOAD_FREG_FTN(WT0, fs);
6383
        GEN_LOAD_FREG_FTN(WT1, ft);
6384
        GEN_LOAD_FREG_FTN(WT2, fr);
6385
        gen_op_float_muladd_s();
6386
        GEN_STORE_FTN_FREG(fd, WT2);
6387
        opn = "madd.s";
6388
        break;
6389
    case OPC_MADD_D:
6390
        check_cop1x(ctx);
6391
        check_cp1_registers(ctx, fd | fs | ft | fr);
6392
        GEN_LOAD_FREG_FTN(DT0, fs);
6393
        GEN_LOAD_FREG_FTN(DT1, ft);
6394
        GEN_LOAD_FREG_FTN(DT2, fr);
6395
        gen_op_float_muladd_d();
6396
        GEN_STORE_FTN_FREG(fd, DT2);
6397
        opn = "madd.d";
6398
        break;
6399
    case OPC_MADD_PS:
6400
        check_cp1_64bitmode(ctx);
6401
        GEN_LOAD_FREG_FTN(WT0, fs);
6402
        GEN_LOAD_FREG_FTN(WTH0, fs);
6403
        GEN_LOAD_FREG_FTN(WT1, ft);
6404
        GEN_LOAD_FREG_FTN(WTH1, ft);
6405
        GEN_LOAD_FREG_FTN(WT2, fr);
6406
        GEN_LOAD_FREG_FTN(WTH2, fr);
6407
        gen_op_float_muladd_ps();
6408
        GEN_STORE_FTN_FREG(fd, WT2);
6409
        GEN_STORE_FTN_FREG(fd, WTH2);
6410
        opn = "madd.ps";
6411
        break;
6412
    case OPC_MSUB_S:
6413
        check_cop1x(ctx);
6414
        GEN_LOAD_FREG_FTN(WT0, fs);
6415
        GEN_LOAD_FREG_FTN(WT1, ft);
6416
        GEN_LOAD_FREG_FTN(WT2, fr);
6417
        gen_op_float_mulsub_s();
6418
        GEN_STORE_FTN_FREG(fd, WT2);
6419
        opn = "msub.s";
6420
        break;
6421
    case OPC_MSUB_D:
6422
        check_cop1x(ctx);
6423
        check_cp1_registers(ctx, fd | fs | ft | fr);
6424
        GEN_LOAD_FREG_FTN(DT0, fs);
6425
        GEN_LOAD_FREG_FTN(DT1, ft);
6426
        GEN_LOAD_FREG_FTN(DT2, fr);
6427
        gen_op_float_mulsub_d();
6428
        GEN_STORE_FTN_FREG(fd, DT2);
6429
        opn = "msub.d";
6430
        break;
6431
    case OPC_MSUB_PS:
6432
        check_cp1_64bitmode(ctx);
6433
        GEN_LOAD_FREG_FTN(WT0, fs);
6434
        GEN_LOAD_FREG_FTN(WTH0, fs);
6435
        GEN_LOAD_FREG_FTN(WT1, ft);
6436
        GEN_LOAD_FREG_FTN(WTH1, ft);
6437
        GEN_LOAD_FREG_FTN(WT2, fr);
6438
        GEN_LOAD_FREG_FTN(WTH2, fr);
6439
        gen_op_float_mulsub_ps();
6440
        GEN_STORE_FTN_FREG(fd, WT2);
6441
        GEN_STORE_FTN_FREG(fd, WTH2);
6442
        opn = "msub.ps";
6443
        break;
6444
    case OPC_NMADD_S:
6445
        check_cop1x(ctx);
6446
        GEN_LOAD_FREG_FTN(WT0, fs);
6447
        GEN_LOAD_FREG_FTN(WT1, ft);
6448
        GEN_LOAD_FREG_FTN(WT2, fr);
6449
        gen_op_float_nmuladd_s();
6450
        GEN_STORE_FTN_FREG(fd, WT2);
6451
        opn = "nmadd.s";
6452
        break;
6453
    case OPC_NMADD_D:
6454
        check_cop1x(ctx);
6455
        check_cp1_registers(ctx, fd | fs | ft | fr);
6456
        GEN_LOAD_FREG_FTN(DT0, fs);
6457
        GEN_LOAD_FREG_FTN(DT1, ft);
6458
        GEN_LOAD_FREG_FTN(DT2, fr);
6459
        gen_op_float_nmuladd_d();
6460
        GEN_STORE_FTN_FREG(fd, DT2);
6461
        opn = "nmadd.d";
6462
        break;
6463
    case OPC_NMADD_PS:
6464
        check_cp1_64bitmode(ctx);
6465
        GEN_LOAD_FREG_FTN(WT0, fs);
6466
        GEN_LOAD_FREG_FTN(WTH0, fs);
6467
        GEN_LOAD_FREG_FTN(WT1, ft);
6468
        GEN_LOAD_FREG_FTN(WTH1, ft);
6469
        GEN_LOAD_FREG_FTN(WT2, fr);
6470
        GEN_LOAD_FREG_FTN(WTH2, fr);
6471
        gen_op_float_nmuladd_ps();
6472
        GEN_STORE_FTN_FREG(fd, WT2);
6473
        GEN_STORE_FTN_FREG(fd, WTH2);
6474
        opn = "nmadd.ps";
6475
        break;
6476
    case OPC_NMSUB_S:
6477
        check_cop1x(ctx);
6478
        GEN_LOAD_FREG_FTN(WT0, fs);
6479
        GEN_LOAD_FREG_FTN(WT1, ft);
6480
        GEN_LOAD_FREG_FTN(WT2, fr);
6481
        gen_op_float_nmulsub_s();
6482
        GEN_STORE_FTN_FREG(fd, WT2);
6483
        opn = "nmsub.s";
6484
        break;
6485
    case OPC_NMSUB_D:
6486
        check_cop1x(ctx);
6487
        check_cp1_registers(ctx, fd | fs | ft | fr);
6488
        GEN_LOAD_FREG_FTN(DT0, fs);
6489
        GEN_LOAD_FREG_FTN(DT1, ft);
6490
        GEN_LOAD_FREG_FTN(DT2, fr);
6491
        gen_op_float_nmulsub_d();
6492
        GEN_STORE_FTN_FREG(fd, DT2);
6493
        opn = "nmsub.d";
6494
        break;
6495
    case OPC_NMSUB_PS:
6496
        check_cp1_64bitmode(ctx);
6497
        GEN_LOAD_FREG_FTN(WT0, fs);
6498
        GEN_LOAD_FREG_FTN(WTH0, fs);
6499
        GEN_LOAD_FREG_FTN(WT1, ft);
6500
        GEN_LOAD_FREG_FTN(WTH1, ft);
6501
        GEN_LOAD_FREG_FTN(WT2, fr);
6502
        GEN_LOAD_FREG_FTN(WTH2, fr);
6503
        gen_op_float_nmulsub_ps();
6504
        GEN_STORE_FTN_FREG(fd, WT2);
6505
        GEN_STORE_FTN_FREG(fd, WTH2);
6506
        opn = "nmsub.ps";
6507
        break;
6508
    default:
6509
        MIPS_INVAL(opn);
6510
        generate_exception (ctx, EXCP_RI);
6511
        return;
6512
    }
6513
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6514
               fregnames[fs], fregnames[ft]);
6515
}
6516

    
6517
/* ISA extensions (ASEs) */
6518
/* MIPS16 extension to MIPS32 */
6519
/* SmartMIPS extension to MIPS32 */
6520

    
6521
#if defined(TARGET_MIPS64)
6522

    
6523
/* MDMX extension to MIPS64 */
6524

    
6525
#endif
6526

    
6527
static void decode_opc (CPUState *env, DisasContext *ctx)
6528
{
6529
    int32_t offset;
6530
    int rs, rt, rd, sa;
6531
    uint32_t op, op1, op2;
6532
    int16_t imm;
6533

    
6534
    /* make sure instructions are on a word boundary */
6535
    if (ctx->pc & 0x3) {
6536
        env->CP0_BadVAddr = ctx->pc;
6537
        generate_exception(ctx, EXCP_AdEL);
6538
        return;
6539
    }
6540

    
6541
    /* Handle blikely not taken case */
6542
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6543
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6544
        int l1 = gen_new_label();
6545

    
6546
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6547
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6548
        tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), l1);
6549
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6550
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6551
        gen_set_label(l1);
6552
    }
6553
    op = MASK_OP_MAJOR(ctx->opcode);
6554
    rs = (ctx->opcode >> 21) & 0x1f;
6555
    rt = (ctx->opcode >> 16) & 0x1f;
6556
    rd = (ctx->opcode >> 11) & 0x1f;
6557
    sa = (ctx->opcode >> 6) & 0x1f;
6558
    imm = (int16_t)ctx->opcode;
6559
    switch (op) {
6560
    case OPC_SPECIAL:
6561
        op1 = MASK_SPECIAL(ctx->opcode);
6562
        switch (op1) {
6563
        case OPC_SLL:          /* Arithmetic with immediate */
6564
        case OPC_SRL ... OPC_SRA:
6565
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6566
            break;
6567
        case OPC_MOVZ ... OPC_MOVN:
6568
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6569
        case OPC_SLLV:         /* Arithmetic */
6570
        case OPC_SRLV ... OPC_SRAV:
6571
        case OPC_ADD ... OPC_NOR:
6572
        case OPC_SLT ... OPC_SLTU:
6573
            gen_arith(env, ctx, op1, rd, rs, rt);
6574
            break;
6575
        case OPC_MULT ... OPC_DIVU:
6576
            if (sa) {
6577
                check_insn(env, ctx, INSN_VR54XX);
6578
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6579
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6580
            } else
6581
                gen_muldiv(ctx, op1, rs, rt);
6582
            break;
6583
        case OPC_JR ... OPC_JALR:
6584
            gen_compute_branch(ctx, op1, rs, rd, sa);
6585
            return;
6586
        case OPC_TGE ... OPC_TEQ: /* Traps */
6587
        case OPC_TNE:
6588
            gen_trap(ctx, op1, rs, rt, -1);
6589
            break;
6590
        case OPC_MFHI:          /* Move from HI/LO */
6591
        case OPC_MFLO:
6592
            gen_HILO(ctx, op1, rd);
6593
            break;
6594
        case OPC_MTHI:
6595
        case OPC_MTLO:          /* Move to HI/LO */
6596
            gen_HILO(ctx, op1, rs);
6597
            break;
6598
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6599
#ifdef MIPS_STRICT_STANDARD
6600
            MIPS_INVAL("PMON / selsl");
6601
            generate_exception(ctx, EXCP_RI);
6602
#else
6603
            gen_op_pmon(sa);
6604
#endif
6605
            break;
6606
        case OPC_SYSCALL:
6607
            generate_exception(ctx, EXCP_SYSCALL);
6608
            break;
6609
        case OPC_BREAK:
6610
            generate_exception(ctx, EXCP_BREAK);
6611
            break;
6612
        case OPC_SPIM:
6613
#ifdef MIPS_STRICT_STANDARD
6614
            MIPS_INVAL("SPIM");
6615
            generate_exception(ctx, EXCP_RI);
6616
#else
6617
           /* Implemented as RI exception for now. */
6618
            MIPS_INVAL("spim (unofficial)");
6619
            generate_exception(ctx, EXCP_RI);
6620
#endif
6621
            break;
6622
        case OPC_SYNC:
6623
            /* Treat as NOP. */
6624
            break;
6625

    
6626
        case OPC_MOVCI:
6627
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6628
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6629
                save_cpu_state(ctx, 1);
6630
                check_cp1_enabled(ctx);
6631
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6632
                          (ctx->opcode >> 16) & 1);
6633
            } else {
6634
                generate_exception_err(ctx, EXCP_CpU, 1);
6635
            }
6636
            break;
6637

    
6638
#if defined(TARGET_MIPS64)
6639
       /* MIPS64 specific opcodes */
6640
        case OPC_DSLL:
6641
        case OPC_DSRL ... OPC_DSRA:
6642
        case OPC_DSLL32:
6643
        case OPC_DSRL32 ... OPC_DSRA32:
6644
            check_insn(env, ctx, ISA_MIPS3);
6645
            check_mips_64(ctx);
6646
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6647
            break;
6648
        case OPC_DSLLV:
6649
        case OPC_DSRLV ... OPC_DSRAV:
6650
        case OPC_DADD ... OPC_DSUBU:
6651
            check_insn(env, ctx, ISA_MIPS3);
6652
            check_mips_64(ctx);
6653
            gen_arith(env, ctx, op1, rd, rs, rt);
6654
            break;
6655
        case OPC_DMULT ... OPC_DDIVU:
6656
            check_insn(env, ctx, ISA_MIPS3);
6657
            check_mips_64(ctx);
6658
            gen_muldiv(ctx, op1, rs, rt);
6659
            break;
6660
#endif
6661
        default:            /* Invalid */
6662
            MIPS_INVAL("special");
6663
            generate_exception(ctx, EXCP_RI);
6664
            break;
6665
        }
6666
        break;
6667
    case OPC_SPECIAL2:
6668
        op1 = MASK_SPECIAL2(ctx->opcode);
6669
        switch (op1) {
6670
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6671
        case OPC_MSUB ... OPC_MSUBU:
6672
            check_insn(env, ctx, ISA_MIPS32);
6673
            gen_muldiv(ctx, op1, rs, rt);
6674
            break;
6675
        case OPC_MUL:
6676
            gen_arith(env, ctx, op1, rd, rs, rt);
6677
            break;
6678
        case OPC_CLZ ... OPC_CLO:
6679
            check_insn(env, ctx, ISA_MIPS32);
6680
            gen_cl(ctx, op1, rd, rs);
6681
            break;
6682
        case OPC_SDBBP:
6683
            /* XXX: not clear which exception should be raised
6684
             *      when in debug mode...
6685
             */
6686
            check_insn(env, ctx, ISA_MIPS32);
6687
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6688
                generate_exception(ctx, EXCP_DBp);
6689
            } else {
6690
                generate_exception(ctx, EXCP_DBp);
6691
            }
6692
            /* Treat as NOP. */
6693
            break;
6694
#if defined(TARGET_MIPS64)
6695
        case OPC_DCLZ ... OPC_DCLO:
6696
            check_insn(env, ctx, ISA_MIPS64);
6697
            check_mips_64(ctx);
6698
            gen_cl(ctx, op1, rd, rs);
6699
            break;
6700
#endif
6701
        default:            /* Invalid */
6702
            MIPS_INVAL("special2");
6703
            generate_exception(ctx, EXCP_RI);
6704
            break;
6705
        }
6706
        break;
6707
    case OPC_SPECIAL3:
6708
         op1 = MASK_SPECIAL3(ctx->opcode);
6709
         switch (op1) {
6710
         case OPC_EXT:
6711
         case OPC_INS:
6712
             check_insn(env, ctx, ISA_MIPS32R2);
6713
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6714
             break;
6715
         case OPC_BSHFL:
6716
             check_insn(env, ctx, ISA_MIPS32R2);
6717
             op2 = MASK_BSHFL(ctx->opcode);
6718
             switch (op2) {
6719
             case OPC_WSBH:
6720
                 gen_load_gpr(cpu_T[1], rt);
6721
                 gen_op_wsbh();
6722
                 break;
6723
             case OPC_SEB:
6724
                 gen_load_gpr(cpu_T[1], rt);
6725
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6726
                 break;
6727
             case OPC_SEH:
6728
                 gen_load_gpr(cpu_T[1], rt);
6729
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6730
                 break;
6731
             default:            /* Invalid */
6732
                 MIPS_INVAL("bshfl");
6733
                 generate_exception(ctx, EXCP_RI);
6734
                 break;
6735
            }
6736
            gen_store_gpr(cpu_T[0], rd);
6737
            break;
6738
        case OPC_RDHWR:
6739
            check_insn(env, ctx, ISA_MIPS32R2);
6740
            switch (rd) {
6741
            case 0:
6742
                save_cpu_state(ctx, 1);
6743
                gen_op_rdhwr_cpunum();
6744
                break;
6745
            case 1:
6746
                save_cpu_state(ctx, 1);
6747
                gen_op_rdhwr_synci_step();
6748
                break;
6749
            case 2:
6750
                save_cpu_state(ctx, 1);
6751
                gen_op_rdhwr_cc();
6752
                break;
6753
            case 3:
6754
                save_cpu_state(ctx, 1);
6755
                gen_op_rdhwr_ccres();
6756
                break;
6757
            case 29:
6758
#if defined (CONFIG_USER_ONLY)
6759
                gen_op_tls_value();
6760
                break;
6761
#endif
6762
            default:            /* Invalid */
6763
                MIPS_INVAL("rdhwr");
6764
                generate_exception(ctx, EXCP_RI);
6765
                break;
6766
            }
6767
            gen_store_gpr(cpu_T[0], rt);
6768
            break;
6769
        case OPC_FORK:
6770
            check_insn(env, ctx, ASE_MT);
6771
            gen_load_gpr(cpu_T[0], rt);
6772
            gen_load_gpr(cpu_T[1], rs);
6773
            gen_op_fork();
6774
            break;
6775
        case OPC_YIELD:
6776
            check_insn(env, ctx, ASE_MT);
6777
            gen_load_gpr(cpu_T[0], rs);
6778
            gen_op_yield();
6779
            gen_store_gpr(cpu_T[0], rd);
6780
            break;
6781
#if defined(TARGET_MIPS64)
6782
        case OPC_DEXTM ... OPC_DEXT:
6783
        case OPC_DINSM ... OPC_DINS:
6784
            check_insn(env, ctx, ISA_MIPS64R2);
6785
            check_mips_64(ctx);
6786
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6787
            break;
6788
        case OPC_DBSHFL:
6789
            check_insn(env, ctx, ISA_MIPS64R2);
6790
            check_mips_64(ctx);
6791
            op2 = MASK_DBSHFL(ctx->opcode);
6792
            switch (op2) {
6793
            case OPC_DSBH:
6794
                gen_load_gpr(cpu_T[1], rt);
6795
                gen_op_dsbh();
6796
                break;
6797
            case OPC_DSHD:
6798
                gen_load_gpr(cpu_T[1], rt);
6799
                gen_op_dshd();
6800
                break;
6801
            default:            /* Invalid */
6802
                MIPS_INVAL("dbshfl");
6803
                generate_exception(ctx, EXCP_RI);
6804
                break;
6805
            }
6806
            gen_store_gpr(cpu_T[0], rd);
6807
            break;
6808
#endif
6809
        default:            /* Invalid */
6810
            MIPS_INVAL("special3");
6811
            generate_exception(ctx, EXCP_RI);
6812
            break;
6813
        }
6814
        break;
6815
    case OPC_REGIMM:
6816
        op1 = MASK_REGIMM(ctx->opcode);
6817
        switch (op1) {
6818
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6819
        case OPC_BLTZAL ... OPC_BGEZALL:
6820
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6821
            return;
6822
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6823
        case OPC_TNEI:
6824
            gen_trap(ctx, op1, rs, -1, imm);
6825
            break;
6826
        case OPC_SYNCI:
6827
            check_insn(env, ctx, ISA_MIPS32R2);
6828
            /* Treat as NOP. */
6829
            break;
6830
        default:            /* Invalid */
6831
            MIPS_INVAL("regimm");
6832
            generate_exception(ctx, EXCP_RI);
6833
            break;
6834
        }
6835
        break;
6836
    case OPC_CP0:
6837
        check_cp0_enabled(ctx);
6838
        op1 = MASK_CP0(ctx->opcode);
6839
        switch (op1) {
6840
        case OPC_MFC0:
6841
        case OPC_MTC0:
6842
        case OPC_MFTR:
6843
        case OPC_MTTR:
6844
#if defined(TARGET_MIPS64)
6845
        case OPC_DMFC0:
6846
        case OPC_DMTC0:
6847
#endif
6848
            gen_cp0(env, ctx, op1, rt, rd);
6849
            break;
6850
        case OPC_C0_FIRST ... OPC_C0_LAST:
6851
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6852
            break;
6853
        case OPC_MFMC0:
6854
            op2 = MASK_MFMC0(ctx->opcode);
6855
            switch (op2) {
6856
            case OPC_DMT:
6857
                check_insn(env, ctx, ASE_MT);
6858
                gen_op_dmt();
6859
                break;
6860
            case OPC_EMT:
6861
                check_insn(env, ctx, ASE_MT);
6862
                gen_op_emt();
6863
                break;
6864
            case OPC_DVPE:
6865
                check_insn(env, ctx, ASE_MT);
6866
                gen_op_dvpe();
6867
                break;
6868
            case OPC_EVPE:
6869
                check_insn(env, ctx, ASE_MT);
6870
                gen_op_evpe();
6871
                break;
6872
            case OPC_DI:
6873
                check_insn(env, ctx, ISA_MIPS32R2);
6874
                save_cpu_state(ctx, 1);
6875
                gen_op_di();
6876
                /* Stop translation as we may have switched the execution mode */
6877
                ctx->bstate = BS_STOP;
6878
                break;
6879
            case OPC_EI:
6880
                check_insn(env, ctx, ISA_MIPS32R2);
6881
                save_cpu_state(ctx, 1);
6882
                gen_op_ei();
6883
                /* Stop translation as we may have switched the execution mode */
6884
                ctx->bstate = BS_STOP;
6885
                break;
6886
            default:            /* Invalid */
6887
                MIPS_INVAL("mfmc0");
6888
                generate_exception(ctx, EXCP_RI);
6889
                break;
6890
            }
6891
            gen_store_gpr(cpu_T[0], rt);
6892
            break;
6893
        case OPC_RDPGPR:
6894
            check_insn(env, ctx, ISA_MIPS32R2);
6895
            gen_load_srsgpr(cpu_T[0], rt);
6896
            gen_store_gpr(cpu_T[0], rd);
6897
            break;
6898
        case OPC_WRPGPR:
6899
            check_insn(env, ctx, ISA_MIPS32R2);
6900
            gen_load_gpr(cpu_T[0], rt);
6901
            gen_store_srsgpr(cpu_T[0], rd);
6902
            break;
6903
        default:
6904
            MIPS_INVAL("cp0");
6905
            generate_exception(ctx, EXCP_RI);
6906
            break;
6907
        }
6908
        break;
6909
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6910
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6911
         break;
6912
    case OPC_J ... OPC_JAL: /* Jump */
6913
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6914
         gen_compute_branch(ctx, op, rs, rt, offset);
6915
         return;
6916
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6917
    case OPC_BEQL ... OPC_BGTZL:
6918
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6919
         return;
6920
    case OPC_LB ... OPC_LWR: /* Load and stores */
6921
    case OPC_SB ... OPC_SW:
6922
    case OPC_SWR:
6923
    case OPC_LL:
6924
    case OPC_SC:
6925
         gen_ldst(ctx, op, rt, rs, imm);
6926
         break;
6927
    case OPC_CACHE:
6928
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6929
        /* Treat as NOP. */
6930
        break;
6931
    case OPC_PREF:
6932
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6933
        /* Treat as NOP. */
6934
        break;
6935

    
6936
    /* Floating point (COP1). */
6937
    case OPC_LWC1:
6938
    case OPC_LDC1:
6939
    case OPC_SWC1:
6940
    case OPC_SDC1:
6941
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6942
            save_cpu_state(ctx, 1);
6943
            check_cp1_enabled(ctx);
6944
            gen_flt_ldst(ctx, op, rt, rs, imm);
6945
        } else {
6946
            generate_exception_err(ctx, EXCP_CpU, 1);
6947
        }
6948
        break;
6949

    
6950
    case OPC_CP1:
6951
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6952
            save_cpu_state(ctx, 1);
6953
            check_cp1_enabled(ctx);
6954
            op1 = MASK_CP1(ctx->opcode);
6955
            switch (op1) {
6956
            case OPC_MFHC1:
6957
            case OPC_MTHC1:
6958
                check_insn(env, ctx, ISA_MIPS32R2);
6959
            case OPC_MFC1:
6960
            case OPC_CFC1:
6961
            case OPC_MTC1:
6962
            case OPC_CTC1:
6963
                gen_cp1(ctx, op1, rt, rd);
6964
                break;
6965
#if defined(TARGET_MIPS64)
6966
            case OPC_DMFC1:
6967
            case OPC_DMTC1:
6968
                check_insn(env, ctx, ISA_MIPS3);
6969
                gen_cp1(ctx, op1, rt, rd);
6970
                break;
6971
#endif
6972
            case OPC_BC1ANY2:
6973
            case OPC_BC1ANY4:
6974
                check_cop1x(ctx);
6975
                check_insn(env, ctx, ASE_MIPS3D);
6976
                /* fall through */
6977
            case OPC_BC1:
6978
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6979
                                    (rt >> 2) & 0x7, imm << 2);
6980
                return;
6981
            case OPC_S_FMT:
6982
            case OPC_D_FMT:
6983
            case OPC_W_FMT:
6984
            case OPC_L_FMT:
6985
            case OPC_PS_FMT:
6986
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6987
                           (imm >> 8) & 0x7);
6988
                break;
6989
            default:
6990
                MIPS_INVAL("cp1");
6991
                generate_exception (ctx, EXCP_RI);
6992
                break;
6993
            }
6994
        } else {
6995
            generate_exception_err(ctx, EXCP_CpU, 1);
6996
        }
6997
        break;
6998

    
6999
    /* COP2.  */
7000
    case OPC_LWC2:
7001
    case OPC_LDC2:
7002
    case OPC_SWC2:
7003
    case OPC_SDC2:
7004
    case OPC_CP2:
7005
        /* COP2: Not implemented. */
7006
        generate_exception_err(ctx, EXCP_CpU, 2);
7007
        break;
7008

    
7009
    case OPC_CP3:
7010
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7011
            save_cpu_state(ctx, 1);
7012
            check_cp1_enabled(ctx);
7013
            op1 = MASK_CP3(ctx->opcode);
7014
            switch (op1) {
7015
            case OPC_LWXC1:
7016
            case OPC_LDXC1:
7017
            case OPC_LUXC1:
7018
            case OPC_SWXC1:
7019
            case OPC_SDXC1:
7020
            case OPC_SUXC1:
7021
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7022
                break;
7023
            case OPC_PREFX:
7024
                /* Treat as NOP. */
7025
                break;
7026
            case OPC_ALNV_PS:
7027
            case OPC_MADD_S:
7028
            case OPC_MADD_D:
7029
            case OPC_MADD_PS:
7030
            case OPC_MSUB_S:
7031
            case OPC_MSUB_D:
7032
            case OPC_MSUB_PS:
7033
            case OPC_NMADD_S:
7034
            case OPC_NMADD_D:
7035
            case OPC_NMADD_PS:
7036
            case OPC_NMSUB_S:
7037
            case OPC_NMSUB_D:
7038
            case OPC_NMSUB_PS:
7039
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7040
                break;
7041
            default:
7042
                MIPS_INVAL("cp3");
7043
                generate_exception (ctx, EXCP_RI);
7044
                break;
7045
            }
7046
        } else {
7047
            generate_exception_err(ctx, EXCP_CpU, 1);
7048
        }
7049
        break;
7050

    
7051
#if defined(TARGET_MIPS64)
7052
    /* MIPS64 opcodes */
7053
    case OPC_LWU:
7054
    case OPC_LDL ... OPC_LDR:
7055
    case OPC_SDL ... OPC_SDR:
7056
    case OPC_LLD:
7057
    case OPC_LD:
7058
    case OPC_SCD:
7059
    case OPC_SD:
7060
        check_insn(env, ctx, ISA_MIPS3);
7061
        check_mips_64(ctx);
7062
        gen_ldst(ctx, op, rt, rs, imm);
7063
        break;
7064
    case OPC_DADDI ... OPC_DADDIU:
7065
        check_insn(env, ctx, ISA_MIPS3);
7066
        check_mips_64(ctx);
7067
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7068
        break;
7069
#endif
7070
    case OPC_JALX:
7071
        check_insn(env, ctx, ASE_MIPS16);
7072
        /* MIPS16: Not implemented. */
7073
    case OPC_MDMX:
7074
        check_insn(env, ctx, ASE_MDMX);
7075
        /* MDMX: Not implemented. */
7076
    default:            /* Invalid */
7077
        MIPS_INVAL("major opcode");
7078
        generate_exception(ctx, EXCP_RI);
7079
        break;
7080
    }
7081
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7082
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7083
        /* Branches completion */
7084
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7085
        ctx->bstate = BS_BRANCH;
7086
        save_cpu_state(ctx, 0);
7087
        switch (hflags) {
7088
        case MIPS_HFLAG_B:
7089
            /* unconditional branch */
7090
            MIPS_DEBUG("unconditional branch");
7091
            gen_goto_tb(ctx, 0, ctx->btarget);
7092
            break;
7093
        case MIPS_HFLAG_BL:
7094
            /* blikely taken case */
7095
            MIPS_DEBUG("blikely branch taken");
7096
            gen_goto_tb(ctx, 0, ctx->btarget);
7097
            break;
7098
        case MIPS_HFLAG_BC:
7099
            /* Conditional branch */
7100
            MIPS_DEBUG("conditional branch");
7101
            {
7102
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7103
                int l1 = gen_new_label();
7104

    
7105
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7106
                tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), l1);
7107
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7108
                gen_set_label(l1);
7109
                gen_goto_tb(ctx, 0, ctx->btarget);
7110
            }
7111
            break;
7112
        case MIPS_HFLAG_BR:
7113
            /* unconditional branch to register */
7114
            MIPS_DEBUG("branch to register");
7115
            gen_breg_pc();
7116
            tcg_gen_exit_tb(0);
7117
            break;
7118
        default:
7119
            MIPS_DEBUG("unknown branch");
7120
            break;
7121
        }
7122
    }
7123
}
7124

    
7125
static always_inline int
7126
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7127
                                int search_pc)
7128
{
7129
    DisasContext ctx;
7130
    target_ulong pc_start;
7131
    uint16_t *gen_opc_end;
7132
    int j, lj = -1;
7133

    
7134
    if (search_pc && loglevel)
7135
        fprintf (logfile, "search pc %d\n", search_pc);
7136

    
7137
    num_temps = 0;
7138
    memset(temps, 0, sizeof(temps));
7139

    
7140
    num_temps = 0;
7141
    memset(temps, 0, sizeof(temps));
7142

    
7143
    pc_start = tb->pc;
7144
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7145
    ctx.pc = pc_start;
7146
    ctx.saved_pc = -1;
7147
    ctx.tb = tb;
7148
    ctx.bstate = BS_NONE;
7149
    /* Restore delay slot state from the tb context.  */
7150
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7151
    restore_cpu_state(env, &ctx);
7152
#if defined(CONFIG_USER_ONLY)
7153
    ctx.mem_idx = MIPS_HFLAG_UM;
7154
#else
7155
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7156
#endif
7157
#ifdef DEBUG_DISAS
7158
    if (loglevel & CPU_LOG_TB_CPU) {
7159
        fprintf(logfile, "------------------------------------------------\n");
7160
        /* FIXME: This may print out stale hflags from env... */
7161
        cpu_dump_state(env, logfile, fprintf, 0);
7162
    }
7163
#endif
7164
#ifdef MIPS_DEBUG_DISAS
7165
    if (loglevel & CPU_LOG_TB_IN_ASM)
7166
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7167
                tb, ctx.mem_idx, ctx.hflags);
7168
#endif
7169
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7170
        if (env->nb_breakpoints > 0) {
7171
            for(j = 0; j < env->nb_breakpoints; j++) {
7172
                if (env->breakpoints[j] == ctx.pc) {
7173
                    save_cpu_state(&ctx, 1);
7174
                    ctx.bstate = BS_BRANCH;
7175
                    gen_op_debug();
7176
                    /* Include the breakpoint location or the tb won't
7177
                     * be flushed when it must be.  */
7178
                    ctx.pc += 4;
7179
                    goto done_generating;
7180
                }
7181
            }
7182
        }
7183

    
7184
        if (search_pc) {
7185
            j = gen_opc_ptr - gen_opc_buf;
7186
            if (lj < j) {
7187
                lj++;
7188
                while (lj < j)
7189
                    gen_opc_instr_start[lj++] = 0;
7190
            }
7191
            gen_opc_pc[lj] = ctx.pc;
7192
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7193
            gen_opc_instr_start[lj] = 1;
7194
        }
7195
        ctx.opcode = ldl_code(ctx.pc);
7196
        decode_opc(env, &ctx);
7197
        if (num_temps) {
7198
            fprintf(stderr,
7199
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7200
                    ctx.pc);
7201
            num_temps = 0;
7202
        }
7203
        ctx.pc += 4;
7204

    
7205
        if (env->singlestep_enabled)
7206
            break;
7207

    
7208
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7209
            break;
7210

    
7211
#if defined (MIPS_SINGLE_STEP)
7212
        break;
7213
#endif
7214
    }
7215
    if (env->singlestep_enabled) {
7216
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7217
        gen_op_debug();
7218
    } else {
7219
        switch (ctx.bstate) {
7220
        case BS_STOP:
7221
            tcg_gen_helper_0_0(do_interrupt_restart);
7222
            gen_goto_tb(&ctx, 0, ctx.pc);
7223
            break;
7224
        case BS_NONE:
7225
            save_cpu_state(&ctx, 0);
7226
            gen_goto_tb(&ctx, 0, ctx.pc);
7227
            break;
7228
        case BS_EXCP:
7229
            tcg_gen_helper_0_0(do_interrupt_restart);
7230
            tcg_gen_exit_tb(0);
7231
            break;
7232
        case BS_BRANCH:
7233
        default:
7234
            break;
7235
        }
7236
    }
7237
done_generating:
7238
    *gen_opc_ptr = INDEX_op_end;
7239
    if (search_pc) {
7240
        j = gen_opc_ptr - gen_opc_buf;
7241
        lj++;
7242
        while (lj <= j)
7243
            gen_opc_instr_start[lj++] = 0;
7244
    } else {
7245
        tb->size = ctx.pc - pc_start;
7246
    }
7247
#ifdef DEBUG_DISAS
7248
#if defined MIPS_DEBUG_DISAS
7249
    if (loglevel & CPU_LOG_TB_IN_ASM)
7250
        fprintf(logfile, "\n");
7251
#endif
7252
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7253
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7254
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7255
        fprintf(logfile, "\n");
7256
    }
7257
    if (loglevel & CPU_LOG_TB_CPU) {
7258
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7259
    }
7260
#endif
7261

    
7262
    return 0;
7263
}
7264

    
7265
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7266
{
7267
    return gen_intermediate_code_internal(env, tb, 0);
7268
}
7269

    
7270
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7271
{
7272
    return gen_intermediate_code_internal(env, tb, 1);
7273
}
7274

    
7275
void fpu_dump_state(CPUState *env, FILE *f,
7276
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7277
                    int flags)
7278
{
7279
    int i;
7280
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7281

    
7282
#define printfpr(fp)                                                        \
7283
    do {                                                                    \
7284
        if (is_fpu64)                                                       \
7285
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7286
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7287
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7288
        else {                                                              \
7289
            fpr_t tmp;                                                      \
7290
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7291
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7292
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7293
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7294
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7295
        }                                                                   \
7296
    } while(0)
7297

    
7298

    
7299
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7300
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7301
                get_float_exception_flags(&env->fpu->fp_status));
7302
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7303
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7304
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7305
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7306
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7307
        printfpr(&env->fpu->fpr[i]);
7308
    }
7309

    
7310
#undef printfpr
7311
}
7312

    
7313
void dump_fpu (CPUState *env)
7314
{
7315
    if (loglevel) {
7316
        fprintf(logfile,
7317
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7318
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7319
                " %04x\n",
7320
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7321
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7322
                env->bcond);
7323
       fpu_dump_state(env, logfile, fprintf, 0);
7324
    }
7325
}
7326

    
7327
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7328
/* Debug help: The architecture requires 32bit code to maintain proper
7329
   sign-extened values on 64bit machines.  */
7330

    
7331
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7332

    
7333
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7334
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7335
                     int flags)
7336
{
7337
    int i;
7338

    
7339
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7340
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7341
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7342
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7343
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7344
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7345
    if (!SIGN_EXT_P(env->btarget))
7346
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7347

    
7348
    for (i = 0; i < 32; i++) {
7349
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7350
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7351
    }
7352

    
7353
    if (!SIGN_EXT_P(env->CP0_EPC))
7354
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7355
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7356
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7357
}
7358
#endif
7359

    
7360
void cpu_dump_state (CPUState *env, FILE *f,
7361
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7362
                     int flags)
7363
{
7364
    int i;
7365

    
7366
    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",
7367
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7368
    for (i = 0; i < 32; i++) {
7369
        if ((i & 3) == 0)
7370
            cpu_fprintf(f, "GPR%02d:", i);
7371
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7372
        if ((i & 3) == 3)
7373
            cpu_fprintf(f, "\n");
7374
    }
7375

    
7376
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7377
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7378
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7379
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7380
    if (env->hflags & MIPS_HFLAG_FPU)
7381
        fpu_dump_state(env, f, cpu_fprintf, flags);
7382
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7383
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7384
#endif
7385
}
7386

    
7387
static void mips_tcg_init(void)
7388
{
7389
    static int inited;
7390

    
7391
    /* Initialize various static tables. */
7392
    if (inited)
7393
        return;
7394

    
7395
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7396
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7397
                                         TCG_AREG0,
7398
                                         offsetof(CPUState, current_tc_gprs),
7399
                                         "current_tc_gprs");
7400
#if TARGET_LONG_BITS > HOST_LONG_BITS
7401
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7402
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7403
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7404
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7405
#else
7406
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7407
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7408
#endif
7409

    
7410
    inited = 1;
7411
}
7412

    
7413
#include "translate_init.c"
7414

    
7415
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7416
{
7417
    CPUMIPSState *env;
7418
    const mips_def_t *def;
7419

    
7420
    def = cpu_mips_find_by_name(cpu_model);
7421
    if (!def)
7422
        return NULL;
7423
    env = qemu_mallocz(sizeof(CPUMIPSState));
7424
    if (!env)
7425
        return NULL;
7426
    env->cpu_model = def;
7427

    
7428
    cpu_exec_init(env);
7429
    env->cpu_model_str = cpu_model;
7430
    mips_tcg_init();
7431
    cpu_reset(env);
7432
    return env;
7433
}
7434

    
7435
void cpu_reset (CPUMIPSState *env)
7436
{
7437
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7438

    
7439
    tlb_flush(env, 1);
7440

    
7441
    /* Minimal init */
7442
#if !defined(CONFIG_USER_ONLY)
7443
    if (env->hflags & MIPS_HFLAG_BMASK) {
7444
        /* If the exception was raised from a delay slot,
7445
         * come back to the jump.  */
7446
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7447
    } else {
7448
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7449
    }
7450
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7451
    env->CP0_Wired = 0;
7452
    /* SMP not implemented */
7453
    env->CP0_EBase = 0x80000000;
7454
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7455
    /* vectored interrupts not implemented, timer on int 7,
7456
       no performance counters. */
7457
    env->CP0_IntCtl = 0xe0000000;
7458
    {
7459
        int i;
7460

    
7461
        for (i = 0; i < 7; i++) {
7462
            env->CP0_WatchLo[i] = 0;
7463
            env->CP0_WatchHi[i] = 0x80000000;
7464
        }
7465
        env->CP0_WatchLo[7] = 0;
7466
        env->CP0_WatchHi[7] = 0;
7467
    }
7468
    /* Count register increments in debug mode, EJTAG version 1 */
7469
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7470
#endif
7471
    env->exception_index = EXCP_NONE;
7472
#if defined(CONFIG_USER_ONLY)
7473
    env->hflags = MIPS_HFLAG_UM;
7474
    env->user_mode_only = 1;
7475
#else
7476
    env->hflags = MIPS_HFLAG_CP0;
7477
#endif
7478
    cpu_mips_register(env, env->cpu_model);
7479
}
7480

    
7481
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7482
                unsigned long searched_pc, int pc_pos, void *puc)
7483
{
7484
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7485
    env->hflags &= ~MIPS_HFLAG_BMASK;
7486
    env->hflags |= gen_opc_hflags[pc_pos];
7487
}