Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 57fec1fe

History | View | Annotate | Download (190.3 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 "tcg-op.h"
33

    
34
//#define MIPS_DEBUG_DISAS
35
//#define MIPS_DEBUG_SIGN_EXTENSIONS
36
//#define MIPS_SINGLE_STEP
37

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

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

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

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

    
182
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
183

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
384
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
385

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

    
398
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
399

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

    
423

    
424
const unsigned char *regnames[] =
425
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
426
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
427
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
428
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
429

    
430
/* Warning: no function for r0 register (hard wired to zero) */
431
#define GEN32(func, NAME)                        \
432
static GenOpFunc *NAME ## _table [32] = {        \
433
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
434
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
435
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
436
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
437
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
438
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
439
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
440
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
441
};                                               \
442
static always_inline void func(int n)            \
443
{                                                \
444
    NAME ## _table[n]();                         \
445
}
446

    
447
/* General purpose registers moves */
448
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
449
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
450
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
451

    
452
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
453
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
454

    
455
/* Moves to/from shadow registers */
456
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
457
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
458

    
459
static const char *fregnames[] =
460
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
461
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
462
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
463
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
464

    
465
#define FGEN32(func, NAME)                       \
466
static GenOpFunc *NAME ## _table [32] = {        \
467
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
468
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
469
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
470
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
471
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
472
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
473
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
474
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
475
};                                               \
476
static always_inline void func(int n)            \
477
{                                                \
478
    NAME ## _table[n]();                         \
479
}
480

    
481
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
482
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
485
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
486

    
487
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
488
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
489

    
490
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
491
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
492

    
493
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
494
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
495

    
496
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
497
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
498

    
499
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
500
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
501

    
502
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
503
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
504

    
505
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
506
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
507

    
508
#define FOP_CONDS(type, fmt)                                            \
509
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
510
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
511
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
512
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
513
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
514
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
515
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
516
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
517
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
518
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
519
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
520
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
521
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
522
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
523
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
524
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
525
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
526
};                                                                      \
527
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
528
{                                                                       \
529
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
530
}
531

    
532
FOP_CONDS(, d)
533
FOP_CONDS(abs, d)
534
FOP_CONDS(, s)
535
FOP_CONDS(abs, s)
536
FOP_CONDS(, ps)
537
FOP_CONDS(abs, ps)
538

    
539
typedef struct DisasContext {
540
    struct TranslationBlock *tb;
541
    target_ulong pc, saved_pc;
542
    uint32_t opcode;
543
    uint32_t fp_status;
544
    /* Routine used to access memory */
545
    int mem_idx;
546
    uint32_t hflags, saved_hflags;
547
    int bstate;
548
    target_ulong btarget;
549
    void *last_T0_store;
550
    int last_T0_gpr;
551
} DisasContext;
552

    
553
enum {
554
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
555
                      * exception condition
556
                      */
557
    BS_STOP     = 1, /* We want to stop translation for any reason */
558
    BS_BRANCH   = 2, /* We reached a branch condition     */
559
    BS_EXCP     = 3, /* We reached an exception condition */
560
};
561

    
562
#ifdef MIPS_DEBUG_DISAS
563
#define MIPS_DEBUG(fmt, args...)                                              \
564
do {                                                                          \
565
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
566
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
567
                ctx->pc, ctx->opcode , ##args);                               \
568
    }                                                                         \
569
} while (0)
570
#else
571
#define MIPS_DEBUG(fmt, args...) do { } while(0)
572
#endif
573

    
574
#define MIPS_INVAL(op)                                                        \
575
do {                                                                          \
576
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
577
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
578
} while (0)
579

    
580
#define GEN_LOAD_REG_T0(Rn)                                                   \
581
do {                                                                          \
582
    if (Rn == 0) {                                                            \
583
        gen_op_reset_T0();                                                    \
584
    } else {                                                                  \
585
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
586
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
587
                gen_op_load_gpr_T0(Rn);                                       \
588
        }                                                                     \
589
    }                                                                         \
590
} while (0)
591

    
592
#define GEN_LOAD_REG_T1(Rn)                                                   \
593
do {                                                                          \
594
    if (Rn == 0) {                                                            \
595
        gen_op_reset_T1();                                                    \
596
    } else {                                                                  \
597
        gen_op_load_gpr_T1(Rn);                                               \
598
    }                                                                         \
599
} while (0)
600

    
601
#define GEN_LOAD_REG_T2(Rn)                                                   \
602
do {                                                                          \
603
    if (Rn == 0) {                                                            \
604
        gen_op_reset_T2();                                                    \
605
    } else {                                                                  \
606
        gen_op_load_gpr_T2(Rn);                                               \
607
    }                                                                         \
608
} while (0)
609

    
610
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
611
do {                                                                          \
612
    if (Rn == 0) {                                                            \
613
        glue(gen_op_reset_, Tn)();                                            \
614
    } else {                                                                  \
615
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
616
    }                                                                         \
617
} while (0)
618

    
619
#if defined(TARGET_MIPS64)
620
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
621
do {                                                                          \
622
    if (Imm == 0) {                                                           \
623
        glue(gen_op_reset_, Tn)();                                            \
624
    } else if ((int32_t)Imm == Imm) {                                         \
625
        glue(gen_op_set_, Tn)(Imm);                                           \
626
    } else {                                                                  \
627
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
628
    }                                                                         \
629
} while (0)
630
#else
631
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
632
do {                                                                          \
633
    if (Imm == 0) {                                                           \
634
        glue(gen_op_reset_, Tn)();                                            \
635
    } else {                                                                  \
636
        glue(gen_op_set_, Tn)(Imm);                                           \
637
    }                                                                         \
638
} while (0)
639
#endif
640

    
641
#define GEN_STORE_T0_REG(Rn)                                                  \
642
do {                                                                          \
643
    if (Rn != 0) {                                                            \
644
        glue(gen_op_store_T0,_gpr)(Rn);                                       \
645
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
646
        ctx->glue(last_T0,_gpr) = Rn;                                         \
647
    }                                                                         \
648
} while (0)
649

    
650
#define GEN_STORE_T1_REG(Rn)                                                  \
651
do {                                                                          \
652
    if (Rn != 0)                                                              \
653
        glue(gen_op_store_T1,_gpr)(Rn);                                       \
654
} while (0)
655

    
656
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
657
do {                                                                          \
658
    if (Rn != 0) {                                                            \
659
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
660
    }                                                                         \
661
} while (0)
662

    
663
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
664
do {                                                                          \
665
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
666
} while (0)
667

    
668
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
669
do {                                                                          \
670
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
671
} while (0)
672

    
673
static always_inline void gen_save_pc(target_ulong pc)
674
{
675
#if defined(TARGET_MIPS64)
676
    if (pc == (int32_t)pc) {
677
        gen_op_save_pc(pc);
678
    } else {
679
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
680
    }
681
#else
682
    gen_op_save_pc(pc);
683
#endif
684
}
685

    
686
static always_inline void gen_save_btarget(target_ulong btarget)
687
{
688
#if defined(TARGET_MIPS64)
689
    if (btarget == (int32_t)btarget) {
690
        gen_op_save_btarget(btarget);
691
    } else {
692
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
693
    }
694
#else
695
    gen_op_save_btarget(btarget);
696
#endif
697
}
698

    
699
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
700
{
701
#if defined MIPS_DEBUG_DISAS
702
    if (loglevel & CPU_LOG_TB_IN_ASM) {
703
            fprintf(logfile, "hflags %08x saved %08x\n",
704
                    ctx->hflags, ctx->saved_hflags);
705
    }
706
#endif
707
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
708
        gen_save_pc(ctx->pc);
709
        ctx->saved_pc = ctx->pc;
710
    }
711
    if (ctx->hflags != ctx->saved_hflags) {
712
        gen_op_save_state(ctx->hflags);
713
        ctx->saved_hflags = ctx->hflags;
714
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
715
        case MIPS_HFLAG_BR:
716
            gen_op_save_breg_target();
717
            break;
718
        case MIPS_HFLAG_BC:
719
            gen_op_save_bcond();
720
            /* fall through */
721
        case MIPS_HFLAG_BL:
722
            /* bcond was already saved by the BL insn */
723
            /* fall through */
724
        case MIPS_HFLAG_B:
725
            gen_save_btarget(ctx->btarget);
726
            break;
727
        }
728
    }
729
}
730

    
731
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
732
{
733
    ctx->saved_hflags = ctx->hflags;
734
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
735
    case MIPS_HFLAG_BR:
736
        gen_op_restore_breg_target();
737
        break;
738
    case MIPS_HFLAG_B:
739
        ctx->btarget = env->btarget;
740
        break;
741
    case MIPS_HFLAG_BC:
742
    case MIPS_HFLAG_BL:
743
        ctx->btarget = env->btarget;
744
        gen_op_restore_bcond();
745
        break;
746
    }
747
}
748

    
749
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
750
{
751
#if defined MIPS_DEBUG_DISAS
752
    if (loglevel & CPU_LOG_TB_IN_ASM)
753
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
754
#endif
755
    save_cpu_state(ctx, 1);
756
    if (err == 0)
757
        gen_op_raise_exception(excp);
758
    else
759
        gen_op_raise_exception_err(excp, err);
760
    ctx->bstate = BS_EXCP;
761
}
762

    
763
static always_inline void generate_exception (DisasContext *ctx, int excp)
764
{
765
    generate_exception_err (ctx, excp, 0);
766
}
767

    
768
static always_inline void check_cp0_enabled(DisasContext *ctx)
769
{
770
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
771
        generate_exception_err(ctx, EXCP_CpU, 1);
772
}
773

    
774
static always_inline void check_cp1_enabled(DisasContext *ctx)
775
{
776
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
777
        generate_exception_err(ctx, EXCP_CpU, 1);
778
}
779

    
780
/* Verify that the processor is running with COP1X instructions enabled.
781
   This is associated with the nabla symbol in the MIPS32 and MIPS64
782
   opcode tables.  */
783

    
784
static always_inline void check_cop1x(DisasContext *ctx)
785
{
786
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
787
        generate_exception(ctx, EXCP_RI);
788
}
789

    
790
/* Verify that the processor is running with 64-bit floating-point
791
   operations enabled.  */
792

    
793
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
794
{
795
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
796
        generate_exception(ctx, EXCP_RI);
797
}
798

    
799
/*
800
 * Verify if floating point register is valid; an operation is not defined
801
 * if bit 0 of any register specification is set and the FR bit in the
802
 * Status register equals zero, since the register numbers specify an
803
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
804
 * in the Status register equals one, both even and odd register numbers
805
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
806
 *
807
 * Multiple 64 bit wide registers can be checked by calling
808
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
809
 */
810
void check_cp1_registers(DisasContext *ctx, int regs)
811
{
812
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
813
        generate_exception(ctx, EXCP_RI);
814
}
815

    
816
/* This code generates a "reserved instruction" exception if the
817
   CPU does not support the instruction set corresponding to flags. */
818
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
819
{
820
    if (unlikely(!(env->insn_flags & flags)))
821
        generate_exception(ctx, EXCP_RI);
822
}
823

    
824
/* This code generates a "reserved instruction" exception if 64-bit
825
   instructions are not enabled. */
826
static always_inline void check_mips_64(DisasContext *ctx)
827
{
828
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
829
        generate_exception(ctx, EXCP_RI);
830
}
831

    
832
#if defined(CONFIG_USER_ONLY)
833
#define op_ldst(name)        gen_op_##name##_raw()
834
#define OP_LD_TABLE(width)
835
#define OP_ST_TABLE(width)
836
#else
837
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
838
#define OP_LD_TABLE(width)                                                    \
839
static GenOpFunc *gen_op_l##width[] = {                                       \
840
    &gen_op_l##width##_kernel,                                                \
841
    &gen_op_l##width##_super,                                                 \
842
    &gen_op_l##width##_user,                                                  \
843
}
844
#define OP_ST_TABLE(width)                                                    \
845
static GenOpFunc *gen_op_s##width[] = {                                       \
846
    &gen_op_s##width##_kernel,                                                \
847
    &gen_op_s##width##_super,                                                 \
848
    &gen_op_s##width##_user,                                                  \
849
}
850
#endif
851

    
852
#if defined(TARGET_MIPS64)
853
OP_LD_TABLE(d);
854
OP_LD_TABLE(dl);
855
OP_LD_TABLE(dr);
856
OP_ST_TABLE(d);
857
OP_ST_TABLE(dl);
858
OP_ST_TABLE(dr);
859
OP_LD_TABLE(ld);
860
OP_ST_TABLE(cd);
861
OP_LD_TABLE(wu);
862
#endif
863
OP_LD_TABLE(w);
864
OP_LD_TABLE(wl);
865
OP_LD_TABLE(wr);
866
OP_ST_TABLE(w);
867
OP_ST_TABLE(wl);
868
OP_ST_TABLE(wr);
869
OP_LD_TABLE(h);
870
OP_LD_TABLE(hu);
871
OP_ST_TABLE(h);
872
OP_LD_TABLE(b);
873
OP_LD_TABLE(bu);
874
OP_ST_TABLE(b);
875
OP_LD_TABLE(l);
876
OP_ST_TABLE(c);
877
OP_LD_TABLE(wc1);
878
OP_ST_TABLE(wc1);
879
OP_LD_TABLE(dc1);
880
OP_ST_TABLE(dc1);
881
OP_LD_TABLE(uxc1);
882
OP_ST_TABLE(uxc1);
883

    
884
/* Load and store */
885
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
886
                      int base, int16_t offset)
887
{
888
    const char *opn = "ldst";
889

    
890
    if (base == 0) {
891
        GEN_LOAD_IMM_TN(T0, offset);
892
    } else if (offset == 0) {
893
        gen_op_load_gpr_T0(base);
894
    } else {
895
        gen_op_load_gpr_T0(base);
896
        gen_op_set_T1(offset);
897
        gen_op_addr_add();
898
    }
899
    /* Don't do NOP if destination is zero: we must perform the actual
900
       memory access. */
901
    switch (opc) {
902
#if defined(TARGET_MIPS64)
903
    case OPC_LWU:
904
        op_ldst(lwu);
905
        GEN_STORE_T0_REG(rt);
906
        opn = "lwu";
907
        break;
908
    case OPC_LD:
909
        op_ldst(ld);
910
        GEN_STORE_T0_REG(rt);
911
        opn = "ld";
912
        break;
913
    case OPC_LLD:
914
        op_ldst(lld);
915
        GEN_STORE_T0_REG(rt);
916
        opn = "lld";
917
        break;
918
    case OPC_SD:
919
        GEN_LOAD_REG_T1(rt);
920
        op_ldst(sd);
921
        opn = "sd";
922
        break;
923
    case OPC_SCD:
924
        save_cpu_state(ctx, 1);
925
        GEN_LOAD_REG_T1(rt);
926
        op_ldst(scd);
927
        GEN_STORE_T0_REG(rt);
928
        opn = "scd";
929
        break;
930
    case OPC_LDL:
931
        GEN_LOAD_REG_T1(rt);
932
        op_ldst(ldl);
933
        GEN_STORE_T1_REG(rt);
934
        opn = "ldl";
935
        break;
936
    case OPC_SDL:
937
        GEN_LOAD_REG_T1(rt);
938
        op_ldst(sdl);
939
        opn = "sdl";
940
        break;
941
    case OPC_LDR:
942
        GEN_LOAD_REG_T1(rt);
943
        op_ldst(ldr);
944
        GEN_STORE_T1_REG(rt);
945
        opn = "ldr";
946
        break;
947
    case OPC_SDR:
948
        GEN_LOAD_REG_T1(rt);
949
        op_ldst(sdr);
950
        opn = "sdr";
951
        break;
952
#endif
953
    case OPC_LW:
954
        op_ldst(lw);
955
        GEN_STORE_T0_REG(rt);
956
        opn = "lw";
957
        break;
958
    case OPC_SW:
959
        GEN_LOAD_REG_T1(rt);
960
        op_ldst(sw);
961
        opn = "sw";
962
        break;
963
    case OPC_LH:
964
        op_ldst(lh);
965
        GEN_STORE_T0_REG(rt);
966
        opn = "lh";
967
        break;
968
    case OPC_SH:
969
        GEN_LOAD_REG_T1(rt);
970
        op_ldst(sh);
971
        opn = "sh";
972
        break;
973
    case OPC_LHU:
974
        op_ldst(lhu);
975
        GEN_STORE_T0_REG(rt);
976
        opn = "lhu";
977
        break;
978
    case OPC_LB:
979
        op_ldst(lb);
980
        GEN_STORE_T0_REG(rt);
981
        opn = "lb";
982
        break;
983
    case OPC_SB:
984
        GEN_LOAD_REG_T1(rt);
985
        op_ldst(sb);
986
        opn = "sb";
987
        break;
988
    case OPC_LBU:
989
        op_ldst(lbu);
990
        GEN_STORE_T0_REG(rt);
991
        opn = "lbu";
992
        break;
993
    case OPC_LWL:
994
        GEN_LOAD_REG_T1(rt);
995
        op_ldst(lwl);
996
        GEN_STORE_T1_REG(rt);
997
        opn = "lwl";
998
        break;
999
    case OPC_SWL:
1000
        GEN_LOAD_REG_T1(rt);
1001
        op_ldst(swl);
1002
        opn = "swr";
1003
        break;
1004
    case OPC_LWR:
1005
        GEN_LOAD_REG_T1(rt);
1006
        op_ldst(lwr);
1007
        GEN_STORE_T1_REG(rt);
1008
        opn = "lwr";
1009
        break;
1010
    case OPC_SWR:
1011
        GEN_LOAD_REG_T1(rt);
1012
        op_ldst(swr);
1013
        opn = "swr";
1014
        break;
1015
    case OPC_LL:
1016
        op_ldst(ll);
1017
        GEN_STORE_T0_REG(rt);
1018
        opn = "ll";
1019
        break;
1020
    case OPC_SC:
1021
        save_cpu_state(ctx, 1);
1022
        GEN_LOAD_REG_T1(rt);
1023
        op_ldst(sc);
1024
        GEN_STORE_T0_REG(rt);
1025
        opn = "sc";
1026
        break;
1027
    default:
1028
        MIPS_INVAL(opn);
1029
        generate_exception(ctx, EXCP_RI);
1030
        return;
1031
    }
1032
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1033
}
1034

    
1035
/* Load and store */
1036
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1037
                      int base, int16_t offset)
1038
{
1039
    const char *opn = "flt_ldst";
1040

    
1041
    if (base == 0) {
1042
        GEN_LOAD_IMM_TN(T0, offset);
1043
    } else if (offset == 0) {
1044
        gen_op_load_gpr_T0(base);
1045
    } else {
1046
        gen_op_load_gpr_T0(base);
1047
        gen_op_set_T1(offset);
1048
        gen_op_addr_add();
1049
    }
1050
    /* Don't do NOP if destination is zero: we must perform the actual
1051
       memory access. */
1052
    switch (opc) {
1053
    case OPC_LWC1:
1054
        op_ldst(lwc1);
1055
        GEN_STORE_FTN_FREG(ft, WT0);
1056
        opn = "lwc1";
1057
        break;
1058
    case OPC_SWC1:
1059
        GEN_LOAD_FREG_FTN(WT0, ft);
1060
        op_ldst(swc1);
1061
        opn = "swc1";
1062
        break;
1063
    case OPC_LDC1:
1064
        op_ldst(ldc1);
1065
        GEN_STORE_FTN_FREG(ft, DT0);
1066
        opn = "ldc1";
1067
        break;
1068
    case OPC_SDC1:
1069
        GEN_LOAD_FREG_FTN(DT0, ft);
1070
        op_ldst(sdc1);
1071
        opn = "sdc1";
1072
        break;
1073
    default:
1074
        MIPS_INVAL(opn);
1075
        generate_exception(ctx, EXCP_RI);
1076
        return;
1077
    }
1078
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1079
}
1080

    
1081
/* Arithmetic with immediate operand */
1082
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1083
                           int rt, int rs, int16_t imm)
1084
{
1085
    target_ulong uimm;
1086
    const char *opn = "imm arith";
1087

    
1088
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1089
        /* If no destination, treat it as a NOP.
1090
           For addi, we must generate the overflow exception when needed. */
1091
        MIPS_DEBUG("NOP");
1092
        return;
1093
    }
1094
    uimm = (uint16_t)imm;
1095
    switch (opc) {
1096
    case OPC_ADDI:
1097
    case OPC_ADDIU:
1098
#if defined(TARGET_MIPS64)
1099
    case OPC_DADDI:
1100
    case OPC_DADDIU:
1101
#endif
1102
    case OPC_SLTI:
1103
    case OPC_SLTIU:
1104
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1105
        /* Fall through. */
1106
    case OPC_ANDI:
1107
    case OPC_ORI:
1108
    case OPC_XORI:
1109
        GEN_LOAD_REG_T0(rs);
1110
        GEN_LOAD_IMM_TN(T1, uimm);
1111
        break;
1112
    case OPC_LUI:
1113
        GEN_LOAD_IMM_TN(T0, imm << 16);
1114
        break;
1115
    case OPC_SLL:
1116
    case OPC_SRA:
1117
    case OPC_SRL:
1118
#if defined(TARGET_MIPS64)
1119
    case OPC_DSLL:
1120
    case OPC_DSRA:
1121
    case OPC_DSRL:
1122
    case OPC_DSLL32:
1123
    case OPC_DSRA32:
1124
    case OPC_DSRL32:
1125
#endif
1126
        uimm &= 0x1f;
1127
        GEN_LOAD_REG_T0(rs);
1128
        GEN_LOAD_IMM_TN(T1, uimm);
1129
        break;
1130
    }
1131
    switch (opc) {
1132
    case OPC_ADDI:
1133
        save_cpu_state(ctx, 1);
1134
        gen_op_addo();
1135
        opn = "addi";
1136
        break;
1137
    case OPC_ADDIU:
1138
        gen_op_add();
1139
        opn = "addiu";
1140
        break;
1141
#if defined(TARGET_MIPS64)
1142
    case OPC_DADDI:
1143
        save_cpu_state(ctx, 1);
1144
        gen_op_daddo();
1145
        opn = "daddi";
1146
        break;
1147
    case OPC_DADDIU:
1148
        gen_op_dadd();
1149
        opn = "daddiu";
1150
        break;
1151
#endif
1152
    case OPC_SLTI:
1153
        gen_op_lt();
1154
        opn = "slti";
1155
        break;
1156
    case OPC_SLTIU:
1157
        gen_op_ltu();
1158
        opn = "sltiu";
1159
        break;
1160
    case OPC_ANDI:
1161
        gen_op_and();
1162
        opn = "andi";
1163
        break;
1164
    case OPC_ORI:
1165
        gen_op_or();
1166
        opn = "ori";
1167
        break;
1168
    case OPC_XORI:
1169
        gen_op_xor();
1170
        opn = "xori";
1171
        break;
1172
    case OPC_LUI:
1173
        opn = "lui";
1174
        break;
1175
    case OPC_SLL:
1176
        gen_op_sll();
1177
        opn = "sll";
1178
        break;
1179
    case OPC_SRA:
1180
        gen_op_sra();
1181
        opn = "sra";
1182
        break;
1183
    case OPC_SRL:
1184
        switch ((ctx->opcode >> 21) & 0x1f) {
1185
        case 0:
1186
            gen_op_srl();
1187
            opn = "srl";
1188
            break;
1189
        case 1:
1190
            /* rotr is decoded as srl on non-R2 CPUs */
1191
            if (env->insn_flags & ISA_MIPS32R2) {
1192
                gen_op_rotr();
1193
                opn = "rotr";
1194
            } else {
1195
                gen_op_srl();
1196
                opn = "srl";
1197
            }
1198
            break;
1199
        default:
1200
            MIPS_INVAL("invalid srl flag");
1201
            generate_exception(ctx, EXCP_RI);
1202
            break;
1203
        }
1204
        break;
1205
#if defined(TARGET_MIPS64)
1206
    case OPC_DSLL:
1207
        gen_op_dsll();
1208
        opn = "dsll";
1209
        break;
1210
    case OPC_DSRA:
1211
        gen_op_dsra();
1212
        opn = "dsra";
1213
        break;
1214
    case OPC_DSRL:
1215
        switch ((ctx->opcode >> 21) & 0x1f) {
1216
        case 0:
1217
            gen_op_dsrl();
1218
            opn = "dsrl";
1219
            break;
1220
        case 1:
1221
            /* drotr is decoded as dsrl on non-R2 CPUs */
1222
            if (env->insn_flags & ISA_MIPS32R2) {
1223
                gen_op_drotr();
1224
                opn = "drotr";
1225
            } else {
1226
                gen_op_dsrl();
1227
                opn = "dsrl";
1228
            }
1229
            break;
1230
        default:
1231
            MIPS_INVAL("invalid dsrl flag");
1232
            generate_exception(ctx, EXCP_RI);
1233
            break;
1234
        }
1235
        break;
1236
    case OPC_DSLL32:
1237
        gen_op_dsll32();
1238
        opn = "dsll32";
1239
        break;
1240
    case OPC_DSRA32:
1241
        gen_op_dsra32();
1242
        opn = "dsra32";
1243
        break;
1244
    case OPC_DSRL32:
1245
        switch ((ctx->opcode >> 21) & 0x1f) {
1246
        case 0:
1247
            gen_op_dsrl32();
1248
            opn = "dsrl32";
1249
            break;
1250
        case 1:
1251
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1252
            if (env->insn_flags & ISA_MIPS32R2) {
1253
                gen_op_drotr32();
1254
                opn = "drotr32";
1255
            } else {
1256
                gen_op_dsrl32();
1257
                opn = "dsrl32";
1258
            }
1259
            break;
1260
        default:
1261
            MIPS_INVAL("invalid dsrl32 flag");
1262
            generate_exception(ctx, EXCP_RI);
1263
            break;
1264
        }
1265
        break;
1266
#endif
1267
    default:
1268
        MIPS_INVAL(opn);
1269
        generate_exception(ctx, EXCP_RI);
1270
        return;
1271
    }
1272
    GEN_STORE_T0_REG(rt);
1273
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1274
}
1275

    
1276
/* Arithmetic */
1277
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1278
                       int rd, int rs, int rt)
1279
{
1280
    const char *opn = "arith";
1281

    
1282
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1283
       && opc != OPC_DADD && opc != OPC_DSUB) {
1284
        /* If no destination, treat it as a NOP.
1285
           For add & sub, we must generate the overflow exception when needed. */
1286
        MIPS_DEBUG("NOP");
1287
        return;
1288
    }
1289
    GEN_LOAD_REG_T0(rs);
1290
    /* Specialcase the conventional move operation. */
1291
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1292
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1293
        GEN_STORE_T0_REG(rd);
1294
        return;
1295
    }
1296
    GEN_LOAD_REG_T1(rt);
