Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 5fafdf24

History | View | Annotate | Download (180.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,
146
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
147
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
148
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
149
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
150
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
151
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
152
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
153
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
154
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
156
    /* Multiplication / division */
157
    OPC_MULT     = 0x18 | OPC_SPECIAL,
158
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
159
    OPC_DIV      = 0x1A | OPC_SPECIAL,
160
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
161
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
162
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
163
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
164
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
165
    /* 2 registers arithmetic / logic */
166
    OPC_ADD      = 0x20 | OPC_SPECIAL,
167
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
168
    OPC_SUB      = 0x22 | OPC_SPECIAL,
169
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
170
    OPC_AND      = 0x24 | OPC_SPECIAL,
171
    OPC_OR       = 0x25 | OPC_SPECIAL,
172
    OPC_XOR      = 0x26 | OPC_SPECIAL,
173
    OPC_NOR      = 0x27 | OPC_SPECIAL,
174
    OPC_SLT      = 0x2A | OPC_SPECIAL,
175
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
176
    OPC_DADD     = 0x2C | OPC_SPECIAL,
177
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
178
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
179
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
180
    /* Jumps */
181
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
183
    /* Traps */
184
    OPC_TGE      = 0x30 | OPC_SPECIAL,
185
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
186
    OPC_TLT      = 0x32 | OPC_SPECIAL,
187
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
188
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
189
    OPC_TNE      = 0x36 | OPC_SPECIAL,
190
    /* HI / LO registers load & stores */
191
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
192
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
193
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
194
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
195
    /* Conditional moves */
196
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
198

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
420

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
740
static inline void check_cp1_64bitmode(DisasContext *ctx)
741
{
742
    if (!(ctx->hflags & MIPS_HFLAG_F64))
743
        generate_exception(ctx, EXCP_RI);
744
}
745

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

    
763
/* This code generates a "reserved instruction" exception if the
764
   CPU is not a MIPS R2 (or higher) CPU. */
765
static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
766
{
767
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) < (1 << CP0C0_AR))
768
        generate_exception(ctx, EXCP_RI);
769
}
770

    
771
/* This code generates a "reserved instruction" exception if the
772
   CPU is not MIPS MT capable. */
773
static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
774
{
775
    if (!(env->CP0_Config3 & (1 << CP0C3_MT)))
776
        generate_exception(ctx, EXCP_RI);
777
}
778

    
779
#if defined(CONFIG_USER_ONLY)
780
#define op_ldst(name)        gen_op_##name##_raw()
781
#define OP_LD_TABLE(width)
782
#define OP_ST_TABLE(width)
783
#else
784
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
785
#define OP_LD_TABLE(width)                                                    \
786
static GenOpFunc *gen_op_l##width[] = {                                       \
787
    &gen_op_l##width##_user,                                                  \
788
    &gen_op_l##width##_kernel,                                                \
789
}
790
#define OP_ST_TABLE(width)                                                    \
791
static GenOpFunc *gen_op_s##width[] = {                                       \
792
    &gen_op_s##width##_user,                                                  \
793
    &gen_op_s##width##_kernel,                                                \
794
}
795
#endif
796

    
797
#ifdef TARGET_MIPS64
798
OP_LD_TABLE(d);
799
OP_LD_TABLE(dl);
800
OP_LD_TABLE(dr);
801
OP_ST_TABLE(d);
802
OP_ST_TABLE(dl);
803
OP_ST_TABLE(dr);
804
OP_LD_TABLE(ld);
805
OP_ST_TABLE(cd);
806
OP_LD_TABLE(wu);
807
#endif
808
OP_LD_TABLE(w);
809
OP_LD_TABLE(wl);
810
OP_LD_TABLE(wr);
811
OP_ST_TABLE(w);
812
OP_ST_TABLE(wl);
813
OP_ST_TABLE(wr);
814
OP_LD_TABLE(h);
815
OP_LD_TABLE(hu);
816
OP_ST_TABLE(h);
817
OP_LD_TABLE(b);
818
OP_LD_TABLE(bu);
819
OP_ST_TABLE(b);
820
OP_LD_TABLE(l);
821
OP_ST_TABLE(c);
822
OP_LD_TABLE(wc1);
823
OP_ST_TABLE(wc1);
824
OP_LD_TABLE(dc1);
825
OP_ST_TABLE(dc1);
826
OP_LD_TABLE(uxc1);
827
OP_ST_TABLE(uxc1);
828

    
829
/* Load and store */
830
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
831
                      int base, int16_t offset)
832
{
833
    const char *opn = "ldst";
834

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

    
980
/* Load and store */
981
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
982
                      int base, int16_t offset)
983
{
984
    const char *opn = "flt_ldst";
985

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

    
1026
/* Arithmetic with immediate operand */
1027
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1028
                           int rs, int16_t imm)
