Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 30898801

History | View | Annotate | Download (215.2 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
/* General purpose registers moves */
469
const unsigned char *regnames[] =
470
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
471
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
472
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
473
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
474

    
475
static inline void gen_op_load_gpr_TN(int t_index, int reg)
476
{
477
    tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
478
}
479

    
480
static inline void gen_op_load_gpr_T0(int reg)
481
{
482
    gen_op_load_gpr_TN(0, reg);
483
}
484

    
485
static inline void gen_op_load_gpr_T1(int reg)
486
{
487
    gen_op_load_gpr_TN(1, reg);
488
}
489

    
490
static inline void gen_op_store_gpr_TN(int t_index, int reg)
491
{
492
    tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
493
}
494

    
495
static inline void gen_op_store_gpr_T0(int reg)
496
{
497
    gen_op_store_gpr_TN(0, reg);
498
}
499

    
500
static inline void gen_op_store_gpr_T1(int reg)
501
{
502
    gen_op_store_gpr_TN(1, reg);
503
}
504

    
505
/* Moves to/from shadow registers */
506
static inline void gen_op_load_srsgpr_T0(int reg)
507
{
508
    TCGv r_tmp = new_tmp();
509

    
510
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
511
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
512
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
513
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
514
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
515

    
516
    tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
517
    dead_tmp(r_tmp);
518
}
519

    
520
static inline void gen_op_store_srsgpr_T0(int reg)
521
{
522
    TCGv r_tmp = new_tmp();
523

    
524
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
525
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
526
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
527
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
528
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
529

    
530
    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
531
    dead_tmp(r_tmp);
532
}
533

    
534
/* Load immediates, zero being a special case. */
535
static inline void gen_op_set_T0(target_ulong arg)
536
{
537
    tcg_gen_movi_tl(cpu_T[0], arg);
538
}
539

    
540
static inline void gen_op_set_T1(target_ulong arg)
541
{
542
    tcg_gen_movi_tl(cpu_T[1], arg);
543
}
544

    
545
static inline void gen_op_reset_T0(void)
546
{
547
    tcg_gen_movi_tl(cpu_T[0], 0);
548
}
549

    
550
static inline void gen_op_reset_T1(void)
551
{
552
    tcg_gen_movi_tl(cpu_T[1], 0);
553
}
554

    
555
/* Moves to/from HI/LO registers. */
556
static inline void gen_op_load_HI(int reg)
557
{
558
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
559
}
560

    
561
static inline void gen_op_store_HI(int reg)
562
{
563
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
564
}
565

    
566
static inline void gen_op_load_LO(int reg)
567
{
568
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
569
}
570

    
571
static inline void gen_op_store_LO(int reg)
572
{
573
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
574
}
575

    
576

    
577
/* Floating point register moves. */
578
static const char *fregnames[] =
579
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
580
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
581
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
582
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
583

    
584
#define FGEN32(func, NAME)                       \
585
static GenOpFunc *NAME ## _table [32] = {        \
586
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
587
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
588
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
589
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
590
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
591
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
592
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
593
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
594
};                                               \
595
static always_inline void func(int n)            \
596
{                                                \
597
    NAME ## _table[n]();                         \
598
}
599

    
600
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
601
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
602

    
603
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
604
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
605

    
606
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
607
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
608

    
609
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
610
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
611

    
612
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
613
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
614

    
615
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
616
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
617

    
618
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
619
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
620

    
621
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
622
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
623

    
624
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
625
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
626

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

    
651
FOP_CONDS(, d)
652
FOP_CONDS(abs, d)
653
FOP_CONDS(, s)
654
FOP_CONDS(abs, s)
655
FOP_CONDS(, ps)
656
FOP_CONDS(abs, ps)
657

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

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

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

    
716

    
717
typedef struct DisasContext {
718
    struct TranslationBlock *tb;
719
    target_ulong pc, saved_pc;
720
    uint32_t opcode;
721
    uint32_t fp_status;
722
    /* Routine used to access memory */
723
    int mem_idx;
724
    uint32_t hflags, saved_hflags;
725
    int bstate;
726
    target_ulong btarget;
727
    void *last_T0_store;
728
    int last_T0_gpr;
729
} DisasContext;
730

    
731
enum {
732
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
733
                      * exception condition
734
                      */
735
    BS_STOP     = 1, /* We want to stop translation for any reason */
736
    BS_BRANCH   = 2, /* We reached a branch condition     */
737
    BS_EXCP     = 3, /* We reached an exception condition */
738
};
739

    
740
#ifdef MIPS_DEBUG_DISAS
741
#define MIPS_DEBUG(fmt, args...)                                              \
742
do {                                                                          \
743
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
744
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
745
                ctx->pc, ctx->opcode , ##args);                               \
746
    }                                                                         \
747
} while (0)
748
#else
749
#define MIPS_DEBUG(fmt, args...) do { } while(0)
750
#endif
751

    
752
#define MIPS_INVAL(op)                                                        \
753
do {                                                                          \
754
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
755
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
756
} while (0)
757

    
758
#define GEN_LOAD_REG_T0(Rn)                                                   \
759
do {                                                                          \
760
    if (Rn == 0) {                                                            \
761
        gen_op_reset_T0();                                                    \
762
    } else {                                                                  \
763
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
764
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
765
                gen_op_load_gpr_T0(Rn);                                       \
766
        }                                                                     \
767
    }                                                                         \
768
} while (0)
769

    
770
#define GEN_LOAD_REG_T1(Rn)                                                   \
771
do {                                                                          \
772
    if (Rn == 0) {                                                            \
773
        gen_op_reset_T1();                                                    \
774
    } else {                                                                  \
775
        gen_op_load_gpr_T1(Rn);                                               \
776
    }                                                                         \
777
} while (0)
778

    
779
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
780
do {                                                                          \
781
    if (Rn == 0) {                                                            \
782
        glue(gen_op_reset_, Tn)();                                            \
783
    } else {                                                                  \
784
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
785
    }                                                                         \
786
} while (0)
787

    
788
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
789
do {                                                                          \
790
    if (Imm == 0) {                                                           \
791
        glue(gen_op_reset_, Tn)();                                            \
792
    } else {                                                                  \
793
        glue(gen_op_set_, Tn)(Imm);                                           \
794
    }                                                                         \
795
} while (0)
796

    
797
#define GEN_STORE_T0_REG(Rn)                                                  \
798
do {                                                                          \
799
    if (Rn != 0) {                                                            \
800
        gen_op_store_gpr_T0(Rn);                                              \
801
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
802
        ctx->glue(last_T0,_gpr) = Rn;                                         \
803
    }                                                                         \
804
} while (0)
805

    
806
#define GEN_STORE_T1_REG(Rn)                                                  \
807
do {                                                                          \
808
    if (Rn != 0)                                                              \
809
        gen_op_store_gpr_T1(Rn);                                              \
810
} while (0)
811

    
812
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
813
do {                                                                          \
814
    if (Rn != 0)                                                              \
815
        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \
816
} while (0)
817

    
818
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
819
do {                                                                          \
820
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
821
} while (0)
822

    
823
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
824
do {                                                                          \
825
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
826
} while (0)
827

    
828
static always_inline void gen_save_pc(target_ulong pc)
829
{
830
#if defined(TARGET_MIPS64)
831
    if (pc == (int32_t)pc) {
832
        gen_op_save_pc(pc);
833
    } else {
834
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
835
    }
836
#else
837
    gen_op_save_pc(pc);
838
#endif
839
}
840

    
841
static always_inline void gen_save_btarget(target_ulong btarget)
842
{
843
#if defined(TARGET_MIPS64)
844
    if (btarget == (int32_t)btarget) {
845
        gen_op_save_btarget(btarget);
846
    } else {
847
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
848
    }
849
#else
850
    gen_op_save_btarget(btarget);
851
#endif
852
}
853

    
854
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
855
{
856
#if defined MIPS_DEBUG_DISAS
857
    if (loglevel & CPU_LOG_TB_IN_ASM) {
858
            fprintf(logfile, "hflags %08x saved %08x\n",
859
                    ctx->hflags, ctx->saved_hflags);
860
    }
861
#endif
862
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
863
        gen_save_pc(ctx->pc);
864
        ctx->saved_pc = ctx->pc;
865
    }
866
    if (ctx->hflags != ctx->saved_hflags) {
867
        gen_op_save_state(ctx->hflags);
868
        ctx->saved_hflags = ctx->hflags;
869
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
870
        case MIPS_HFLAG_BR:
871
            break;
872
        case MIPS_HFLAG_BC:
873
        case MIPS_HFLAG_BL:
874
        case MIPS_HFLAG_B:
875
            gen_save_btarget(ctx->btarget);
876
            break;
877
        }
878
    }
879
}
880

    
881
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
882
{
883
    ctx->saved_hflags = ctx->hflags;
884
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
885
    case MIPS_HFLAG_BR:
886
        break;
887
    case MIPS_HFLAG_BC:
888
    case MIPS_HFLAG_BL:
889
    case MIPS_HFLAG_B:
890
        ctx->btarget = env->btarget;
891
        break;
892
    }
893
}
894

    
895
static always_inline void
896
generate_exception_err (DisasContext *ctx, int excp, int err)
897
{
898
    save_cpu_state(ctx, 1);
899
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
900
    tcg_gen_helper_0_0(do_interrupt_restart);
901
    tcg_gen_exit_tb(0);
902
}
903

    
904
static always_inline void
905
generate_exception (DisasContext *ctx, int excp)
906
{
907
    save_cpu_state(ctx, 1);
908
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
909
    tcg_gen_helper_0_0(do_interrupt_restart);
910
    tcg_gen_exit_tb(0);
911
}
912

    
913
/* Addresses computation */
914
static inline void gen_op_addr_add (void)
915
{
916
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
917

    
918
#if defined(TARGET_MIPS64)
919
    /* For compatibility with 32-bit code, data reference in user mode
920
       with Status_UX = 0 should be casted to 32-bit and sign extended.
921
       See the MIPS64 PRA manual, section 4.10. */
922
    {
923
        TCGv r_tmp = new_tmp();
924
        int l1 = gen_new_label();
925

    
926
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
927
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
928
        tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(MIPS_HFLAG_UM), l1);
929
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
930
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
931
        tcg_gen_brcond_i32(TCG_COND_NE, r_tmp, tcg_const_i32(0), l1);
932
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
933
        gen_set_label(l1);
934
        dead_tmp(r_tmp);
935
    }
936
#endif
937
}
938

    
939
static always_inline void check_cp0_enabled(DisasContext *ctx)
940
{
941
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
942
        generate_exception_err(ctx, EXCP_CpU, 1);
943
}
944

    
945
static always_inline void check_cp1_enabled(DisasContext *ctx)
946
{
947
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
948
        generate_exception_err(ctx, EXCP_CpU, 1);
949
}
950

    
951
/* Verify that the processor is running with COP1X instructions enabled.
952
   This is associated with the nabla symbol in the MIPS32 and MIPS64
953
   opcode tables.  */
