Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 540635ba

History | View | Annotate | Download (185.4 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

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

    
37
#ifdef USE_DIRECT_JUMP
38
#define TBPARAM(x)
39
#else
40
#define TBPARAM(x) (long)(x)
41
#endif
42

    
43
enum {
44
#define DEF(s, n, copy_size) INDEX_op_ ## s,
45
#include "opc.h"
46
#undef DEF
47
    NB_OPS,
48
};
49

    
50
static uint16_t *gen_opc_ptr;
51
static uint32_t *gen_opparam_ptr;
52

    
53
#include "gen-op.h"
54

    
55
/* MIPS major opcodes */
56
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
57

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

    
133
/* MIPS special opcodes */
134
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
135

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

    
201
    /* Special */
202
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
203
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
205
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
206
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
207

    
208
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215
};
216

    
217
/* REGIMM (rt field) opcodes */
218
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219

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

    
238
/* Special2 opcodes */
239
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
240

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

    
257
/* Special3 opcodes */
258
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
259

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

    
276
/* BSHFL opcodes */
277
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
278

    
279
enum {
280
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
281
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
282
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
283
};
284

    
285
/* DBSHFL opcodes */
286
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
287

    
288
enum {
289
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
290
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
291
};
292

    
293
/* Coprocessor 0 (rs field) */
294
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
295

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

    
311
/* MFMC0 opcodes */
312
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
313

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

    
323
/* Coprocessor 0 (with rs == C0) */
324
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
325

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

    
337
/* Coprocessor 1 (rs field) */
338
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
339

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

    
361
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
362
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
363

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

    
371
enum {
372
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
373
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
374
};
375

    
376
enum {
377
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
378
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
379
};
380

    
381
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
382

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

    
395
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
396

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

    
420

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

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

    
444
/* General purpose registers moves */
445
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
446
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
447
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
448

    
449
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
450
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
451

    
452
/* Moves to/from shadow registers */
453
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
454
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
455

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

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

    
478
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
479
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
480

    
481
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
482
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
485
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
486

    
487
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
488
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
489

    
490
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
491
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
492

    
493
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
494
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
495

    
496
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
497
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
498

    
499
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
500
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
501

    
502
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
503
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
504

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

    
529
FOP_CONDS(, d)
530
FOP_CONDS(abs, d)
531
FOP_CONDS(, s)
532
FOP_CONDS(abs, s)
533
FOP_CONDS(, ps)
534
FOP_CONDS(abs, ps)
535

    
536
typedef struct DisasContext {
537
    struct TranslationBlock *tb;
538
    target_ulong pc, saved_pc;
539
    uint32_t opcode;
540
    uint32_t fp_status;
541
    /* Routine used to access memory */
542
    int mem_idx;
543
    uint32_t hflags, saved_hflags;
544
    int bstate;
545
    target_ulong btarget;
546
} DisasContext;
547

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

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

    
569
#define MIPS_INVAL(op)                                                        \
570
do {                                                                          \
571
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
572
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
573
} while (0)
574

    
575
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
576
do {                                                                          \
577
    if (Rn == 0) {                                                            \
578
        glue(gen_op_reset_, Tn)();                                            \
579
    } else {                                                                  \
580
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
581
    }                                                                         \
582
} while (0)
583

    
584
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
585
do {                                                                          \
586
    if (Rn == 0) {                                                            \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
590
    }                                                                         \
591
} while (0)
592

    
593
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
594
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
595
do {                                                                          \
596
    if (Imm == 0) {                                                           \
597
        glue(gen_op_reset_, Tn)();                                            \
598
    } else if ((int32_t)Imm == Imm) {                                         \
599
        glue(gen_op_set_, Tn)(Imm);                                           \
600
    } else {                                                                  \
601
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
602
    }                                                                         \
603
} while (0)
604
#else
605
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
606
do {                                                                          \
607
    if (Imm == 0) {                                                           \
608
        glue(gen_op_reset_, Tn)();                                            \
609
    } else {                                                                  \
610
        glue(gen_op_set_, Tn)(Imm);                                           \
611
    }                                                                         \
612
} while (0)
613
#endif
614

    
615
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
616
do {                                                                          \
617
    if (Rn != 0) {                                                            \
618
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
619
    }                                                                         \
620
} while (0)
621

    
622
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
623
do {                                                                          \
624
    if (Rn != 0) {                                                            \
625
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
626
    }                                                                         \
627
} while (0)
628

    
629
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
630
do {                                                                          \
631
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
632
} while (0)
633

    
634
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
635
do {                                                                          \
636
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
637
} while (0)
638

    
639
static inline void gen_save_pc(target_ulong pc)
640
{
641
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
642
    if (pc == (int32_t)pc) {
643
        gen_op_save_pc(pc);
644
    } else {
645
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
646
    }
647
#else
648
    gen_op_save_pc(pc);
649
#endif
650
}
651

    
652
static inline void gen_save_btarget(target_ulong btarget)
653
{
654
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
655
    if (btarget == (int32_t)btarget) {
656
        gen_op_save_btarget(btarget);
657
    } else {
658
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
659
    }
660
#else
661
    gen_op_save_btarget(btarget);
662
#endif
663
}
664

    
665
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
666
{
667
#if defined MIPS_DEBUG_DISAS
668
    if (loglevel & CPU_LOG_TB_IN_ASM) {
669
            fprintf(logfile, "hflags %08x saved %08x\n",
670
                    ctx->hflags, ctx->saved_hflags);
671
    }
672
#endif
673
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
674
        gen_save_pc(ctx->pc);
675
        ctx->saved_pc = ctx->pc;
676
    }
677
    if (ctx->hflags != ctx->saved_hflags) {
678
        gen_op_save_state(ctx->hflags);
679
        ctx->saved_hflags = ctx->hflags;
680
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
681
        case MIPS_HFLAG_BR:
682
            gen_op_save_breg_target();
683
            break;
684
        case MIPS_HFLAG_BC:
685
            gen_op_save_bcond();
686
            /* fall through */
687
        case MIPS_HFLAG_BL:
688
            /* bcond was already saved by the BL insn */
689
            /* fall through */
690
        case MIPS_HFLAG_B:
691
            gen_save_btarget(ctx->btarget);
692
            break;
693
        }
694
    }
695
}
696

    
697
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
698
{
699
    ctx->saved_hflags = ctx->hflags;
700
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
701
    case MIPS_HFLAG_BR:
702
        gen_op_restore_breg_target();
703
        break;
704
    case MIPS_HFLAG_B:
705
        ctx->btarget = env->btarget;
706
        break;
707
    case MIPS_HFLAG_BC:
708
    case MIPS_HFLAG_BL:
709
        ctx->btarget = env->btarget;
710
        gen_op_restore_bcond();
711
        break;
712
    }
713
}
714

    
715
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
716
{
717
#if defined MIPS_DEBUG_DISAS
718
    if (loglevel & CPU_LOG_TB_IN_ASM)
719
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
720
#endif
721
    save_cpu_state(ctx, 1);
722
    if (err == 0)
723
        gen_op_raise_exception(excp);
724
    else
725
        gen_op_raise_exception_err(excp, err);
726
    ctx->bstate = BS_EXCP;
727
}
728

    
729
static inline void generate_exception (DisasContext *ctx, int excp)
730
{
731
    generate_exception_err (ctx, excp, 0);
732
}
733

    
734
static inline void check_cp0_enabled(DisasContext *ctx)
735
{
736
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
737
        generate_exception_err(ctx, EXCP_CpU, 1);
738
}
739

    
740
static inline void check_cp1_enabled(DisasContext *ctx)
741
{
742
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
743
        generate_exception_err(ctx, EXCP_CpU, 1);
744
}
745

    
746
static inline void check_cp1_64bitmode(DisasContext *ctx)
747
{
748
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64)))
749
        generate_exception(ctx, EXCP_RI);
750
}
751

    
752
/*
753
 * Verify if floating point register is valid; an operation is not defined
754
 * if bit 0 of any register specification is set and the FR bit in the
755
 * Status register equals zero, since the register numbers specify an
756
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
757
 * in the Status register equals one, both even and odd register numbers
758
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
759
 *
760
 * Multiple 64 bit wide registers can be checked by calling
761
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
762
 */
763
void check_cp1_registers(DisasContext *ctx, int regs)
764
{
765
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
766
        generate_exception(ctx, EXCP_RI);
767
}
768

    
769
/* This code generates a "reserved instruction" exception if the
770
   CPU does not support the instruction set corresponding to flags. */
771
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
772
{
773
    if (unlikely(!(env->insn_flags & flags)))
774
        generate_exception(ctx, EXCP_RI);
775
}
776

    
777
/* This code generates a "reserved instruction" exception if the
778
   CPU is not MIPS MT capable. */
779
static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
780
{
781
    if (unlikely(!(env->CP0_Config3 & (1 << CP0C3_MT))))
782
        generate_exception(ctx, EXCP_RI);
783
}
784

    
785
/* This code generates a "reserved instruction" exception if 64-bit
786
   instructions are not enabled. */
787
static inline void check_mips_64(DisasContext *ctx)
788
{
789
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
790
        generate_exception(ctx, EXCP_RI);
791
}
792

    
793
#if defined(CONFIG_USER_ONLY)
794
#define op_ldst(name)        gen_op_##name##_raw()
795
#define OP_LD_TABLE(width)
796
#define OP_ST_TABLE(width)
797
#else
798
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
799
#define OP_LD_TABLE(width)                                                    \
800
static GenOpFunc *gen_op_l##width[] = {                                       \
801
    &gen_op_l##width##_user,                                                  \
802
    &gen_op_l##width##_kernel,                                                \
803
}
804
#define OP_ST_TABLE(width)                                                    \
805
static GenOpFunc *gen_op_s##width[] = {                                       \
806
    &gen_op_s##width##_user,                                                  \
807
    &gen_op_s##width##_kernel,                                                \
808
}
809
#endif
810

    
811
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
812
OP_LD_TABLE(d);
813
OP_LD_TABLE(dl);
814
OP_LD_TABLE(dr);
815
OP_ST_TABLE(d);
816
OP_ST_TABLE(dl);
817
OP_ST_TABLE(dr);
818
OP_LD_TABLE(ld);
819
OP_ST_TABLE(cd);
820
OP_LD_TABLE(wu);
821
#endif
822
OP_LD_TABLE(w);
823
OP_LD_TABLE(wl);
824
OP_LD_TABLE(wr);
825
OP_ST_TABLE(w);
826
OP_ST_TABLE(wl);
827
OP_ST_TABLE(wr);
828
OP_LD_TABLE(h);
829
OP_LD_TABLE(hu);
830
OP_ST_TABLE(h);
831
OP_LD_TABLE(b);
832
OP_LD_TABLE(bu);
833
OP_ST_TABLE(b);
834
OP_LD_TABLE(l);
835
OP_ST_TABLE(c);
836
OP_LD_TABLE(wc1);
837
OP_ST_TABLE(wc1);
838
OP_LD_TABLE(dc1);
839
OP_ST_TABLE(dc1);
840
OP_LD_TABLE(uxc1);
841
OP_ST_TABLE(uxc1);
842

    
843
/* Load and store */
844
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
845
                      int base, int16_t offset)
846
{
847
    const char *opn = "ldst";
848

    
849
    if (base == 0) {
850
        GEN_LOAD_IMM_TN(T0, offset);
851
    } else if (offset == 0) {
852
        gen_op_load_gpr_T0(base);
853
    } else {
854
        gen_op_load_gpr_T0(base);
855
        gen_op_set_T1(offset);
856
        gen_op_addr_add();
857
    }
858
    /* Don't do NOP if destination is zero: we must perform the actual
859
       memory access. */
860
    switch (opc) {
861
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
862
    case OPC_LWU:
863
        op_ldst(lwu);
864
        GEN_STORE_TN_REG(rt, T0);
865
        opn = "lwu";
866
        break;
867
    case OPC_LD:
868
        op_ldst(ld);
869
        GEN_STORE_TN_REG(rt, T0);
870
        opn = "ld";
871
        break;
872
    case OPC_LLD:
873
        op_ldst(lld);
874
        GEN_STORE_TN_REG(rt, T0);
875
        opn = "lld";
876
        break;
877
    case OPC_SD:
878
        GEN_LOAD_REG_TN(T1, rt);
879
        op_ldst(sd);
880
        opn = "sd";
881
        break;
882
    case OPC_SCD:
883
        save_cpu_state(ctx, 1);
884
        GEN_LOAD_REG_TN(T1, rt);
885
        op_ldst(scd);
886
        GEN_STORE_TN_REG(rt, T0);
887
        opn = "scd";
888
        break;
889
    case OPC_LDL:
890
        GEN_LOAD_REG_TN(T1, rt);
891
        op_ldst(ldl);
892
        GEN_STORE_TN_REG(rt, T0);
893
        opn = "ldl";
894
        break;
895
    case OPC_SDL:
896
        GEN_LOAD_REG_TN(T1, rt);
897
        op_ldst(sdl);
898
        opn = "sdl";
899
        break;
900
    case OPC_LDR:
901
        GEN_LOAD_REG_TN(T1, rt);
902
        op_ldst(ldr);
903
        GEN_STORE_TN_REG(rt, T0);
904
        opn = "ldr";
905
        break;
906
    case OPC_SDR:
907
        GEN_LOAD_REG_TN(T1, rt);
908
        op_ldst(sdr);
909
        opn = "sdr";
910
        break;
911
#endif
912
    case OPC_LW:
913
        op_ldst(lw);
914
        GEN_STORE_TN_REG(rt, T0);
915
        opn = "lw";
916
        break;
917
    case OPC_SW:
918
        GEN_LOAD_REG_TN(T1, rt);
919
        op_ldst(sw);
920
        opn = "sw";
921
        break;
922
    case OPC_LH:
923
        op_ldst(lh);
924
        GEN_STORE_TN_REG(rt, T0);
925
        opn = "lh";
926
        break;
927
    case OPC_SH:
928
        GEN_LOAD_REG_TN(T1, rt);
929
        op_ldst(sh);
930
        opn = "sh";
931
        break;
932
    case OPC_LHU:
933
        op_ldst(lhu);
934
        GEN_STORE_TN_REG(rt, T0);
935
        opn = "lhu";
936
        break;
937
    case OPC_LB:
938
        op_ldst(lb);
939
        GEN_STORE_TN_REG(rt, T0);
940
        opn = "lb";
941
        break;
942
    case OPC_SB:
943
        GEN_LOAD_REG_TN(T1, rt);
944
        op_ldst(sb);
945
        opn = "sb";
946
        break;
947
    case OPC_LBU:
948
        op_ldst(lbu);
949
        GEN_STORE_TN_REG(rt, T0);
950
        opn = "lbu";
951
        break;
952
    case OPC_LWL:
953
        GEN_LOAD_REG_TN(T1, rt);
954
        op_ldst(lwl);
955
        GEN_STORE_TN_REG(rt, T0);
956
        opn = "lwl";
957
        break;
958
    case OPC_SWL:
959
        GEN_LOAD_REG_TN(T1, rt);
960
        op_ldst(swl);
961
        opn = "swr";
962
        break;
963
    case OPC_LWR:
964
        GEN_LOAD_REG_TN(T1, rt);
965
        op_ldst(lwr);
966
        GEN_STORE_TN_REG(rt, T0);
967
        opn = "lwr";
968
        break;
969
    case OPC_SWR:
970
        GEN_LOAD_REG_TN(T1, rt);
971
        op_ldst(swr);
972
        opn = "swr";
973
        break;
974
    case OPC_LL:
975
        op_ldst(ll);
976
        GEN_STORE_TN_REG(rt, T0);
977
        opn = "ll";
978
        break;
979
    case OPC_SC:
980
        save_cpu_state(ctx, 1);
981
        GEN_LOAD_REG_TN(T1, rt);
982
        op_ldst(sc);
983
        GEN_STORE_TN_REG(rt, T0);
984
        opn = "sc";
985
        break;
986
    default:
987
        MIPS_INVAL(opn);
988
        generate_exception(ctx, EXCP_RI);
989
        return;
990
    }
991
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
992
}
993

    
994
/* Load and store */
995
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
996
                      int base, int16_t offset)
997
{
998
    const char *opn = "flt_ldst";
999

    
1000
    if (base == 0) {
1001
        GEN_LOAD_IMM_TN(T0, offset);
1002
    } else if (offset == 0) {
1003
        gen_op_load_gpr_T0(base);
1004
    } else {
1005
        gen_op_load_gpr_T0(base);
1006
        gen_op_set_T1(offset);
1007
        gen_op_addr_add();
1008
    }
1009
    /* Don't do NOP if destination is zero: we must perform the actual
1010
       memory access. */
1011
    switch (opc) {
1012
    case OPC_LWC1:
1013
        op_ldst(lwc1);
1014
        GEN_STORE_FTN_FREG(ft, WT0);
1015
        opn = "lwc1";
1016
        break;
1017
    case OPC_SWC1:
1018
        GEN_LOAD_FREG_FTN(WT0, ft);
1019
        op_ldst(swc1);
1020
        opn = "swc1";
1021
        break;
1022
    case OPC_LDC1:
1023
        op_ldst(ldc1);
1024
        GEN_STORE_FTN_FREG(ft, DT0);
1025
        opn = "ldc1";
1026
        break;
1027
    case OPC_SDC1:
1028
        GEN_LOAD_FREG_FTN(DT0, ft);
1029
        op_ldst(sdc1);
1030
        opn = "sdc1";
1031
        break;
1032
    default:
1033
        MIPS_INVAL(opn);
1034
        generate_exception(ctx, EXCP_RI);
1035
        return;
1036
    }
1037
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1038
}
1039

    
1040
/* Arithmetic with immediate operand */
1041
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1042
                           int rt, int rs, int16_t imm)
1043
{
1044
    target_ulong uimm;
1045
    const char *opn = "imm arith";
1046

    
1047
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1048
        /* If no destination, treat it as a NOP.
1049
           For addi, we must generate the overflow exception when needed. */
1050
        MIPS_DEBUG("NOP");
1051
        return;
1052
    }
1053
    uimm = (uint16_t)imm;
1054
    switch (opc) {
1055
    case OPC_ADDI:
1056
    case OPC_ADDIU:
1057
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1058
    case OPC_DADDI:
1059
    case OPC_DADDIU:
1060
#endif
1061
    case OPC_SLTI:
1062
    case OPC_SLTIU:
1063
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1064
        /* Fall through. */
1065
    case OPC_ANDI:
1066
    case OPC_ORI:
1067
    case OPC_XORI:
1068
        GEN_LOAD_REG_TN(T0, rs);
1069
        GEN_LOAD_IMM_TN(T1, uimm);
1070
        break;
1071
    case OPC_LUI:
1072
        GEN_LOAD_IMM_TN(T0, imm << 16);
1073
        break;
1074
    case OPC_SLL:
1075
    case OPC_SRA:
1076
    case OPC_SRL:
1077
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1078
    case OPC_DSLL:
1079
    case OPC_DSRA:
1080
    case OPC_DSRL:
1081
    case OPC_DSLL32:
1082
    case OPC_DSRA32:
1083
    case OPC_DSRL32:
1084
#endif
1085
        uimm &= 0x1f;
1086
        GEN_LOAD_REG_TN(T0, rs);
1087
        GEN_LOAD_IMM_TN(T1, uimm);
1088
        break;
1089
    }
1090
    switch (opc) {
1091
    case OPC_ADDI:
1092
        save_cpu_state(ctx, 1);
1093
        gen_op_addo();
1094
        opn = "addi";
1095
        break;
1096
    case OPC_ADDIU:
1097
        gen_op_add();
1098
        opn = "addiu";
1099
        break;
1100
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1101
    case OPC_DADDI:
1102
        save_cpu_state(ctx, 1);
1103
        gen_op_daddo();
1104
        opn = "daddi";
1105
        break;
1106
    case OPC_DADDIU:
1107
        gen_op_dadd();
1108
        opn = "daddiu";
1109
        break;
1110
#endif
1111
    case OPC_SLTI:
1112
        gen_op_lt();
1113
        opn = "slti";
1114
        break;
1115
    case OPC_SLTIU:
1116
        gen_op_ltu();
1117
        opn = "sltiu";
1118
        break;
1119
    case OPC_ANDI:
1120
        gen_op_and();
1121
        opn = "andi";
1122
        break;
1123
    case OPC_ORI:
1124
        gen_op_or();
1125
        opn = "ori";
1126
        break;
1127
    case OPC_XORI:
1128
        gen_op_xor();
1129
        opn = "xori";
1130
        break;
1131
    case OPC_LUI:
1132
        opn = "lui";
1133
        break;
1134
    case OPC_SLL:
1135
        gen_op_sll();
1136
        opn = "sll";
1137
        break;
1138
    case OPC_SRA:
1139
        gen_op_sra();
1140
        opn = "sra";
1141
        break;
1142
    case OPC_SRL:
1143
        switch ((ctx->opcode >> 21) & 0x1f) {
1144
        case 0:
1145
            gen_op_srl();
1146
            opn = "srl";
1147
            break;
1148
        case 1:
1149
            /* rotr is decoded as srl on non-R2 CPUs */
1150
            if (env->insn_flags & ISA_MIPS32R2) {
1151
                gen_op_rotr();
1152
                opn = "rotr";
1153
            } else {
1154
                gen_op_srl();
1155
                opn = "srl";
1156
            }
1157
            break;
1158
        default:
1159
            MIPS_INVAL("invalid srl flag");
1160
            generate_exception(ctx, EXCP_RI);
1161
            break;
1162
        }
1163
        break;
1164
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1165
    case OPC_DSLL:
1166
        gen_op_dsll();
1167
        opn = "dsll";
1168
        break;
1169
    case OPC_DSRA:
1170
        gen_op_dsra();
1171
        opn = "dsra";
1172
        break;
1173
    case OPC_DSRL:
1174
        switch ((ctx->opcode >> 21) & 0x1f) {
1175
        case 0:
1176
            gen_op_dsrl();
1177
            opn = "dsrl";
1178
            break;
1179
        case 1:
1180
            /* drotr is decoded as dsrl on non-R2 CPUs */
1181
            if (env->insn_flags & ISA_MIPS32R2) {
1182
                gen_op_drotr();
1183
                opn = "drotr";
1184
            } else {
1185
                gen_op_dsrl();
1186
                opn = "dsrl";
1187
            }
1188
            break;
1189
        default:
1190
            MIPS_INVAL("invalid dsrl flag");
1191
            generate_exception(ctx, EXCP_RI);
1192
            break;
1193
        }
1194
        break;
1195
    case OPC_DSLL32:
1196
        gen_op_dsll32();
1197
        opn = "dsll32";
1198
        break;
1199
    case OPC_DSRA32:
1200
        gen_op_dsra32();
1201
        opn = "dsra32";
1202
        break;
1203
    case OPC_DSRL32:
1204
        switch ((ctx->opcode >> 21) & 0x1f) {
1205
        case 0:
1206
            gen_op_dsrl32();
1207
            opn = "dsrl32";
1208
            break;
1209
        case 1:
1210
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1211
            if (env->insn_flags & ISA_MIPS32R2) {
1212
                gen_op_drotr32();
1213
                opn = "drotr32";
1214
            } else {
1215
                gen_op_dsrl32();
1216
                opn = "dsrl32";
1217
            }
1218
            break;
1219
        default:
1220
            MIPS_INVAL("invalid dsrl32 flag");
1221
            generate_exception(ctx, EXCP_RI);
1222
            break;
1223
        }
1224
        break;
1225
#endif
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        return;
1230
    }
1231
    GEN_STORE_TN_REG(rt, T0);
1232
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1233
}
1234

    
1235
/* Arithmetic */
1236
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1237
                       int rd, int rs, int rt)
1238
{
1239
    const char *opn = "arith";
1240

    
1241
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1242
       && opc != OPC_DADD && opc != OPC_DSUB) {
1243
        /* If no destination, treat it as a NOP.
1244
           For add & sub, we must generate the overflow exception when needed. */
1245
        MIPS_DEBUG("NOP");
1246
        return;
1247
    }
1248
    GEN_LOAD_REG_TN(T0, rs);
1249
    GEN_LOAD_REG_TN(T1, rt);