1297
    switch (opc) {
1298
    case OPC_ADD:
1299
        save_cpu_state(ctx, 1);
1300
        gen_op_addo();
1301
        opn = "add";
1302
        break;
1303
    case OPC_ADDU:
1304
        gen_op_add();
1305
        opn = "addu";
1306
        break;
1307
    case OPC_SUB:
1308
        save_cpu_state(ctx, 1);
1309
        gen_op_subo();
1310
        opn = "sub";
1311
        break;
1312
    case OPC_SUBU:
1313
        gen_op_sub();
1314
        opn = "subu";
1315
        break;
1316
#if defined(TARGET_MIPS64)
1317
    case OPC_DADD:
1318
        save_cpu_state(ctx, 1);
1319
        gen_op_daddo();
1320
        opn = "dadd";
1321
        break;
1322
    case OPC_DADDU:
1323
        gen_op_dadd();
1324
        opn = "daddu";
1325
        break;
1326
    case OPC_DSUB:
1327
        save_cpu_state(ctx, 1);
1328
        gen_op_dsubo();
1329
        opn = "dsub";
1330
        break;
1331
    case OPC_DSUBU:
1332
        gen_op_dsub();
1333
        opn = "dsubu";
1334
        break;
1335
#endif
1336
    case OPC_SLT:
1337
        gen_op_lt();
1338
        opn = "slt";
1339
        break;
1340
    case OPC_SLTU:
1341
        gen_op_ltu();
1342
        opn = "sltu";
1343
        break;
1344
    case OPC_AND:
1345
        gen_op_and();
1346
        opn = "and";
1347
        break;
1348
    case OPC_NOR:
1349
        gen_op_nor();
1350
        opn = "nor";
1351
        break;
1352
    case OPC_OR:
1353
        gen_op_or();
1354
        opn = "or";
1355
        break;
1356
    case OPC_XOR:
1357
        gen_op_xor();
1358
        opn = "xor";
1359
        break;
1360
    case OPC_MUL:
1361
        gen_op_mul();
1362
        opn = "mul";
1363
        break;
1364
    case OPC_MOVN:
1365
        gen_op_movn(rd);
1366
        opn = "movn";
1367
        goto print;
1368
    case OPC_MOVZ:
1369
        gen_op_movz(rd);
1370
        opn = "movz";
1371
        goto print;
1372
    case OPC_SLLV:
1373
        gen_op_sllv();
1374
        opn = "sllv";
1375
        break;
1376
    case OPC_SRAV:
1377
        gen_op_srav();
1378
        opn = "srav";
1379
        break;
1380
    case OPC_SRLV:
1381
        switch ((ctx->opcode >> 6) & 0x1f) {
1382
        case 0:
1383
            gen_op_srlv();
1384
            opn = "srlv";
1385
            break;
1386
        case 1:
1387
            /* rotrv is decoded as srlv on non-R2 CPUs */
1388
            if (env->insn_flags & ISA_MIPS32R2) {
1389
                gen_op_rotrv();
1390
                opn = "rotrv";
1391
            } else {
1392
                gen_op_srlv();
1393
                opn = "srlv";
1394
            }
1395
            break;
1396
        default:
1397
            MIPS_INVAL("invalid srlv flag");
1398
            generate_exception(ctx, EXCP_RI);
1399
            break;
1400
        }
1401
        break;
1402
#if defined(TARGET_MIPS64)
1403
    case OPC_DSLLV:
1404
        gen_op_dsllv();
1405
        opn = "dsllv";
1406
        break;
1407
    case OPC_DSRAV:
1408
        gen_op_dsrav();
1409
        opn = "dsrav";
1410
        break;
1411
    case OPC_DSRLV:
1412
        switch ((ctx->opcode >> 6) & 0x1f) {
1413
        case 0:
1414
            gen_op_dsrlv();
1415
            opn = "dsrlv";
1416
            break;
1417
        case 1:
1418
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1419
            if (env->insn_flags & ISA_MIPS32R2) {
1420
                gen_op_drotrv();
1421
                opn = "drotrv";
1422
            } else {
1423
                gen_op_dsrlv();
1424
                opn = "dsrlv";
1425
            }
1426
            break;
1427
        default:
1428
            MIPS_INVAL("invalid dsrlv flag");
1429
            generate_exception(ctx, EXCP_RI);
1430
            break;
1431
        }
1432
        break;
1433
#endif
1434
    default:
1435
        MIPS_INVAL(opn);
1436
        generate_exception(ctx, EXCP_RI);
1437
        return;
1438
    }
1439
    GEN_STORE_T0_REG(rd);
1440
 print:
1441
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1442
}
1443

    
1444
/* Arithmetic on HI/LO registers */
1445
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1446
{
1447
    const char *opn = "hilo";
1448

    
1449
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1450
        /* Treat as NOP. */
1451
        MIPS_DEBUG("NOP");
1452
        return;
1453
    }
1454
    switch (opc) {
1455
    case OPC_MFHI:
1456
        gen_op_load_HI(0);
1457
        GEN_STORE_T0_REG(reg);
1458
        opn = "mfhi";
1459
        break;
1460
    case OPC_MFLO:
1461
        gen_op_load_LO(0);
1462
        GEN_STORE_T0_REG(reg);
1463
        opn = "mflo";
1464
        break;
1465
    case OPC_MTHI:
1466
        GEN_LOAD_REG_T0(reg);
1467
        gen_op_store_HI(0);
1468
        opn = "mthi";
1469
        break;
1470
    case OPC_MTLO:
1471
        GEN_LOAD_REG_T0(reg);
1472
        gen_op_store_LO(0);
1473
        opn = "mtlo";
1474
        break;
1475
    default:
1476
        MIPS_INVAL(opn);
1477
        generate_exception(ctx, EXCP_RI);
1478
        return;
1479
    }
1480
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1481
}
1482

    
1483
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1484
                        int rs, int rt)
1485
{
1486
    const char *opn = "mul/div";
1487

    
1488
    GEN_LOAD_REG_T0(rs);
1489
    GEN_LOAD_REG_T1(rt);
1490
    switch (opc) {
1491
    case OPC_DIV:
1492
        gen_op_div();
1493
        opn = "div";
1494
        break;
1495
    case OPC_DIVU:
1496
        gen_op_divu();
1497
        opn = "divu";
1498
        break;
1499
    case OPC_MULT:
1500
        gen_op_mult();
1501
        opn = "mult";
1502
        break;
1503
    case OPC_MULTU:
1504
        gen_op_multu();
1505
        opn = "multu";
1506
        break;
1507
#if defined(TARGET_MIPS64)
1508
    case OPC_DDIV:
1509
        gen_op_ddiv();
1510
        opn = "ddiv";
1511
        break;
1512
    case OPC_DDIVU:
1513
        gen_op_ddivu();
1514
        opn = "ddivu";
1515
        break;
1516
    case OPC_DMULT:
1517
        gen_op_dmult();
1518
        opn = "dmult";
1519
        break;
1520
    case OPC_DMULTU:
1521
        gen_op_dmultu();
1522
        opn = "dmultu";
1523
        break;
1524
#endif
1525
    case OPC_MADD:
1526
        gen_op_madd();
1527
        opn = "madd";
1528
        break;
1529
    case OPC_MADDU:
1530
        gen_op_maddu();
1531
        opn = "maddu";
1532
        break;
1533
    case OPC_MSUB:
1534
        gen_op_msub();
1535
        opn = "msub";
1536
        break;
1537
    case OPC_MSUBU:
1538
        gen_op_msubu();
1539
        opn = "msubu";
1540
        break;
1541
    default:
1542
        MIPS_INVAL(opn);
1543
        generate_exception(ctx, EXCP_RI);
1544
        return;
1545
    }
1546
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1547
}
1548

    
1549
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1550
                            int rd, int rs, int rt)
1551
{
1552
    const char *opn = "mul vr54xx";
1553

    
1554
    GEN_LOAD_REG_T0(rs);
1555
    GEN_LOAD_REG_T1(rt);
1556

    
1557
    switch (opc) {
1558
    case OPC_VR54XX_MULS:
1559
        gen_op_muls();
1560
        opn = "muls";
1561
        break;
1562
    case OPC_VR54XX_MULSU:
1563
        gen_op_mulsu();
1564
        opn = "mulsu";
1565
        break;
1566
    case OPC_VR54XX_MACC:
1567
        gen_op_macc();
1568
        opn = "macc";
1569
        break;
1570
    case OPC_VR54XX_MACCU:
1571
        gen_op_maccu();
1572
        opn = "maccu";
1573
        break;
1574
    case OPC_VR54XX_MSAC:
1575
        gen_op_msac();
1576
        opn = "msac";
1577
        break;
1578
    case OPC_VR54XX_MSACU:
1579
        gen_op_msacu();
1580
        opn = "msacu";
1581
        break;
1582
    case OPC_VR54XX_MULHI:
1583
        gen_op_mulhi();
1584
        opn = "mulhi";
1585
        break;
1586
    case OPC_VR54XX_MULHIU:
1587
        gen_op_mulhiu();
1588
        opn = "mulhiu";
1589
        break;
1590
    case OPC_VR54XX_MULSHI:
1591
        gen_op_mulshi();
1592
        opn = "mulshi";
1593
        break;
1594
    case OPC_VR54XX_MULSHIU:
1595
        gen_op_mulshiu();
1596
        opn = "mulshiu";
1597
        break;
1598
    case OPC_VR54XX_MACCHI:
1599
        gen_op_macchi();
1600
        opn = "macchi";
1601
        break;
1602
    case OPC_VR54XX_MACCHIU:
1603
        gen_op_macchiu();
1604
        opn = "macchiu";
1605
        break;
1606
    case OPC_VR54XX_MSACHI:
1607
        gen_op_msachi();
1608
        opn = "msachi";
1609
        break;
1610
    case OPC_VR54XX_MSACHIU:
1611
        gen_op_msachiu();
1612
        opn = "msachiu";
1613
        break;
1614
    default:
1615
        MIPS_INVAL("mul vr54xx");
1616
        generate_exception(ctx, EXCP_RI);
1617
        return;
1618
    }
1619
    GEN_STORE_T0_REG(rd);
1620
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1621
}
1622

    
1623
static void gen_cl (DisasContext *ctx, uint32_t opc,
1624
                    int rd, int rs)
1625
{
1626
    const char *opn = "CLx";
1627
    if (rd == 0) {
1628
        /* Treat as NOP. */
1629
        MIPS_DEBUG("NOP");
1630
        return;
1631
    }
1632
    GEN_LOAD_REG_T0(rs);
1633
    switch (opc) {
1634
    case OPC_CLO:
1635
        gen_op_clo();
1636
        opn = "clo";
1637
        break;
1638
    case OPC_CLZ:
1639
        gen_op_clz();
1640
        opn = "clz";
1641
        break;
1642
#if defined(TARGET_MIPS64)
1643
    case OPC_DCLO:
1644
        gen_op_dclo();
1645
        opn = "dclo";
1646
        break;
1647
    case OPC_DCLZ:
1648
        gen_op_dclz();
1649
        opn = "dclz";
1650
        break;
1651
#endif
1652
    default:
1653
        MIPS_INVAL(opn);
1654
        generate_exception(ctx, EXCP_RI);
1655
        return;
1656
    }
1657
    gen_op_store_T0_gpr(rd);
1658
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1659
}
1660

    
1661
/* Traps */
1662
static void gen_trap (DisasContext *ctx, uint32_t opc,
1663
                      int rs, int rt, int16_t imm)
1664
{
1665
    int cond;
1666

    
1667
    cond = 0;
1668
    /* Load needed operands */
1669
    switch (opc) {
1670
    case OPC_TEQ:
1671
    case OPC_TGE:
1672
    case OPC_TGEU:
1673
    case OPC_TLT:
1674
    case OPC_TLTU:
1675
    case OPC_TNE:
1676
        /* Compare two registers */
1677
        if (rs != rt) {
1678
            GEN_LOAD_REG_T0(rs);
1679
            GEN_LOAD_REG_T1(rt);
1680
            cond = 1;
1681
        }
1682
        break;
1683
    case OPC_TEQI:
1684
    case OPC_TGEI:
1685
    case OPC_TGEIU:
1686
    case OPC_TLTI:
1687
    case OPC_TLTIU:
1688
    case OPC_TNEI:
1689
        /* Compare register to immediate */
1690
        if (rs != 0 || imm != 0) {
1691
            GEN_LOAD_REG_T0(rs);
1692
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1693
            cond = 1;
1694
        }
1695
        break;
1696
    }
1697
    if (cond == 0) {
1698
        switch (opc) {
1699
        case OPC_TEQ:   /* rs == rs */
1700
        case OPC_TEQI:  /* r0 == 0  */
1701
        case OPC_TGE:   /* rs >= rs */
1702
        case OPC_TGEI:  /* r0 >= 0  */
1703
        case OPC_TGEU:  /* rs >= rs unsigned */
1704
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1705
            /* Always trap */
1706
            gen_op_set_T0(1);
1707
            break;
1708
        case OPC_TLT:   /* rs < rs           */
1709
        case OPC_TLTI:  /* r0 < 0            */
1710
        case OPC_TLTU:  /* rs < rs unsigned  */
1711
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1712
        case OPC_TNE:   /* rs != rs          */
1713
        case OPC_TNEI:  /* r0 != 0           */
1714
            /* Never trap: treat as NOP. */
1715
            return;
1716
        default:
1717
            MIPS_INVAL("trap");
1718
            generate_exception(ctx, EXCP_RI);
1719
            return;
1720
        }
1721
    } else {
1722
        switch (opc) {
1723
        case OPC_TEQ:
1724
        case OPC_TEQI:
1725
            gen_op_eq();
1726
            break;
1727
        case OPC_TGE:
1728
        case OPC_TGEI:
1729
            gen_op_ge();
1730
            break;
1731
        case OPC_TGEU:
1732
        case OPC_TGEIU:
1733
            gen_op_geu();
1734
            break;
1735
        case OPC_TLT:
1736
        case OPC_TLTI:
1737
            gen_op_lt();
1738
            break;
1739
        case OPC_TLTU:
1740
        case OPC_TLTIU:
1741
            gen_op_ltu();
1742
            break;
1743
        case OPC_TNE:
1744
        case OPC_TNEI:
1745
            gen_op_ne();
1746
            break;
1747
        default:
1748
            MIPS_INVAL("trap");
1749
            generate_exception(ctx, EXCP_RI);
1750
            return;
1751
        }
1752
    }
1753
    save_cpu_state(ctx, 1);
1754
    gen_op_trap();
1755
    ctx->bstate = BS_STOP;
1756
}
1757

    
1758
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1759
{
1760
    TranslationBlock *tb;
1761
    tb = ctx->tb;
1762
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1763
        tcg_gen_goto_tb(n);
1764
        gen_save_pc(dest);
1765
        tcg_gen_exit_tb((long)tb + n);
1766
    } else {
1767
        gen_save_pc(dest);
1768
        tcg_gen_exit_tb(0);
1769
    }
1770
}
1771

    
1772
/* Branches (before delay slot) */
1773
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1774
                                int rs, int rt, int32_t offset)
1775
{
1776
    target_ulong btarget = -1;
1777
    int blink = 0;
1778
    int bcond = 0;
1779

    
1780
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1781
#ifdef MIPS_DEBUG_DISAS
1782
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1783
            fprintf(logfile,
1784
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1785
                    ctx->pc);
1786
        }
1787
#endif
1788
        generate_exception(ctx, EXCP_RI);
1789
        return;
1790
    }
1791

    
1792
    /* Load needed operands */
1793
    switch (opc) {
1794
    case OPC_BEQ:
1795
    case OPC_BEQL:
1796
    case OPC_BNE:
1797
    case OPC_BNEL:
1798
        /* Compare two registers */
1799
        if (rs != rt) {
1800
            GEN_LOAD_REG_T0(rs);
1801
            GEN_LOAD_REG_T1(rt);
1802
            bcond = 1;
1803
        }
1804
        btarget = ctx->pc + 4 + offset;
1805
        break;
1806
    case OPC_BGEZ:
1807
    case OPC_BGEZAL:
1808
    case OPC_BGEZALL:
1809
    case OPC_BGEZL:
1810
    case OPC_BGTZ:
1811
    case OPC_BGTZL:
1812
    case OPC_BLEZ:
1813
    case OPC_BLEZL:
1814
    case OPC_BLTZ:
1815
    case OPC_BLTZAL:
1816
    case OPC_BLTZALL:
1817
    case OPC_BLTZL:
1818
        /* Compare to zero */
1819
        if (rs != 0) {
1820
            gen_op_load_gpr_T0(rs);
1821
            bcond = 1;
1822
        }
1823
        btarget = ctx->pc + 4 + offset;
1824
        break;
1825
    case OPC_J:
1826
    case OPC_JAL:
1827
        /* Jump to immediate */
1828
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1829
        break;
1830
    case OPC_JR:
1831
    case OPC_JALR:
1832
        /* Jump to register */
1833
        if (offset != 0 && offset != 16) {
1834
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1835
               others are reserved. */
1836
            MIPS_INVAL("jump hint");
1837
            generate_exception(ctx, EXCP_RI);
1838
            return;
1839
        }
1840
        GEN_LOAD_REG_T2(rs);
1841
        break;
1842
    default:
1843
        MIPS_INVAL("branch/jump");
1844
        generate_exception(ctx, EXCP_RI);
1845
        return;
1846
    }
1847
    if (bcond == 0) {
1848
        /* No condition to be computed */
1849
        switch (opc) {
1850
        case OPC_BEQ:     /* rx == rx        */
1851
        case OPC_BEQL:    /* rx == rx likely */
1852
        case OPC_BGEZ:    /* 0 >= 0          */
1853
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1854
        case OPC_BLEZ:    /* 0 <= 0          */
1855
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1856
            /* Always take */
1857
            ctx->hflags |= MIPS_HFLAG_B;
1858
            MIPS_DEBUG("balways");
1859
            break;
1860
        case OPC_BGEZAL:  /* 0 >= 0          */
1861
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1862
            /* Always take and link */
1863
            blink = 31;
1864
            ctx->hflags |= MIPS_HFLAG_B;
1865
            MIPS_DEBUG("balways and link");
1866
            break;
1867
        case OPC_BNE:     /* rx != rx        */
1868
        case OPC_BGTZ:    /* 0 > 0           */
1869
        case OPC_BLTZ:    /* 0 < 0           */
1870
            /* Treat as NOP. */
1871
            MIPS_DEBUG("bnever (NOP)");
1872
            return;
1873
        case OPC_BLTZAL:  /* 0 < 0           */
1874
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1875
            gen_op_store_T0_gpr(31);
1876
            MIPS_DEBUG("bnever and link");
1877
            return;
1878
        case OPC_BLTZALL: /* 0 < 0 likely */
1879
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1880
            gen_op_store_T0_gpr(31);
1881
            /* Skip the instruction in the delay slot */
1882
            MIPS_DEBUG("bnever, link and skip");
1883
            ctx->pc += 4;
1884
            return;
1885
        case OPC_BNEL:    /* rx != rx likely */
1886
        case OPC_BGTZL:   /* 0 > 0 likely */
1887
        case OPC_BLTZL:   /* 0 < 0 likely */
1888
            /* Skip the instruction in the delay slot */
1889
            MIPS_DEBUG("bnever and skip");
1890
            ctx->pc += 4;
1891
            return;
1892
        case OPC_J:
1893
            ctx->hflags |= MIPS_HFLAG_B;
1894
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1895
            break;
1896
        case OPC_JAL:
1897
            blink = 31;
1898
            ctx->hflags |= MIPS_HFLAG_B;
1899
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1900
            break;
1901
        case OPC_JR:
1902
            ctx->hflags |= MIPS_HFLAG_BR;
1903
            MIPS_DEBUG("jr %s", regnames[rs]);
1904
            break;
1905
        case OPC_JALR:
1906
            blink = rt;
1907
            ctx->hflags |= MIPS_HFLAG_BR;
1908
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1909
            break;
1910
        default:
1911
            MIPS_INVAL("branch/jump");
1912
            generate_exception(ctx, EXCP_RI);
1913
            return;
1914
        }
1915
    } else {
1916
        switch (opc) {
1917
        case OPC_BEQ:
1918
            gen_op_eq();
1919
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1920
                       regnames[rs], regnames[rt], btarget);
1921
            goto not_likely;
1922
        case OPC_BEQL:
1923
            gen_op_eq();
1924
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1925
                       regnames[rs], regnames[rt], btarget);
1926
            goto likely;
1927
        case OPC_BNE:
1928
            gen_op_ne();
1929
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1930
                       regnames[rs], regnames[rt], btarget);
1931
            goto not_likely;
1932
        case OPC_BNEL:
1933
            gen_op_ne();
1934
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1935
                       regnames[rs], regnames[rt], btarget);
1936
            goto likely;
1937
        case OPC_BGEZ:
1938
            gen_op_gez();
1939
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1940
            goto not_likely;
1941
        case OPC_BGEZL:
1942
            gen_op_gez();
1943
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1944
            goto likely;
1945
        case OPC_BGEZAL:
1946
            gen_op_gez();
1947
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1948
            blink = 31;
1949
            goto not_likely;
1950
        case OPC_BGEZALL:
1951
            gen_op_gez();
1952
            blink = 31;
1953
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1954
            goto likely;
1955
        case OPC_BGTZ:
1956
            gen_op_gtz();
1957
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1958
            goto not_likely;
1959
        case OPC_BGTZL:
1960
            gen_op_gtz();
1961
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1962
            goto likely;
1963
        case OPC_BLEZ:
1964
            gen_op_lez();
1965
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1966
            goto not_likely;
1967
        case OPC_BLEZL:
1968
            gen_op_lez();
1969
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1970
            goto likely;
1971
        case OPC_BLTZ:
1972
            gen_op_ltz();
1973
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1974
            goto not_likely;
1975
        case OPC_BLTZL:
1976
            gen_op_ltz();
1977
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1978
            goto likely;
1979
        case OPC_BLTZAL:
1980
            gen_op_ltz();
1981
            blink = 31;
1982
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1983
        not_likely:
1984
            ctx->hflags |= MIPS_HFLAG_BC;
1985
            gen_op_set_bcond();
1986
            break;
1987
        case OPC_BLTZALL:
1988
            gen_op_ltz();
1989
            blink = 31;
1990
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1991
        likely:
1992
            ctx->hflags |= MIPS_HFLAG_BL;
1993
            gen_op_set_bcond();
1994
            gen_op_save_bcond();
1995
            break;
1996
        default:
1997
            MIPS_INVAL("conditional branch/jump");
1998
            generate_exception(ctx, EXCP_RI);
1999
            return;
2000
        }
2001
    }
2002
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2003
               blink, ctx->hflags, btarget);
2004

    
2005
    ctx->btarget = btarget;
2006
    if (blink > 0) {
2007
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2008
        gen_op_store_T0_gpr(blink);
2009
    }
2010
}
2011

    
2012
/* special3 bitfield operations */
2013
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2014
                       int rs, int lsb, int msb)