954

    
955
static always_inline void check_cop1x(DisasContext *ctx)
956
{
957
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
958
        generate_exception(ctx, EXCP_RI);
959
}
960

    
961
/* Verify that the processor is running with 64-bit floating-point
962
   operations enabled.  */
963

    
964
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
965
{
966
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
967
        generate_exception(ctx, EXCP_RI);
968
}
969

    
970
/*
971
 * Verify if floating point register is valid; an operation is not defined
972
 * if bit 0 of any register specification is set and the FR bit in the
973
 * Status register equals zero, since the register numbers specify an
974
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
975
 * in the Status register equals one, both even and odd register numbers
976
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
977
 *
978
 * Multiple 64 bit wide registers can be checked by calling
979
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
980
 */
981
void check_cp1_registers(DisasContext *ctx, int regs)
982
{
983
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
984
        generate_exception(ctx, EXCP_RI);
985
}
986

    
987
/* This code generates a "reserved instruction" exception if the
988
   CPU does not support the instruction set corresponding to flags. */
989
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
990
{
991
    if (unlikely(!(env->insn_flags & flags)))
992
        generate_exception(ctx, EXCP_RI);
993
}
994

    
995
/* This code generates a "reserved instruction" exception if 64-bit
996
   instructions are not enabled. */
997
static always_inline void check_mips_64(DisasContext *ctx)
998
{
999
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1000
        generate_exception(ctx, EXCP_RI);
1001
}
1002

    
1003
/* load/store instructions. */
1004
#if defined(CONFIG_USER_ONLY)
1005
#define op_ldst(name)        gen_op_##name##_raw()
1006
#define OP_LD_TABLE(width)
1007
#define OP_ST_TABLE(width)
1008
#else
1009
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1010
#define OP_LD_TABLE(width)                                                    \
1011
static GenOpFunc *gen_op_l##width[] = {                                       \
1012
    &gen_op_l##width##_kernel,                                                \
1013
    &gen_op_l##width##_super,                                                 \
1014
    &gen_op_l##width##_user,                                                  \
1015
}
1016
#define OP_ST_TABLE(width)                                                    \
1017
static GenOpFunc *gen_op_s##width[] = {                                       \
1018
    &gen_op_s##width##_kernel,                                                \
1019
    &gen_op_s##width##_super,                                                 \
1020
    &gen_op_s##width##_user,                                                  \
1021
}
1022
#endif
1023

    
1024
#if defined(TARGET_MIPS64)
1025
OP_LD_TABLE(dl);
1026
OP_LD_TABLE(dr);
1027
OP_ST_TABLE(dl);
1028
OP_ST_TABLE(dr);
1029
#endif
1030
OP_LD_TABLE(wl);
1031
OP_LD_TABLE(wr);
1032
OP_ST_TABLE(wl);
1033
OP_ST_TABLE(wr);
1034
OP_LD_TABLE(wc1);
1035
OP_ST_TABLE(wc1);
1036
OP_LD_TABLE(dc1);
1037
OP_ST_TABLE(dc1);
1038
OP_LD_TABLE(uxc1);
1039
OP_ST_TABLE(uxc1);
1040

    
1041
#define OP_LD(insn,fname)                                        \
1042
void inline op_ldst_##insn(DisasContext *ctx)                    \
1043
{                                                                \
1044
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
1045
}
1046
OP_LD(lb,ld8s);
1047
OP_LD(lbu,ld8u);
1048
OP_LD(lh,ld16s);
1049
OP_LD(lhu,ld16u);
1050
OP_LD(lw,ld32s);
1051
#if defined(TARGET_MIPS64)
1052
OP_LD(lwu,ld32u);
1053
OP_LD(ld,ld64);
1054
#endif
1055
#undef OP_LD
1056

    
1057
#define OP_ST(insn,fname)                                        \
1058
void inline op_ldst_##insn(DisasContext *ctx)                    \
1059
{                                                                \
1060
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
1061
}
1062
OP_ST(sb,st8);
1063
OP_ST(sh,st16);
1064
OP_ST(sw,st32);
1065
#if defined(TARGET_MIPS64)
1066
OP_ST(sd,st64);
1067
#endif
1068
#undef OP_ST
1069

    
1070
#define OP_LD_ATOMIC(insn,fname)                                        \
1071
void inline op_ldst_##insn(DisasContext *ctx)                           \
1072
{                                                                       \
1073
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
1074
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1075
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1076
}
1077
OP_LD_ATOMIC(ll,ld32s);
1078
#if defined(TARGET_MIPS64)
1079
OP_LD_ATOMIC(lld,ld64);
1080
#endif
1081
#undef OP_LD_ATOMIC
1082

    
1083
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1084
void inline op_ldst_##insn(DisasContext *ctx)                           \
1085
{                                                                       \
1086
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
1087
    int l1 = gen_new_label();                                           \
1088
    int l2 = gen_new_label();                                           \
1089
    int l3 = gen_new_label();                                           \
1090
                                                                        \
1091
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1092
    tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1);         \
1093
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1094
    generate_exception(ctx, EXCP_AdES);                             \
1095
    gen_set_label(l1);                                                  \
1096
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1097
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1098
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1099
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1100
    tcg_gen_br(l3);                                                     \
1101
    gen_set_label(l2);                                                  \
1102
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1103
    gen_set_label(l3);                                                  \
1104
}
1105
OP_ST_ATOMIC(sc,st32,0x3);
1106
#if defined(TARGET_MIPS64)
1107
OP_ST_ATOMIC(scd,st64,0x7);
1108
#endif
1109
#undef OP_ST_ATOMIC
1110

    
1111
void inline op_ldst_lwc1(DisasContext *ctx)
1112
{
1113
    op_ldst(lwc1);
1114
}
1115

    
1116
void inline op_ldst_ldc1(DisasContext *ctx)
1117
{
1118
    op_ldst(ldc1);
1119
}
1120

    
1121
void inline op_ldst_swc1(DisasContext *ctx)
1122
{
1123
    op_ldst(swc1);
1124
}
1125

    
1126
void inline op_ldst_sdc1(DisasContext *ctx)
1127
{
1128
    op_ldst(sdc1);
1129
}
1130

    
1131
/* Load and store */
1132
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1133
                      int base, int16_t offset)
1134
{
1135
    const char *opn = "ldst";
1136

    
1137
    if (base == 0) {
1138
        GEN_LOAD_IMM_TN(T0, offset);
1139
    } else if (offset == 0) {
1140
        gen_op_load_gpr_T0(base);
1141
    } else {
1142
        gen_op_load_gpr_T0(base);
1143
        gen_op_set_T1(offset);
1144
        gen_op_addr_add();
1145
    }
1146
    /* Don't do NOP if destination is zero: we must perform the actual
1147
       memory access. */
1148
    switch (opc) {
1149
#if defined(TARGET_MIPS64)
1150
    case OPC_LWU:
1151
        op_ldst_lwu(ctx);
1152
        GEN_STORE_T0_REG(rt);
1153
        opn = "lwu";
1154
        break;
1155
    case OPC_LD:
1156
        op_ldst_ld(ctx);
1157
        GEN_STORE_T0_REG(rt);
1158
        opn = "ld";
1159
        break;
1160
    case OPC_LLD:
1161
        op_ldst_lld(ctx);
1162
        GEN_STORE_T0_REG(rt);
1163
        opn = "lld";
1164
        break;
1165
    case OPC_SD:
1166
        GEN_LOAD_REG_T1(rt);
1167
        op_ldst_sd(ctx);
1168
        opn = "sd";
1169
        break;
1170
    case OPC_SCD:
1171
        save_cpu_state(ctx, 1);
1172
        GEN_LOAD_REG_T1(rt);
1173
        op_ldst_scd(ctx);
1174
        GEN_STORE_T0_REG(rt);
1175
        opn = "scd";
1176
        break;
1177
    case OPC_LDL:
1178
        GEN_LOAD_REG_T1(rt);
1179
        op_ldst(ldl);
1180
        GEN_STORE_T1_REG(rt);
1181
        opn = "ldl";
1182
        break;
1183
    case OPC_SDL:
1184
        GEN_LOAD_REG_T1(rt);
1185
        op_ldst(sdl);
1186
        opn = "sdl";
1187
        break;
1188
    case OPC_LDR:
1189
        GEN_LOAD_REG_T1(rt);
1190
        op_ldst(ldr);
1191
        GEN_STORE_T1_REG(rt);
1192
        opn = "ldr";
1193
        break;
1194
    case OPC_SDR:
1195
        GEN_LOAD_REG_T1(rt);
1196
        op_ldst(sdr);
1197
        opn = "sdr";
1198
        break;
1199
#endif
1200
    case OPC_LW:
1201
        op_ldst_lw(ctx);
1202
        GEN_STORE_T0_REG(rt);
1203
        opn = "lw";
1204
        break;
1205
    case OPC_SW:
1206
        GEN_LOAD_REG_T1(rt);
1207
        op_ldst_sw(ctx);
1208
        opn = "sw";
1209
        break;
1210
    case OPC_LH:
1211
        op_ldst_lh(ctx);
1212
        GEN_STORE_T0_REG(rt);
1213
        opn = "lh";
1214
        break;
1215
    case OPC_SH:
1216
        GEN_LOAD_REG_T1(rt);
1217
        op_ldst_sh(ctx);
1218
        opn = "sh";
1219
        break;
1220
    case OPC_LHU:
1221
        op_ldst_lhu(ctx);
1222
        GEN_STORE_T0_REG(rt);
1223
        opn = "lhu";
1224
        break;
1225
    case OPC_LB:
1226
        op_ldst_lb(ctx);
1227
        GEN_STORE_T0_REG(rt);
1228
        opn = "lb";
1229
        break;
1230
    case OPC_SB:
1231
        GEN_LOAD_REG_T1(rt);
1232
        op_ldst_sb(ctx);
1233
        opn = "sb";
1234
        break;
1235
    case OPC_LBU:
1236
        op_ldst_lbu(ctx);
1237
        GEN_STORE_T0_REG(rt);
1238
        opn = "lbu";
1239
        break;
1240
    case OPC_LWL:
1241
        GEN_LOAD_REG_T1(rt);
1242
        op_ldst(lwl);
1243
        GEN_STORE_T1_REG(rt);
1244
        opn = "lwl";
1245
        break;
1246
    case OPC_SWL:
1247
        GEN_LOAD_REG_T1(rt);
1248
        op_ldst(swl);
1249
        opn = "swr";
1250
        break;
1251
    case OPC_LWR:
1252
        GEN_LOAD_REG_T1(rt);
1253
        op_ldst(lwr);
1254
        GEN_STORE_T1_REG(rt);
1255
        opn = "lwr";
1256
        break;
1257
    case OPC_SWR:
1258
        GEN_LOAD_REG_T1(rt);
1259
        op_ldst(swr);
1260
        opn = "swr";
1261
        break;
1262
    case OPC_LL:
1263
        op_ldst_ll(ctx);
1264
        GEN_STORE_T0_REG(rt);
1265
        opn = "ll";
1266
        break;
1267
    case OPC_SC:
1268
        save_cpu_state(ctx, 1);
1269
        GEN_LOAD_REG_T1(rt);
1270
        op_ldst_sc(ctx);
1271
        GEN_STORE_T0_REG(rt);
1272
        opn = "sc";
1273
        break;
1274
    default:
1275
        MIPS_INVAL(opn);
1276
        generate_exception(ctx, EXCP_RI);
1277
        return;
1278
    }
1279
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1280
}
1281

    
1282
/* Load and store */
1283
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1284
                      int base, int16_t offset)