1250
    switch (opc) {
1251
    case OPC_ADD:
1252
        save_cpu_state(ctx, 1);
1253
        gen_op_addo();
1254
        opn = "add";
1255
        break;
1256
    case OPC_ADDU:
1257
        gen_op_add();
1258
        opn = "addu";
1259
        break;
1260
    case OPC_SUB:
1261
        save_cpu_state(ctx, 1);
1262
        gen_op_subo();
1263
        opn = "sub";
1264
        break;
1265
    case OPC_SUBU:
1266
        gen_op_sub();
1267
        opn = "subu";
1268
        break;
1269
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1270
    case OPC_DADD:
1271
        save_cpu_state(ctx, 1);
1272
        gen_op_daddo();
1273
        opn = "dadd";
1274
        break;
1275
    case OPC_DADDU:
1276
        gen_op_dadd();
1277
        opn = "daddu";
1278
        break;
1279
    case OPC_DSUB:
1280
        save_cpu_state(ctx, 1);
1281
        gen_op_dsubo();
1282
        opn = "dsub";
1283
        break;
1284
    case OPC_DSUBU:
1285
        gen_op_dsub();
1286
        opn = "dsubu";
1287
        break;
1288
#endif
1289
    case OPC_SLT:
1290
        gen_op_lt();
1291
        opn = "slt";
1292
        break;
1293
    case OPC_SLTU:
1294
        gen_op_ltu();
1295
        opn = "sltu";
1296
        break;
1297
    case OPC_AND:
1298
        gen_op_and();
1299
        opn = "and";
1300
        break;
1301
    case OPC_NOR:
1302
        gen_op_nor();
1303
        opn = "nor";
1304
        break;
1305
    case OPC_OR:
1306
        gen_op_or();
1307
        opn = "or";
1308
        break;
1309
    case OPC_XOR:
1310
        gen_op_xor();
1311
        opn = "xor";
1312
        break;
1313
    case OPC_MUL:
1314
        gen_op_mul();
1315
        opn = "mul";
1316
        break;
1317
    case OPC_MOVN:
1318
        gen_op_movn(rd);
1319
        opn = "movn";
1320
        goto print;
1321
    case OPC_MOVZ:
1322
        gen_op_movz(rd);
1323
        opn = "movz";
1324
        goto print;
1325
    case OPC_SLLV:
1326
        gen_op_sllv();
1327
        opn = "sllv";
1328
        break;
1329
    case OPC_SRAV:
1330
        gen_op_srav();
1331
        opn = "srav";
1332
        break;
1333
    case OPC_SRLV:
1334
        switch ((ctx->opcode >> 6) & 0x1f) {
1335
        case 0:
1336
            gen_op_srlv();
1337
            opn = "srlv";
1338
            break;
1339
        case 1:
1340
            /* rotrv is decoded as srlv on non-R2 CPUs */
1341
            if (env->insn_flags & ISA_MIPS32R2) {
1342
                gen_op_rotrv();
1343
                opn = "rotrv";
1344
            } else {
1345
                gen_op_srlv();
1346
                opn = "srlv";
1347
            }
1348
            break;
1349
        default:
1350
            MIPS_INVAL("invalid srlv flag");
1351
            generate_exception(ctx, EXCP_RI);
1352
            break;
1353
        }
1354
        break;
1355
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1356
    case OPC_DSLLV:
1357
        gen_op_dsllv();
1358
        opn = "dsllv";
1359
        break;
1360
    case OPC_DSRAV:
1361
        gen_op_dsrav();
1362
        opn = "dsrav";
1363
        break;
1364
    case OPC_DSRLV:
1365
        switch ((ctx->opcode >> 6) & 0x1f) {
1366
        case 0:
1367
            gen_op_dsrlv();
1368
            opn = "dsrlv";
1369
            break;
1370
        case 1:
1371
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1372
            if (env->insn_flags & ISA_MIPS32R2) {
1373
                gen_op_drotrv();
1374
                opn = "drotrv";
1375
            } else {
1376
                gen_op_dsrlv();
1377
                opn = "dsrlv";
1378
            }
1379
            break;
1380
        default:
1381
            MIPS_INVAL("invalid dsrlv flag");
1382
            generate_exception(ctx, EXCP_RI);
1383
            break;
1384
        }
1385
        break;
1386
#endif
1387
    default:
1388
        MIPS_INVAL(opn);
1389
        generate_exception(ctx, EXCP_RI);
1390
        return;
1391
    }
1392
    GEN_STORE_TN_REG(rd, T0);
1393
 print:
1394
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1395
}
1396

    
1397
/* Arithmetic on HI/LO registers */
1398
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1399
{
1400
    const char *opn = "hilo";
1401

    
1402
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1403
        /* Treat as NOP. */
1404
        MIPS_DEBUG("NOP");
1405
        return;
1406
    }
1407
    switch (opc) {
1408
    case OPC_MFHI:
1409
        gen_op_load_HI(0);
1410
        GEN_STORE_TN_REG(reg, T0);
1411
        opn = "mfhi";
1412
        break;
1413
    case OPC_MFLO:
1414
        gen_op_load_LO(0);
1415
        GEN_STORE_TN_REG(reg, T0);
1416
        opn = "mflo";
1417
        break;
1418
    case OPC_MTHI:
1419
        GEN_LOAD_REG_TN(T0, reg);
1420
        gen_op_store_HI(0);
1421
        opn = "mthi";
1422
        break;
1423
    case OPC_MTLO:
1424
        GEN_LOAD_REG_TN(T0, reg);
1425
        gen_op_store_LO(0);
1426
        opn = "mtlo";
1427
        break;
1428
    default:
1429
        MIPS_INVAL(opn);
1430
        generate_exception(ctx, EXCP_RI);
1431
        return;
1432
    }
1433
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1434
}
1435

    
1436
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1437
                        int rs, int rt)
1438
{
1439
    const char *opn = "mul/div";
1440

    
1441
    GEN_LOAD_REG_TN(T0, rs);
1442
    GEN_LOAD_REG_TN(T1, rt);
1443
    switch (opc) {
1444
    case OPC_DIV:
1445
        gen_op_div();
1446
        opn = "div";
1447
        break;
1448
    case OPC_DIVU:
1449
        gen_op_divu();
1450
        opn = "divu";
1451
        break;
1452
    case OPC_MULT:
1453
        gen_op_mult();
1454
        opn = "mult";
1455
        break;
1456
    case OPC_MULTU:
1457
        gen_op_multu();
1458
        opn = "multu";
1459
        break;
1460
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1461
    case OPC_DDIV:
1462
        gen_op_ddiv();
1463
        opn = "ddiv";
1464
        break;
1465
    case OPC_DDIVU:
1466
        gen_op_ddivu();
1467
        opn = "ddivu";
1468
        break;
1469
    case OPC_DMULT:
1470
        gen_op_dmult();
1471
        opn = "dmult";
1472
        break;
1473
    case OPC_DMULTU:
1474
        gen_op_dmultu();
1475
        opn = "dmultu";
1476
        break;
1477
#endif
1478
    case OPC_MADD:
1479
        gen_op_madd();
1480
        opn = "madd";
1481
        break;
1482
    case OPC_MADDU:
1483
        gen_op_maddu();
1484
        opn = "maddu";
1485
        break;
1486
    case OPC_MSUB:
1487
        gen_op_msub();
1488
        opn = "msub";
1489
        break;
1490
    case OPC_MSUBU:
1491
        gen_op_msubu();
1492
        opn = "msubu";
1493
        break;
1494
    default:
1495
        MIPS_INVAL(opn);
1496
        generate_exception(ctx, EXCP_RI);
1497
        return;
1498
    }
1499
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1500
}
1501

    
1502
static void gen_cl (DisasContext *ctx, uint32_t opc,
1503
                    int rd, int rs)
1504
{
1505
    const char *opn = "CLx";
1506
    if (rd == 0) {
1507
        /* Treat as NOP. */
1508
        MIPS_DEBUG("NOP");
1509
        return;
1510
    }
1511
    GEN_LOAD_REG_TN(T0, rs);
1512
    switch (opc) {
1513
    case OPC_CLO:
1514
        gen_op_clo();
1515
        opn = "clo";
1516
        break;
1517
    case OPC_CLZ:
1518
        gen_op_clz();
1519
        opn = "clz";
1520
        break;
1521
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1522
    case OPC_DCLO:
1523
        gen_op_dclo();
1524
        opn = "dclo";
1525
        break;
1526
    case OPC_DCLZ:
1527
        gen_op_dclz();
1528
        opn = "dclz";
1529
        break;
1530
#endif
1531
    default:
1532
        MIPS_INVAL(opn);
1533
        generate_exception(ctx, EXCP_RI);
1534
        return;
1535
    }
1536
    gen_op_store_T0_gpr(rd);
1537
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1538
}
1539

    
1540
/* Traps */
1541
static void gen_trap (DisasContext *ctx, uint32_t opc,
1542
                      int rs, int rt, int16_t imm)
1543
{
1544
    int cond;
1545

    
1546
    cond = 0;
1547
    /* Load needed operands */
1548
    switch (opc) {
1549
    case OPC_TEQ:
1550
    case OPC_TGE:
1551
    case OPC_TGEU:
1552
    case OPC_TLT:
1553
    case OPC_TLTU:
1554
    case OPC_TNE:
1555
        /* Compare two registers */
1556
        if (rs != rt) {
1557
            GEN_LOAD_REG_TN(T0, rs);
1558
            GEN_LOAD_REG_TN(T1, rt);
1559
            cond = 1;
1560
        }
1561
        break;
1562
    case OPC_TEQI:
1563
    case OPC_TGEI:
1564
    case OPC_TGEIU:
1565
    case OPC_TLTI:
1566
    case OPC_TLTIU:
1567
    case OPC_TNEI:
1568
        /* Compare register to immediate */
1569
        if (rs != 0 || imm != 0) {
1570
            GEN_LOAD_REG_TN(T0, rs);
1571
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1572
            cond = 1;
1573
        }
1574
        break;
1575
    }
1576
    if (cond == 0) {
1577
        switch (opc) {
1578
        case OPC_TEQ:   /* rs == rs */
1579
        case OPC_TEQI:  /* r0 == 0  */
1580
        case OPC_TGE:   /* rs >= rs */
1581
        case OPC_TGEI:  /* r0 >= 0  */
1582
        case OPC_TGEU:  /* rs >= rs unsigned */
1583
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1584
            /* Always trap */
1585
            gen_op_set_T0(1);
1586
            break;
1587
        case OPC_TLT:   /* rs < rs           */
1588
        case OPC_TLTI:  /* r0 < 0            */
1589
        case OPC_TLTU:  /* rs < rs unsigned  */
1590
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1591
        case OPC_TNE:   /* rs != rs          */
1592
        case OPC_TNEI:  /* r0 != 0           */
1593
            /* Never trap: treat as NOP. */
1594
            return;
1595
        default:
1596
            MIPS_INVAL("trap");
1597
            generate_exception(ctx, EXCP_RI);
1598
            return;
1599
        }
1600
    } else {
1601
        switch (opc) {
1602
        case OPC_TEQ:
1603
        case OPC_TEQI:
1604
            gen_op_eq();
1605
            break;
1606
        case OPC_TGE:
1607
        case OPC_TGEI:
1608
            gen_op_ge();
1609
            break;
1610
        case OPC_TGEU:
1611
        case OPC_TGEIU:
1612
            gen_op_geu();
1613
            break;
1614
        case OPC_TLT:
1615
        case OPC_TLTI:
1616
            gen_op_lt();
1617
            break;
1618
        case OPC_TLTU:
1619
        case OPC_TLTIU:
1620
            gen_op_ltu();
1621
            break;
1622
        case OPC_TNE:
1623
        case OPC_TNEI:
1624
            gen_op_ne();
1625
            break;
1626
        default:
1627
            MIPS_INVAL("trap");
1628
            generate_exception(ctx, EXCP_RI);
1629
            return;
1630
        }
1631
    }
1632
    save_cpu_state(ctx, 1);
1633
    gen_op_trap();
1634
    ctx->bstate = BS_STOP;
1635
}
1636

    
1637
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1638
{
1639
    TranslationBlock *tb;
1640
    tb = ctx->tb;
1641
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1642
        if (n == 0)
1643
            gen_op_goto_tb0(TBPARAM(tb));
1644
        else
1645
            gen_op_goto_tb1(TBPARAM(tb));
1646
        gen_save_pc(dest);
1647
        gen_op_set_T0((long)tb + n);
1648
    } else {
1649
        gen_save_pc(dest);
1650
        gen_op_reset_T0();
1651
    }
1652
    gen_op_exit_tb();
1653
}
1654

    
1655
/* Branches (before delay slot) */
1656
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1657
                                int rs, int rt, int32_t offset)
1658
{
1659
    target_ulong btarget = -1;
1660
    int blink = 0;
1661
    int bcond = 0;
1662

    
1663
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1664
#ifdef MIPS_DEBUG_DISAS
1665
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1666
            fprintf(logfile,
1667
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1668
                    ctx->pc);
1669
        }
1670
#endif
1671
        generate_exception(ctx, EXCP_RI);
1672
        return;
1673
    }
1674

    
1675
    /* Load needed operands */
1676
    switch (opc) {
1677
    case OPC_BEQ:
1678
    case OPC_BEQL:
1679
    case OPC_BNE:
1680
    case OPC_BNEL:
1681
        /* Compare two registers */
1682
        if (rs != rt) {
1683
            GEN_LOAD_REG_TN(T0, rs);
1684
            GEN_LOAD_REG_TN(T1, rt);
1685
            bcond = 1;
1686
        }
1687
        btarget = ctx->pc + 4 + offset;
1688
        break;
1689
    case OPC_BGEZ:
1690
    case OPC_BGEZAL:
1691
    case OPC_BGEZALL:
1692
    case OPC_BGEZL:
1693
    case OPC_BGTZ:
1694
    case OPC_BGTZL:
1695
    case OPC_BLEZ:
1696
    case OPC_BLEZL:
1697
    case OPC_BLTZ:
1698
    case OPC_BLTZAL:
1699
    case OPC_BLTZALL:
1700
    case OPC_BLTZL:
1701
        /* Compare to zero */
1702
        if (rs != 0) {
1703
            gen_op_load_gpr_T0(rs);
1704
            bcond = 1;
1705
        }
1706
        btarget = ctx->pc + 4 + offset;
1707
        break;
1708
    case OPC_J:
1709
    case OPC_JAL:
1710
        /* Jump to immediate */
1711
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1712
        break;
1713
    case OPC_JR:
1714
    case OPC_JALR:
1715
        /* Jump to register */
1716
        if (offset != 0 && offset != 16) {
1717
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1718
               others are reserved. */
1719
            MIPS_INVAL("jump hint");
1720
            generate_exception(ctx, EXCP_RI);
1721
            return;
1722
        }
1723
        GEN_LOAD_REG_TN(T2, rs);
1724
        break;
1725
    default:
1726
        MIPS_INVAL("branch/jump");
1727
        generate_exception(ctx, EXCP_RI);
1728
        return;
1729
    }
1730
    if (bcond == 0) {
1731
        /* No condition to be computed */
1732
        switch (opc) {
1733
        case OPC_BEQ:     /* rx == rx        */
1734
        case OPC_BEQL:    /* rx == rx likely */
1735
        case OPC_BGEZ:    /* 0 >= 0          */
1736
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1737
        case OPC_BLEZ:    /* 0 <= 0          */
1738
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1739
            /* Always take */
1740
            ctx->hflags |= MIPS_HFLAG_B;
1741
            MIPS_DEBUG("balways");
1742
            break;
1743
        case OPC_BGEZAL:  /* 0 >= 0          */
1744
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1745
            /* Always take and link */
1746
            blink = 31;
1747
            ctx->hflags |= MIPS_HFLAG_B;
1748
            MIPS_DEBUG("balways and link");
1749
            break;
1750
        case OPC_BNE:     /* rx != rx        */
1751
        case OPC_BGTZ:    /* 0 > 0           */
1752
        case OPC_BLTZ:    /* 0 < 0           */
1753
            /* Treat as NOP. */
1754
            MIPS_DEBUG("bnever (NOP)");
1755
            return;
1756
        case OPC_BLTZAL:  /* 0 < 0           */
1757
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1758
            gen_op_store_T0_gpr(31);
1759
            MIPS_DEBUG("bnever and link");
1760
            return;
1761
        case OPC_BLTZALL: /* 0 < 0 likely */
1762
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1763
            gen_op_store_T0_gpr(31);
1764
            /* Skip the instruction in the delay slot */
1765
            MIPS_DEBUG("bnever, link and skip");
1766
            ctx->pc += 4;
1767
            return;
1768
        case OPC_BNEL:    /* rx != rx likely */
1769
        case OPC_BGTZL:   /* 0 > 0 likely */
1770
        case OPC_BLTZL:   /* 0 < 0 likely */
1771
            /* Skip the instruction in the delay slot */
1772
            MIPS_DEBUG("bnever and skip");
1773
            ctx->pc += 4;
1774
            return;
1775
        case OPC_J:
1776
            ctx->hflags |= MIPS_HFLAG_B;
1777
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1778
            break;
1779
        case OPC_JAL:
1780
            blink = 31;
1781
            ctx->hflags |= MIPS_HFLAG_B;
1782
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1783
            break;
1784
        case OPC_JR:
1785
            ctx->hflags |= MIPS_HFLAG_BR;
1786
            MIPS_DEBUG("jr %s", regnames[rs]);
1787
            break;
1788
        case OPC_JALR:
1789
            blink = rt;
1790
            ctx->hflags |= MIPS_HFLAG_BR;
1791
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1792
            break;
1793
        default:
1794
            MIPS_INVAL("branch/jump");
1795
            generate_exception(ctx, EXCP_RI);
1796
            return;
1797
        }
1798
    } else {
1799
        switch (opc) {
1800
        case OPC_BEQ:
1801
            gen_op_eq();
1802
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1803
                       regnames[rs], regnames[rt], btarget);
1804
            goto not_likely;
1805
        case OPC_BEQL:
1806
            gen_op_eq();
1807
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1808
                       regnames[rs], regnames[rt], btarget);
1809
            goto likely;
1810
        case OPC_BNE:
1811
            gen_op_ne();
1812
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1813
                       regnames[rs], regnames[rt], btarget);
1814
            goto not_likely;
1815
        case OPC_BNEL:
1816
            gen_op_ne();
1817
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1818
                       regnames[rs], regnames[rt], btarget);
1819
            goto likely;
1820
        case OPC_BGEZ:
1821
            gen_op_gez();
1822
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1823
            goto not_likely;
1824
        case OPC_BGEZL:
1825
            gen_op_gez();
1826
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1827
            goto likely;
1828
        case OPC_BGEZAL:
1829
            gen_op_gez();
1830
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1831
            blink = 31;
1832
            goto not_likely;
1833
        case OPC_BGEZALL:
1834
            gen_op_gez();
1835
            blink = 31;
1836
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1837
            goto likely;
1838
        case OPC_BGTZ:
1839
            gen_op_gtz();
1840
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1841
            goto not_likely;
1842
        case OPC_BGTZL:
1843
            gen_op_gtz();
1844
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1845
            goto likely;
1846
        case OPC_BLEZ:
1847
            gen_op_lez();
1848
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1849
            goto not_likely;
1850
        case OPC_BLEZL:
1851
            gen_op_lez();
1852
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1853
            goto likely;
1854
        case OPC_BLTZ:
1855
            gen_op_ltz();
1856
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1857
            goto not_likely;
1858
        case OPC_BLTZL:
1859
            gen_op_ltz();
1860
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1861
            goto likely;
1862
        case OPC_BLTZAL:
1863
            gen_op_ltz();
1864
            blink = 31;
1865
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1866
        not_likely:
1867
            ctx->hflags |= MIPS_HFLAG_BC;
1868
            gen_op_set_bcond();
1869
            break;
1870
        case OPC_BLTZALL:
1871
            gen_op_ltz();
1872
            blink = 31;
1873
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1874
        likely:
1875
            ctx->hflags |= MIPS_HFLAG_BL;
1876
            gen_op_set_bcond();
1877
            gen_op_save_bcond();
1878
            break;
1879
        default:
1880
            MIPS_INVAL("conditional branch/jump");
1881
            generate_exception(ctx, EXCP_RI);
1882
            return;
1883
        }
1884
    }
1885
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1886
               blink, ctx->hflags, btarget);
1887

    
1888
    ctx->btarget = btarget;
1889
    if (blink > 0) {
1890
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1891
        gen_op_store_T0_gpr(blink);
1892
    }
1893
}
1894

    
1895
/* special3 bitfield operations */
1896
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1897
                       int rs, int lsb, int msb)