2015
{
2016
    GEN_LOAD_REG_T1(rs);
2017
    switch (opc) {
2018
    case OPC_EXT:
2019
        if (lsb + msb > 31)
2020
            goto fail;
2021
        gen_op_ext(lsb, msb + 1);
2022
        break;
2023
#if defined(TARGET_MIPS64)
2024
    case OPC_DEXTM:
2025
        if (lsb + msb > 63)
2026
            goto fail;
2027
        gen_op_dext(lsb, msb + 1 + 32);
2028
        break;
2029
    case OPC_DEXTU:
2030
        if (lsb + msb > 63)
2031
            goto fail;
2032
        gen_op_dext(lsb + 32, msb + 1);
2033
        break;
2034
    case OPC_DEXT:
2035
        if (lsb + msb > 63)
2036
            goto fail;
2037
        gen_op_dext(lsb, msb + 1);
2038
        break;
2039
#endif
2040
    case OPC_INS:
2041
        if (lsb > msb)
2042
            goto fail;
2043
        GEN_LOAD_REG_T0(rt);
2044
        gen_op_ins(lsb, msb - lsb + 1);
2045
        break;
2046
#if defined(TARGET_MIPS64)
2047
    case OPC_DINSM:
2048
        if (lsb > msb)
2049
            goto fail;
2050
        GEN_LOAD_REG_T0(rt);
2051
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2052
        break;
2053
    case OPC_DINSU:
2054
        if (lsb > msb)
2055
            goto fail;
2056
        GEN_LOAD_REG_T0(rt);
2057
        gen_op_dins(lsb + 32, msb - lsb + 1);
2058
        break;
2059
    case OPC_DINS:
2060
        if (lsb > msb)
2061
            goto fail;
2062
        GEN_LOAD_REG_T0(rt);
2063
        gen_op_dins(lsb, msb - lsb + 1);
2064
        break;
2065
#endif
2066
    default:
2067
fail:
2068
        MIPS_INVAL("bitops");
2069
        generate_exception(ctx, EXCP_RI);
2070
        return;
2071
    }
2072
    GEN_STORE_T0_REG(rt);
2073
}
2074

    
2075
/* CP0 (MMU and control) */
2076
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2077
{
2078
    const char *rn = "invalid";
2079

    
2080
    if (sel != 0)
2081
        check_insn(env, ctx, ISA_MIPS32);
2082

    
2083
    switch (reg) {
2084
    case 0:
2085
        switch (sel) {
2086
        case 0:
2087
            gen_op_mfc0_index();
2088
            rn = "Index";
2089
            break;
2090
        case 1:
2091
            check_insn(env, ctx, ASE_MT);
2092
            gen_op_mfc0_mvpcontrol();
2093
            rn = "MVPControl";
2094
            break;
2095
        case 2:
2096
            check_insn(env, ctx, ASE_MT);
2097
            gen_op_mfc0_mvpconf0();
2098
            rn = "MVPConf0";
2099
            break;
2100
        case 3:
2101
            check_insn(env, ctx, ASE_MT);
2102
            gen_op_mfc0_mvpconf1();
2103
            rn = "MVPConf1";
2104
            break;
2105
        default:
2106
            goto die;
2107
        }
2108
        break;
2109
    case 1:
2110
        switch (sel) {
2111
        case 0:
2112
            gen_op_mfc0_random();
2113
            rn = "Random";
2114
            break;
2115
        case 1:
2116
            check_insn(env, ctx, ASE_MT);
2117
            gen_op_mfc0_vpecontrol();
2118
            rn = "VPEControl";
2119
            break;
2120
        case 2:
2121
            check_insn(env, ctx, ASE_MT);
2122
            gen_op_mfc0_vpeconf0();
2123
            rn = "VPEConf0";
2124
            break;
2125
        case 3:
2126
            check_insn(env, ctx, ASE_MT);
2127
            gen_op_mfc0_vpeconf1();
2128
            rn = "VPEConf1";
2129
            break;
2130
        case 4:
2131
            check_insn(env, ctx, ASE_MT);
2132
            gen_op_mfc0_yqmask();
2133
            rn = "YQMask";
2134
            break;
2135
        case 5:
2136
            check_insn(env, ctx, ASE_MT);
2137
            gen_op_mfc0_vpeschedule();
2138
            rn = "VPESchedule";
2139
            break;
2140
        case 6:
2141
            check_insn(env, ctx, ASE_MT);
2142
            gen_op_mfc0_vpeschefback();
2143
            rn = "VPEScheFBack";
2144
            break;
2145
        case 7:
2146
            check_insn(env, ctx, ASE_MT);
2147
            gen_op_mfc0_vpeopt();
2148
            rn = "VPEOpt";
2149
            break;
2150
        default:
2151
            goto die;
2152
        }
2153
        break;
2154
    case 2:
2155
        switch (sel) {
2156
        case 0:
2157
            gen_op_mfc0_entrylo0();
2158
            rn = "EntryLo0";
2159
            break;
2160
        case 1:
2161
            check_insn(env, ctx, ASE_MT);
2162
            gen_op_mfc0_tcstatus();
2163
            rn = "TCStatus";
2164
            break;
2165
        case 2:
2166
            check_insn(env, ctx, ASE_MT);
2167
            gen_op_mfc0_tcbind();
2168
            rn = "TCBind";
2169
            break;
2170
        case 3:
2171
            check_insn(env, ctx, ASE_MT);
2172
            gen_op_mfc0_tcrestart();
2173
            rn = "TCRestart";
2174
            break;
2175
        case 4:
2176
            check_insn(env, ctx, ASE_MT);
2177
            gen_op_mfc0_tchalt();
2178
            rn = "TCHalt";
2179
            break;
2180
        case 5:
2181
            check_insn(env, ctx, ASE_MT);
2182
            gen_op_mfc0_tccontext();
2183
            rn = "TCContext";
2184
            break;
2185
        case 6:
2186
            check_insn(env, ctx, ASE_MT);
2187
            gen_op_mfc0_tcschedule();
2188
            rn = "TCSchedule";
2189
            break;
2190
        case 7:
2191
            check_insn(env, ctx, ASE_MT);
2192
            gen_op_mfc0_tcschefback();
2193
            rn = "TCScheFBack";
2194
            break;
2195
        default:
2196
            goto die;
2197
        }
2198
        break;
2199
    case 3:
2200
        switch (sel) {
2201
        case 0:
2202
            gen_op_mfc0_entrylo1();
2203
            rn = "EntryLo1";
2204
            break;
2205
        default:
2206
            goto die;
2207
        }
2208
        break;
2209
    case 4:
2210
        switch (sel) {
2211
        case 0:
2212
            gen_op_mfc0_context();
2213
            rn = "Context";
2214
            break;
2215
        case 1:
2216
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2217
            rn = "ContextConfig";
2218
//            break;
2219
        default:
2220
            goto die;
2221
        }
2222
        break;
2223
    case 5:
2224
        switch (sel) {
2225
        case 0:
2226
            gen_op_mfc0_pagemask();
2227
            rn = "PageMask";
2228
            break;
2229
        case 1:
2230
            check_insn(env, ctx, ISA_MIPS32R2);
2231
            gen_op_mfc0_pagegrain();
2232
            rn = "PageGrain";
2233
            break;
2234
        default:
2235
            goto die;
2236
        }
2237
        break;
2238
    case 6:
2239
        switch (sel) {
2240
        case 0:
2241
            gen_op_mfc0_wired();
2242
            rn = "Wired";
2243
            break;
2244
        case 1:
2245
            check_insn(env, ctx, ISA_MIPS32R2);
2246
            gen_op_mfc0_srsconf0();
2247
            rn = "SRSConf0";
2248
            break;
2249
        case 2:
2250
            check_insn(env, ctx, ISA_MIPS32R2);
2251
            gen_op_mfc0_srsconf1();
2252
            rn = "SRSConf1";
2253
            break;
2254
        case 3:
2255
            check_insn(env, ctx, ISA_MIPS32R2);
2256
            gen_op_mfc0_srsconf2();
2257
            rn = "SRSConf2";
2258
            break;
2259
        case 4:
2260
            check_insn(env, ctx, ISA_MIPS32R2);
2261
            gen_op_mfc0_srsconf3();
2262
            rn = "SRSConf3";
2263
            break;
2264
        case 5:
2265
            check_insn(env, ctx, ISA_MIPS32R2);
2266
            gen_op_mfc0_srsconf4();
2267
            rn = "SRSConf4";
2268
            break;
2269
        default:
2270
            goto die;
2271
        }
2272
        break;
2273
    case 7:
2274
        switch (sel) {
2275
        case 0:
2276
            check_insn(env, ctx, ISA_MIPS32R2);
2277
            gen_op_mfc0_hwrena();
2278
            rn = "HWREna";
2279
            break;
2280
        default:
2281
            goto die;
2282
        }
2283
        break;
2284
    case 8:
2285
        switch (sel) {
2286
        case 0:
2287
            gen_op_mfc0_badvaddr();
2288
            rn = "BadVaddr";
2289
            break;
2290
        default:
2291
            goto die;
2292
       }
2293
        break;
2294
    case 9:
2295
        switch (sel) {
2296
        case 0:
2297
            gen_op_mfc0_count();
2298
            rn = "Count";
2299
            break;
2300
        /* 6,7 are implementation dependent */
2301
        default:
2302
            goto die;
2303
        }
2304
        break;
2305
    case 10:
2306
        switch (sel) {
2307
        case 0:
2308
            gen_op_mfc0_entryhi();
2309
            rn = "EntryHi";
2310
            break;
2311
        default:
2312
            goto die;
2313
        }
2314
        break;
2315
    case 11:
2316
        switch (sel) {
2317
        case 0:
2318
            gen_op_mfc0_compare();
2319
            rn = "Compare";
2320
            break;
2321
        /* 6,7 are implementation dependent */
2322
        default:
2323
            goto die;
2324
        }
2325
        break;
2326
    case 12:
2327
        switch (sel) {
2328
        case 0:
2329
            gen_op_mfc0_status();
2330
            rn = "Status";
2331
            break;
2332
        case 1:
2333
            check_insn(env, ctx, ISA_MIPS32R2);
2334
            gen_op_mfc0_intctl();
2335
            rn = "IntCtl";
2336
            break;
2337
        case 2:
2338
            check_insn(env, ctx, ISA_MIPS32R2);
2339
            gen_op_mfc0_srsctl();
2340
            rn = "SRSCtl";
2341
            break;
2342
        case 3:
2343
            check_insn(env, ctx, ISA_MIPS32R2);
2344
            gen_op_mfc0_srsmap();
2345
            rn = "SRSMap";
2346
            break;
2347
        default:
2348
            goto die;
2349
       }
2350
        break;
2351
    case 13:
2352
        switch (sel) {
2353
        case 0:
2354
            gen_op_mfc0_cause();
2355
            rn = "Cause";
2356
            break;
2357
        default:
2358
            goto die;
2359
       }
2360
        break;
2361
    case 14:
2362
        switch (sel) {
2363
        case 0:
2364
            gen_op_mfc0_epc();
2365
            rn = "EPC";
2366
            break;
2367
        default:
2368
            goto die;
2369
        }
2370
        break;
2371
    case 15:
2372
        switch (sel) {
2373
        case 0:
2374
            gen_op_mfc0_prid();
2375
            rn = "PRid";
2376
            break;
2377
        case 1:
2378
            check_insn(env, ctx, ISA_MIPS32R2);
2379
            gen_op_mfc0_ebase();
2380
            rn = "EBase";
2381
            break;
2382
        default:
2383
            goto die;
2384
       }
2385
        break;
2386
    case 16:
2387
        switch (sel) {
2388
        case 0:
2389
            gen_op_mfc0_config0();
2390
            rn = "Config";
2391
            break;
2392
        case 1:
2393
            gen_op_mfc0_config1();
2394
            rn = "Config1";
2395
            break;
2396
        case 2:
2397
            gen_op_mfc0_config2();
2398
            rn = "Config2";
2399
            break;
2400
        case 3:
2401
            gen_op_mfc0_config3();
2402
            rn = "Config3";
2403
            break;
2404
        /* 4,5 are reserved */
2405
        /* 6,7 are implementation dependent */
2406
        case 6:
2407
            gen_op_mfc0_config6();
2408
            rn = "Config6";
2409
            break;
2410
        case 7:
2411
            gen_op_mfc0_config7();
2412
            rn = "Config7";
2413
            break;
2414
        default:
2415
            goto die;
2416
        }
2417
        break;
2418
    case 17:
2419
        switch (sel) {
2420
        case 0:
2421
            gen_op_mfc0_lladdr();
2422
            rn = "LLAddr";
2423
            break;
2424
        default:
2425
            goto die;
2426
        }
2427
        break;
2428
    case 18:
2429
        switch (sel) {
2430
        case 0 ... 7:
2431
            gen_op_mfc0_watchlo(sel);
2432
            rn = "WatchLo";
2433
            break;
2434
        default:
2435
            goto die;
2436
        }
2437
        break;
2438
    case 19:
2439
        switch (sel) {
2440
        case 0 ...7:
2441
            gen_op_mfc0_watchhi(sel);
2442
            rn = "WatchHi";
2443
            break;
2444
        default:
2445
            goto die;
2446
        }
2447
        break;
2448
    case 20:
2449
        switch (sel) {
2450
        case 0:
2451
#if defined(TARGET_MIPS64)
2452
            check_insn(env, ctx, ISA_MIPS3);
2453
            gen_op_mfc0_xcontext();
2454
            rn = "XContext";
2455
            break;
2456
#endif
2457
        default:
2458
            goto die;
2459
        }
2460
        break;
2461
    case 21:
2462
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2463
        switch (sel) {
2464
        case 0:
2465
            gen_op_mfc0_framemask();
2466
            rn = "Framemask";
2467
            break;
2468
        default:
2469
            goto die;
2470
        }
2471
        break;
2472
    case 22:
2473
        /* ignored */
2474
        rn = "'Diagnostic"; /* implementation dependent */
2475
        break;
2476
    case 23:
2477
        switch (sel) {
2478
        case 0:
2479
            gen_op_mfc0_debug(); /* EJTAG support */
2480
            rn = "Debug";
2481
            break;
2482
        case 1:
2483
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2484
            rn = "TraceControl";
2485
//            break;
2486
        case 2:
2487
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2488
            rn = "TraceControl2";
2489
//            break;
2490
        case 3:
2491
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2492
            rn = "UserTraceData";
2493
//            break;
2494
        case 4:
2495
//            gen_op_mfc0_debug(); /* PDtrace support */
2496
            rn = "TraceBPC";
2497
//            break;
2498
        default:
2499
            goto die;
2500
        }
2501
        break;
2502
    case 24:
2503
        switch (sel) {
2504
        case 0:
2505
            gen_op_mfc0_depc(); /* EJTAG support */
2506
            rn = "DEPC";
2507
            break;
2508
        default:
2509
            goto die;
2510
        }
2511
        break;
2512
    case 25:
2513
        switch (sel) {
2514
        case 0:
2515
            gen_op_mfc0_performance0();
2516
            rn = "Performance0";
2517
            break;
2518
        case 1:
2519
//            gen_op_mfc0_performance1();
2520
            rn = "Performance1";
2521
//            break;
2522
        case 2:
2523
//            gen_op_mfc0_performance2();
2524
            rn = "Performance2";
2525
//            break;
2526
        case 3:
2527
//            gen_op_mfc0_performance3();
2528
            rn = "Performance3";
2529
//            break;
2530
        case 4:
2531
//            gen_op_mfc0_performance4();
2532
            rn = "Performance4";
2533
//            break;
2534
        case 5:
2535
//            gen_op_mfc0_performance5();
2536
            rn = "Performance5";
2537
//            break;
2538
        case 6:
2539
//            gen_op_mfc0_performance6();
2540
            rn = "Performance6";
2541
//            break;
2542
        case 7:
2543
//            gen_op_mfc0_performance7();
2544
            rn = "Performance7";
2545
//            break;
2546
        default:
2547
            goto die;
2548
        }
2549
        break;
2550
    case 26:
2551
       rn = "ECC";
2552
       break;
2553
    case 27:
2554
        switch (sel) {
2555
        /* ignored */
2556
        case 0 ... 3:
2557
            rn = "CacheErr";
2558
            break;
2559
        default:
2560
            goto die;
2561
        }
2562
        break;
2563
    case 28:
2564
        switch (sel) {
2565
        case 0:
2566
        case 2:
2567
        case 4:
2568
        case 6:
2569
            gen_op_mfc0_taglo();
2570
            rn = "TagLo";
2571
            break;
2572
        case 1:
2573
        case 3:
2574
        case 5:
2575
        case 7:
2576
            gen_op_mfc0_datalo();
2577
            rn = "DataLo";
2578
            break;
2579
        default:
2580
            goto die;
2581
        }
2582
        break;
2583
    case 29:
2584
        switch (sel) {
2585
        case 0:
2586
        case 2:
2587
        case 4:
2588
        case 6:
2589
            gen_op_mfc0_taghi();
2590
            rn = "TagHi";
2591
            break;
2592
        case 1:
2593
        case 3:
2594
        case 5:
2595
        case 7:
2596
            gen_op_mfc0_datahi();
2597
            rn = "DataHi";
2598
            break;
2599
        default:
2600
            goto die;
2601
        }
2602
        break;
2603
    case 30:
2604
        switch (sel) {
2605
        case 0:
2606
            gen_op_mfc0_errorepc();
2607
            rn = "ErrorEPC";
2608
            break;
2609
        default:
2610
            goto die;
2611
        }
2612
        break;
2613
    case 31:
2614
        switch (sel) {
2615
        case 0:
2616
            gen_op_mfc0_desave(); /* EJTAG support */
2617
            rn = "DESAVE";
2618
            break;
2619
        default:
2620
            goto die;
2621
        }
2622
        break;
2623
    default:
2624
       goto die;
2625
    }
2626
#if defined MIPS_DEBUG_DISAS
2627
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2628
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2629
                rn, reg, sel);
2630
    }
2631
#endif
2632
    return;
2633

    
2634
die:
2635
#if defined MIPS_DEBUG_DISAS
2636
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2637
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2638
                rn, reg, sel);
2639
    }
2640
#endif
2641
    generate_exception(ctx, EXCP_RI);
2642
}
2643

    
2644
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2645
{
2646
    const char *rn = "invalid";
2647

    
2648
    if (sel != 0)
2649
        check_insn(env, ctx, ISA_MIPS32);
2650

    
2651
    switch (reg) {
2652
    case 0:
2653
        switch (sel) {
2654
        case 0:
2655
            gen_op_mtc0_index();
2656
            rn = "Index";
2657
            break;
2658
        case 1:
2659
            check_insn(env, ctx, ASE_MT);
2660
            gen_op_mtc0_mvpcontrol();
2661
            rn = "MVPControl";
2662
            break;
2663
        case 2:
2664
            check_insn(env, ctx, ASE_MT);
2665
            /* ignored */
2666
            rn = "MVPConf0";
2667
            break;
2668
        case 3:
2669
            check_insn(env, ctx, ASE_MT);
2670
            /* ignored */
2671
            rn = "MVPConf1";
2672
            break;
2673
        default:
2674
            goto die;
2675
        }
2676
        break;
2677
    case 1:
2678
        switch (sel) {
2679
        case 0:
2680
            /* ignored */
2681
            rn = "Random";
2682
            break;
2683
        case 1:
2684
            check_insn(env, ctx, ASE_MT);
2685
            gen_op_mtc0_vpecontrol();
2686
            rn = "VPEControl";
2687
            break;
2688
        case 2:
2689
            check_insn(env, ctx, ASE_MT);
2690
            gen_op_mtc0_vpeconf0();
2691
            rn = "VPEConf0";
2692
            break;
2693
        case 3:
2694
            check_insn(env, ctx, ASE_MT);
2695
            gen_op_mtc0_vpeconf1();
2696
            rn = "VPEConf1";
2697
            break;
2698
        case 4:
2699
            check_insn(env, ctx, ASE_MT);
2700
            gen_op_mtc0_yqmask();
2701
            rn = "YQMask";
2702
            break;
2703
        case 5:
2704
            check_insn(env, ctx, ASE_MT);
2705
            gen_op_mtc0_vpeschedule();
2706
            rn = "VPESchedule";
2707
            break;
2708
        case 6:
2709
            check_insn(env, ctx, ASE_MT);
2710
            gen_op_mtc0_vpeschefback();
2711
            rn = "VPEScheFBack";
2712
            break;
2713
        case 7:
2714
            check_insn(env, ctx, ASE_MT);
2715
            gen_op_mtc0_vpeopt();
2716
            rn = "VPEOpt";
2717
            break;
2718
        default:
2719
            goto die;
2720
        }
2721
        break;
2722
    case 2:
2723
        switch (sel) {
2724
        case 0:
2725
            gen_op_mtc0_entrylo0();
2726
            rn = "EntryLo0";
2727
            break;
2728
        case 1:
2729
            check_insn(env, ctx, ASE_MT);
2730
            gen_op_mtc0_tcstatus();
2731
            rn = "TCStatus";
2732
            break;
2733
        case 2:
2734
            check_insn(env, ctx, ASE_MT);
2735
            gen_op_mtc0_tcbind();
2736
            rn = "TCBind";
2737
            break;
2738
        case 3:
2739
            check_insn(env, ctx, ASE_MT);
2740
            gen_op_mtc0_tcrestart();
2741
            rn = "TCRestart";
2742
            break;
2743
        case 4:
2744
            check_insn(env, ctx, ASE_MT);
2745
            gen_op_mtc0_tchalt();
2746
            rn = "TCHalt";
2747
            break;
2748
        case 5:
2749
            check_insn(env, ctx, ASE_MT);
2750
            gen_op_mtc0_tccontext();
2751
            rn = "TCContext";
2752
            break;
2753
        case 6:
2754
            check_insn(env, ctx, ASE_MT);
2755
            gen_op_mtc0_tcschedule();
2756
            rn = "TCSchedule";
2757
            break;
2758
        case 7:
2759
            check_insn(env, ctx, ASE_MT);
2760
            gen_op_mtc0_tcschefback();
2761
            rn = "TCScheFBack";
2762
            break;
2763
        default:
2764
            goto die;
2765
        }
2766
        break;
2767
    case 3:
2768
        switch (sel) {
2769
        case 0:
2770
            gen_op_mtc0_entrylo1();
2771
            rn = "EntryLo1";
2772
            break;
2773
        default:
2774
            goto die;
2775
        }
2776
        break;
2777
    case 4:
2778
        switch (sel) {
2779
        case 0:
2780
            gen_op_mtc0_context();
2781
            rn = "Context";
2782
            break;
2783
        case 1:
2784
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2785
            rn = "ContextConfig";
2786
//            break;
2787
        default:
2788
            goto die;
2789
        }
2790
        break;
2791
    case 5:
2792
        switch (sel) {
2793
        case 0:
2794
            gen_op_mtc0_pagemask();
2795
            rn = "PageMask";
2796
            break;
2797
        case 1:
2798
            check_insn(env, ctx, ISA_MIPS32R2);
2799
            gen_op_mtc0_pagegrain();
2800
            rn = "PageGrain";
2801
            break;
2802
        default:
2803
            goto die;
2804
        }
2805
        break;
2806
    case 6:
2807
        switch (sel) {
2808
        case 0:
2809
            gen_op_mtc0_wired();
2810
            rn = "Wired";
2811
            break;
2812
        case 1:
2813
            check_insn(env, ctx, ISA_MIPS32R2);
2814
            gen_op_mtc0_srsconf0();
2815
            rn = "SRSConf0";
2816
            break;
2817
        case 2:
2818
            check_insn(env, ctx, ISA_MIPS32R2);
2819
            gen_op_mtc0_srsconf1();
2820
            rn = "SRSConf1";
2821
            break;
2822
        case 3:
2823
            check_insn(env, ctx, ISA_MIPS32R2);
2824
            gen_op_mtc0_srsconf2();
2825
            rn = "SRSConf2";
2826
            break;
2827
        case 4:
2828
            check_insn(env, ctx, ISA_MIPS32R2);
2829
            gen_op_mtc0_srsconf3();
2830
            rn = "SRSConf3";
2831
            break;
2832
        case 5:
2833
            check_insn(env, ctx, ISA_MIPS32R2);
2834
            gen_op_mtc0_srsconf4();
2835
            rn = "SRSConf4";
2836
            break;
2837
        default:
2838
            goto die;
2839
        }
2840
        break;
2841
    case 7:
2842
        switch (sel) {
2843
        case 0:
2844
            check_insn(env, ctx, ISA_MIPS32R2);
2845
            gen_op_mtc0_hwrena();
2846
            rn = "HWREna";
2847
            break;
2848
        default:
2849
            goto die;
2850
        }
2851
        break;
2852
    case 8:
2853
        /* ignored */
2854
        rn = "BadVaddr";
2855
        break;
2856
    case 9:
2857
        switch (sel) {
2858
        case 0:
2859
            gen_op_mtc0_count();
2860
            rn = "Count";
2861
            break;
2862
        /* 6,7 are implementation dependent */
2863
        default:
2864
            goto die;
2865
        }
2866
        /* Stop translation as we may have switched the execution mode */
2867
        ctx->bstate = BS_STOP;
2868
        break;
2869
    case 10:
2870
        switch (sel) {
2871
        case 0:
2872
            gen_op_mtc0_entryhi();
2873
            rn = "EntryHi";
2874
            break;
2875
        default:
2876
            goto die;
2877
        }
2878
        break;
2879
    case 11:
2880
        switch (sel) {
2881
        case 0:
2882
            gen_op_mtc0_compare();
2883
            rn = "Compare";
2884
            break;
2885
        /* 6,7 are implementation dependent */
2886
        default:
2887
            goto die;
2888
        }
2889
        /* Stop translation as we may have switched the execution mode */
2890
        ctx->bstate = BS_STOP;
2891
        break;
2892
    case 12:
2893
        switch (sel) {
2894
        case 0:
2895
            gen_op_mtc0_status();
2896
            /* BS_STOP isn't good enough here, hflags may have changed. */
2897
            gen_save_pc(ctx->pc + 4);
2898
            ctx->bstate = BS_EXCP;
2899
            rn = "Status";
2900
            break;
2901
        case 1:
2902
            check_insn(env, ctx, ISA_MIPS32R2);
2903
            gen_op_mtc0_intctl();
2904
            /* Stop translation as we may have switched the execution mode */
2905
            ctx->bstate = BS_STOP;
2906
            rn = "IntCtl";
2907
            break;
2908
        case 2:
2909
            check_insn(env, ctx, ISA_MIPS32R2);
2910
            gen_op_mtc0_srsctl();
2911
            /* Stop translation as we may have switched the execution mode */
2912
            ctx->bstate = BS_STOP;
2913
            rn = "SRSCtl";
2914
            break;
2915
        case 3:
2916
            check_insn(env, ctx, ISA_MIPS32R2);
2917
            gen_op_mtc0_srsmap();
2918
            /* Stop translation as we may have switched the execution mode */
2919
            ctx->bstate = BS_STOP;
2920
            rn = "SRSMap";
2921
            break;
2922
        default:
2923
            goto die;
2924
        }
2925
        break;
2926
    case 13:
2927
        switch (sel) {
2928
        case 0:
2929
            gen_op_mtc0_cause();
2930
            rn = "Cause";
2931
            break;
2932
        default:
2933
            goto die;
2934
        }
2935
        /* Stop translation as we may have switched the execution mode */
2936
        ctx->bstate = BS_STOP;
2937
        break;
2938
    case 14:
2939
        switch (sel) {
2940
        case 0:
2941
            gen_op_mtc0_epc();
2942
            rn = "EPC";
2943
            break;
2944
        default:
2945
            goto die;
2946
        }
2947
        break;
2948
    case 15:
2949
        switch (sel) {
2950
        case 0:
2951
            /* ignored */
2952
            rn = "PRid";
2953
            break;
2954
        case 1:
2955
            check_insn(env, ctx, ISA_MIPS32R2);
2956
            gen_op_mtc0_ebase();
2957
            rn = "EBase";
2958
            break;
2959
        default:
2960
            goto die;
2961
        }
2962
        break;
2963
    case 16:
2964
        switch (sel) {
2965
        case 0:
2966
            gen_op_mtc0_config0();
2967
            rn = "Config";
2968
            /* Stop translation as we may have switched the execution mode */
2969
            ctx->bstate = BS_STOP;
2970
            break;
2971
        case 1:
2972
            /* ignored, read only */
2973
            rn = "Config1";
2974
            break;
2975
        case 2:
2976
            gen_op_mtc0_config2();
2977
            rn = "Config2";
2978
            /* Stop translation as we may have switched the execution mode */
2979
            ctx->bstate = BS_STOP;
2980
            break;
2981
        case 3:
2982
            /* ignored, read only */
2983
            rn = "Config3";
2984
            break;
2985
        /* 4,5 are reserved */
2986
        /* 6,7 are implementation dependent */
2987
        case 6:
2988
            /* ignored */
2989
            rn = "Config6";
2990
            break;
2991
        case 7:
2992
            /* ignored */
2993
            rn = "Config7";
2994
            break;
2995
        default:
2996
            rn = "Invalid config selector";
2997
            goto die;
2998
        }
2999
        break;
3000
    case 17:
3001
        switch (sel) {
3002
        case 0:
3003
            /* ignored */
3004
            rn = "LLAddr";
3005
            break;
3006
        default:
3007
            goto die;
3008
        }
3009
        break;
3010
    case 18:
3011
        switch (sel) {
3012
        case 0 ... 7:
3013
            gen_op_mtc0_watchlo(sel);
3014
            rn = "WatchLo";
3015
            break;
3016
        default:
3017
            goto die;
3018
        }
3019
        break;
3020
    case 19:
3021
        switch (sel) {
3022
        case 0 ... 7:
3023
            gen_op_mtc0_watchhi(sel);
3024
            rn = "WatchHi";
3025
            break;
3026
        default:
3027
            goto die;
3028
        }
3029
        break;
3030
    case 20:
3031
        switch (sel) {
3032
        case 0:
3033
#if defined(TARGET_MIPS64)
3034
            check_insn(env, ctx, ISA_MIPS3);
3035
            gen_op_mtc0_xcontext();
3036
            rn = "XContext";
3037
            break;
3038
#endif
3039
        default:
3040
            goto die;
3041
        }
3042
        break;
3043
    case 21:
3044
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3045
        switch (sel) {
3046
        case 0:
3047
            gen_op_mtc0_framemask();
3048
            rn = "Framemask";
3049
            break;
3050
        default:
3051
            goto die;
3052
        }
3053
        break;
3054
    case 22:
3055
        /* ignored */
3056
        rn = "Diagnostic"; /* implementation dependent */
3057
        break;
3058
    case 23:
3059
        switch (sel) {
3060
        case 0:
3061
            gen_op_mtc0_debug(); /* EJTAG support */
3062
            /* BS_STOP isn't good enough here, hflags may have changed. */
3063
            gen_save_pc(ctx->pc + 4);
3064
            ctx->bstate = BS_EXCP;
3065
            rn = "Debug";
3066
            break;
3067
        case 1:
3068
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3069
            rn = "TraceControl";
3070
            /* Stop translation as we may have switched the execution mode */
3071
            ctx->bstate = BS_STOP;
3072
//            break;
3073
        case 2:
3074
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3075
            rn = "TraceControl2";
3076
            /* Stop translation as we may have switched the execution mode */
3077
            ctx->bstate = BS_STOP;
3078
//            break;
3079
        case 3:
3080
            /* Stop translation as we may have switched the execution mode */
3081
            ctx->bstate = BS_STOP;
3082
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3083
            rn = "UserTraceData";
3084
            /* Stop translation as we may have switched the execution mode */
3085
            ctx->bstate = BS_STOP;
3086
//            break;
3087
        case 4:
3088
//            gen_op_mtc0_debug(); /* PDtrace support */
3089
            /* Stop translation as we may have switched the execution mode */
3090
            ctx->bstate = BS_STOP;
3091
            rn = "TraceBPC";
3092
//            break;
3093
        default:
3094
            goto die;
3095
        }
3096
        break;
3097
    case 24:
3098
        switch (sel) {
3099
        case 0:
3100
            gen_op_mtc0_depc(); /* EJTAG support */
3101
            rn = "DEPC";
3102
            break;
3103
        default:
3104
            goto die;
3105
        }
3106
        break;
3107
    case 25:
3108
        switch (sel) {
3109
        case 0:
3110
            gen_op_mtc0_performance0();
3111
            rn = "Performance0";
3112
            break;
3113
        case 1:
3114
//            gen_op_mtc0_performance1();
3115
            rn = "Performance1";
3116
//            break;
3117
        case 2:
3118
//            gen_op_mtc0_performance2();
3119
            rn = "Performance2";
3120
//            break;
3121
        case 3:
3122
//            gen_op_mtc0_performance3();
3123
            rn = "Performance3";
3124
//            break;
3125
        case 4:
3126
//            gen_op_mtc0_performance4();
3127
            rn = "Performance4";
3128
//            break;
3129
        case 5:
3130
//            gen_op_mtc0_performance5();
3131
            rn = "Performance5";
3132
//            break;
3133
        case 6:
3134
//            gen_op_mtc0_performance6();
3135
            rn = "Performance6";
3136
//            break;
3137
        case 7:
3138
//            gen_op_mtc0_performance7();
3139
            rn = "Performance7";
3140
//            break;
3141
        default:
3142
            goto die;
3143
        }
3144
       break;
3145
    case 26:
3146
        /* ignored */
3147
        rn = "ECC";
3148
        break;
3149
    case 27:
3150
        switch (sel) {
3151
        case 0 ... 3:
3152
            /* ignored */
3153
            rn = "CacheErr";
3154
            break;
3155
        default:
3156
            goto die;
3157
        }
3158
       break;
3159
    case 28:
3160
        switch (sel) {
3161
        case 0:
3162
        case 2:
3163
        case 4:
3164
        case 6:
3165
            gen_op_mtc0_taglo();
3166
            rn = "TagLo";
3167
            break;
3168
        case 1:
3169
        case 3:
3170
        case 5:
3171
        case 7:
3172
            gen_op_mtc0_datalo();
3173
            rn = "DataLo";
3174
            break;
3175
        default:
3176
            goto die;
3177
        }
3178
        break;
3179
    case 29:
3180
        switch (sel) {
3181
        case 0:
3182
        case 2:
3183
        case 4:
3184
        case 6:
3185
            gen_op_mtc0_taghi();
3186
            rn = "TagHi";
3187
            break;
3188
        case 1:
3189
        case 3:
3190
        case 5:
3191
        case 7:
3192
            gen_op_mtc0_datahi();
3193
            rn = "DataHi";
3194
            break;
3195
        default:
3196
            rn = "invalid sel";
3197
            goto die;
3198
        }
3199
       break;
3200
    case 30:
3201
        switch (sel) {
3202
        case 0:
3203
            gen_op_mtc0_errorepc();
3204
            rn = "ErrorEPC";
3205
            break;
3206
        default:
3207
            goto die;
3208
        }
3209
        break;
3210
    case 31:
3211
        switch (sel) {
3212
        case 0:
3213
            gen_op_mtc0_desave(); /* EJTAG support */
3214
            rn = "DESAVE";
3215
            break;
3216
        default:
3217
            goto die;
3218
        }
3219
        /* Stop translation as we may have switched the execution mode */
3220
        ctx->bstate = BS_STOP;
3221
        break;
3222
    default:
3223
       goto die;
3224
    }
3225
#if defined MIPS_DEBUG_DISAS
3226
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3227
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3228
                rn, reg, sel);