1029
{
1030
    target_ulong uimm;
1031
    const char *opn = "imm arith";
1032

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

    
1203
/* Arithmetic */
1204
static void gen_arith (DisasContext *ctx, uint32_t opc,
1205
                       int rd, int rs, int rt)
1206
{
1207
    const char *opn = "arith";
1208

    
1209
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1210
       && opc != OPC_DADD && opc != OPC_DSUB) {
1211
        /* If no destination, treat it as a NOP.
1212
           For add & sub, we must generate the overflow exception when needed. */
1213
        MIPS_DEBUG("NOP");
1214
        return;
1215
    }
1216
    GEN_LOAD_REG_TN(T0, rs);
1217
    GEN_LOAD_REG_TN(T1, rt);
1218
    switch (opc) {
1219
    case OPC_ADD:
1220
        save_cpu_state(ctx, 1);
1221
        gen_op_addo();
1222
        opn = "add";
1223
        break;
1224
    case OPC_ADDU:
1225
        gen_op_add();
1226
        opn = "addu";
1227
        break;
1228
    case OPC_SUB:
1229
        save_cpu_state(ctx, 1);
1230
        gen_op_subo();
1231
        opn = "sub";
1232
        break;
1233
    case OPC_SUBU:
1234
        gen_op_sub();
1235
        opn = "subu";
1236
        break;
1237
#ifdef TARGET_MIPS64
1238
    case OPC_DADD:
1239
        save_cpu_state(ctx, 1);
1240
        gen_op_daddo();
1241
        opn = "dadd";
1242
        break;
1243
    case OPC_DADDU:
1244
        gen_op_dadd();
1245
        opn = "daddu";
1246
        break;
1247
    case OPC_DSUB:
1248
        save_cpu_state(ctx, 1);
1249
        gen_op_dsubo();
1250
        opn = "dsub";
1251
        break;
1252
    case OPC_DSUBU:
1253
        gen_op_dsub();
1254
        opn = "dsubu";
1255
        break;
1256
#endif
1257
    case OPC_SLT:
1258
        gen_op_lt();
1259
        opn = "slt";
1260
        break;
1261
    case OPC_SLTU:
1262
        gen_op_ltu();
1263
        opn = "sltu";
1264
        break;
1265
    case OPC_AND:
1266
        gen_op_and();
1267
        opn = "and";
1268
        break;
1269
    case OPC_NOR:
1270
        gen_op_nor();
1271
        opn = "nor";
1272
        break;
1273
    case OPC_OR:
1274
        gen_op_or();
1275
        opn = "or";
1276
        break;
1277
    case OPC_XOR:
1278
        gen_op_xor();
1279
        opn = "xor";
1280
        break;
1281
    case OPC_MUL:
1282
        gen_op_mul();
1283
        opn = "mul";
1284
        break;
1285
    case OPC_MOVN:
1286
        gen_op_movn(rd);
1287
        opn = "movn";
1288
        goto print;
1289
    case OPC_MOVZ:
1290
        gen_op_movz(rd);
1291
        opn = "movz";
1292
        goto print;
1293
    case OPC_SLLV:
1294
        gen_op_sllv();
1295
        opn = "sllv";
1296
        break;
1297
    case OPC_SRAV:
1298
        gen_op_srav();
1299
        opn = "srav";
1300
        break;
1301
    case OPC_SRLV:
1302
        switch ((ctx->opcode >> 6) & 0x1f) {
1303
        case 0:
1304
            gen_op_srlv();
1305
            opn = "srlv";
1306
            break;
1307
        case 1:
1308
            gen_op_rotrv();
1309
            opn = "rotrv";
1310
            break;
1311
        default:
1312
            MIPS_INVAL("invalid srlv flag");
1313
            generate_exception(ctx, EXCP_RI);
1314
            break;
1315
        }
1316
        break;
1317
#ifdef TARGET_MIPS64
1318
    case OPC_DSLLV:
1319
        gen_op_dsllv();
1320
        opn = "dsllv";
1321
        break;
1322
    case OPC_DSRAV:
1323
        gen_op_dsrav();
1324
        opn = "dsrav";
1325
        break;
1326
    case OPC_DSRLV:
1327
        switch ((ctx->opcode >> 6) & 0x1f) {
1328
        case 0:
1329
            gen_op_dsrlv();
1330
            opn = "dsrlv";
1331
            break;
1332
        case 1:
1333
            gen_op_drotrv();
1334
            opn = "drotrv";
1335
            break;
1336
        default:
1337
            MIPS_INVAL("invalid dsrlv flag");
1338
            generate_exception(ctx, EXCP_RI);
1339
            break;
1340
        }
1341
        break;
1342
#endif
1343
    default:
1344
        MIPS_INVAL(opn);
1345
        generate_exception(ctx, EXCP_RI);
1346
        return;
1347
    }
1348
    GEN_STORE_TN_REG(rd, T0);
1349
 print:
1350
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1351
}
1352

    
1353
/* Arithmetic on HI/LO registers */
1354
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1355
{
1356
    const char *opn = "hilo";
1357

    
1358
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1359
        /* Treat as NOP. */
1360
        MIPS_DEBUG("NOP");
1361
        return;
1362
    }