1898
{
1899
    GEN_LOAD_REG_TN(T1, rs);
1900
    switch (opc) {
1901
    case OPC_EXT:
1902
        if (lsb + msb > 31)
1903
            goto fail;
1904
        gen_op_ext(lsb, msb + 1);
1905
        break;
1906
    case OPC_DEXTM:
1907
        if (lsb + msb > 63)
1908
            goto fail;
1909
        gen_op_ext(lsb, msb + 1 + 32);
1910
        break;
1911
    case OPC_DEXTU:
1912
        if (lsb + msb > 63)
1913
            goto fail;
1914
        gen_op_ext(lsb + 32, msb + 1);
1915
        break;
1916
    case OPC_DEXT:
1917
        gen_op_ext(lsb, msb + 1);
1918
        break;
1919
    case OPC_INS:
1920
        if (lsb > msb)
1921
            goto fail;
1922
        GEN_LOAD_REG_TN(T0, rt);
1923
        gen_op_ins(lsb, msb - lsb + 1);
1924
        break;
1925
    case OPC_DINSM:
1926
        if (lsb > msb)
1927
            goto fail;
1928
        GEN_LOAD_REG_TN(T0, rt);
1929
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1930
        break;
1931
    case OPC_DINSU:
1932
        if (lsb > msb)
1933
            goto fail;
1934
        GEN_LOAD_REG_TN(T0, rt);
1935
        gen_op_ins(lsb + 32, msb - lsb + 1);
1936
        break;
1937
    case OPC_DINS:
1938
        if (lsb > msb)
1939
            goto fail;
1940
        GEN_LOAD_REG_TN(T0, rt);
1941
        gen_op_ins(lsb, msb - lsb + 1);
1942
        break;
1943
    default:
1944
fail:
1945
        MIPS_INVAL("bitops");
1946
        generate_exception(ctx, EXCP_RI);
1947
        return;
1948
    }
1949
    GEN_STORE_TN_REG(rt, T0);
1950
}
1951

    
1952
/* CP0 (MMU and control) */
1953
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1954
{
1955
    const char *rn = "invalid";
1956

    
1957
    if (sel != 0)
1958
        check_insn(env, ctx, ISA_MIPS32);
1959

    
1960
    switch (reg) {
1961
    case 0:
1962
        switch (sel) {
1963
        case 0:
1964
            gen_op_mfc0_index();
1965
            rn = "Index";
1966
            break;
1967
        case 1:
1968
            check_mips_mt(env, ctx);
1969
            gen_op_mfc0_mvpcontrol();
1970
            rn = "MVPControl";
1971
            break;
1972
        case 2:
1973
            check_mips_mt(env, ctx);
1974
            gen_op_mfc0_mvpconf0();
1975
            rn = "MVPConf0";
1976
            break;
1977
        case 3:
1978
            check_mips_mt(env, ctx);
1979
            gen_op_mfc0_mvpconf1();
1980
            rn = "MVPConf1";
1981
            break;
1982
        default:
1983
            goto die;
1984
        }
1985
        break;
1986
    case 1:
1987
        switch (sel) {
1988
        case 0:
1989
            gen_op_mfc0_random();
1990
            rn = "Random";
1991
            break;
1992
        case 1:
1993
            check_mips_mt(env, ctx);
1994
            gen_op_mfc0_vpecontrol();
1995
            rn = "VPEControl";
1996
            break;
1997
        case 2:
1998
            check_mips_mt(env, ctx);
1999
            gen_op_mfc0_vpeconf0();
2000
            rn = "VPEConf0";
2001
            break;
2002
        case 3:
2003
            check_mips_mt(env, ctx);
2004
            gen_op_mfc0_vpeconf1();
2005
            rn = "VPEConf1";
2006
            break;
2007
        case 4:
2008
            check_mips_mt(env, ctx);
2009
            gen_op_mfc0_yqmask();
2010
            rn = "YQMask";
2011
            break;
2012
        case 5:
2013
            check_mips_mt(env, ctx);
2014
            gen_op_mfc0_vpeschedule();
2015
            rn = "VPESchedule";
2016
            break;
2017
        case 6:
2018
            check_mips_mt(env, ctx);
2019
            gen_op_mfc0_vpeschefback();
2020
            rn = "VPEScheFBack";
2021
            break;
2022
        case 7:
2023
            check_mips_mt(env, ctx);
2024
            gen_op_mfc0_vpeopt();
2025
            rn = "VPEOpt";
2026
            break;
2027
        default:
2028
            goto die;
2029
        }
2030
        break;
2031
    case 2:
2032
        switch (sel) {
2033
        case 0:
2034
            gen_op_mfc0_entrylo0();
2035
            rn = "EntryLo0";
2036
            break;
2037
        case 1:
2038
            check_mips_mt(env, ctx);
2039
            gen_op_mfc0_tcstatus();
2040
            rn = "TCStatus";
2041
            break;
2042
        case 2:
2043
            check_mips_mt(env, ctx);
2044
            gen_op_mfc0_tcbind();
2045
            rn = "TCBind";
2046
            break;
2047
        case 3:
2048
            check_mips_mt(env, ctx);
2049
            gen_op_mfc0_tcrestart();
2050
            rn = "TCRestart";
2051
            break;
2052
        case 4:
2053
            check_mips_mt(env, ctx);
2054
            gen_op_mfc0_tchalt();
2055
            rn = "TCHalt";
2056
            break;
2057
        case 5:
2058
            check_mips_mt(env, ctx);
2059
            gen_op_mfc0_tccontext();
2060
            rn = "TCContext";
2061
            break;
2062
        case 6:
2063
            check_mips_mt(env, ctx);
2064
            gen_op_mfc0_tcschedule();
2065
            rn = "TCSchedule";
2066
            break;
2067
        case 7:
2068
            check_mips_mt(env, ctx);
2069
            gen_op_mfc0_tcschefback();
2070
            rn = "TCScheFBack";
2071
            break;
2072
        default:
2073
            goto die;
2074
        }
2075
        break;
2076
    case 3:
2077
        switch (sel) {
2078
        case 0:
2079
            gen_op_mfc0_entrylo1();
2080
            rn = "EntryLo1";
2081
            break;
2082
        default:
2083
            goto die;
2084
        }
2085
        break;
2086
    case 4:
2087
        switch (sel) {
2088
        case 0:
2089
            gen_op_mfc0_context();
2090
            rn = "Context";
2091
            break;
2092
        case 1:
2093
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2094
            rn = "ContextConfig";
2095
//            break;
2096
        default:
2097
            goto die;
2098
        }
2099
        break;
2100
    case 5:
2101
        switch (sel) {
2102
        case 0:
2103
            gen_op_mfc0_pagemask();
2104
            rn = "PageMask";
2105
            break;
2106
        case 1:
2107
            check_insn(env, ctx, ISA_MIPS32R2);
2108
            gen_op_mfc0_pagegrain();
2109
            rn = "PageGrain";
2110
            break;
2111
        default:
2112
            goto die;
2113
        }
2114
        break;
2115
    case 6:
2116
        switch (sel) {
2117
        case 0:
2118
            gen_op_mfc0_wired();
2119
            rn = "Wired";
2120
            break;
2121
        case 1:
2122
            check_insn(env, ctx, ISA_MIPS32R2);
2123
            gen_op_mfc0_srsconf0();
2124
            rn = "SRSConf0";
2125
            break;
2126
        case 2:
2127
            check_insn(env, ctx, ISA_MIPS32R2);
2128
            gen_op_mfc0_srsconf1();
2129
            rn = "SRSConf1";
2130
            break;
2131
        case 3:
2132
            check_insn(env, ctx, ISA_MIPS32R2);
2133
            gen_op_mfc0_srsconf2();
2134
            rn = "SRSConf2";
2135
            break;
2136
        case 4:
2137
            check_insn(env, ctx, ISA_MIPS32R2);
2138
            gen_op_mfc0_srsconf3();
2139
            rn = "SRSConf3";
2140
            break;
2141
        case 5:
2142
            check_insn(env, ctx, ISA_MIPS32R2);
2143
            gen_op_mfc0_srsconf4();
2144
            rn = "SRSConf4";
2145
            break;
2146
        default:
2147
            goto die;
2148
        }
2149
        break;
2150
    case 7:
2151
        switch (sel) {
2152
        case 0:
2153
            check_insn(env, ctx, ISA_MIPS32R2);
2154
            gen_op_mfc0_hwrena();
2155
            rn = "HWREna";
2156
            break;
2157
        default:
2158
            goto die;
2159
        }
2160
        break;
2161
    case 8:
2162
        switch (sel) {
2163
        case 0:
2164
            gen_op_mfc0_badvaddr();
2165
            rn = "BadVaddr";
2166
            break;
2167
        default:
2168
            goto die;
2169
       }
2170
        break;
2171
    case 9:
2172
        switch (sel) {
2173
        case 0:
2174
            gen_op_mfc0_count();
2175
            rn = "Count";
2176
            break;
2177
        /* 6,7 are implementation dependent */
2178
        default:
2179
            goto die;
2180
        }
2181
        break;
2182
    case 10:
2183
        switch (sel) {
2184
        case 0:
2185
            gen_op_mfc0_entryhi();
2186
            rn = "EntryHi";
2187
            break;
2188
        default:
2189
            goto die;
2190
        }
2191
        break;
2192
    case 11:
2193
        switch (sel) {
2194
        case 0:
2195
            gen_op_mfc0_compare();
2196
            rn = "Compare";
2197
            break;
2198
        /* 6,7 are implementation dependent */
2199
        default:
2200
            goto die;
2201
        }
2202
        break;
2203
    case 12:
2204
        switch (sel) {
2205
        case 0:
2206
            gen_op_mfc0_status();
2207
            rn = "Status";
2208
            break;
2209
        case 1:
2210
            check_insn(env, ctx, ISA_MIPS32R2);
2211
            gen_op_mfc0_intctl();
2212
            rn = "IntCtl";
2213
            break;
2214
        case 2:
2215
            check_insn(env, ctx, ISA_MIPS32R2);
2216
            gen_op_mfc0_srsctl();
2217
            rn = "SRSCtl";
2218
            break;
2219
        case 3:
2220
            check_insn(env, ctx, ISA_MIPS32R2);
2221
            gen_op_mfc0_srsmap();
2222
            rn = "SRSMap";
2223
            break;
2224
        default:
2225
            goto die;
2226
       }
2227
        break;
2228
    case 13:
2229
        switch (sel) {
2230
        case 0:
2231
            gen_op_mfc0_cause();
2232
            rn = "Cause";
2233
            break;
2234
        default:
2235
            goto die;
2236
       }
2237
        break;
2238
    case 14:
2239
        switch (sel) {
2240
        case 0:
2241
            gen_op_mfc0_epc();
2242
            rn = "EPC";
2243
            break;
2244
        default:
2245
            goto die;
2246
        }
2247
        break;
2248
    case 15:
2249
        switch (sel) {
2250
        case 0:
2251
            gen_op_mfc0_prid();
2252
            rn = "PRid";
2253
            break;
2254
        case 1:
2255
            check_insn(env, ctx, ISA_MIPS32R2);
2256
            gen_op_mfc0_ebase();
2257
            rn = "EBase";
2258
            break;
2259
        default:
2260
            goto die;
2261
       }
2262
        break;
2263
    case 16:
2264
        switch (sel) {
2265
        case 0:
2266
            gen_op_mfc0_config0();
2267
            rn = "Config";
2268
            break;
2269
        case 1:
2270
            gen_op_mfc0_config1();
2271
            rn = "Config1";
2272
            break;
2273
        case 2:
2274
            gen_op_mfc0_config2();
2275
            rn = "Config2";
2276
            break;
2277
        case 3:
2278
            gen_op_mfc0_config3();
2279
            rn = "Config3";
2280
            break;
2281
        /* 4,5 are reserved */
2282
        /* 6,7 are implementation dependent */
2283
        case 6:
2284
            gen_op_mfc0_config6();
2285
            rn = "Config6";
2286
            break;
2287
        case 7:
2288
            gen_op_mfc0_config7();
2289
            rn = "Config7";
2290
            break;
2291
        default:
2292
            goto die;
2293
        }
2294
        break;
2295
    case 17:
2296
        switch (sel) {
2297
        case 0:
2298
            gen_op_mfc0_lladdr();
2299
            rn = "LLAddr";
2300
            break;
2301
        default:
2302
            goto die;
2303
        }
2304
        break;
2305
    case 18:
2306
        switch (sel) {
2307
        case 0 ... 7:
2308
            gen_op_mfc0_watchlo(sel);
2309
            rn = "WatchLo";
2310
            break;
2311
        default:
2312
            goto die;
2313
        }
2314
        break;
2315
    case 19:
2316
        switch (sel) {
2317
        case 0 ...7:
2318
            gen_op_mfc0_watchhi(sel);
2319
            rn = "WatchHi";
2320
            break;
2321
        default:
2322
            goto die;
2323
        }
2324
        break;
2325
    case 20:
2326
        switch (sel) {
2327
        case 0:
2328
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
2329
            check_insn(env, ctx, ISA_MIPS3);
2330
            gen_op_mfc0_xcontext();
2331
            rn = "XContext";
2332
            break;
2333
#endif
2334
        default:
2335
            goto die;
2336
        }
2337
        break;
2338
    case 21:
2339
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2340
        switch (sel) {
2341
        case 0:
2342
            gen_op_mfc0_framemask();
2343
            rn = "Framemask";
2344
            break;
2345
        default:
2346
            goto die;
2347
        }
2348
        break;
2349
    case 22:
2350
        /* ignored */
2351
        rn = "'Diagnostic"; /* implementation dependent */
2352
        break;
2353
    case 23:
2354
        switch (sel) {
2355
        case 0:
2356
            gen_op_mfc0_debug(); /* EJTAG support */
2357
            rn = "Debug";
2358
            break;
2359
        case 1:
2360
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2361
            rn = "TraceControl";
2362
//            break;
2363
        case 2:
2364
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2365
            rn = "TraceControl2";
2366
//            break;
2367
        case 3:
2368
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2369
            rn = "UserTraceData";
2370
//            break;
2371
        case 4:
2372
//            gen_op_mfc0_debug(); /* PDtrace support */
2373
            rn = "TraceBPC";
2374
//            break;
2375
        default:
2376
            goto die;
2377
        }
2378
        break;
2379
    case 24:
2380
        switch (sel) {
2381
        case 0:
2382
            gen_op_mfc0_depc(); /* EJTAG support */
2383
            rn = "DEPC";
2384
            break;
2385
        default:
2386
            goto die;
2387
        }
2388
        break;
2389
    case 25:
2390
        switch (sel) {
2391
        case 0:
2392
            gen_op_mfc0_performance0();
2393
            rn = "Performance0";
2394
            break;
2395
        case 1:
2396
//            gen_op_mfc0_performance1();
2397
            rn = "Performance1";
2398
//            break;
2399
        case 2:
2400
//            gen_op_mfc0_performance2();
2401
            rn = "Performance2";
2402
//            break;
2403
        case 3:
2404
//            gen_op_mfc0_performance3();
2405
            rn = "Performance3";
2406
//            break;
2407
        case 4:
2408
//            gen_op_mfc0_performance4();
2409
            rn = "Performance4";
2410
//            break;
2411
        case 5:
2412
//            gen_op_mfc0_performance5();
2413
            rn = "Performance5";
2414
//            break;
2415
        case 6:
2416
//            gen_op_mfc0_performance6();
2417
            rn = "Performance6";
2418
//            break;
2419
        case 7:
2420
//            gen_op_mfc0_performance7();
2421
            rn = "Performance7";
2422
//            break;
2423
        default:
2424
            goto die;
2425
        }
2426
        break;
2427
    case 26:
2428
       rn = "ECC";
2429
       break;
2430
    case 27:
2431
        switch (sel) {
2432
        /* ignored */
2433
        case 0 ... 3:
2434
            rn = "CacheErr";
2435
            break;
2436
        default:
2437
            goto die;
2438
        }
2439
        break;
2440
    case 28:
2441
        switch (sel) {
2442
        case 0:
2443
        case 2:
2444
        case 4:
2445
        case 6:
2446
            gen_op_mfc0_taglo();
2447
            rn = "TagLo";
2448
            break;
2449
        case 1:
2450
        case 3:
2451
        case 5:
2452
        case 7:
2453
            gen_op_mfc0_datalo();
2454
            rn = "DataLo";
2455
            break;
2456
        default:
2457
            goto die;
2458
        }
2459
        break;
2460
    case 29:
2461
        switch (sel) {
2462
        case 0:
2463
        case 2:
2464
        case 4:
2465
        case 6:
2466
            gen_op_mfc0_taghi();
2467
            rn = "TagHi";
2468
            break;
2469
        case 1:
2470
        case 3:
2471
        case 5:
2472
        case 7:
2473
            gen_op_mfc0_datahi();
2474
            rn = "DataHi";
2475
            break;
2476
        default:
2477
            goto die;
2478
        }
2479
        break;
2480
    case 30:
2481
        switch (sel) {
2482
        case 0:
2483
            gen_op_mfc0_errorepc();
2484
            rn = "ErrorEPC";
2485
            break;
2486
        default:
2487
            goto die;
2488
        }
2489
        break;
2490
    case 31:
2491
        switch (sel) {
2492
        case 0:
2493
            gen_op_mfc0_desave(); /* EJTAG support */
2494
            rn = "DESAVE";
2495
            break;
2496
        default:
2497
            goto die;
2498
        }
2499
        break;
2500
    default:
2501
       goto die;
2502
    }
2503
#if defined MIPS_DEBUG_DISAS
2504
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2505
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2506
                rn, reg, sel);
2507
    }
2508
#endif
2509
    return;
2510

    
2511
die:
2512
#if defined MIPS_DEBUG_DISAS
2513
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2514
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2515
                rn, reg, sel);
2516
    }
2517
#endif
2518
    generate_exception(ctx, EXCP_RI);
2519
}
2520

    
2521
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2522
{
2523
    const char *rn = "invalid";
2524

    
2525
    if (sel != 0)
2526
        check_insn(env, ctx, ISA_MIPS32);
2527

    
2528
    switch (reg) {
2529
    case 0:
2530
        switch (sel) {
2531
        case 0:
2532
           gen_op_mtc0_index();
2533
            rn = "Index";
2534
            break;
2535
        case 1:
2536
            check_mips_mt(env, ctx);
2537
            gen_op_mtc0_mvpcontrol();
2538
            rn = "MVPControl";
2539
            break;
2540
        case 2:
2541
            check_mips_mt(env, ctx);
2542
            /* ignored */
2543
            rn = "MVPConf0";
2544
            break;
2545
        case 3:
2546
            check_mips_mt(env, ctx);
2547
            /* ignored */
2548
            rn = "MVPConf1";
2549
            break;
2550
        default:
2551
            goto die;
2552
        }
2553
        break;
2554
    case 1:
2555
        switch (sel) {
2556
        case 0:
2557
            /* ignored */
2558
            rn = "Random";
2559
            break;
2560
        case 1:
2561
            check_mips_mt(env, ctx);
2562
            gen_op_mtc0_vpecontrol();
2563
            rn = "VPEControl";
2564
            break;
2565
        case 2:
2566
            check_mips_mt(env, ctx);
2567
            gen_op_mtc0_vpeconf0();
2568
            rn = "VPEConf0";
2569
            break;
2570
        case 3:
2571
            check_mips_mt(env, ctx);
2572
            gen_op_mtc0_vpeconf1();
2573
            rn = "VPEConf1";
2574
            break;
2575
        case 4:
2576
            check_mips_mt(env, ctx);
2577
            gen_op_mtc0_yqmask();
2578
            rn = "YQMask";
2579
            break;
2580
        case 5:
2581
            check_mips_mt(env, ctx);
2582
            gen_op_mtc0_vpeschedule();
2583
            rn = "VPESchedule";
2584
            break;
2585
        case 6:
2586
            check_mips_mt(env, ctx);
2587
            gen_op_mtc0_vpeschefback();
2588
            rn = "VPEScheFBack";
2589
            break;
2590
        case 7:
2591
            check_mips_mt(env, ctx);
2592
            gen_op_mtc0_vpeopt();
2593
            rn = "VPEOpt";
2594
            break;
2595
        default:
2596
            goto die;
2597
        }
2598
        break;
2599
    case 2:
2600
        switch (sel) {
2601
        case 0:
2602
            gen_op_mtc0_entrylo0();
2603
            rn = "EntryLo0";
2604
            break;
2605
        case 1:
2606
            check_mips_mt(env, ctx);
2607
            gen_op_mtc0_tcstatus();
2608
            rn = "TCStatus";
2609
            break;
2610
        case 2:
2611
            check_mips_mt(env, ctx);
2612
            gen_op_mtc0_tcbind();
2613
            rn = "TCBind";
2614
            break;
2615
        case 3:
2616
            check_mips_mt(env, ctx);
2617
            gen_op_mtc0_tcrestart();
2618
            rn = "TCRestart";
2619
            break;
2620
        case 4:
2621
            check_mips_mt(env, ctx);
2622
            gen_op_mtc0_tchalt();
2623
            rn = "TCHalt";
2624
            break;
2625
        case 5:
2626
            check_mips_mt(env, ctx);
2627
            gen_op_mtc0_tccontext();
2628
            rn = "TCContext";
2629
            break;
2630
        case 6:
2631
            check_mips_mt(env, ctx);
2632
            gen_op_mtc0_tcschedule();
2633
            rn = "TCSchedule";
2634
            break;
2635
        case 7:
2636
            check_mips_mt(env, ctx);
2637
            gen_op_mtc0_tcschefback();
2638
            rn = "TCScheFBack";
2639
            break;
2640
        default:
2641
            goto die;
2642
        }
2643
        break;
2644
    case 3:
2645
        switch (sel) {
2646
        case 0:
2647
            gen_op_mtc0_entrylo1();
2648
            rn = "EntryLo1";
2649
            break;
2650
        default:
2651
            goto die;
2652
        }
2653
        break;
2654
    case 4:
2655
        switch (sel) {
2656
        case 0:
2657
            gen_op_mtc0_context();
2658
            rn = "Context";
2659
            break;
2660
        case 1:
2661
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2662
            rn = "ContextConfig";
2663
//            break;
2664
        default:
2665
            goto die;
2666
        }
2667
        break;
2668
    case 5:
2669
        switch (sel) {
2670
        case 0:
2671
            gen_op_mtc0_pagemask();
2672
            rn = "PageMask";
2673
            break;
2674
        case 1:
2675
            check_insn(env, ctx, ISA_MIPS32R2);
2676
            gen_op_mtc0_pagegrain();
2677
            rn = "PageGrain";
2678
            break;
2679
        default:
2680
            goto die;
2681
        }
2682
        break;
2683
    case 6:
2684
        switch (sel) {
2685
        case 0:
2686
            gen_op_mtc0_wired();
2687
            rn = "Wired";
2688
            break;
2689
        case 1:
2690
            check_insn(env, ctx, ISA_MIPS32R2);
2691
            gen_op_mtc0_srsconf0();
2692
            rn = "SRSConf0";
2693
            break;
2694
        case 2:
2695
            check_insn(env, ctx, ISA_MIPS32R2);
2696
            gen_op_mtc0_srsconf1();
2697
            rn = "SRSConf1";
2698
            break;
2699
        case 3:
2700
            check_insn(env, ctx, ISA_MIPS32R2);
2701
            gen_op_mtc0_srsconf2();
2702
            rn = "SRSConf2";
2703
            break;
2704
        case 4:
2705
            check_insn(env, ctx, ISA_MIPS32R2);
2706
            gen_op_mtc0_srsconf3();
2707
            rn = "SRSConf3";
2708
            break;
2709
        case 5:
2710
            check_insn(env, ctx, ISA_MIPS32R2);
2711
            gen_op_mtc0_srsconf4();
2712
            rn = "SRSConf4";
2713
            break;
2714
        default:
2715
            goto die;
2716
        }
2717
        break;
2718
    case 7:
2719
        switch (sel) {
2720
        case 0:
2721
            check_insn(env, ctx, ISA_MIPS32R2);
2722
            gen_op_mtc0_hwrena();
2723
            rn = "HWREna";
2724
            break;
2725
        default:
2726
            goto die;
2727
        }
2728
        break;
2729
    case 8:
2730
        /* ignored */
2731
        rn = "BadVaddr";
2732
        break;
2733
    case 9:
2734
        switch (sel) {
2735
        case 0:
2736
            gen_op_mtc0_count();
2737
            rn = "Count";
2738
            break;
2739
        /* 6,7 are implementation dependent */
2740
        default:
2741
            goto die;
2742
        }
2743
        /* Stop translation as we may have switched the execution mode */
2744
        ctx->bstate = BS_STOP;
2745
        break;
2746
    case 10:
2747
        switch (sel) {
2748
        case 0:
2749
            gen_op_mtc0_entryhi();
2750
            rn = "EntryHi";
2751
            break;
2752
        default:
2753
            goto die;
2754
        }
2755
        break;
2756
    case 11:
2757
        switch (sel) {
2758
        case 0:
2759
            gen_op_mtc0_compare();
2760
            rn = "Compare";
2761
            break;
2762
        /* 6,7 are implementation dependent */
2763
        default:
2764
            goto die;
2765
        }
2766
        /* Stop translation as we may have switched the execution mode */
2767
        ctx->bstate = BS_STOP;
2768
        break;
2769
    case 12:
2770
        switch (sel) {
2771
        case 0:
2772
            gen_op_mtc0_status();
2773
            /* BS_STOP isn't good enough here, hflags may have changed. */
2774
            gen_save_pc(ctx->pc + 4);
2775
            ctx->bstate = BS_EXCP;
2776
            rn = "Status";
2777
            break;
2778
        case 1:
2779
            check_insn(env, ctx, ISA_MIPS32R2);
2780
            gen_op_mtc0_intctl();
2781
            /* Stop translation as we may have switched the execution mode */
2782
            ctx->bstate = BS_STOP;
2783
            rn = "IntCtl";
2784
            break;
2785
        case 2:
2786
            check_insn(env, ctx, ISA_MIPS32R2);
2787
            gen_op_mtc0_srsctl();
2788
            /* Stop translation as we may have switched the execution mode */
2789
            ctx->bstate = BS_STOP;
2790
            rn = "SRSCtl";
2791
            break;
2792
        case 3:
2793
            check_insn(env, ctx, ISA_MIPS32R2);
2794
            gen_op_mtc0_srsmap();
2795
            /* Stop translation as we may have switched the execution mode */
2796
            ctx->bstate = BS_STOP;
2797
            rn = "SRSMap";
2798
            break;
2799
        default:
2800
            goto die;
2801
        }
2802
        break;
2803
    case 13:
2804
        switch (sel) {
2805
        case 0:
2806
            gen_op_mtc0_cause();
2807
            rn = "Cause";
2808
            break;
2809
        default:
2810
            goto die;
2811
        }
2812
        /* Stop translation as we may have switched the execution mode */
2813
        ctx->bstate = BS_STOP;
2814
        break;
2815
    case 14:
2816
        switch (sel) {
2817
        case 0:
2818
            gen_op_mtc0_epc();
2819
            rn = "EPC";
2820
            break;
2821
        default:
2822
            goto die;
2823
        }
2824
        break;
2825
    case 15:
2826
        switch (sel) {
2827
        case 0:
2828
            /* ignored */
2829
            rn = "PRid";
2830
            break;
2831
        case 1:
2832
            check_insn(env, ctx, ISA_MIPS32R2);
2833
            gen_op_mtc0_ebase();
2834
            rn = "EBase";
2835
            break;
2836
        default:
2837
            goto die;
2838
        }
2839
        break;
2840
    case 16:
2841
        switch (sel) {
2842
        case 0:
2843
            gen_op_mtc0_config0();
2844
            rn = "Config";
2845
            /* Stop translation as we may have switched the execution mode */
2846
            ctx->bstate = BS_STOP;
2847
            break;
2848
        case 1:
2849
            /* ignored, read only */
2850
            rn = "Config1";
2851
            break;
2852
        case 2:
2853
            gen_op_mtc0_config2();
2854
            rn = "Config2";
2855
            /* Stop translation as we may have switched the execution mode */
2856
            ctx->bstate = BS_STOP;
2857
            break;
2858
        case 3:
2859
            /* ignored, read only */
2860
            rn = "Config3";
2861
            break;
2862
        /* 4,5 are reserved */
2863
        /* 6,7 are implementation dependent */
2864
        case 6:
2865
            /* ignored */
2866
            rn = "Config6";
2867
            break;
2868
        case 7:
2869
            /* ignored */
2870
            rn = "Config7";
2871
            break;
2872
        default:
2873
            rn = "Invalid config selector";
2874
            goto die;
2875
        }
2876
        break;
2877
    case 17:
2878
        switch (sel) {
2879
        case 0:
2880
            /* ignored */
2881
            rn = "LLAddr";
2882
            break;
2883
        default:
2884
            goto die;
2885
        }
2886
        break;
2887
    case 18:
2888
        switch (sel) {
2889
        case 0 ... 7:
2890
            gen_op_mtc0_watchlo(sel);
2891
            rn = "WatchLo";
2892
            break;
2893
        default:
2894
            goto die;
2895
        }
2896
        break;
2897
    case 19:
2898
        switch (sel) {
2899
        case 0 ... 7:
2900
            gen_op_mtc0_watchhi(sel);
2901
            rn = "WatchHi";
2902
            break;
2903
        default:
2904
            goto die;
2905
        }
2906
        break;
2907
    case 20:
2908
        switch (sel) {
2909
        case 0:
2910
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
2911
            check_insn(env, ctx, ISA_MIPS3);
2912
            gen_op_mtc0_xcontext();
2913
            rn = "XContext";
2914
            break;
2915
#endif
2916
        default:
2917
            goto die;
2918
        }
2919
        break;
2920
    case 21:
2921
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2922
        switch (sel) {
2923
        case 0:
2924
            gen_op_mtc0_framemask();
2925
            rn = "Framemask";
2926
            break;
2927
        default:
2928
            goto die;
2929
        }
2930
        break;
2931
    case 22:
2932
        /* ignored */
2933
        rn = "Diagnostic"; /* implementation dependent */
2934
        break;
2935
    case 23:
2936
        switch (sel) {
2937
        case 0:
2938
            gen_op_mtc0_debug(); /* EJTAG support */
2939
            /* BS_STOP isn't good enough here, hflags may have changed. */
2940
            gen_save_pc(ctx->pc + 4);
2941
            ctx->bstate = BS_EXCP;
2942
            rn = "Debug";
2943
            break;
2944
        case 1:
2945
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2946
            rn = "TraceControl";
2947
            /* Stop translation as we may have switched the execution mode */
2948
            ctx->bstate = BS_STOP;
2949
//            break;
2950
        case 2:
2951
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2952
            rn = "TraceControl2";
2953
            /* Stop translation as we may have switched the execution mode */
2954
            ctx->bstate = BS_STOP;
2955
//            break;
2956
        case 3:
2957
            /* Stop translation as we may have switched the execution mode */
2958
            ctx->bstate = BS_STOP;
2959
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2960
            rn = "UserTraceData";
2961
            /* Stop translation as we may have switched the execution mode */
2962
            ctx->bstate = BS_STOP;
2963
//            break;
2964
        case 4:
2965
//            gen_op_mtc0_debug(); /* PDtrace support */
2966
            /* Stop translation as we may have switched the execution mode */
2967
            ctx->bstate = BS_STOP;
2968
            rn = "TraceBPC";
2969
//            break;
2970
        default:
2971
            goto die;
2972
        }
2973
        break;
2974
    case 24:
2975
        switch (sel) {
2976
        case 0:
2977
            gen_op_mtc0_depc(); /* EJTAG support */
2978
            rn = "DEPC";
2979
            break;
2980
        default:
2981
            goto die;
2982
        }
2983
        break;
2984
    case 25:
2985
        switch (sel) {
2986
        case 0:
2987
            gen_op_mtc0_performance0();
2988
            rn = "Performance0";
2989
            break;
2990
        case 1:
2991
//            gen_op_mtc0_performance1();
2992
            rn = "Performance1";
2993
//            break;
2994
        case 2:
2995
//            gen_op_mtc0_performance2();
2996
            rn = "Performance2";
2997
//            break;
2998
        case 3:
2999
//            gen_op_mtc0_performance3();
3000
            rn = "Performance3";
3001
//            break;
3002
        case 4:
3003
//            gen_op_mtc0_performance4();
3004
            rn = "Performance4";
3005
//            break;
3006
        case 5:
3007
//            gen_op_mtc0_performance5();
3008
            rn = "Performance5";
3009
//            break;
3010
        case 6:
3011
//            gen_op_mtc0_performance6();
3012
            rn = "Performance6";
3013
//            break;
3014
        case 7:
3015
//            gen_op_mtc0_performance7();
3016
            rn = "Performance7";
3017
//            break;
3018
        default:
3019
            goto die;
3020
        }
3021
       break;
3022
    case 26:
3023
        /* ignored */
3024
        rn = "ECC";
3025
        break;
3026
    case 27:
3027
        switch (sel) {
3028
        case 0 ... 3:
3029
            /* ignored */
3030
            rn = "CacheErr";
3031
            break;
3032
        default:
3033
            goto die;
3034
        }
3035
       break;
3036
    case 28:
3037
        switch (sel) {
3038
        case 0:
3039
        case 2:
3040
        case 4:
3041
        case 6:
3042
            gen_op_mtc0_taglo();
3043
            rn = "TagLo";
3044
            break;
3045
        case 1:
3046
        case 3:
3047
        case 5:
3048
        case 7:
3049
            gen_op_mtc0_datalo();
3050
            rn = "DataLo";
3051
            break;
3052
        default:
3053
            goto die;
3054
        }
3055
        break;
3056
    case 29:
3057
        switch (sel) {
3058
        case 0:
3059
        case 2:
3060
        case 4:
3061
        case 6:
3062
            gen_op_mtc0_taghi();
3063
            rn = "TagHi";
3064
            break;
3065
        case 1:
3066
        case 3:
3067
        case 5:
3068
        case 7:
3069
            gen_op_mtc0_datahi();
3070
            rn = "DataHi";
3071
            break;
3072
        default:
3073
            rn = "invalid sel";
3074
            goto die;
3075
        }
3076
       break;
3077
    case 30:
3078
        switch (sel) {
3079
        case 0:
3080
            gen_op_mtc0_errorepc();
3081
            rn = "ErrorEPC";
3082
            break;
3083
        default:
3084
            goto die;
3085
        }
3086
        break;
3087
    case 31:
3088
        switch (sel) {
3089
        case 0:
3090
            gen_op_mtc0_desave(); /* EJTAG support */
3091
            rn = "DESAVE";
3092
            break;
3093
        default:
3094
            goto die;
3095
        }
3096
        /* Stop translation as we may have switched the execution mode */
3097
        ctx->bstate = BS_STOP;
3098
        break;
3099
    default:
3100
       goto die;
3101
    }
3102
#if defined MIPS_DEBUG_DISAS
3103
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3104
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3105
                rn, reg, sel);
