Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 855cea8c

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

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

    
777
/* This code generates a "reserved instruction" exception if 64-bit
778
   instructions are not enabled. */
779
static always_inline void check_mips_64(DisasContext *ctx)
780
{
781
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
782
        generate_exception(ctx, EXCP_RI);
783
}
784

    
785
#if defined(CONFIG_USER_ONLY)
786
#define op_ldst(name)        gen_op_##name##_raw()
787
#define OP_LD_TABLE(width)
788
#define OP_ST_TABLE(width)
789
#else
790
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
791
#define OP_LD_TABLE(width)                                                    \
792
static GenOpFunc *gen_op_l##width[] = {                                       \
793
    &gen_op_l##width##_kernel,                                                \
794
    &gen_op_l##width##_super,                                                 \
795
    &gen_op_l##width##_user,                                                  \
796
}
797
#define OP_ST_TABLE(width)                                                    \
798
static GenOpFunc *gen_op_s##width[] = {                                       \
799
    &gen_op_s##width##_kernel,                                                \
800
    &gen_op_s##width##_super,                                                 \
801
    &gen_op_s##width##_user,                                                  \
802
}
803
#endif
804

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

    
837
/* Load and store */
838
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
839
                      int base, int16_t offset)
840
{
841
    const char *opn = "ldst";
842

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

    
988
/* Load and store */
989
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
990
                      int base, int16_t offset)
991
{
992
    const char *opn = "flt_ldst";
993

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

    
1034
/* Arithmetic with immediate operand */
1035
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1036
                           int rt, int rs, int16_t imm)
1037
{
1038
    target_ulong uimm;
1039
    const char *opn = "imm arith";
1040

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

    
1229
/* Arithmetic */
1230
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1231
                       int rd, int rs, int rt)
1232
{
1233
    const char *opn = "arith";
1234

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

    
1391
/* Arithmetic on HI/LO registers */
1392
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1393
{
1394
    const char *opn = "hilo";
1395

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

    
1430
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1431
                        int rs, int rt)
1432
{
1433
    const char *opn = "mul/div";
1434

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

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

    
1534
/* Traps */
1535
static void gen_trap (DisasContext *ctx, uint32_t opc,
1536
                      int rs, int rt, int16_t imm)
1537
{
1538
    int cond;
1539

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

    
1631
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1632
{
1633
    TranslationBlock *tb;
1634
    tb = ctx->tb;
1635
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1636
        if (n == 0)
1637
            gen_op_goto_tb0(TBPARAM(tb));
1638
        else
1639
            gen_op_goto_tb1(TBPARAM(tb));
1640
        gen_save_pc(dest);
1641
        gen_op_set_T0((long)tb + n);
1642
    } else {
1643
        gen_save_pc(dest);
1644
        gen_op_reset_T0();
1645
    }
1646
    gen_op_exit_tb();
1647
}
1648

    
1649
/* Branches (before delay slot) */
1650
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1651
                                int rs, int rt, int32_t offset)
1652
{
1653
    target_ulong btarget = -1;
1654
    int blink = 0;
1655
    int bcond = 0;
1656

    
1657
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1658
#ifdef MIPS_DEBUG_DISAS
1659
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1660
            fprintf(logfile,
1661
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1662
                    ctx->pc);
1663
        }
1664
#endif
1665
        generate_exception(ctx, EXCP_RI);
1666
        return;
1667
    }
1668

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

    
1882
    ctx->btarget = btarget;
1883
    if (blink > 0) {
1884
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1885
        gen_op_store_T0_gpr(blink);
1886
    }
1887
}
1888

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

    
1946
/* CP0 (MMU and control) */
1947
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1948
{
1949
    const char *rn = "invalid";
1950

    
1951
    if (sel != 0)
1952
        check_insn(env, ctx, ISA_MIPS32);
1953

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

    
2505
die:
2506
#if defined MIPS_DEBUG_DISAS
2507
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2508
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2509
                rn, reg, sel);
2510
    }
2511
#endif
2512
    generate_exception(ctx, EXCP_RI);
2513
}
2514

    
2515
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2516
{
2517
    const char *rn = "invalid";
2518

    
2519
    if (sel != 0)
2520
        check_insn(env, ctx, ISA_MIPS32);
2521

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

    
3104
die:
3105
#if defined MIPS_DEBUG_DISAS
3106
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3107
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3108
                rn, reg, sel);
3109
    }
3110
#endif
3111
    generate_exception(ctx, EXCP_RI);
3112
}
3113

    
3114
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
3115
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3116
{
3117
    const char *rn = "invalid";
3118

    
3119
    if (sel != 0)
3120
        check_insn(env, ctx, ISA_MIPS64);
3121

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

    
3662
die:
3663
#if defined MIPS_DEBUG_DISAS
3664
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3665
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3666
                rn, reg, sel);
3667
    }
3668
#endif
3669
    generate_exception(ctx, EXCP_RI);
3670
}
3671

    
3672
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3673
{
3674
    const char *rn = "invalid";
3675

    
3676
    if (sel != 0)
3677
        check_insn(env, ctx, ISA_MIPS64);
3678

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

    
4248
die:
4249
#if defined MIPS_DEBUG_DISAS
4250
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4251
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4252
                rn, reg, sel);
4253
    }
4254
#endif
4255
    generate_exception(ctx, EXCP_RI);
4256
}
4257
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
4258

    
4259
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4260
                     int u, int sel, int h)
4261
{
4262
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4263

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

    
4413
die:
4414
#if defined MIPS_DEBUG_DISAS
4415
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4416
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4417
                rt, u, sel, h);
4418
    }
4419
#endif
4420
    generate_exception(ctx, EXCP_RI);
4421
}
4422

    
4423
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4424
                     int u, int sel, int h)
4425
{
4426
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4427

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

    
4577
die:
4578
#if defined MIPS_DEBUG_DISAS
4579
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4580
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4581
                rd, u, sel, h);
4582
    }
4583
#endif
4584
    generate_exception(ctx, EXCP_RI);
4585
}
4586

    
4587
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4588
{
4589
    const char *opn = "ldst";
4590

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