3229
    }
3230
#endif
3231
    return;
3232

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

    
3243
#if defined(TARGET_MIPS64)
3244
static void gen_dmfc0 (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_MIPS64);
3250

    
3251
    switch (reg) {
3252
    case 0:
3253
        switch (sel) {
3254
        case 0:
3255
            gen_op_mfc0_index();
3256
            rn = "Index";
3257
            break;
3258
        case 1:
3259
            check_insn(env, ctx, ASE_MT);
3260
            gen_op_mfc0_mvpcontrol();
3261
            rn = "MVPControl";
3262
            break;
3263
        case 2:
3264
            check_insn(env, ctx, ASE_MT);
3265
            gen_op_mfc0_mvpconf0();
3266
            rn = "MVPConf0";
3267
            break;
3268
        case 3:
3269
            check_insn(env, ctx, ASE_MT);
3270
            gen_op_mfc0_mvpconf1();
3271
            rn = "MVPConf1";
3272
            break;
3273
        default:
3274
            goto die;
3275
        }
3276
        break;
3277
    case 1:
3278
        switch (sel) {
3279
        case 0:
3280
            gen_op_mfc0_random();
3281
            rn = "Random";
3282
            break;
3283
        case 1:
3284
            check_insn(env, ctx, ASE_MT);
3285
            gen_op_mfc0_vpecontrol();
3286
            rn = "VPEControl";
3287
            break;
3288
        case 2:
3289
            check_insn(env, ctx, ASE_MT);
3290
            gen_op_mfc0_vpeconf0();
3291
            rn = "VPEConf0";
3292
            break;
3293
        case 3:
3294
            check_insn(env, ctx, ASE_MT);
3295
            gen_op_mfc0_vpeconf1();
3296
            rn = "VPEConf1";
3297
            break;
3298
        case 4:
3299
            check_insn(env, ctx, ASE_MT);
3300
            gen_op_dmfc0_yqmask();
3301
            rn = "YQMask";
3302
            break;
3303
        case 5:
3304
            check_insn(env, ctx, ASE_MT);
3305
            gen_op_dmfc0_vpeschedule();
3306
            rn = "VPESchedule";
3307
            break;
3308
        case 6:
3309
            check_insn(env, ctx, ASE_MT);
3310
            gen_op_dmfc0_vpeschefback();
3311
            rn = "VPEScheFBack";
3312
            break;
3313
        case 7:
3314
            check_insn(env, ctx, ASE_MT);
3315
            gen_op_mfc0_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_dmfc0_entrylo0();
3326
            rn = "EntryLo0";
3327
            break;
3328
        case 1:
3329
            check_insn(env, ctx, ASE_MT);
3330
            gen_op_mfc0_tcstatus();
3331
            rn = "TCStatus";
3332
            break;
3333
        case 2:
3334
            check_insn(env, ctx, ASE_MT);
3335
            gen_op_mfc0_tcbind();
3336
            rn = "TCBind";
3337
            break;
3338
        case 3:
3339
            check_insn(env, ctx, ASE_MT);
3340
            gen_op_dmfc0_tcrestart();
3341
            rn = "TCRestart";
3342
            break;
3343
        case 4:
3344
            check_insn(env, ctx, ASE_MT);
3345
            gen_op_dmfc0_tchalt();
3346
            rn = "TCHalt";
3347
            break;
3348
        case 5:
3349
            check_insn(env, ctx, ASE_MT);
3350
            gen_op_dmfc0_tccontext();
3351
            rn = "TCContext";
3352
            break;
3353
        case 6:
3354
            check_insn(env, ctx, ASE_MT);
3355
            gen_op_dmfc0_tcschedule();
3356
            rn = "TCSchedule";
3357
            break;
3358
        case 7:
3359
            check_insn(env, ctx, ASE_MT);
3360
            gen_op_dmfc0_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_dmfc0_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_dmfc0_context();
3381
            rn = "Context";
3382
            break;
3383
        case 1:
3384
//            gen_op_dmfc0_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_mfc0_pagemask();
3395
            rn = "PageMask";
3396
            break;
3397
        case 1:
3398
            check_insn(env, ctx, ISA_MIPS32R2);
3399
            gen_op_mfc0_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_mfc0_wired();
3410
            rn = "Wired";
3411
            break;
3412
        case 1:
3413
            check_insn(env, ctx, ISA_MIPS32R2);
3414
            gen_op_mfc0_srsconf0();
3415
            rn = "SRSConf0";
3416
            break;
3417
        case 2:
3418
            check_insn(env, ctx, ISA_MIPS32R2);
3419
            gen_op_mfc0_srsconf1();
3420
            rn = "SRSConf1";
3421
            break;
3422
        case 3:
3423
            check_insn(env, ctx, ISA_MIPS32R2);
3424
            gen_op_mfc0_srsconf2();
3425
            rn = "SRSConf2";
3426
            break;
3427
        case 4:
3428
            check_insn(env, ctx, ISA_MIPS32R2);
3429
            gen_op_mfc0_srsconf3();
3430
            rn = "SRSConf3";
3431
            break;
3432
        case 5:
3433
            check_insn(env, ctx, ISA_MIPS32R2);
3434
            gen_op_mfc0_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_mfc0_hwrena();
3446
            rn = "HWREna";
3447
            break;
3448
        default:
3449
            goto die;
3450
        }
3451
        break;
3452
    case 8:
3453
        switch (sel) {
3454
        case 0:
3455
            gen_op_dmfc0_badvaddr();
3456
            rn = "BadVaddr";
3457
            break;
3458
        default:
3459
            goto die;
3460
        }
3461
        break;
3462
    case 9:
3463
        switch (sel) {
3464
        case 0:
3465
            gen_op_mfc0_count();
3466
            rn = "Count";
3467
            break;
3468
        /* 6,7 are implementation dependent */
3469
        default:
3470
            goto die;
3471
        }
3472
        break;
3473
    case 10:
3474
        switch (sel) {
3475
        case 0:
3476
            gen_op_dmfc0_entryhi();
3477
            rn = "EntryHi";
3478
            break;
3479
        default:
3480
            goto die;
3481
        }
3482
        break;
3483
    case 11:
3484
        switch (sel) {
3485
        case 0:
3486
            gen_op_mfc0_compare();
3487
            rn = "Compare";
3488
            break;
3489
        /* 6,7 are implementation dependent */
3490
        default:
3491
            goto die;
3492
        }
3493
        break;
3494
    case 12:
3495
        switch (sel) {
3496
        case 0:
3497
            gen_op_mfc0_status();
3498
            rn = "Status";
3499
            break;
3500
        case 1:
3501
            check_insn(env, ctx, ISA_MIPS32R2);
3502
            gen_op_mfc0_intctl();
3503
            rn = "IntCtl";
3504
            break;
3505
        case 2:
3506
            check_insn(env, ctx, ISA_MIPS32R2);
3507
            gen_op_mfc0_srsctl();
3508
            rn = "SRSCtl";
3509
            break;
3510
        case 3:
3511
            check_insn(env, ctx, ISA_MIPS32R2);
3512
            gen_op_mfc0_srsmap();
3513
            rn = "SRSMap";
3514
            break;
3515
        default:
3516
            goto die;
3517
        }
3518
        break;
3519
    case 13:
3520
        switch (sel) {
3521
        case 0:
3522
            gen_op_mfc0_cause();
3523
            rn = "Cause";
3524
            break;
3525
        default:
3526
            goto die;
3527
        }
3528
        break;
3529
    case 14:
3530
        switch (sel) {
3531
        case 0:
3532
            gen_op_dmfc0_epc();
3533
            rn = "EPC";
3534
            break;
3535
        default:
3536
            goto die;
3537
        }
3538
        break;
3539
    case 15:
3540
        switch (sel) {
3541
        case 0:
3542
            gen_op_mfc0_prid();
3543
            rn = "PRid";
3544
            break;
3545
        case 1:
3546
            check_insn(env, ctx, ISA_MIPS32R2);
3547
            gen_op_mfc0_ebase();
3548
            rn = "EBase";
3549
            break;
3550
        default:
3551
            goto die;
3552
        }
3553
        break;
3554
    case 16:
3555
        switch (sel) {
3556
        case 0:
3557
            gen_op_mfc0_config0();
3558
            rn = "Config";
3559
            break;
3560
        case 1:
3561
            gen_op_mfc0_config1();
3562
            rn = "Config1";
3563
            break;
3564
        case 2:
3565
            gen_op_mfc0_config2();
3566
            rn = "Config2";
3567
            break;
3568
        case 3:
3569
            gen_op_mfc0_config3();
3570
            rn = "Config3";
3571
            break;
3572
       /* 6,7 are implementation dependent */
3573
        default:
3574
            goto die;
3575
        }
3576
        break;
3577
    case 17:
3578
        switch (sel) {
3579
        case 0:
3580
            gen_op_dmfc0_lladdr();
3581
            rn = "LLAddr";
3582
            break;
3583
        default:
3584
            goto die;
3585
        }
3586
        break;
3587
    case 18:
3588
        switch (sel) {
3589
        case 0 ... 7:
3590
            gen_op_dmfc0_watchlo(sel);
3591
            rn = "WatchLo";
3592
            break;
3593
        default:
3594
            goto die;
3595
        }
3596
        break;
3597
    case 19:
3598
        switch (sel) {
3599
        case 0 ... 7:
3600
            gen_op_mfc0_watchhi(sel);
3601
            rn = "WatchHi";
3602
            break;
3603
        default:
3604
            goto die;
3605
        }
3606
        break;
3607
    case 20:
3608
        switch (sel) {
3609
        case 0:
3610
            check_insn(env, ctx, ISA_MIPS3);
3611
            gen_op_dmfc0_xcontext();
3612
            rn = "XContext";
3613
            break;
3614
        default:
3615
            goto die;
3616
        }
3617
        break;
3618
    case 21:
3619
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3620
        switch (sel) {
3621
        case 0:
3622
            gen_op_mfc0_framemask();
3623
            rn = "Framemask";
3624
            break;
3625
        default:
3626
            goto die;
3627
        }
3628
        break;
3629
    case 22:
3630
        /* ignored */
3631
        rn = "'Diagnostic"; /* implementation dependent */
3632
        break;
3633
    case 23:
3634
        switch (sel) {
3635
        case 0:
3636
            gen_op_mfc0_debug(); /* EJTAG support */
3637
            rn = "Debug";
3638
            break;
3639
        case 1:
3640
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3641
            rn = "TraceControl";
3642
//            break;
3643
        case 2:
3644
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3645
            rn = "TraceControl2";
3646
//            break;
3647
        case 3:
3648
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3649
            rn = "UserTraceData";
3650
//            break;
3651
        case 4:
3652
//            gen_op_dmfc0_debug(); /* PDtrace support */
3653
            rn = "TraceBPC";
3654
//            break;
3655
        default:
3656
            goto die;
3657
        }
3658
        break;
3659
    case 24:
3660
        switch (sel) {
3661
        case 0:
3662
            gen_op_dmfc0_depc(); /* EJTAG support */
3663
            rn = "DEPC";
3664
            break;
3665
        default:
3666
            goto die;
3667
        }
3668
        break;
3669
    case 25:
3670
        switch (sel) {
3671
        case 0:
3672
            gen_op_mfc0_performance0();
3673
            rn = "Performance0";
3674
            break;
3675
        case 1:
3676
//            gen_op_dmfc0_performance1();
3677
            rn = "Performance1";
3678
//            break;
3679
        case 2:
3680
//            gen_op_dmfc0_performance2();
3681
            rn = "Performance2";
3682
//            break;
3683
        case 3:
3684
//            gen_op_dmfc0_performance3();
3685
            rn = "Performance3";
3686
//            break;
3687
        case 4:
3688
//            gen_op_dmfc0_performance4();
3689
            rn = "Performance4";
3690
//            break;
3691
        case 5:
3692
//            gen_op_dmfc0_performance5();
3693
            rn = "Performance5";
3694
//            break;
3695
        case 6:
3696
//            gen_op_dmfc0_performance6();
3697
            rn = "Performance6";
3698
//            break;
3699
        case 7:
3700
//            gen_op_dmfc0_performance7();
3701
            rn = "Performance7";
3702
//            break;
3703
        default:
3704
            goto die;
3705
        }
3706
        break;
3707
    case 26:
3708
       rn = "ECC";
3709
       break;
3710
    case 27:
3711
        switch (sel) {
3712
        /* ignored */
3713
        case 0 ... 3:
3714
            rn = "CacheErr";
3715
            break;
3716
        default:
3717
            goto die;
3718
        }
3719
        break;
3720
    case 28:
3721
        switch (sel) {
3722
        case 0:
3723
        case 2:
3724
        case 4:
3725
        case 6:
3726
            gen_op_mfc0_taglo();
3727
            rn = "TagLo";
3728
            break;
3729
        case 1:
3730
        case 3:
3731
        case 5:
3732
        case 7:
3733
            gen_op_mfc0_datalo();
3734
            rn = "DataLo";
3735
            break;
3736
        default:
3737
            goto die;
3738
        }
3739
        break;
3740
    case 29:
3741
        switch (sel) {
3742
        case 0:
3743
        case 2:
3744
        case 4:
3745
        case 6:
3746
            gen_op_mfc0_taghi();
3747
            rn = "TagHi";
3748
            break;
3749
        case 1:
3750
        case 3:
3751
        case 5:
3752
        case 7:
3753
            gen_op_mfc0_datahi();
3754
            rn = "DataHi";
3755
            break;
3756
        default:
3757
            goto die;
3758
        }
3759
        break;
3760
    case 30:
3761
        switch (sel) {
3762
        case 0:
3763
            gen_op_dmfc0_errorepc();
3764
            rn = "ErrorEPC";
3765
            break;
3766
        default:
3767
            goto die;
3768
        }
3769
        break;
3770
    case 31:
3771
        switch (sel) {
3772
        case 0:
3773
            gen_op_mfc0_desave(); /* EJTAG support */
3774
            rn = "DESAVE";
3775
            break;
3776
        default:
3777
            goto die;
3778
        }
3779
        break;
3780
    default:
3781
        goto die;
3782
    }
3783
#if defined MIPS_DEBUG_DISAS
3784
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3785
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3786
                rn, reg, sel);
3787
    }
3788
#endif
3789
    return;
3790

    
3791
die:
3792
#if defined MIPS_DEBUG_DISAS
3793
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3794
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3795
                rn, reg, sel);
3796
    }
3797
#endif
3798
    generate_exception(ctx, EXCP_RI);