3106
    }
3107
#endif
3108
    return;
3109

    
3110
die:
3111
#if defined MIPS_DEBUG_DISAS
3112
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3113
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3114
                rn, reg, sel);
3115
    }
3116
#endif
3117
    generate_exception(ctx, EXCP_RI);
3118
}
3119

    
3120
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
3121
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3122
{
3123
    const char *rn = "invalid";
3124

    
3125
    if (sel != 0)
3126
        check_insn(env, ctx, ISA_MIPS64);
3127

    
3128
    switch (reg) {
3129
    case 0:
3130
        switch (sel) {
3131
        case 0:
3132
            gen_op_mfc0_index();
3133
            rn = "Index";
3134
            break;
3135
        case 1:
3136
            check_mips_mt(env, ctx);
3137
            gen_op_mfc0_mvpcontrol();
3138
            rn = "MVPControl";
3139
            break;
3140
        case 2:
3141
            check_mips_mt(env, ctx);
3142
            gen_op_mfc0_mvpconf0();
3143
            rn = "MVPConf0";
3144
            break;
3145
        case 3:
3146
            check_mips_mt(env, ctx);
3147
            gen_op_mfc0_mvpconf1();
3148
            rn = "MVPConf1";
3149
            break;
3150
        default:
3151
            goto die;
3152
        }
3153
        break;
3154
    case 1:
3155
        switch (sel) {
3156
        case 0:
3157
            gen_op_mfc0_random();
3158
            rn = "Random";
3159
            break;
3160
        case 1:
3161
            check_mips_mt(env, ctx);
3162
            gen_op_mfc0_vpecontrol();
3163
            rn = "VPEControl";
3164
            break;
3165
        case 2:
3166
            check_mips_mt(env, ctx);
3167
            gen_op_mfc0_vpeconf0();
3168
            rn = "VPEConf0";
3169
            break;
3170
        case 3:
3171
            check_mips_mt(env, ctx);
3172
            gen_op_mfc0_vpeconf1();
3173
            rn = "VPEConf1";
3174
            break;
3175
        case 4:
3176
            check_mips_mt(env, ctx);
3177
            gen_op_dmfc0_yqmask();
3178
            rn = "YQMask";
3179
            break;
3180
        case 5:
3181
            check_mips_mt(env, ctx);
3182
            gen_op_dmfc0_vpeschedule();
3183
            rn = "VPESchedule";
3184
            break;
3185
        case 6:
3186
            check_mips_mt(env, ctx);
3187
            gen_op_dmfc0_vpeschefback();
3188
            rn = "VPEScheFBack";
3189
            break;
3190
        case 7:
3191
            check_mips_mt(env, ctx);
3192
            gen_op_mfc0_vpeopt();
3193
            rn = "VPEOpt";
3194
            break;
3195
        default:
3196
            goto die;
3197
        }
3198
        break;
3199
    case 2:
3200
        switch (sel) {
3201
        case 0:
3202
            gen_op_dmfc0_entrylo0();
3203
            rn = "EntryLo0";
3204
            break;
3205
        case 1:
3206
            check_mips_mt(env, ctx);
3207
            gen_op_mfc0_tcstatus();
3208
            rn = "TCStatus";
3209
            break;
3210
        case 2:
3211
            check_mips_mt(env, ctx);
3212
            gen_op_mfc0_tcbind();
3213
            rn = "TCBind";
3214
            break;
3215
        case 3:
3216
            check_mips_mt(env, ctx);
3217
            gen_op_dmfc0_tcrestart();
3218
            rn = "TCRestart";
3219
            break;
3220
        case 4:
3221
            check_mips_mt(env, ctx);
3222
            gen_op_dmfc0_tchalt();
3223
            rn = "TCHalt";
3224
            break;
3225
        case 5:
3226
            check_mips_mt(env, ctx);
3227
            gen_op_dmfc0_tccontext();
3228
            rn = "TCContext";
3229
            break;
3230
        case 6:
3231
            check_mips_mt(env, ctx);
3232
            gen_op_dmfc0_tcschedule();
3233
            rn = "TCSchedule";
3234
            break;
3235
        case 7:
3236
            check_mips_mt(env, ctx);
3237
            gen_op_dmfc0_tcschefback();
3238
            rn = "TCScheFBack";
3239
            break;
3240
        default:
3241
            goto die;
3242
        }
3243
        break;
3244
    case 3:
3245
        switch (sel) {
3246
        case 0:
3247
            gen_op_dmfc0_entrylo1();
3248
            rn = "EntryLo1";
3249
            break;
3250
        default:
3251
            goto die;
3252
        }
3253
        break;
3254
    case 4:
3255
        switch (sel) {
3256
        case 0:
3257
            gen_op_dmfc0_context();
3258
            rn = "Context";
3259
            break;
3260
        case 1:
3261
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3262
            rn = "ContextConfig";
3263
//            break;
3264
        default:
3265
            goto die;
3266
        }
3267
        break;
3268
    case 5:
3269
        switch (sel) {
3270
        case 0:
3271
            gen_op_mfc0_pagemask();
3272
            rn = "PageMask";
3273
            break;
3274
        case 1:
3275
            check_insn(env, ctx, ISA_MIPS32R2);
3276
            gen_op_mfc0_pagegrain();
3277
            rn = "PageGrain";
3278
            break;
3279
        default:
3280
            goto die;
3281
        }
3282
        break;
3283
    case 6:
3284
        switch (sel) {
3285
        case 0:
3286
            gen_op_mfc0_wired();
3287
            rn = "Wired";
3288
            break;
3289
        case 1:
3290
            check_insn(env, ctx, ISA_MIPS32R2);
3291
            gen_op_mfc0_srsconf0();
3292
            rn = "SRSConf0";
3293
            break;
3294
        case 2:
3295
            check_insn(env, ctx, ISA_MIPS32R2);
3296
            gen_op_mfc0_srsconf1();
3297
            rn = "SRSConf1";
3298
            break;
3299
        case 3:
3300
            check_insn(env, ctx, ISA_MIPS32R2);
3301
            gen_op_mfc0_srsconf2();
3302
            rn = "SRSConf2";
3303
            break;
3304
        case 4:
3305
            check_insn(env, ctx, ISA_MIPS32R2);
3306
            gen_op_mfc0_srsconf3();
3307
            rn = "SRSConf3";
3308
            break;
3309
        case 5:
3310
            check_insn(env, ctx, ISA_MIPS32R2);
3311
            gen_op_mfc0_srsconf4();
3312
            rn = "SRSConf4";
3313
            break;
3314
        default:
3315
            goto die;
3316
        }
3317
        break;
3318
    case 7:
3319
        switch (sel) {
3320
        case 0:
3321
            check_insn(env, ctx, ISA_MIPS32R2);
3322
            gen_op_mfc0_hwrena();
3323
            rn = "HWREna";
3324
            break;
3325
        default:
3326
            goto die;
3327
        }
3328
        break;
3329
    case 8:
3330
        switch (sel) {
3331
        case 0:
3332
            gen_op_dmfc0_badvaddr();
3333
            rn = "BadVaddr";
3334
            break;
3335
        default:
3336
            goto die;
3337
        }
3338
        break;
3339
    case 9:
3340
        switch (sel) {
3341
        case 0:
3342
            gen_op_mfc0_count();
3343
            rn = "Count";
3344
            break;
3345
        /* 6,7 are implementation dependent */
3346
        default:
3347
            goto die;
3348
        }
3349
        break;
3350
    case 10:
3351
        switch (sel) {
3352
        case 0:
3353
            gen_op_dmfc0_entryhi();
3354
            rn = "EntryHi";
3355
            break;
3356
        default:
3357
            goto die;
3358
        }
3359
        break;
3360
    case 11:
3361
        switch (sel) {
3362
        case 0:
3363
            gen_op_mfc0_compare();
3364
            rn = "Compare";
3365
            break;
3366
        /* 6,7 are implementation dependent */
3367
        default:
3368
            goto die;
3369
        }
3370
        break;
3371
    case 12:
3372
        switch (sel) {
3373
        case 0:
3374
            gen_op_mfc0_status();
3375
            rn = "Status";
3376
            break;
3377
        case 1:
3378
            check_insn(env, ctx, ISA_MIPS32R2);
3379
            gen_op_mfc0_intctl();
3380
            rn = "IntCtl";
3381
            break;
3382
        case 2:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mfc0_srsctl();
3385
            rn = "SRSCtl";
3386
            break;
3387
        case 3:
3388
            check_insn(env, ctx, ISA_MIPS32R2);
3389
            gen_op_mfc0_srsmap();
3390
            rn = "SRSMap";
3391
            break;
3392
        default:
3393
            goto die;
3394
        }
3395
        break;
3396
    case 13:
3397
        switch (sel) {
3398
        case 0:
3399
            gen_op_mfc0_cause();
3400
            rn = "Cause";
3401
            break;
3402
        default:
3403
            goto die;
3404
        }
3405
        break;
3406
    case 14:
3407
        switch (sel) {
3408
        case 0:
3409
            gen_op_dmfc0_epc();
3410
            rn = "EPC";
3411
            break;
3412
        default:
3413
            goto die;
3414
        }
3415
        break;
3416
    case 15:
3417
        switch (sel) {
3418
        case 0:
3419
            gen_op_mfc0_prid();
3420
            rn = "PRid";
3421
            break;
3422
        case 1:
3423
            check_insn(env, ctx, ISA_MIPS32R2);
3424
            gen_op_mfc0_ebase();
3425
            rn = "EBase";
3426
            break;
3427
        default:
3428
            goto die;
3429
        }
3430
        break;
3431
    case 16:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mfc0_config0();
3435
            rn = "Config";
3436
            break;
3437
        case 1:
3438
            gen_op_mfc0_config1();
3439
            rn = "Config1";
3440
            break;
3441
        case 2:
3442
            gen_op_mfc0_config2();
3443
            rn = "Config2";
3444
            break;
3445
        case 3:
3446
            gen_op_mfc0_config3();
3447
            rn = "Config3";
3448
            break;
3449
       /* 6,7 are implementation dependent */
3450
        default:
3451
            goto die;
3452
        }
3453
        break;
3454
    case 17:
3455
        switch (sel) {
3456
        case 0:
3457
            gen_op_dmfc0_lladdr();
3458
            rn = "LLAddr";
3459
            break;
3460
        default:
3461
            goto die;
3462
        }
3463
        break;
3464
    case 18:
3465
        switch (sel) {
3466
        case 0 ... 7:
3467
            gen_op_dmfc0_watchlo(sel);
3468
            rn = "WatchLo";
3469
            break;
3470
        default:
3471
            goto die;
3472
        }
3473
        break;
3474
    case 19:
3475
        switch (sel) {
3476
        case 0 ... 7:
3477
            gen_op_mfc0_watchhi(sel);
3478
            rn = "WatchHi";
3479
            break;
3480
        default:
3481
            goto die;
3482
        }
3483
        break;
3484
    case 20:
3485
        switch (sel) {
3486
        case 0:
3487
            check_insn(env, ctx, ISA_MIPS3);
3488
            gen_op_dmfc0_xcontext();
3489
            rn = "XContext";
3490
            break;
3491
        default:
3492
            goto die;
3493
        }
3494
        break;
3495
    case 21:
3496
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3497
        switch (sel) {
3498
        case 0:
3499
            gen_op_mfc0_framemask();
3500
            rn = "Framemask";
3501
            break;
3502
        default:
3503
            goto die;
3504
        }
3505
        break;
3506
    case 22:
3507
        /* ignored */
3508
        rn = "'Diagnostic"; /* implementation dependent */
3509
        break;
3510
    case 23:
3511
        switch (sel) {
3512
        case 0:
3513
            gen_op_mfc0_debug(); /* EJTAG support */
3514
            rn = "Debug";
3515
            break;
3516
        case 1:
3517
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3518
            rn = "TraceControl";
3519
//            break;
3520
        case 2:
3521
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3522
            rn = "TraceControl2";
3523
//            break;
3524
        case 3:
3525
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3526
            rn = "UserTraceData";
3527
//            break;
3528
        case 4:
3529
//            gen_op_dmfc0_debug(); /* PDtrace support */
3530
            rn = "TraceBPC";
3531
//            break;
3532
        default:
3533
            goto die;
3534
        }
3535
        break;
3536
    case 24:
3537
        switch (sel) {
3538
        case 0:
3539
            gen_op_dmfc0_depc(); /* EJTAG support */
3540
            rn = "DEPC";
3541
            break;
3542
        default:
3543
            goto die;
3544
        }
3545
        break;
3546
    case 25:
3547
        switch (sel) {
3548
        case 0:
3549
            gen_op_mfc0_performance0();
3550
            rn = "Performance0";
3551
            break;
3552
        case 1:
3553
//            gen_op_dmfc0_performance1();
3554
            rn = "Performance1";
3555
//            break;
3556
        case 2:
3557
//            gen_op_dmfc0_performance2();
3558
            rn = "Performance2";
3559
//            break;
3560
        case 3:
3561
//            gen_op_dmfc0_performance3();
3562
            rn = "Performance3";
3563
//            break;
3564
        case 4:
3565
//            gen_op_dmfc0_performance4();
3566
            rn = "Performance4";
3567
//            break;
3568
        case 5:
3569
//            gen_op_dmfc0_performance5();
3570
            rn = "Performance5";
3571
//            break;
3572
        case 6:
3573
//            gen_op_dmfc0_performance6();
3574
            rn = "Performance6";
3575
//            break;
3576
        case 7:
3577
//            gen_op_dmfc0_performance7();
3578
            rn = "Performance7";
3579
//            break;
3580
        default:
3581
            goto die;
3582
        }
3583
        break;
3584
    case 26:
3585
       rn = "ECC";
3586
       break;
3587
    case 27:
3588
        switch (sel) {
3589
        /* ignored */
3590
        case 0 ... 3:
3591
            rn = "CacheErr";
3592
            break;
3593
        default:
3594
            goto die;
3595
        }
3596
        break;
3597
    case 28:
3598
        switch (sel) {
3599
        case 0:
3600
        case 2:
3601
        case 4:
3602
        case 6:
3603
            gen_op_mfc0_taglo();
3604
            rn = "TagLo";
3605
            break;
3606
        case 1:
3607
        case 3:
3608
        case 5:
3609
        case 7:
3610
            gen_op_mfc0_datalo();
3611
            rn = "DataLo";
3612
            break;
3613
        default:
3614
            goto die;
3615
        }
3616
        break;
3617
    case 29:
3618
        switch (sel) {
3619
        case 0:
3620
        case 2:
3621
        case 4:
3622
        case 6:
3623
            gen_op_mfc0_taghi();
3624
            rn = "TagHi";
3625
            break;
3626
        case 1:
3627
        case 3:
3628
        case 5:
3629
        case 7:
3630
            gen_op_mfc0_datahi();
3631
            rn = "DataHi";
3632
            break;
3633
        default:
3634
            goto die;
3635
        }
3636
        break;
3637
    case 30:
3638
        switch (sel) {
3639
        case 0:
3640
            gen_op_dmfc0_errorepc();
3641
            rn = "ErrorEPC";
3642
            break;
3643
        default:
3644
            goto die;
3645
        }
3646
        break;
3647
    case 31:
3648
        switch (sel) {
3649
        case 0:
3650
            gen_op_mfc0_desave(); /* EJTAG support */
3651
            rn = "DESAVE";
3652
            break;
3653
        default:
3654
            goto die;
3655
        }
3656
        break;
3657
    default:
3658
        goto die;
3659
    }
3660
#if defined MIPS_DEBUG_DISAS
3661
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3662
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3663
                rn, reg, sel);
3664
    }
3665
#endif
3666
    return;
3667

    
3668
die:
3669
#if defined MIPS_DEBUG_DISAS
3670
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3671
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3672
                rn, reg, sel);
3673
    }
3674
#endif
3675
    generate_exception(ctx, EXCP_RI);
3676
}
3677

    
3678
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3679
{
3680
    const char *rn = "invalid";
3681

    
3682
    if (sel != 0)
3683
        check_insn(env, ctx, ISA_MIPS64);
3684

    
3685
    switch (reg) {
3686
    case 0:
3687
        switch (sel) {
3688
        case 0:
3689
            gen_op_mtc0_index();
3690
            rn = "Index";
3691
            break;
3692
        case 1:
3693
            check_mips_mt(env, ctx);
3694
            gen_op_mtc0_mvpcontrol();
3695
            rn = "MVPControl";
3696
            break;
3697
        case 2:
3698
            check_mips_mt(env, ctx);
3699
            /* ignored */
3700
            rn = "MVPConf0";
3701
            break;
3702
        case 3:
3703
            check_mips_mt(env, ctx);
3704
            /* ignored */
3705
            rn = "MVPConf1";
3706
            break;
3707
        default:
3708
            goto die;
3709
        }
3710
        break;
3711
    case 1:
3712
        switch (sel) {
3713
        case 0:
3714
            /* ignored */
3715
            rn = "Random";
3716
            break;
3717
        case 1:
3718
            check_mips_mt(env, ctx);
3719
            gen_op_mtc0_vpecontrol();
3720
            rn = "VPEControl";
3721
            break;
3722
        case 2:
3723
            check_mips_mt(env, ctx);
3724
            gen_op_mtc0_vpeconf0();
3725
            rn = "VPEConf0";
3726
            break;
3727
        case 3:
3728
            check_mips_mt(env, ctx);
3729
            gen_op_mtc0_vpeconf1();
3730
            rn = "VPEConf1";
3731
            break;
3732
        case 4:
3733
            check_mips_mt(env, ctx);
3734
            gen_op_mtc0_yqmask();
3735
            rn = "YQMask";
3736
            break;
3737
        case 5:
3738
            check_mips_mt(env, ctx);
3739
            gen_op_mtc0_vpeschedule();
3740
            rn = "VPESchedule";
3741
            break;
3742
        case 6:
3743
            check_mips_mt(env, ctx);
3744
            gen_op_mtc0_vpeschefback();
3745
            rn = "VPEScheFBack";
3746
            break;
3747
        case 7:
3748
            check_mips_mt(env, ctx);
3749
            gen_op_mtc0_vpeopt();
3750
            rn = "VPEOpt";
3751
            break;
3752
        default:
3753
            goto die;
3754
        }
3755
        break;
3756
    case 2:
3757
        switch (sel) {
3758
        case 0:
3759
            gen_op_mtc0_entrylo0();
3760
            rn = "EntryLo0";
3761
            break;
3762
        case 1:
3763
            check_mips_mt(env, ctx);
3764
            gen_op_mtc0_tcstatus();
3765
            rn = "TCStatus";
3766
            break;
3767
        case 2:
3768
            check_mips_mt(env, ctx);
3769
            gen_op_mtc0_tcbind();
3770
            rn = "TCBind";
3771
            break;
3772
        case 3:
3773
            check_mips_mt(env, ctx);
3774
            gen_op_mtc0_tcrestart();
3775
            rn = "TCRestart";
3776
            break;
3777
        case 4:
3778
            check_mips_mt(env, ctx);
3779
            gen_op_mtc0_tchalt();
3780
            rn = "TCHalt";
3781
            break;
3782
        case 5:
3783
            check_mips_mt(env, ctx);
3784
            gen_op_mtc0_tccontext();
3785
            rn = "TCContext";
3786
            break;
3787
        case 6:
3788
            check_mips_mt(env, ctx);
3789
            gen_op_mtc0_tcschedule();
3790
            rn = "TCSchedule";
3791
            break;
3792
        case 7:
3793
            check_mips_mt(env, ctx);
3794
            gen_op_mtc0_tcschefback();
3795
            rn = "TCScheFBack";
3796
            break;
3797
        default:
3798
            goto die;
3799
        }
3800
        break;
3801
    case 3:
3802
        switch (sel) {
3803
        case 0:
3804
            gen_op_mtc0_entrylo1();
3805
            rn = "EntryLo1";
3806
            break;
3807
        default:
3808
            goto die;
3809
        }
3810
        break;
3811
    case 4:
3812
        switch (sel) {
3813
        case 0:
3814
            gen_op_mtc0_context();
3815
            rn = "Context";
3816
            break;
3817
        case 1:
3818
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3819
            rn = "ContextConfig";
3820
//           break;
3821
        default:
3822
            goto die;
3823
        }
3824
        break;
3825
    case 5:
3826
        switch (sel) {
3827
        case 0:
3828
            gen_op_mtc0_pagemask();
3829
            rn = "PageMask";
3830
            break;
3831
        case 1:
3832
            check_insn(env, ctx, ISA_MIPS32R2);
3833
            gen_op_mtc0_pagegrain();
3834
            rn = "PageGrain";
3835
            break;
3836
        default:
3837
            goto die;
3838
        }
3839
        break;
3840
    case 6:
3841
        switch (sel) {
3842
        case 0:
3843
            gen_op_mtc0_wired();
3844
            rn = "Wired";
3845
            break;
3846
        case 1:
3847
            check_insn(env, ctx, ISA_MIPS32R2);
3848
            gen_op_mtc0_srsconf0();
3849
            rn = "SRSConf0";
3850
            break;
3851
        case 2:
3852
            check_insn(env, ctx, ISA_MIPS32R2);
3853
            gen_op_mtc0_srsconf1();
3854
            rn = "SRSConf1";
3855
            break;
3856
        case 3:
3857
            check_insn(env, ctx, ISA_MIPS32R2);
3858
            gen_op_mtc0_srsconf2();
3859
            rn = "SRSConf2";
3860
            break;
3861
        case 4:
3862
            check_insn(env, ctx, ISA_MIPS32R2);
3863
            gen_op_mtc0_srsconf3();
3864
            rn = "SRSConf3";
3865
            break;
3866
        case 5:
3867
            check_insn(env, ctx, ISA_MIPS32R2);
3868
            gen_op_mtc0_srsconf4();
3869
            rn = "SRSConf4";
3870
            break;
3871
        default:
3872
            goto die;
3873
        }
3874
        break;
3875
    case 7:
3876
        switch (sel) {
3877
        case 0:
3878
            check_insn(env, ctx, ISA_MIPS32R2);
3879
            gen_op_mtc0_hwrena();
3880
            rn = "HWREna";
3881
            break;
3882
        default:
3883
            goto die;
3884
        }
3885
        break;
3886
    case 8:
3887
        /* ignored */
3888
        rn = "BadVaddr";
3889
        break;
3890
    case 9:
3891
        switch (sel) {
3892
        case 0:
3893
            gen_op_mtc0_count();
3894
            rn = "Count";
3895
            break;
3896
        /* 6,7 are implementation dependent */
3897
        default:
3898
            goto die;
3899
        }
3900
        /* Stop translation as we may have switched the execution mode */
3901
        ctx->bstate = BS_STOP;
3902
        break;
3903
    case 10:
3904
        switch (sel) {
3905
        case 0:
3906
            gen_op_mtc0_entryhi();
3907
            rn = "EntryHi";
3908
            break;
3909
        default:
3910
            goto die;
3911
        }
3912
        break;
3913
    case 11:
3914
        switch (sel) {
3915
        case 0:
3916
            gen_op_mtc0_compare();
3917
            rn = "Compare";
3918
            break;
3919
        /* 6,7 are implementation dependent */
3920
        default:
3921
            goto die;
3922
        }
3923
        /* Stop translation as we may have switched the execution mode */
3924
        ctx->bstate = BS_STOP;
3925
        break;
3926
    case 12:
3927
        switch (sel) {
3928
        case 0:
3929
            gen_op_mtc0_status();
3930
            /* BS_STOP isn't good enough here, hflags may have changed. */
3931
            gen_save_pc(ctx->pc + 4);
3932
            ctx->bstate = BS_EXCP;
3933
            rn = "Status";
3934
            break;
3935
        case 1:
3936
            check_insn(env, ctx, ISA_MIPS32R2);
3937
            gen_op_mtc0_intctl();
3938
            /* Stop translation as we may have switched the execution mode */
3939
            ctx->bstate = BS_STOP;
3940
            rn = "IntCtl";
3941
            break;
3942
        case 2:
3943
            check_insn(env, ctx, ISA_MIPS32R2);
3944
            gen_op_mtc0_srsctl();
3945
            /* Stop translation as we may have switched the execution mode */
3946
            ctx->bstate = BS_STOP;
3947
            rn = "SRSCtl";
3948
            break;
3949
        case 3:
3950
            check_insn(env, ctx, ISA_MIPS32R2);
3951
            gen_op_mtc0_srsmap();
3952
            /* Stop translation as we may have switched the execution mode */
3953
            ctx->bstate = BS_STOP;
3954
            rn = "SRSMap";
3955
            break;
3956
        default:
3957
            goto die;
3958
        }
3959
        break;
3960
    case 13:
3961
        switch (sel) {
3962
        case 0:
3963
            gen_op_mtc0_cause();
3964
            rn = "Cause";
3965
            break;
3966
        default:
3967
            goto die;
3968
        }
3969
        /* Stop translation as we may have switched the execution mode */
3970
        ctx->bstate = BS_STOP;
3971
        break;
3972
    case 14:
3973
        switch (sel) {
3974
        case 0:
3975
            gen_op_mtc0_epc();
3976
            rn = "EPC";
3977
            break;
3978
        default:
3979
            goto die;
3980
        }
3981
        break;
3982
    case 15:
3983
        switch (sel) {
3984
        case 0:
3985
            /* ignored */
3986
            rn = "PRid";
3987
            break;
3988
        case 1:
3989
            check_insn(env, ctx, ISA_MIPS32R2);
3990
            gen_op_mtc0_ebase();
3991
            rn = "EBase";
3992
            break;
3993
        default:
3994
            goto die;
3995
        }
3996
        break;
3997
    case 16:
3998
        switch (sel) {
3999
        case 0:
4000
            gen_op_mtc0_config0();
4001
            rn = "Config";
4002
            /* Stop translation as we may have switched the execution mode */
4003
            ctx->bstate = BS_STOP;
4004
            break;
4005
        case 1:
4006
            /* ignored */
4007
            rn = "Config1";
4008
            break;
4009
        case 2:
4010
            gen_op_mtc0_config2();
4011
            rn = "Config2";
4012
            /* Stop translation as we may have switched the execution mode */
4013
            ctx->bstate = BS_STOP;
4014
            break;
4015
        case 3:
4016
            /* ignored */
4017
            rn = "Config3";
4018
            break;
4019
        /* 6,7 are implementation dependent */
4020
        default:
4021
            rn = "Invalid config selector";
4022
            goto die;
4023
        }
4024
        break;
4025
    case 17:
4026
        switch (sel) {
4027
        case 0:
4028
            /* ignored */
4029
            rn = "LLAddr";
4030
            break;
4031
        default:
4032
            goto die;
4033
        }
4034
        break;
4035
    case 18:
4036
        switch (sel) {
4037
        case 0 ... 7:
4038
            gen_op_mtc0_watchlo(sel);
4039
            rn = "WatchLo";
4040
            break;
4041
        default:
4042
            goto die;
4043
        }
4044
        break;
4045
    case 19:
4046
        switch (sel) {
4047
        case 0 ... 7:
4048
            gen_op_mtc0_watchhi(sel);
4049
            rn = "WatchHi";
4050
            break;
4051
        default:
4052
            goto die;
4053
        }
4054
        break;
4055
    case 20:
4056
        switch (sel) {
4057
        case 0:
4058
            check_insn(env, ctx, ISA_MIPS3);
4059
            gen_op_mtc0_xcontext();
4060
            rn = "XContext";
4061
            break;
4062
        default:
4063
            goto die;
4064
        }
4065
        break;
4066
    case 21:
4067
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4068
        switch (sel) {
4069
        case 0:
4070
            gen_op_mtc0_framemask();
4071
            rn = "Framemask";
4072
            break;
4073
        default:
4074
            goto die;
4075
        }
4076
        break;
4077
    case 22:
4078
        /* ignored */
4079
        rn = "Diagnostic"; /* implementation dependent */
4080
        break;
4081
    case 23:
4082
        switch (sel) {
4083
        case 0:
4084
            gen_op_mtc0_debug(); /* EJTAG support */
4085
            /* BS_STOP isn't good enough here, hflags may have changed. */
4086
            gen_save_pc(ctx->pc + 4);
4087
            ctx->bstate = BS_EXCP;
4088
            rn = "Debug";
4089
            break;
4090
        case 1:
4091
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4092
            /* Stop translation as we may have switched the execution mode */
4093
            ctx->bstate = BS_STOP;
4094
            rn = "TraceControl";
4095
//            break;
4096
        case 2:
4097
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4098
            /* Stop translation as we may have switched the execution mode */
4099
            ctx->bstate = BS_STOP;
4100
            rn = "TraceControl2";
4101
//            break;
4102
        case 3:
4103
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4104
            /* Stop translation as we may have switched the execution mode */
4105
            ctx->bstate = BS_STOP;
4106
            rn = "UserTraceData";
4107
//            break;
4108
        case 4:
4109
//            gen_op_mtc0_debug(); /* PDtrace support */
4110
            /* Stop translation as we may have switched the execution mode */
4111
            ctx->bstate = BS_STOP;
4112
            rn = "TraceBPC";
4113
//            break;
4114
        default:
4115
            goto die;
4116
        }
4117
        break;
4118
    case 24:
4119
        switch (sel) {
4120
        case 0:
4121
            gen_op_mtc0_depc(); /* EJTAG support */
4122
            rn = "DEPC";
4123
            break;
4124
        default:
4125
            goto die;
4126
        }
4127
        break;
4128
    case 25:
4129
        switch (sel) {
4130
        case 0:
4131
            gen_op_mtc0_performance0();
4132
            rn = "Performance0";
4133
            break;
4134
        case 1:
4135
//            gen_op_mtc0_performance1();
4136
            rn = "Performance1";
4137
//            break;
4138
        case 2:
4139
//            gen_op_mtc0_performance2();
4140
            rn = "Performance2";
4141
//            break;
4142
        case 3:
4143
//            gen_op_mtc0_performance3();
4144
            rn = "Performance3";
4145
//            break;
4146
        case 4:
4147
//            gen_op_mtc0_performance4();
4148
            rn = "Performance4";
4149
//            break;
4150
        case 5:
4151
//            gen_op_mtc0_performance5();
4152
            rn = "Performance5";
4153
//            break;
4154
        case 6:
4155
//            gen_op_mtc0_performance6();
4156
            rn = "Performance6";
4157
//            break;
4158
        case 7:
4159
//            gen_op_mtc0_performance7();
4160
            rn = "Performance7";
4161
//            break;
4162
        default:
4163
            goto die;
4164
        }
4165
        break;
4166
    case 26:
4167
        /* ignored */
4168
        rn = "ECC";
4169
        break;
4170
    case 27:
4171
        switch (sel) {
4172
        case 0 ... 3:
4173
            /* ignored */
4174
            rn = "CacheErr";
4175
            break;
4176
        default:
4177
            goto die;
4178
        }
4179
        break;
4180
    case 28:
4181
        switch (sel) {
4182
        case 0:
4183
        case 2:
4184
        case 4:
4185
        case 6:
4186
            gen_op_mtc0_taglo();
4187
            rn = "TagLo";
4188
            break;
4189
        case 1:
4190
        case 3:
4191
        case 5:
4192
        case 7:
4193
            gen_op_mtc0_datalo();
4194
            rn = "DataLo";
4195
            break;
4196
        default:
4197
            goto die;
4198
        }
4199
        break;
4200
    case 29:
4201
        switch (sel) {
4202
        case 0:
4203
        case 2:
4204
        case 4:
4205
        case 6:
4206
            gen_op_mtc0_taghi();
4207
            rn = "TagHi";
4208
            break;
4209
        case 1:
4210
        case 3:
4211
        case 5:
4212
        case 7:
4213
            gen_op_mtc0_datahi();
4214
            rn = "DataHi";
4215
            break;
4216
        default:
4217
            rn = "invalid sel";
4218
            goto die;
4219
        }
4220
        break;
4221
    case 30:
4222
        switch (sel) {
4223
        case 0:
4224
            gen_op_mtc0_errorepc();
4225
            rn = "ErrorEPC";
4226
            break;
4227
        default:
4228
            goto die;
4229
        }
4230
        break;
4231
    case 31:
4232
        switch (sel) {
4233
        case 0:
4234
            gen_op_mtc0_desave(); /* EJTAG support */
4235
            rn = "DESAVE";
4236
            break;
4237
        default:
4238
            goto die;
4239
        }
4240
        /* Stop translation as we may have switched the execution mode */
4241
        ctx->bstate = BS_STOP;
4242
        break;
4243
    default:
4244
        goto die;
4245
    }
4246
#if defined MIPS_DEBUG_DISAS
4247
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4248
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4249
                rn, reg, sel);