1285
{
1286
    const char *opn = "flt_ldst";
1287

    
1288
    if (base == 0) {
1289
        GEN_LOAD_IMM_TN(T0, offset);
1290
    } else if (offset == 0) {
1291
        gen_op_load_gpr_T0(base);
1292
    } else {
1293
        gen_op_load_gpr_T0(base);
1294
        gen_op_set_T1(offset);
1295
        gen_op_addr_add();
1296
    }
1297
    /* Don't do NOP if destination is zero: we must perform the actual
1298
       memory access. */
1299
    switch (opc) {
1300
    case OPC_LWC1:
1301
        op_ldst_lwc1(ctx);
1302
        GEN_STORE_FTN_FREG(ft, WT0);
1303
        opn = "lwc1";
1304
        break;
1305
    case OPC_SWC1:
1306
        GEN_LOAD_FREG_FTN(WT0, ft);
1307
        op_ldst_swc1(ctx);
1308
        opn = "swc1";
1309
        break;
1310
    case OPC_LDC1:
1311
        op_ldst_ldc1(ctx);
1312
        GEN_STORE_FTN_FREG(ft, DT0);
1313
        opn = "ldc1";
1314
        break;
1315
    case OPC_SDC1:
1316
        GEN_LOAD_FREG_FTN(DT0, ft);
1317
        op_ldst_sdc1(ctx);
1318
        opn = "sdc1";
1319
        break;
1320
    default:
1321
        MIPS_INVAL(opn);
1322
        generate_exception(ctx, EXCP_RI);
1323
        return;
1324
    }
1325
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1326
}
1327

    
1328
/* Arithmetic with immediate operand */
1329
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1330
                           int rt, int rs, int16_t imm)
1331
{
1332
    target_ulong uimm;
1333
    const char *opn = "imm arith";
1334

    
1335
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1336
        /* If no destination, treat it as a NOP.
1337
           For addi, we must generate the overflow exception when needed. */
1338
        MIPS_DEBUG("NOP");
1339
        return;
1340
    }
1341
    uimm = (uint16_t)imm;
1342
    switch (opc) {
1343
    case OPC_ADDI:
1344
    case OPC_ADDIU:
1345
#if defined(TARGET_MIPS64)
1346
    case OPC_DADDI:
1347
    case OPC_DADDIU:
1348
#endif
1349
    case OPC_SLTI:
1350
    case OPC_SLTIU:
1351
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1352
        GEN_LOAD_IMM_TN(T1, uimm);
1353
        /* Fall through. */
1354
    case OPC_ANDI:
1355
    case OPC_ORI:
1356
    case OPC_XORI:
1357
        GEN_LOAD_REG_T0(rs);
1358
        break;
1359
    case OPC_LUI:
1360
        GEN_LOAD_IMM_TN(T0, imm << 16);
1361
        break;
1362
    case OPC_SLL:
1363
    case OPC_SRA:
1364
    case OPC_SRL:
1365
#if defined(TARGET_MIPS64)
1366
    case OPC_DSLL:
1367
    case OPC_DSRA:
1368
    case OPC_DSRL:
1369
    case OPC_DSLL32:
1370
    case OPC_DSRA32:
1371
    case OPC_DSRL32:
1372
#endif
1373
        uimm &= 0x1f;
1374
        GEN_LOAD_REG_T0(rs);
1375
        break;
1376
    }
1377
    switch (opc) {
1378
    case OPC_ADDI:
1379
        {
1380
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1381
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1382
            int l1 = gen_new_label();
1383

    
1384
            save_cpu_state(ctx, 1);
1385
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1386
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1387

    
1388
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1389
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1390
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1391
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1392
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1393
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1394
            /* operands of same sign, result different sign */
1395
            generate_exception(ctx, EXCP_OVERFLOW);
1396
            gen_set_label(l1);
1397

    
1398
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1399
        }
1400
        opn = "addi";
1401
        break;
1402
    case OPC_ADDIU:
1403
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1404
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1405
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1406
        opn = "addiu";
1407
        break;
1408
#if defined(TARGET_MIPS64)
1409
    case OPC_DADDI:
1410
        {
1411
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1412
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1413
            int l1 = gen_new_label();
1414

    
1415
            save_cpu_state(ctx, 1);
1416
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1417
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1418

    
1419
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1420
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1421
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1422
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1423
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1424
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1425
            /* operands of same sign, result different sign */
1426
            generate_exception(ctx, EXCP_OVERFLOW);
1427
            gen_set_label(l1);
1428
        }
1429
        opn = "daddi";
1430
        break;
1431
    case OPC_DADDIU:
1432
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1433
        opn = "daddiu";
1434
        break;
1435
#endif
1436
    case OPC_SLTI:
1437
        gen_op_lti(uimm);
1438
        opn = "slti";
1439
        break;
1440
    case OPC_SLTIU:
1441
        gen_op_ltiu(uimm);
1442
        opn = "sltiu";
1443
        break;
1444
    case OPC_ANDI:
1445
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1446
        opn = "andi";
1447
        break;
1448
    case OPC_ORI:
1449
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1450
        opn = "ori";
1451
        break;
1452
    case OPC_XORI:
1453
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1454
        opn = "xori";
1455
        break;
1456
    case OPC_LUI:
1457
        opn = "lui";
1458
        break;
1459
    case OPC_SLL:
1460
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1461
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1462
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1463
        opn = "sll";
1464
        break;
1465
    case OPC_SRA:
1466
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1467
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1468
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1469
        opn = "sra";
1470
        break;
1471
    case OPC_SRL:
1472
        switch ((ctx->opcode >> 21) & 0x1f) {
1473
        case 0:
1474
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1475
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1476
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1477
            opn = "srl";
1478
            break;
1479
        case 1:
1480
            /* rotr is decoded as srl on non-R2 CPUs */
1481
            if (env->insn_flags & ISA_MIPS32R2) {
1482
                if (uimm != 0) {
1483
                    TCGv r_tmp1 = new_tmp();
1484
                    TCGv r_tmp2 = new_tmp();
1485

    
1486
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1487
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1488
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1489
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1490
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1491
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1492
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1493
                    dead_tmp(r_tmp1);
1494
                    dead_tmp(r_tmp2);
1495
                }
1496
                opn = "rotr";
1497
            } else {
1498
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1499
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1500
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1501
                opn = "srl";
1502
            }
1503
            break;
1504
        default:
1505
            MIPS_INVAL("invalid srl flag");
1506
            generate_exception(ctx, EXCP_RI);
1507
            break;
1508
        }
1509
        break;
1510
#if defined(TARGET_MIPS64)
1511
    case OPC_DSLL:
1512
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1513
        opn = "dsll";
1514
        break;
1515
    case OPC_DSRA:
1516
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1517
        opn = "dsra";
1518
        break;
1519
    case OPC_DSRL:
1520
        switch ((ctx->opcode >> 21) & 0x1f) {
1521
        case 0:
1522
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1523
            opn = "dsrl";
1524
            break;
1525
        case 1:
1526
            /* drotr is decoded as dsrl on non-R2 CPUs */
1527
            if (env->insn_flags & ISA_MIPS32R2) {
1528
                if (uimm != 0) {
1529
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1530

    
1531
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1532
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1533
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1534
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1535
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1536
                }
1537
                opn = "drotr";
1538
            } else {
1539
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1540
                opn = "dsrl";
1541
            }
1542
            break;
1543
        default:
1544
            MIPS_INVAL("invalid dsrl flag");
1545
            generate_exception(ctx, EXCP_RI);
1546
            break;
1547
        }
1548
        break;
1549
    case OPC_DSLL32:
1550
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1551
        opn = "dsll32";
1552
        break;
1553
    case OPC_DSRA32:
1554
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1555
        opn = "dsra32";
1556
        break;
1557
    case OPC_DSRL32:
1558
        switch ((ctx->opcode >> 21) & 0x1f) {
1559
        case 0:
1560
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1561
            opn = "dsrl32";
1562
            break;
1563
        case 1:
1564
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1565
            if (env->insn_flags & ISA_MIPS32R2) {
1566
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1567
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1568

    
1569
                tcg_gen_movi_tl(r_tmp1, 0x40);
1570
                tcg_gen_movi_tl(r_tmp2, 32);
1571
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1572
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1573
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1574
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1575
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1576
                opn = "drotr32";
1577
            } else {
1578
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1579
                opn = "dsrl32";
1580
            }
1581
            break;
1582
        default:
1583
            MIPS_INVAL("invalid dsrl32 flag");
1584
            generate_exception(ctx, EXCP_RI);
1585
            break;
1586
        }
1587
        break;
1588
#endif
1589
    default:
1590
        MIPS_INVAL(opn);
1591
        generate_exception(ctx, EXCP_RI);
1592
        return;
1593
    }
1594
    GEN_STORE_T0_REG(rt);
1595
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1596
}
1597

    
1598
/* Arithmetic */
1599
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1600
                       int rd, int rs, int rt)
1601
{
1602
    const char *opn = "arith";
1603

    
1604
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1605
       && opc != OPC_DADD && opc != OPC_DSUB) {
1606
        /* If no destination, treat it as a NOP.
1607
           For add & sub, we must generate the overflow exception when needed. */
1608
        MIPS_DEBUG("NOP");
1609
        return;
1610
    }
1611
    GEN_LOAD_REG_T0(rs);
1612
    /* Specialcase the conventional move operation. */
1613
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1614
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1615
        GEN_STORE_T0_REG(rd);
1616
        return;
1617
    }
1618
    GEN_LOAD_REG_T1(rt);