1363
    switch (opc) {
1364
    case OPC_MFHI:
1365
        gen_op_load_HI(0);
1366
        GEN_STORE_TN_REG(reg, T0);
1367
        opn = "mfhi";
1368
        break;
1369
    case OPC_MFLO:
1370
        gen_op_load_LO(0);
1371
        GEN_STORE_TN_REG(reg, T0);
1372
        opn = "mflo";
1373
        break;
1374
    case OPC_MTHI:
1375
        GEN_LOAD_REG_TN(T0, reg);
1376
        gen_op_store_HI(0);
1377
        opn = "mthi";
1378
        break;
1379
    case OPC_MTLO:
1380
        GEN_LOAD_REG_TN(T0, reg);
1381
        gen_op_store_LO(0);
1382
        opn = "mtlo";
1383
        break;
1384
    default:
1385
        MIPS_INVAL(opn);
1386
        generate_exception(ctx, EXCP_RI);
1387
        return;
1388
    }
1389
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1390
}
1391

    
1392
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1393
                        int rs, int rt)
1394
{
1395
    const char *opn = "mul/div";
1396

    
1397
    GEN_LOAD_REG_TN(T0, rs);
1398
    GEN_LOAD_REG_TN(T1, rt);
1399
    switch (opc) {
1400
    case OPC_DIV:
1401
        gen_op_div();
1402
        opn = "div";
1403
        break;
1404
    case OPC_DIVU:
1405
        gen_op_divu();
1406
        opn = "divu";
1407
        break;
1408
    case OPC_MULT:
1409
        gen_op_mult();
1410
        opn = "mult";
1411
        break;
1412
    case OPC_MULTU:
1413
        gen_op_multu();
1414
        opn = "multu";
1415
        break;
1416
#ifdef TARGET_MIPS64
1417
    case OPC_DDIV:
1418
        gen_op_ddiv();
1419
        opn = "ddiv";
1420
        break;
1421
    case OPC_DDIVU:
1422
        gen_op_ddivu();
1423
        opn = "ddivu";
1424
        break;
1425
    case OPC_DMULT:
1426
        gen_op_dmult();
1427
        opn = "dmult";
1428
        break;
1429
    case OPC_DMULTU:
1430
        gen_op_dmultu();
1431
        opn = "dmultu";
1432
        break;
1433
#endif
1434
    case OPC_MADD:
1435
        gen_op_madd();
1436
        opn = "madd";
1437
        break;
1438
    case OPC_MADDU:
1439
        gen_op_maddu();
1440
        opn = "maddu";
1441
        break;
1442
    case OPC_MSUB:
1443
        gen_op_msub();
1444
        opn = "msub";
1445
        break;
1446
    case OPC_MSUBU:
1447
        gen_op_msubu();
1448
        opn = "msubu";
1449
        break;
1450
    default:
1451
        MIPS_INVAL(opn);
1452
        generate_exception(ctx, EXCP_RI);
1453
        return;
1454
    }
1455
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1456
}
1457

    
1458
static void gen_cl (DisasContext *ctx, uint32_t opc,
1459
                    int rd, int rs)
1460
{
1461
    const char *opn = "CLx";
1462
    if (rd == 0) {
1463
        /* Treat as NOP. */
1464
        MIPS_DEBUG("NOP");
1465
        return;
1466
    }
1467
    GEN_LOAD_REG_TN(T0, rs);
1468
    switch (opc) {
1469
    case OPC_CLO:
1470
        gen_op_clo();
1471
        opn = "clo";
1472
        break;
1473
    case OPC_CLZ:
1474
        gen_op_clz();
1475
        opn = "clz";
1476
        break;
1477
#ifdef TARGET_MIPS64
1478
    case OPC_DCLO:
1479
        gen_op_dclo();
1480
        opn = "dclo";
1481
        break;
1482
    case OPC_DCLZ:
1483
        gen_op_dclz();
1484
        opn = "dclz";
1485
        break;
1486
#endif
1487
    default:
1488
        MIPS_INVAL(opn);
1489
        generate_exception(ctx, EXCP_RI);
1490
        return;
1491
    }
1492
    gen_op_store_T0_gpr(rd);
1493
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1494
}
1495

    
1496
/* Traps */
1497
static void gen_trap (DisasContext *ctx, uint32_t opc,
1498
                      int rs, int rt, int16_t imm)