4250
    }
4251
#endif
4252
    return;
4253

    
4254
die:
4255
#if defined MIPS_DEBUG_DISAS
4256
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4257
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4258
                rn, reg, sel);
4259
    }
4260
#endif
4261
    generate_exception(ctx, EXCP_RI);
4262
}
4263
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
4264

    
4265
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4266
                     int u, int sel, int h)
4267
{
4268
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4269

    
4270
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4271
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4272
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4273
        gen_op_set_T0(-1);
4274
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4275
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4276
        gen_op_set_T0(-1);
4277
    else if (u == 0) {
4278
        switch (rt) {
4279
        case 2:
4280
            switch (sel) {
4281
            case 1:
4282
                gen_op_mftc0_tcstatus();
4283
                break;
4284
            case 2:
4285
                gen_op_mftc0_tcbind();
4286
                break;
4287
            case 3:
4288
                gen_op_mftc0_tcrestart();
4289
                break;
4290
            case 4:
4291
                gen_op_mftc0_tchalt();
4292
                break;
4293
            case 5:
4294
                gen_op_mftc0_tccontext();
4295
                break;
4296
            case 6:
4297
                gen_op_mftc0_tcschedule();
4298
                break;
4299
            case 7:
4300
                gen_op_mftc0_tcschefback();
4301
                break;
4302
            default:
4303
                gen_mfc0(env, ctx, rt, sel);
4304
                break;
4305
            }
4306
            break;
4307
        case 10:
4308
            switch (sel) {
4309
            case 0:
4310
                gen_op_mftc0_entryhi();
4311
                break;
4312
            default:
4313
                gen_mfc0(env, ctx, rt, sel);
4314
                break;
4315
            }
4316
        case 12:
4317
            switch (sel) {
4318
            case 0:
4319
                gen_op_mftc0_status();
4320
                break;
4321
            default:
4322
                gen_mfc0(env, ctx, rt, sel);
4323
                break;
4324
            }
4325
        case 23:
4326
            switch (sel) {
4327
            case 0:
4328
                gen_op_mftc0_debug();
4329
                break;
4330
            default:
4331
                gen_mfc0(env, ctx, rt, sel);
4332
                break;
4333
            }
4334
            break;
4335
        default:
4336
            gen_mfc0(env, ctx, rt, sel);
4337
        }
4338
    } else switch (sel) {
4339
    /* GPR registers. */
4340
    case 0:
4341
        gen_op_mftgpr(rt);
4342
        break;
4343
    /* Auxiliary CPU registers */
4344
    case 1:
4345
        switch (rt) {
4346
        case 0:
4347
            gen_op_mftlo(0);
4348
            break;
4349
        case 1:
4350
            gen_op_mfthi(0);
4351
            break;
4352
        case 2:
4353
            gen_op_mftacx(0);
4354
            break;
4355
        case 4:
4356
            gen_op_mftlo(1);
4357
            break;
4358
        case 5:
4359
            gen_op_mfthi(1);
4360
            break;
4361
        case 6:
4362
            gen_op_mftacx(1);
4363
            break;
4364
        case 8:
4365
            gen_op_mftlo(2);
4366
            break;
4367
        case 9:
4368
            gen_op_mfthi(2);
4369
            break;
4370
        case 10:
4371
            gen_op_mftacx(2);
4372
            break;
4373
        case 12:
4374
            gen_op_mftlo(3);
4375
            break;
4376
        case 13:
4377
            gen_op_mfthi(3);
4378
            break;
4379
        case 14:
4380
            gen_op_mftacx(3);
4381
            break;
4382
        case 16:
4383
            gen_op_mftdsp();
4384
            break;
4385
        default:
4386
            goto die;
4387
        }
4388
        break;
4389
    /* Floating point (COP1). */
4390
    case 2:
4391
        /* XXX: For now we support only a single FPU context. */
4392
        if (h == 0) {
4393
            GEN_LOAD_FREG_FTN(WT0, rt);
4394
            gen_op_mfc1();
4395
        } else {
4396
            GEN_LOAD_FREG_FTN(WTH0, rt);
4397
            gen_op_mfhc1();
4398
        }
4399
        break;
4400
    case 3:
4401
        /* XXX: For now we support only a single FPU context. */
4402
        gen_op_cfc1(rt);
4403
        break;
4404
    /* COP2: Not implemented. */
4405
    case 4:
4406
    case 5:
4407
        /* fall through */
4408
    default:
4409
        goto die;
4410
    }
4411
#if defined MIPS_DEBUG_DISAS
4412
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4413
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4414
                rt, u, sel, h);
4415
    }
4416
#endif
4417
    return;
4418

    
4419
die:
4420
#if defined MIPS_DEBUG_DISAS
4421
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4422
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4423
                rt, u, sel, h);
4424
    }
4425
#endif
4426
    generate_exception(ctx, EXCP_RI);
4427
}
4428

    
4429
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4430
                     int u, int sel, int h)
4431
{
4432
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4433

    
4434
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4435
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4436
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4437
        /* NOP */ ;
4438
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4439
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4440
        /* NOP */ ;
4441
    else if (u == 0) {
4442
        switch (rd) {
4443
        case 2:
4444
            switch (sel) {
4445
            case 1:
4446
                gen_op_mttc0_tcstatus();
4447
                break;
4448
            case 2:
4449
                gen_op_mttc0_tcbind();
4450
                break;
4451
            case 3:
4452
                gen_op_mttc0_tcrestart();
4453
                break;
4454
            case 4:
4455
                gen_op_mttc0_tchalt();
4456
                break;
4457
            case 5:
4458
                gen_op_mttc0_tccontext();
4459
                break;
4460
            case 6:
4461
                gen_op_mttc0_tcschedule();
4462
                break;
4463
            case 7:
4464
                gen_op_mttc0_tcschefback();
4465
                break;
4466
            default:
4467
                gen_mtc0(env, ctx, rd, sel);
4468
                break;
4469
            }
4470
            break;
4471
        case 10:
4472
            switch (sel) {
4473
            case 0:
4474
                gen_op_mttc0_entryhi();
4475
                break;
4476
            default:
4477
                gen_mtc0(env, ctx, rd, sel);
4478
                break;
4479
            }
4480
        case 12:
4481
            switch (sel) {
4482
            case 0:
4483
                gen_op_mttc0_status();
4484
                break;
4485
            default:
4486
                gen_mtc0(env, ctx, rd, sel);
4487
                break;
4488
            }
4489
        case 23:
4490
            switch (sel) {
4491
            case 0:
4492
                gen_op_mttc0_debug();
4493
                break;
4494
            default:
4495
                gen_mtc0(env, ctx, rd, sel);
4496
                break;
4497
            }
4498
            break;
4499
        default:
4500
            gen_mtc0(env, ctx, rd, sel);
4501
        }
4502
    } else switch (sel) {
4503
    /* GPR registers. */
4504
    case 0:
4505
        gen_op_mttgpr(rd);
4506
        break;
4507
    /* Auxiliary CPU registers */
4508
    case 1:
4509
        switch (rd) {
4510
        case 0:
4511
            gen_op_mttlo(0);
4512
            break;
4513
        case 1:
4514
            gen_op_mtthi(0);
4515
            break;
4516
        case 2:
4517
            gen_op_mttacx(0);
4518
            break;
4519
        case 4:
4520
            gen_op_mttlo(1);
4521
            break;
4522
        case 5:
4523
            gen_op_mtthi(1);
4524
            break;
4525
        case 6:
4526
            gen_op_mttacx(1);
4527
            break;
4528
        case 8:
4529
            gen_op_mttlo(2);
4530
            break;
4531
        case 9:
4532
            gen_op_mtthi(2);
4533
            break;
4534
        case 10:
4535
            gen_op_mttacx(2);
4536
            break;
4537
        case 12:
4538
            gen_op_mttlo(3);
4539
            break;
4540
        case 13:
4541
            gen_op_mtthi(3);
4542
            break;
4543
        case 14:
4544
            gen_op_mttacx(3);
4545
            break;
4546
        case 16:
4547
            gen_op_mttdsp();
4548
            break;
4549
        default:
4550
            goto die;
4551
        }
4552
        break;
4553
    /* Floating point (COP1). */
4554
    case 2:
4555
        /* XXX: For now we support only a single FPU context. */
4556
        if (h == 0) {
4557
            gen_op_mtc1();
4558
            GEN_STORE_FTN_FREG(rd, WT0);
4559
        } else {
4560
            gen_op_mthc1();
4561
            GEN_STORE_FTN_FREG(rd, WTH0);
4562
        }
4563
        break;
4564
    case 3:
4565
        /* XXX: For now we support only a single FPU context. */
4566
        gen_op_ctc1(rd);
4567
        break;
4568
    /* COP2: Not implemented. */
4569
    case 4:
4570
    case 5:
4571
        /* fall through */
4572
    default:
4573
        goto die;
4574
    }
4575
#if defined MIPS_DEBUG_DISAS
4576
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4577
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4578
                rd, u, sel, h);
4579
    }
4580
#endif
4581
    return;
4582

    
4583
die:
4584
#if defined MIPS_DEBUG_DISAS
4585
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4586
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4587
                rd, u, sel, h);
4588
    }
4589
#endif
4590
    generate_exception(ctx, EXCP_RI);
4591
}
4592

    
4593
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4594
{
4595
    const char *opn = "ldst";
4596

    
4597
    switch (opc) {
4598
    case OPC_MFC0:
4599
        if (rt == 0) {
4600
            /* Treat as NOP. */
4601
            return;
4602
        }
4603
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4604
        gen_op_store_T0_gpr(rt);
4605
        opn = "mfc0";
4606
        break;
4607
    case OPC_MTC0:
4608
        GEN_LOAD_REG_TN(T0, rt);
4609
        save_cpu_state(ctx, 1);
4610
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4611
        opn = "mtc0";
4612
        break;
4613
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
4614
    case OPC_DMFC0:
4615
        check_insn(env, ctx, ISA_MIPS3);
4616
        if (rt == 0) {
4617
            /* Treat as NOP. */
4618
            return;
4619
        }
4620
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4621
        gen_op_store_T0_gpr(rt);
4622
        opn = "dmfc0";
4623
        break;
4624
    case OPC_DMTC0:
4625
        check_insn(env, ctx, ISA_MIPS3);
4626
        GEN_LOAD_REG_TN(T0, rt);
4627
        save_cpu_state(ctx, 1);
4628
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4629
        opn = "dmtc0";
4630
        break;
4631
#endif
4632
    case OPC_MFTR:
4633
        check_mips_mt(env, ctx);
4634
        if (rd == 0) {
4635
            /* Treat as NOP. */
4636
            return;
4637
        }
4638
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4639
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4640
        gen_op_store_T0_gpr(rd);
4641
        opn = "mftr";
4642
        break;
4643
    case OPC_MTTR:
4644
        check_mips_mt(env, ctx);
4645
        GEN_LOAD_REG_TN(T0, rt);
4646
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4647
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4648
        opn = "mttr";
4649
        break;
4650
    case OPC_TLBWI:
4651
        opn = "tlbwi";
4652
        if (!env->tlb->do_tlbwi)
4653
            goto die;
4654
        gen_op_tlbwi();
4655
        break;
4656
    case OPC_TLBWR:
4657
        opn = "tlbwr";
4658
        if (!env->tlb->do_tlbwr)
4659
            goto die;
4660
        gen_op_tlbwr();
4661
        break;
4662
    case OPC_TLBP:
4663
        opn = "tlbp";
4664
        if (!env->tlb->do_tlbp)
4665
            goto die;
4666
        gen_op_tlbp();
4667
        break;
4668
    case OPC_TLBR:
4669
        opn = "tlbr";
4670
        if (!env->tlb->do_tlbr)
4671
            goto die;
4672
        gen_op_tlbr();
4673
        break;
4674
    case OPC_ERET:
4675
        opn = "eret";
4676
        check_insn(env, ctx, ISA_MIPS2);
4677
        save_cpu_state(ctx, 1);
4678
        gen_op_eret();
4679
        ctx->bstate = BS_EXCP;
4680
        break;
4681
    case OPC_DERET:
4682
        opn = "deret";
4683
        check_insn(env, ctx, ISA_MIPS32);
4684
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4685
            MIPS_INVAL(opn);
4686
            generate_exception(ctx, EXCP_RI);
4687
        } else {
4688
            save_cpu_state(ctx, 1);
4689
            gen_op_deret();
4690
            ctx->bstate = BS_EXCP;
4691
        }
4692
        break;
4693
    case OPC_WAIT:
4694
        opn = "wait";
4695
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4696
        /* If we get an exception, we want to restart at next instruction */
4697
        ctx->pc += 4;
4698
        save_cpu_state(ctx, 1);
4699
        ctx->pc -= 4;
4700
        gen_op_wait();
4701
        ctx->bstate = BS_EXCP;
4702
        break;
4703
    default:
4704
 die:
4705
        MIPS_INVAL(opn);
4706
        generate_exception(ctx, EXCP_RI);
4707
        return;
4708
    }
4709
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4710
}
4711

    
4712
/* CP1 Branches (before delay slot) */
4713
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4714
                                 int32_t cc, int32_t offset)
4715
{
4716
    target_ulong btarget;
4717
    const char *opn = "cp1 cond branch";
4718

    
4719
    if (cc != 0)
4720
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4721

    
4722
    btarget = ctx->pc + 4 + offset;
4723

    
4724
    switch (op) {
4725
    case OPC_BC1F:
4726
        gen_op_bc1f(cc);
4727
        opn = "bc1f";
4728
        goto not_likely;
4729
    case OPC_BC1FL:
4730
        gen_op_bc1f(cc);
4731
        opn = "bc1fl";
4732
        goto likely;
4733
    case OPC_BC1T:
4734
        gen_op_bc1t(cc);
4735
        opn = "bc1t";
4736
        goto not_likely;
4737
    case OPC_BC1TL:
4738
        gen_op_bc1t(cc);
4739
        opn = "bc1tl";
4740
    likely:
4741
        ctx->hflags |= MIPS_HFLAG_BL;
4742
        gen_op_set_bcond();
4743
        gen_op_save_bcond();
4744
        break;
4745
    case OPC_BC1FANY2:
4746
        gen_op_bc1any2f(cc);
4747
        opn = "bc1any2f";
4748
        goto not_likely;
4749
    case OPC_BC1TANY2:
4750
        gen_op_bc1any2t(cc);
4751
        opn = "bc1any2t";
4752
        goto not_likely;
4753
    case OPC_BC1FANY4:
4754
        gen_op_bc1any4f(cc);
4755
        opn = "bc1any4f";
4756
        goto not_likely;
4757
    case OPC_BC1TANY4:
4758
        gen_op_bc1any4t(cc);
4759
        opn = "bc1any4t";
4760
    not_likely:
4761
        ctx->hflags |= MIPS_HFLAG_BC;
4762
        gen_op_set_bcond();
4763
        break;
4764
    default:
4765
        MIPS_INVAL(opn);
4766
        generate_exception (ctx, EXCP_RI);
4767
        return;
4768
    }
4769
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4770
               ctx->hflags, btarget);
4771
    ctx->btarget = btarget;
4772
}
4773

    
4774
/* Coprocessor 1 (FPU) */
4775

    
4776
#define FOP(func, fmt) (((fmt) << 21) | (func))
4777

    
4778
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4779
{
4780
    const char *opn = "cp1 move";
4781

    
4782
    switch (opc) {
4783
    case OPC_MFC1:
4784
        GEN_LOAD_FREG_FTN(WT0, fs);
4785
        gen_op_mfc1();
4786
        GEN_STORE_TN_REG(rt, T0);
4787
        opn = "mfc1";
4788
        break;
4789
    case OPC_MTC1:
4790
        GEN_LOAD_REG_TN(T0, rt);
4791
        gen_op_mtc1();
4792
        GEN_STORE_FTN_FREG(fs, WT0);
4793
        opn = "mtc1";
4794
        break;
4795
    case OPC_CFC1:
4796
        gen_op_cfc1(fs);
4797
        GEN_STORE_TN_REG(rt, T0);
4798
        opn = "cfc1";
4799
        break;
4800
    case OPC_CTC1:
4801
        GEN_LOAD_REG_TN(T0, rt);
4802
        gen_op_ctc1(fs);
4803
        opn = "ctc1";
4804
        break;
4805
    case OPC_DMFC1:
4806
        GEN_LOAD_FREG_FTN(DT0, fs);
4807
        gen_op_dmfc1();
4808
        GEN_STORE_TN_REG(rt, T0);
4809
        opn = "dmfc1";
4810
        break;
4811
    case OPC_DMTC1:
4812
        GEN_LOAD_REG_TN(T0, rt);
4813
        gen_op_dmtc1();
4814
        GEN_STORE_FTN_FREG(fs, DT0);
4815
        opn = "dmtc1";
4816
        break;
4817
    case OPC_MFHC1:
4818
        GEN_LOAD_FREG_FTN(WTH0, fs);
4819
        gen_op_mfhc1();
4820
        GEN_STORE_TN_REG(rt, T0);
4821
        opn = "mfhc1";
4822
        break;
4823
    case OPC_MTHC1:
4824
        GEN_LOAD_REG_TN(T0, rt);
4825
        gen_op_mthc1();
4826
        GEN_STORE_FTN_FREG(fs, WTH0);
4827
        opn = "mthc1";
4828
        break;
4829
    default:
4830
        MIPS_INVAL(opn);
4831
        generate_exception (ctx, EXCP_RI);
4832
        return;
4833
    }
4834
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4835
}
4836

    
4837
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4838
{
4839
    uint32_t ccbit;
4840

    
4841
    GEN_LOAD_REG_TN(T0, rd);
4842
    GEN_LOAD_REG_TN(T1, rs);
4843
    if (cc) {
4844
        ccbit = 1 << (24 + cc);
4845
    } else
4846
        ccbit = 1 << 23;
4847
    if (!tf)
4848
        gen_op_movf(ccbit);
4849
    else
4850
        gen_op_movt(ccbit);
4851
    GEN_STORE_TN_REG(rd, T0);
4852
}
4853

    
4854
#define GEN_MOVCF(fmt)                                                \
4855
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4856
{                                                                     \
4857
    uint32_t ccbit;                                                   \
4858
                                                                      \
4859
    if (cc) {                                                         \
4860
        ccbit = 1 << (24 + cc);                                       \
4861
    } else                                                            \
4862
        ccbit = 1 << 23;                                              \
4863
    if (!tf)                                                          \
4864
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4865
    else                                                              \
4866
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4867
}
4868
GEN_MOVCF(d);
4869
GEN_MOVCF(s);
4870
GEN_MOVCF(ps);
4871
#undef GEN_MOVCF
4872

    
4873
static void gen_farith (DisasContext *ctx, uint32_t op1,
4874
                        int ft, int fs, int fd, int cc)