1619
    switch (opc) {
1620
    case OPC_ADD:
1621
        {
1622
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1623
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1624
            int l1 = gen_new_label();
1625

    
1626
            save_cpu_state(ctx, 1);
1627
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1628
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1629
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1630

    
1631
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1632
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1633
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1634
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1635
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1636
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1637
            /* operands of same sign, result different sign */
1638
            generate_exception(ctx, EXCP_OVERFLOW);
1639
            gen_set_label(l1);
1640

    
1641
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1642
        }
1643
        opn = "add";
1644
        break;
1645
    case OPC_ADDU:
1646
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1647
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1648
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1649
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1650
        opn = "addu";
1651
        break;
1652
    case OPC_SUB:
1653
        {
1654
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1655
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1656
            int l1 = gen_new_label();
1657

    
1658
            save_cpu_state(ctx, 1);
1659
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1660
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1661
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1662

    
1663
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1664
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1665
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1666
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1667
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1668
            /* operands of different sign, first operand and result different sign */
1669
            generate_exception(ctx, EXCP_OVERFLOW);
1670
            gen_set_label(l1);
1671

    
1672
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1673
        }
1674
        opn = "sub";
1675
        break;
1676
    case OPC_SUBU:
1677
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1678
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1679
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1680
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1681
        opn = "subu";
1682
        break;
1683
#if defined(TARGET_MIPS64)
1684
    case OPC_DADD:
1685
        {
1686
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1687
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1688
            int l1 = gen_new_label();
1689

    
1690
            save_cpu_state(ctx, 1);
1691
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1692
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1693

    
1694
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1695
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1696
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1697
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1698
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1699
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1700
            /* operands of same sign, result different sign */
1701
            generate_exception(ctx, EXCP_OVERFLOW);
1702
            gen_set_label(l1);
1703
        }
1704
        opn = "dadd";
1705
        break;
1706
    case OPC_DADDU:
1707
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1708
        opn = "daddu";
1709
        break;
1710
    case OPC_DSUB:
1711
        {
1712
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1713
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1714
            int l1 = gen_new_label();
1715

    
1716
            save_cpu_state(ctx, 1);
1717
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1718
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1719

    
1720
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1721
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1722
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1723
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1724
            tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp1, tcg_const_tl(0), l1);
1725
            /* operands of different sign, first operand and result different sign */
1726
            generate_exception(ctx, EXCP_OVERFLOW);
1727
            gen_set_label(l1);
1728
        }
1729
        opn = "dsub";
1730
        break;
1731
    case OPC_DSUBU:
1732
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1733
        opn = "dsubu";
1734
        break;
1735
#endif
1736
    case OPC_SLT:
1737
        gen_op_lt();
1738
        opn = "slt";
1739
        break;
1740
    case OPC_SLTU:
1741
        gen_op_ltu();
1742
        opn = "sltu";
1743
        break;
1744
    case OPC_AND:
1745
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1746
        opn = "and";
1747
        break;
1748
    case OPC_NOR:
1749
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1750
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1751
        opn = "nor";
1752
        break;
1753
    case OPC_OR:
1754
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1755
        opn = "or";
1756
        break;
1757
    case OPC_XOR:
1758
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1759
        opn = "xor";
1760
        break;
1761
    case OPC_MUL:
1762
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1763
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1764
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1765
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1766
        opn = "mul";
1767
        break;
1768
    case OPC_MOVN:
1769
        {
1770
            int l1 = gen_new_label();
1771

    
1772
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1773
            gen_op_store_gpr_T0(rd);
1774
            gen_set_label(l1);
1775
        }
1776
        opn = "movn";
1777
        goto print;
1778
    case OPC_MOVZ:
1779
        {
1780
            int l1 = gen_new_label();
1781

    
1782
            tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(0), l1);
1783
            gen_op_store_gpr_T0(rd);
1784
            gen_set_label(l1);
1785
        }
1786
        opn = "movz";
1787
        goto print;
1788
    case OPC_SLLV:
1789
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1790
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1791
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1792
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1793
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1794
        opn = "sllv";
1795
        break;
1796
    case OPC_SRAV:
1797
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1798
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1799
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1800
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1801
        opn = "srav";
1802
        break;
1803
    case OPC_SRLV:
1804
        switch ((ctx->opcode >> 6) & 0x1f) {
1805
        case 0:
1806
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1807
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1808
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1809
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1810
            opn = "srlv";
1811
            break;
1812
        case 1:
1813
            /* rotrv is decoded as srlv on non-R2 CPUs */
1814
            if (env->insn_flags & ISA_MIPS32R2) {
1815
                int l1 = gen_new_label();
1816
                int l2 = gen_new_label();
1817

    
1818
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1819
                tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
1820
                {
1821
                    TCGv r_tmp1 = new_tmp();
1822
                    TCGv r_tmp2 = new_tmp();
1823
                    TCGv r_tmp3 = new_tmp();
1824

    
1825
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1826
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1827
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1828
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1829
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1830
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1831
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1832
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1833
                    dead_tmp(r_tmp1);
1834
                    dead_tmp(r_tmp2);
1835
                    dead_tmp(r_tmp3);
1836
                    tcg_gen_br(l2);
1837
                }
1838
                gen_set_label(l1);
1839
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1840
                gen_set_label(l2);
1841
                opn = "rotrv";
1842
            } else {
1843
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1844
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1845
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1846
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1847
                opn = "srlv";
1848
            }
1849
            break;
1850
        default:
1851
            MIPS_INVAL("invalid srlv flag");
1852
            generate_exception(ctx, EXCP_RI);
1853
            break;
1854
        }
1855
        break;
1856
#if defined(TARGET_MIPS64)
1857
    case OPC_DSLLV:
1858
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1859
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1860
        opn = "dsllv";
1861
        break;
1862
    case OPC_DSRAV:
1863
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1864
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1865
        opn = "dsrav";
1866
        break;
1867
    case OPC_DSRLV:
1868
        switch ((ctx->opcode >> 6) & 0x1f) {
1869
        case 0:
1870
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1871
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1872
            opn = "dsrlv";
1873
            break;
1874
        case 1:
1875
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1876
            if (env->insn_flags & ISA_MIPS32R2) {
1877
                int l1 = gen_new_label();
1878
                int l2 = gen_new_label();
1879

    
1880
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1881
                tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
1882
                {
1883
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1884

    
1885
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1886
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1887
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1888
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1889
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1890
                    tcg_gen_br(l2);
1891
                }
1892
                gen_set_label(l1);
1893
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1894
                gen_set_label(l2);
1895
                opn = "drotrv";
1896
            } else {
1897
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1898
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1899
                opn = "dsrlv";
1900
            }
1901
            break;
1902
        default:
1903
            MIPS_INVAL("invalid dsrlv flag");
1904
            generate_exception(ctx, EXCP_RI);
1905
            break;
1906
        }
1907
        break;
1908
#endif
1909
    default:
1910
        MIPS_INVAL(opn);
1911
        generate_exception(ctx, EXCP_RI);
1912
        return;
1913
    }
1914
    GEN_STORE_T0_REG(rd);
1915
 print:
1916
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1917
}
1918

    
1919
/* Arithmetic on HI/LO registers */
1920
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1921
{
1922
    const char *opn = "hilo";
1923

    
1924
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1925
        /* Treat as NOP. */
1926
        MIPS_DEBUG("NOP");
1927
        return;
1928
    }
1929
    switch (opc) {
1930
    case OPC_MFHI:
1931
        gen_op_load_HI(0);
1932
        GEN_STORE_T0_REG(reg);
1933
        opn = "mfhi";
1934
        break;
1935
    case OPC_MFLO:
1936
        gen_op_load_LO(0);
1937
        GEN_STORE_T0_REG(reg);
1938
        opn = "mflo";
1939
        break;
1940
    case OPC_MTHI:
1941
        GEN_LOAD_REG_T0(reg);
1942
        gen_op_store_HI(0);
1943
        opn = "mthi";
1944
        break;
1945
    case OPC_MTLO:
1946
        GEN_LOAD_REG_T0(reg);
1947
        gen_op_store_LO(0);
1948
        opn = "mtlo";
1949
        break;
1950
    default:
1951
        MIPS_INVAL(opn);
1952
        generate_exception(ctx, EXCP_RI);
1953
        return;
1954
    }
1955
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1956
}
1957

    
1958
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1959
                        int rs, int rt)
1960
{
1961
    const char *opn = "mul/div";
1962

    
1963
    GEN_LOAD_REG_T0(rs);
1964
    GEN_LOAD_REG_T1(rt);
1965
    switch (opc) {
1966
    case OPC_DIV:
1967
        {
1968
            int l1 = gen_new_label();
1969

    
1970
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
1971
            {
1972
                TCGv r_tmp1 = new_tmp();
1973
                TCGv r_tmp2 = new_tmp();
1974
                TCGv r_tmp3 = new_tmp();
1975
                TCGv r_tc_off = new_tmp();
1976
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1977
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1978

    
1979
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1980
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1981
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1982
                tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
1983
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1984
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1985
                dead_tmp(r_tmp1);
1986
                dead_tmp(r_tmp2);
1987
                dead_tmp(r_tmp3);
1988
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1989
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1990
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1991
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1992
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1993
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1994
                dead_tmp(r_tc_off);
1995
            }
1996
            gen_set_label(l1);
1997
        }
1998
        opn = "div";
1999
        break;
2000
    case OPC_DIVU:
2001
        {
2002
            int l1 = gen_new_label();
2003

    
2004
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
2005
            {
2006
                TCGv r_tmp1 = new_tmp();
2007
                TCGv r_tmp2 = new_tmp();
2008
                TCGv r_tmp3 = new_tmp();
2009
                TCGv r_tc_off = new_tmp();
2010
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
2011
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
2012

    
2013
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
2014
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
2015
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
2016
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
2017
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
2018
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
2019
                dead_tmp(r_tmp1);
2020
                dead_tmp(r_tmp2);
2021
                dead_tmp(r_tmp3);
2022
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
2023
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
2024
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
2025
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
2026
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
2027
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
2028
                dead_tmp(r_tc_off);
2029
            }
2030
            gen_set_label(l1);
2031
        }
2032
        opn = "divu";
2033
        break;
2034
    case OPC_MULT:
2035
        gen_op_mult();
2036
        opn = "mult";
2037
        break;
2038
    case OPC_MULTU:
2039
        gen_op_multu();
2040
        opn = "multu";
2041
        break;
2042
#if defined(TARGET_MIPS64)
2043
    case OPC_DDIV:
2044
        {
2045
            int l1 = gen_new_label();
2046

    
2047
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
2048
            {
2049
                TCGv r_tc_off = new_tmp();
2050
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
2051
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
2052
                int l2 = gen_new_label();
2053
                int l3 = gen_new_label();
2054

    
2055
                tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], tcg_const_tl(1ULL << 63), l2);
2056
                tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(-1ULL), l2);
2057
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2058
                tcg_gen_movi_tl(cpu_T[1], 0);
2059
                tcg_gen_br(l3);
2060
                gen_set_label(l2);
2061
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2062
                tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
2063
                gen_set_label(l3);
2064

    
2065
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
2066
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
2067
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
2068
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
2069
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
2070
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
2071
                dead_tmp(r_tc_off);
2072
            }