3799
}
3800

    
3801
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3802
{
3803
    const char *rn = "invalid";
3804

    
3805
    if (sel != 0)
3806
        check_insn(env, ctx, ISA_MIPS64);
3807

    
3808
    switch (reg) {
3809
    case 0:
3810
        switch (sel) {
3811
        case 0:
3812
            gen_op_mtc0_index();
3813
            rn = "Index";
3814
            break;
3815
        case 1:
3816
            check_insn(env, ctx, ASE_MT);
3817
            gen_op_mtc0_mvpcontrol();
3818
            rn = "MVPControl";
3819
            break;
3820
        case 2:
3821
            check_insn(env, ctx, ASE_MT);
3822
            /* ignored */
3823
            rn = "MVPConf0";
3824
            break;
3825
        case 3:
3826
            check_insn(env, ctx, ASE_MT);
3827
            /* ignored */
3828
            rn = "MVPConf1";
3829
            break;
3830
        default:
3831
            goto die;
3832
        }
3833
        break;
3834
    case 1:
3835
        switch (sel) {
3836
        case 0:
3837
            /* ignored */
3838
            rn = "Random";
3839
            break;
3840
        case 1:
3841
            check_insn(env, ctx, ASE_MT);
3842
            gen_op_mtc0_vpecontrol();
3843
            rn = "VPEControl";
3844
            break;
3845
        case 2:
3846
            check_insn(env, ctx, ASE_MT);
3847
            gen_op_mtc0_vpeconf0();
3848
            rn = "VPEConf0";
3849
            break;
3850
        case 3:
3851
            check_insn(env, ctx, ASE_MT);
3852
            gen_op_mtc0_vpeconf1();
3853
            rn = "VPEConf1";
3854
            break;
3855
        case 4:
3856
            check_insn(env, ctx, ASE_MT);
3857
            gen_op_mtc0_yqmask();
3858
            rn = "YQMask";
3859
            break;
3860
        case 5:
3861
            check_insn(env, ctx, ASE_MT);
3862
            gen_op_mtc0_vpeschedule();
3863
            rn = "VPESchedule";
3864
            break;
3865
        case 6:
3866
            check_insn(env, ctx, ASE_MT);
3867
            gen_op_mtc0_vpeschefback();
3868
            rn = "VPEScheFBack";
3869
            break;
3870
        case 7:
3871
            check_insn(env, ctx, ASE_MT);
3872
            gen_op_mtc0_vpeopt();
3873
            rn = "VPEOpt";
3874
            break;
3875
        default:
3876
            goto die;
3877
        }
3878
        break;
3879
    case 2:
3880
        switch (sel) {
3881
        case 0:
3882
            gen_op_mtc0_entrylo0();
3883
            rn = "EntryLo0";
3884
            break;
3885
        case 1:
3886
            check_insn(env, ctx, ASE_MT);
3887
            gen_op_mtc0_tcstatus();
3888
            rn = "TCStatus";
3889
            break;
3890
        case 2:
3891
            check_insn(env, ctx, ASE_MT);
3892
            gen_op_mtc0_tcbind();
3893
            rn = "TCBind";
3894
            break;
3895
        case 3:
3896
            check_insn(env, ctx, ASE_MT);
3897
            gen_op_mtc0_tcrestart();
3898
            rn = "TCRestart";
3899
            break;
3900
        case 4:
3901
            check_insn(env, ctx, ASE_MT);
3902
            gen_op_mtc0_tchalt();
3903
            rn = "TCHalt";
3904
            break;
3905
        case 5:
3906
            check_insn(env, ctx, ASE_MT);
3907
            gen_op_mtc0_tccontext();
3908
            rn = "TCContext";
3909
            break;
3910
        case 6:
3911
            check_insn(env, ctx, ASE_MT);
3912
            gen_op_mtc0_tcschedule();
3913
            rn = "TCSchedule";
3914
            break;
3915
        case 7:
3916
            check_insn(env, ctx, ASE_MT);
3917
            gen_op_mtc0_tcschefback();
3918
            rn = "TCScheFBack";
3919
            break;
3920
        default:
3921
            goto die;
3922
        }
3923
        break;
3924
    case 3:
3925
        switch (sel) {
3926
        case 0:
3927
            gen_op_mtc0_entrylo1();
3928
            rn = "EntryLo1";
3929
            break;
3930
        default:
3931
            goto die;
3932
        }
3933
        break;
3934
    case 4:
3935
        switch (sel) {
3936
        case 0:
3937
            gen_op_mtc0_context();
3938
            rn = "Context";
3939
            break;
3940
        case 1:
3941
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3942
            rn = "ContextConfig";
3943
//           break;
3944
        default:
3945
            goto die;
3946
        }
3947
        break;
3948
    case 5:
3949
        switch (sel) {
3950
        case 0:
3951
            gen_op_mtc0_pagemask();
3952
            rn = "PageMask";
3953
            break;
3954
        case 1:
3955
            check_insn(env, ctx, ISA_MIPS32R2);
3956
            gen_op_mtc0_pagegrain();
3957
            rn = "PageGrain";
3958
            break;
3959
        default:
3960
            goto die;
3961
        }
3962
        break;
3963
    case 6:
3964
        switch (sel) {
3965
        case 0:
3966
            gen_op_mtc0_wired();
3967
            rn = "Wired";
3968
            break;
3969
        case 1:
3970
            check_insn(env, ctx, ISA_MIPS32R2);
3971
            gen_op_mtc0_srsconf0();
3972
            rn = "SRSConf0";
3973
            break;
3974
        case 2:
3975
            check_insn(env, ctx, ISA_MIPS32R2);
3976
            gen_op_mtc0_srsconf1();
3977
            rn = "SRSConf1";
3978
            break;
3979
        case 3:
3980
            check_insn(env, ctx, ISA_MIPS32R2);
3981
            gen_op_mtc0_srsconf2();
3982
            rn = "SRSConf2";
3983
            break;
3984
        case 4:
3985
            check_insn(env, ctx, ISA_MIPS32R2);
3986
            gen_op_mtc0_srsconf3();
3987
            rn = "SRSConf3";
3988
            break;
3989
        case 5:
3990
            check_insn(env, ctx, ISA_MIPS32R2);
3991
            gen_op_mtc0_srsconf4();
3992
            rn = "SRSConf4";
3993
            break;
3994
        default:
3995
            goto die;
3996
        }
3997
        break;
3998
    case 7:
3999
        switch (sel) {
4000
        case 0:
4001
            check_insn(env, ctx, ISA_MIPS32R2);
4002
            gen_op_mtc0_hwrena();
4003
            rn = "HWREna";
4004
            break;
4005
        default:
4006
            goto die;
4007
        }
4008
        break;
4009
    case 8:
4010
        /* ignored */
4011
        rn = "BadVaddr";
4012
        break;
4013
    case 9:
4014
        switch (sel) {
4015
        case 0:
4016
            gen_op_mtc0_count();
4017
            rn = "Count";
4018
            break;
4019
        /* 6,7 are implementation dependent */
4020
        default:
4021
            goto die;
4022
        }
4023
        /* Stop translation as we may have switched the execution mode */
4024
        ctx->bstate = BS_STOP;
4025
        break;
4026
    case 10:
4027
        switch (sel) {
4028
        case 0:
4029
            gen_op_mtc0_entryhi();
4030
            rn = "EntryHi";
4031
            break;
4032
        default:
4033
            goto die;
4034
        }
4035
        break;
4036
    case 11:
4037
        switch (sel) {
4038
        case 0:
4039
            gen_op_mtc0_compare();
4040
            rn = "Compare";
4041
            break;
4042
        /* 6,7 are implementation dependent */
4043
        default:
4044
            goto die;
4045
        }
4046
        /* Stop translation as we may have switched the execution mode */
4047
        ctx->bstate = BS_STOP;
4048
        break;
4049
    case 12:
4050
        switch (sel) {
4051
        case 0:
4052
            gen_op_mtc0_status();
4053
            /* BS_STOP isn't good enough here, hflags may have changed. */
4054
            gen_save_pc(ctx->pc + 4);
4055
            ctx->bstate = BS_EXCP;
4056
            rn = "Status";
4057
            break;
4058
        case 1:
4059
            check_insn(env, ctx, ISA_MIPS32R2);
4060
            gen_op_mtc0_intctl();
4061
            /* Stop translation as we may have switched the execution mode */
4062
            ctx->bstate = BS_STOP;
4063
            rn = "IntCtl";
4064
            break;
4065
        case 2:
4066
            check_insn(env, ctx, ISA_MIPS32R2);
4067
            gen_op_mtc0_srsctl();
4068
            /* Stop translation as we may have switched the execution mode */
4069
            ctx->bstate = BS_STOP;
4070
            rn = "SRSCtl";
4071
            break;
4072
        case 3:
4073
            check_insn(env, ctx, ISA_MIPS32R2);
4074
            gen_op_mtc0_srsmap();
4075
            /* Stop translation as we may have switched the execution mode */
4076
            ctx->bstate = BS_STOP;
4077
            rn = "SRSMap";
4078
            break;
4079
        default:
4080
            goto die;
4081
        }
4082
        break;
4083
    case 13:
4084
        switch (sel) {
4085
        case 0:
4086
            gen_op_mtc0_cause();
4087
            rn = "Cause";
4088
            break;
4089
        default:
4090
            goto die;
4091
        }
4092
        /* Stop translation as we may have switched the execution mode */
4093
        ctx->bstate = BS_STOP;
4094
        break;
4095
    case 14:
4096
        switch (sel) {
4097
        case 0:
4098
            gen_op_mtc0_epc();
4099
            rn = "EPC";
4100
            break;
4101
        default:
4102
            goto die;
4103
        }
4104
        break;
4105
    case 15:
4106
        switch (sel) {
4107
        case 0:
4108
            /* ignored */
4109
            rn = "PRid";
4110
            break;
4111
        case 1:
4112
            check_insn(env, ctx, ISA_MIPS32R2);
4113
            gen_op_mtc0_ebase();
4114
            rn = "EBase";
4115
            break;
4116
        default:
4117
            goto die;
4118
        }
4119
        break;
4120
    case 16:
4121
        switch (sel) {
4122
        case 0:
4123
            gen_op_mtc0_config0();
4124
            rn = "Config";
4125
            /* Stop translation as we may have switched the execution mode */
4126
            ctx->bstate = BS_STOP;
4127
            break;
4128
        case 1:
4129
            /* ignored */
4130
            rn = "Config1";
4131
            break;
4132
        case 2:
4133
            gen_op_mtc0_config2();
4134
            rn = "Config2";
4135
            /* Stop translation as we may have switched the execution mode */
4136
            ctx->bstate = BS_STOP;
4137
            break;
4138
        case 3:
4139
            /* ignored */
4140
            rn = "Config3";
4141
            break;
4142
        /* 6,7 are implementation dependent */
4143
        default:
4144
            rn = "Invalid config selector";
4145
            goto die;
4146
        }
4147
        break;
4148
    case 17:
4149
        switch (sel) {
4150
        case 0:
4151
            /* ignored */
4152
            rn = "LLAddr";
4153
            break;
4154
        default:
4155
            goto die;
4156
        }
4157
        break;
4158
    case 18:
4159
        switch (sel) {
4160
        case 0 ... 7:
4161
            gen_op_mtc0_watchlo(sel);
4162
            rn = "WatchLo";
4163
            break;
4164
        default:
4165
            goto die;
4166
        }
4167
        break;
4168
    case 19:
4169
        switch (sel) {
4170
        case 0 ... 7:
4171
            gen_op_mtc0_watchhi(sel);
4172
            rn = "WatchHi";
4173
            break;
4174
        default:
4175
            goto die;
4176
        }
4177
        break;
4178
    case 20:
4179
        switch (sel) {
4180
        case 0:
4181
            check_insn(env, ctx, ISA_MIPS3);
4182
            gen_op_mtc0_xcontext();
4183
            rn = "XContext";
4184
            break;
4185
        default:
4186
            goto die;
4187
        }
4188
        break;
4189
    case 21:
4190
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4191
        switch (sel) {
4192
        case 0:
4193
            gen_op_mtc0_framemask();
4194
            rn = "Framemask";
4195
            break;
4196
        default:
4197
            goto die;
4198
        }
4199
        break;
4200
    case 22:
4201
        /* ignored */
4202
        rn = "Diagnostic"; /* implementation dependent */
4203
        break;
4204
    case 23:
4205
        switch (sel) {
4206
        case 0:
4207
            gen_op_mtc0_debug(); /* EJTAG support */
4208
            /* BS_STOP isn't good enough here, hflags may have changed. */
4209
            gen_save_pc(ctx->pc + 4);
4210
            ctx->bstate = BS_EXCP;
4211
            rn = "Debug";
4212
            break;
4213
        case 1:
4214
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4215
            /* Stop translation as we may have switched the execution mode */
4216
            ctx->bstate = BS_STOP;
4217
            rn = "TraceControl";
4218
//            break;
4219
        case 2:
4220
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4221
            /* Stop translation as we may have switched the execution mode */
4222
            ctx->bstate = BS_STOP;
4223
            rn = "TraceControl2";
4224
//            break;
4225
        case 3:
4226
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4227
            /* Stop translation as we may have switched the execution mode */
4228
            ctx->bstate = BS_STOP;
4229
            rn = "UserTraceData";
4230
//            break;
4231
        case 4:
4232
//            gen_op_mtc0_debug(); /* PDtrace support */
4233
            /* Stop translation as we may have switched the execution mode */
4234
            ctx->bstate = BS_STOP;
4235
            rn = "TraceBPC";
4236
//            break;
4237
        default:
4238
            goto die;
4239
        }
4240
        break;
4241
    case 24:
4242
        switch (sel) {
4243
        case 0:
4244
            gen_op_mtc0_depc(); /* EJTAG support */
4245
            rn = "DEPC";
4246
            break;
4247
        default:
4248
            goto die;
4249
        }
4250
        break;
4251
    case 25:
4252
        switch (sel) {
4253
        case 0:
4254
            gen_op_mtc0_performance0();
4255
            rn = "Performance0";
4256
            break;
4257
        case 1:
4258
//            gen_op_mtc0_performance1();
4259
            rn = "Performance1";
4260
//            break;
4261
        case 2:
4262
//            gen_op_mtc0_performance2();
4263
            rn = "Performance2";
4264
//            break;
4265
        case 3:
4266
//            gen_op_mtc0_performance3();
4267
            rn = "Performance3";
4268
//            break;
4269
        case 4:
4270
//            gen_op_mtc0_performance4();
4271
            rn = "Performance4";
4272
//            break;
4273
        case 5:
4274
//            gen_op_mtc0_performance5();
4275
            rn = "Performance5";
4276
//            break;
4277
        case 6:
4278
//            gen_op_mtc0_performance6();
4279
            rn = "Performance6";
4280
//            break;
4281
        case 7:
4282
//            gen_op_mtc0_performance7();
4283
            rn = "Performance7";
4284
//            break;
4285
        default:
4286
            goto die;
4287
        }
4288
        break;
4289
    case 26:
4290
        /* ignored */
4291
        rn = "ECC";
4292
        break;
4293
    case 27:
4294
        switch (sel) {
4295
        case 0 ... 3:
4296
            /* ignored */
4297
            rn = "CacheErr";
4298
            break;
4299
        default:
4300
            goto die;
4301
        }
4302
        break;
4303
    case 28:
4304
        switch (sel) {
4305
        case 0:
4306
        case 2:
4307
        case 4:
4308
        case 6:
4309
            gen_op_mtc0_taglo();
4310
            rn = "TagLo";
4311
            break;
4312
        case 1:
4313
        case 3:
4314
        case 5:
4315
        case 7:
4316
            gen_op_mtc0_datalo();
4317
            rn = "DataLo";
4318
            break;
4319
        default:
4320
            goto die;
4321
        }
4322
        break;
4323
    case 29:
4324
        switch (sel) {
4325
        case 0:
4326
        case 2:
4327
        case 4:
4328
        case 6:
4329
            gen_op_mtc0_taghi();
4330
            rn = "TagHi";
4331
            break;
4332
        case 1:
4333
        case 3:
4334
        case 5:
4335
        case 7:
4336
            gen_op_mtc0_datahi();
4337
            rn = "DataHi";
4338
            break;
4339
        default:
4340
            rn = "invalid sel";
4341
            goto die;
4342
        }
4343
        break;
4344
    case 30:
4345
        switch (sel) {
4346
        case 0:
4347
            gen_op_mtc0_errorepc();
4348
            rn = "ErrorEPC";
4349
            break;
4350
        default:
4351
            goto die;
4352
        }
4353
        break;
4354
    case 31:
4355
        switch (sel) {
4356
        case 0:
4357
            gen_op_mtc0_desave(); /* EJTAG support */
4358
            rn = "DESAVE";
4359
            break;
4360
        default:
4361
            goto die;
4362
        }
4363
        /* Stop translation as we may have switched the execution mode */
4364
        ctx->bstate = BS_STOP;
4365
        break;
4366
    default:
4367
        goto die;
4368
    }
4369
#if defined MIPS_DEBUG_DISAS
4370
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4371
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4372
                rn, reg, sel);
4373
    }
4374
#endif
4375
    return;
4376

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

    
4388
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4389
                     int u, int sel, int h)
4390
{
4391
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4392

    
4393
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4394
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4395
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4396
        gen_op_set_T0(-1);
4397
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4398
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4399
        gen_op_set_T0(-1);
4400
    else if (u == 0) {
4401
        switch (rt) {
4402
        case 2:
4403
            switch (sel) {
4404
            case 1:
4405
                gen_op_mftc0_tcstatus();
4406
                break;
4407
            case 2:
4408
                gen_op_mftc0_tcbind();
4409
                break;
4410
            case 3:
4411
                gen_op_mftc0_tcrestart();
4412
                break;
4413
            case 4:
4414
                gen_op_mftc0_tchalt();
4415
                break;
4416
            case 5:
4417
                gen_op_mftc0_tccontext();
4418
                break;
4419
            case 6:
4420
                gen_op_mftc0_tcschedule();
4421
                break;
4422
            case 7:
4423
                gen_op_mftc0_tcschefback();
4424
                break;
4425
            default:
4426
                gen_mfc0(env, ctx, rt, sel);
4427
                break;
4428
            }
4429
            break;
4430
        case 10:
4431
            switch (sel) {
4432
            case 0:
4433
                gen_op_mftc0_entryhi();
4434
                break;
4435
            default:
4436
                gen_mfc0(env, ctx, rt, sel);
4437
                break;
4438
            }
4439
        case 12:
4440
            switch (sel) {
4441
            case 0:
4442
                gen_op_mftc0_status();
4443
                break;
4444
            default:
4445
                gen_mfc0(env, ctx, rt, sel);
4446
                break;
4447
            }
4448
        case 23:
4449
            switch (sel) {
4450
            case 0:
4451
                gen_op_mftc0_debug();
4452
                break;
4453
            default:
4454
                gen_mfc0(env, ctx, rt, sel);
4455
                break;
4456
            }
4457
            break;
4458
        default:
4459
            gen_mfc0(env, ctx, rt, sel);
4460
        }
4461
    } else switch (sel) {
4462
    /* GPR registers. */
4463
    case 0:
4464
        gen_op_mftgpr(rt);
4465
        break;
4466
    /* Auxiliary CPU registers */
4467
    case 1:
4468
        switch (rt) {
4469
        case 0:
4470
            gen_op_mftlo(0);
4471
            break;
4472
        case 1:
4473
            gen_op_mfthi(0);
4474
            break;
4475
        case 2:
4476
            gen_op_mftacx(0);
4477
            break;
4478
        case 4:
4479
            gen_op_mftlo(1);
4480
            break;
4481
        case 5:
4482
            gen_op_mfthi(1);
4483
            break;
4484
        case 6:
4485
            gen_op_mftacx(1);
4486
            break;
4487
        case 8:
4488
            gen_op_mftlo(2);
4489
            break;
4490
        case 9:
4491
            gen_op_mfthi(2);
4492
            break;
4493
        case 10:
4494
            gen_op_mftacx(2);
4495
            break;
4496
        case 12:
4497
            gen_op_mftlo(3);
4498
            break;
4499
        case 13:
4500
            gen_op_mfthi(3);
4501
            break;
4502
        case 14:
4503
            gen_op_mftacx(3);
4504
            break;
4505
        case 16:
4506
            gen_op_mftdsp();
4507
            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    /* Floating point (COP1). */
4513
    case 2:
4514
        /* XXX: For now we support only a single FPU context. */
4515
        if (h == 0) {
4516
            GEN_LOAD_FREG_FTN(WT0, rt);
4517
            gen_op_mfc1();
4518
        } else {
4519
            GEN_LOAD_FREG_FTN(WTH0, rt);
4520
            gen_op_mfhc1();
4521
        }
4522
        break;
4523
    case 3:
4524
        /* XXX: For now we support only a single FPU context. */
4525
        gen_op_cfc1(rt);
4526
        break;
4527
    /* COP2: Not implemented. */
4528
    case 4:
4529
    case 5:
4530
        /* fall through */
4531
    default:
4532
        goto die;
4533
    }
4534
#if defined MIPS_DEBUG_DISAS
4535
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4536
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4537
                rt, u, sel, h);
4538
    }
4539
#endif
4540
    return;
4541

    
4542
die:
4543
#if defined MIPS_DEBUG_DISAS
4544
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4545
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4546
                rt, u, sel, h);
4547
    }
4548
#endif
4549
    generate_exception(ctx, EXCP_RI);
4550
}
4551

    
4552
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4553
                     int u, int sel, int h)
4554
{
4555
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4556

    
4557
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4558
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4559
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4560
        /* NOP */ ;
4561
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4562
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4563
        /* NOP */ ;
4564
    else if (u == 0) {
4565
        switch (rd) {
4566
        case 2:
4567
            switch (sel) {
4568
            case 1:
4569
                gen_op_mttc0_tcstatus();
4570
                break;
4571
            case 2:
4572
                gen_op_mttc0_tcbind();
4573
                break;
4574
            case 3:
4575
                gen_op_mttc0_tcrestart();
4576
                break;
4577
            case 4:
4578
                gen_op_mttc0_tchalt();
4579
                break;
4580
            case 5:
4581
                gen_op_mttc0_tccontext();
4582
                break;
4583
            case 6:
4584
                gen_op_mttc0_tcschedule();
4585
                break;
4586
            case 7:
4587
                gen_op_mttc0_tcschefback();
4588
                break;
4589
            default:
4590
                gen_mtc0(env, ctx, rd, sel);
4591
                break;
4592
            }
4593
            break;
4594
        case 10:
4595
            switch (sel) {
4596
            case 0:
4597
                gen_op_mttc0_entryhi();
4598
                break;
4599
            default:
4600
                gen_mtc0(env, ctx, rd, sel);
4601
                break;
4602
            }
4603
        case 12:
4604
            switch (sel) {
4605
            case 0:
4606
                gen_op_mttc0_status();
4607
                break;
4608
            default:
4609
                gen_mtc0(env, ctx, rd, sel);
4610
                break;
4611
            }
4612
        case 23:
4613
            switch (sel) {
4614
            case 0:
4615
                gen_op_mttc0_debug();
4616
                break;
4617
            default:
4618
                gen_mtc0(env, ctx, rd, sel);
4619
                break;
4620
            }
4621
            break;
4622
        default:
4623
            gen_mtc0(env, ctx, rd, sel);
4624
        }
4625
    } else switch (sel) {
4626
    /* GPR registers. */
4627
    case 0:
4628
        gen_op_mttgpr(rd);
4629
        break;
4630
    /* Auxiliary CPU registers */
4631
    case 1:
4632
        switch (rd) {
4633
        case 0:
4634
            gen_op_mttlo(0);
4635
            break;
4636
        case 1:
4637
            gen_op_mtthi(0);
4638
            break;
4639
        case 2:
4640
            gen_op_mttacx(0);
4641
            break;
4642
        case 4:
4643
            gen_op_mttlo(1);
4644
            break;
4645
        case 5:
4646
            gen_op_mtthi(1);
4647
            break;
4648
        case 6:
4649
            gen_op_mttacx(1);
4650
            break;
4651
        case 8:
4652
            gen_op_mttlo(2);
4653
            break;
4654
        case 9:
4655
            gen_op_mtthi(2);
4656
            break;
4657
        case 10:
4658
            gen_op_mttacx(2);
4659
            break;
4660
        case 12:
4661
            gen_op_mttlo(3);
4662
            break;
4663
        case 13:
4664
            gen_op_mtthi(3);
4665
            break;
4666
        case 14:
4667
            gen_op_mttacx(3);
4668
            break;
4669
        case 16:
4670
            gen_op_mttdsp();
4671
            break;
4672
        default:
4673
            goto die;
4674
        }
4675
        break;
4676
    /* Floating point (COP1). */
4677
    case 2:
4678
        /* XXX: For now we support only a single FPU context. */
4679
        if (h == 0) {
4680
            gen_op_mtc1();
4681
            GEN_STORE_FTN_FREG(rd, WT0);
4682
        } else {
4683
            gen_op_mthc1();
4684
            GEN_STORE_FTN_FREG(rd, WTH0);
4685
        }
4686
        break;
4687
    case 3:
4688
        /* XXX: For now we support only a single FPU context. */
4689
        gen_op_ctc1(rd);
4690
        break;
4691
    /* COP2: Not implemented. */
4692
    case 4:
4693
    case 5:
4694
        /* fall through */
4695
    default:
4696
        goto die;
4697
    }
4698
#if defined MIPS_DEBUG_DISAS
4699
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4700
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4701
                rd, u, sel, h);
4702
    }
4703
#endif
4704
    return;
4705

    
4706
die:
4707
#if defined MIPS_DEBUG_DISAS
4708
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4709
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4710
                rd, u, sel, h);
4711
    }
4712
#endif
4713
    generate_exception(ctx, EXCP_RI);
4714
}
4715

    
4716
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4717
{
4718
    const char *opn = "ldst";
4719

    
4720
    switch (opc) {
4721
    case OPC_MFC0:
4722
        if (rt == 0) {
4723
            /* Treat as NOP. */
4724
            return;
4725
        }
4726
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4727
        gen_op_store_T0_gpr(rt);
4728
        opn = "mfc0";
4729
        break;
4730
    case OPC_MTC0:
4731
        GEN_LOAD_REG_T0(rt);
4732
        save_cpu_state(ctx, 1);
4733
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4734
        opn = "mtc0";
4735
        break;
4736
#if defined(TARGET_MIPS64)
4737
    case OPC_DMFC0:
4738
        check_insn(env, ctx, ISA_MIPS3);
4739
        if (rt == 0) {
4740
            /* Treat as NOP. */
4741
            return;
4742
        }
4743
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4744
        gen_op_store_T0_gpr(rt);
4745
        opn = "dmfc0";
4746
        break;
4747
    case OPC_DMTC0:
4748
        check_insn(env, ctx, ISA_MIPS3);
4749
        GEN_LOAD_REG_T0(rt);
4750
        save_cpu_state(ctx, 1);
4751
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4752
        opn = "dmtc0";
4753
        break;
4754
#endif
4755
    case OPC_MFTR:
4756
        check_insn(env, ctx, ASE_MT);
4757
        if (rd == 0) {
4758
            /* Treat as NOP. */
4759
            return;
4760
        }
4761
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4762
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4763
        gen_op_store_T0_gpr(rd);
4764
        opn = "mftr";
4765
        break;
4766
    case OPC_MTTR:
4767
        check_insn(env, ctx, ASE_MT);
4768
        GEN_LOAD_REG_T0(rt);
4769
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4770
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4771
        opn = "mttr";
4772
        break;
4773
    case OPC_TLBWI:
4774
        opn = "tlbwi";
4775
        if (!env->tlb->do_tlbwi)
4776
            goto die;
4777
        gen_op_tlbwi();
4778
        break;
4779
    case OPC_TLBWR:
4780
        opn = "tlbwr";
4781
        if (!env->tlb->do_tlbwr)
4782
            goto die;
4783
        gen_op_tlbwr();
4784
        break;
4785
    case OPC_TLBP:
4786
        opn = "tlbp";
4787
        if (!env->tlb->do_tlbp)
4788
            goto die;
4789
        gen_op_tlbp();
4790
        break;
4791
    case OPC_TLBR:
4792
        opn = "tlbr";
4793
        if (!env->tlb->do_tlbr)
4794
            goto die;
4795
        gen_op_tlbr();
4796
        break;
4797
    case OPC_ERET:
4798
        opn = "eret";
4799
        check_insn(env, ctx, ISA_MIPS2);
4800
        save_cpu_state(ctx, 1);
4801
        gen_op_eret();
4802
        ctx->bstate = BS_EXCP;
4803
        break;
4804
    case OPC_DERET:
4805
        opn = "deret";
4806
        check_insn(env, ctx, ISA_MIPS32);
4807
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4808
            MIPS_INVAL(opn);
4809
            generate_exception(ctx, EXCP_RI);
4810
        } else {
4811
            save_cpu_state(ctx, 1);
4812
            gen_op_deret();
4813
            ctx->bstate = BS_EXCP;
4814
        }
4815
        break;
4816
    case OPC_WAIT:
4817
        opn = "wait";
4818
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4819
        /* If we get an exception, we want to restart at next instruction */
4820
        ctx->pc += 4;
4821
        save_cpu_state(ctx, 1);
4822
        ctx->pc -= 4;
4823
        gen_op_wait();
4824
        ctx->bstate = BS_EXCP;
4825
        break;
4826
    default:
4827
 die:
4828
        MIPS_INVAL(opn);
4829
        generate_exception(ctx, EXCP_RI);
4830
        return;
4831
    }
4832
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4833
}
4834

    
4835
/* CP1 Branches (before delay slot) */
4836
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4837
                                 int32_t cc, int32_t offset)
4838
{
4839
    target_ulong btarget;
4840
    const char *opn = "cp1 cond branch";
4841

    
4842
    if (cc != 0)
4843
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4844

    
4845
    btarget = ctx->pc + 4 + offset;
4846

    
4847
    switch (op) {
4848
    case OPC_BC1F:
4849
        gen_op_bc1f(cc);
4850
        opn = "bc1f";
4851
        goto not_likely;
4852
    case OPC_BC1FL:
4853
        gen_op_bc1f(cc);
4854
        opn = "bc1fl";
4855
        goto likely;
4856
    case OPC_BC1T:
4857
        gen_op_bc1t(cc);
4858
        opn = "bc1t";
4859
        goto not_likely;
4860
    case OPC_BC1TL:
4861
        gen_op_bc1t(cc);
4862
        opn = "bc1tl";
4863
    likely:
4864
        ctx->hflags |= MIPS_HFLAG_BL;
4865
        gen_op_set_bcond();
4866
        gen_op_save_bcond();
4867
        break;
4868
    case OPC_BC1FANY2:
4869
        gen_op_bc1any2f(cc);
4870
        opn = "bc1any2f";
4871
        goto not_likely;
4872
    case OPC_BC1TANY2:
4873
        gen_op_bc1any2t(cc);
4874
        opn = "bc1any2t";
4875
        goto not_likely;
4876
    case OPC_BC1FANY4:
4877
        gen_op_bc1any4f(cc);
4878
        opn = "bc1any4f";
4879
        goto not_likely;
4880
    case OPC_BC1TANY4:
4881
        gen_op_bc1any4t(cc);
4882
        opn = "bc1any4t";
4883
    not_likely:
4884
        ctx->hflags |= MIPS_HFLAG_BC;
4885
        gen_op_set_bcond();
4886
        break;
4887
    default:
4888
        MIPS_INVAL(opn);
4889
        generate_exception (ctx, EXCP_RI);
4890
        return;
4891
    }
4892
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4893
               ctx->hflags, btarget);
4894
    ctx->btarget = btarget;
4895
}
4896

    
4897
/* Coprocessor 1 (FPU) */
4898

    
4899
#define FOP(func, fmt) (((fmt) << 21) | (func))
4900

    
4901
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4902
{
4903
    const char *opn = "cp1 move";
4904

    
4905
    switch (opc) {
4906
    case OPC_MFC1:
4907
        GEN_LOAD_FREG_FTN(WT0, fs);
4908
        gen_op_mfc1();
4909
        GEN_STORE_T0_REG(rt);
4910
        opn = "mfc1";
4911
        break;
4912
    case OPC_MTC1:
4913
        GEN_LOAD_REG_T0(rt);
4914
        gen_op_mtc1();
4915
        GEN_STORE_FTN_FREG(fs, WT0);
4916
        opn = "mtc1";
4917
        break;
4918
    case OPC_CFC1:
4919
        gen_op_cfc1(fs);
4920
        GEN_STORE_T0_REG(rt);
4921
        opn = "cfc1";
4922
        break;
4923
    case OPC_CTC1:
4924
        GEN_LOAD_REG_T0(rt);
4925
        gen_op_ctc1(fs);
4926
        opn = "ctc1";
4927
        break;
4928
    case OPC_DMFC1:
4929
        GEN_LOAD_FREG_FTN(DT0, fs);
4930
        gen_op_dmfc1();
4931
        GEN_STORE_T0_REG(rt);
4932
        opn = "dmfc1";
4933
        break;
4934
    case OPC_DMTC1:
4935
        GEN_LOAD_REG_T0(rt);
4936
        gen_op_dmtc1();
4937
        GEN_STORE_FTN_FREG(fs, DT0);
4938
        opn = "dmtc1";
4939
        break;
4940
    case OPC_MFHC1:
4941
        GEN_LOAD_FREG_FTN(WTH0, fs);
4942
        gen_op_mfhc1();
4943
        GEN_STORE_T0_REG(rt);
4944
        opn = "mfhc1";
4945
        break;
4946
    case OPC_MTHC1:
4947
        GEN_LOAD_REG_T0(rt);
4948
        gen_op_mthc1();
4949
        GEN_STORE_FTN_FREG(fs, WTH0);
4950
        opn = "mthc1";
4951
        break;
4952
    default:
4953
        MIPS_INVAL(opn);
4954
        generate_exception (ctx, EXCP_RI);
4955
        return;
4956
    }
4957
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4958
}
4959

    
4960
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4961
{
4962
    uint32_t ccbit;
4963

    
4964
    GEN_LOAD_REG_T0(rd);
4965
    GEN_LOAD_REG_T1(rs);
4966
    if (cc) {
4967
        ccbit = 1 << (24 + cc);
4968
    } else
4969
        ccbit = 1 << 23;
4970
    if (!tf)
4971
        gen_op_movf(ccbit);
4972
    else
4973
        gen_op_movt(ccbit);
4974
    GEN_STORE_T0_REG(rd);
4975
}
4976

    
4977
#define GEN_MOVCF(fmt)                                                \
4978
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4979
{                                                                     \
4980
    uint32_t ccbit;                                                   \
4981
                                                                      \
4982
    if (cc) {                                                         \
4983
        ccbit = 1 << (24 + cc);                                       \
4984
    } else                                                            \
4985
        ccbit = 1 << 23;                                              \
4986
    if (!tf)                                                          \
4987
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4988
    else                                                              \
4989
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4990
}
4991
GEN_MOVCF(d);
4992
GEN_MOVCF(s);
4993
GEN_MOVCF(ps);
4994
#undef GEN_MOVCF
4995

    
4996
static void gen_farith (DisasContext *ctx, uint32_t op1,
4997
                        int ft, int fs, int fd, int cc)