1499
{
1500
    int cond;
1501

    
1502
    cond = 0;
1503
    /* Load needed operands */
1504
    switch (opc) {
1505
    case OPC_TEQ:
1506
    case OPC_TGE:
1507
    case OPC_TGEU:
1508
    case OPC_TLT:
1509
    case OPC_TLTU:
1510
    case OPC_TNE:
1511
        /* Compare two registers */
1512
        if (rs != rt) {
1513
            GEN_LOAD_REG_TN(T0, rs);
1514
            GEN_LOAD_REG_TN(T1, rt);
1515
            cond = 1;
1516
        }
1517
        break;
1518
    case OPC_TEQI:
1519
    case OPC_TGEI:
1520
    case OPC_TGEIU:
1521
    case OPC_TLTI:
1522
    case OPC_TLTIU:
1523
    case OPC_TNEI:
1524
        /* Compare register to immediate */
1525
        if (rs != 0 || imm != 0) {
1526
            GEN_LOAD_REG_TN(T0, rs);
1527
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1528
            cond = 1;
1529
        }
1530
        break;
1531
    }
1532
    if (cond == 0) {
1533
        switch (opc) {
1534
        case OPC_TEQ:   /* rs == rs */
1535
        case OPC_TEQI:  /* r0 == 0  */
1536
        case OPC_TGE:   /* rs >= rs */
1537
        case OPC_TGEI:  /* r0 >= 0  */
1538
        case OPC_TGEU:  /* rs >= rs unsigned */
1539
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1540
            /* Always trap */
1541
            gen_op_set_T0(1);
1542
            break;
1543
        case OPC_TLT:   /* rs < rs           */
1544
        case OPC_TLTI:  /* r0 < 0            */
1545
        case OPC_TLTU:  /* rs < rs unsigned  */
1546
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1547
        case OPC_TNE:   /* rs != rs          */
1548
        case OPC_TNEI:  /* r0 != 0           */
1549
            /* Never trap: treat as NOP. */
1550
            return;
1551
        default:
1552
            MIPS_INVAL("trap");
1553
            generate_exception(ctx, EXCP_RI);
1554
            return;
1555
        }
1556
    } else {
1557
        switch (opc) {
1558
        case OPC_TEQ:
1559
        case OPC_TEQI:
1560
            gen_op_eq();
1561
            break;
1562
        case OPC_TGE:
1563
        case OPC_TGEI:
1564
            gen_op_ge();
1565
            break;
1566
        case OPC_TGEU:
1567
        case OPC_TGEIU:
1568
            gen_op_geu();
1569
            break;
1570
        case OPC_TLT:
1571
        case OPC_TLTI:
1572
            gen_op_lt();
1573
            break;
1574
        case OPC_TLTU:
1575
        case OPC_TLTIU:
1576
            gen_op_ltu();
1577
            break;
1578
        case OPC_TNE:
1579
        case OPC_TNEI:
1580
            gen_op_ne();
1581
            break;
1582
        default:
1583
            MIPS_INVAL("trap");
1584
            generate_exception(ctx, EXCP_RI);
1585
            return;
1586
        }
1587
    }
1588
    save_cpu_state(ctx, 1);
1589
    gen_op_trap();
1590
    ctx->bstate = BS_STOP;
1591
}
1592

    
1593
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1594
{
1595
    TranslationBlock *tb;
1596
    tb = ctx->tb;
1597
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1598
        if (n == 0)
1599
            gen_op_goto_tb0(TBPARAM(tb));
1600
        else
1601
            gen_op_goto_tb1(TBPARAM(tb));
1602
        gen_save_pc(dest);
1603
        gen_op_set_T0((long)tb + n);
1604
    } else {
1605
        gen_save_pc(dest);
1606
        gen_op_reset_T0();
1607
    }
1608
    gen_op_exit_tb();
1609
}
1610

    
1611
/* Branches (before delay slot) */
1612
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1613
                                int rs, int rt, int32_t offset)
1614
{
1615
    target_ulong btarget = -1;
1616
    int blink = 0;
1617
    int bcond = 0;
1618

    
1619
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1620
#ifdef MIPS_DEBUG_DISAS
1621
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1622
            fprintf(logfile,
1623
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1624
                    ctx->pc);
1625
        }
1626
#endif
1627
        generate_exception(ctx, EXCP_RI);
1628
        return;
1629
    }
1630

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

    
1844
    ctx->btarget = btarget;
1845
    if (blink > 0) {
1846
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1847
        gen_op_store_T0_gpr(blink);
1848
    }
1849
}
1850

    
1851
/* special3 bitfield operations */
1852
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1853
                       int rs, int lsb, int msb)