2073
            gen_set_label(l1);
2074
        }
2075
        opn = "ddiv";
2076
        break;
2077
    case OPC_DDIVU:
2078
        {
2079
            int l1 = gen_new_label();
2080

    
2081
            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), l1);
2082
            {
2083
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2084
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2085
                TCGv r_tc_off = new_tmp();
2086
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
2087
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
2088

    
2089
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
2090
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
2091
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
2092
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
2093
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
2094
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
2095
                tcg_gen_st_tl(r_tmp1, r_ptr, offsetof(CPUState, LO));
2096
                tcg_gen_st_tl(r_tmp2, r_ptr, offsetof(CPUState, HI));
2097
                dead_tmp(r_tc_off);
2098
            }
2099
            gen_set_label(l1);
2100
        }
2101
        opn = "ddivu";
2102
        break;
2103
    case OPC_DMULT:
2104
        gen_op_dmult();
2105
        opn = "dmult";
2106
        break;
2107
    case OPC_DMULTU:
2108
        gen_op_dmultu();
2109
        opn = "dmultu";
2110
        break;
2111
#endif
2112
    case OPC_MADD:
2113
        gen_op_madd();
2114
        opn = "madd";
2115
        break;
2116
    case OPC_MADDU:
2117
        gen_op_maddu();
2118
        opn = "maddu";
2119
        break;
2120
    case OPC_MSUB:
2121
        gen_op_msub();
2122
        opn = "msub";
2123
        break;
2124
    case OPC_MSUBU:
2125
        gen_op_msubu();
2126
        opn = "msubu";
2127
        break;
2128
    default:
2129
        MIPS_INVAL(opn);
2130
        generate_exception(ctx, EXCP_RI);
2131
        return;
2132
    }
2133
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2134
}
2135

    
2136
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2137
                            int rd, int rs, int rt)
2138
{
2139
    const char *opn = "mul vr54xx";
2140

    
2141
    GEN_LOAD_REG_T0(rs);
2142
    GEN_LOAD_REG_T1(rt);
2143

    
2144
    switch (opc) {
2145
    case OPC_VR54XX_MULS:
2146
        gen_op_muls();
2147
        opn = "muls";
2148
        break;
2149
    case OPC_VR54XX_MULSU:
2150
        gen_op_mulsu();
2151
        opn = "mulsu";
2152
        break;
2153
    case OPC_VR54XX_MACC:
2154
        gen_op_macc();
2155
        opn = "macc";
2156
        break;
2157
    case OPC_VR54XX_MACCU:
2158
        gen_op_maccu();
2159
        opn = "maccu";
2160
        break;
2161
    case OPC_VR54XX_MSAC:
2162
        gen_op_msac();
2163
        opn = "msac";
2164
        break;
2165
    case OPC_VR54XX_MSACU:
2166
        gen_op_msacu();
2167
        opn = "msacu";
2168
        break;
2169
    case OPC_VR54XX_MULHI:
2170
        gen_op_mulhi();
2171
        opn = "mulhi";
2172
        break;
2173
    case OPC_VR54XX_MULHIU:
2174
        gen_op_mulhiu();
2175
        opn = "mulhiu";
2176
        break;
2177
    case OPC_VR54XX_MULSHI:
2178
        gen_op_mulshi();
2179
        opn = "mulshi";
2180
        break;
2181
    case OPC_VR54XX_MULSHIU:
2182
        gen_op_mulshiu();
2183
        opn = "mulshiu";
2184
        break;
2185
    case OPC_VR54XX_MACCHI:
2186
        gen_op_macchi();
2187
        opn = "macchi";
2188
        break;
2189
    case OPC_VR54XX_MACCHIU:
2190
        gen_op_macchiu();
2191
        opn = "macchiu";
2192
        break;
2193
    case OPC_VR54XX_MSACHI:
2194
        gen_op_msachi();
2195
        opn = "msachi";
2196
        break;
2197
    case OPC_VR54XX_MSACHIU:
2198
        gen_op_msachiu();
2199
        opn = "msachiu";
2200
        break;
2201
    default:
2202
        MIPS_INVAL("mul vr54xx");
2203
        generate_exception(ctx, EXCP_RI);
2204
        return;
2205
    }
2206
    GEN_STORE_T0_REG(rd);
2207
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2208
}
2209

    
2210
static void gen_cl (DisasContext *ctx, uint32_t opc,
2211
                    int rd, int rs)
2212
{
2213
    const char *opn = "CLx";
2214
    if (rd == 0) {
2215
        /* Treat as NOP. */
2216
        MIPS_DEBUG("NOP");
2217
        return;
2218
    }
2219
    GEN_LOAD_REG_T0(rs);
2220
    switch (opc) {
2221
    case OPC_CLO:
2222
        tcg_gen_helper_0_0(do_clo);
2223
        opn = "clo";
2224
        break;
2225
    case OPC_CLZ:
2226
        tcg_gen_helper_0_0(do_clz);
2227
        opn = "clz";
2228
        break;
2229
#if defined(TARGET_MIPS64)
2230
    case OPC_DCLO:
2231
        tcg_gen_helper_0_0(do_dclo);
2232
        opn = "dclo";
2233
        break;
2234
    case OPC_DCLZ:
2235
        tcg_gen_helper_0_0(do_dclz);
2236
        opn = "dclz";
2237
        break;
2238
#endif
2239
    default:
2240
        MIPS_INVAL(opn);
2241
        generate_exception(ctx, EXCP_RI);
2242
        return;
2243
    }
2244
    gen_op_store_gpr_T0(rd);
2245
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2246
}
2247

    
2248
/* Traps */
2249
static void gen_trap (DisasContext *ctx, uint32_t opc,
2250
                      int rs, int rt, int16_t imm)
2251
{
2252
    int cond;
2253

    
2254
    cond = 0;
2255
    /* Load needed operands */
2256
    switch (opc) {
2257
    case OPC_TEQ:
2258
    case OPC_TGE:
2259
    case OPC_TGEU:
2260
    case OPC_TLT:
2261
    case OPC_TLTU:
2262
    case OPC_TNE:
2263
        /* Compare two registers */
2264
        if (rs != rt) {
2265
            GEN_LOAD_REG_T0(rs);
2266
            GEN_LOAD_REG_T1(rt);
2267
            cond = 1;
2268
        }
2269
        break;
2270
    case OPC_TEQI:
2271
    case OPC_TGEI:
2272
    case OPC_TGEIU:
2273
    case OPC_TLTI:
2274
    case OPC_TLTIU:
2275
    case OPC_TNEI:
2276
        /* Compare register to immediate */
2277
        if (rs != 0 || imm != 0) {
2278
            GEN_LOAD_REG_T0(rs);
2279
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
2280
            cond = 1;
2281
        }
2282
        break;
2283
    }
2284
    if (cond == 0) {
2285
        switch (opc) {
2286
        case OPC_TEQ:   /* rs == rs */
2287
        case OPC_TEQI:  /* r0 == 0  */
2288
        case OPC_TGE:   /* rs >= rs */
2289
        case OPC_TGEI:  /* r0 >= 0  */
2290
        case OPC_TGEU:  /* rs >= rs unsigned */
2291
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2292
            /* Always trap */
2293
            gen_op_set_T0(1);
2294
            break;
2295
        case OPC_TLT:   /* rs < rs           */
2296
        case OPC_TLTI:  /* r0 < 0            */
2297
        case OPC_TLTU:  /* rs < rs unsigned  */
2298
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2299
        case OPC_TNE:   /* rs != rs          */
2300
        case OPC_TNEI:  /* r0 != 0           */
2301
            /* Never trap: treat as NOP. */
2302
            return;
2303
        default:
2304
            MIPS_INVAL("trap");
2305
            generate_exception(ctx, EXCP_RI);
2306
            return;
2307
        }
2308
    } else {
2309
        switch (opc) {
2310
        case OPC_TEQ:
2311
        case OPC_TEQI:
2312
            gen_op_eq();
2313
            break;
2314
        case OPC_TGE:
2315
        case OPC_TGEI:
2316
            gen_op_ge();
2317
            break;
2318
        case OPC_TGEU:
2319
        case OPC_TGEIU:
2320
            gen_op_geu();
2321
            break;
2322
        case OPC_TLT:
2323
        case OPC_TLTI:
2324
            gen_op_lt();
2325
            break;
2326
        case OPC_TLTU:
2327
        case OPC_TLTIU:
2328
            gen_op_ltu();
2329
            break;
2330
        case OPC_TNE:
2331
        case OPC_TNEI:
2332
            gen_op_ne();
2333
            break;
2334
        default:
2335
            MIPS_INVAL("trap");
2336
            generate_exception(ctx, EXCP_RI);
2337
            return;
2338
        }
2339
    }
2340
    save_cpu_state(ctx, 1);
2341
    gen_op_trap();
2342
    ctx->bstate = BS_STOP;
2343
}
2344

    
2345
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2346
{
2347
    TranslationBlock *tb;
2348
    tb = ctx->tb;
2349
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2350
        tcg_gen_goto_tb(n);
2351
        gen_save_pc(dest);
2352
        tcg_gen_exit_tb((long)tb + n);
2353
    } else {
2354
        gen_save_pc(dest);
2355
        tcg_gen_exit_tb(0);
2356
    }
2357
}
2358

    
2359
static inline void tcg_gen_set_bcond(void)
2360
{
2361
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2362
}
2363

    
2364
static inline void tcg_gen_jnz_bcond(int label)
2365
{
2366
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
2367

    
2368
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
2369
    tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);
2370
}
2371

    
2372
/* Branches (before delay slot) */
2373
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2374
                                int rs, int rt, int32_t offset)
2375
{
2376
    target_ulong btarget = -1;
2377
    int blink = 0;
2378
    int bcond = 0;
2379

    
2380
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2381
#ifdef MIPS_DEBUG_DISAS
2382
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2383
            fprintf(logfile,
2384
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2385
                    ctx->pc);
2386
        }
2387
#endif
2388
        generate_exception(ctx, EXCP_RI);
2389
        return;
2390
    }
2391

    
2392
    /* Load needed operands */