4998
{
4999
    const char *opn = "farith";
5000
    const char *condnames[] = {
5001
            "c.f",
5002
            "c.un",
5003
            "c.eq",
5004
            "c.ueq",
5005
            "c.olt",
5006
            "c.ult",
5007
            "c.ole",
5008
            "c.ule",
5009
            "c.sf",
5010
            "c.ngle",
5011
            "c.seq",
5012
            "c.ngl",
5013
            "c.lt",
5014
            "c.nge",
5015
            "c.le",
5016
            "c.ngt",
5017
    };
5018
    const char *condnames_abs[] = {
5019
            "cabs.f",
5020
            "cabs.un",
5021
            "cabs.eq",
5022
            "cabs.ueq",
5023
            "cabs.olt",
5024
            "cabs.ult",
5025
            "cabs.ole",
5026
            "cabs.ule",
5027
            "cabs.sf",
5028
            "cabs.ngle",
5029
            "cabs.seq",
5030
            "cabs.ngl",
5031
            "cabs.lt",
5032
            "cabs.nge",
5033
            "cabs.le",
5034
            "cabs.ngt",
5035
    };
5036
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5037
    uint32_t func = ctx->opcode & 0x3f;
5038

    
5039
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5040
    case FOP(0, 16):
5041
        GEN_LOAD_FREG_FTN(WT0, fs);
5042
        GEN_LOAD_FREG_FTN(WT1, ft);
5043
        gen_op_float_add_s();
5044
        GEN_STORE_FTN_FREG(fd, WT2);
5045
        opn = "add.s";
5046
        optype = BINOP;
5047
        break;
5048
    case FOP(1, 16):
5049
        GEN_LOAD_FREG_FTN(WT0, fs);
5050
        GEN_LOAD_FREG_FTN(WT1, ft);
5051
        gen_op_float_sub_s();
5052
        GEN_STORE_FTN_FREG(fd, WT2);
5053
        opn = "sub.s";
5054
        optype = BINOP;
5055
        break;
5056
    case FOP(2, 16):
5057
        GEN_LOAD_FREG_FTN(WT0, fs);
5058
        GEN_LOAD_FREG_FTN(WT1, ft);
5059
        gen_op_float_mul_s();
5060
        GEN_STORE_FTN_FREG(fd, WT2);
5061
        opn = "mul.s";
5062
        optype = BINOP;
5063
        break;
5064
    case FOP(3, 16):
5065
        GEN_LOAD_FREG_FTN(WT0, fs);
5066
        GEN_LOAD_FREG_FTN(WT1, ft);
5067
        gen_op_float_div_s();
5068
        GEN_STORE_FTN_FREG(fd, WT2);
5069
        opn = "div.s";
5070
        optype = BINOP;
5071
        break;
5072
    case FOP(4, 16):
5073
        GEN_LOAD_FREG_FTN(WT0, fs);
5074
        gen_op_float_sqrt_s();
5075
        GEN_STORE_FTN_FREG(fd, WT2);
5076
        opn = "sqrt.s";
5077
        break;
5078
    case FOP(5, 16):
5079
        GEN_LOAD_FREG_FTN(WT0, fs);
5080
        gen_op_float_abs_s();
5081
        GEN_STORE_FTN_FREG(fd, WT2);
5082
        opn = "abs.s";
5083
        break;
5084
    case FOP(6, 16):
5085
        GEN_LOAD_FREG_FTN(WT0, fs);
5086
        gen_op_float_mov_s();
5087
        GEN_STORE_FTN_FREG(fd, WT2);
5088
        opn = "mov.s";
5089
        break;
5090
    case FOP(7, 16):
5091
        GEN_LOAD_FREG_FTN(WT0, fs);
5092
        gen_op_float_chs_s();
5093
        GEN_STORE_FTN_FREG(fd, WT2);
5094
        opn = "neg.s";
5095
        break;
5096
    case FOP(8, 16):
5097
        check_cp1_64bitmode(ctx);
5098
        GEN_LOAD_FREG_FTN(WT0, fs);
5099
        gen_op_float_roundl_s();
5100
        GEN_STORE_FTN_FREG(fd, DT2);
5101
        opn = "round.l.s";
5102
        break;
5103
    case FOP(9, 16):
5104
        check_cp1_64bitmode(ctx);
5105
        GEN_LOAD_FREG_FTN(WT0, fs);
5106
        gen_op_float_truncl_s();
5107
        GEN_STORE_FTN_FREG(fd, DT2);
5108
        opn = "trunc.l.s";
5109
        break;
5110
    case FOP(10, 16):
5111
        check_cp1_64bitmode(ctx);
5112
        GEN_LOAD_FREG_FTN(WT0, fs);
5113
        gen_op_float_ceill_s();
5114
        GEN_STORE_FTN_FREG(fd, DT2);
5115
        opn = "ceil.l.s";
5116
        break;
5117
    case FOP(11, 16):
5118
        check_cp1_64bitmode(ctx);
5119
        GEN_LOAD_FREG_FTN(WT0, fs);
5120
        gen_op_float_floorl_s();
5121
        GEN_STORE_FTN_FREG(fd, DT2);
5122
        opn = "floor.l.s";
5123
        break;
5124
    case FOP(12, 16):
5125
        GEN_LOAD_FREG_FTN(WT0, fs);
5126
        gen_op_float_roundw_s();
5127
        GEN_STORE_FTN_FREG(fd, WT2);
5128
        opn = "round.w.s";
5129
        break;
5130
    case FOP(13, 16):
5131
        GEN_LOAD_FREG_FTN(WT0, fs);
5132
        gen_op_float_truncw_s();
5133
        GEN_STORE_FTN_FREG(fd, WT2);
5134
        opn = "trunc.w.s";
5135
        break;
5136
    case FOP(14, 16):
5137
        GEN_LOAD_FREG_FTN(WT0, fs);
5138
        gen_op_float_ceilw_s();
5139
        GEN_STORE_FTN_FREG(fd, WT2);
5140
        opn = "ceil.w.s";
5141
        break;
5142
    case FOP(15, 16):
5143
        GEN_LOAD_FREG_FTN(WT0, fs);
5144
        gen_op_float_floorw_s();
5145
        GEN_STORE_FTN_FREG(fd, WT2);
5146
        opn = "floor.w.s";
5147
        break;
5148
    case FOP(17, 16):
5149
        GEN_LOAD_REG_T0(ft);
5150
        GEN_LOAD_FREG_FTN(WT0, fs);
5151
        GEN_LOAD_FREG_FTN(WT2, fd);
5152
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5153
        GEN_STORE_FTN_FREG(fd, WT2);
5154
        opn = "movcf.s";
5155
        break;
5156
    case FOP(18, 16):
5157
        GEN_LOAD_REG_T0(ft);
5158
        GEN_LOAD_FREG_FTN(WT0, fs);
5159
        GEN_LOAD_FREG_FTN(WT2, fd);
5160
        gen_op_float_movz_s();
5161
        GEN_STORE_FTN_FREG(fd, WT2);
5162
        opn = "movz.s";
5163
        break;
5164
    case FOP(19, 16):
5165
        GEN_LOAD_REG_T0(ft);
5166
        GEN_LOAD_FREG_FTN(WT0, fs);
5167
        GEN_LOAD_FREG_FTN(WT2, fd);
5168
        gen_op_float_movn_s();
5169
        GEN_STORE_FTN_FREG(fd, WT2);
5170
        opn = "movn.s";
5171
        break;
5172
    case FOP(21, 16):
5173
        check_cop1x(ctx);
5174
        GEN_LOAD_FREG_FTN(WT0, fs);
5175
        gen_op_float_recip_s();
5176
        GEN_STORE_FTN_FREG(fd, WT2);
5177
        opn = "recip.s";
5178
        break;
5179
    case FOP(22, 16):
5180
        check_cop1x(ctx);
5181
        GEN_LOAD_FREG_FTN(WT0, fs);
5182
        gen_op_float_rsqrt_s();
5183
        GEN_STORE_FTN_FREG(fd, WT2);
5184
        opn = "rsqrt.s";
5185
        break;
5186
    case FOP(28, 16):
5187
        check_cp1_64bitmode(ctx);
5188
        GEN_LOAD_FREG_FTN(WT0, fs);
5189
        GEN_LOAD_FREG_FTN(WT2, fd);
5190
        gen_op_float_recip2_s();
5191
        GEN_STORE_FTN_FREG(fd, WT2);
5192
        opn = "recip2.s";
5193
        break;
5194
    case FOP(29, 16):
5195
        check_cp1_64bitmode(ctx);
5196
        GEN_LOAD_FREG_FTN(WT0, fs);
5197
        gen_op_float_recip1_s();
5198
        GEN_STORE_FTN_FREG(fd, WT2);
5199
        opn = "recip1.s";
5200
        break;
5201
    case FOP(30, 16):
5202
        check_cp1_64bitmode(ctx);
5203
        GEN_LOAD_FREG_FTN(WT0, fs);
5204
        gen_op_float_rsqrt1_s();
5205
        GEN_STORE_FTN_FREG(fd, WT2);
5206
        opn = "rsqrt1.s";
5207
        break;
5208
    case FOP(31, 16):
5209
        check_cp1_64bitmode(ctx);
5210
        GEN_LOAD_FREG_FTN(WT0, fs);
5211
        GEN_LOAD_FREG_FTN(WT2, ft);
5212
        gen_op_float_rsqrt2_s();
5213
        GEN_STORE_FTN_FREG(fd, WT2);
5214
        opn = "rsqrt2.s";
5215
        break;
5216
    case FOP(33, 16):
5217
        check_cp1_registers(ctx, fd);
5218
        GEN_LOAD_FREG_FTN(WT0, fs);
5219
        gen_op_float_cvtd_s();
5220
        GEN_STORE_FTN_FREG(fd, DT2);
5221
        opn = "cvt.d.s";
5222
        break;
5223
    case FOP(36, 16):
5224
        GEN_LOAD_FREG_FTN(WT0, fs);
5225
        gen_op_float_cvtw_s();
5226
        GEN_STORE_FTN_FREG(fd, WT2);
5227
        opn = "cvt.w.s";
5228
        break;
5229
    case FOP(37, 16):
5230
        check_cp1_64bitmode(ctx);
5231
        GEN_LOAD_FREG_FTN(WT0, fs);
5232
        gen_op_float_cvtl_s();
5233
        GEN_STORE_FTN_FREG(fd, DT2);
5234
        opn = "cvt.l.s";
5235
        break;
5236
    case FOP(38, 16):
5237
        check_cp1_64bitmode(ctx);
5238
        GEN_LOAD_FREG_FTN(WT1, fs);
5239
        GEN_LOAD_FREG_FTN(WT0, ft);
5240
        gen_op_float_cvtps_s();
5241
        GEN_STORE_FTN_FREG(fd, DT2);
5242
        opn = "cvt.ps.s";
5243
        break;
5244
    case FOP(48, 16):
5245
    case FOP(49, 16):
5246
    case FOP(50, 16):
5247
    case FOP(51, 16):
5248
    case FOP(52, 16):
5249
    case FOP(53, 16):
5250
    case FOP(54, 16):
5251
    case FOP(55, 16):
5252
    case FOP(56, 16):
5253
    case FOP(57, 16):
5254
    case FOP(58, 16):
5255
    case FOP(59, 16):
5256
    case FOP(60, 16):
5257
    case FOP(61, 16):
5258
    case FOP(62, 16):
5259
    case FOP(63, 16):
5260
        GEN_LOAD_FREG_FTN(WT0, fs);
5261
        GEN_LOAD_FREG_FTN(WT1, ft);
5262
        if (ctx->opcode & (1 << 6)) {
5263
            check_cop1x(ctx);
5264
            gen_cmpabs_s(func-48, cc);
5265
            opn = condnames_abs[func-48];
5266
        } else {
5267
            gen_cmp_s(func-48, cc);
5268
            opn = condnames[func-48];
5269
        }
5270
        break;
5271
    case FOP(0, 17):
5272
        check_cp1_registers(ctx, fs | ft | fd);
5273
        GEN_LOAD_FREG_FTN(DT0, fs);
5274
        GEN_LOAD_FREG_FTN(DT1, ft);
5275
        gen_op_float_add_d();
5276
        GEN_STORE_FTN_FREG(fd, DT2);
5277
        opn = "add.d";
5278
        optype = BINOP;
5279
        break;
5280
    case FOP(1, 17):
5281
        check_cp1_registers(ctx, fs | ft | fd);
5282
        GEN_LOAD_FREG_FTN(DT0, fs);
5283
        GEN_LOAD_FREG_FTN(DT1, ft);
5284
        gen_op_float_sub_d();
5285
        GEN_STORE_FTN_FREG(fd, DT2);
5286
        opn = "sub.d";
5287
        optype = BINOP;
5288
        break;
5289
    case FOP(2, 17):
5290
        check_cp1_registers(ctx, fs | ft | fd);
5291
        GEN_LOAD_FREG_FTN(DT0, fs);
5292
        GEN_LOAD_FREG_FTN(DT1, ft);
5293
        gen_op_float_mul_d();
5294
        GEN_STORE_FTN_FREG(fd, DT2);
5295
        opn = "mul.d";
5296
        optype = BINOP;
5297
        break;
5298
    case FOP(3, 17):
5299
        check_cp1_registers(ctx, fs | ft | fd);
5300
        GEN_LOAD_FREG_FTN(DT0, fs);
5301
        GEN_LOAD_FREG_FTN(DT1, ft);
5302
        gen_op_float_div_d();
5303
        GEN_STORE_FTN_FREG(fd, DT2);
5304
        opn = "div.d";
5305
        optype = BINOP;
5306
        break;
5307
    case FOP(4, 17):
5308
        check_cp1_registers(ctx, fs | fd);
5309
        GEN_LOAD_FREG_FTN(DT0, fs);
5310
        gen_op_float_sqrt_d();
5311
        GEN_STORE_FTN_FREG(fd, DT2);
5312
        opn = "sqrt.d";
5313
        break;
5314
    case FOP(5, 17):
5315
        check_cp1_registers(ctx, fs | fd);
5316
        GEN_LOAD_FREG_FTN(DT0, fs);
5317
        gen_op_float_abs_d();
5318
        GEN_STORE_FTN_FREG(fd, DT2);
5319
        opn = "abs.d";
5320
        break;
5321
    case FOP(6, 17):
5322
        check_cp1_registers(ctx, fs | fd);
5323
        GEN_LOAD_FREG_FTN(DT0, fs);
5324
        gen_op_float_mov_d();
5325
        GEN_STORE_FTN_FREG(fd, DT2);
5326
        opn = "mov.d";
5327
        break;
5328
    case FOP(7, 17):
5329
        check_cp1_registers(ctx, fs | fd);
5330
        GEN_LOAD_FREG_FTN(DT0, fs);
5331
        gen_op_float_chs_d();
5332
        GEN_STORE_FTN_FREG(fd, DT2);
5333
        opn = "neg.d";
5334
        break;
5335
    case FOP(8, 17):
5336
        check_cp1_64bitmode(ctx);
5337
        GEN_LOAD_FREG_FTN(DT0, fs);
5338
        gen_op_float_roundl_d();
5339
        GEN_STORE_FTN_FREG(fd, DT2);
5340
        opn = "round.l.d";
5341
        break;
5342
    case FOP(9, 17):
5343
        check_cp1_64bitmode(ctx);
5344
        GEN_LOAD_FREG_FTN(DT0, fs);
5345
        gen_op_float_truncl_d();
5346
        GEN_STORE_FTN_FREG(fd, DT2);
5347
        opn = "trunc.l.d";
5348
        break;
5349
    case FOP(10, 17):
5350
        check_cp1_64bitmode(ctx);
5351
        GEN_LOAD_FREG_FTN(DT0, fs);
5352
        gen_op_float_ceill_d();
5353
        GEN_STORE_FTN_FREG(fd, DT2);
5354
        opn = "ceil.l.d";
5355
        break;
5356
    case FOP(11, 17):
5357
        check_cp1_64bitmode(ctx);
5358
        GEN_LOAD_FREG_FTN(DT0, fs);
5359
        gen_op_float_floorl_d();
5360
        GEN_STORE_FTN_FREG(fd, DT2);
5361
        opn = "floor.l.d";
5362
        break;
5363
    case FOP(12, 17):
5364
        check_cp1_registers(ctx, fs);
5365
        GEN_LOAD_FREG_FTN(DT0, fs);
5366
        gen_op_float_roundw_d();
5367
        GEN_STORE_FTN_FREG(fd, WT2);
5368
        opn = "round.w.d";
5369
        break;
5370
    case FOP(13, 17):
5371
        check_cp1_registers(ctx, fs);
5372
        GEN_LOAD_FREG_FTN(DT0, fs);
5373
        gen_op_float_truncw_d();
5374
        GEN_STORE_FTN_FREG(fd, WT2);
5375
        opn = "trunc.w.d";
5376
        break;
5377
    case FOP(14, 17):
5378
        check_cp1_registers(ctx, fs);
5379
        GEN_LOAD_FREG_FTN(DT0, fs);
5380
        gen_op_float_ceilw_d();
5381
        GEN_STORE_FTN_FREG(fd, WT2);
5382
        opn = "ceil.w.d";
5383
        break;
5384
    case FOP(15, 17):
5385
        check_cp1_registers(ctx, fs);
5386
        GEN_LOAD_FREG_FTN(DT0, fs);
5387
        gen_op_float_floorw_d();
5388
        GEN_STORE_FTN_FREG(fd, WT2);
5389
        opn = "floor.w.d";
5390
        break;
5391
    case FOP(17, 17):
5392
        GEN_LOAD_REG_T0(ft);
5393
        GEN_LOAD_FREG_FTN(DT0, fs);
5394
        GEN_LOAD_FREG_FTN(DT2, fd);
5395
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5396
        GEN_STORE_FTN_FREG(fd, DT2);
5397
        opn = "movcf.d";
5398
        break;
5399
    case FOP(18, 17):
5400
        GEN_LOAD_REG_T0(ft);
5401
        GEN_LOAD_FREG_FTN(DT0, fs);
5402
        GEN_LOAD_FREG_FTN(DT2, fd);
5403
        gen_op_float_movz_d();
5404
        GEN_STORE_FTN_FREG(fd, DT2);
5405
        opn = "movz.d";
5406
        break;
5407
    case FOP(19, 17):
5408
        GEN_LOAD_REG_T0(ft);
5409
        GEN_LOAD_FREG_FTN(DT0, fs);
5410
        GEN_LOAD_FREG_FTN(DT2, fd);
5411
        gen_op_float_movn_d();
5412
        GEN_STORE_FTN_FREG(fd, DT2);
5413
        opn = "movn.d";
5414
        break;
5415
    case FOP(21, 17):
5416
        check_cp1_64bitmode(ctx);
5417
        GEN_LOAD_FREG_FTN(DT0, fs);
5418
        gen_op_float_recip_d();
5419
        GEN_STORE_FTN_FREG(fd, DT2);
5420
        opn = "recip.d";
5421
        break;
5422
    case FOP(22, 17):
5423
        check_cp1_64bitmode(ctx);
5424
        GEN_LOAD_FREG_FTN(DT0, fs);
5425
        gen_op_float_rsqrt_d();
5426
        GEN_STORE_FTN_FREG(fd, DT2);
5427
        opn = "rsqrt.d";
5428
        break;
5429
    case FOP(28, 17):
5430
        check_cp1_64bitmode(ctx);
5431
        GEN_LOAD_FREG_FTN(DT0, fs);
5432
        GEN_LOAD_FREG_FTN(DT2, ft);
5433
        gen_op_float_recip2_d();
5434
        GEN_STORE_FTN_FREG(fd, DT2);
5435
        opn = "recip2.d";
5436
        break;
5437
    case FOP(29, 17):
5438
        check_cp1_64bitmode(ctx);
5439
        GEN_LOAD_FREG_FTN(DT0, fs);
5440
        gen_op_float_recip1_d();
5441
        GEN_STORE_FTN_FREG(fd, DT2);
5442
        opn = "recip1.d";
5443
        break;
5444
    case FOP(30, 17):
5445
        check_cp1_64bitmode(ctx);
5446
        GEN_LOAD_FREG_FTN(DT0, fs);
5447
        gen_op_float_rsqrt1_d();
5448
        GEN_STORE_FTN_FREG(fd, DT2);
5449
        opn = "rsqrt1.d";
5450
        break;
5451
    case FOP(31, 17):
5452
        check_cp1_64bitmode(ctx);
5453
        GEN_LOAD_FREG_FTN(DT0, fs);
5454
        GEN_LOAD_FREG_FTN(DT2, ft);
5455
        gen_op_float_rsqrt2_d();
5456
        GEN_STORE_FTN_FREG(fd, DT2);
5457
        opn = "rsqrt2.d";
5458
        break;
5459
    case FOP(48, 17):
5460
    case FOP(49, 17):
5461
    case FOP(50, 17):
5462
    case FOP(51, 17):
5463
    case FOP(52, 17):
5464
    case FOP(53, 17):
5465
    case FOP(54, 17):
5466
    case FOP(55, 17):
5467
    case FOP(56, 17):
5468
    case FOP(57, 17):
5469
    case FOP(58, 17):
5470
    case FOP(59, 17):
5471
    case FOP(60, 17):
5472
    case FOP(61, 17):
5473
    case FOP(62, 17):
5474
    case FOP(63, 17):
5475
        GEN_LOAD_FREG_FTN(DT0, fs);
5476
        GEN_LOAD_FREG_FTN(DT1, ft);
5477
        if (ctx->opcode & (1 << 6)) {
5478
            check_cop1x(ctx);
5479
            check_cp1_registers(ctx, fs | ft);
5480
            gen_cmpabs_d(func-48, cc);
5481
            opn = condnames_abs[func-48];
5482
        } else {
5483
            check_cp1_registers(ctx, fs | ft);
5484
            gen_cmp_d(func-48, cc);
5485
            opn = condnames[func-48];
5486
        }
5487
        break;
5488
    case FOP(32, 17):
5489
        check_cp1_registers(ctx, fs);
5490
        GEN_LOAD_FREG_FTN(DT0, fs);
5491
        gen_op_float_cvts_d();
5492
        GEN_STORE_FTN_FREG(fd, WT2);
5493
        opn = "cvt.s.d";
5494
        break;
5495
    case FOP(36, 17):
5496
        check_cp1_registers(ctx, fs);
5497
        GEN_LOAD_FREG_FTN(DT0, fs);
5498
        gen_op_float_cvtw_d();
5499
        GEN_STORE_FTN_FREG(fd, WT2);
5500
        opn = "cvt.w.d";
5501
        break;
5502
    case FOP(37, 17):
5503
        check_cp1_64bitmode(ctx);
5504
        GEN_LOAD_FREG_FTN(DT0, fs);
5505
        gen_op_float_cvtl_d();
5506
        GEN_STORE_FTN_FREG(fd, DT2);
5507
        opn = "cvt.l.d";
5508
        break;
5509
    case FOP(32, 20):
5510
        GEN_LOAD_FREG_FTN(WT0, fs);
5511
        gen_op_float_cvts_w();
5512
        GEN_STORE_FTN_FREG(fd, WT2);
5513
        opn = "cvt.s.w";
5514
        break;
5515
    case FOP(33, 20):
5516
        check_cp1_registers(ctx, fd);
5517
        GEN_LOAD_FREG_FTN(WT0, fs);
5518
        gen_op_float_cvtd_w();
5519
        GEN_STORE_FTN_FREG(fd, DT2);
5520
        opn = "cvt.d.w";
5521
        break;
5522
    case FOP(32, 21):
5523
        check_cp1_64bitmode(ctx);
5524
        GEN_LOAD_FREG_FTN(DT0, fs);
5525
        gen_op_float_cvts_l();
5526
        GEN_STORE_FTN_FREG(fd, WT2);
5527
        opn = "cvt.s.l";
5528
        break;
5529
    case FOP(33, 21):
5530
        check_cp1_64bitmode(ctx);
5531
        GEN_LOAD_FREG_FTN(DT0, fs);
5532
        gen_op_float_cvtd_l();
5533
        GEN_STORE_FTN_FREG(fd, DT2);
5534
        opn = "cvt.d.l";
5535
        break;
5536
    case FOP(38, 20):
5537
        check_cp1_64bitmode(ctx);
5538
        GEN_LOAD_FREG_FTN(WT0, fs);
5539
        GEN_LOAD_FREG_FTN(WTH0, fs);
5540
        gen_op_float_cvtps_pw();
5541
        GEN_STORE_FTN_FREG(fd, WT2);
5542
        GEN_STORE_FTN_FREG(fd, WTH2);
5543
        opn = "cvt.ps.pw";
5544
        break;
5545
    case FOP(0, 22):
5546
        check_cp1_64bitmode(ctx);
5547
        GEN_LOAD_FREG_FTN(WT0, fs);
5548
        GEN_LOAD_FREG_FTN(WTH0, fs);
5549
        GEN_LOAD_FREG_FTN(WT1, ft);
5550
        GEN_LOAD_FREG_FTN(WTH1, ft);
5551
        gen_op_float_add_ps();
5552
        GEN_STORE_FTN_FREG(fd, WT2);
5553
        GEN_STORE_FTN_FREG(fd, WTH2);
5554
        opn = "add.ps";
5555
        break;
5556
    case FOP(1, 22):
5557
        check_cp1_64bitmode(ctx);
5558
        GEN_LOAD_FREG_FTN(WT0, fs);
5559
        GEN_LOAD_FREG_FTN(WTH0, fs);
5560
        GEN_LOAD_FREG_FTN(WT1, ft);
5561
        GEN_LOAD_FREG_FTN(WTH1, ft);
5562
        gen_op_float_sub_ps();
5563
        GEN_STORE_FTN_FREG(fd, WT2);
5564
        GEN_STORE_FTN_FREG(fd, WTH2);
5565
        opn = "sub.ps";
5566
        break;
5567
    case FOP(2, 22):
5568
        check_cp1_64bitmode(ctx);
5569
        GEN_LOAD_FREG_FTN(WT0, fs);
5570
        GEN_LOAD_FREG_FTN(WTH0, fs);
5571
        GEN_LOAD_FREG_FTN(WT1, ft);
5572
        GEN_LOAD_FREG_FTN(WTH1, ft);
5573
        gen_op_float_mul_ps();
5574
        GEN_STORE_FTN_FREG(fd, WT2);
5575
        GEN_STORE_FTN_FREG(fd, WTH2);
5576
        opn = "mul.ps";
5577
        break;
5578
    case FOP(5, 22):
5579
        check_cp1_64bitmode(ctx);
5580
        GEN_LOAD_FREG_FTN(WT0, fs);
5581
        GEN_LOAD_FREG_FTN(WTH0, fs);
5582
        gen_op_float_abs_ps();
5583
        GEN_STORE_FTN_FREG(fd, WT2);
5584
        GEN_STORE_FTN_FREG(fd, WTH2);
5585
        opn = "abs.ps";
5586
        break;
5587
    case FOP(6, 22):
5588
        check_cp1_64bitmode(ctx);
5589
        GEN_LOAD_FREG_FTN(WT0, fs);
5590
        GEN_LOAD_FREG_FTN(WTH0, fs);
5591
        gen_op_float_mov_ps();
5592
        GEN_STORE_FTN_FREG(fd, WT2);
5593
        GEN_STORE_FTN_FREG(fd, WTH2);
5594
        opn = "mov.ps";
5595
        break;
5596
    case FOP(7, 22):
5597
        check_cp1_64bitmode(ctx);
5598
        GEN_LOAD_FREG_FTN(WT0, fs);
5599
        GEN_LOAD_FREG_FTN(WTH0, fs);
5600
        gen_op_float_chs_ps();
5601
        GEN_STORE_FTN_FREG(fd, WT2);
5602
        GEN_STORE_FTN_FREG(fd, WTH2);
5603
        opn = "neg.ps";
5604
        break;
5605
    case FOP(17, 22):
5606
        check_cp1_64bitmode(ctx);
5607
        GEN_LOAD_REG_T0(ft);
5608
        GEN_LOAD_FREG_FTN(WT0, fs);
5609
        GEN_LOAD_FREG_FTN(WTH0, fs);
5610
        GEN_LOAD_FREG_FTN(WT2, fd);
5611
        GEN_LOAD_FREG_FTN(WTH2, fd);
5612
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5613
        GEN_STORE_FTN_FREG(fd, WT2);
5614
        GEN_STORE_FTN_FREG(fd, WTH2);
5615
        opn = "movcf.ps";
5616
        break;
5617
    case FOP(18, 22):
5618
        check_cp1_64bitmode(ctx);
5619
        GEN_LOAD_REG_T0(ft);
5620
        GEN_LOAD_FREG_FTN(WT0, fs);
5621
        GEN_LOAD_FREG_FTN(WTH0, fs);
5622
        GEN_LOAD_FREG_FTN(WT2, fd);
5623
        GEN_LOAD_FREG_FTN(WTH2, fd);
5624
        gen_op_float_movz_ps();
5625
        GEN_STORE_FTN_FREG(fd, WT2);
5626
        GEN_STORE_FTN_FREG(fd, WTH2);
5627
        opn = "movz.ps";
5628
        break;
5629
    case FOP(19, 22):
5630
        check_cp1_64bitmode(ctx);
5631
        GEN_LOAD_REG_T0(ft);
5632
        GEN_LOAD_FREG_FTN(WT0, fs);
5633
        GEN_LOAD_FREG_FTN(WTH0, fs);
5634
        GEN_LOAD_FREG_FTN(WT2, fd);
5635
        GEN_LOAD_FREG_FTN(WTH2, fd);
5636
        gen_op_float_movn_ps();
5637
        GEN_STORE_FTN_FREG(fd, WT2);
5638
        GEN_STORE_FTN_FREG(fd, WTH2);
5639
        opn = "movn.ps";
5640
        break;
5641
    case FOP(24, 22):
5642
        check_cp1_64bitmode(ctx);
5643
        GEN_LOAD_FREG_FTN(WT0, ft);
5644
        GEN_LOAD_FREG_FTN(WTH0, ft);
5645
        GEN_LOAD_FREG_FTN(WT1, fs);
5646
        GEN_LOAD_FREG_FTN(WTH1, fs);
5647
        gen_op_float_addr_ps();
5648
        GEN_STORE_FTN_FREG(fd, WT2);
5649
        GEN_STORE_FTN_FREG(fd, WTH2);
5650
        opn = "addr.ps";
5651
        break;
5652
    case FOP(26, 22):
5653
        check_cp1_64bitmode(ctx);
5654
        GEN_LOAD_FREG_FTN(WT0, ft);
5655
        GEN_LOAD_FREG_FTN(WTH0, ft);
5656
        GEN_LOAD_FREG_FTN(WT1, fs);
5657
        GEN_LOAD_FREG_FTN(WTH1, fs);
5658
        gen_op_float_mulr_ps();
5659
        GEN_STORE_FTN_FREG(fd, WT2);
5660
        GEN_STORE_FTN_FREG(fd, WTH2);
5661
        opn = "mulr.ps";
5662
        break;
5663
    case FOP(28, 22):
5664
        check_cp1_64bitmode(ctx);
5665
        GEN_LOAD_FREG_FTN(WT0, fs);
5666
        GEN_LOAD_FREG_FTN(WTH0, fs);
5667
        GEN_LOAD_FREG_FTN(WT2, fd);
5668
        GEN_LOAD_FREG_FTN(WTH2, fd);
5669
        gen_op_float_recip2_ps();
5670
        GEN_STORE_FTN_FREG(fd, WT2);
5671
        GEN_STORE_FTN_FREG(fd, WTH2);
5672
        opn = "recip2.ps";
5673
        break;
5674
    case FOP(29, 22):
5675
        check_cp1_64bitmode(ctx);
5676
        GEN_LOAD_FREG_FTN(WT0, fs);
5677
        GEN_LOAD_FREG_FTN(WTH0, fs);
5678
        gen_op_float_recip1_ps();
5679
        GEN_STORE_FTN_FREG(fd, WT2);
5680
        GEN_STORE_FTN_FREG(fd, WTH2);
5681
        opn = "recip1.ps";
5682
        break;
5683
    case FOP(30, 22):
5684
        check_cp1_64bitmode(ctx);
5685
        GEN_LOAD_FREG_FTN(WT0, fs);
5686
        GEN_LOAD_FREG_FTN(WTH0, fs);
5687
        gen_op_float_rsqrt1_ps();
5688
        GEN_STORE_FTN_FREG(fd, WT2);
5689
        GEN_STORE_FTN_FREG(fd, WTH2);
5690
        opn = "rsqrt1.ps";
5691
        break;
5692
    case FOP(31, 22):
5693
        check_cp1_64bitmode(ctx);
5694
        GEN_LOAD_FREG_FTN(WT0, fs);
5695
        GEN_LOAD_FREG_FTN(WTH0, fs);
5696
        GEN_LOAD_FREG_FTN(WT2, ft);
5697
        GEN_LOAD_FREG_FTN(WTH2, ft);
5698
        gen_op_float_rsqrt2_ps();
5699
        GEN_STORE_FTN_FREG(fd, WT2);
5700
        GEN_STORE_FTN_FREG(fd, WTH2);
5701
        opn = "rsqrt2.ps";
5702
        break;
5703
    case FOP(32, 22):
5704
        check_cp1_64bitmode(ctx);
5705
        GEN_LOAD_FREG_FTN(WTH0, fs);
5706
        gen_op_float_cvts_pu();
5707
        GEN_STORE_FTN_FREG(fd, WT2);
5708
        opn = "cvt.s.pu";
5709
        break;
5710
    case FOP(36, 22):
5711
        check_cp1_64bitmode(ctx);
5712
        GEN_LOAD_FREG_FTN(WT0, fs);
5713
        GEN_LOAD_FREG_FTN(WTH0, fs);
5714
        gen_op_float_cvtpw_ps();
5715
        GEN_STORE_FTN_FREG(fd, WT2);
5716
        GEN_STORE_FTN_FREG(fd, WTH2);
5717
        opn = "cvt.pw.ps";
5718
        break;
5719
    case FOP(40, 22):
5720
        check_cp1_64bitmode(ctx);
5721
        GEN_LOAD_FREG_FTN(WT0, fs);
5722
        gen_op_float_cvts_pl();
5723
        GEN_STORE_FTN_FREG(fd, WT2);
5724
        opn = "cvt.s.pl";
5725
        break;
5726
    case FOP(44, 22):
5727
        check_cp1_64bitmode(ctx);
5728
        GEN_LOAD_FREG_FTN(WT0, fs);
5729
        GEN_LOAD_FREG_FTN(WT1, ft);
5730
        gen_op_float_pll_ps();
5731
        GEN_STORE_FTN_FREG(fd, DT2);
5732
        opn = "pll.ps";
5733
        break;
5734
    case FOP(45, 22):
5735
        check_cp1_64bitmode(ctx);
5736
        GEN_LOAD_FREG_FTN(WT0, fs);
5737
        GEN_LOAD_FREG_FTN(WTH1, ft);
5738
        gen_op_float_plu_ps();
5739
        GEN_STORE_FTN_FREG(fd, DT2);
5740
        opn = "plu.ps";
5741
        break;
5742
    case FOP(46, 22):
5743
        check_cp1_64bitmode(ctx);
5744
        GEN_LOAD_FREG_FTN(WTH0, fs);
5745
        GEN_LOAD_FREG_FTN(WT1, ft);
5746
        gen_op_float_pul_ps();
5747
        GEN_STORE_FTN_FREG(fd, DT2);
5748
        opn = "pul.ps";
5749
        break;
5750
    case FOP(47, 22):
5751
        check_cp1_64bitmode(ctx);
5752
        GEN_LOAD_FREG_FTN(WTH0, fs);
5753
        GEN_LOAD_FREG_FTN(WTH1, ft);
5754
        gen_op_float_puu_ps();
5755
        GEN_STORE_FTN_FREG(fd, DT2);
5756
        opn = "puu.ps";
5757
        break;
5758
    case FOP(48, 22):
5759
    case FOP(49, 22):
5760
    case FOP(50, 22):
5761
    case FOP(51, 22):
5762
    case FOP(52, 22):
5763
    case FOP(53, 22):
5764
    case FOP(54, 22):
5765
    case FOP(55, 22):
5766
    case FOP(56, 22):
5767
    case FOP(57, 22):
5768
    case FOP(58, 22):
5769
    case FOP(59, 22):
5770
    case FOP(60, 22):
5771
    case FOP(61, 22):
5772
    case FOP(62, 22):
5773
    case FOP(63, 22):
5774
        check_cp1_64bitmode(ctx);
5775
        GEN_LOAD_FREG_FTN(WT0, fs);
5776
        GEN_LOAD_FREG_FTN(WTH0, fs);
5777
        GEN_LOAD_FREG_FTN(WT1, ft);
5778
        GEN_LOAD_FREG_FTN(WTH1, ft);
5779
        if (ctx->opcode & (1 << 6)) {
5780
            gen_cmpabs_ps(func-48, cc);
5781
            opn = condnames_abs[func-48];
5782
        } else {
5783
            gen_cmp_ps(func-48, cc);
5784
            opn = condnames[func-48];
5785
        }
5786
        break;
5787
    default:
5788
        MIPS_INVAL(opn);
5789
        generate_exception (ctx, EXCP_RI);
5790
        return;
5791
    }