1854
{
1855
    GEN_LOAD_REG_TN(T1, rs);
1856
    switch (opc) {
1857
    case OPC_EXT:
1858
        if (lsb + msb > 31)
1859
            goto fail;
1860
        gen_op_ext(lsb, msb + 1);
1861
        break;
1862
    case OPC_DEXTM:
1863
        if (lsb + msb > 63)
1864
            goto fail;
1865
        gen_op_ext(lsb, msb + 1 + 32);
1866
        break;
1867
    case OPC_DEXTU:
1868
        if (lsb + msb > 63)
1869
            goto fail;
1870
        gen_op_ext(lsb + 32, msb + 1);
1871
        break;
1872
    case OPC_DEXT:
1873
        gen_op_ext(lsb, msb + 1);
1874
        break;
1875
    case OPC_INS:
1876
        if (lsb > msb)
1877
            goto fail;
1878
        GEN_LOAD_REG_TN(T0, rt);
1879
        gen_op_ins(lsb, msb - lsb + 1);
1880
        break;
1881
    case OPC_DINSM:
1882
        if (lsb > msb)
1883
            goto fail;
1884
        GEN_LOAD_REG_TN(T0, rt);
1885
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1886
        break;
1887
    case OPC_DINSU:
1888
        if (lsb > msb)
1889
            goto fail;
1890
        GEN_LOAD_REG_TN(T0, rt);
1891
        gen_op_ins(lsb + 32, msb - lsb + 1);
1892
        break;
1893
    case OPC_DINS:
1894
        if (lsb > msb)
1895
            goto fail;
1896
        GEN_LOAD_REG_TN(T0, rt);
1897
        gen_op_ins(lsb, msb - lsb + 1);
1898
        break;
1899
    default:
1900
fail:
1901
        MIPS_INVAL("bitops");
1902
        generate_exception(ctx, EXCP_RI);
1903
        return;
1904
    }
1905
    GEN_STORE_TN_REG(rt, T0);
1906
}
1907

    
1908
/* CP0 (MMU and control) */
1909
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1910
{
1911
    const char *rn = "invalid";
1912

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

    
2460
die:
2461
#if defined MIPS_DEBUG_DISAS
2462
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2463
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2464
                rn, reg, sel);
2465
    }
2466
#endif
2467
    generate_exception(ctx, EXCP_RI);
2468
}
2469

    
2470
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2471
{
2472
    const char *rn = "invalid";
2473

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

    
3052
die:
3053
#if defined MIPS_DEBUG_DISAS
3054
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3055
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3056
                rn, reg, sel);
3057
    }
3058
#endif
3059
    generate_exception(ctx, EXCP_RI);
3060
}
3061

    
3062
#ifdef TARGET_MIPS64
3063
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3064
{
3065
    const char *rn = "invalid";
3066

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

    
3601
die:
3602
#if defined MIPS_DEBUG_DISAS
3603
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3604
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3605
                rn, reg, sel);
3606
    }
3607
#endif
3608
    generate_exception(ctx, EXCP_RI);
3609
}
3610

    
3611
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3612
{
3613
    const char *rn = "invalid";
3614

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

    
4178
die:
4179
#if defined MIPS_DEBUG_DISAS
4180
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4181
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4182
                rn, reg, sel);
4183
    }
4184
#endif
4185
    generate_exception(ctx, EXCP_RI);
4186
}
4187
#endif /* TARGET_MIPS64 */
4188

    
4189
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4190
                     int u, int sel, int h)
