Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d8a5950a

History | View | Annotate | Download (185.7 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 always_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 always_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 always_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 always_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 always_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 always_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 always_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 always_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 always_inline void generate_exception (DisasContext *ctx, int excp)
730
{
731
    generate_exception_err (ctx, excp, 0);
732
}
733

    
734
static always_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 always_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 always_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
static always_inline void check_cp1_3d(CPUState *env, DisasContext *ctx)
753
{
754
    if (unlikely(!(env->fpu->fcr0 & (1 << FCR0_3D))))
755
        generate_exception(ctx, EXCP_RI);
756
}
757

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

    
775
/* This code generates a "reserved instruction" exception if the
776
   CPU does not support the instruction set corresponding to flags. */
777
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
778
{
779
    if (unlikely(!(env->insn_flags & flags)))
780
        generate_exception(ctx, EXCP_RI);
781
}
782

    
783
/* This code generates a "reserved instruction" exception if the
784
   CPU is not MIPS MT capable. */
785
static always_inline void check_mips_mt(CPUState *env, DisasContext *ctx)
786
{
787
    if (unlikely(!(env->CP0_Config3 & (1 << CP0C3_MT))))
788
        generate_exception(ctx, EXCP_RI);
789
}
790

    
791
/* This code generates a "reserved instruction" exception if 64-bit
792
   instructions are not enabled. */
793
static always_inline void check_mips_64(DisasContext *ctx)
794
{
795
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
796
        generate_exception(ctx, EXCP_RI);
797
}
798

    
799
#if defined(CONFIG_USER_ONLY)
800
#define op_ldst(name)        gen_op_##name##_raw()
801
#define OP_LD_TABLE(width)
802
#define OP_ST_TABLE(width)
803
#else
804
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
805
#define OP_LD_TABLE(width)                                                    \
806
static GenOpFunc *gen_op_l##width[] = {                                       \
807
    &gen_op_l##width##_user,                                                  \
808
    &gen_op_l##width##_kernel,                                                \
809
}
810
#define OP_ST_TABLE(width)                                                    \
811
static GenOpFunc *gen_op_s##width[] = {                                       \
812
    &gen_op_s##width##_user,                                                  \
813
    &gen_op_s##width##_kernel,                                                \
814
}
815
#endif
816

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

    
849
/* Load and store */
850
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
851
                      int base, int16_t offset)
852
{
853
    const char *opn = "ldst";
854

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

    
1000
/* Load and store */
1001
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1002
                      int base, int16_t offset)
1003
{
1004
    const char *opn = "flt_ldst";
1005

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

    
1046
/* Arithmetic with immediate operand */
1047
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1048
                           int rt, int rs, int16_t imm)
1049
{
1050
    target_ulong uimm;
1051
    const char *opn = "imm arith";
1052

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

    
1241
/* Arithmetic */
1242
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1243
                       int rd, int rs, int rt)
1244
{
1245
    const char *opn = "arith";
1246

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

    
1403
/* Arithmetic on HI/LO registers */
1404
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1405
{
1406
    const char *opn = "hilo";
1407

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

    
1442
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1443
                        int rs, int rt)
1444
{
1445
    const char *opn = "mul/div";
1446

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

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

    
1546
/* Traps */
1547
static void gen_trap (DisasContext *ctx, uint32_t opc,
1548
                      int rs, int rt, int16_t imm)
1549
{
1550
    int cond;
1551

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

    
1643
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1644
{
1645
    TranslationBlock *tb;
1646
    tb = ctx->tb;
1647
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1648
        if (n == 0)
1649
            gen_op_goto_tb0(TBPARAM(tb));
1650
        else
1651
            gen_op_goto_tb1(TBPARAM(tb));
1652
        gen_save_pc(dest);
1653
        gen_op_set_T0((long)tb + n);
1654
    } else {
1655
        gen_save_pc(dest);
1656
        gen_op_reset_T0();
1657
    }
1658
    gen_op_exit_tb();
1659
}
1660

    
1661
/* Branches (before delay slot) */
1662
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1663
                                int rs, int rt, int32_t offset)
1664
{
1665
    target_ulong btarget = -1;
1666
    int blink = 0;
1667
    int bcond = 0;
1668

    
1669
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1670
#ifdef MIPS_DEBUG_DISAS
1671
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1672
            fprintf(logfile,
1673
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1674
                    ctx->pc);
1675
        }
1676
#endif
1677
        generate_exception(ctx, EXCP_RI);
1678
        return;
1679
    }
1680

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

    
1894
    ctx->btarget = btarget;
1895
    if (blink > 0) {
1896
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1897
        gen_op_store_T0_gpr(blink);
1898
    }
1899
}
1900

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

    
1958
/* CP0 (MMU and control) */
1959
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1960
{
1961
    const char *rn = "invalid";
1962

    
1963
    if (sel != 0)
1964
        check_insn(env, ctx, ISA_MIPS32);
1965

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

    
2517
die:
2518
#if defined MIPS_DEBUG_DISAS
2519
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2520
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2521
                rn, reg, sel);
2522
    }
2523
#endif
2524
    generate_exception(ctx, EXCP_RI);
2525
}
2526

    
2527
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2528
{
2529
    const char *rn = "invalid";
2530

    
2531
    if (sel != 0)
2532
        check_insn(env, ctx, ISA_MIPS32);
2533

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

    
3116
die:
3117
#if defined MIPS_DEBUG_DISAS
3118
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3119
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3120
                rn, reg, sel);
3121
    }
3122
#endif
3123
    generate_exception(ctx, EXCP_RI);
3124
}
3125

    
3126
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
3127
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3128
{
3129
    const char *rn = "invalid";
3130

    
3131
    if (sel != 0)
3132
        check_insn(env, ctx, ISA_MIPS64);
3133

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

    
3674
die:
3675
#if defined MIPS_DEBUG_DISAS
3676
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3677
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3678
                rn, reg, sel);
3679
    }
3680
#endif
3681
    generate_exception(ctx, EXCP_RI);
3682
}
3683

    
3684
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3685
{
3686
    const char *rn = "invalid";
3687

    
3688
    if (sel != 0)
3689
        check_insn(env, ctx, ISA_MIPS64);
3690

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

    
4260
die:
4261
#if defined MIPS_DEBUG_DISAS
4262
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4263
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4264
                rn, reg, sel);
4265
    }
4266
#endif
4267
    generate_exception(ctx, EXCP_RI);
4268
}
4269
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
4270

    
4271
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4272
                     int u, int sel, int h)
4273
{
4274
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4275

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

    
4425
die:
4426
#if defined MIPS_DEBUG_DISAS
4427
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4428
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4429
                rt, u, sel, h);
4430
    }
4431
#endif
4432
    generate_exception(ctx, EXCP_RI);
4433
}
4434

    
4435
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4436
                     int u, int sel, int h)
4437
{
4438
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4439

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

    
4589
die:
4590
#if defined MIPS_DEBUG_DISAS
4591
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4592
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4593
                rd, u, sel, h);
4594
    }
4595
#endif
4596
    generate_exception(ctx, EXCP_RI);
4597
}
4598

    
4599
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4600
{
4601
    const char *opn = "ldst";
4602

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