4875
{
4876
    const char *opn = "farith";
4877
    const char *condnames[] = {
4878
            "c.f",
4879
            "c.un",
4880
            "c.eq",
4881
            "c.ueq",
4882
            "c.olt",
4883
            "c.ult",
4884
            "c.ole",
4885
            "c.ule",
4886
            "c.sf",
4887
            "c.ngle",
4888
            "c.seq",
4889
            "c.ngl",
4890
            "c.lt",
4891
            "c.nge",
4892
            "c.le",
4893
            "c.ngt",
4894
    };
4895
    const char *condnames_abs[] = {
4896
            "cabs.f",
4897
            "cabs.un",
4898
            "cabs.eq",
4899
            "cabs.ueq",
4900
            "cabs.olt",
4901
            "cabs.ult",
4902
            "cabs.ole",
4903
            "cabs.ule",
4904
            "cabs.sf",
4905
            "cabs.ngle",
4906
            "cabs.seq",
4907
            "cabs.ngl",
4908
            "cabs.lt",
4909
            "cabs.nge",
4910
            "cabs.le",
4911
            "cabs.ngt",
4912
    };
4913
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4914
    uint32_t func = ctx->opcode & 0x3f;
4915

    
4916
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4917
    case FOP(0, 16):
4918
        GEN_LOAD_FREG_FTN(WT0, fs);
4919
        GEN_LOAD_FREG_FTN(WT1, ft);
4920
        gen_op_float_add_s();
4921
        GEN_STORE_FTN_FREG(fd, WT2);
4922
        opn = "add.s";
4923
        optype = BINOP;
4924
        break;
4925
    case FOP(1, 16):
4926
        GEN_LOAD_FREG_FTN(WT0, fs);
4927
        GEN_LOAD_FREG_FTN(WT1, ft);
4928
        gen_op_float_sub_s();
4929
        GEN_STORE_FTN_FREG(fd, WT2);
4930
        opn = "sub.s";
4931
        optype = BINOP;
4932
        break;
4933
    case FOP(2, 16):
4934
        GEN_LOAD_FREG_FTN(WT0, fs);
4935
        GEN_LOAD_FREG_FTN(WT1, ft);
4936
        gen_op_float_mul_s();
4937
        GEN_STORE_FTN_FREG(fd, WT2);
4938
        opn = "mul.s";
4939
        optype = BINOP;
4940
        break;
4941
    case FOP(3, 16):
4942
        GEN_LOAD_FREG_FTN(WT0, fs);
4943
        GEN_LOAD_FREG_FTN(WT1, ft);
4944
        gen_op_float_div_s();
4945
        GEN_STORE_FTN_FREG(fd, WT2);
4946
        opn = "div.s";
4947
        optype = BINOP;
4948
        break;
4949
    case FOP(4, 16):
4950
        GEN_LOAD_FREG_FTN(WT0, fs);
4951
        gen_op_float_sqrt_s();
4952
        GEN_STORE_FTN_FREG(fd, WT2);
4953
        opn = "sqrt.s";
4954
        break;
4955
    case FOP(5, 16):
4956
        GEN_LOAD_FREG_FTN(WT0, fs);
4957
        gen_op_float_abs_s();
4958
        GEN_STORE_FTN_FREG(fd, WT2);
4959
        opn = "abs.s";
4960
        break;
4961
    case FOP(6, 16):
4962
        GEN_LOAD_FREG_FTN(WT0, fs);
4963
        gen_op_float_mov_s();
4964
        GEN_STORE_FTN_FREG(fd, WT2);
4965
        opn = "mov.s";
4966
        break;
4967
    case FOP(7, 16):
4968
        GEN_LOAD_FREG_FTN(WT0, fs);
4969
        gen_op_float_chs_s();
4970
        GEN_STORE_FTN_FREG(fd, WT2);
4971
        opn = "neg.s";
4972
        break;
4973
    case FOP(8, 16):
4974
        check_cp1_64bitmode(ctx);
4975
        GEN_LOAD_FREG_FTN(WT0, fs);
4976
        gen_op_float_roundl_s();
4977
        GEN_STORE_FTN_FREG(fd, DT2);
4978
        opn = "round.l.s";
4979
        break;
4980
    case FOP(9, 16):
4981
        check_cp1_64bitmode(ctx);
4982
        GEN_LOAD_FREG_FTN(WT0, fs);
4983
        gen_op_float_truncl_s();
4984
        GEN_STORE_FTN_FREG(fd, DT2);
4985
        opn = "trunc.l.s";
4986
        break;
4987
    case FOP(10, 16):
4988
        check_cp1_64bitmode(ctx);
4989
        GEN_LOAD_FREG_FTN(WT0, fs);
4990
        gen_op_float_ceill_s();
4991
        GEN_STORE_FTN_FREG(fd, DT2);
4992
        opn = "ceil.l.s";
4993
        break;
4994
    case FOP(11, 16):
4995
        check_cp1_64bitmode(ctx);
4996
        GEN_LOAD_FREG_FTN(WT0, fs);
4997
        gen_op_float_floorl_s();
4998
        GEN_STORE_FTN_FREG(fd, DT2);
4999
        opn = "floor.l.s";
5000
        break;
5001
    case FOP(12, 16):
5002
        GEN_LOAD_FREG_FTN(WT0, fs);
5003
        gen_op_float_roundw_s();
5004
        GEN_STORE_FTN_FREG(fd, WT2);
5005
        opn = "round.w.s";
5006
        break;
5007
    case FOP(13, 16):
5008
        GEN_LOAD_FREG_FTN(WT0, fs);
5009
        gen_op_float_truncw_s();
5010
        GEN_STORE_FTN_FREG(fd, WT2);
5011
        opn = "trunc.w.s";
5012
        break;
5013
    case FOP(14, 16):
5014
        GEN_LOAD_FREG_FTN(WT0, fs);
5015
        gen_op_float_ceilw_s();
5016
        GEN_STORE_FTN_FREG(fd, WT2);
5017
        opn = "ceil.w.s";
5018
        break;
5019
    case FOP(15, 16):
5020
        GEN_LOAD_FREG_FTN(WT0, fs);
5021
        gen_op_float_floorw_s();
5022
        GEN_STORE_FTN_FREG(fd, WT2);
5023
        opn = "floor.w.s";
5024
        break;
5025
    case FOP(17, 16):
5026
        GEN_LOAD_REG_TN(T0, ft);
5027
        GEN_LOAD_FREG_FTN(WT0, fs);
5028
        GEN_LOAD_FREG_FTN(WT2, fd);
5029
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5030
        GEN_STORE_FTN_FREG(fd, WT2);
5031
        opn = "movcf.s";
5032
        break;
5033
    case FOP(18, 16):
5034
        GEN_LOAD_REG_TN(T0, ft);
5035
        GEN_LOAD_FREG_FTN(WT0, fs);
5036
        GEN_LOAD_FREG_FTN(WT2, fd);
5037
        gen_op_float_movz_s();
5038
        GEN_STORE_FTN_FREG(fd, WT2);
5039
        opn = "movz.s";
5040
        break;
5041
    case FOP(19, 16):
5042
        GEN_LOAD_REG_TN(T0, ft);
5043
        GEN_LOAD_FREG_FTN(WT0, fs);
5044
        GEN_LOAD_FREG_FTN(WT2, fd);
5045
        gen_op_float_movn_s();
5046
        GEN_STORE_FTN_FREG(fd, WT2);
5047
        opn = "movn.s";
5048
        break;
5049
    case FOP(21, 16):
5050
        GEN_LOAD_FREG_FTN(WT0, fs);
5051
        gen_op_float_recip_s();
5052
        GEN_STORE_FTN_FREG(fd, WT2);
5053
        opn = "recip.s";
5054
        break;
5055
    case FOP(22, 16):
5056
        GEN_LOAD_FREG_FTN(WT0, fs);
5057
        gen_op_float_rsqrt_s();
5058
        GEN_STORE_FTN_FREG(fd, WT2);
5059
        opn = "rsqrt.s";
5060
        break;
5061
    case FOP(28, 16):
5062
        check_cp1_64bitmode(ctx);
5063
        GEN_LOAD_FREG_FTN(WT0, fs);
5064
        GEN_LOAD_FREG_FTN(WT2, fd);
5065
        gen_op_float_recip2_s();
5066
        GEN_STORE_FTN_FREG(fd, WT2);
5067
        opn = "recip2.s";
5068
        break;
5069
    case FOP(29, 16):
5070
        check_cp1_64bitmode(ctx);
5071
        GEN_LOAD_FREG_FTN(WT0, fs);
5072
        gen_op_float_recip1_s();
5073
        GEN_STORE_FTN_FREG(fd, WT2);
5074
        opn = "recip1.s";
5075
        break;
5076
    case FOP(30, 16):
5077
        check_cp1_64bitmode(ctx);
5078
        GEN_LOAD_FREG_FTN(WT0, fs);
5079
        gen_op_float_rsqrt1_s();
5080
        GEN_STORE_FTN_FREG(fd, WT2);
5081
        opn = "rsqrt1.s";
5082
        break;
5083
    case FOP(31, 16):
5084
        check_cp1_64bitmode(ctx);
5085
        GEN_LOAD_FREG_FTN(WT0, fs);
5086
        GEN_LOAD_FREG_FTN(WT2, ft);
5087
        gen_op_float_rsqrt2_s();
5088
        GEN_STORE_FTN_FREG(fd, WT2);
5089
        opn = "rsqrt2.s";
5090
        break;
5091
    case FOP(33, 16):
5092
        check_cp1_registers(ctx, fd);
5093
        GEN_LOAD_FREG_FTN(WT0, fs);
5094
        gen_op_float_cvtd_s();
5095
        GEN_STORE_FTN_FREG(fd, DT2);
5096
        opn = "cvt.d.s";
5097
        break;
5098
    case FOP(36, 16):
5099
        GEN_LOAD_FREG_FTN(WT0, fs);
5100
        gen_op_float_cvtw_s();
5101
        GEN_STORE_FTN_FREG(fd, WT2);
5102
        opn = "cvt.w.s";
5103
        break;
5104
    case FOP(37, 16):
5105
        check_cp1_64bitmode(ctx);
5106
        GEN_LOAD_FREG_FTN(WT0, fs);
5107
        gen_op_float_cvtl_s();
5108
        GEN_STORE_FTN_FREG(fd, DT2);
5109
        opn = "cvt.l.s";
5110
        break;
5111
    case FOP(38, 16):
5112
        check_cp1_64bitmode(ctx);
5113
        GEN_LOAD_FREG_FTN(WT1, fs);
5114
        GEN_LOAD_FREG_FTN(WT0, ft);
5115
        gen_op_float_cvtps_s();
5116
        GEN_STORE_FTN_FREG(fd, DT2);
5117
        opn = "cvt.ps.s";
5118
        break;
5119
    case FOP(48, 16):
5120
    case FOP(49, 16):
5121
    case FOP(50, 16):
5122
    case FOP(51, 16):
5123
    case FOP(52, 16):
5124
    case FOP(53, 16):
5125
    case FOP(54, 16):
5126
    case FOP(55, 16):
5127
    case FOP(56, 16):
5128
    case FOP(57, 16):
5129
    case FOP(58, 16):
5130
    case FOP(59, 16):
5131
    case FOP(60, 16):
5132
    case FOP(61, 16):
5133
    case FOP(62, 16):
5134
    case FOP(63, 16):
5135
        GEN_LOAD_FREG_FTN(WT0, fs);
5136
        GEN_LOAD_FREG_FTN(WT1, ft);
5137
        if (ctx->opcode & (1 << 6)) {
5138
            check_cp1_64bitmode(ctx);
5139
            gen_cmpabs_s(func-48, cc);
5140
            opn = condnames_abs[func-48];
5141
        } else {
5142
            gen_cmp_s(func-48, cc);
5143
            opn = condnames[func-48];
5144
        }
5145
        break;
5146
    case FOP(0, 17):
5147
        check_cp1_registers(ctx, fs | ft | fd);
5148
        GEN_LOAD_FREG_FTN(DT0, fs);
5149
        GEN_LOAD_FREG_FTN(DT1, ft);
5150
        gen_op_float_add_d();
5151
        GEN_STORE_FTN_FREG(fd, DT2);
5152
        opn = "add.d";
5153
        optype = BINOP;
5154
        break;
5155
    case FOP(1, 17):
5156
        check_cp1_registers(ctx, fs | ft | fd);
5157
        GEN_LOAD_FREG_FTN(DT0, fs);
5158
        GEN_LOAD_FREG_FTN(DT1, ft);
5159
        gen_op_float_sub_d();
5160
        GEN_STORE_FTN_FREG(fd, DT2);
5161
        opn = "sub.d";
5162
        optype = BINOP;
5163
        break;
5164
    case FOP(2, 17):
5165
        check_cp1_registers(ctx, fs | ft | fd);
5166
        GEN_LOAD_FREG_FTN(DT0, fs);
5167
        GEN_LOAD_FREG_FTN(DT1, ft);
5168
        gen_op_float_mul_d();
5169
        GEN_STORE_FTN_FREG(fd, DT2);
5170
        opn = "mul.d";
5171
        optype = BINOP;
5172
        break;
5173
    case FOP(3, 17):
5174
        check_cp1_registers(ctx, fs | ft | fd);
5175
        GEN_LOAD_FREG_FTN(DT0, fs);
5176
        GEN_LOAD_FREG_FTN(DT1, ft);
5177
        gen_op_float_div_d();
5178
        GEN_STORE_FTN_FREG(fd, DT2);
5179
        opn = "div.d";
5180
        optype = BINOP;
5181
        break;
5182
    case FOP(4, 17):
5183
        check_cp1_registers(ctx, fs | fd);
5184
        GEN_LOAD_FREG_FTN(DT0, fs);
5185
        gen_op_float_sqrt_d();
5186
        GEN_STORE_FTN_FREG(fd, DT2);
5187
        opn = "sqrt.d";
5188
        break;
5189
    case FOP(5, 17):
5190
        check_cp1_registers(ctx, fs | fd);
5191
        GEN_LOAD_FREG_FTN(DT0, fs);
5192
        gen_op_float_abs_d();
5193
        GEN_STORE_FTN_FREG(fd, DT2);
5194
        opn = "abs.d";
5195
        break;
5196
    case FOP(6, 17):
5197
        check_cp1_registers(ctx, fs | fd);
5198
        GEN_LOAD_FREG_FTN(DT0, fs);
5199
        gen_op_float_mov_d();
5200
        GEN_STORE_FTN_FREG(fd, DT2);
5201
        opn = "mov.d";
5202
        break;
5203
    case FOP(7, 17):
5204
        check_cp1_registers(ctx, fs | fd);
5205
        GEN_LOAD_FREG_FTN(DT0, fs);
5206
        gen_op_float_chs_d();
5207
        GEN_STORE_FTN_FREG(fd, DT2);
5208
        opn = "neg.d";
5209
        break;
5210
    case FOP(8, 17):
5211
        check_cp1_64bitmode(ctx);
5212
        GEN_LOAD_FREG_FTN(DT0, fs);
5213
        gen_op_float_roundl_d();
5214
        GEN_STORE_FTN_FREG(fd, DT2);
5215
        opn = "round.l.d";
5216
        break;
5217
    case FOP(9, 17):
5218
        check_cp1_64bitmode(ctx);
5219
        GEN_LOAD_FREG_FTN(DT0, fs);
5220
        gen_op_float_truncl_d();
5221
        GEN_STORE_FTN_FREG(fd, DT2);
5222
        opn = "trunc.l.d";
5223
        break;
5224
    case FOP(10, 17):
5225
        check_cp1_64bitmode(ctx);
5226
        GEN_LOAD_FREG_FTN(DT0, fs);
5227
        gen_op_float_ceill_d();
5228
        GEN_STORE_FTN_FREG(fd, DT2);
5229
        opn = "ceil.l.d";
5230
        break;
5231
    case FOP(11, 17):
5232
        check_cp1_64bitmode(ctx);
5233
        GEN_LOAD_FREG_FTN(DT0, fs);
5234
        gen_op_float_floorl_d();
5235
        GEN_STORE_FTN_FREG(fd, DT2);
5236
        opn = "floor.l.d";
5237
        break;
5238
    case FOP(12, 17):
5239
        check_cp1_registers(ctx, fs);
5240
        GEN_LOAD_FREG_FTN(DT0, fs);
5241
        gen_op_float_roundw_d();
5242
        GEN_STORE_FTN_FREG(fd, WT2);
5243
        opn = "round.w.d";
5244
        break;
5245
    case FOP(13, 17):
5246
        check_cp1_registers(ctx, fs);
5247
        GEN_LOAD_FREG_FTN(DT0, fs);
5248
        gen_op_float_truncw_d();
5249
        GEN_STORE_FTN_FREG(fd, WT2);
5250
        opn = "trunc.w.d";
5251
        break;
5252
    case FOP(14, 17):
5253
        check_cp1_registers(ctx, fs);
5254
        GEN_LOAD_FREG_FTN(DT0, fs);
5255
        gen_op_float_ceilw_d();
5256
        GEN_STORE_FTN_FREG(fd, WT2);
5257
        opn = "ceil.w.d";
5258
        break;
5259
    case FOP(15, 17):
5260
        check_cp1_registers(ctx, fs);
5261
        GEN_LOAD_FREG_FTN(DT0, fs);
5262
        gen_op_float_floorw_d();
5263
        GEN_STORE_FTN_FREG(fd, WT2);
5264
        opn = "floor.w.d";
5265
        break;
5266
    case FOP(17, 17):
5267
        GEN_LOAD_REG_TN(T0, ft);
5268
        GEN_LOAD_FREG_FTN(DT0, fs);
5269
        GEN_LOAD_FREG_FTN(DT2, fd);
5270
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5271
        GEN_STORE_FTN_FREG(fd, DT2);
5272
        opn = "movcf.d";
5273
        break;
5274
    case FOP(18, 17):
5275
        GEN_LOAD_REG_TN(T0, ft);
5276
        GEN_LOAD_FREG_FTN(DT0, fs);
5277
        GEN_LOAD_FREG_FTN(DT2, fd);
5278
        gen_op_float_movz_d();
5279
        GEN_STORE_FTN_FREG(fd, DT2);
5280
        opn = "movz.d";
5281
        break;
5282
    case FOP(19, 17):
5283
        GEN_LOAD_REG_TN(T0, ft);
5284
        GEN_LOAD_FREG_FTN(DT0, fs);
5285
        GEN_LOAD_FREG_FTN(DT2, fd);
5286
        gen_op_float_movn_d();
5287
        GEN_STORE_FTN_FREG(fd, DT2);
5288
        opn = "movn.d";
5289
        break;
5290
    case FOP(21, 17):
5291
        check_cp1_registers(ctx, fs | fd);
5292
        GEN_LOAD_FREG_FTN(DT0, fs);
5293
        gen_op_float_recip_d();
5294
        GEN_STORE_FTN_FREG(fd, DT2);
5295
        opn = "recip.d";
5296
        break;
5297
    case FOP(22, 17):
5298
        check_cp1_registers(ctx, fs | fd);
5299
        GEN_LOAD_FREG_FTN(DT0, fs);
5300
        gen_op_float_rsqrt_d();
5301
        GEN_STORE_FTN_FREG(fd, DT2);
5302
        opn = "rsqrt.d";
5303
        break;
5304
    case FOP(28, 17):
5305
        check_cp1_64bitmode(ctx);
5306
        GEN_LOAD_FREG_FTN(DT0, fs);
5307
        GEN_LOAD_FREG_FTN(DT2, ft);
5308
        gen_op_float_recip2_d();
5309
        GEN_STORE_FTN_FREG(fd, DT2);
5310
        opn = "recip2.d";
5311
        break;
5312
    case FOP(29, 17):
5313
        check_cp1_64bitmode(ctx);
5314
        GEN_LOAD_FREG_FTN(DT0, fs);
5315
        gen_op_float_recip1_d();
5316
        GEN_STORE_FTN_FREG(fd, DT2);
5317
        opn = "recip1.d";
5318
        break;
5319
    case FOP(30, 17):
5320
        check_cp1_64bitmode(ctx);
5321
        GEN_LOAD_FREG_FTN(DT0, fs);
5322
        gen_op_float_rsqrt1_d();
5323
        GEN_STORE_FTN_FREG(fd, DT2);
5324
        opn = "rsqrt1.d";
5325
        break;
5326
    case FOP(31, 17):
5327
        check_cp1_64bitmode(ctx);
5328
        GEN_LOAD_FREG_FTN(DT0, fs);
5329
        GEN_LOAD_FREG_FTN(DT2, ft);
5330
        gen_op_float_rsqrt2_d();
5331
        GEN_STORE_FTN_FREG(fd, DT2);
5332
        opn = "rsqrt2.d";
5333
        break;
5334
    case FOP(48, 17):
5335
    case FOP(49, 17):
5336
    case FOP(50, 17):
5337
    case FOP(51, 17):
5338
    case FOP(52, 17):
5339
    case FOP(53, 17):
5340
    case FOP(54, 17):
5341
    case FOP(55, 17):
5342
    case FOP(56, 17):
5343
    case FOP(57, 17):
5344
    case FOP(58, 17):
5345
    case FOP(59, 17):
5346
    case FOP(60, 17):
5347
    case FOP(61, 17):
5348
    case FOP(62, 17):
5349
    case FOP(63, 17):
5350
        GEN_LOAD_FREG_FTN(DT0, fs);
5351
        GEN_LOAD_FREG_FTN(DT1, ft);
5352
        if (ctx->opcode & (1 << 6)) {
5353
            check_cp1_64bitmode(ctx);
5354
            gen_cmpabs_d(func-48, cc);
5355
            opn = condnames_abs[func-48];
5356
        } else {
5357
            check_cp1_registers(ctx, fs | ft);
5358
            gen_cmp_d(func-48, cc);
5359
            opn = condnames[func-48];
5360
        }
5361
        break;
5362
    case FOP(32, 17):
5363
        check_cp1_registers(ctx, fs);
5364
        GEN_LOAD_FREG_FTN(DT0, fs);
5365
        gen_op_float_cvts_d();
5366
        GEN_STORE_FTN_FREG(fd, WT2);
5367
        opn = "cvt.s.d";
5368
        break;
5369
    case FOP(36, 17):
5370
        check_cp1_registers(ctx, fs);
5371
        GEN_LOAD_FREG_FTN(DT0, fs);
5372
        gen_op_float_cvtw_d();
5373
        GEN_STORE_FTN_FREG(fd, WT2);
5374
        opn = "cvt.w.d";
5375
        break;
5376
    case FOP(37, 17):
5377
        check_cp1_64bitmode(ctx);
5378
        GEN_LOAD_FREG_FTN(DT0, fs);
5379
        gen_op_float_cvtl_d();
5380
        GEN_STORE_FTN_FREG(fd, DT2);
5381
        opn = "cvt.l.d";
5382
        break;
5383
    case FOP(32, 20):
5384
        GEN_LOAD_FREG_FTN(WT0, fs);
5385
        gen_op_float_cvts_w();
5386
        GEN_STORE_FTN_FREG(fd, WT2);
5387
        opn = "cvt.s.w";
5388
        break;
5389
    case FOP(33, 20):
5390
        check_cp1_registers(ctx, fd);
5391
        GEN_LOAD_FREG_FTN(WT0, fs);
5392
        gen_op_float_cvtd_w();
5393
        GEN_STORE_FTN_FREG(fd, DT2);
5394
        opn = "cvt.d.w";
5395
        break;
5396
    case FOP(32, 21):
5397
        check_cp1_64bitmode(ctx);
5398
        GEN_LOAD_FREG_FTN(DT0, fs);
5399
        gen_op_float_cvts_l();
5400
        GEN_STORE_FTN_FREG(fd, WT2);
5401
        opn = "cvt.s.l";
5402
        break;
5403
    case FOP(33, 21):
5404
        check_cp1_64bitmode(ctx);
5405
        GEN_LOAD_FREG_FTN(DT0, fs);
5406
        gen_op_float_cvtd_l();
5407
        GEN_STORE_FTN_FREG(fd, DT2);
5408
        opn = "cvt.d.l";
5409
        break;
5410
    case FOP(38, 20):
5411
    case FOP(38, 21):
5412
        check_cp1_64bitmode(ctx);
5413
        GEN_LOAD_FREG_FTN(WT0, fs);
5414
        GEN_LOAD_FREG_FTN(WTH0, fs);
5415
        gen_op_float_cvtps_pw();
5416
        GEN_STORE_FTN_FREG(fd, WT2);
5417
        GEN_STORE_FTN_FREG(fd, WTH2);
5418
        opn = "cvt.ps.pw";
5419
        break;
5420
    case FOP(0, 22):
5421
        check_cp1_64bitmode(ctx);
5422
        GEN_LOAD_FREG_FTN(WT0, fs);
5423
        GEN_LOAD_FREG_FTN(WTH0, fs);
5424
        GEN_LOAD_FREG_FTN(WT1, ft);
5425
        GEN_LOAD_FREG_FTN(WTH1, ft);
5426
        gen_op_float_add_ps();
5427
        GEN_STORE_FTN_FREG(fd, WT2);
5428
        GEN_STORE_FTN_FREG(fd, WTH2);
5429
        opn = "add.ps";
5430
        break;
5431
    case FOP(1, 22):
5432
        check_cp1_64bitmode(ctx);
5433
        GEN_LOAD_FREG_FTN(WT0, fs);
5434
        GEN_LOAD_FREG_FTN(WTH0, fs);
5435
        GEN_LOAD_FREG_FTN(WT1, ft);
5436
        GEN_LOAD_FREG_FTN(WTH1, ft);
5437
        gen_op_float_sub_ps();
5438
        GEN_STORE_FTN_FREG(fd, WT2);
5439
        GEN_STORE_FTN_FREG(fd, WTH2);
5440
        opn = "sub.ps";
5441
        break;
5442
    case FOP(2, 22):
5443
        check_cp1_64bitmode(ctx);
5444
        GEN_LOAD_FREG_FTN(WT0, fs);
5445
        GEN_LOAD_FREG_FTN(WTH0, fs);
5446
        GEN_LOAD_FREG_FTN(WT1, ft);
5447
        GEN_LOAD_FREG_FTN(WTH1, ft);
5448
        gen_op_float_mul_ps();
5449
        GEN_STORE_FTN_FREG(fd, WT2);
5450
        GEN_STORE_FTN_FREG(fd, WTH2);
5451
        opn = "mul.ps";
5452
        break;
5453
    case FOP(5, 22):
5454
        check_cp1_64bitmode(ctx);
5455
        GEN_LOAD_FREG_FTN(WT0, fs);
5456
        GEN_LOAD_FREG_FTN(WTH0, fs);
5457
        gen_op_float_abs_ps();
5458
        GEN_STORE_FTN_FREG(fd, WT2);
5459
        GEN_STORE_FTN_FREG(fd, WTH2);
5460
        opn = "abs.ps";
5461
        break;
5462
    case FOP(6, 22):
5463
        check_cp1_64bitmode(ctx);
5464
        GEN_LOAD_FREG_FTN(WT0, fs);
5465
        GEN_LOAD_FREG_FTN(WTH0, fs);
5466
        gen_op_float_mov_ps();
5467
        GEN_STORE_FTN_FREG(fd, WT2);
5468
        GEN_STORE_FTN_FREG(fd, WTH2);
5469
        opn = "mov.ps";
5470
        break;
5471
    case FOP(7, 22):
5472
        check_cp1_64bitmode(ctx);
5473
        GEN_LOAD_FREG_FTN(WT0, fs);
5474
        GEN_LOAD_FREG_FTN(WTH0, fs);
5475
        gen_op_float_chs_ps();
5476
        GEN_STORE_FTN_FREG(fd, WT2);
5477
        GEN_STORE_FTN_FREG(fd, WTH2);
5478
        opn = "neg.ps";
5479
        break;
5480
    case FOP(17, 22):
5481
        check_cp1_64bitmode(ctx);
5482
        GEN_LOAD_REG_TN(T0, ft);
5483
        GEN_LOAD_FREG_FTN(WT0, fs);
5484
        GEN_LOAD_FREG_FTN(WTH0, fs);
5485
        GEN_LOAD_FREG_FTN(WT2, fd);
5486
        GEN_LOAD_FREG_FTN(WTH2, fd);
5487
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5488
        GEN_STORE_FTN_FREG(fd, WT2);
5489
        GEN_STORE_FTN_FREG(fd, WTH2);
5490
        opn = "movcf.ps";
5491
        break;
5492
    case FOP(18, 22):
5493
        check_cp1_64bitmode(ctx);
5494
        GEN_LOAD_REG_TN(T0, ft);
5495
        GEN_LOAD_FREG_FTN(WT0, fs);
5496
        GEN_LOAD_FREG_FTN(WTH0, fs);
5497
        GEN_LOAD_FREG_FTN(WT2, fd);
5498
        GEN_LOAD_FREG_FTN(WTH2, fd);
5499
        gen_op_float_movz_ps();
5500
        GEN_STORE_FTN_FREG(fd, WT2);
5501
        GEN_STORE_FTN_FREG(fd, WTH2);
5502
        opn = "movz.ps";
5503
        break;
5504
    case FOP(19, 22):
5505
        check_cp1_64bitmode(ctx);
5506
        GEN_LOAD_REG_TN(T0, ft);
5507
        GEN_LOAD_FREG_FTN(WT0, fs);
5508
        GEN_LOAD_FREG_FTN(WTH0, fs);
5509
        GEN_LOAD_FREG_FTN(WT2, fd);
5510
        GEN_LOAD_FREG_FTN(WTH2, fd);
5511
        gen_op_float_movn_ps();
5512
        GEN_STORE_FTN_FREG(fd, WT2);
5513
        GEN_STORE_FTN_FREG(fd, WTH2);
5514
        opn = "movn.ps";
5515
        break;
5516
    case FOP(24, 22):
5517
        check_cp1_64bitmode(ctx);
5518
        GEN_LOAD_FREG_FTN(WT0, ft);
5519
        GEN_LOAD_FREG_FTN(WTH0, ft);
5520
        GEN_LOAD_FREG_FTN(WT1, fs);
5521
        GEN_LOAD_FREG_FTN(WTH1, fs);
5522
        gen_op_float_addr_ps();
5523
        GEN_STORE_FTN_FREG(fd, WT2);
5524
        GEN_STORE_FTN_FREG(fd, WTH2);
5525
        opn = "addr.ps";
5526
        break;
5527
    case FOP(26, 22):
5528
        check_cp1_64bitmode(ctx);
5529
        GEN_LOAD_FREG_FTN(WT0, ft);
5530
        GEN_LOAD_FREG_FTN(WTH0, ft);
5531
        GEN_LOAD_FREG_FTN(WT1, fs);
5532
        GEN_LOAD_FREG_FTN(WTH1, fs);
5533
        gen_op_float_mulr_ps();
5534
        GEN_STORE_FTN_FREG(fd, WT2);
5535
        GEN_STORE_FTN_FREG(fd, WTH2);
5536
        opn = "mulr.ps";
5537
        break;
5538
    case FOP(28, 22):
5539
        check_cp1_64bitmode(ctx);
5540
        GEN_LOAD_FREG_FTN(WT0, fs);
5541
        GEN_LOAD_FREG_FTN(WTH0, fs);
5542
        GEN_LOAD_FREG_FTN(WT2, fd);
5543
        GEN_LOAD_FREG_FTN(WTH2, fd);
5544
        gen_op_float_recip2_ps();
5545
        GEN_STORE_FTN_FREG(fd, WT2);
5546
        GEN_STORE_FTN_FREG(fd, WTH2);
5547
        opn = "recip2.ps";
5548
        break;
5549
    case FOP(29, 22):
5550
        check_cp1_64bitmode(ctx);
5551
        GEN_LOAD_FREG_FTN(WT0, fs);
5552
        GEN_LOAD_FREG_FTN(WTH0, fs);
5553
        gen_op_float_recip1_ps();
5554
        GEN_STORE_FTN_FREG(fd, WT2);
5555
        GEN_STORE_FTN_FREG(fd, WTH2);
5556
        opn = "recip1.ps";
5557
        break;
5558
    case FOP(30, 22):
5559
        check_cp1_64bitmode(ctx);
5560
        GEN_LOAD_FREG_FTN(WT0, fs);
5561
        GEN_LOAD_FREG_FTN(WTH0, fs);
5562
        gen_op_float_rsqrt1_ps();
5563
        GEN_STORE_FTN_FREG(fd, WT2);
5564
        GEN_STORE_FTN_FREG(fd, WTH2);
5565
        opn = "rsqrt1.ps";
5566
        break;
5567
    case FOP(31, 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(WT2, ft);
5572
        GEN_LOAD_FREG_FTN(WTH2, ft);
5573
        gen_op_float_rsqrt2_ps();
5574
        GEN_STORE_FTN_FREG(fd, WT2);
5575
        GEN_STORE_FTN_FREG(fd, WTH2);
5576
        opn = "rsqrt2.ps";
5577
        break;
5578
    case FOP(32, 22):
5579
        check_cp1_64bitmode(ctx);
5580
        GEN_LOAD_FREG_FTN(WTH0, fs);
5581
        gen_op_float_cvts_pu();
5582
        GEN_STORE_FTN_FREG(fd, WT2);
5583
        opn = "cvt.s.pu";
5584
        break;
5585
    case FOP(36, 22):
5586
        check_cp1_64bitmode(ctx);
5587
        GEN_LOAD_FREG_FTN(WT0, fs);
5588
        GEN_LOAD_FREG_FTN(WTH0, fs);
5589
        gen_op_float_cvtpw_ps();
5590
        GEN_STORE_FTN_FREG(fd, WT2);
5591
        GEN_STORE_FTN_FREG(fd, WTH2);
5592
        opn = "cvt.pw.ps";
5593
        break;
5594
    case FOP(40, 22):
5595
        check_cp1_64bitmode(ctx);
5596
        GEN_LOAD_FREG_FTN(WT0, fs);
5597
        gen_op_float_cvts_pl();
5598
        GEN_STORE_FTN_FREG(fd, WT2);
5599
        opn = "cvt.s.pl";
5600
        break;
5601
    case FOP(44, 22):
5602
        check_cp1_64bitmode(ctx);
5603
        GEN_LOAD_FREG_FTN(WT0, fs);
5604
        GEN_LOAD_FREG_FTN(WT1, ft);
5605
        gen_op_float_pll_ps();
5606
        GEN_STORE_FTN_FREG(fd, DT2);
5607
        opn = "pll.ps";
5608
        break;
5609
    case FOP(45, 22):
5610
        check_cp1_64bitmode(ctx);
5611
        GEN_LOAD_FREG_FTN(WT0, fs);
5612
        GEN_LOAD_FREG_FTN(WTH1, ft);
5613
        gen_op_float_plu_ps();
5614
        GEN_STORE_FTN_FREG(fd, DT2);
5615
        opn = "plu.ps";
5616
        break;
5617
    case FOP(46, 22):
5618
        check_cp1_64bitmode(ctx);
5619
        GEN_LOAD_FREG_FTN(WTH0, fs);
5620
        GEN_LOAD_FREG_FTN(WT1, ft);
5621
        gen_op_float_pul_ps();
5622
        GEN_STORE_FTN_FREG(fd, DT2);
5623
        opn = "pul.ps";
5624
        break;
5625
    case FOP(47, 22):
5626
        check_cp1_64bitmode(ctx);
5627
        GEN_LOAD_FREG_FTN(WTH0, fs);
5628
        GEN_LOAD_FREG_FTN(WTH1, ft);
5629
        gen_op_float_puu_ps();
5630
        GEN_STORE_FTN_FREG(fd, DT2);
5631
        opn = "puu.ps";
5632
        break;
5633
    case FOP(48, 22):
5634
    case FOP(49, 22):
5635
    case FOP(50, 22):
5636
    case FOP(51, 22):
5637
    case FOP(52, 22):
5638
    case FOP(53, 22):
5639
    case FOP(54, 22):
5640
    case FOP(55, 22):
5641
    case FOP(56, 22):
5642
    case FOP(57, 22):
5643
    case FOP(58, 22):
5644
    case FOP(59, 22):
5645
    case FOP(60, 22):
5646
    case FOP(61, 22):
5647
    case FOP(62, 22):
5648
    case FOP(63, 22):
5649
        check_cp1_64bitmode(ctx);
5650
        GEN_LOAD_FREG_FTN(WT0, fs);
5651
        GEN_LOAD_FREG_FTN(WTH0, fs);
5652
        GEN_LOAD_FREG_FTN(WT1, ft);
5653
        GEN_LOAD_FREG_FTN(WTH1, ft);
5654
        if (ctx->opcode & (1 << 6)) {
5655
            gen_cmpabs_ps(func-48, cc);
5656
            opn = condnames_abs[func-48];
5657
        } else {
5658
            gen_cmp_ps(func-48, cc);
5659
            opn = condnames[func-48];
5660
        }
5661
        break;
5662
    default:
5663
        MIPS_INVAL(opn);
5664
        generate_exception (ctx, EXCP_RI);
5665
        return;
5666
    }
5667
    switch (optype) {
5668
    case BINOP:
5669
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5670
        break;
5671
    case CMPOP:
5672
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5673
        break;
5674
    default:
5675
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5676
        break;
5677
    }
5678
}
5679

    
5680
/* Coprocessor 3 (FPU) */
5681
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5682
                           int fd, int fs, int base, int index)