2393
    switch (opc) {
2394
    case OPC_BEQ:
2395
    case OPC_BEQL:
2396
    case OPC_BNE:
2397
    case OPC_BNEL:
2398
        /* Compare two registers */
2399
        if (rs != rt) {
2400
            GEN_LOAD_REG_T0(rs);
2401
            GEN_LOAD_REG_T1(rt);
2402
            bcond = 1;
2403
        }
2404
        btarget = ctx->pc + 4 + offset;
2405
        break;
2406
    case OPC_BGEZ:
2407
    case OPC_BGEZAL:
2408
    case OPC_BGEZALL:
2409
    case OPC_BGEZL:
2410
    case OPC_BGTZ:
2411
    case OPC_BGTZL:
2412
    case OPC_BLEZ:
2413
    case OPC_BLEZL:
2414
    case OPC_BLTZ:
2415
    case OPC_BLTZAL:
2416
    case OPC_BLTZALL:
2417
    case OPC_BLTZL:
2418
        /* Compare to zero */
2419
        if (rs != 0) {
2420
            gen_op_load_gpr_T0(rs);
2421
            bcond = 1;
2422
        }
2423
        btarget = ctx->pc + 4 + offset;
2424
        break;
2425
    case OPC_J:
2426
    case OPC_JAL:
2427
        /* Jump to immediate */
2428
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2429
        break;
2430
    case OPC_JR:
2431
    case OPC_JALR:
2432
        /* Jump to register */
2433
        if (offset != 0 && offset != 16) {
2434
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2435
               others are reserved. */
2436
            MIPS_INVAL("jump hint");
2437
            generate_exception(ctx, EXCP_RI);
2438
            return;
2439
        }
2440
        GEN_LOAD_REG_T1(rs);
2441
        gen_op_save_breg_target();
2442
        break;
2443
    default:
2444
        MIPS_INVAL("branch/jump");
2445
        generate_exception(ctx, EXCP_RI);
2446
        return;
2447
    }
2448
    if (bcond == 0) {
2449
        /* No condition to be computed */
2450
        switch (opc) {
2451
        case OPC_BEQ:     /* rx == rx        */
2452
        case OPC_BEQL:    /* rx == rx likely */
2453
        case OPC_BGEZ:    /* 0 >= 0          */
2454
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2455
        case OPC_BLEZ:    /* 0 <= 0          */
2456
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2457
            /* Always take */
2458
            ctx->hflags |= MIPS_HFLAG_B;
2459
            MIPS_DEBUG("balways");
2460
            break;
2461
        case OPC_BGEZAL:  /* 0 >= 0          */
2462
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2463
            /* Always take and link */
2464
            blink = 31;
2465
            ctx->hflags |= MIPS_HFLAG_B;
2466
            MIPS_DEBUG("balways and link");
2467
            break;
2468
        case OPC_BNE:     /* rx != rx        */
2469
        case OPC_BGTZ:    /* 0 > 0           */
2470
        case OPC_BLTZ:    /* 0 < 0           */
2471
            /* Treat as NOP. */
2472
            MIPS_DEBUG("bnever (NOP)");
2473
            return;
2474
        case OPC_BLTZAL:  /* 0 < 0           */
2475
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2476
            gen_op_store_gpr_T0(31);
2477
            MIPS_DEBUG("bnever and link");
2478
            return;
2479
        case OPC_BLTZALL: /* 0 < 0 likely */
2480
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2481
            gen_op_store_gpr_T0(31);
2482
            /* Skip the instruction in the delay slot */
2483
            MIPS_DEBUG("bnever, link and skip");
2484
            ctx->pc += 4;
2485
            return;
2486
        case OPC_BNEL:    /* rx != rx likely */
2487
        case OPC_BGTZL:   /* 0 > 0 likely */
2488
        case OPC_BLTZL:   /* 0 < 0 likely */
2489
            /* Skip the instruction in the delay slot */
2490
            MIPS_DEBUG("bnever and skip");
2491
            ctx->pc += 4;
2492
            return;
2493
        case OPC_J:
2494
            ctx->hflags |= MIPS_HFLAG_B;
2495
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2496
            break;
2497
        case OPC_JAL:
2498
            blink = 31;
2499
            ctx->hflags |= MIPS_HFLAG_B;
2500
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2501
            break;
2502
        case OPC_JR:
2503
            ctx->hflags |= MIPS_HFLAG_BR;
2504
            MIPS_DEBUG("jr %s", regnames[rs]);
2505
            break;
2506
        case OPC_JALR:
2507
            blink = rt;
2508
            ctx->hflags |= MIPS_HFLAG_BR;
2509
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2510
            break;
2511
        default:
2512
            MIPS_INVAL("branch/jump");
2513
            generate_exception(ctx, EXCP_RI);
2514
            return;
2515
        }
2516
    } else {
2517
        switch (opc) {
2518
        case OPC_BEQ:
2519
            gen_op_eq();
2520
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2521
                       regnames[rs], regnames[rt], btarget);
2522
            goto not_likely;
2523
        case OPC_BEQL:
2524
            gen_op_eq();
2525
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2526
                       regnames[rs], regnames[rt], btarget);
2527
            goto likely;
2528
        case OPC_BNE:
2529
            gen_op_ne();
2530
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2531
                       regnames[rs], regnames[rt], btarget);
2532
            goto not_likely;
2533
        case OPC_BNEL:
2534
            gen_op_ne();
2535
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2536
                       regnames[rs], regnames[rt], btarget);
2537
            goto likely;
2538
        case OPC_BGEZ:
2539
            gen_op_gez();
2540
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2541
            goto not_likely;
2542
        case OPC_BGEZL:
2543
            gen_op_gez();
2544
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2545
            goto likely;
2546
        case OPC_BGEZAL:
2547
            gen_op_gez();
2548
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2549
            blink = 31;
2550
            goto not_likely;
2551
        case OPC_BGEZALL:
2552
            gen_op_gez();
2553
            blink = 31;
2554
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2555
            goto likely;
2556
        case OPC_BGTZ:
2557
            gen_op_gtz();
2558
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2559
            goto not_likely;
2560
        case OPC_BGTZL:
2561
            gen_op_gtz();
2562
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2563
            goto likely;
2564
        case OPC_BLEZ:
2565
            gen_op_lez();
2566
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2567
            goto not_likely;
2568
        case OPC_BLEZL:
2569
            gen_op_lez();
2570
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2571
            goto likely;
2572
        case OPC_BLTZ:
2573
            gen_op_ltz();
2574
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2575
            goto not_likely;
2576
        case OPC_BLTZL:
2577
            gen_op_ltz();
2578
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2579
            goto likely;
2580
        case OPC_BLTZAL:
2581
            gen_op_ltz();
2582
            blink = 31;
2583
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2584
        not_likely:
2585
            ctx->hflags |= MIPS_HFLAG_BC;
2586
            tcg_gen_set_bcond();
2587
            break;
2588
        case OPC_BLTZALL:
2589
            gen_op_ltz();
2590
            blink = 31;
2591
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2592
        likely:
2593
            ctx->hflags |= MIPS_HFLAG_BL;
2594
            tcg_gen_set_bcond();
2595
            break;
2596
        default:
2597
            MIPS_INVAL("conditional branch/jump");
2598
            generate_exception(ctx, EXCP_RI);
2599
            return;
2600
        }
2601
    }
2602
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2603
               blink, ctx->hflags, btarget);
2604

    
2605
    ctx->btarget = btarget;
2606
    if (blink > 0) {
2607
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2608
        gen_op_store_gpr_T0(blink);
2609
    }
2610
}
2611

    
2612
/* special3 bitfield operations */
2613
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2614
                       int rs, int lsb, int msb)