4191
{
4192
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4193

    
4194
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4195
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4196
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4197
        gen_op_set_T0(-1);
4198
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4199
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4200
        gen_op_set_T0(-1);
4201
    else if (u == 0) {
4202
        switch (rt) {
4203
        case 2:
4204
            switch (sel) {
4205
            case 1:
4206
                gen_op_mftc0_tcstatus();
4207
                break;
4208
            case 2:
4209
                gen_op_mftc0_tcbind();
4210
                break;
4211
            case 3:
4212
                gen_op_mftc0_tcrestart();
4213
                break;
4214
            case 4:
4215
                gen_op_mftc0_tchalt();
4216
                break;
4217
            case 5:
4218
                gen_op_mftc0_tccontext();
4219
                break;
4220
            case 6:
4221
                gen_op_mftc0_tcschedule();
4222
                break;
4223
            case 7:
4224
                gen_op_mftc0_tcschefback();
4225
                break;
4226
            default:
4227
                gen_mfc0(env, ctx, rt, sel);
4228
                break;
4229
            }
4230
            break;
4231
        case 10:
4232
            switch (sel) {
4233
            case 0:
4234
                gen_op_mftc0_entryhi();
4235
                break;
4236
            default:
4237
                gen_mfc0(env, ctx, rt, sel);
4238
                break;
4239
            }
4240
        case 12:
4241
            switch (sel) {
4242
            case 0:
4243
                gen_op_mftc0_status();
4244
                break;
4245
            default:
4246
                gen_mfc0(env, ctx, rt, sel);
4247
                break;
4248
            }
4249
        case 23:
4250
            switch (sel) {
4251
            case 0:
4252
                gen_op_mftc0_debug();
4253
                break;
4254
            default:
4255
                gen_mfc0(env, ctx, rt, sel);
4256
                break;
4257
            }
4258
            break;
4259
        default:
4260
            gen_mfc0(env, ctx, rt, sel);
4261
        }
4262
    } else switch (sel) {
4263
    /* GPR registers. */
4264
    case 0:
4265
        gen_op_mftgpr(rt);
4266
        break;
4267
    /* Auxiliary CPU registers */
4268
    case 1:
4269
        switch (rt) {
4270
        case 0:
4271
            gen_op_mftlo(0);
4272
            break;
4273
        case 1:
4274
            gen_op_mfthi(0);
4275
            break;
4276
        case 2:
4277
            gen_op_mftacx(0);
4278
            break;
4279
        case 4:
4280
            gen_op_mftlo(1);
4281
            break;
4282
        case 5:
4283
            gen_op_mfthi(1);
4284
            break;
4285
        case 6:
4286
            gen_op_mftacx(1);
4287
            break;
4288
        case 8:
4289
            gen_op_mftlo(2);
4290
            break;
4291
        case 9:
4292
            gen_op_mfthi(2);
4293
            break;
4294
        case 10:
4295
            gen_op_mftacx(2);
4296
            break;
4297
        case 12:
4298
            gen_op_mftlo(3);
4299
            break;
4300
        case 13:
4301
            gen_op_mfthi(3);
4302
            break;
4303
        case 14:
4304
            gen_op_mftacx(3);
4305
            break;
4306
        case 16:
4307
            gen_op_mftdsp();
4308
            break;
4309
        default:
4310
            goto die;
4311
        }
4312
        break;
4313
    /* Floating point (COP1). */
4314
    case 2:
4315
        /* XXX: For now we support only a single FPU context. */
4316
        if (h == 0) {
4317
            GEN_LOAD_FREG_FTN(WT0, rt);
4318
            gen_op_mfc1();
4319
        } else {
4320
            GEN_LOAD_FREG_FTN(WTH0, rt);
4321
            gen_op_mfhc1();
4322
        }
4323
        break;
4324
    case 3:
4325
        /* XXX: For now we support only a single FPU context. */
4326
        gen_op_cfc1(rt);
4327
        break;
4328
    /* COP2: Not implemented. */
4329
    case 4:
4330
    case 5:
4331
        /* fall through */
4332
    default:
4333
        goto die;
4334
    }
4335
#if defined MIPS_DEBUG_DISAS
4336
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4337
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4338
                rt, u, sel, h);
4339
    }
4340
#endif
4341
    return;
4342

    
4343
die:
4344
#if defined MIPS_DEBUG_DISAS
4345
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4346
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4347
                rt, u, sel, h);
4348
    }
4349
#endif
4350
    generate_exception(ctx, EXCP_RI);
4351
}
4352

    
4353
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4354
                     int u, int sel, int h)