5683
{
5684
    const char *opn = "extended float load/store";
5685
    int store = 0;
5686

    
5687
    /* All of those work only on 64bit FPUs. */
5688
    check_cp1_64bitmode(ctx);
5689
    if (base == 0) {
5690
        if (index == 0)
5691
            gen_op_reset_T0();
5692
        else
5693
            GEN_LOAD_REG_TN(T0, index);
5694
    } else if (index == 0) {
5695
        GEN_LOAD_REG_TN(T0, base);
5696
    } else {
5697
        GEN_LOAD_REG_TN(T0, base);
5698
        GEN_LOAD_REG_TN(T1, index);
5699
        gen_op_addr_add();
5700
    }
5701
    /* Don't do NOP if destination is zero: we must perform the actual
5702
       memory access. */
5703
    switch (opc) {
5704
    case OPC_LWXC1:
5705
        op_ldst(lwc1);
5706
        GEN_STORE_FTN_FREG(fd, WT0);
5707
        opn = "lwxc1";
5708
        break;
5709
    case OPC_LDXC1:
5710
        op_ldst(ldc1);
5711
        GEN_STORE_FTN_FREG(fd, DT0);
5712
        opn = "ldxc1";
5713
        break;
5714
    case OPC_LUXC1:
5715
        op_ldst(luxc1);
5716
        GEN_STORE_FTN_FREG(fd, DT0);
5717
        opn = "luxc1";
5718
        break;
5719
    case OPC_SWXC1:
5720
        GEN_LOAD_FREG_FTN(WT0, fs);
5721
        op_ldst(swc1);
5722
        opn = "swxc1";
5723
        store = 1;
5724
        break;
5725
    case OPC_SDXC1:
5726
        GEN_LOAD_FREG_FTN(DT0, fs);
5727
        op_ldst(sdc1);
5728
        opn = "sdxc1";
5729
        store = 1;
5730
        break;
5731
    case OPC_SUXC1:
5732
        GEN_LOAD_FREG_FTN(DT0, fs);
5733
        op_ldst(suxc1);
5734
        opn = "suxc1";
5735
        store = 1;
5736
        break;
5737
    default:
5738
        MIPS_INVAL(opn);
5739
        generate_exception(ctx, EXCP_RI);
5740
        return;
5741
    }
5742
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5743
               regnames[index], regnames[base]);
5744
}
5745

    
5746
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5747
                            int fd, int fr, int fs, int ft)
5748
{
5749
    const char *opn = "flt3_arith";
5750

    
5751
    /* All of those work only on 64bit FPUs. */
5752
    check_cp1_64bitmode(ctx);
5753
    switch (opc) {
5754
    case OPC_ALNV_PS:
5755
        GEN_LOAD_REG_TN(T0, fr);
5756
        GEN_LOAD_FREG_FTN(DT0, fs);
5757
        GEN_LOAD_FREG_FTN(DT1, ft);
5758
        gen_op_float_alnv_ps();
5759
        GEN_STORE_FTN_FREG(fd, DT2);
5760
        opn = "alnv.ps";
5761
        break;
5762
    case OPC_MADD_S:
5763
        GEN_LOAD_FREG_FTN(WT0, fs);
5764
        GEN_LOAD_FREG_FTN(WT1, ft);
5765
        GEN_LOAD_FREG_FTN(WT2, fr);
5766
        gen_op_float_muladd_s();
5767
        GEN_STORE_FTN_FREG(fd, WT2);
5768
        opn = "madd.s";
5769
        break;
5770
    case OPC_MADD_D:
5771
        GEN_LOAD_FREG_FTN(DT0, fs);
5772
        GEN_LOAD_FREG_FTN(DT1, ft);
5773
        GEN_LOAD_FREG_FTN(DT2, fr);
5774
        gen_op_float_muladd_d();
5775
        GEN_STORE_FTN_FREG(fd, DT2);
5776
        opn = "madd.d";
5777
        break;
5778
    case OPC_MADD_PS:
5779
        GEN_LOAD_FREG_FTN(WT0, fs);
5780
        GEN_LOAD_FREG_FTN(WTH0, fs);
5781
        GEN_LOAD_FREG_FTN(WT1, ft);
5782
        GEN_LOAD_FREG_FTN(WTH1, ft);
5783
        GEN_LOAD_FREG_FTN(WT2, fr);
5784
        GEN_LOAD_FREG_FTN(WTH2, fr);
5785
        gen_op_float_muladd_ps();
5786
        GEN_STORE_FTN_FREG(fd, WT2);
5787
        GEN_STORE_FTN_FREG(fd, WTH2);
5788
        opn = "madd.ps";
5789
        break;
5790
    case OPC_MSUB_S:
5791
        GEN_LOAD_FREG_FTN(WT0, fs);
5792
        GEN_LOAD_FREG_FTN(WT1, ft);
5793
        GEN_LOAD_FREG_FTN(WT2, fr);
5794
        gen_op_float_mulsub_s();
5795
        GEN_STORE_FTN_FREG(fd, WT2);
5796
        opn = "msub.s";
5797
        break;
5798
    case OPC_MSUB_D:
5799
        GEN_LOAD_FREG_FTN(DT0, fs);
5800
        GEN_LOAD_FREG_FTN(DT1, ft);
5801
        GEN_LOAD_FREG_FTN(DT2, fr);
5802
        gen_op_float_mulsub_d();
5803
        GEN_STORE_FTN_FREG(fd, DT2);
5804
        opn = "msub.d";
5805
        break;
5806
    case OPC_MSUB_PS:
5807
        GEN_LOAD_FREG_FTN(WT0, fs);
5808
        GEN_LOAD_FREG_FTN(WTH0, fs);
5809
        GEN_LOAD_FREG_FTN(WT1, ft);
5810
        GEN_LOAD_FREG_FTN(WTH1, ft);
5811
        GEN_LOAD_FREG_FTN(WT2, fr);
5812
        GEN_LOAD_FREG_FTN(WTH2, fr);
5813
        gen_op_float_mulsub_ps();
5814
        GEN_STORE_FTN_FREG(fd, WT2);
5815
        GEN_STORE_FTN_FREG(fd, WTH2);
5816
        opn = "msub.ps";
5817
        break;
5818
    case OPC_NMADD_S:
5819
        GEN_LOAD_FREG_FTN(WT0, fs);
5820
        GEN_LOAD_FREG_FTN(WT1, ft);
5821
        GEN_LOAD_FREG_FTN(WT2, fr);
5822
        gen_op_float_nmuladd_s();
5823
        GEN_STORE_FTN_FREG(fd, WT2);
5824
        opn = "nmadd.s";
5825
        break;
5826
    case OPC_NMADD_D:
5827
        GEN_LOAD_FREG_FTN(DT0, fs);
5828
        GEN_LOAD_FREG_FTN(DT1, ft);
5829
        GEN_LOAD_FREG_FTN(DT2, fr);
5830
        gen_op_float_nmuladd_d();
5831
        GEN_STORE_FTN_FREG(fd, DT2);
5832
        opn = "nmadd.d";
5833
        break;
5834
    case OPC_NMADD_PS:
5835
        GEN_LOAD_FREG_FTN(WT0, fs);
5836
        GEN_LOAD_FREG_FTN(WTH0, fs);
5837
        GEN_LOAD_FREG_FTN(WT1, ft);
5838
        GEN_LOAD_FREG_FTN(WTH1, ft);
5839
        GEN_LOAD_FREG_FTN(WT2, fr);
5840
        GEN_LOAD_FREG_FTN(WTH2, fr);
5841
        gen_op_float_nmuladd_ps();
5842
        GEN_STORE_FTN_FREG(fd, WT2);
5843
        GEN_STORE_FTN_FREG(fd, WTH2);
5844
        opn = "nmadd.ps";
5845
        break;
5846
    case OPC_NMSUB_S:
5847
        GEN_LOAD_FREG_FTN(WT0, fs);
5848
        GEN_LOAD_FREG_FTN(WT1, ft);
5849
        GEN_LOAD_FREG_FTN(WT2, fr);
5850
        gen_op_float_nmulsub_s();
5851
        GEN_STORE_FTN_FREG(fd, WT2);
5852
        opn = "nmsub.s";
5853
        break;
5854
    case OPC_NMSUB_D:
5855
        GEN_LOAD_FREG_FTN(DT0, fs);
5856
        GEN_LOAD_FREG_FTN(DT1, ft);
5857
        GEN_LOAD_FREG_FTN(DT2, fr);
5858
        gen_op_float_nmulsub_d();
5859
        GEN_STORE_FTN_FREG(fd, DT2);
5860
        opn = "nmsub.d";
5861
        break;
5862
    case OPC_NMSUB_PS:
5863
        GEN_LOAD_FREG_FTN(WT0, fs);
5864
        GEN_LOAD_FREG_FTN(WTH0, fs);
5865
        GEN_LOAD_FREG_FTN(WT1, ft);
5866
        GEN_LOAD_FREG_FTN(WTH1, ft);
5867
        GEN_LOAD_FREG_FTN(WT2, fr);
5868
        GEN_LOAD_FREG_FTN(WTH2, fr);
5869
        gen_op_float_nmulsub_ps();
5870
        GEN_STORE_FTN_FREG(fd, WT2);
5871
        GEN_STORE_FTN_FREG(fd, WTH2);
5872
        opn = "nmsub.ps";
5873
        break;
5874
    default:
5875
        MIPS_INVAL(opn);
5876
        generate_exception (ctx, EXCP_RI);
5877
        return;
5878
    }
5879
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5880
               fregnames[fs], fregnames[ft]);
5881
}
5882

    
5883
/* ISA extensions (ASEs) */
5884
/* MIPS16 extension to MIPS32 */
5885
/* SmartMIPS extension to MIPS32 */
5886

    
5887
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
5888

    
5889
/* MDMX extension to MIPS64 */
5890
/* MIPS-3D extension to MIPS64 */
5891

    
5892
#endif
5893

    
5894
static void decode_opc (CPUState *env, DisasContext *ctx)
5895
{
5896
    int32_t offset;
5897
    int rs, rt, rd, sa;
5898
    uint32_t op, op1, op2;
5899
    int16_t imm;
5900

    
5901
    /* make sure instructions are on a word boundary */
5902
    if (ctx->pc & 0x3) {
5903
        env->CP0_BadVAddr = ctx->pc;
5904
        generate_exception(ctx, EXCP_AdEL);
5905
        return;
5906
    }
5907

    
5908
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5909
        int l1;
5910
        /* Handle blikely not taken case */
5911
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5912
        l1 = gen_new_label();
5913
        gen_op_jnz_T2(l1);
5914
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5915
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5916
        gen_set_label(l1);
5917
    }
5918
    op = MASK_OP_MAJOR(ctx->opcode);
5919
    rs = (ctx->opcode >> 21) & 0x1f;
5920
    rt = (ctx->opcode >> 16) & 0x1f;
5921
    rd = (ctx->opcode >> 11) & 0x1f;
5922
    sa = (ctx->opcode >> 6) & 0x1f;
5923
    imm = (int16_t)ctx->opcode;
5924
    switch (op) {
5925
    case OPC_SPECIAL:
5926
        op1 = MASK_SPECIAL(ctx->opcode);
5927
        switch (op1) {
5928
        case OPC_SLL:          /* Arithmetic with immediate */
5929
        case OPC_SRL ... OPC_SRA:
5930
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
5931
            break;
5932
        case OPC_MOVZ ... OPC_MOVN:
5933
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5934
        case OPC_SLLV:         /* Arithmetic */
5935
        case OPC_SRLV ... OPC_SRAV:
5936
        case OPC_ADD ... OPC_NOR:
5937
        case OPC_SLT ... OPC_SLTU:
5938
            gen_arith(env, ctx, op1, rd, rs, rt);
5939
            break;
5940
        case OPC_MULT ... OPC_DIVU:
5941
            gen_muldiv(ctx, op1, rs, rt);
5942
            break;
5943
        case OPC_JR ... OPC_JALR:
5944
            gen_compute_branch(ctx, op1, rs, rd, sa);
5945
            return;
5946
        case OPC_TGE ... OPC_TEQ: /* Traps */
5947
        case OPC_TNE:
5948
            gen_trap(ctx, op1, rs, rt, -1);
5949
            break;
5950
        case OPC_MFHI:          /* Move from HI/LO */
5951
        case OPC_MFLO:
5952
            gen_HILO(ctx, op1, rd);
5953
            break;
5954
        case OPC_MTHI:
5955
        case OPC_MTLO:          /* Move to HI/LO */
5956
            gen_HILO(ctx, op1, rs);
5957
            break;
5958
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5959
#ifdef MIPS_STRICT_STANDARD
5960
            MIPS_INVAL("PMON / selsl");
5961
            generate_exception(ctx, EXCP_RI);
5962
#else
5963
            gen_op_pmon(sa);
5964
#endif
5965
            break;
5966
        case OPC_SYSCALL:
5967
            generate_exception(ctx, EXCP_SYSCALL);
5968
            break;
5969
        case OPC_BREAK:
5970
            generate_exception(ctx, EXCP_BREAK);
5971
            break;
5972
        case OPC_SPIM:
5973
#ifdef MIPS_STRICT_STANDARD
5974
            MIPS_INVAL("SPIM");
5975
            generate_exception(ctx, EXCP_RI);
5976
#else
5977
           /* Implemented as RI exception for now. */
5978
            MIPS_INVAL("spim (unofficial)");
5979
            generate_exception(ctx, EXCP_RI);
5980
#endif
5981
            break;
5982
        case OPC_SYNC:
5983
            /* Treat as NOP. */
5984
            break;
5985

    
5986
        case OPC_MOVCI:
5987
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5988
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5989
                save_cpu_state(ctx, 1);
5990
                check_cp1_enabled(ctx);
5991
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5992
                          (ctx->opcode >> 16) & 1);
5993
            } else {
5994
                generate_exception_err(ctx, EXCP_CpU, 1);
5995
            }
5996
            break;
5997

    
5998
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
5999
       /* MIPS64 specific opcodes */
6000
        case OPC_DSLL:
6001
        case OPC_DSRL ... OPC_DSRA:
6002
        case OPC_DSLL32:
6003
        case OPC_DSRL32 ... OPC_DSRA32:
6004
            check_insn(env, ctx, ISA_MIPS3);
6005
            check_mips_64(ctx);
6006
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6007
            break;
6008
        case OPC_DSLLV:
6009
        case OPC_DSRLV ... OPC_DSRAV:
6010
        case OPC_DADD ... OPC_DSUBU:
6011
            check_insn(env, ctx, ISA_MIPS3);
6012
            check_mips_64(ctx);
6013
            gen_arith(env, ctx, op1, rd, rs, rt);
6014
            break;
6015
        case OPC_DMULT ... OPC_DDIVU:
6016
            check_insn(env, ctx, ISA_MIPS3);
6017
            check_mips_64(ctx);