5792
    switch (optype) {
5793
    case BINOP:
5794
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5795
        break;
5796
    case CMPOP:
5797
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5798
        break;
5799
    default:
5800
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5801
        break;
5802
    }
5803
}
5804

    
5805
/* Coprocessor 3 (FPU) */
5806
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5807
                           int fd, int fs, int base, int index)
5808
{
5809
    const char *opn = "extended float load/store";
5810
    int store = 0;
5811

    
5812
    if (base == 0) {
5813
        if (index == 0)
5814
            gen_op_reset_T0();
5815
        else
5816
            GEN_LOAD_REG_T0(index);
5817
    } else if (index == 0) {
5818
        GEN_LOAD_REG_T0(base);
5819
    } else {
5820
        GEN_LOAD_REG_T0(base);
5821
        GEN_LOAD_REG_T1(index);
5822
        gen_op_addr_add();
5823
    }
5824
    /* Don't do NOP if destination is zero: we must perform the actual
5825
       memory access. */
5826
    switch (opc) {
5827
    case OPC_LWXC1:
5828
        check_cop1x(ctx);
5829
        op_ldst(lwc1);
5830
        GEN_STORE_FTN_FREG(fd, WT0);
5831
        opn = "lwxc1";
5832
        break;
5833
    case OPC_LDXC1:
5834
        check_cop1x(ctx);
5835
        check_cp1_registers(ctx, fd);
5836
        op_ldst(ldc1);
5837
        GEN_STORE_FTN_FREG(fd, DT0);
5838
        opn = "ldxc1";
5839
        break;
5840
    case OPC_LUXC1:
5841
        check_cp1_64bitmode(ctx);
5842
        op_ldst(luxc1);
5843
        GEN_STORE_FTN_FREG(fd, DT0);
5844
        opn = "luxc1";
5845
        break;
5846
    case OPC_SWXC1:
5847
        check_cop1x(ctx);
5848
        GEN_LOAD_FREG_FTN(WT0, fs);
5849
        op_ldst(swc1);
5850
        opn = "swxc1";
5851
        store = 1;
5852
        break;
5853
    case OPC_SDXC1:
5854
        check_cop1x(ctx);
5855
        check_cp1_registers(ctx, fs);
5856
        GEN_LOAD_FREG_FTN(DT0, fs);
5857
        op_ldst(sdc1);
5858
        opn = "sdxc1";
5859
        store = 1;
5860
        break;
5861
    case OPC_SUXC1:
5862
        check_cp1_64bitmode(ctx);
5863
        GEN_LOAD_FREG_FTN(DT0, fs);
5864
        op_ldst(suxc1);
5865
        opn = "suxc1";
5866
        store = 1;
5867
        break;
5868
    default:
5869
        MIPS_INVAL(opn);
5870
        generate_exception(ctx, EXCP_RI);
5871
        return;
5872
    }
5873
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5874
               regnames[index], regnames[base]);
5875
}
5876

    
5877
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5878
                            int fd, int fr, int fs, int ft)
5879
{
5880
    const char *opn = "flt3_arith";
5881

    
5882
    switch (opc) {
5883
    case OPC_ALNV_PS:
5884
        check_cp1_64bitmode(ctx);
5885
        GEN_LOAD_REG_T0(fr);
5886
        GEN_LOAD_FREG_FTN(DT0, fs);
5887
        GEN_LOAD_FREG_FTN(DT1, ft);
5888
        gen_op_float_alnv_ps();
5889
        GEN_STORE_FTN_FREG(fd, DT2);
5890
        opn = "alnv.ps";
5891
        break;
5892
    case OPC_MADD_S:
5893
        check_cop1x(ctx);
5894
        GEN_LOAD_FREG_FTN(WT0, fs);
5895
        GEN_LOAD_FREG_FTN(WT1, ft);
5896
        GEN_LOAD_FREG_FTN(WT2, fr);
5897
        gen_op_float_muladd_s();
5898
        GEN_STORE_FTN_FREG(fd, WT2);
5899
        opn = "madd.s";
5900
        break;
5901
    case OPC_MADD_D:
5902
        check_cop1x(ctx);
5903
        check_cp1_registers(ctx, fd | fs | ft | fr);
5904
        GEN_LOAD_FREG_FTN(DT0, fs);
5905
        GEN_LOAD_FREG_FTN(DT1, ft);
5906
        GEN_LOAD_FREG_FTN(DT2, fr);
5907
        gen_op_float_muladd_d();
5908
        GEN_STORE_FTN_FREG(fd, DT2);
5909
        opn = "madd.d";
5910
        break;
5911
    case OPC_MADD_PS:
5912
        check_cp1_64bitmode(ctx);
5913
        GEN_LOAD_FREG_FTN(WT0, fs);
5914
        GEN_LOAD_FREG_FTN(WTH0, fs);
5915
        GEN_LOAD_FREG_FTN(WT1, ft);
5916
        GEN_LOAD_FREG_FTN(WTH1, ft);
5917
        GEN_LOAD_FREG_FTN(WT2, fr);
5918
        GEN_LOAD_FREG_FTN(WTH2, fr);
5919
        gen_op_float_muladd_ps();
5920
        GEN_STORE_FTN_FREG(fd, WT2);
5921
        GEN_STORE_FTN_FREG(fd, WTH2);
5922
        opn = "madd.ps";
5923
        break;
5924
    case OPC_MSUB_S:
5925
        check_cop1x(ctx);
5926
        GEN_LOAD_FREG_FTN(WT0, fs);
5927
        GEN_LOAD_FREG_FTN(WT1, ft);
5928
        GEN_LOAD_FREG_FTN(WT2, fr);
5929
        gen_op_float_mulsub_s();
5930
        GEN_STORE_FTN_FREG(fd, WT2);
5931
        opn = "msub.s";
5932
        break;
5933
    case OPC_MSUB_D:
5934
        check_cop1x(ctx);
5935
        check_cp1_registers(ctx, fd | fs | ft | fr);
5936
        GEN_LOAD_FREG_FTN(DT0, fs);
5937
        GEN_LOAD_FREG_FTN(DT1, ft);
5938
        GEN_LOAD_FREG_FTN(DT2, fr);
5939
        gen_op_float_mulsub_d();
5940
        GEN_STORE_FTN_FREG(fd, DT2);
5941
        opn = "msub.d";
5942
        break;
5943
    case OPC_MSUB_PS:
5944
        check_cp1_64bitmode(ctx);
5945
        GEN_LOAD_FREG_FTN(WT0, fs);
5946
        GEN_LOAD_FREG_FTN(WTH0, fs);
5947
        GEN_LOAD_FREG_FTN(WT1, ft);
5948
        GEN_LOAD_FREG_FTN(WTH1, ft);
5949
        GEN_LOAD_FREG_FTN(WT2, fr);
5950
        GEN_LOAD_FREG_FTN(WTH2, fr);
5951
        gen_op_float_mulsub_ps();
5952
        GEN_STORE_FTN_FREG(fd, WT2);
5953
        GEN_STORE_FTN_FREG(fd, WTH2);
5954
        opn = "msub.ps";
5955
        break;
5956
    case OPC_NMADD_S:
5957
        check_cop1x(ctx);
5958
        GEN_LOAD_FREG_FTN(WT0, fs);
5959
        GEN_LOAD_FREG_FTN(WT1, ft);
5960
        GEN_LOAD_FREG_FTN(WT2, fr);
5961
        gen_op_float_nmuladd_s();
5962
        GEN_STORE_FTN_FREG(fd, WT2);
5963
        opn = "nmadd.s";
5964
        break;
5965
    case OPC_NMADD_D:
5966
        check_cop1x(ctx);
5967
        check_cp1_registers(ctx, fd | fs | ft | fr);
5968
        GEN_LOAD_FREG_FTN(DT0, fs);
5969
        GEN_LOAD_FREG_FTN(DT1, ft);
5970
        GEN_LOAD_FREG_FTN(DT2, fr);
5971
        gen_op_float_nmuladd_d();
5972
        GEN_STORE_FTN_FREG(fd, DT2);
5973
        opn = "nmadd.d";
5974
        break;
5975
    case OPC_NMADD_PS:
5976
        check_cp1_64bitmode(ctx);
5977
        GEN_LOAD_FREG_FTN(WT0, fs);
5978
        GEN_LOAD_FREG_FTN(WTH0, fs);
5979
        GEN_LOAD_FREG_FTN(WT1, ft);
5980
        GEN_LOAD_FREG_FTN(WTH1, ft);
5981
        GEN_LOAD_FREG_FTN(WT2, fr);
5982
        GEN_LOAD_FREG_FTN(WTH2, fr);
5983
        gen_op_float_nmuladd_ps();
5984
        GEN_STORE_FTN_FREG(fd, WT2);
5985
        GEN_STORE_FTN_FREG(fd, WTH2);
5986
        opn = "nmadd.ps";
5987
        break;
5988
    case OPC_NMSUB_S:
5989
        check_cop1x(ctx);
5990
        GEN_LOAD_FREG_FTN(WT0, fs);
5991
        GEN_LOAD_FREG_FTN(WT1, ft);
5992
        GEN_LOAD_FREG_FTN(WT2, fr);
5993
        gen_op_float_nmulsub_s();
5994
        GEN_STORE_FTN_FREG(fd, WT2);
5995
        opn = "nmsub.s";
5996
        break;
5997
    case OPC_NMSUB_D:
5998
        check_cop1x(ctx);
5999
        check_cp1_registers(ctx, fd | fs | ft | fr);
6000
        GEN_LOAD_FREG_FTN(DT0, fs);
6001
        GEN_LOAD_FREG_FTN(DT1, ft);
6002
        GEN_LOAD_FREG_FTN(DT2, fr);
6003
        gen_op_float_nmulsub_d();
6004
        GEN_STORE_FTN_FREG(fd, DT2);
6005
        opn = "nmsub.d";
6006
        break;
6007
    case OPC_NMSUB_PS:
6008
        check_cp1_64bitmode(ctx);
6009
        GEN_LOAD_FREG_FTN(WT0, fs);
6010
        GEN_LOAD_FREG_FTN(WTH0, fs);
6011
        GEN_LOAD_FREG_FTN(WT1, ft);
6012
        GEN_LOAD_FREG_FTN(WTH1, ft);
6013
        GEN_LOAD_FREG_FTN(WT2, fr);
6014
        GEN_LOAD_FREG_FTN(WTH2, fr);
6015
        gen_op_float_nmulsub_ps();
6016
        GEN_STORE_FTN_FREG(fd, WT2);
6017
        GEN_STORE_FTN_FREG(fd, WTH2);
6018
        opn = "nmsub.ps";
6019
        break;
6020
    default:
6021
        MIPS_INVAL(opn);
6022
        generate_exception (ctx, EXCP_RI);
6023
        return;
6024
    }
6025
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6026
               fregnames[fs], fregnames[ft]);
6027
}
6028

    
6029
/* ISA extensions (ASEs) */
6030
/* MIPS16 extension to MIPS32 */
6031
/* SmartMIPS extension to MIPS32 */
6032

    
6033
#if defined(TARGET_MIPS64)
6034

    
6035
/* MDMX extension to MIPS64 */
6036

    
6037
#endif
6038

    
6039
static void decode_opc (CPUState *env, DisasContext *ctx)
6040
{
6041
    int32_t offset;
6042
    int rs, rt, rd, sa;
6043
    uint32_t op, op1, op2;
6044
    int16_t imm;
6045

    
6046
    /* make sure instructions are on a word boundary */
6047
    if (ctx->pc & 0x3) {
6048
        env->CP0_BadVAddr = ctx->pc;
6049
        generate_exception(ctx, EXCP_AdEL);
6050
        return;
6051
    }
6052

    
6053
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6054
        int l1;
6055
        /* Handle blikely not taken case */
6056
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6057
        l1 = gen_new_label();
6058
        gen_op_jnz_T2(l1);
6059
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6060
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6061
        gen_set_label(l1);
6062
    }
6063
    op = MASK_OP_MAJOR(ctx->opcode);
6064
    rs = (ctx->opcode >> 21) & 0x1f;
6065
    rt = (ctx->opcode >> 16) & 0x1f;
6066
    rd = (ctx->opcode >> 11) & 0x1f;
6067
    sa = (ctx->opcode >> 6) & 0x1f;
6068
    imm = (int16_t)ctx->opcode;
6069
    switch (op) {
6070
    case OPC_SPECIAL:
6071
        op1 = MASK_SPECIAL(ctx->opcode);
6072
        switch (op1) {
6073
        case OPC_SLL:          /* Arithmetic with immediate */
6074
        case OPC_SRL ... OPC_SRA:
6075
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6076
            break;
6077
        case OPC_MOVZ ... OPC_MOVN:
6078
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6079
        case OPC_SLLV:         /* Arithmetic */
6080
        case OPC_SRLV ... OPC_SRAV:
6081
        case OPC_ADD ... OPC_NOR:
6082
        case OPC_SLT ... OPC_SLTU:
6083
            gen_arith(env, ctx, op1, rd, rs, rt);
6084
            break;
6085
        case OPC_MULT ... OPC_DIVU:
6086
            if (sa) {
6087
                check_insn(env, ctx, INSN_VR54XX);
6088
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6089
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6090
            } else
6091
                gen_muldiv(ctx, op1, rs, rt);
6092
            break;
6093
        case OPC_JR ... OPC_JALR:
6094
            gen_compute_branch(ctx, op1, rs, rd, sa);
6095
            return;
6096
        case OPC_TGE ... OPC_TEQ: /* Traps */
6097
        case OPC_TNE:
6098
            gen_trap(ctx, op1, rs, rt, -1);
6099
            break;
6100
        case OPC_MFHI:          /* Move from HI/LO */
6101
        case OPC_MFLO:
6102
            gen_HILO(ctx, op1, rd);
6103
            break;
6104
        case OPC_MTHI:
6105
        case OPC_MTLO:          /* Move to HI/LO */
6106
            gen_HILO(ctx, op1, rs);
6107
            break;
6108
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6109
#ifdef MIPS_STRICT_STANDARD
6110
            MIPS_INVAL("PMON / selsl");
6111
            generate_exception(ctx, EXCP_RI);
6112
#else
6113
            gen_op_pmon(sa);
6114
#endif
6115
            break;
6116
        case OPC_SYSCALL:
6117
            generate_exception(ctx, EXCP_SYSCALL);
6118
            break;
6119
        case OPC_BREAK:
6120
            generate_exception(ctx, EXCP_BREAK);
6121
            break;
6122
        case OPC_SPIM:
6123
#ifdef MIPS_STRICT_STANDARD
6124
            MIPS_INVAL("SPIM");
6125
            generate_exception(ctx, EXCP_RI);
6126
#else
6127
           /* Implemented as RI exception for now. */
6128
            MIPS_INVAL("spim (unofficial)");
6129
            generate_exception(ctx, EXCP_RI);
6130
#endif
6131
            break;
6132
        case OPC_SYNC:
6133
            /* Treat as NOP. */
6134
            break;
6135

    
6136
        case OPC_MOVCI:
6137
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6138
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6139
                save_cpu_state(ctx, 1);
6140
                check_cp1_enabled(ctx);
6141
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6142
                          (ctx->opcode >> 16) & 1);
6143
            } else {
6144
                generate_exception_err(ctx, EXCP_CpU, 1);
6145
            }
6146
            break;
6147

    
6148
#if defined(TARGET_MIPS64)
6149
       /* MIPS64 specific opcodes */
6150
        case OPC_DSLL:
6151
        case OPC_DSRL ... OPC_DSRA:
6152
        case OPC_DSLL32:
6153
        case OPC_DSRL32 ... OPC_DSRA32:
6154
            check_insn(env, ctx, ISA_MIPS3);
6155
            check_mips_64(ctx);
6156
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6157
            break;
6158
        case OPC_DSLLV:
6159
        case OPC_DSRLV ... OPC_DSRAV:
6160
        case OPC_DADD ... OPC_DSUBU:
6161
            check_insn(env, ctx, ISA_MIPS3);
6162
            check_mips_64(ctx);
6163
            gen_arith(env, ctx, op1, rd, rs, rt);
6164
            break;
6165
        case OPC_DMULT ... OPC_DDIVU:
6166
            check_insn(env, ctx, ISA_MIPS3);
6167
            check_mips_64(ctx);
6168
            gen_muldiv(ctx, op1, rs, rt);
6169
            break;
6170
#endif
6171
        default:            /* Invalid */
6172
            MIPS_INVAL("special");
6173
            generate_exception(ctx, EXCP_RI);
6174
            break;
6175
        }
6176
        break;
6177
    case OPC_SPECIAL2:
6178
        op1 = MASK_SPECIAL2(ctx->opcode);
6179
        switch (op1) {
6180
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6181
        case OPC_MSUB ... OPC_MSUBU:
6182
            check_insn(env, ctx, ISA_MIPS32);
6183
            gen_muldiv(ctx, op1, rs, rt);
6184
            break;
6185
        case OPC_MUL:
6186
            gen_arith(env, ctx, op1, rd, rs, rt);
6187
            break;
6188
        case OPC_CLZ ... OPC_CLO:
6189
            check_insn(env, ctx, ISA_MIPS32);
6190
            gen_cl(ctx, op1, rd, rs);
6191
            break;
6192
        case OPC_SDBBP:
6193
            /* XXX: not clear which exception should be raised
6194
             *      when in debug mode...
6195
             */
6196
            check_insn(env, ctx, ISA_MIPS32);
6197
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6198
                generate_exception(ctx, EXCP_DBp);
6199
            } else {
6200
                generate_exception(ctx, EXCP_DBp);
6201
            }
6202
            /* Treat as NOP. */
6203
            break;
6204
#if defined(TARGET_MIPS64)
6205
        case OPC_DCLZ ... OPC_DCLO:
6206
            check_insn(env, ctx, ISA_MIPS64);
6207
            check_mips_64(ctx);
6208
            gen_cl(ctx, op1, rd, rs);
6209
            break;
6210
#endif
6211
        default:            /* Invalid */
6212
            MIPS_INVAL("special2");
6213
            generate_exception(ctx, EXCP_RI);
6214
            break;
6215
        }
6216
        break;
6217
    case OPC_SPECIAL3:
6218
         op1 = MASK_SPECIAL3(ctx->opcode);
6219
         switch (op1) {
6220
         case OPC_EXT:
6221
         case OPC_INS:
6222
             check_insn(env, ctx, ISA_MIPS32R2);
6223
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6224
             break;
6225
         case OPC_BSHFL:
6226
             check_insn(env, ctx, ISA_MIPS32R2);
6227
             op2 = MASK_BSHFL(ctx->opcode);
6228
             switch (op2) {
6229
             case OPC_WSBH:
6230
                 GEN_LOAD_REG_T1(rt);
6231
                 gen_op_wsbh();
6232
                 break;
6233
             case OPC_SEB:
6234
                 GEN_LOAD_REG_T1(rt);
6235
                 gen_op_seb();
6236
                 break;
6237
             case OPC_SEH:
6238
                 GEN_LOAD_REG_T1(rt);
6239
                 gen_op_seh();
6240
                 break;
6241
             default:            /* Invalid */
6242
                 MIPS_INVAL("bshfl");
6243
                 generate_exception(ctx, EXCP_RI);
6244
                 break;
6245
            }
6246
            GEN_STORE_T0_REG(rd);
6247
            break;
6248
        case OPC_RDHWR:
6249
            check_insn(env, ctx, ISA_MIPS32R2);
6250
            switch (rd) {
6251
            case 0:
6252
                save_cpu_state(ctx, 1);
6253
                gen_op_rdhwr_cpunum();
6254
                break;
6255
            case 1:
6256
                save_cpu_state(ctx, 1);
6257
                gen_op_rdhwr_synci_step();
6258
                break;
6259
            case 2:
6260
                save_cpu_state(ctx, 1);
6261
                gen_op_rdhwr_cc();
6262
                break;
6263
            case 3:
6264
                save_cpu_state(ctx, 1);
6265
                gen_op_rdhwr_ccres();
6266
                break;
6267
            case 29:
6268
#if defined (CONFIG_USER_ONLY)
6269
                gen_op_tls_value();
6270
                break;
6271
#endif
6272
            default:            /* Invalid */
6273
                MIPS_INVAL("rdhwr");
6274
                generate_exception(ctx, EXCP_RI);
6275
                break;
6276
            }
6277
            GEN_STORE_T0_REG(rt);
6278
            break;
6279
        case OPC_FORK:
6280
            check_insn(env, ctx, ASE_MT);
6281
            GEN_LOAD_REG_T0(rt);
6282
            GEN_LOAD_REG_T1(rs);
6283
            gen_op_fork();
6284
            break;
6285
        case OPC_YIELD:
6286
            check_insn(env, ctx, ASE_MT);
6287
            GEN_LOAD_REG_T0(rs);
6288
            gen_op_yield();
6289
            GEN_STORE_T0_REG(rd);
6290
            break;
6291
#if defined(TARGET_MIPS64)
6292
        case OPC_DEXTM ... OPC_DEXT:
6293
        case OPC_DINSM ... OPC_DINS:
6294
            check_insn(env, ctx, ISA_MIPS64R2);
6295
            check_mips_64(ctx);
6296
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6297
            break;
6298
        case OPC_DBSHFL:
6299
            check_insn(env, ctx, ISA_MIPS64R2);
6300
            check_mips_64(ctx);
6301
            op2 = MASK_DBSHFL(ctx->opcode);
6302
            switch (op2) {
6303
            case OPC_DSBH:
6304
                GEN_LOAD_REG_T1(rt);
6305
                gen_op_dsbh();
6306
                break;
6307
            case OPC_DSHD:
6308
                GEN_LOAD_REG_T1(rt);
6309
                gen_op_dshd();
6310
                break;
6311
            default:            /* Invalid */
6312
                MIPS_INVAL("dbshfl");
6313
                generate_exception(ctx, EXCP_RI);
6314
                break;
6315
            }
6316
            GEN_STORE_T0_REG(rd);
6317
            break;
6318
#endif
6319
        default:            /* Invalid */
6320
            MIPS_INVAL("special3");
6321
            generate_exception(ctx, EXCP_RI);
6322
            break;
6323
        }
6324
        break;
6325
    case OPC_REGIMM:
6326
        op1 = MASK_REGIMM(ctx->opcode);
6327
        switch (op1) {
6328
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6329
        case OPC_BLTZAL ... OPC_BGEZALL:
6330
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6331
            return;
6332
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6333
        case OPC_TNEI:
6334
            gen_trap(ctx, op1, rs, -1, imm);
6335
            break;
6336
        case OPC_SYNCI:
6337
            check_insn(env, ctx, ISA_MIPS32R2);
6338
            /* Treat as NOP. */
6339
            break;
6340
        default:            /* Invalid */
6341
            MIPS_INVAL("regimm");
6342
            generate_exception(ctx, EXCP_RI);
6343
            break;
6344
        }
6345
        break;
6346
    case OPC_CP0:
6347
        check_cp0_enabled(ctx);
6348
        op1 = MASK_CP0(ctx->opcode);
6349
        switch (op1) {
6350
        case OPC_MFC0:
6351
        case OPC_MTC0:
6352
        case OPC_MFTR:
6353
        case OPC_MTTR:
6354
#if defined(TARGET_MIPS64)
6355
        case OPC_DMFC0:
6356
        case OPC_DMTC0:
6357
#endif
6358
            gen_cp0(env, ctx, op1, rt, rd);
6359
            break;
6360
        case OPC_C0_FIRST ... OPC_C0_LAST:
6361
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6362
            break;
6363
        case OPC_MFMC0:
6364
            op2 = MASK_MFMC0(ctx->opcode);
6365
            switch (op2) {
6366
            case OPC_DMT:
6367
                check_insn(env, ctx, ASE_MT);
6368
                gen_op_dmt();
6369
                break;
6370
            case OPC_EMT:
6371
                check_insn(env, ctx, ASE_MT);
6372
                gen_op_emt();
6373
                break;
6374
            case OPC_DVPE:
6375
                check_insn(env, ctx, ASE_MT);
6376
                gen_op_dvpe();
6377
                break;
6378
            case OPC_EVPE:
6379
                check_insn(env, ctx, ASE_MT);
6380
                gen_op_evpe();
6381
                break;
6382
            case OPC_DI:
6383
                check_insn(env, ctx, ISA_MIPS32R2);
6384
                save_cpu_state(ctx, 1);
6385
                gen_op_di();
6386
                /* Stop translation as we may have switched the execution mode */
6387
                ctx->bstate = BS_STOP;
6388
                break;
6389
            case OPC_EI:
6390
                check_insn(env, ctx, ISA_MIPS32R2);
6391
                save_cpu_state(ctx, 1);
6392
                gen_op_ei();
6393
                /* Stop translation as we may have switched the execution mode */
6394
                ctx->bstate = BS_STOP;
6395
                break;
6396
            default:            /* Invalid */
6397
                MIPS_INVAL("mfmc0");
6398
                generate_exception(ctx, EXCP_RI);
6399
                break;
6400
            }
6401
            GEN_STORE_T0_REG(rt);
6402
            break;
6403
        case OPC_RDPGPR:
6404
            check_insn(env, ctx, ISA_MIPS32R2);
6405
            GEN_LOAD_SRSREG_TN(T0, rt);
6406
            GEN_STORE_T0_REG(rd);
6407
            break;
6408
        case OPC_WRPGPR:
6409
            check_insn(env, ctx, ISA_MIPS32R2);
6410
            GEN_LOAD_REG_T0(rt);
6411
            GEN_STORE_TN_SRSREG(rd, T0);
6412
            break;
6413
        default:
6414
            MIPS_INVAL("cp0");
6415
            generate_exception(ctx, EXCP_RI);
6416
            break;
6417
        }
6418
        break;
6419
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6420
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6421
         break;
6422
    case OPC_J ... OPC_JAL: /* Jump */
6423
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6424
         gen_compute_branch(ctx, op, rs, rt, offset);
6425
         return;
6426
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6427
    case OPC_BEQL ... OPC_BGTZL:
6428
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6429
         return;
6430
    case OPC_LB ... OPC_LWR: /* Load and stores */
6431
    case OPC_SB ... OPC_SW:
6432
    case OPC_SWR:
6433
    case OPC_LL:
6434
    case OPC_SC:
6435
         gen_ldst(ctx, op, rt, rs, imm);
6436
         break;
6437
    case OPC_CACHE:
6438
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6439
        /* Treat as NOP. */
6440
        break;
6441
    case OPC_PREF:
6442
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6443
        /* Treat as NOP. */
6444
        break;
6445

    
6446
    /* Floating point (COP1). */
6447
    case OPC_LWC1:
6448
    case OPC_LDC1:
6449
    case OPC_SWC1:
6450
    case OPC_SDC1:
6451
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6452
            save_cpu_state(ctx, 1);
6453
            check_cp1_enabled(ctx);
6454
            gen_flt_ldst(ctx, op, rt, rs, imm);
6455
        } else {
6456
            generate_exception_err(ctx, EXCP_CpU, 1);
6457
        }
6458
        break;
6459

    
6460
    case OPC_CP1:
6461
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6462
            save_cpu_state(ctx, 1);
6463
            check_cp1_enabled(ctx);
6464
            op1 = MASK_CP1(ctx->opcode);
6465
            switch (op1) {
6466
            case OPC_MFHC1:
6467
            case OPC_MTHC1:
6468
                check_insn(env, ctx, ISA_MIPS32R2);
6469
            case OPC_MFC1:
6470
            case OPC_CFC1:
6471
            case OPC_MTC1:
6472
            case OPC_CTC1:
6473
                gen_cp1(ctx, op1, rt, rd);
6474
                break;
6475
#if defined(TARGET_MIPS64)
6476
            case OPC_DMFC1:
6477
            case OPC_DMTC1:
6478
                check_insn(env, ctx, ISA_MIPS3);
6479
                gen_cp1(ctx, op1, rt, rd);
6480
                break;
6481
#endif
6482
            case OPC_BC1ANY2:
6483
            case OPC_BC1ANY4:
6484
                check_cop1x(ctx);
6485
                check_insn(env, ctx, ASE_MIPS3D);
6486
                /* fall through */
6487
            case OPC_BC1:
6488
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6489
                                    (rt >> 2) & 0x7, imm << 2);
6490
                return;
6491
            case OPC_S_FMT:
6492
            case OPC_D_FMT:
6493
            case OPC_W_FMT:
6494
            case OPC_L_FMT:
6495
            case OPC_PS_FMT:
6496
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6497
                           (imm >> 8) & 0x7);
6498
                break;
6499
            default:
6500
                MIPS_INVAL("cp1");
6501
                generate_exception (ctx, EXCP_RI);
6502
                break;
6503
            }
6504
        } else {
6505
            generate_exception_err(ctx, EXCP_CpU, 1);
6506
        }
6507
        break;
6508

    
6509
    /* COP2.  */
6510
    case OPC_LWC2:
6511
    case OPC_LDC2:
6512
    case OPC_SWC2:
6513
    case OPC_SDC2:
6514
    case OPC_CP2:
6515
        /* COP2: Not implemented. */
6516
        generate_exception_err(ctx, EXCP_CpU, 2);
6517
        break;
6518

    
6519
    case OPC_CP3:
6520
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6521
            save_cpu_state(ctx, 1);
6522
            check_cp1_enabled(ctx);
6523
            op1 = MASK_CP3(ctx->opcode);
6524
            switch (op1) {
6525
            case OPC_LWXC1:
6526
            case OPC_LDXC1:
6527
            case OPC_LUXC1:
6528
            case OPC_SWXC1:
6529
            case OPC_SDXC1:
6530
            case OPC_SUXC1:
6531
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6532
                break;
6533
            case OPC_PREFX:
6534
                /* Treat as NOP. */
6535
                break;
6536
            case OPC_ALNV_PS:
6537
            case OPC_MADD_S:
6538
            case OPC_MADD_D:
6539
            case OPC_MADD_PS:
6540
            case OPC_MSUB_S:
6541
            case OPC_MSUB_D:
6542
            case OPC_MSUB_PS:
6543
            case OPC_NMADD_S:
6544
            case OPC_NMADD_D:
6545
            case OPC_NMADD_PS:
6546
            case OPC_NMSUB_S:
6547
            case OPC_NMSUB_D:
6548
            case OPC_NMSUB_PS:
6549
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6550
                break;
6551
            default:
6552
                MIPS_INVAL("cp3");
6553
                generate_exception (ctx, EXCP_RI);
6554
                break;
6555
            }
6556
        } else {
6557
            generate_exception_err(ctx, EXCP_CpU, 1);
6558
        }
6559
        break;
6560

    
6561
#if defined(TARGET_MIPS64)
6562
    /* MIPS64 opcodes */
6563
    case OPC_LWU:
6564
    case OPC_LDL ... OPC_LDR:
6565
    case OPC_SDL ... OPC_SDR:
6566
    case OPC_LLD:
6567
    case OPC_LD:
6568
    case OPC_SCD:
6569
    case OPC_SD:
6570
        check_insn(env, ctx, ISA_MIPS3);
6571
        check_mips_64(ctx);
6572
        gen_ldst(ctx, op, rt, rs, imm);
6573
        break;
6574
    case OPC_DADDI ... OPC_DADDIU:
6575
        check_insn(env, ctx, ISA_MIPS3);
6576
        check_mips_64(ctx);
6577
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6578
        break;
6579
#endif
6580
    case OPC_JALX:
6581
        check_insn(env, ctx, ASE_MIPS16);
6582
        /* MIPS16: Not implemented. */
6583
    case OPC_MDMX:
6584
        check_insn(env, ctx, ASE_MDMX);
6585
        /* MDMX: Not implemented. */
6586
    default:            /* Invalid */
6587
        MIPS_INVAL("major opcode");
6588
        generate_exception(ctx, EXCP_RI);
6589
        break;
6590
    }
6591
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6592
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6593
        /* Branches completion */
6594
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6595
        ctx->bstate = BS_BRANCH;
6596
        save_cpu_state(ctx, 0);
6597
        switch (hflags) {
6598
        case MIPS_HFLAG_B:
6599
            /* unconditional branch */
6600
            MIPS_DEBUG("unconditional branch");
6601
            gen_goto_tb(ctx, 0, ctx->btarget);
6602
            break;
6603
        case MIPS_HFLAG_BL:
6604
            /* blikely taken case */
6605
            MIPS_DEBUG("blikely branch taken");
6606
            gen_goto_tb(ctx, 0, ctx->btarget);
6607
            break;
6608
        case MIPS_HFLAG_BC:
6609
            /* Conditional branch */
6610
            MIPS_DEBUG("conditional branch");
6611
            {
6612
              int l1;
6613
              l1 = gen_new_label();
6614
              gen_op_jnz_T2(l1);
6615
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6616
              gen_set_label(l1);
6617
              gen_goto_tb(ctx, 0, ctx->btarget);
6618
            }
6619
            break;
6620
        case MIPS_HFLAG_BR:
6621
            /* unconditional branch to register */
6622
            MIPS_DEBUG("branch to register");
6623
            gen_op_breg();
6624
            tcg_gen_exit_tb(0);
6625
            break;
6626
        default:
6627
            MIPS_DEBUG("unknown branch");
6628
            break;
6629
        }
6630
    }
6631
}
6632

    
6633
static always_inline int
6634
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6635
                                int search_pc)
6636
{
6637
    DisasContext ctx;
6638
    target_ulong pc_start;
6639
    uint16_t *gen_opc_end;
6640
    int j, lj = -1;
6641

    
6642
    if (search_pc && loglevel)
6643
        fprintf (logfile, "search pc %d\n", search_pc);
6644

    
6645
    pc_start = tb->pc;
6646
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6647
    ctx.pc = pc_start;
6648
    ctx.saved_pc = -1;
6649
    ctx.tb = tb;
6650
    ctx.bstate = BS_NONE;
6651
    /* Restore delay slot state from the tb context.  */
6652
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6653
    restore_cpu_state(env, &ctx);
6654
#if defined(CONFIG_USER_ONLY)
6655
    ctx.mem_idx = MIPS_HFLAG_UM;
6656
#else
6657
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6658
#endif
6659
#ifdef DEBUG_DISAS
6660
    if (loglevel & CPU_LOG_TB_CPU) {
6661
        fprintf(logfile, "------------------------------------------------\n");
6662
        /* FIXME: This may print out stale hflags from env... */
6663
        cpu_dump_state(env, logfile, fprintf, 0);
6664
    }
6665
#endif
6666
#ifdef MIPS_DEBUG_DISAS
6667
    if (loglevel & CPU_LOG_TB_IN_ASM)
6668
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6669
                tb, ctx.mem_idx, ctx.hflags);
6670
#endif
6671
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6672
        if (env->nb_breakpoints > 0) {
6673
            for(j = 0; j < env->nb_breakpoints; j++) {
6674
                if (env->breakpoints[j] == ctx.pc) {
6675
                    save_cpu_state(&ctx, 1);
6676
                    ctx.bstate = BS_BRANCH;
6677
                    gen_op_debug();
6678
                    /* Include the breakpoint location or the tb won't
6679
                     * be flushed when it must be.  */
6680
                    ctx.pc += 4;
6681
                    goto done_generating;
6682
                }
6683
            }
6684
        }
6685

    
6686
        if (search_pc) {
6687
            j = gen_opc_ptr - gen_opc_buf;
6688
            if (lj < j) {
6689
                lj++;
6690
                while (lj < j)
6691
                    gen_opc_instr_start[lj++] = 0;
6692
            }
6693
            gen_opc_pc[lj] = ctx.pc;
6694
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6695
            gen_opc_instr_start[lj] = 1;
6696
        }
6697
        ctx.opcode = ldl_code(ctx.pc);
6698
        decode_opc(env, &ctx);
6699
        ctx.pc += 4;
6700

    
6701
        if (env->singlestep_enabled)
6702
            break;
6703

    
6704
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6705
            break;
6706

    
6707
#if defined (MIPS_SINGLE_STEP)
6708
        break;
6709
#endif
6710
    }
6711
    if (env->singlestep_enabled) {
6712
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6713
        gen_op_debug();
6714
    } else {
6715
        switch (ctx.bstate) {
6716
        case BS_STOP:
6717
            gen_op_interrupt_restart();
6718
            gen_goto_tb(&ctx, 0, ctx.pc);
6719
            break;
6720
        case BS_NONE:
6721
            save_cpu_state(&ctx, 0);
6722
            gen_goto_tb(&ctx, 0, ctx.pc);
6723
            break;
6724
        case BS_EXCP:
6725
            gen_op_interrupt_restart();
6726
            tcg_gen_exit_tb(0);
6727
            break;
6728
        case BS_BRANCH:
6729
        default:
6730
            break;
6731
        }
6732
    }
6733
done_generating:
6734
    ctx.last_T0_store = NULL;
6735
    *gen_opc_ptr = INDEX_op_end;
6736
    if (search_pc) {
6737
        j = gen_opc_ptr - gen_opc_buf;
6738
        lj++;
6739
        while (lj <= j)
6740
            gen_opc_instr_start[lj++] = 0;
6741
    } else {
6742
        tb->size = ctx.pc - pc_start;
6743
    }
6744
#ifdef DEBUG_DISAS
6745
#if defined MIPS_DEBUG_DISAS
6746
    if (loglevel & CPU_LOG_TB_IN_ASM)
6747
        fprintf(logfile, "\n");
6748
#endif
6749
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6750
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6751
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6752
        fprintf(logfile, "\n");
6753
    }
6754
    if (loglevel & CPU_LOG_TB_CPU) {
6755
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6756
    }
6757
#endif
6758

    
6759
    return 0;
6760
}
6761

    
6762
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6763
{
6764
    return gen_intermediate_code_internal(env, tb, 0);
6765
}
6766

    
6767
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6768
{
6769
    return gen_intermediate_code_internal(env, tb, 1);
6770
}
6771

    
6772
void fpu_dump_state(CPUState *env, FILE *f,
6773
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6774
                    int flags)
6775
{
6776
    int i;
6777
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6778

    
6779
#define printfpr(fp)                                                        \
6780
    do {                                                                    \
6781
        if (is_fpu64)                                                       \
6782
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6783
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6784
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6785
        else {                                                              \
6786
            fpr_t tmp;                                                      \
6787
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6788
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6789
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6790
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6791
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6792
        }                                                                   \
6793
    } while(0)
6794

    
6795

    
6796
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6797
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6798
                get_float_exception_flags(&env->fpu->fp_status));
6799
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6800
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6801
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6802
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6803
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6804
        printfpr(&env->fpu->fpr[i]);
6805
    }
6806

    
6807
#undef printfpr
6808
}
6809

    
6810
void dump_fpu (CPUState *env)
6811
{
6812
    if (loglevel) {
6813
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6814
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6815
       fpu_dump_state(env, logfile, fprintf, 0);
6816
    }
6817
}
6818

    
6819
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6820
/* Debug help: The architecture requires 32bit code to maintain proper
6821
   sign-extened values on 64bit machines.  */
6822

    
6823
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6824

    
6825
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6826
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6827
                     int flags)
6828
{
6829
    int i;
6830

    
6831
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6832
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6833
    if (!SIGN_EXT_P(env->HI[0][env->current_tc]))
6834
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[0][env->current_tc]);
6835
    if (!SIGN_EXT_P(env->LO[0][env->current_tc]))
6836
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[0][env->current_tc]);
6837
    if (!SIGN_EXT_P(env->btarget))
6838
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6839

    
6840
    for (i = 0; i < 32; i++) {
6841
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6842
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6843
    }
6844

    
6845
    if (!SIGN_EXT_P(env->CP0_EPC))
6846
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6847
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6848
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6849
}
6850
#endif
6851

    
6852
void cpu_dump_state (CPUState *env, FILE *f,
6853
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6854
                     int flags)
6855
{
6856
    int i;
6857

    
6858
    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",
6859
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6860
    for (i = 0; i < 32; i++) {
6861
        if ((i & 3) == 0)
6862
            cpu_fprintf(f, "GPR%02d:", i);
6863
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6864
        if ((i & 3) == 3)
6865
            cpu_fprintf(f, "\n");
6866
    }
6867

    
6868
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6869
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6870
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6871
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6872
    if (env->hflags & MIPS_HFLAG_FPU)
6873
        fpu_dump_state(env, f, cpu_fprintf, flags);
6874
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6875
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6876
#endif
6877
}
6878

    
6879
#include "translate_init.c"
6880

    
6881
CPUMIPSState *cpu_mips_init (const char *cpu_model)
6882
{
6883
    CPUMIPSState *env;
6884
    const mips_def_t *def;
6885

    
6886
    def = cpu_mips_find_by_name(cpu_model);
6887
    if (!def)
6888
        return NULL;
6889
    env = qemu_mallocz(sizeof(CPUMIPSState));
6890
    if (!env)
6891
        return NULL;
6892
    env->cpu_model = def;
6893

    
6894
    cpu_exec_init(env);
6895
    env->cpu_model_str = cpu_model;
6896
    cpu_reset(env);
6897
    return env;
6898
}
6899

    
6900
void cpu_reset (CPUMIPSState *env)
6901
{
6902
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6903

    
6904
    tlb_flush(env, 1);
6905

    
6906
    /* Minimal init */
6907
#if !defined(CONFIG_USER_ONLY)
6908
    if (env->hflags & MIPS_HFLAG_BMASK) {
6909
        /* If the exception was raised from a delay slot,
6910
         * come back to the jump.  */
6911
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6912
    } else {
6913
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6914
    }
6915
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6916
    env->CP0_Wired = 0;
6917
    /* SMP not implemented */
6918
    env->CP0_EBase = 0x80000000;
6919
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6920
    /* vectored interrupts not implemented, timer on int 7,
6921
       no performance counters. */
6922
    env->CP0_IntCtl = 0xe0000000;
6923
    {
6924
        int i;
6925

    
6926
        for (i = 0; i < 7; i++) {
6927
            env->CP0_WatchLo[i] = 0;
6928
            env->CP0_WatchHi[i] = 0x80000000;
6929
        }
6930
        env->CP0_WatchLo[7] = 0;
6931
        env->CP0_WatchHi[7] = 0;
6932
    }
6933
    /* Count register increments in debug mode, EJTAG version 1 */
6934
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6935
#endif
6936
    env->exception_index = EXCP_NONE;
6937
#if defined(CONFIG_USER_ONLY)
6938
    env->hflags = MIPS_HFLAG_UM;
6939
    env->user_mode_only = 1;
6940
#else
6941
    env->hflags = MIPS_HFLAG_CP0;
6942
#endif
6943
    cpu_mips_register(env, env->cpu_model);
6944
}