4355
{
4356
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4357

    
4358
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4359
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4360
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4361
        /* NOP */ ;
4362
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4363
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4364
        /* NOP */ ;
4365
    else if (u == 0) {
4366
        switch (rd) {
4367
        case 2:
4368
            switch (sel) {
4369
            case 1:
4370
                gen_op_mttc0_tcstatus();
4371
                break;
4372
            case 2:
4373
                gen_op_mttc0_tcbind();
4374
                break;
4375
            case 3:
4376
                gen_op_mttc0_tcrestart();
4377
                break;
4378
            case 4:
4379
                gen_op_mttc0_tchalt();
4380
                break;
4381
            case 5:
4382
                gen_op_mttc0_tccontext();
4383
                break;
4384
            case 6:
4385
                gen_op_mttc0_tcschedule();
4386
                break;
4387
            case 7:
4388
                gen_op_mttc0_tcschefback();
4389
                break;
4390
            default:
4391
                gen_mtc0(env, ctx, rd, sel);
4392
                break;
4393
            }
4394
            break;
4395
        case 10:
4396
            switch (sel) {
4397
            case 0:
4398
                gen_op_mttc0_entryhi();
4399
                break;
4400
            default:
4401
                gen_mtc0(env, ctx, rd, sel);
4402
                break;
4403
            }
4404
        case 12:
4405
            switch (sel) {
4406
            case 0:
4407
                gen_op_mttc0_status();
4408
                break;
4409
            default:
4410
                gen_mtc0(env, ctx, rd, sel);
4411
                break;
4412
            }
4413
        case 23:
4414
            switch (sel) {
4415
            case 0:
4416
                gen_op_mttc0_debug();
4417
                break;
4418
            default:
4419
                gen_mtc0(env, ctx, rd, sel);
4420
                break;
4421
            }
4422
            break;
4423
        default:
4424
            gen_mtc0(env, ctx, rd, sel);
4425
        }
4426
    } else switch (sel) {
4427
    /* GPR registers. */
4428
    case 0:
4429
        gen_op_mttgpr(rd);
4430
        break;
4431
    /* Auxiliary CPU registers */
4432
    case 1:
4433
        switch (rd) {
4434
        case 0:
4435
            gen_op_mttlo(0);
4436
            break;
4437
        case 1:
4438
            gen_op_mtthi(0);
4439
            break;
4440
        case 2:
4441
            gen_op_mttacx(0);
4442
            break;
4443
        case 4:
4444
            gen_op_mttlo(1);
4445
            break;
4446
        case 5:
4447
            gen_op_mtthi(1);
4448
            break;
4449
        case 6:
4450
            gen_op_mttacx(1);
4451
            break;
4452
        case 8:
4453
            gen_op_mttlo(2);
4454
            break;
4455
        case 9:
4456
            gen_op_mtthi(2);
4457
            break;
4458
        case 10:
4459
            gen_op_mttacx(2);
4460
            break;
4461
        case 12:
4462
            gen_op_mttlo(3);
4463
            break;
4464
        case 13:
4465
            gen_op_mtthi(3);
4466
            break;
4467
        case 14:
4468
            gen_op_mttacx(3);
4469
            break;
4470
        case 16:
4471
            gen_op_mttdsp();
4472
            break;
4473
        default:
4474
            goto die;
4475
        }
4476
        break;
4477
    /* Floating point (COP1). */
4478
    case 2:
4479
        /* XXX: For now we support only a single FPU context. */
4480
        if (h == 0) {
4481
            gen_op_mtc1();
4482
            GEN_STORE_FTN_FREG(rd, WT0);
4483
        } else {
4484
            gen_op_mthc1();
4485
            GEN_STORE_FTN_FREG(rd, WTH0);
4486
        }
4487
        break;
4488
    case 3:
4489
        /* XXX: For now we support only a single FPU context. */
4490
        gen_op_ctc1(rd);
4491
        break;
4492
    /* COP2: Not implemented. */
4493
    case 4:
4494
    case 5:
4495
        /* fall through */
4496
    default:
4497
        goto die;
4498
    }
4499
#if defined MIPS_DEBUG_DISAS
4500
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4501
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4502
                rd, u, sel, h);
4503
    }
4504
#endif
4505
    return;
4506

    
4507
die:
4508
#if defined MIPS_DEBUG_DISAS
4509
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4510
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4511
                rd, u, sel, h);
4512
    }
4513
#endif
4514
    generate_exception(ctx, EXCP_RI);
