Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 9f77c1cd

History | View | Annotate | Download (185.6 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##_user,                                                  \
794
    &gen_op_l##width##_kernel,                                                \
795
}
796
#define OP_ST_TABLE(width)                                                    \
797
static GenOpFunc *gen_op_s##width[] = {                                       \
798
    &gen_op_s##width##_user,                                                  \
799
    &gen_op_s##width##_kernel,                                                \
800
}
801
#endif
802

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1949
    if (sel != 0)
1950
        check_insn(env, ctx, ISA_MIPS32);
1951

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

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

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

    
2517
    if (sel != 0)
2518
        check_insn(env, ctx, ISA_MIPS32);
2519

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

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

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

    
3117
    if (sel != 0)
3118
        check_insn(env, ctx, ISA_MIPS64);
3119

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

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

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

    
3674
    if (sel != 0)
3675
        check_insn(env, ctx, ISA_MIPS64);
3676

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

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

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

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

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

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

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

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

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

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