2615
{
2616
    GEN_LOAD_REG_T1(rs);
2617
    switch (opc) {
2618
    case OPC_EXT:
2619
        if (lsb + msb > 31)
2620
            goto fail;
2621
        gen_op_ext(lsb, msb + 1);
2622
        break;
2623
#if defined(TARGET_MIPS64)
2624
    case OPC_DEXTM:
2625
        if (lsb + msb > 63)
2626
            goto fail;
2627
        gen_op_dext(lsb, msb + 1 + 32);
2628
        break;
2629
    case OPC_DEXTU:
2630
        if (lsb + msb > 63)
2631
            goto fail;
2632
        gen_op_dext(lsb + 32, msb + 1);
2633
        break;
2634
    case OPC_DEXT:
2635
        if (lsb + msb > 63)
2636
            goto fail;
2637
        gen_op_dext(lsb, msb + 1);
2638
        break;
2639
#endif
2640
    case OPC_INS:
2641
        if (lsb > msb)
2642
            goto fail;
2643
        GEN_LOAD_REG_T0(rt);
2644
        gen_op_ins(lsb, msb - lsb + 1);
2645
        break;
2646
#if defined(TARGET_MIPS64)
2647
    case OPC_DINSM:
2648
        if (lsb > msb)
2649
            goto fail;
2650
        GEN_LOAD_REG_T0(rt);
2651
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2652
        break;
2653
    case OPC_DINSU:
2654
        if (lsb > msb)
2655
            goto fail;
2656
        GEN_LOAD_REG_T0(rt);
2657
        gen_op_dins(lsb + 32, msb - lsb + 1);
2658
        break;
2659
    case OPC_DINS:
2660
        if (lsb > msb)
2661
            goto fail;
2662
        GEN_LOAD_REG_T0(rt);
2663
        gen_op_dins(lsb, msb - lsb + 1);
2664
        break;
2665
#endif
2666
    default:
2667
fail:
2668
        MIPS_INVAL("bitops");
2669
        generate_exception(ctx, EXCP_RI);
2670
        return;
2671
    }
2672
    GEN_STORE_T0_REG(rt);
2673
}
2674

    
2675
/* CP0 (MMU and control) */
2676
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2677
{
2678
    const char *rn = "invalid";
2679

    
2680
    if (sel != 0)
2681
        check_insn(env, ctx, ISA_MIPS32);
2682

    
2683
    switch (reg) {
2684
    case 0:
2685
        switch (sel) {
2686
        case 0:
2687
            gen_op_mfc0_index();
2688
            rn = "Index";
2689
            break;
2690
        case 1:
2691
            check_insn(env, ctx, ASE_MT);
2692
            gen_op_mfc0_mvpcontrol();
2693
            rn = "MVPControl";
2694
            break;
2695
        case 2:
2696
            check_insn(env, ctx, ASE_MT);
2697
            gen_op_mfc0_mvpconf0();
2698
            rn = "MVPConf0";
2699
            break;
2700
        case 3:
2701
            check_insn(env, ctx, ASE_MT);
2702
            gen_op_mfc0_mvpconf1();
2703
            rn = "MVPConf1";
2704
            break;
2705
        default:
2706
            goto die;
2707
        }
2708
        break;
2709
    case 1:
2710
        switch (sel) {
2711
        case 0:
2712
            gen_op_mfc0_random();
2713
            rn = "Random";
2714
            break;
2715
        case 1:
2716
            check_insn(env, ctx, ASE_MT);
2717
            gen_op_mfc0_vpecontrol();
2718
            rn = "VPEControl";
2719
            break;
2720
        case 2:
2721
            check_insn(env, ctx, ASE_MT);
2722
            gen_op_mfc0_vpeconf0();
2723
            rn = "VPEConf0";
2724
            break;
2725
        case 3:
2726
            check_insn(env, ctx, ASE_MT);
2727
            gen_op_mfc0_vpeconf1();
2728
            rn = "VPEConf1";
2729
            break;
2730
        case 4:
2731
            check_insn(env, ctx, ASE_MT);
2732
            gen_op_mfc0_yqmask();
2733
            rn = "YQMask";
2734
            break;
2735
        case 5:
2736
            check_insn(env, ctx, ASE_MT);
2737
            gen_op_mfc0_vpeschedule();
2738
            rn = "VPESchedule";
2739
            break;
2740
        case 6:
2741
            check_insn(env, ctx, ASE_MT);
2742
            gen_op_mfc0_vpeschefback();
2743
            rn = "VPEScheFBack";
2744
            break;
2745
        case 7:
2746
            check_insn(env, ctx, ASE_MT);
2747
            gen_op_mfc0_vpeopt();
2748
            rn = "VPEOpt";
2749
            break;
2750
        default:
2751
            goto die;
2752
        }
2753
        break;
2754
    case 2:
2755
        switch (sel) {
2756
        case 0:
2757
            gen_op_mfc0_entrylo0();
2758
            rn = "EntryLo0";
2759
            break;
2760
        case 1:
2761
            check_insn(env, ctx, ASE_MT);
2762
            gen_op_mfc0_tcstatus();
2763
            rn = "TCStatus";
2764
            break;
2765
        case 2:
2766
            check_insn(env, ctx, ASE_MT);
2767
            gen_op_mfc0_tcbind();
2768
            rn = "TCBind";
2769
            break;
2770
        case 3:
2771
            check_insn(env, ctx, ASE_MT);
2772
            gen_op_mfc0_tcrestart();
2773
            rn = "TCRestart";
2774
            break;
2775
        case 4:
2776
            check_insn(env, ctx, ASE_MT);
2777
            gen_op_mfc0_tchalt();
2778
            rn = "TCHalt";
2779
            break;
2780
        case 5:
2781
            check_insn(env, ctx, ASE_MT);
2782
            gen_op_mfc0_tccontext();
2783
            rn = "TCContext";
2784
            break;
2785
        case 6:
2786
            check_insn(env, ctx, ASE_MT);
2787
            gen_op_mfc0_tcschedule();
2788
            rn = "TCSchedule";
2789
            break;
2790
        case 7:
2791
            check_insn(env, ctx, ASE_MT);
2792
            gen_op_mfc0_tcschefback();
2793
            rn = "TCScheFBack";
2794
            break;
2795
        default:
2796
            goto die;
2797
        }
2798
        break;
2799
    case 3:
2800
        switch (sel) {
2801
        case 0:
2802
            gen_op_mfc0_entrylo1();
2803
            rn = "EntryLo1";
2804
            break;
2805
        default:
2806
            goto die;
2807
        }
2808
        break;
2809
    case 4:
2810
        switch (sel) {
2811
        case 0:
2812
            gen_op_mfc0_context();
2813
            rn = "Context";
2814
            break;
2815
        case 1:
2816
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2817
            rn = "ContextConfig";
2818
//            break;
2819
        default:
2820
            goto die;
2821
        }
2822
        break;
2823
    case 5:
2824
        switch (sel) {
2825
        case 0:
2826
            gen_op_mfc0_pagemask();
2827
            rn = "PageMask";
2828
            break;
2829
        case 1:
2830
            check_insn(env, ctx, ISA_MIPS32R2);
2831
            gen_op_mfc0_pagegrain();
2832
            rn = "PageGrain";
2833
            break;
2834
        default:
2835
            goto die;
2836
        }
2837
        break;
2838
    case 6:
2839
        switch (sel) {
2840
        case 0:
2841
            gen_op_mfc0_wired();
2842
            rn = "Wired";
2843
            break;
2844
        case 1:
2845
            check_insn(env, ctx, ISA_MIPS32R2);
2846
            gen_op_mfc0_srsconf0();
2847
            rn = "SRSConf0";
2848
            break;
2849
        case 2:
2850
            check_insn(env, ctx, ISA_MIPS32R2);
2851
            gen_op_mfc0_srsconf1();
2852
            rn = "SRSConf1";
2853
            break;
2854
        case 3:
2855
            check_insn(env, ctx, ISA_MIPS32R2);
2856
            gen_op_mfc0_srsconf2();
2857
            rn = "SRSConf2";
2858
            break;
2859
        case 4:
2860
            check_insn(env, ctx, ISA_MIPS32R2);
2861
            gen_op_mfc0_srsconf3();
2862
            rn = "SRSConf3";
2863
            break;
2864
        case 5:
2865
            check_insn(env, ctx, ISA_MIPS32R2);
2866
            gen_op_mfc0_srsconf4();
2867
            rn = "SRSConf4";
2868
            break;
2869
        default:
2870
            goto die;
2871
        }
2872
        break;
2873
    case 7:
2874
        switch (sel) {
2875
        case 0:
2876
            check_insn(env, ctx, ISA_MIPS32R2);
2877
            gen_op_mfc0_hwrena();
2878
            rn = "HWREna";
2879
            break;
2880
        default:
2881
            goto die;
2882
        }
2883
        break;
2884
    case 8:
2885
        switch (sel) {
2886
        case 0:
2887
            gen_op_mfc0_badvaddr();
2888
            rn = "BadVaddr";
2889
            break;
2890
        default:
2891
            goto die;
2892
       }
2893
        break;
2894
    case 9:
2895
        switch (sel) {
2896
        case 0:
2897
            gen_op_mfc0_count();
2898
            rn = "Count";
2899
            break;
2900
        /* 6,7 are implementation dependent */
2901
        default:
2902
            goto die;
2903
        }
2904
        break;
2905
    case 10:
2906
        switch (sel) {
2907
        case 0:
2908
            gen_op_mfc0_entryhi();
2909
            rn = "EntryHi";
2910
            break;
2911
        default:
2912
            goto die;
2913
        }
2914
        break;
2915
    case 11:
2916
        switch (sel) {
2917
        case 0:
2918
            gen_op_mfc0_compare();
2919
            rn = "Compare";
2920
            break;
2921
        /* 6,7 are implementation dependent */
2922
        default:
2923
            goto die;
2924
        }
2925
        break;
2926
    case 12:
2927
        switch (sel) {
2928
        case 0:
2929
            gen_op_mfc0_status();
2930
            rn = "Status";
2931
            break;
2932
        case 1:
2933
            check_insn(env, ctx, ISA_MIPS32R2);
2934
            gen_op_mfc0_intctl();
2935
            rn = "IntCtl";
2936
            break;
2937
        case 2:
2938
            check_insn(env, ctx, ISA_MIPS32R2);
2939
            gen_op_mfc0_srsctl();
2940
            rn = "SRSCtl";
2941
            break;
2942
        case 3:
2943
            check_insn(env, ctx, ISA_MIPS32R2);
2944
            gen_op_mfc0_srsmap();
2945
            rn = "SRSMap";
2946
            break;
2947
        default:
2948
            goto die;
2949
       }
2950
        break;
2951
    case 13:
2952
        switch (sel) {
2953
        case 0:
2954
            gen_op_mfc0_cause();
2955
            rn = "Cause";
2956
            break;
2957
        default:
2958
            goto die;
2959
       }
2960
        break;
2961
    case 14:
2962
        switch (sel) {
2963
        case 0:
2964
            gen_op_mfc0_epc();
2965
            rn = "EPC";
2966
            break;
2967
        default:
2968
            goto die;
2969
        }
2970
        break;
2971
    case 15:
2972
        switch (sel) {
2973
        case 0:
2974
            gen_op_mfc0_prid();
2975
            rn = "PRid";
2976
            break;
2977
        case 1:
2978
            check_insn(env, ctx, ISA_MIPS32R2);
2979
            gen_op_mfc0_ebase();
2980
            rn = "EBase";
2981
            break;
2982
        default:
2983
            goto die;
2984
       }
2985
        break;
2986
    case 16:
2987
        switch (sel) {
2988
        case 0:
2989
            gen_op_mfc0_config0();
2990
            rn = "Config";
2991
            break;
2992
        case 1:
2993
            gen_op_mfc0_config1();
2994
            rn = "Config1";
2995
            break;
2996
        case 2:
2997
            gen_op_mfc0_config2();
2998
            rn = "Config2";
2999
            break;
3000
        case 3:
3001
            gen_op_mfc0_config3();
3002
            rn = "Config3";
3003
            break;
3004
        /* 4,5 are reserved */
3005
        /* 6,7 are implementation dependent */
3006
        case 6:
3007
            gen_op_mfc0_config6();
3008
            rn = "Config6";
3009
            break;
3010
        case 7:
3011
            gen_op_mfc0_config7();
3012
            rn = "Config7";
3013
            break;
3014
        default:
3015
            goto die;
3016
        }
3017
        break;
3018
    case 17:
3019
        switch (sel) {
3020
        case 0:
3021
            gen_op_mfc0_lladdr();
3022
            rn = "LLAddr";
3023
            break;
3024
        default:
3025
            goto die;
3026
        }
3027
        break;
3028
    case 18:
3029
        switch (sel) {
3030
        case 0 ... 7:
3031
            gen_op_mfc0_watchlo(sel);
3032
            rn = "WatchLo";
3033
            break;
3034
        default:
3035
            goto die;
3036
        }
3037
        break;
3038
    case 19:
3039
        switch (sel) {
3040
        case 0 ...7:
3041
            gen_op_mfc0_watchhi(sel);
3042
            rn = "WatchHi";
3043
            break;
3044
        default:
3045
            goto die;
3046
        }
3047
        break;
3048
    case 20:
3049
        switch (sel) {
3050
        case 0:
3051
#if defined(TARGET_MIPS64)
3052
            check_insn(env, ctx, ISA_MIPS3);
3053
            gen_op_mfc0_xcontext();
3054
            rn = "XContext";
3055
            break;
3056
#endif
3057
        default:
3058
            goto die;
3059
        }
3060
        break;
3061
    case 21:
3062
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3063
        switch (sel) {
3064
        case 0:
3065
            gen_op_mfc0_framemask();
3066
            rn = "Framemask";
3067
            break;
3068
        default:
3069
            goto die;
3070
        }
3071
        break;
3072
    case 22:
3073
        /* ignored */
3074
        rn = "'Diagnostic"; /* implementation dependent */
3075
        break;
3076
    case 23:
3077
        switch (sel) {
3078
        case 0:
3079
            gen_op_mfc0_debug(); /* EJTAG support */
3080
            rn = "Debug";
3081
            break;
3082
        case 1:
3083
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3084
            rn = "TraceControl";
3085
//            break;
3086
        case 2:
3087
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3088
            rn = "TraceControl2";
3089
//            break;
3090
        case 3:
3091
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3092
            rn = "UserTraceData";
3093
//            break;
3094
        case 4:
3095
//            gen_op_mfc0_debug(); /* PDtrace support */
3096
            rn = "TraceBPC";
3097
//            break;
3098
        default:
3099
            goto die;
3100
        }
3101
        break;
3102
    case 24:
3103
        switch (sel) {
3104
        case 0:
3105
            gen_op_mfc0_depc(); /* EJTAG support */
3106
            rn = "DEPC";
3107
            break;
3108
        default:
3109
            goto die;
3110
        }
3111
        break;
3112
    case 25:
3113
        switch (sel) {
3114
        case 0:
3115
            gen_op_mfc0_performance0();
3116
            rn = "Performance0";
3117
            break;
3118
        case 1:
3119
//            gen_op_mfc0_performance1();
3120
            rn = "Performance1";
3121
//            break;
3122
        case 2:
3123
//            gen_op_mfc0_performance2();
3124
            rn = "Performance2";
3125
//            break;
3126
        case 3:
3127
//            gen_op_mfc0_performance3();
3128
            rn = "Performance3";
3129
//            break;
3130
        case 4:
3131
//            gen_op_mfc0_performance4();
3132
            rn = "Performance4";
3133
//            break;
3134
        case 5:
3135
//            gen_op_mfc0_performance5();
3136
            rn = "Performance5";
3137
//            break;
3138
        case 6:
3139
//            gen_op_mfc0_performance6();
3140
            rn = "Performance6";
3141
//            break;
3142
        case 7:
3143
//            gen_op_mfc0_performance7();
3144
            rn = "Performance7";
3145
//            break;
3146
        default:
3147
            goto die;
3148
        }
3149
        break;
3150
    case 26:
3151
       rn = "ECC";
3152
       break;
3153
    case 27:
3154
        switch (sel) {
3155
        /* ignored */
3156
        case 0 ... 3:
3157
            rn = "CacheErr";
3158
            break;
3159
        default:
3160
            goto die;
3161
        }
3162
        break;
3163
    case 28:
3164
        switch (sel) {
3165
        case 0:
3166
        case 2:
3167
        case 4:
3168
        case 6:
3169
            gen_op_mfc0_taglo();
3170
            rn = "TagLo";
3171
            break;
3172
        case 1:
3173
        case 3:
3174
        case 5:
3175
        case 7:
3176
            gen_op_mfc0_datalo();
3177
            rn = "DataLo";
3178
            break;
3179
        default:
3180
            goto die;
3181
        }
3182
        break;
3183
    case 29:
3184
        switch (sel) {
3185
        case 0:
3186
        case 2:
3187
        case 4:
3188
        case 6:
3189
            gen_op_mfc0_taghi();
3190
            rn = "TagHi";
3191
            break;
3192
        case 1:
3193
        case 3:
3194
        case 5:
3195
        case 7:
3196
            gen_op_mfc0_datahi();
3197
            rn = "DataHi";
3198
            break;
3199
        default:
3200
            goto die;
3201
        }
3202
        break;
3203
    case 30:
3204
        switch (sel) {
3205
        case 0:
3206
            gen_op_mfc0_errorepc();
3207
            rn = "ErrorEPC";
3208
            break;
3209
        default:
3210
            goto die;
3211
        }
3212
        break;
3213
    case 31:
3214
        switch (sel) {
3215
        case 0:
3216
            gen_op_mfc0_desave(); /* EJTAG support */
3217
            rn = "DESAVE";
3218
            break;
3219
        default:
3220
            goto die;
3221
        }
3222
        break;
3223
    default:
3224
       goto die;
3225
    }
3226
#if defined MIPS_DEBUG_DISAS
3227
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3228
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3229
                rn, reg, sel);