4515
}
4516

    
4517
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4518
{
4519
    const char *opn = "ldst";
4520

    
4521
    switch (opc) {
4522
    case OPC_MFC0:
4523
        if (rt == 0) {
4524
            /* Treat as NOP. */
4525
            return;
4526
        }
4527
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4528
        gen_op_store_T0_gpr(rt);
4529
        opn = "mfc0";
4530
        break;
4531
    case OPC_MTC0:
4532
        GEN_LOAD_REG_TN(T0, rt);
4533
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4534
        opn = "mtc0";
4535
        break;
4536
#ifdef TARGET_MIPS64
4537
    case OPC_DMFC0:
4538
        if (!(ctx->hflags & MIPS_HFLAG_64))
4539
            generate_exception(ctx, EXCP_RI);
4540
        if (rt == 0) {
4541
            /* Treat as NOP. */
4542
            return;
4543
        }
4544
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4545
        gen_op_store_T0_gpr(rt);
4546
        opn = "dmfc0";
4547
        break;
4548
    case OPC_DMTC0:
4549
        if (!(ctx->hflags & MIPS_HFLAG_64))
4550
            generate_exception(ctx, EXCP_RI);
4551
        GEN_LOAD_REG_TN(T0, rt);
4552
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4553
        opn = "dmtc0";
4554
        break;
4555
#endif
4556
    case OPC_MFTR:
4557
        check_mips_mt(env, ctx);
4558
        if (rd == 0) {
4559
            /* Treat as NOP. */
4560
            return;
4561
        }
4562
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4563
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4564
        gen_op_store_T0_gpr(rd);
4565
        opn = "mftr";
4566
        break;
4567
    case OPC_MTTR:
4568
        check_mips_mt(env, ctx);
4569
        GEN_LOAD_REG_TN(T0, rt);
4570
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4571
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4572
        opn = "mttr";
4573
        break;
4574
    case OPC_TLBWI:
4575
        opn = "tlbwi";
4576
        if (!env->tlb->do_tlbwi)
4577
            goto die;
4578
        gen_op_tlbwi();
4579
        break;
4580
    case OPC_TLBWR:
4581
        opn = "tlbwr";
4582
        if (!env->tlb->do_tlbwr)
4583
            goto die;
4584
        gen_op_tlbwr();
4585
        break;
4586
    case OPC_TLBP:
4587
        opn = "tlbp";
4588
        if (!env->tlb->do_tlbp)
4589
            goto die;
4590
        gen_op_tlbp();
4591
        break;
4592
    case OPC_TLBR:
4593
        opn = "tlbr";
4594
        if (!env->tlb->do_tlbr)
4595
            goto die;
4596
        gen_op_tlbr();
4597
        break;
4598
    case OPC_ERET:
4599
        opn = "eret";
4600
        gen_op_eret();
4601
        ctx->bstate = BS_EXCP;
4602
        break;
4603
    case OPC_DERET:
4604
        opn = "deret";
4605
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4606
            MIPS_INVAL(opn);
4607
            generate_exception(ctx, EXCP_RI);
4608
        } else {
4609
            gen_op_deret();
4610
            ctx->bstate = BS_EXCP;
4611
        }
4612
        break;
4613
    case OPC_WAIT:
4614
        opn = "wait";
4615
        /* If we get an exception, we want to restart at next instruction */
4616
        ctx->pc += 4;
4617
        save_cpu_state(ctx, 1);
4618
        ctx->pc -= 4;
4619
        gen_op_wait();
4620
        ctx->bstate = BS_EXCP;
4621
        break;
4622
    default:
4623
 die:
4624
        MIPS_INVAL(opn);
4625
        generate_exception(ctx, EXCP_RI);
4626
        return;
4627
    }
4628
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4629
}
4630

    
4631
/* CP1 Branches (before delay slot) */
4632
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4633
                                 int32_t cc, int32_t offset)
4634
{
4635
    target_ulong btarget;
4636
    const char *opn = "cp1 cond branch";
4637

    
4638
    btarget = ctx->pc + 4 + offset;
4639

    
4640
    switch (op) {
4641
    case OPC_BC1F:
4642
        gen_op_bc1f(cc);
4643
        opn = "bc1f";
4644
        goto not_likely;
4645
    case OPC_BC1FL:
4646
        gen_op_bc1f(cc);
4647
        opn = "bc1fl";
4648
        goto likely;
4649
    case OPC_BC1T:
4650
        gen_op_bc1t(cc);
4651
        opn = "bc1t";
4652
        goto not_likely;
4653
    case OPC_BC1TL:
4654
        gen_op_bc1t(cc);
4655
        opn = "bc1tl";
4656
    likely:
4657
        ctx->hflags |= MIPS_HFLAG_BL;
4658
        gen_op_set_bcond();
4659
        gen_op_save_bcond();
4660
        break;
4661
    case OPC_BC1FANY2:
4662
        gen_op_bc1any2f(cc);
4663
        opn = "bc1any2f";
4664
        goto not_likely;
4665
    case OPC_BC1TANY2:
4666
        gen_op_bc1any2t(cc);
4667
        opn = "bc1any2t";
4668
        goto not_likely;
4669
    case OPC_BC1FANY4:
4670
        gen_op_bc1any4f(cc);
4671
        opn = "bc1any4f";
4672
        goto not_likely;
4673
    case OPC_BC1TANY4:
4674
        gen_op_bc1any4t(cc);
4675
        opn = "bc1any4t";
4676
    not_likely:
4677
        ctx->hflags |= MIPS_HFLAG_BC;
4678
        gen_op_set_bcond();
4679
        break;
4680
    default:
4681
        MIPS_INVAL(opn);
4682
        generate_exception (ctx, EXCP_RI);
4683
        return;
4684
    }
4685
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4686
               ctx->hflags, btarget);
4687
    ctx->btarget = btarget;
4688
}
4689

    
4690
/* Coprocessor 1 (FPU) */
4691

    
4692
#define FOP(func, fmt) (((fmt) << 21) | (func))
4693

    
4694
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4695
{
4696
    const char *opn = "cp1 move";
4697

    
4698
    switch (opc) {
4699
    case OPC_MFC1:
4700
        GEN_LOAD_FREG_FTN(WT0, fs);
4701
        gen_op_mfc1();
4702
        GEN_STORE_TN_REG(rt, T0);
4703
        opn = "mfc1";