6018
            gen_muldiv(ctx, op1, rs, rt);
6019
            break;
6020
#endif
6021
        default:            /* Invalid */
6022
            MIPS_INVAL("special");
6023
            generate_exception(ctx, EXCP_RI);
6024
            break;
6025
        }
6026
        break;
6027
    case OPC_SPECIAL2:
6028
        op1 = MASK_SPECIAL2(ctx->opcode);
6029
        switch (op1) {
6030
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6031
        case OPC_MSUB ... OPC_MSUBU:
6032
            check_insn(env, ctx, ISA_MIPS32);
6033
            gen_muldiv(ctx, op1, rs, rt);
6034
            break;
6035
        case OPC_MUL:
6036
            gen_arith(env, ctx, op1, rd, rs, rt);
6037
            break;
6038
        case OPC_CLZ ... OPC_CLO:
6039
            check_insn(env, ctx, ISA_MIPS32);
6040
            gen_cl(ctx, op1, rd, rs);
6041
            break;
6042
        case OPC_SDBBP:
6043
            /* XXX: not clear which exception should be raised
6044
             *      when in debug mode...
6045
             */
6046
            check_insn(env, ctx, ISA_MIPS32);
6047
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6048
                generate_exception(ctx, EXCP_DBp);
6049
            } else {
6050
                generate_exception(ctx, EXCP_DBp);
6051
            }
6052
            /* Treat as NOP. */
6053
            break;
6054
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6055
        case OPC_DCLZ ... OPC_DCLO:
6056
            check_insn(env, ctx, ISA_MIPS64);
6057
            check_mips_64(ctx);
6058
            gen_cl(ctx, op1, rd, rs);
6059
            break;
6060
#endif
6061
        default:            /* Invalid */
6062
            MIPS_INVAL("special2");
6063
            generate_exception(ctx, EXCP_RI);
6064
            break;
6065
        }
6066
        break;
6067
    case OPC_SPECIAL3:
6068
         op1 = MASK_SPECIAL3(ctx->opcode);
6069
         switch (op1) {
6070
         case OPC_EXT:
6071
         case OPC_INS:
6072
             check_insn(env, ctx, ISA_MIPS32R2);
6073
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6074
             break;
6075
         case OPC_BSHFL:
6076
             check_insn(env, ctx, ISA_MIPS32R2);
6077
             op2 = MASK_BSHFL(ctx->opcode);
6078
             switch (op2) {
6079
             case OPC_WSBH:
6080
                 GEN_LOAD_REG_TN(T1, rt);
6081
                 gen_op_wsbh();
6082
                 break;
6083
             case OPC_SEB:
6084
                 GEN_LOAD_REG_TN(T1, rt);
6085
                 gen_op_seb();
6086
                 break;
6087
             case OPC_SEH:
6088
                 GEN_LOAD_REG_TN(T1, rt);
6089
                 gen_op_seh();
6090
                 break;
6091
             default:            /* Invalid */
6092
                 MIPS_INVAL("bshfl");
6093
                 generate_exception(ctx, EXCP_RI);
6094
                 break;
6095
            }
6096
            GEN_STORE_TN_REG(rd, T0);
6097
            break;
6098
        case OPC_RDHWR:
6099
            check_insn(env, ctx, ISA_MIPS32R2);
6100
            switch (rd) {
6101
            case 0:
6102
                save_cpu_state(ctx, 1);
6103
                gen_op_rdhwr_cpunum();
6104
                break;
6105
            case 1:
6106
                save_cpu_state(ctx, 1);
6107
                gen_op_rdhwr_synci_step();
6108
                break;
6109
            case 2:
6110
                save_cpu_state(ctx, 1);
6111
                gen_op_rdhwr_cc();
6112
                break;
6113
            case 3:
6114
                save_cpu_state(ctx, 1);
6115
                gen_op_rdhwr_ccres();
6116
                break;
6117
            case 29:
6118
#if defined (CONFIG_USER_ONLY)
6119
                gen_op_tls_value();
6120
                break;
6121
#endif
6122
            default:            /* Invalid */
6123
                MIPS_INVAL("rdhwr");
6124
                generate_exception(ctx, EXCP_RI);
6125
                break;
6126
            }
6127
            GEN_STORE_TN_REG(rt, T0);
6128
            break;
6129
        case OPC_FORK:
6130
            check_mips_mt(env, ctx);
6131
            GEN_LOAD_REG_TN(T0, rt);
6132
            GEN_LOAD_REG_TN(T1, rs);
6133
            gen_op_fork();
6134
            break;
6135
        case OPC_YIELD:
6136
            check_mips_mt(env, ctx);
6137
            GEN_LOAD_REG_TN(T0, rs);
6138
            gen_op_yield();
6139
            GEN_STORE_TN_REG(rd, T0);
6140
            break;
6141
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6142
        case OPC_DEXTM ... OPC_DEXT:
6143
        case OPC_DINSM ... OPC_DINS:
6144
            check_insn(env, ctx, ISA_MIPS64R2);
6145
            check_mips_64(ctx);
6146
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6147
            break;
6148
        case OPC_DBSHFL:
6149
            check_insn(env, ctx, ISA_MIPS64R2);
6150
            check_mips_64(ctx);
6151
            op2 = MASK_DBSHFL(ctx->opcode);
6152
            switch (op2) {
6153
            case OPC_DSBH:
6154
                GEN_LOAD_REG_TN(T1, rt);
6155
                gen_op_dsbh();
6156
                break;
6157
            case OPC_DSHD:
6158
                GEN_LOAD_REG_TN(T1, rt);
6159
                gen_op_dshd();
6160
                break;
6161
            default:            /* Invalid */
6162
                MIPS_INVAL("dbshfl");
6163
                generate_exception(ctx, EXCP_RI);
6164
                break;
6165
            }
6166
            GEN_STORE_TN_REG(rd, T0);
6167
#endif
6168
        default:            /* Invalid */
6169
            MIPS_INVAL("special3");
6170
            generate_exception(ctx, EXCP_RI);
6171
            break;
6172
        }
6173
        break;
6174
    case OPC_REGIMM:
6175
        op1 = MASK_REGIMM(ctx->opcode);
6176
        switch (op1) {
6177
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6178
        case OPC_BLTZAL ... OPC_BGEZALL:
6179
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6180
            return;
6181
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6182
        case OPC_TNEI:
6183
            gen_trap(ctx, op1, rs, -1, imm);
6184
            break;
6185
        case OPC_SYNCI:
6186
            check_insn(env, ctx, ISA_MIPS32R2);
6187
            /* Treat as NOP. */
6188
            break;
6189
        default:            /* Invalid */
6190
            MIPS_INVAL("regimm");
6191
            generate_exception(ctx, EXCP_RI);
6192
            break;
6193
        }
6194
        break;
6195
    case OPC_CP0:
6196
        check_cp0_enabled(ctx);
6197
        op1 = MASK_CP0(ctx->opcode);
6198
        switch (op1) {
6199
        case OPC_MFC0:
6200
        case OPC_MTC0:
6201
        case OPC_MFTR:
6202
        case OPC_MTTR:
6203
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6204
        case OPC_DMFC0:
6205
        case OPC_DMTC0:
6206
#endif
6207
            gen_cp0(env, ctx, op1, rt, rd);
6208
            break;
6209
        case OPC_C0_FIRST ... OPC_C0_LAST:
6210
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6211
            break;
6212
        case OPC_MFMC0:
6213
            op2 = MASK_MFMC0(ctx->opcode);
6214
            switch (op2) {
6215
            case OPC_DMT:
6216
                check_mips_mt(env, ctx);
6217
                gen_op_dmt();
6218
                break;
6219
            case OPC_EMT:
6220
                check_mips_mt(env, ctx);
6221
                gen_op_emt();
6222
                break;
6223
            case OPC_DVPE:
6224
                check_mips_mt(env, ctx);
6225
                gen_op_dvpe();
6226
                break;
6227
            case OPC_EVPE:
6228
                check_mips_mt(env, ctx);
6229
                gen_op_evpe();
6230
                break;
6231
            case OPC_DI:
6232
                check_insn(env, ctx, ISA_MIPS32R2);
6233
                save_cpu_state(ctx, 1);
6234
                gen_op_di();
6235
                /* Stop translation as we may have switched the execution mode */
6236
                ctx->bstate = BS_STOP;
6237
                break;
6238
            case OPC_EI:
6239
                check_insn(env, ctx, ISA_MIPS32R2);
6240
                save_cpu_state(ctx, 1);
6241
                gen_op_ei();
6242
                /* Stop translation as we may have switched the execution mode */
6243
                ctx->bstate = BS_STOP;
6244
                break;
6245
            default:            /* Invalid */
6246
                MIPS_INVAL("mfmc0");
6247
                generate_exception(ctx, EXCP_RI);
6248
                break;
6249
            }
6250
            GEN_STORE_TN_REG(rt, T0);
6251
            break;
6252
        case OPC_RDPGPR:
6253
            check_insn(env, ctx, ISA_MIPS32R2);
6254
            GEN_LOAD_SRSREG_TN(T0, rt);
6255
            GEN_STORE_TN_REG(rd, T0);
6256
            break;
6257
        case OPC_WRPGPR:
6258
            check_insn(env, ctx, ISA_MIPS32R2);
6259
            GEN_LOAD_REG_TN(T0, rt);
6260
            GEN_STORE_TN_SRSREG(rd, T0);
6261
            break;
6262
        default:
6263
            MIPS_INVAL("cp0");
6264
            generate_exception(ctx, EXCP_RI);
6265
            break;
6266
        }
6267
        break;
6268
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6269
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6270
         break;
6271
    case OPC_J ... OPC_JAL: /* Jump */
6272
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6273
         gen_compute_branch(ctx, op, rs, rt, offset);
6274
         return;
6275
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6276
    case OPC_BEQL ... OPC_BGTZL:
6277
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6278
         return;
6279
    case OPC_LB ... OPC_LWR: /* Load and stores */
6280
    case OPC_SB ... OPC_SW:
6281
    case OPC_SWR:
6282
    case OPC_LL:
6283
    case OPC_SC:
6284
         gen_ldst(ctx, op, rt, rs, imm);
6285
         break;
6286
    case OPC_CACHE:
6287
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6288
        /* Treat as NOP. */
6289
        break;
6290
    case OPC_PREF:
6291
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6292
        /* Treat as NOP. */
6293
        break;
6294

    
6295
    /* Floating point (COP1). */
6296
    case OPC_LWC1:
6297
    case OPC_LDC1:
6298
    case OPC_SWC1:
6299
    case OPC_SDC1:
6300
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6301
            save_cpu_state(ctx, 1);
6302
            check_cp1_enabled(ctx);
6303
            gen_flt_ldst(ctx, op, rt, rs, imm);
6304
        } else {
6305
            generate_exception_err(ctx, EXCP_CpU, 1);
6306
        }
6307
        break;
6308

    
6309
    case OPC_CP1:
6310
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6311
            save_cpu_state(ctx, 1);
6312
            check_cp1_enabled(ctx);
6313
            op1 = MASK_CP1(ctx->opcode);
6314
            switch (op1) {
6315
            case OPC_MFHC1:
6316
            case OPC_MTHC1:
6317
                check_insn(env, ctx, ISA_MIPS32R2);
6318
            case OPC_MFC1:
6319
            case OPC_CFC1:
6320
            case OPC_MTC1:
6321
            case OPC_CTC1:
6322
                gen_cp1(ctx, op1, rt, rd);
6323
                break;
6324
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6325
            case OPC_DMFC1:
6326
            case OPC_DMTC1:
6327
                check_insn(env, ctx, ISA_MIPS3);
6328
                gen_cp1(ctx, op1, rt, rd);
6329
                break;
6330
#endif
6331
            case OPC_BC1:
6332
            case OPC_BC1ANY2:
6333
            case OPC_BC1ANY4:
6334
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6335
                                    (rt >> 2) & 0x7, imm << 2);
6336
                return;
6337
            case OPC_S_FMT:
6338
            case OPC_D_FMT:
6339
            case OPC_W_FMT:
6340
            case OPC_L_FMT:
6341
            case OPC_PS_FMT:
6342
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6343
                           (imm >> 8) & 0x7);
6344
                break;
6345
            default:
6346
                MIPS_INVAL("cp1");
6347
                generate_exception (ctx, EXCP_RI);
6348
                break;
6349
            }
6350
        } else {
6351
            generate_exception_err(ctx, EXCP_CpU, 1);
6352
        }
6353
        break;
6354

    
6355
    /* COP2.  */
6356
    case OPC_LWC2:
6357
    case OPC_LDC2:
6358
    case OPC_SWC2:
6359
    case OPC_SDC2:
6360
    case OPC_CP2:
6361
        /* COP2: Not implemented. */
6362
        generate_exception_err(ctx, EXCP_CpU, 2);
6363
        break;
6364

    
6365
    case OPC_CP3:
6366
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6367
            save_cpu_state(ctx, 1);
6368
            check_cp1_enabled(ctx);
6369
            op1 = MASK_CP3(ctx->opcode);
6370
            switch (op1) {
6371
            case OPC_LWXC1:
6372
            case OPC_LDXC1:
6373
            case OPC_LUXC1:
6374
            case OPC_SWXC1:
6375
            case OPC_SDXC1:
6376
            case OPC_SUXC1:
6377
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6378
                break;
6379
            case OPC_PREFX:
6380
                /* Treat as NOP. */
6381
                break;
6382
            case OPC_ALNV_PS:
6383
            case OPC_MADD_S:
6384
            case OPC_MADD_D:
6385
            case OPC_MADD_PS:
6386
            case OPC_MSUB_S:
6387
            case OPC_MSUB_D:
6388
            case OPC_MSUB_PS:
6389
            case OPC_NMADD_S:
6390
            case OPC_NMADD_D:
6391
            case OPC_NMADD_PS:
6392
            case OPC_NMSUB_S:
6393
            case OPC_NMSUB_D:
6394
            case OPC_NMSUB_PS:
6395
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6396
                break;
6397
            default:
6398
                MIPS_INVAL("cp3");
6399
                generate_exception (ctx, EXCP_RI);
6400
                break;
6401
            }
6402
        } else {
6403
            generate_exception_err(ctx, EXCP_CpU, 1);
6404
        }
6405
        break;
6406

    
6407
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6408
    /* MIPS64 opcodes */
6409
    case OPC_LWU:
6410
    case OPC_LDL ... OPC_LDR:
6411
    case OPC_SDL ... OPC_SDR:
6412
    case OPC_LLD:
6413
    case OPC_LD:
6414
    case OPC_SCD:
6415
    case OPC_SD:
6416
        check_insn(env, ctx, ISA_MIPS3);
6417
        check_mips_64(ctx);
6418
        gen_ldst(ctx, op, rt, rs, imm);
6419
        break;
6420
    case OPC_DADDI ... OPC_DADDIU:
6421
        check_insn(env, ctx, ISA_MIPS3);
6422
        check_mips_64(ctx);
6423
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6424
        break;
6425
#endif
6426
    case OPC_JALX:
6427
        check_insn(env, ctx, ASE_MIPS16);
6428
        /* MIPS16: Not implemented. */
6429
    case OPC_MDMX:
6430
        check_insn(env, ctx, ASE_MDMX);
6431
        /* MDMX: Not implemented. */
6432
    default:            /* Invalid */
6433
        MIPS_INVAL("major opcode");
6434
        generate_exception(ctx, EXCP_RI);
6435
        break;
6436
    }
6437
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6438
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6439
        /* Branches completion */
6440
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6441
        ctx->bstate = BS_BRANCH;
6442
        save_cpu_state(ctx, 0);
6443
        switch (hflags) {
6444
        case MIPS_HFLAG_B:
6445
            /* unconditional branch */
6446
            MIPS_DEBUG("unconditional branch");
6447
            gen_goto_tb(ctx, 0, ctx->btarget);
6448
            break;
6449
        case MIPS_HFLAG_BL:
6450
            /* blikely taken case */
6451
            MIPS_DEBUG("blikely branch taken");
6452
            gen_goto_tb(ctx, 0, ctx->btarget);
6453
            break;
6454
        case MIPS_HFLAG_BC:
6455
            /* Conditional branch */
6456
            MIPS_DEBUG("conditional branch");
6457
            {
6458
              int l1;
6459
              l1 = gen_new_label();
6460
              gen_op_jnz_T2(l1);
6461
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6462
              gen_set_label(l1);
6463
              gen_goto_tb(ctx, 0, ctx->btarget);
6464
            }
6465
            break;
6466
        case MIPS_HFLAG_BR:
6467
            /* unconditional branch to register */
6468
            MIPS_DEBUG("branch to register");
6469
            gen_op_breg();
6470
            gen_op_reset_T0();
6471
            gen_op_exit_tb();
6472
            break;
6473
        default:
6474
            MIPS_DEBUG("unknown branch");
6475
            break;
6476
        }
6477
    }
6478
}
6479

    
6480
static inline int
6481
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6482
                                int search_pc)
6483
{
6484
    DisasContext ctx;
6485
    target_ulong pc_start;
6486
    uint16_t *gen_opc_end;
6487
    int j, lj = -1;
6488

    
6489
    if (search_pc && loglevel)
6490
        fprintf (logfile, "search pc %d\n", search_pc);
6491

    
6492
    pc_start = tb->pc;
6493
    gen_opc_ptr = gen_opc_buf;
6494
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6495
    gen_opparam_ptr = gen_opparam_buf;
6496
    nb_gen_labels = 0;
6497
    ctx.pc = pc_start;
6498
    ctx.saved_pc = -1;
6499
    ctx.tb = tb;
6500
    ctx.bstate = BS_NONE;
6501
    /* Restore delay slot state from the tb context.  */
6502
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6503
    restore_cpu_state(env, &ctx);
6504
#if defined(CONFIG_USER_ONLY)
6505
    ctx.mem_idx = 0;
6506
#else
6507
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
6508
#endif
6509
#ifdef DEBUG_DISAS
6510
    if (loglevel & CPU_LOG_TB_CPU) {
6511
        fprintf(logfile, "------------------------------------------------\n");
6512
        /* FIXME: This may print out stale hflags from env... */
6513
        cpu_dump_state(env, logfile, fprintf, 0);
6514
    }
6515
#endif
6516
#ifdef MIPS_DEBUG_DISAS
6517
    if (loglevel & CPU_LOG_TB_IN_ASM)
6518
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
6519
                tb, ctx.mem_idx, ctx.hflags);
6520
#endif
6521
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6522
        if (env->nb_breakpoints > 0) {
6523
            for(j = 0; j < env->nb_breakpoints; j++) {
6524
                if (env->breakpoints[j] == ctx.pc) {
6525
                    save_cpu_state(&ctx, 1);
6526
                    ctx.bstate = BS_BRANCH;
6527
                    gen_op_debug();
6528
                    /* Include the breakpoint location or the tb won't
6529
                     * be flushed when it must be.  */
6530
                    ctx.pc += 4;
6531
                    goto done_generating;
6532
                }
6533
            }
6534
        }
6535

    
6536
        if (search_pc) {
6537
            j = gen_opc_ptr - gen_opc_buf;
6538
            if (lj < j) {
6539
                lj++;
6540
                while (lj < j)
6541
                    gen_opc_instr_start[lj++] = 0;
6542
            }
6543
            gen_opc_pc[lj] = ctx.pc;
6544
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6545
            gen_opc_instr_start[lj] = 1;
6546
        }
6547
        ctx.opcode = ldl_code(ctx.pc);
6548
        decode_opc(env, &ctx);
6549
        ctx.pc += 4;
6550

    
6551
        if (env->singlestep_enabled)
6552
            break;
6553

    
6554
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6555
            break;
6556

    
6557
#if defined (MIPS_SINGLE_STEP)
6558
        break;
6559
#endif
6560
    }
6561
    if (env->singlestep_enabled) {
6562
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6563
        gen_op_debug();
6564
    } else {
6565
        switch (ctx.bstate) {
6566
        case BS_STOP:
6567
            gen_op_interrupt_restart();
6568
            gen_goto_tb(&ctx, 0, ctx.pc);
6569
            break;
6570
        case BS_NONE:
6571
            save_cpu_state(&ctx, 0);
6572
            gen_goto_tb(&ctx, 0, ctx.pc);
6573
            break;
6574
        case BS_EXCP:
6575
            gen_op_interrupt_restart();
6576
            gen_op_reset_T0();
6577
            gen_op_exit_tb();
6578
            break;
6579
        case BS_BRANCH:
6580
        default:
6581
            break;
6582
        }
6583
    }
6584
done_generating:
6585
    *gen_opc_ptr = INDEX_op_end;
6586
    if (search_pc) {
6587
        j = gen_opc_ptr - gen_opc_buf;
6588
        lj++;
6589
        while (lj <= j)
6590
            gen_opc_instr_start[lj++] = 0;
6591
    } else {
6592
        tb->size = ctx.pc - pc_start;
6593
    }
6594
#ifdef DEBUG_DISAS
6595
#if defined MIPS_DEBUG_DISAS
6596
    if (loglevel & CPU_LOG_TB_IN_ASM)
6597
        fprintf(logfile, "\n");
6598
#endif
6599
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6600
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6601
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6602
        fprintf(logfile, "\n");
6603
    }
6604
    if (loglevel & CPU_LOG_TB_OP) {
6605
        fprintf(logfile, "OP:\n");
6606
        dump_ops(gen_opc_buf, gen_opparam_buf);
6607
        fprintf(logfile, "\n");
6608
    }
6609
    if (loglevel & CPU_LOG_TB_CPU) {
6610
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6611
    }
6612
#endif
6613

    
6614
    return 0;
6615
}
6616

    
6617
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6618
{
6619
    return gen_intermediate_code_internal(env, tb, 0);
6620
}
6621

    
6622
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6623
{
6624
    return gen_intermediate_code_internal(env, tb, 1);
6625
}
6626

    
6627
void fpu_dump_state(CPUState *env, FILE *f,
6628
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6629
                    int flags)
6630
{
6631
    int i;
6632
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6633

    
6634
#define printfpr(fp)                                                        \
6635
    do {                                                                    \
6636
        if (is_fpu64)                                                       \
6637
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6638
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6639
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6640
        else {                                                              \
6641
            fpr_t tmp;                                                      \
6642
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6643
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6644
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6645
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6646
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6647
        }                                                                   \
6648
    } while(0)
6649

    
6650

    
6651
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6652
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6653
                get_float_exception_flags(&env->fpu->fp_status));
6654
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6655
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6656
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6657
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6658
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6659
        printfpr(&env->fpu->fpr[i]);
6660
    }
6661

    
6662
#undef printfpr
6663
}
6664

    
6665
void dump_fpu (CPUState *env)
6666
{
6667
    if (loglevel) {
6668
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6669
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6670
       fpu_dump_state(env, logfile, fprintf, 0);
6671
    }
6672
}
6673

    
6674
#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6675
/* Debug help: The architecture requires 32bit code to maintain proper
6676
   sign-extened values on 64bit machines.  */
6677

    
6678
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6679

    
6680
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6681
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6682
                     int flags)
6683
{
6684
    int i;
6685

    
6686
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6687
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6688
    if (!SIGN_EXT_P(env->HI[env->current_tc]))
6689
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc]);
6690
    if (!SIGN_EXT_P(env->LO[env->current_tc]))
6691
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc]);
6692
    if (!SIGN_EXT_P(env->btarget))
6693
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6694

    
6695
    for (i = 0; i < 32; i++) {
6696
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6697
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6698
    }
6699

    
6700
    if (!SIGN_EXT_P(env->CP0_EPC))
6701
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6702
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6703
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6704
}
6705
#endif
6706

    
6707
void cpu_dump_state (CPUState *env, FILE *f,
6708
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6709
                     int flags)
6710
{
6711
    int i;
6712

    
6713
    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",
6714
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6715
    for (i = 0; i < 32; i++) {
6716
        if ((i & 3) == 0)
6717
            cpu_fprintf(f, "GPR%02d:", i);
6718
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6719
        if ((i & 3) == 3)
6720
            cpu_fprintf(f, "\n");
6721
    }
6722

    
6723
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6724
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6725
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6726
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6727
    if (env->hflags & MIPS_HFLAG_FPU)
6728
        fpu_dump_state(env, f, cpu_fprintf, flags);
6729
#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6730
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6731
#endif
6732
}
6733

    
6734
CPUMIPSState *cpu_mips_init (void)
6735
{
6736
    CPUMIPSState *env;
6737

    
6738
    env = qemu_mallocz(sizeof(CPUMIPSState));
6739
    if (!env)
6740
        return NULL;
6741
    cpu_exec_init(env);
6742
    cpu_reset(env);
6743
    return env;
6744
}
6745

    
6746
void cpu_reset (CPUMIPSState *env)
6747
{
6748
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6749

    
6750
    tlb_flush(env, 1);
6751

    
6752
    /* Minimal init */
6753
#if !defined(CONFIG_USER_ONLY)
6754
    if (env->hflags & MIPS_HFLAG_BMASK) {
6755
        /* If the exception was raised from a delay slot,
6756
         * come back to the jump.  */
6757
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6758
    } else {
6759
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6760
    }
6761
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6762
    env->CP0_Wired = 0;
6763
    /* SMP not implemented */
6764
    env->CP0_EBase = 0x80000000;
6765
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6766
    /* vectored interrupts not implemented, timer on int 7,
6767
       no performance counters. */
6768
    env->CP0_IntCtl = 0xe0000000;
6769
    {
6770
        int i;
6771

    
6772
        for (i = 0; i < 7; i++) {
6773
            env->CP0_WatchLo[i] = 0;
6774
            env->CP0_WatchHi[i] = 0x80000000;
6775
        }
6776
        env->CP0_WatchLo[7] = 0;
6777
        env->CP0_WatchHi[7] = 0;
6778
    }
6779
    /* Count register increments in debug mode, EJTAG version 1 */
6780
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6781
#endif
6782
    env->exception_index = EXCP_NONE;
6783
#if defined(CONFIG_USER_ONLY)
6784
    env->hflags = MIPS_HFLAG_UM;
6785
    env->user_mode_only = 1;
6786
#else
6787
    env->hflags = MIPS_HFLAG_CP0;
6788
#endif
6789
}
6790

    
6791
#include "translate_init.c"