3230
    }
3231
#endif
3232
    return;
3233

    
3234
die:
3235
#if defined MIPS_DEBUG_DISAS
3236
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3237
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3238
                rn, reg, sel);
3239
    }
3240
#endif
3241
    generate_exception(ctx, EXCP_RI);
3242
}
3243

    
3244
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3245
{
3246
    const char *rn = "invalid";
3247

    
3248
    if (sel != 0)
3249
        check_insn(env, ctx, ISA_MIPS32);
3250

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

    
3833
die:
3834
#if defined MIPS_DEBUG_DISAS
3835
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3836
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3837
                rn, reg, sel);
3838
    }
3839
#endif
3840
    generate_exception(ctx, EXCP_RI);
3841
}
3842

    
3843
#if defined(TARGET_MIPS64)
3844
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3845
{
3846
    const char *rn = "invalid";
3847

    
3848
    if (sel != 0)
3849
        check_insn(env, ctx, ISA_MIPS64);
3850

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

    
4391
die:
4392
#if defined MIPS_DEBUG_DISAS
4393
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4394
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4395
                rn, reg, sel);
4396
    }
4397
#endif
4398
    generate_exception(ctx, EXCP_RI);
4399
}
4400

    
4401
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4402
{
4403
    const char *rn = "invalid";
4404

    
4405
    if (sel != 0)
4406
        check_insn(env, ctx, ISA_MIPS64);
4407

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

    
4977
die:
4978
#if defined MIPS_DEBUG_DISAS
4979
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4980
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4981
                rn, reg, sel);
4982
    }
4983
#endif
4984
    generate_exception(ctx, EXCP_RI);
4985
}
4986
#endif /* TARGET_MIPS64 */
4987

    
4988
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4989
                     int u, int sel, int h)
4990
{
4991
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4992

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

    
5142
die:
5143
#if defined MIPS_DEBUG_DISAS
5144
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5145
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5146
                rt, u, sel, h);
5147
    }
5148
#endif
5149
    generate_exception(ctx, EXCP_RI);
5150
}
5151

    
5152
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5153
                     int u, int sel, int h)
5154
{
5155
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5156

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

    
5306
die:
5307
#if defined MIPS_DEBUG_DISAS
5308
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5309
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5310
                rd, u, sel, h);
5311
    }
5312
#endif
5313
    generate_exception(ctx, EXCP_RI);
5314
}
5315

    
5316
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5317
{
5318
    const char *opn = "ldst";
5319

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

    
5435
/* CP1 Branches (before delay slot) */
5436
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5437
                                 int32_t cc, int32_t offset)
5438
{
5439
    target_ulong btarget;
5440
    const char *opn = "cp1 cond branch";
5441

    
5442
    if (cc != 0)
5443
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5444

    
5445
    btarget = ctx->pc + 4 + offset;
5446

    
5447
    switch (op) {
5448
    case OPC_BC1F:
5449
        gen_op_bc1f(cc);
5450
        opn = "bc1f";
5451
        goto not_likely;
5452
    case OPC_BC1FL:
5453
        gen_op_bc1f(cc);
5454
        opn = "bc1fl";
5455
        goto likely;
5456
    case OPC_BC1T:
5457
        gen_op_bc1t(cc);
5458
        opn = "bc1t";
5459
        goto not_likely;
5460
    case OPC_BC1TL:
5461
        gen_op_bc1t(cc);
5462
        opn = "bc1tl";
5463
    likely:
5464
        ctx->hflags |= MIPS_HFLAG_BL;
5465
        tcg_gen_set_bcond();
5466
        break;
5467
    case OPC_BC1FANY2:
5468
        gen_op_bc1any2f(cc);
5469
        opn = "bc1any2f";
5470
        goto not_likely;
5471
    case OPC_BC1TANY2:
5472
        gen_op_bc1any2t(cc);
5473
        opn = "bc1any2t";
5474
        goto not_likely;
5475
    case OPC_BC1FANY4:
5476
        gen_op_bc1any4f(cc);
5477
        opn = "bc1any4f";
5478
        goto not_likely;
5479
    case OPC_BC1TANY4:
5480
        gen_op_bc1any4t(cc);
5481
        opn = "bc1any4t";
5482
    not_likely:
5483
        ctx->hflags |= MIPS_HFLAG_BC;
5484
        tcg_gen_set_bcond();
5485
        break;
5486
    default:
5487
        MIPS_INVAL(opn);
5488
        generate_exception (ctx, EXCP_RI);
5489
        return;
5490
    }
5491
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5492
               ctx->hflags, btarget);
5493
    ctx->btarget = btarget;
5494
}
5495

    
5496
/* Coprocessor 1 (FPU) */
5497

    
5498
#define FOP(func, fmt) (((fmt) << 21) | (func))
5499

    
5500
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5501
{
5502
    const char *opn = "cp1 move";
5503

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

    
5559
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5560
{
5561
    uint32_t ccbit;
5562

    
5563
    GEN_LOAD_REG_T0(rd);
5564
    GEN_LOAD_REG_T1(rs);
5565
    if (cc) {
5566
        ccbit = 1 << (24 + cc);
5567
    } else
5568
        ccbit = 1 << 23;
5569
    if (!tf)
5570
        gen_op_movf(ccbit);
5571
    else
5572
        gen_op_movt(ccbit);
5573
    GEN_STORE_T0_REG(rd);
5574
}
5575

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

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

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

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

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

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

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

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

    
6632
#if defined(TARGET_MIPS64)
6633

    
6634
/* MDMX extension to MIPS64 */
6635

    
6636
#endif
6637

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

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

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

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

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

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

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

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

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

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

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

    
7241
    if (search_pc && loglevel)
7242
        fprintf (logfile, "search pc %d\n", search_pc);
7243

    
7244
    num_temps = 0;
7245
    memset(temps, 0, sizeof(temps));
7246

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

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

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

    
7312
        if (env->singlestep_enabled)
7313
            break;
7314

    
7315
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7316
            break;
7317

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

    
7370
    return 0;
7371
}
7372

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

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

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

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

    
7406

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

    
7418
#undef printfpr
7419
}
7420

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

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

    
7439
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7440

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

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

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

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

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

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

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

    
7495
static void mips_tcg_init(void)
7496
{
7497
    static int inited;
7498

    
7499
    /* Initialize various static tables. */
7500
    if (inited)
7501
        return;
7502

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

    
7518
    inited = 1;
7519
}
7520

    
7521
#include "translate_init.c"
7522

    
7523
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7524
{
7525
    CPUMIPSState *env;
7526
    const mips_def_t *def;
7527

    
7528
    def = cpu_mips_find_by_name(cpu_model);
7529
    if (!def)
7530
        return NULL;
7531
    env = qemu_mallocz(sizeof(CPUMIPSState));
7532
    if (!env)
7533
        return NULL;
7534
    env->cpu_model = def;
7535

    
7536
    cpu_exec_init(env);
7537
    env->cpu_model_str = cpu_model;
7538
    mips_tcg_init();
7539
    cpu_reset(env);
7540
    return env;
7541
}
7542

    
7543
void cpu_reset (CPUMIPSState *env)
7544
{
7545
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7546

    
7547
    tlb_flush(env, 1);
7548

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

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

    
7589
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7590
                unsigned long searched_pc, int pc_pos, void *puc)
7591
{
7592
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7593
    env->hflags &= ~MIPS_HFLAG_BMASK;
7594
    env->hflags |= gen_opc_hflags[pc_pos];
7595
}