Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 8487327a

History | View | Annotate | Download (166.8 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 * 
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

    
29
#include "cpu.h"
30
#include "exec-all.h"
31
#include "disas.h"
32

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL,
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_BSHFL    = 0x20 | OPC_SPECIAL3,
270
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
271
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
272
};
273

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

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

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

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

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

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

    
307
/* MFMC0 opcodes */
308
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
309

    
310
enum {
311
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313
};
314

    
315
/* Coprocessor 0 (with rs == C0) */
316
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
317

    
318
enum {
319
    OPC_TLBR     = 0x01 | OPC_C0,
320
    OPC_TLBWI    = 0x02 | OPC_C0,
321
    OPC_TLBWR    = 0x06 | OPC_C0,
322
    OPC_TLBP     = 0x08 | OPC_C0,
323
    OPC_RFE      = 0x10 | OPC_C0,
324
    OPC_ERET     = 0x18 | OPC_C0,
325
    OPC_DERET    = 0x1F | OPC_C0,
326
    OPC_WAIT     = 0x20 | OPC_C0,
327
};
328

    
329
/* Coprocessor 1 (rs field) */
330
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
331

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

    
353
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
354
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
355

    
356
enum {
357
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
358
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
359
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
360
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
361
};
362

    
363
enum {
364
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
365
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
366
};
367

    
368
enum {
369
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
370
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
371
};
372

    
373
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
374

    
375
enum {
376
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
377
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
378
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
379
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
380
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
381
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
382
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
383
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
384
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
385
};
386

    
387
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
388

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

    
412

    
413
const unsigned char *regnames[] =
414
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
415
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
416
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
417
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
418

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

    
436
/* General purpose registers moves */
437
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
438
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
439
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
440

    
441
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
443

    
444
static const char *fregnames[] =
445
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
446
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
447
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
448
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
449

    
450
#define FGEN32(func, NAME)                       \
451
static GenOpFunc *NAME ## _table [32] = {        \
452
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
453
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
454
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
455
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
456
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
457
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
458
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
459
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
460
};                                               \
461
static inline void func(int n)                   \
462
{                                                \
463
    NAME ## _table[n]();                         \
464
}
465

    
466
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
467
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
468

    
469
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
470
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
471

    
472
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
473
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
474

    
475
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
476
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
477

    
478
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
479
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
480

    
481
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
482
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
485
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
486

    
487
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
488
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
489

    
490
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
491
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492

    
493
#define FOP_CONDS(type, fmt)                                            \
494
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
495
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
496
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
497
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
498
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
499
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
500
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
501
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
502
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
503
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
504
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
505
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
506
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
507
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
508
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
509
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
510
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
511
};                                                                      \
512
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)          \
513
{                                                                       \
514
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
515
}
516

    
517
FOP_CONDS(, d)
518
FOP_CONDS(abs, d)
519
FOP_CONDS(, s)
520
FOP_CONDS(abs, s)
521
FOP_CONDS(, ps)
522
FOP_CONDS(abs, ps)
523

    
524
typedef struct DisasContext {
525
    struct TranslationBlock *tb;
526
    target_ulong pc, saved_pc;
527
    uint32_t opcode;
528
    uint32_t fp_status;
529
    /* Routine used to access memory */
530
    int mem_idx;
531
    uint32_t hflags, saved_hflags;
532
    int bstate;
533
    target_ulong btarget;
534
} DisasContext;
535

    
536
enum {
537
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
538
                      * exception condition
539
                      */
540
    BS_STOP     = 1, /* We want to stop translation for any reason */
541
    BS_BRANCH   = 2, /* We reached a branch condition     */
542
    BS_EXCP     = 3, /* We reached an exception condition */
543
};
544

    
545
#ifdef MIPS_DEBUG_DISAS
546
#define MIPS_DEBUG(fmt, args...)                                              \
547
do {                                                                          \
548
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
549
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
550
                ctx->pc, ctx->opcode , ##args);                               \
551
    }                                                                         \
552
} while (0)
553
#else
554
#define MIPS_DEBUG(fmt, args...) do { } while(0)
555
#endif
556

    
557
#define MIPS_INVAL(op)                                                        \
558
do {                                                                          \
559
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
560
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
561
} while (0)
562

    
563
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
564
do {                                                                          \
565
    if (Rn == 0) {                                                            \
566
        glue(gen_op_reset_, Tn)();                                            \
567
    } else {                                                                  \
568
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
569
    }                                                                         \
570
} while (0)
571

    
572
#ifdef TARGET_MIPS64
573
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
574
do {                                                                          \
575
    if (Imm == 0) {                                                           \
576
        glue(gen_op_reset_, Tn)();                                            \
577
    } else if ((int32_t)Imm == Imm) {                                         \
578
        glue(gen_op_set_, Tn)(Imm);                                           \
579
    } else {                                                                  \
580
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
581
    }                                                                         \
582
} while (0)
583
#else
584
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
585
do {                                                                          \
586
    if (Imm == 0) {                                                           \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_set_, Tn)(Imm);                                           \
590
    }                                                                         \
591
} while (0)
592
#endif
593

    
594
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
595
do {                                                                          \
596
    if (Rn != 0) {                                                            \
597
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
598
    }                                                                         \
599
} while (0)
600

    
601
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
602
do {                                                                          \
603
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
604
} while (0)
605

    
606
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
607
do {                                                                          \
608
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
609
} while (0)
610

    
611
static inline void gen_save_pc(target_ulong pc)
612
{
613
#ifdef TARGET_MIPS64
614
    if (pc == (int32_t)pc) {
615
        gen_op_save_pc(pc);
616
    } else {
617
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
618
    }
619
#else
620
    gen_op_save_pc(pc);
621
#endif
622
}
623

    
624
static inline void gen_save_btarget(target_ulong btarget)
625
{
626
#ifdef TARGET_MIPS64
627
    if (btarget == (int32_t)btarget) {
628
        gen_op_save_btarget(btarget);
629
    } else {
630
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
631
    }
632
#else
633
    gen_op_save_btarget(btarget);
634
#endif
635
}
636

    
637
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
638
{
639
#if defined MIPS_DEBUG_DISAS
640
    if (loglevel & CPU_LOG_TB_IN_ASM) {
641
            fprintf(logfile, "hflags %08x saved %08x\n",
642
                    ctx->hflags, ctx->saved_hflags);
643
    }
644
#endif
645
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
646
        gen_save_pc(ctx->pc);
647
        ctx->saved_pc = ctx->pc;
648
    }
649
    if (ctx->hflags != ctx->saved_hflags) {
650
        gen_op_save_state(ctx->hflags);
651
        ctx->saved_hflags = ctx->hflags;
652
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
653
        case MIPS_HFLAG_BR:
654
            gen_op_save_breg_target();
655
            break;
656
        case MIPS_HFLAG_BC:
657
            gen_op_save_bcond();
658
            /* fall through */
659
        case MIPS_HFLAG_BL:
660
            /* bcond was already saved by the BL insn */
661
            /* fall through */
662
        case MIPS_HFLAG_B:
663
            gen_save_btarget(ctx->btarget);
664
            break;
665
        }
666
    }
667
}
668

    
669
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
670
{
671
    ctx->saved_hflags = ctx->hflags;
672
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
673
    case MIPS_HFLAG_BR:
674
        gen_op_restore_breg_target();
675
        break;
676
    case MIPS_HFLAG_B:
677
        ctx->btarget = env->btarget;
678
        break;
679
    case MIPS_HFLAG_BC:
680
    case MIPS_HFLAG_BL:
681
        ctx->btarget = env->btarget;
682
        gen_op_restore_bcond();
683
        break;
684
    }
685
}
686

    
687
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
688
{
689
#if defined MIPS_DEBUG_DISAS
690
    if (loglevel & CPU_LOG_TB_IN_ASM)
691
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
692
#endif
693
    save_cpu_state(ctx, 1);
694
    if (err == 0)
695
        gen_op_raise_exception(excp);
696
    else
697
        gen_op_raise_exception_err(excp, err);
698
    ctx->bstate = BS_EXCP;
699
}
700

    
701
static inline void generate_exception (DisasContext *ctx, int excp)
702
{
703
    generate_exception_err (ctx, excp, 0);
704
}
705

    
706
static inline void check_cp1_enabled(DisasContext *ctx)
707
{
708
    if (!(ctx->hflags & MIPS_HFLAG_FPU))
709
        generate_exception_err(ctx, EXCP_CpU, 1);
710
}
711

    
712
static inline void check_cp1_64bitmode(DisasContext *ctx)
713
{
714
    if (!(ctx->hflags & MIPS_HFLAG_F64))
715
        generate_exception(ctx, EXCP_RI);
716
}
717

    
718
/*
719
 * Verify if floating point register is valid; an operation is not defined
720
 * if bit 0 of any register specification is set and the FR bit in the
721
 * Status register equals zero, since the register numbers specify an
722
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
723
 * in the Status register equals one, both even and odd register numbers
724
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
725
 *
726
 * Multiple 64 bit wide registers can be checked by calling
727
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
728
 */
729
void check_cp1_registers(DisasContext *ctx, int regs)
730
{
731
    if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))
732
        generate_exception(ctx, EXCP_RI);
733
}
734

    
735
#if defined(CONFIG_USER_ONLY)
736
#define op_ldst(name)        gen_op_##name##_raw()
737
#define OP_LD_TABLE(width)
738
#define OP_ST_TABLE(width)
739
#else
740
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
741
#define OP_LD_TABLE(width)                                                    \
742
static GenOpFunc *gen_op_l##width[] = {                                       \
743
    &gen_op_l##width##_user,                                                  \
744
    &gen_op_l##width##_kernel,                                                \
745
}
746
#define OP_ST_TABLE(width)                                                    \
747
static GenOpFunc *gen_op_s##width[] = {                                       \
748
    &gen_op_s##width##_user,                                                  \
749
    &gen_op_s##width##_kernel,                                                \
750
}
751
#endif
752

    
753
#ifdef TARGET_MIPS64
754
OP_LD_TABLE(d);
755
OP_LD_TABLE(dl);
756
OP_LD_TABLE(dr);
757
OP_ST_TABLE(d);
758
OP_ST_TABLE(dl);
759
OP_ST_TABLE(dr);
760
OP_LD_TABLE(ld);
761
OP_ST_TABLE(cd);
762
OP_LD_TABLE(wu);
763
#endif
764
OP_LD_TABLE(w);
765
OP_LD_TABLE(wl);
766
OP_LD_TABLE(wr);
767
OP_ST_TABLE(w);
768
OP_ST_TABLE(wl);
769
OP_ST_TABLE(wr);
770
OP_LD_TABLE(h);
771
OP_LD_TABLE(hu);
772
OP_ST_TABLE(h);
773
OP_LD_TABLE(b);
774
OP_LD_TABLE(bu);
775
OP_ST_TABLE(b);
776
OP_LD_TABLE(l);
777
OP_ST_TABLE(c);
778
OP_LD_TABLE(wc1);
779
OP_ST_TABLE(wc1);
780
OP_LD_TABLE(dc1);
781
OP_ST_TABLE(dc1);
782
OP_LD_TABLE(uxc1);
783
OP_ST_TABLE(uxc1);
784

    
785
/* Load and store */
786
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
787
                      int base, int16_t offset)
788
{
789
    const char *opn = "ldst";
790

    
791
    if (base == 0) {
792
        GEN_LOAD_IMM_TN(T0, offset);
793
    } else if (offset == 0) {
794
        gen_op_load_gpr_T0(base);
795
    } else {
796
        gen_op_load_gpr_T0(base);
797
        gen_op_set_T1(offset);
798
        gen_op_addr_add();
799
    }
800
    /* Don't do NOP if destination is zero: we must perform the actual
801
     * memory access
802
     */
803
    switch (opc) {
804
#ifdef TARGET_MIPS64
805
    case OPC_LWU:
806
        op_ldst(lwu);
807
        GEN_STORE_TN_REG(rt, T0);
808
        opn = "lwu";
809
        break;
810
    case OPC_LD:
811
        op_ldst(ld);
812
        GEN_STORE_TN_REG(rt, T0);
813
        opn = "ld";
814
        break;
815
    case OPC_LLD:
816
        op_ldst(lld);
817
        GEN_STORE_TN_REG(rt, T0);
818
        opn = "lld";
819
        break;
820
    case OPC_SD:
821
        GEN_LOAD_REG_TN(T1, rt);
822
        op_ldst(sd);
823
        opn = "sd";
824
        break;
825
    case OPC_SCD:
826
        save_cpu_state(ctx, 1);
827
        GEN_LOAD_REG_TN(T1, rt);
828
        op_ldst(scd);
829
        GEN_STORE_TN_REG(rt, T0);
830
        opn = "scd";
831
        break;
832
    case OPC_LDL:
833
        GEN_LOAD_REG_TN(T1, rt);
834
        op_ldst(ldl);
835
        GEN_STORE_TN_REG(rt, T0);
836
        opn = "ldl";
837
        break;
838
    case OPC_SDL:
839
        GEN_LOAD_REG_TN(T1, rt);
840
        op_ldst(sdl);
841
        opn = "sdl";
842
        break;
843
    case OPC_LDR:
844
        GEN_LOAD_REG_TN(T1, rt);
845
        op_ldst(ldr);
846
        GEN_STORE_TN_REG(rt, T0);
847
        opn = "ldr";
848
        break;
849
    case OPC_SDR:
850
        GEN_LOAD_REG_TN(T1, rt);
851
        op_ldst(sdr);
852
        opn = "sdr";
853
        break;
854
#endif
855
    case OPC_LW:
856
        op_ldst(lw);
857
        GEN_STORE_TN_REG(rt, T0);
858
        opn = "lw";
859
        break;
860
    case OPC_SW:
861
        GEN_LOAD_REG_TN(T1, rt);
862
        op_ldst(sw);
863
        opn = "sw";
864
        break;
865
    case OPC_LH:
866
        op_ldst(lh);
867
        GEN_STORE_TN_REG(rt, T0);
868
        opn = "lh";
869
        break;
870
    case OPC_SH:
871
        GEN_LOAD_REG_TN(T1, rt);
872
        op_ldst(sh);
873
        opn = "sh";
874
        break;
875
    case OPC_LHU:
876
        op_ldst(lhu);
877
        GEN_STORE_TN_REG(rt, T0);
878
        opn = "lhu";
879
        break;
880
    case OPC_LB:
881
        op_ldst(lb);
882
        GEN_STORE_TN_REG(rt, T0);
883
        opn = "lb";
884
        break;
885
    case OPC_SB:
886
        GEN_LOAD_REG_TN(T1, rt);
887
        op_ldst(sb);
888
        opn = "sb";
889
        break;
890
    case OPC_LBU:
891
        op_ldst(lbu);
892
        GEN_STORE_TN_REG(rt, T0);
893
        opn = "lbu";
894
        break;
895
    case OPC_LWL:
896
        GEN_LOAD_REG_TN(T1, rt);
897
        op_ldst(lwl);
898
        GEN_STORE_TN_REG(rt, T0);
899
        opn = "lwl";
900
        break;
901
    case OPC_SWL:
902
        GEN_LOAD_REG_TN(T1, rt);
903
        op_ldst(swl);
904
        opn = "swr";
905
        break;
906
    case OPC_LWR:
907
        GEN_LOAD_REG_TN(T1, rt);
908
        op_ldst(lwr);
909
        GEN_STORE_TN_REG(rt, T0);
910
        opn = "lwr";
911
        break;
912
    case OPC_SWR:
913
        GEN_LOAD_REG_TN(T1, rt);
914
        op_ldst(swr);
915
        opn = "swr";
916
        break;
917
    case OPC_LL:
918
        op_ldst(ll);
919
        GEN_STORE_TN_REG(rt, T0);
920
        opn = "ll";
921
        break;
922
    case OPC_SC:
923
        save_cpu_state(ctx, 1);
924
        GEN_LOAD_REG_TN(T1, rt);
925
        op_ldst(sc);
926
        GEN_STORE_TN_REG(rt, T0);
927
        opn = "sc";
928
        break;
929
    default:
930
        MIPS_INVAL(opn);
931
        generate_exception(ctx, EXCP_RI);
932
        return;
933
    }
934
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
935
}
936

    
937
/* Load and store */
938
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
939
                      int base, int16_t offset)
940
{
941
    const char *opn = "flt_ldst";
942

    
943
    if (base == 0) {
944
        GEN_LOAD_IMM_TN(T0, offset);
945
    } else if (offset == 0) {
946
        gen_op_load_gpr_T0(base);
947
    } else {
948
        gen_op_load_gpr_T0(base);
949
        gen_op_set_T1(offset);
950
        gen_op_addr_add();
951
    }
952
    /* Don't do NOP if destination is zero: we must perform the actual
953
     * memory access
954
     */
955
    switch (opc) {
956
    case OPC_LWC1:
957
        op_ldst(lwc1);
958
        GEN_STORE_FTN_FREG(ft, WT0);
959
        opn = "lwc1";
960
        break;
961
    case OPC_SWC1:
962
        GEN_LOAD_FREG_FTN(WT0, ft);
963
        op_ldst(swc1);
964
        opn = "swc1";
965
        break;
966
    case OPC_LDC1:
967
        op_ldst(ldc1);
968
        GEN_STORE_FTN_FREG(ft, DT0);
969
        opn = "ldc1";
970
        break;
971
    case OPC_SDC1:
972
        GEN_LOAD_FREG_FTN(DT0, ft);
973
        op_ldst(sdc1);
974
        opn = "sdc1";
975
        break;
976
    default:
977
        MIPS_INVAL(opn);
978
        generate_exception(ctx, EXCP_RI);
979
        return;
980
    }
981
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
982
}
983

    
984
/* Arithmetic with immediate operand */
985
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
986
                           int rs, int16_t imm)
987
{
988
    target_ulong uimm;
989
    const char *opn = "imm arith";
990

    
991
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
992
        /* if no destination, treat it as a NOP 
993
         * For addi, we must generate the overflow exception when needed.
994
         */
995
        MIPS_DEBUG("NOP");
996
        return;
997
    }
998
    uimm = (uint16_t)imm;
999
    switch (opc) {
1000
    case OPC_ADDI:
1001
    case OPC_ADDIU:
1002
#ifdef TARGET_MIPS64
1003
    case OPC_DADDI:
1004
    case OPC_DADDIU:
1005
#endif
1006
    case OPC_SLTI:
1007
    case OPC_SLTIU:
1008
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1009
        /* Fall through. */
1010
    case OPC_ANDI:
1011
    case OPC_ORI:
1012
    case OPC_XORI:
1013
        GEN_LOAD_REG_TN(T0, rs);
1014
        GEN_LOAD_IMM_TN(T1, uimm);
1015
        break;
1016
    case OPC_LUI:
1017
        GEN_LOAD_IMM_TN(T0, imm << 16);
1018
        break;
1019
    case OPC_SLL:
1020
    case OPC_SRA:
1021
    case OPC_SRL:
1022
#ifdef TARGET_MIPS64
1023
    case OPC_DSLL:
1024
    case OPC_DSRA:
1025
    case OPC_DSRL:
1026
    case OPC_DSLL32:
1027
    case OPC_DSRA32:
1028
    case OPC_DSRL32:
1029
#endif
1030
        uimm &= 0x1f;
1031
        GEN_LOAD_REG_TN(T0, rs);
1032
        GEN_LOAD_IMM_TN(T1, uimm);
1033
        break;
1034
    }
1035
    switch (opc) {
1036
    case OPC_ADDI:
1037
        save_cpu_state(ctx, 1);
1038
        gen_op_addo();
1039
        opn = "addi";
1040
        break;
1041
    case OPC_ADDIU:
1042
        gen_op_add();
1043
        opn = "addiu";
1044
        break;
1045
#ifdef TARGET_MIPS64
1046
    case OPC_DADDI:
1047
        save_cpu_state(ctx, 1);
1048
        gen_op_daddo();
1049
        opn = "daddi";
1050
        break;
1051
    case OPC_DADDIU:
1052
        gen_op_dadd();
1053
        opn = "daddiu";
1054
        break;
1055
#endif
1056
    case OPC_SLTI:
1057
        gen_op_lt();
1058
        opn = "slti";
1059
        break;
1060
    case OPC_SLTIU:
1061
        gen_op_ltu();
1062
        opn = "sltiu";
1063
        break;
1064
    case OPC_ANDI:
1065
        gen_op_and();
1066
        opn = "andi";
1067
        break;
1068
    case OPC_ORI:
1069
        gen_op_or();
1070
        opn = "ori";
1071
        break;
1072
    case OPC_XORI:
1073
        gen_op_xor();
1074
        opn = "xori";
1075
        break;
1076
    case OPC_LUI:
1077
        opn = "lui";
1078
        break;
1079
    case OPC_SLL:
1080
        gen_op_sll();
1081
        opn = "sll";
1082
        break;
1083
    case OPC_SRA:
1084
        gen_op_sra();
1085
        opn = "sra";
1086
        break;
1087
    case OPC_SRL:
1088
        switch ((ctx->opcode >> 21) & 0x1f) {
1089
        case 0:
1090
            gen_op_srl();
1091
            opn = "srl";
1092
            break;
1093
        case 1:
1094
            gen_op_rotr();
1095
            opn = "rotr";
1096
            break;
1097
        default:
1098
            MIPS_INVAL("invalid srl flag");
1099
            generate_exception(ctx, EXCP_RI);
1100
            break;
1101
        }
1102
        break;
1103
#ifdef TARGET_MIPS64
1104
    case OPC_DSLL:
1105
        gen_op_dsll();
1106
        opn = "dsll";
1107
        break;
1108
    case OPC_DSRA:
1109
        gen_op_dsra();
1110
        opn = "dsra";
1111
        break;
1112
    case OPC_DSRL:
1113
        switch ((ctx->opcode >> 21) & 0x1f) {
1114
        case 0:
1115
            gen_op_dsrl();
1116
            opn = "dsrl";
1117
            break;
1118
        case 1:
1119
            gen_op_drotr();
1120
            opn = "drotr";
1121
            break;
1122
        default:
1123
            MIPS_INVAL("invalid dsrl flag");
1124
            generate_exception(ctx, EXCP_RI);
1125
            break;
1126
        }
1127
        break;
1128
    case OPC_DSLL32:
1129
        gen_op_dsll32();
1130
        opn = "dsll32";
1131
        break;
1132
    case OPC_DSRA32:
1133
        gen_op_dsra32();
1134
        opn = "dsra32";
1135
        break;
1136
    case OPC_DSRL32:
1137
        switch ((ctx->opcode >> 21) & 0x1f) {
1138
        case 0:
1139
            gen_op_dsrl32();
1140
            opn = "dsrl32";
1141
            break;
1142
        case 1:
1143
            gen_op_drotr32();
1144
            opn = "drotr32";
1145
            break;
1146
        default:
1147
            MIPS_INVAL("invalid dsrl32 flag");
1148
            generate_exception(ctx, EXCP_RI);
1149
            break;
1150
        }
1151
        break;
1152
#endif
1153
    default:
1154
        MIPS_INVAL(opn);
1155
        generate_exception(ctx, EXCP_RI);
1156
        return;
1157
    }
1158
    GEN_STORE_TN_REG(rt, T0);
1159
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1160
}
1161

    
1162
/* Arithmetic */
1163
static void gen_arith (DisasContext *ctx, uint32_t opc,
1164
                       int rd, int rs, int rt)
1165
{
1166
    const char *opn = "arith";
1167

    
1168
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1169
       && opc != OPC_DADD && opc != OPC_DSUB) {
1170
        /* if no destination, treat it as a NOP 
1171
         * For add & sub, we must generate the overflow exception when needed.
1172
         */
1173
        MIPS_DEBUG("NOP");
1174
        return;
1175
    }
1176
    GEN_LOAD_REG_TN(T0, rs);
1177
    GEN_LOAD_REG_TN(T1, rt);
1178
    switch (opc) {
1179
    case OPC_ADD:
1180
        save_cpu_state(ctx, 1);
1181
        gen_op_addo();
1182
        opn = "add";
1183
        break;
1184
    case OPC_ADDU:
1185
        gen_op_add();
1186
        opn = "addu";
1187
        break;
1188
    case OPC_SUB:
1189
        save_cpu_state(ctx, 1);
1190
        gen_op_subo();
1191
        opn = "sub";
1192
        break;
1193
    case OPC_SUBU:
1194
        gen_op_sub();
1195
        opn = "subu";
1196
        break;
1197
#ifdef TARGET_MIPS64
1198
    case OPC_DADD:
1199
        save_cpu_state(ctx, 1);
1200
        gen_op_daddo();
1201
        opn = "dadd";
1202
        break;
1203
    case OPC_DADDU:
1204
        gen_op_dadd();
1205
        opn = "daddu";
1206
        break;
1207
    case OPC_DSUB:
1208
        save_cpu_state(ctx, 1);
1209
        gen_op_dsubo();
1210
        opn = "dsub";
1211
        break;
1212
    case OPC_DSUBU:
1213
        gen_op_dsub();
1214
        opn = "dsubu";
1215
        break;
1216
#endif
1217
    case OPC_SLT:
1218
        gen_op_lt();
1219
        opn = "slt";
1220
        break;
1221
    case OPC_SLTU:
1222
        gen_op_ltu();
1223
        opn = "sltu";
1224
        break;
1225
    case OPC_AND:
1226
        gen_op_and();
1227
        opn = "and";
1228
        break;
1229
    case OPC_NOR:
1230
        gen_op_nor();
1231
        opn = "nor";
1232
        break;
1233
    case OPC_OR:
1234
        gen_op_or();
1235
        opn = "or";
1236
        break;
1237
    case OPC_XOR:
1238
        gen_op_xor();
1239
        opn = "xor";
1240
        break;
1241
    case OPC_MUL:
1242
        gen_op_mul();
1243
        opn = "mul";
1244
        break;
1245
    case OPC_MOVN:
1246
        gen_op_movn(rd);
1247
        opn = "movn";
1248
        goto print;
1249
    case OPC_MOVZ:
1250
        gen_op_movz(rd);
1251
        opn = "movz";
1252
        goto print;
1253
    case OPC_SLLV:
1254
        gen_op_sllv();
1255
        opn = "sllv";
1256
        break;
1257
    case OPC_SRAV:
1258
        gen_op_srav();
1259
        opn = "srav";
1260
        break;
1261
    case OPC_SRLV:
1262
        switch ((ctx->opcode >> 6) & 0x1f) {
1263
        case 0:
1264
            gen_op_srlv();
1265
            opn = "srlv";
1266
            break;
1267
        case 1:
1268
            gen_op_rotrv();
1269
            opn = "rotrv";
1270
            break;
1271
        default:
1272
            MIPS_INVAL("invalid srlv flag");
1273
            generate_exception(ctx, EXCP_RI);
1274
            break;
1275
        }
1276
        break;
1277
#ifdef TARGET_MIPS64
1278
    case OPC_DSLLV:
1279
        gen_op_dsllv();
1280
        opn = "dsllv";
1281
        break;
1282
    case OPC_DSRAV:
1283
        gen_op_dsrav();
1284
        opn = "dsrav";
1285
        break;
1286
    case OPC_DSRLV:
1287
        switch ((ctx->opcode >> 6) & 0x1f) {
1288
        case 0:
1289
            gen_op_dsrlv();
1290
            opn = "dsrlv";
1291
            break;
1292
        case 1:
1293
            gen_op_drotrv();
1294
            opn = "drotrv";
1295
            break;
1296
        default:
1297
            MIPS_INVAL("invalid dsrlv flag");
1298
            generate_exception(ctx, EXCP_RI);
1299
            break;
1300
        }
1301
        break;
1302
#endif
1303
    default:
1304
        MIPS_INVAL(opn);
1305
        generate_exception(ctx, EXCP_RI);
1306
        return;
1307
    }
1308
    GEN_STORE_TN_REG(rd, T0);
1309
 print:
1310
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1311
}
1312

    
1313
/* Arithmetic on HI/LO registers */
1314
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1315
{
1316
    const char *opn = "hilo";
1317

    
1318
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1319
        /* Treat as a NOP */
1320
        MIPS_DEBUG("NOP");
1321
        return;
1322
    }
1323
    switch (opc) {
1324
    case OPC_MFHI:
1325
        gen_op_load_HI();
1326
        GEN_STORE_TN_REG(reg, T0);
1327
        opn = "mfhi";
1328
        break;
1329
    case OPC_MFLO:
1330
        gen_op_load_LO();
1331
        GEN_STORE_TN_REG(reg, T0);
1332
        opn = "mflo";
1333
        break;
1334
    case OPC_MTHI:
1335
        GEN_LOAD_REG_TN(T0, reg);
1336
        gen_op_store_HI();
1337
        opn = "mthi";
1338
        break;
1339
    case OPC_MTLO:
1340
        GEN_LOAD_REG_TN(T0, reg);
1341
        gen_op_store_LO();
1342
        opn = "mtlo";
1343
        break;
1344
    default:
1345
        MIPS_INVAL(opn);
1346
        generate_exception(ctx, EXCP_RI);
1347
        return;
1348
    }
1349
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1350
}
1351

    
1352
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1353
                        int rs, int rt)
1354
{
1355
    const char *opn = "mul/div";
1356

    
1357
    GEN_LOAD_REG_TN(T0, rs);
1358
    GEN_LOAD_REG_TN(T1, rt);
1359
    switch (opc) {
1360
    case OPC_DIV:
1361
        gen_op_div();
1362
        opn = "div";
1363
        break;
1364
    case OPC_DIVU:
1365
        gen_op_divu();
1366
        opn = "divu";
1367
        break;
1368
    case OPC_MULT:
1369
        gen_op_mult();
1370
        opn = "mult";
1371
        break;
1372
    case OPC_MULTU:
1373
        gen_op_multu();
1374
        opn = "multu";
1375
        break;
1376
#ifdef TARGET_MIPS64
1377
    case OPC_DDIV:
1378
        gen_op_ddiv();
1379
        opn = "ddiv";
1380
        break;
1381
    case OPC_DDIVU:
1382
        gen_op_ddivu();
1383
        opn = "ddivu";
1384
        break;
1385
    case OPC_DMULT:
1386
        gen_op_dmult();
1387
        opn = "dmult";
1388
        break;
1389
    case OPC_DMULTU:
1390
        gen_op_dmultu();
1391
        opn = "dmultu";
1392
        break;
1393
#endif
1394
    case OPC_MADD:
1395
        gen_op_madd();
1396
        opn = "madd";
1397
        break;
1398
    case OPC_MADDU:
1399
        gen_op_maddu();
1400
        opn = "maddu";
1401
        break;
1402
    case OPC_MSUB:
1403
        gen_op_msub();
1404
        opn = "msub";
1405
        break;
1406
    case OPC_MSUBU:
1407
        gen_op_msubu();
1408
        opn = "msubu";
1409
        break;
1410
    default:
1411
        MIPS_INVAL(opn);
1412
        generate_exception(ctx, EXCP_RI);
1413
        return;
1414
    }
1415
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1416
}
1417

    
1418
static void gen_cl (DisasContext *ctx, uint32_t opc,
1419
                    int rd, int rs)
1420
{
1421
    const char *opn = "CLx";
1422
    if (rd == 0) {
1423
        /* Treat as a NOP */
1424
        MIPS_DEBUG("NOP");
1425
        return;
1426
    }
1427
    GEN_LOAD_REG_TN(T0, rs);
1428
    switch (opc) {
1429
    case OPC_CLO:
1430
        gen_op_clo();
1431
        opn = "clo";
1432
        break;
1433
    case OPC_CLZ:
1434
        gen_op_clz();
1435
        opn = "clz";
1436
        break;
1437
#ifdef TARGET_MIPS64
1438
    case OPC_DCLO:
1439
        gen_op_dclo();
1440
        opn = "dclo";
1441
        break;
1442
    case OPC_DCLZ:
1443
        gen_op_dclz();
1444
        opn = "dclz";
1445
        break;
1446
#endif
1447
    default:
1448
        MIPS_INVAL(opn);
1449
        generate_exception(ctx, EXCP_RI);
1450
        return;
1451
    }
1452
    gen_op_store_T0_gpr(rd);
1453
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1454
}
1455

    
1456
/* Traps */
1457
static void gen_trap (DisasContext *ctx, uint32_t opc,
1458
                      int rs, int rt, int16_t imm)
1459
{
1460
    int cond;
1461

    
1462
    cond = 0;
1463
    /* Load needed operands */
1464
    switch (opc) {
1465
    case OPC_TEQ:
1466
    case OPC_TGE:
1467
    case OPC_TGEU:
1468
    case OPC_TLT:
1469
    case OPC_TLTU:
1470
    case OPC_TNE:
1471
        /* Compare two registers */
1472
        if (rs != rt) {
1473
            GEN_LOAD_REG_TN(T0, rs);
1474
            GEN_LOAD_REG_TN(T1, rt);
1475
            cond = 1;
1476
        }
1477
        break;
1478
    case OPC_TEQI:
1479
    case OPC_TGEI:
1480
    case OPC_TGEIU:
1481
    case OPC_TLTI:
1482
    case OPC_TLTIU:
1483
    case OPC_TNEI:
1484
        /* Compare register to immediate */
1485
        if (rs != 0 || imm != 0) {
1486
            GEN_LOAD_REG_TN(T0, rs);
1487
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1488
            cond = 1;
1489
        }
1490
        break;
1491
    }
1492
    if (cond == 0) {
1493
        switch (opc) {
1494
        case OPC_TEQ:   /* rs == rs */
1495
        case OPC_TEQI:  /* r0 == 0  */
1496
        case OPC_TGE:   /* rs >= rs */
1497
        case OPC_TGEI:  /* r0 >= 0  */
1498
        case OPC_TGEU:  /* rs >= rs unsigned */
1499
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1500
            /* Always trap */
1501
            gen_op_set_T0(1);
1502
            break;
1503
        case OPC_TLT:   /* rs < rs           */
1504
        case OPC_TLTI:  /* r0 < 0            */
1505
        case OPC_TLTU:  /* rs < rs unsigned  */
1506
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1507
        case OPC_TNE:   /* rs != rs          */
1508
        case OPC_TNEI:  /* r0 != 0           */
1509
            /* Never trap: treat as NOP */
1510
            return;
1511
        default:
1512
            MIPS_INVAL("trap");
1513
            generate_exception(ctx, EXCP_RI);
1514
            return;
1515
        }
1516
    } else {
1517
        switch (opc) {
1518
        case OPC_TEQ:
1519
        case OPC_TEQI:
1520
            gen_op_eq();
1521
            break;
1522
        case OPC_TGE:
1523
        case OPC_TGEI:
1524
            gen_op_ge();
1525
            break;
1526
        case OPC_TGEU:
1527
        case OPC_TGEIU:
1528
            gen_op_geu();
1529
            break;
1530
        case OPC_TLT:
1531
        case OPC_TLTI:
1532
            gen_op_lt();
1533
            break;
1534
        case OPC_TLTU:
1535
        case OPC_TLTIU:
1536
            gen_op_ltu();
1537
            break;
1538
        case OPC_TNE:
1539
        case OPC_TNEI:
1540
            gen_op_ne();
1541
            break;
1542
        default:
1543
            MIPS_INVAL("trap");
1544
            generate_exception(ctx, EXCP_RI);
1545
            return;
1546
        }
1547
    }
1548
    save_cpu_state(ctx, 1);
1549
    gen_op_trap();
1550
    ctx->bstate = BS_STOP;
1551
}
1552

    
1553
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1554
{
1555
    TranslationBlock *tb;
1556
    tb = ctx->tb;
1557
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1558
        if (n == 0)
1559
            gen_op_goto_tb0(TBPARAM(tb));
1560
        else
1561
            gen_op_goto_tb1(TBPARAM(tb));
1562
        gen_save_pc(dest);
1563
        gen_op_set_T0((long)tb + n);
1564
    } else {
1565
        gen_save_pc(dest);
1566
        gen_op_reset_T0();
1567
    }
1568
    gen_op_exit_tb();
1569
}
1570

    
1571
/* Branches (before delay slot) */
1572
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1573
                                int rs, int rt, int32_t offset)
1574
{
1575
    target_ulong btarget = -1;
1576
    int blink = 0;
1577
    int bcond = 0;
1578

    
1579
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1580
#ifdef MIPS_DEBUG_DISAS
1581
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1582
            fprintf(logfile,
1583
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1584
                    ctx->pc);
1585
        }
1586
#endif
1587
        generate_exception(ctx, EXCP_RI);
1588
        return;
1589
    }
1590

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

    
1804
    ctx->btarget = btarget;
1805
    if (blink > 0) {
1806
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1807
        gen_op_store_T0_gpr(blink);
1808
    }
1809
}
1810

    
1811
/* special3 bitfield operations */
1812
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1813
                       int rs, int lsb, int msb)
1814
{
1815
    GEN_LOAD_REG_TN(T1, rs);
1816
    switch (opc) {
1817
    case OPC_EXT:
1818
        if (lsb + msb > 31)
1819
            goto fail;
1820
        gen_op_ext(lsb, msb + 1);
1821
        break;
1822
    case OPC_DEXTM:
1823
        if (lsb + msb > 63)
1824
            goto fail;
1825
        gen_op_ext(lsb, msb + 1 + 32);
1826
        break;
1827
    case OPC_DEXTU:
1828
        if (lsb + msb > 63)
1829
            goto fail;
1830
        gen_op_ext(lsb + 32, msb + 1);
1831
        break;
1832
    case OPC_DEXT:
1833
        gen_op_ext(lsb, msb + 1);
1834
        break;
1835
    case OPC_INS:
1836
        if (lsb > msb)
1837
            goto fail;
1838
        GEN_LOAD_REG_TN(T0, rt);
1839
        gen_op_ins(lsb, msb - lsb + 1);
1840
        break;
1841
    case OPC_DINSM:
1842
        if (lsb > msb)
1843
            goto fail;
1844
        GEN_LOAD_REG_TN(T0, rt);
1845
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1846
        break;
1847
    case OPC_DINSU:
1848
        if (lsb > msb)
1849
            goto fail;
1850
        GEN_LOAD_REG_TN(T0, rt);
1851
        gen_op_ins(lsb + 32, msb - lsb + 1);
1852
        break;
1853
    case OPC_DINS:
1854
        if (lsb > msb)
1855
            goto fail;
1856
        GEN_LOAD_REG_TN(T0, rt);
1857
        gen_op_ins(lsb, msb - lsb + 1);
1858
        break;
1859
    default:
1860
fail:
1861
        MIPS_INVAL("bitops");
1862
        generate_exception(ctx, EXCP_RI);
1863
        return;
1864
    }
1865
    GEN_STORE_TN_REG(rt, T0);
1866
}
1867

    
1868
/* CP0 (MMU and control) */
1869
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1870
{
1871
    const char *rn = "invalid";
1872

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

    
2395
die:
2396
#if defined MIPS_DEBUG_DISAS
2397
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2398
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2399
                rn, reg, sel);
2400
    }
2401
#endif
2402
    generate_exception(ctx, EXCP_RI);
2403
}
2404

    
2405
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2406
{
2407
    const char *rn = "invalid";
2408

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

    
2962
die:
2963
#if defined MIPS_DEBUG_DISAS
2964
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2965
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2966
                rn, reg, sel);
2967
    }
2968
#endif
2969
    generate_exception(ctx, EXCP_RI);
2970
}
2971

    
2972
#ifdef TARGET_MIPS64
2973
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2974
{
2975
    const char *rn = "invalid";
2976

    
2977
    switch (reg) {
2978
    case 0:
2979
        switch (sel) {
2980
        case 0:
2981
            gen_op_mfc0_index();
2982
            rn = "Index";
2983
            break;
2984
        case 1:
2985
//            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2986
            rn = "MVPControl";
2987
//            break;
2988
        case 2:
2989
//            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2990
            rn = "MVPConf0";
2991
//            break;
2992
        case 3:
2993
//            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2994
            rn = "MVPConf1";
2995
//            break;
2996
        default:
2997
            goto die;
2998
        }
2999
        break;
3000
    case 1:
3001
        switch (sel) {
3002
        case 0:
3003
            gen_op_mfc0_random();
3004
            rn = "Random";
3005
            break;
3006
        case 1:
3007
//            gen_op_dmfc0_vpecontrol(); /* MT ASE */
3008
            rn = "VPEControl";
3009
//            break;
3010
        case 2:
3011
//            gen_op_dmfc0_vpeconf0(); /* MT ASE */
3012
            rn = "VPEConf0";
3013
//            break;
3014
        case 3:
3015
//            gen_op_dmfc0_vpeconf1(); /* MT ASE */
3016
            rn = "VPEConf1";
3017
//            break;
3018
        case 4:
3019
//            gen_op_dmfc0_YQMask(); /* MT ASE */
3020
            rn = "YQMask";
3021
//            break;
3022
        case 5:
3023
//            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3024
            rn = "VPESchedule";
3025
//            break;
3026
        case 6:
3027
//            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3028
            rn = "VPEScheFBack";
3029
//            break;
3030
        case 7:
3031
//            gen_op_dmfc0_vpeopt(); /* MT ASE */
3032
            rn = "VPEOpt";
3033
//            break;
3034
        default:
3035
            goto die;
3036
        }
3037
        break;
3038
    case 2:
3039
        switch (sel) {
3040
        case 0:
3041
            gen_op_dmfc0_entrylo0();
3042
            rn = "EntryLo0";
3043
            break;
3044
        case 1:
3045
//            gen_op_dmfc0_tcstatus(); /* MT ASE */
3046
            rn = "TCStatus";
3047
//            break;
3048
        case 2:
3049
//            gen_op_dmfc0_tcbind(); /* MT ASE */
3050
            rn = "TCBind";
3051
//            break;
3052
        case 3:
3053
//            gen_op_dmfc0_tcrestart(); /* MT ASE */
3054
            rn = "TCRestart";
3055
//            break;
3056
        case 4:
3057
//            gen_op_dmfc0_tchalt(); /* MT ASE */
3058
            rn = "TCHalt";
3059
//            break;
3060
        case 5:
3061
//            gen_op_dmfc0_tccontext(); /* MT ASE */
3062
            rn = "TCContext";
3063
//            break;
3064
        case 6:
3065
//            gen_op_dmfc0_tcschedule(); /* MT ASE */
3066
            rn = "TCSchedule";
3067
//            break;
3068
        case 7:
3069
//            gen_op_dmfc0_tcschefback(); /* MT ASE */
3070
            rn = "TCScheFBack";
3071
//            break;
3072
        default:
3073
            goto die;
3074
        }
3075
        break;
3076
    case 3:
3077
        switch (sel) {
3078
        case 0:
3079
            gen_op_dmfc0_entrylo1();
3080
            rn = "EntryLo1";
3081
            break;
3082
        default:
3083
            goto die;
3084
        }
3085
        break;
3086
    case 4:
3087
        switch (sel) {
3088
        case 0:
3089
            gen_op_dmfc0_context();
3090
            rn = "Context";
3091
            break;
3092
        case 1:
3093
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3094
            rn = "ContextConfig";
3095
//            break;
3096
        default:
3097
            goto die;
3098
        }
3099
        break;
3100
    case 5:
3101
        switch (sel) {
3102
        case 0:
3103
            gen_op_mfc0_pagemask();
3104
            rn = "PageMask";
3105
            break;
3106
        case 1:
3107
            gen_op_mfc0_pagegrain();
3108
            rn = "PageGrain";
3109
            break;
3110
        default:
3111
            goto die;
3112
        }
3113
        break;
3114
    case 6:
3115
        switch (sel) {
3116
        case 0:
3117
            gen_op_mfc0_wired();
3118
            rn = "Wired";
3119
            break;
3120
        case 1:
3121
//            gen_op_dmfc0_srsconf0(); /* shadow registers */
3122
            rn = "SRSConf0";
3123
//            break;
3124
        case 2:
3125
//            gen_op_dmfc0_srsconf1(); /* shadow registers */
3126
            rn = "SRSConf1";
3127
//            break;
3128
        case 3:
3129
//            gen_op_dmfc0_srsconf2(); /* shadow registers */
3130
            rn = "SRSConf2";
3131
//            break;
3132
        case 4:
3133
//            gen_op_dmfc0_srsconf3(); /* shadow registers */
3134
            rn = "SRSConf3";
3135
//            break;
3136
        case 5:
3137
//            gen_op_dmfc0_srsconf4(); /* shadow registers */
3138
            rn = "SRSConf4";
3139
//            break;
3140
        default:
3141
            goto die;
3142
        }
3143
        break;
3144
    case 7:
3145
        switch (sel) {
3146
        case 0:
3147
            gen_op_mfc0_hwrena();
3148
            rn = "HWREna";
3149
            break;
3150
        default:
3151
            goto die;
3152
        }
3153
        break;
3154
    case 8:
3155
        switch (sel) {
3156
        case 0:
3157
            gen_op_dmfc0_badvaddr();
3158
            rn = "BadVaddr";
3159
            break;
3160
        default:
3161
            goto die;
3162
        }
3163
        break;
3164
    case 9:
3165
        switch (sel) {
3166
        case 0:
3167
            gen_op_mfc0_count();
3168
            rn = "Count";
3169
            break;
3170
        /* 6,7 are implementation dependent */
3171
        default:
3172
            goto die;
3173
        }
3174
        break;
3175
    case 10:
3176
        switch (sel) {
3177
        case 0:
3178
            gen_op_dmfc0_entryhi();
3179
            rn = "EntryHi";
3180
            break;
3181
        default:
3182
            goto die;
3183
        }
3184
        break;
3185
    case 11:
3186
        switch (sel) {
3187
        case 0:
3188
            gen_op_mfc0_compare();
3189
            rn = "Compare";
3190
            break;
3191
        /* 6,7 are implementation dependent */
3192
        default:
3193
            goto die;
3194
        }
3195
        break;
3196
    case 12:
3197
        switch (sel) {
3198
        case 0:
3199
            gen_op_mfc0_status();
3200
            rn = "Status";
3201
            break;
3202
        case 1:
3203
            gen_op_mfc0_intctl();
3204
            rn = "IntCtl";
3205
            break;
3206
        case 2:
3207
            gen_op_mfc0_srsctl();
3208
            rn = "SRSCtl";
3209
            break;
3210
        case 3:
3211
            gen_op_mfc0_srsmap(); /* shadow registers */
3212
            rn = "SRSMap";
3213
            break;
3214
        default:
3215
            goto die;
3216
        }
3217
        break;
3218
    case 13:
3219
        switch (sel) {
3220
        case 0:
3221
            gen_op_mfc0_cause();
3222
            rn = "Cause";
3223
            break;
3224
        default:
3225
            goto die;
3226
        }
3227
        break;
3228
    case 14:
3229
        switch (sel) {
3230
        case 0:
3231
            gen_op_dmfc0_epc();
3232
            rn = "EPC";
3233
            break;
3234
        default:
3235
            goto die;
3236
        }
3237
        break;
3238
    case 15:
3239
        switch (sel) {
3240
        case 0:
3241
            gen_op_mfc0_prid();
3242
            rn = "PRid";
3243
            break;
3244
        case 1:
3245
            gen_op_mfc0_ebase();
3246
            rn = "EBase";
3247
            break;
3248
        default:
3249
            goto die;
3250
        }
3251
        break;
3252
    case 16:
3253
        switch (sel) {
3254
        case 0:
3255
            gen_op_mfc0_config0();
3256
            rn = "Config";
3257
            break;
3258
        case 1:
3259
            gen_op_mfc0_config1();
3260
            rn = "Config1";
3261
            break;
3262
        case 2:
3263
            gen_op_mfc0_config2();
3264
            rn = "Config2";
3265
            break;
3266
        case 3:
3267
            gen_op_mfc0_config3();
3268
            rn = "Config3";
3269
            break;
3270
       /* 6,7 are implementation dependent */
3271
        default:
3272
            goto die;
3273
        }
3274
        break;
3275
    case 17:
3276
        switch (sel) {
3277
        case 0:
3278
            gen_op_dmfc0_lladdr();
3279
            rn = "LLAddr";
3280
            break;
3281
        default:
3282
            goto die;
3283
        }
3284
        break;
3285
    case 18:
3286
        switch (sel) {
3287
        case 0 ... 7:
3288
            gen_op_dmfc0_watchlo(sel);
3289
            rn = "WatchLo";
3290
            break;
3291
        default:
3292
            goto die;
3293
        }
3294
        break;
3295
    case 19:
3296
        switch (sel) {
3297
        case 0 ... 7:
3298
            gen_op_mfc0_watchhi(sel);
3299
            rn = "WatchHi";
3300
            break;
3301
        default:
3302
            goto die;
3303
        }
3304
        break;
3305
    case 20:
3306
        switch (sel) {
3307
        case 0:
3308
#ifdef TARGET_MIPS64
3309
            gen_op_dmfc0_xcontext();
3310
            rn = "XContext";
3311
            break;
3312
#endif
3313
        default:
3314
            goto die;
3315
        }
3316
        break;
3317
    case 21:
3318
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3319
        switch (sel) {
3320
        case 0:
3321
            gen_op_mfc0_framemask();
3322
            rn = "Framemask";
3323
            break;
3324
        default:
3325
            goto die;
3326
        }
3327
        break;
3328
    case 22:
3329
        /* ignored */
3330
        rn = "'Diagnostic"; /* implementation dependent */
3331
        break;
3332
    case 23:
3333
        switch (sel) {
3334
        case 0:
3335
            gen_op_mfc0_debug(); /* EJTAG support */
3336
            rn = "Debug";
3337
            break;
3338
        case 1:
3339
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3340
            rn = "TraceControl";
3341
//            break;
3342
        case 2:
3343
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3344
            rn = "TraceControl2";
3345
//            break;
3346
        case 3:
3347
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3348
            rn = "UserTraceData";
3349
//            break;
3350
        case 4:
3351
//            gen_op_dmfc0_debug(); /* PDtrace support */
3352
            rn = "TraceBPC";
3353
//            break;
3354
        default:
3355
            goto die;
3356
        }
3357
        break;
3358
    case 24:
3359
        switch (sel) {
3360
        case 0:
3361
            gen_op_dmfc0_depc(); /* EJTAG support */
3362
            rn = "DEPC";
3363
            break;
3364
        default:
3365
            goto die;
3366
        }
3367
        break;
3368
    case 25:
3369
        switch (sel) {
3370
        case 0:
3371
            gen_op_mfc0_performance0();
3372
            rn = "Performance0";
3373
            break;
3374
        case 1:
3375
//            gen_op_dmfc0_performance1();
3376
            rn = "Performance1";
3377
//            break;
3378
        case 2:
3379
//            gen_op_dmfc0_performance2();
3380
            rn = "Performance2";
3381
//            break;
3382
        case 3:
3383
//            gen_op_dmfc0_performance3();
3384
            rn = "Performance3";
3385
//            break;
3386
        case 4:
3387
//            gen_op_dmfc0_performance4();
3388
            rn = "Performance4";
3389
//            break;
3390
        case 5:
3391
//            gen_op_dmfc0_performance5();
3392
            rn = "Performance5";
3393
//            break;
3394
        case 6:
3395
//            gen_op_dmfc0_performance6();
3396
            rn = "Performance6";
3397
//            break;
3398
        case 7:
3399
//            gen_op_dmfc0_performance7();
3400
            rn = "Performance7";
3401
//            break;
3402
        default:
3403
            goto die;
3404
        }
3405
        break;
3406
    case 26:
3407
       rn = "ECC";
3408
       break;
3409
    case 27:
3410
        switch (sel) {
3411
        /* ignored */
3412
        case 0 ... 3:
3413
            rn = "CacheErr";
3414
            break;
3415
        default:
3416
            goto die;
3417
        }
3418
        break;
3419
    case 28:
3420
        switch (sel) {
3421
        case 0:
3422
        case 2:
3423
        case 4:
3424
        case 6:
3425
            gen_op_mfc0_taglo();
3426
            rn = "TagLo";
3427
            break;
3428
        case 1:
3429
        case 3:
3430
        case 5:
3431
        case 7:
3432
            gen_op_mfc0_datalo();
3433
            rn = "DataLo";
3434
            break;
3435
        default:
3436
            goto die;
3437
        }
3438
        break;
3439
    case 29:
3440
        switch (sel) {
3441
        case 0:
3442
        case 2:
3443
        case 4:
3444
        case 6:
3445
            gen_op_mfc0_taghi();
3446
            rn = "TagHi";
3447
            break;
3448
        case 1:
3449
        case 3:
3450
        case 5:
3451
        case 7:
3452
            gen_op_mfc0_datahi();
3453
            rn = "DataHi";
3454
            break;
3455
        default:
3456
            goto die;
3457
        }
3458
        break;
3459
    case 30:
3460
        switch (sel) {
3461
        case 0:
3462
            gen_op_dmfc0_errorepc();
3463
            rn = "ErrorEPC";
3464
            break;
3465
        default:
3466
            goto die;
3467
        }
3468
        break;
3469
    case 31:
3470
        switch (sel) {
3471
        case 0:
3472
            gen_op_mfc0_desave(); /* EJTAG support */
3473
            rn = "DESAVE";
3474
            break;
3475
        default:
3476
            goto die;
3477
        }
3478
        break;
3479
    default:
3480
        goto die;
3481
    }
3482
#if defined MIPS_DEBUG_DISAS
3483
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3484
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3485
                rn, reg, sel);
3486
    }
3487
#endif
3488
    return;
3489

    
3490
die:
3491
#if defined MIPS_DEBUG_DISAS
3492
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3493
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3494
                rn, reg, sel);
3495
    }
3496
#endif
3497
    generate_exception(ctx, EXCP_RI);
3498
}
3499

    
3500
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3501
{
3502
    const char *rn = "invalid";
3503

    
3504
    switch (reg) {
3505
    case 0:
3506
        switch (sel) {
3507
        case 0:
3508
            gen_op_mtc0_index();
3509
            rn = "Index";
3510
            break;
3511
        case 1:
3512
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
3513
            rn = "MVPControl";
3514
//            break;
3515
        case 2:
3516
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
3517
            rn = "MVPConf0";
3518
//            break;
3519
        case 3:
3520
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
3521
            rn = "MVPConf1";
3522
//            break;
3523
        default:
3524
            goto die;
3525
        }
3526
        break;
3527
    case 1:
3528
        switch (sel) {
3529
        case 0:
3530
            /* ignored */
3531
            rn = "Random";
3532
            break;
3533
        case 1:
3534
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
3535
            rn = "VPEControl";
3536
//            break;
3537
        case 2:
3538
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
3539
            rn = "VPEConf0";
3540
//            break;
3541
        case 3:
3542
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
3543
            rn = "VPEConf1";
3544
//            break;
3545
        case 4:
3546
//            gen_op_mtc0_YQMask(); /* MT ASE */
3547
            rn = "YQMask";
3548
//            break;
3549
        case 5:
3550
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
3551
            rn = "VPESchedule";
3552
//            break;
3553
        case 6:
3554
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
3555
            rn = "VPEScheFBack";
3556
//            break;
3557
        case 7:
3558
//            gen_op_mtc0_vpeopt(); /* MT ASE */
3559
            rn = "VPEOpt";
3560
//            break;
3561
        default:
3562
            goto die;
3563
        }
3564
        break;
3565
    case 2:
3566
        switch (sel) {
3567
        case 0:
3568
            gen_op_mtc0_entrylo0();
3569
            rn = "EntryLo0";
3570
            break;
3571
        case 1:
3572
//            gen_op_mtc0_tcstatus(); /* MT ASE */
3573
            rn = "TCStatus";
3574
//            break;
3575
        case 2:
3576
//            gen_op_mtc0_tcbind(); /* MT ASE */
3577
            rn = "TCBind";
3578
//            break;
3579
        case 3:
3580
//            gen_op_mtc0_tcrestart(); /* MT ASE */
3581
            rn = "TCRestart";
3582
//            break;
3583
        case 4:
3584
//            gen_op_mtc0_tchalt(); /* MT ASE */
3585
            rn = "TCHalt";
3586
//            break;
3587
        case 5:
3588
//            gen_op_mtc0_tccontext(); /* MT ASE */
3589
            rn = "TCContext";
3590
//            break;
3591
        case 6:
3592
//            gen_op_mtc0_tcschedule(); /* MT ASE */
3593
            rn = "TCSchedule";
3594
//            break;
3595
        case 7:
3596
//            gen_op_mtc0_tcschefback(); /* MT ASE */
3597
            rn = "TCScheFBack";
3598
//            break;
3599
        default:
3600
            goto die;
3601
        }
3602
        break;
3603
    case 3:
3604
        switch (sel) {
3605
        case 0:
3606
            gen_op_mtc0_entrylo1();
3607
            rn = "EntryLo1";
3608
            break;
3609
        default:
3610
            goto die;
3611
        }
3612
        break;
3613
    case 4:
3614
        switch (sel) {
3615
        case 0:
3616
            gen_op_mtc0_context();
3617
            rn = "Context";
3618
            break;
3619
        case 1:
3620
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3621
            rn = "ContextConfig";
3622
//           break;
3623
        default:
3624
            goto die;
3625
        }
3626
        break;
3627
    case 5:
3628
        switch (sel) {
3629
        case 0:
3630
            gen_op_mtc0_pagemask();
3631
            rn = "PageMask";
3632
            break;
3633
        case 1:
3634
            gen_op_mtc0_pagegrain();
3635
            rn = "PageGrain";
3636
            break;
3637
        default:
3638
            goto die;
3639
        }
3640
        break;
3641
    case 6:
3642
        switch (sel) {
3643
        case 0:
3644
            gen_op_mtc0_wired();
3645
            rn = "Wired";
3646
            break;
3647
        case 1:
3648
//            gen_op_mtc0_srsconf0(); /* shadow registers */
3649
            rn = "SRSConf0";
3650
//            break;
3651
        case 2:
3652
//            gen_op_mtc0_srsconf1(); /* shadow registers */
3653
            rn = "SRSConf1";
3654
//            break;
3655
        case 3:
3656
//            gen_op_mtc0_srsconf2(); /* shadow registers */
3657
            rn = "SRSConf2";
3658
//            break;
3659
        case 4:
3660
//            gen_op_mtc0_srsconf3(); /* shadow registers */
3661
            rn = "SRSConf3";
3662
//            break;
3663
        case 5:
3664
//            gen_op_mtc0_srsconf4(); /* shadow registers */
3665
            rn = "SRSConf4";
3666
//            break;
3667
        default:
3668
            goto die;
3669
        }
3670
        break;
3671
    case 7:
3672
        switch (sel) {
3673
        case 0:
3674
            gen_op_mtc0_hwrena();
3675
            rn = "HWREna";
3676
            break;
3677
        default:
3678
            goto die;
3679
        }
3680
        break;
3681
    case 8:
3682
        /* ignored */
3683
        rn = "BadVaddr";
3684
        break;
3685
    case 9:
3686
        switch (sel) {
3687
        case 0:
3688
            gen_op_mtc0_count();
3689
            rn = "Count";
3690
            break;
3691
        /* 6,7 are implementation dependent */
3692
        default:
3693
            goto die;
3694
        }
3695
        /* Stop translation as we may have switched the execution mode */
3696
        ctx->bstate = BS_STOP;
3697
        break;
3698
    case 10:
3699
        switch (sel) {
3700
        case 0:
3701
            gen_op_mtc0_entryhi();
3702
            rn = "EntryHi";
3703
            break;
3704
        default:
3705
            goto die;
3706
        }
3707
        break;
3708
    case 11:
3709
        switch (sel) {
3710
        case 0:
3711
            gen_op_mtc0_compare();
3712
            rn = "Compare";
3713
            break;
3714
        /* 6,7 are implementation dependent */
3715
        default:
3716
            goto die;
3717
        }
3718
        /* Stop translation as we may have switched the execution mode */
3719
        ctx->bstate = BS_STOP;
3720
        break;
3721
    case 12:
3722
        switch (sel) {
3723
        case 0:
3724
            gen_op_mtc0_status();
3725
            /* BS_STOP isn't good enough here, hflags may have changed. */
3726
            gen_save_pc(ctx->pc + 4);
3727
            ctx->bstate = BS_EXCP;
3728
            rn = "Status";
3729
            break;
3730
        case 1:
3731
            gen_op_mtc0_intctl();
3732
            /* Stop translation as we may have switched the execution mode */
3733
            ctx->bstate = BS_STOP;
3734
            rn = "IntCtl";
3735
            break;
3736
        case 2:
3737
            gen_op_mtc0_srsctl();
3738
            /* Stop translation as we may have switched the execution mode */
3739
            ctx->bstate = BS_STOP;
3740
            rn = "SRSCtl";
3741
            break;
3742
        case 3:
3743
            gen_op_mtc0_srsmap();
3744
            /* Stop translation as we may have switched the execution mode */
3745
            ctx->bstate = BS_STOP;
3746
            rn = "SRSMap";
3747
            break;
3748
        default:
3749
            goto die;
3750
        }
3751
        break;
3752
    case 13:
3753
        switch (sel) {
3754
        case 0:
3755
            gen_op_mtc0_cause();
3756
            rn = "Cause";
3757
            break;
3758
        default:
3759
            goto die;
3760
        }
3761
        /* Stop translation as we may have switched the execution mode */
3762
        ctx->bstate = BS_STOP;
3763
        break;
3764
    case 14:
3765
        switch (sel) {
3766
        case 0:
3767
            gen_op_mtc0_epc();
3768
            rn = "EPC";
3769
            break;
3770
        default:
3771
            goto die;
3772
        }
3773
        break;
3774
    case 15:
3775
        switch (sel) {
3776
        case 0:
3777
            /* ignored */
3778
            rn = "PRid";
3779
            break;
3780
        case 1:
3781
            gen_op_mtc0_ebase();
3782
            rn = "EBase";
3783
            break;
3784
        default:
3785
            goto die;
3786
        }
3787
        break;
3788
    case 16:
3789
        switch (sel) {
3790
        case 0:
3791
            gen_op_mtc0_config0();
3792
            rn = "Config";
3793
            /* Stop translation as we may have switched the execution mode */
3794
            ctx->bstate = BS_STOP;
3795
            break;
3796
        case 1:
3797
            /* ignored */
3798
            rn = "Config1";
3799
            break;
3800
        case 2:
3801
            gen_op_mtc0_config2();
3802
            rn = "Config2";
3803
            /* Stop translation as we may have switched the execution mode */
3804
            ctx->bstate = BS_STOP;
3805
            break;
3806
        case 3:
3807
            /* ignored */
3808
            rn = "Config3";
3809
            break;
3810
        /* 6,7 are implementation dependent */
3811
        default:
3812
            rn = "Invalid config selector";
3813
            goto die;
3814
        }
3815
        break;
3816
    case 17:
3817
        switch (sel) {
3818
        case 0:
3819
            /* ignored */
3820
            rn = "LLAddr";
3821
            break;
3822
        default:
3823
            goto die;
3824
        }
3825
        break;
3826
    case 18:
3827
        switch (sel) {
3828
        case 0 ... 7:
3829
            gen_op_mtc0_watchlo(sel);
3830
            rn = "WatchLo";
3831
            break;
3832
        default:
3833
            goto die;
3834
        }
3835
        break;
3836
    case 19:
3837
        switch (sel) {
3838
        case 0 ... 7:
3839
            gen_op_mtc0_watchhi(sel);
3840
            rn = "WatchHi";
3841
            break;
3842
        default:
3843
            goto die;
3844
        }
3845
        break;
3846
    case 20:
3847
        switch (sel) {
3848
        case 0:
3849
#ifdef TARGET_MIPS64
3850
            gen_op_mtc0_xcontext();
3851
            rn = "XContext";
3852
            break;
3853
#endif
3854
        default:
3855
            goto die;
3856
        }
3857
        break;
3858
    case 21:
3859
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3860
        switch (sel) {
3861
        case 0:
3862
            gen_op_mtc0_framemask();
3863
            rn = "Framemask";
3864
            break;
3865
        default:
3866
            goto die;
3867
        }
3868
        break;
3869
    case 22:
3870
        /* ignored */
3871
        rn = "Diagnostic"; /* implementation dependent */
3872
        break;
3873
    case 23:
3874
        switch (sel) {
3875
        case 0:
3876
            gen_op_mtc0_debug(); /* EJTAG support */
3877
            /* BS_STOP isn't good enough here, hflags may have changed. */
3878
            gen_save_pc(ctx->pc + 4);
3879
            ctx->bstate = BS_EXCP;
3880
            rn = "Debug";
3881
            break;
3882
        case 1:
3883
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3884
            /* Stop translation as we may have switched the execution mode */
3885
            ctx->bstate = BS_STOP;
3886
            rn = "TraceControl";
3887
//            break;
3888
        case 2:
3889
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3890
            /* Stop translation as we may have switched the execution mode */
3891
            ctx->bstate = BS_STOP;
3892
            rn = "TraceControl2";
3893
//            break;
3894
        case 3:
3895
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3896
            /* Stop translation as we may have switched the execution mode */
3897
            ctx->bstate = BS_STOP;
3898
            rn = "UserTraceData";
3899
//            break;
3900
        case 4:
3901
//            gen_op_mtc0_debug(); /* PDtrace support */
3902
            /* Stop translation as we may have switched the execution mode */
3903
            ctx->bstate = BS_STOP;
3904
            rn = "TraceBPC";
3905
//            break;
3906
        default:
3907
            goto die;
3908
        }
3909
        break;
3910
    case 24:
3911
        switch (sel) {
3912
        case 0:
3913
            gen_op_mtc0_depc(); /* EJTAG support */
3914
            rn = "DEPC";
3915
            break;
3916
        default:
3917
            goto die;
3918
        }
3919
        break;
3920
    case 25:
3921
        switch (sel) {
3922
        case 0:
3923
            gen_op_mtc0_performance0();
3924
            rn = "Performance0";
3925
            break;
3926
        case 1:
3927
//            gen_op_mtc0_performance1();
3928
            rn = "Performance1";
3929
//            break;
3930
        case 2:
3931
//            gen_op_mtc0_performance2();
3932
            rn = "Performance2";
3933
//            break;
3934
        case 3:
3935
//            gen_op_mtc0_performance3();
3936
            rn = "Performance3";
3937
//            break;
3938
        case 4:
3939
//            gen_op_mtc0_performance4();
3940
            rn = "Performance4";
3941
//            break;
3942
        case 5:
3943
//            gen_op_mtc0_performance5();
3944
            rn = "Performance5";
3945
//            break;
3946
        case 6:
3947
//            gen_op_mtc0_performance6();
3948
            rn = "Performance6";
3949
//            break;
3950
        case 7:
3951
//            gen_op_mtc0_performance7();
3952
            rn = "Performance7";
3953
//            break;
3954
        default:
3955
            goto die;
3956
        }
3957
        break;
3958
    case 26:
3959
        /* ignored */
3960
        rn = "ECC";
3961
        break;
3962
    case 27:
3963
        switch (sel) {
3964
        case 0 ... 3:
3965
            /* ignored */
3966
            rn = "CacheErr";
3967
            break;
3968
        default:
3969
            goto die;
3970
        }
3971
        break;
3972
    case 28:
3973
        switch (sel) {
3974
        case 0:
3975
        case 2:
3976
        case 4:
3977
        case 6:
3978
            gen_op_mtc0_taglo();
3979
            rn = "TagLo";
3980
            break;
3981
        case 1:
3982
        case 3:
3983
        case 5:
3984
        case 7:
3985
            gen_op_mtc0_datalo();
3986
            rn = "DataLo";
3987
            break;
3988
        default:
3989
            goto die;
3990
        }
3991
        break;
3992
    case 29:
3993
        switch (sel) {
3994
        case 0:
3995
        case 2:
3996
        case 4:
3997
        case 6:
3998
            gen_op_mtc0_taghi();
3999
            rn = "TagHi";
4000
            break;
4001
        case 1:
4002
        case 3:
4003
        case 5:
4004
        case 7:
4005
            gen_op_mtc0_datahi();
4006
            rn = "DataHi";
4007
            break;
4008
        default:
4009
            rn = "invalid sel";
4010
            goto die;
4011
        }
4012
        break;
4013
    case 30:
4014
        switch (sel) {
4015
        case 0:
4016
            gen_op_mtc0_errorepc();
4017
            rn = "ErrorEPC";
4018
            break;
4019
        default:
4020
            goto die;
4021
        }
4022
        break;
4023
    case 31:
4024
        switch (sel) {
4025
        case 0:
4026
            gen_op_mtc0_desave(); /* EJTAG support */
4027
            rn = "DESAVE";
4028
            break;
4029
        default:
4030
            goto die;
4031
        }
4032
        /* Stop translation as we may have switched the execution mode */
4033
        ctx->bstate = BS_STOP;
4034
        break;
4035
    default:
4036
        goto die;
4037
    }
4038
#if defined MIPS_DEBUG_DISAS
4039
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4040
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4041
                rn, reg, sel);
4042
    }
4043
#endif
4044
    return;
4045

    
4046
die:
4047
#if defined MIPS_DEBUG_DISAS
4048
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4049
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4050
                rn, reg, sel);
4051
    }
4052
#endif
4053
    generate_exception(ctx, EXCP_RI);
4054
}
4055
#endif /* TARGET_MIPS64 */
4056

    
4057
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4058
{
4059
    const char *opn = "ldst";
4060

    
4061
    switch (opc) {
4062
    case OPC_MFC0:
4063
        if (rt == 0) {
4064
            /* Treat as NOP */
4065
            return;
4066
        }
4067
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4068
        gen_op_store_T0_gpr(rt);
4069
        opn = "mfc0";
4070
        break;
4071
    case OPC_MTC0:
4072
        GEN_LOAD_REG_TN(T0, rt);
4073
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4074
        opn = "mtc0";
4075
        break;
4076
#ifdef TARGET_MIPS64
4077
    case OPC_DMFC0:
4078
        if (rt == 0) {
4079
            /* Treat as NOP */
4080
            return;
4081
        }
4082
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4083
        gen_op_store_T0_gpr(rt);
4084
        opn = "dmfc0";
4085
        break;
4086
    case OPC_DMTC0:
4087
        GEN_LOAD_REG_TN(T0, rt);
4088
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4089
        opn = "dmtc0";
4090
        break;
4091
#endif
4092
    case OPC_TLBWI:
4093
        opn = "tlbwi";
4094
        if (!env->do_tlbwi)
4095
            goto die;
4096
        gen_op_tlbwi();
4097
        break;
4098
    case OPC_TLBWR:
4099
        opn = "tlbwr";
4100
        if (!env->do_tlbwr)
4101
            goto die;
4102
        gen_op_tlbwr();
4103
        break;
4104
    case OPC_TLBP:
4105
        opn = "tlbp";
4106
        if (!env->do_tlbp)
4107
            goto die;
4108
        gen_op_tlbp();
4109
        break;
4110
    case OPC_TLBR:
4111
        opn = "tlbr";
4112
        if (!env->do_tlbr)
4113
            goto die;
4114
        gen_op_tlbr();
4115
        break;
4116
    case OPC_ERET:
4117
        opn = "eret";
4118
        gen_op_eret();
4119
        ctx->bstate = BS_EXCP;
4120
        break;
4121
    case OPC_DERET:
4122
        opn = "deret";
4123
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4124
            MIPS_INVAL(opn);
4125
            generate_exception(ctx, EXCP_RI);
4126
        } else {
4127
            gen_op_deret();
4128
            ctx->bstate = BS_EXCP;
4129
        }
4130
        break;
4131
    case OPC_WAIT:
4132
        opn = "wait";
4133
        /* If we get an exception, we want to restart at next instruction */
4134
        ctx->pc += 4;
4135
        save_cpu_state(ctx, 1);
4136
        ctx->pc -= 4;
4137
        gen_op_wait();
4138
        ctx->bstate = BS_EXCP;
4139
        break;
4140
    default:
4141
 die:
4142
        MIPS_INVAL(opn);
4143
        generate_exception(ctx, EXCP_RI);
4144
        return;
4145
    }
4146
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4147
}
4148

    
4149
/* CP1 Branches (before delay slot) */
4150
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4151
                                 int32_t cc, int32_t offset)
4152
{
4153
    target_ulong btarget;
4154
    const char *opn = "cp1 cond branch";
4155

    
4156
    btarget = ctx->pc + 4 + offset;
4157

    
4158
    switch (op) {
4159
    case OPC_BC1F:
4160
        gen_op_bc1f(cc);
4161
        opn = "bc1f";
4162
        goto not_likely;
4163
    case OPC_BC1FL:
4164
        gen_op_bc1f(cc);
4165
        opn = "bc1fl";
4166
        goto likely;
4167
    case OPC_BC1T:
4168
        gen_op_bc1t(cc);
4169
        opn = "bc1t";
4170
        goto not_likely;
4171
    case OPC_BC1TL:
4172
        gen_op_bc1t(cc);
4173
        opn = "bc1tl";
4174
    likely:
4175
        ctx->hflags |= MIPS_HFLAG_BL;
4176
        gen_op_set_bcond();
4177
        gen_op_save_bcond();
4178
        break;
4179
    case OPC_BC1FANY2:
4180
        gen_op_bc1any2f(cc);
4181
        opn = "bc1any2f";
4182
        goto not_likely;
4183
    case OPC_BC1TANY2:
4184
        gen_op_bc1any2t(cc);
4185
        opn = "bc1any2t";
4186
        goto not_likely;
4187
    case OPC_BC1FANY4:
4188
        gen_op_bc1any4f(cc);
4189
        opn = "bc1any4f";
4190
        goto not_likely;
4191
    case OPC_BC1TANY4:
4192
        gen_op_bc1any4t(cc);
4193
        opn = "bc1any4t";
4194
    not_likely:
4195
        ctx->hflags |= MIPS_HFLAG_BC;
4196
        gen_op_set_bcond();
4197
        break;
4198
    default:
4199
        MIPS_INVAL(opn);
4200
        generate_exception (ctx, EXCP_RI);
4201
        return;
4202
    }
4203
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4204
               ctx->hflags, btarget);
4205
    ctx->btarget = btarget;
4206
}
4207

    
4208
/* Coprocessor 1 (FPU) */
4209

    
4210
#define FOP(func, fmt) (((fmt) << 21) | (func))
4211

    
4212
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4213
{
4214
    const char *opn = "cp1 move";
4215

    
4216
    switch (opc) {
4217
    case OPC_MFC1:
4218
        GEN_LOAD_FREG_FTN(WT0, fs);
4219
        gen_op_mfc1();
4220
        GEN_STORE_TN_REG(rt, T0);
4221
        opn = "mfc1";
4222
        break;
4223
    case OPC_MTC1:
4224
        GEN_LOAD_REG_TN(T0, rt);
4225
        gen_op_mtc1();
4226
        GEN_STORE_FTN_FREG(fs, WT0);
4227
        opn = "mtc1";
4228
        break;
4229
    case OPC_CFC1:
4230
        GEN_LOAD_IMM_TN(T1, fs);
4231
        gen_op_cfc1();
4232
        GEN_STORE_TN_REG(rt, T0);
4233
        opn = "cfc1";
4234
        break;
4235
    case OPC_CTC1:
4236
        GEN_LOAD_IMM_TN(T1, fs);
4237
        GEN_LOAD_REG_TN(T0, rt);
4238
        gen_op_ctc1();
4239
        opn = "ctc1";
4240
        break;
4241
    case OPC_DMFC1:
4242
        GEN_LOAD_FREG_FTN(DT0, fs);
4243
        gen_op_dmfc1();
4244
        GEN_STORE_TN_REG(rt, T0);
4245
        opn = "dmfc1";
4246
        break;
4247
    case OPC_DMTC1:
4248
        GEN_LOAD_REG_TN(T0, rt);
4249
        gen_op_dmtc1();
4250
        GEN_STORE_FTN_FREG(fs, DT0);
4251
        opn = "dmtc1";
4252
        break;
4253
    case OPC_MFHC1:
4254
        GEN_LOAD_FREG_FTN(WTH0, fs);
4255
        gen_op_mfhc1();
4256
        GEN_STORE_TN_REG(rt, T0);
4257
        opn = "mfhc1";
4258
        break;
4259
    case OPC_MTHC1:
4260
        GEN_LOAD_REG_TN(T0, rt);
4261
        gen_op_mthc1();
4262
        GEN_STORE_FTN_FREG(fs, WTH0);
4263
        opn = "mthc1";
4264
        break;
4265
    default:
4266
        MIPS_INVAL(opn);
4267
        generate_exception (ctx, EXCP_RI);
4268
        return;
4269
    }
4270
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4271
}
4272

    
4273
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4274
{
4275
    uint32_t ccbit;
4276

    
4277
    GEN_LOAD_REG_TN(T0, rd);
4278
    GEN_LOAD_REG_TN(T1, rs);
4279
    if (cc) {
4280
        ccbit = 1 << (24 + cc);
4281
    } else
4282
        ccbit = 1 << 23;
4283
    if (!tf)
4284
        gen_op_movf(ccbit);
4285
    else
4286
        gen_op_movt(ccbit);
4287
    GEN_STORE_TN_REG(rd, T0);
4288
}
4289

    
4290
#define GEN_MOVCF(fmt)                                                \
4291
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4292
{                                                                     \
4293
    uint32_t ccbit;                                                   \
4294
                                                                      \
4295
    if (cc) {                                                         \
4296
        ccbit = 1 << (24 + cc);                                       \
4297
    } else                                                            \
4298
        ccbit = 1 << 23;                                              \
4299
    if (!tf)                                                          \
4300
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4301
    else                                                              \
4302
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4303
}
4304
GEN_MOVCF(d);
4305
GEN_MOVCF(s);
4306
GEN_MOVCF(ps);
4307
#undef GEN_MOVCF
4308

    
4309
static void gen_farith (DisasContext *ctx, uint32_t op1,
4310
                        int ft, int fs, int fd, int cc)
4311
{
4312
    const char *opn = "farith";
4313
    const char *condnames[] = {
4314
            "c.f",
4315
            "c.un",
4316
            "c.eq",
4317
            "c.ueq",
4318
            "c.olt",
4319
            "c.ult",
4320
            "c.ole",
4321
            "c.ule",
4322
            "c.sf",
4323
            "c.ngle",
4324
            "c.seq",
4325
            "c.ngl",
4326
            "c.lt",
4327
            "c.nge",
4328
            "c.le",
4329
            "c.ngt",
4330
    };
4331
    const char *condnames_abs[] = {
4332
            "cabs.f",
4333
            "cabs.un",
4334
            "cabs.eq",
4335
            "cabs.ueq",
4336
            "cabs.olt",
4337
            "cabs.ult",
4338
            "cabs.ole",
4339
            "cabs.ule",
4340
            "cabs.sf",
4341
            "cabs.ngle",
4342
            "cabs.seq",
4343
            "cabs.ngl",
4344
            "cabs.lt",
4345
            "cabs.nge",
4346
            "cabs.le",
4347
            "cabs.ngt",
4348
    };
4349
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4350
    uint32_t func = ctx->opcode & 0x3f;
4351

    
4352
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4353
    case FOP(0, 16):
4354
        GEN_LOAD_FREG_FTN(WT0, fs);
4355
        GEN_LOAD_FREG_FTN(WT1, ft);
4356
        gen_op_float_add_s();
4357
        GEN_STORE_FTN_FREG(fd, WT2);
4358
        opn = "add.s";
4359
        optype = BINOP;
4360
        break;
4361
    case FOP(1, 16):
4362
        GEN_LOAD_FREG_FTN(WT0, fs);
4363
        GEN_LOAD_FREG_FTN(WT1, ft);
4364
        gen_op_float_sub_s();
4365
        GEN_STORE_FTN_FREG(fd, WT2);
4366
        opn = "sub.s";
4367
        optype = BINOP;
4368
        break;
4369
    case FOP(2, 16):
4370
        GEN_LOAD_FREG_FTN(WT0, fs);
4371
        GEN_LOAD_FREG_FTN(WT1, ft);
4372
        gen_op_float_mul_s();
4373
        GEN_STORE_FTN_FREG(fd, WT2);
4374
        opn = "mul.s";
4375
        optype = BINOP;
4376
        break;
4377
    case FOP(3, 16):
4378
        GEN_LOAD_FREG_FTN(WT0, fs);
4379
        GEN_LOAD_FREG_FTN(WT1, ft);
4380
        gen_op_float_div_s();
4381
        GEN_STORE_FTN_FREG(fd, WT2);
4382
        opn = "div.s";
4383
        optype = BINOP;
4384
        break;
4385
    case FOP(4, 16):
4386
        GEN_LOAD_FREG_FTN(WT0, fs);
4387
        gen_op_float_sqrt_s();
4388
        GEN_STORE_FTN_FREG(fd, WT2);
4389
        opn = "sqrt.s";
4390
        break;
4391
    case FOP(5, 16):
4392
        GEN_LOAD_FREG_FTN(WT0, fs);
4393
        gen_op_float_abs_s();
4394
        GEN_STORE_FTN_FREG(fd, WT2);
4395
        opn = "abs.s";
4396
        break;
4397
    case FOP(6, 16):
4398
        GEN_LOAD_FREG_FTN(WT0, fs);
4399
        gen_op_float_mov_s();
4400
        GEN_STORE_FTN_FREG(fd, WT2);
4401
        opn = "mov.s";
4402
        break;
4403
    case FOP(7, 16):
4404
        GEN_LOAD_FREG_FTN(WT0, fs);
4405
        gen_op_float_chs_s();
4406
        GEN_STORE_FTN_FREG(fd, WT2);
4407
        opn = "neg.s";
4408
        break;
4409
    case FOP(8, 16):
4410
        check_cp1_64bitmode(ctx);
4411
        GEN_LOAD_FREG_FTN(WT0, fs);
4412
        gen_op_float_roundl_s();
4413
        GEN_STORE_FTN_FREG(fd, DT2);
4414
        opn = "round.l.s";
4415
        break;
4416
    case FOP(9, 16):
4417
        check_cp1_64bitmode(ctx);
4418
        GEN_LOAD_FREG_FTN(WT0, fs);
4419
        gen_op_float_truncl_s();
4420
        GEN_STORE_FTN_FREG(fd, DT2);
4421
        opn = "trunc.l.s";
4422
        break;
4423
    case FOP(10, 16):
4424
        check_cp1_64bitmode(ctx);
4425
        GEN_LOAD_FREG_FTN(WT0, fs);
4426
        gen_op_float_ceill_s();
4427
        GEN_STORE_FTN_FREG(fd, DT2);
4428
        opn = "ceil.l.s";
4429
        break;
4430
    case FOP(11, 16):
4431
        check_cp1_64bitmode(ctx);
4432
        GEN_LOAD_FREG_FTN(WT0, fs);
4433
        gen_op_float_floorl_s();
4434
        GEN_STORE_FTN_FREG(fd, DT2);
4435
        opn = "floor.l.s";
4436
        break;
4437
    case FOP(12, 16):
4438
        GEN_LOAD_FREG_FTN(WT0, fs);
4439
        gen_op_float_roundw_s();
4440
        GEN_STORE_FTN_FREG(fd, WT2);
4441
        opn = "round.w.s";
4442
        break;
4443
    case FOP(13, 16):
4444
        GEN_LOAD_FREG_FTN(WT0, fs);
4445
        gen_op_float_truncw_s();
4446
        GEN_STORE_FTN_FREG(fd, WT2);
4447
        opn = "trunc.w.s";
4448
        break;
4449
    case FOP(14, 16):
4450
        GEN_LOAD_FREG_FTN(WT0, fs);
4451
        gen_op_float_ceilw_s();
4452
        GEN_STORE_FTN_FREG(fd, WT2);
4453
        opn = "ceil.w.s";
4454
        break;
4455
    case FOP(15, 16):
4456
        GEN_LOAD_FREG_FTN(WT0, fs);
4457
        gen_op_float_floorw_s();
4458
        GEN_STORE_FTN_FREG(fd, WT2);
4459
        opn = "floor.w.s";
4460
        break;
4461
    case FOP(17, 16):
4462
        GEN_LOAD_REG_TN(T0, ft);
4463
        GEN_LOAD_FREG_FTN(WT0, fs);
4464
        GEN_LOAD_FREG_FTN(WT2, fd);
4465
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4466
        GEN_STORE_FTN_FREG(fd, WT2);
4467
        opn = "movcf.s";
4468
        break;
4469
    case FOP(18, 16):
4470
        GEN_LOAD_REG_TN(T0, ft);
4471
        GEN_LOAD_FREG_FTN(WT0, fs);
4472
        GEN_LOAD_FREG_FTN(WT2, fd);
4473
        gen_op_float_movz_s();
4474
        GEN_STORE_FTN_FREG(fd, WT2);
4475
        opn = "movz.s";
4476
        break;
4477
    case FOP(19, 16):
4478
        GEN_LOAD_REG_TN(T0, ft);
4479
        GEN_LOAD_FREG_FTN(WT0, fs);
4480
        GEN_LOAD_FREG_FTN(WT2, fd);
4481
        gen_op_float_movn_s();
4482
        GEN_STORE_FTN_FREG(fd, WT2);
4483
        opn = "movn.s";
4484
        break;
4485
    case FOP(21, 16):
4486
        GEN_LOAD_FREG_FTN(WT0, fs);
4487
        gen_op_float_recip_s();
4488
        GEN_STORE_FTN_FREG(fd, WT2);
4489
        opn = "recip.s";
4490
        break;
4491
    case FOP(22, 16):
4492
        GEN_LOAD_FREG_FTN(WT0, fs);
4493
        gen_op_float_rsqrt_s();
4494
        GEN_STORE_FTN_FREG(fd, WT2);
4495
        opn = "rsqrt.s";
4496
        break;
4497
    case FOP(28, 16):
4498
        check_cp1_64bitmode(ctx);
4499
        GEN_LOAD_FREG_FTN(WT0, fs);
4500
        GEN_LOAD_FREG_FTN(WT2, fd);
4501
        gen_op_float_recip2_s();
4502
        GEN_STORE_FTN_FREG(fd, WT2);
4503
        opn = "recip2.s";
4504
        break;
4505
    case FOP(29, 16):
4506
        check_cp1_64bitmode(ctx);
4507
        GEN_LOAD_FREG_FTN(WT0, fs);
4508
        gen_op_float_recip1_s();
4509
        GEN_STORE_FTN_FREG(fd, WT2);
4510
        opn = "recip1.s";
4511
        break;
4512
    case FOP(30, 16):
4513
        check_cp1_64bitmode(ctx);
4514
        GEN_LOAD_FREG_FTN(WT0, fs);
4515
        gen_op_float_rsqrt1_s();
4516
        GEN_STORE_FTN_FREG(fd, WT2);
4517
        opn = "rsqrt1.s";
4518
        break;
4519
    case FOP(31, 16):
4520
        check_cp1_64bitmode(ctx);
4521
        GEN_LOAD_FREG_FTN(WT0, fs);
4522
        GEN_LOAD_FREG_FTN(WT2, fd);
4523
        gen_op_float_rsqrt2_s();
4524
        GEN_STORE_FTN_FREG(fd, WT2);
4525
        opn = "rsqrt2.s";
4526
        break;
4527
    case FOP(33, 16):
4528
        check_cp1_registers(ctx, fd);
4529
        GEN_LOAD_FREG_FTN(WT0, fs);
4530
        gen_op_float_cvtd_s();
4531
        GEN_STORE_FTN_FREG(fd, DT2);
4532
        opn = "cvt.d.s";
4533
        break;
4534
    case FOP(36, 16):
4535
        GEN_LOAD_FREG_FTN(WT0, fs);
4536
        gen_op_float_cvtw_s();
4537
        GEN_STORE_FTN_FREG(fd, WT2);
4538
        opn = "cvt.w.s";
4539
        break;
4540
    case FOP(37, 16):
4541
        check_cp1_64bitmode(ctx);
4542
        GEN_LOAD_FREG_FTN(WT0, fs);
4543
        gen_op_float_cvtl_s();
4544
        GEN_STORE_FTN_FREG(fd, DT2);
4545
        opn = "cvt.l.s";
4546
        break;
4547
    case FOP(38, 16):
4548
        check_cp1_64bitmode(ctx);
4549
        GEN_LOAD_FREG_FTN(WT1, fs);
4550
        GEN_LOAD_FREG_FTN(WT0, ft);
4551
        gen_op_float_cvtps_s();
4552
        GEN_STORE_FTN_FREG(fd, DT2);
4553
        opn = "cvt.ps.s";
4554
        break;
4555
    case FOP(48, 16):
4556
    case FOP(49, 16):
4557
    case FOP(50, 16):
4558
    case FOP(51, 16):
4559
    case FOP(52, 16):
4560
    case FOP(53, 16):
4561
    case FOP(54, 16):
4562
    case FOP(55, 16):
4563
    case FOP(56, 16):
4564
    case FOP(57, 16):
4565
    case FOP(58, 16):
4566
    case FOP(59, 16):
4567
    case FOP(60, 16):
4568
    case FOP(61, 16):
4569
    case FOP(62, 16):
4570
    case FOP(63, 16):
4571
        GEN_LOAD_FREG_FTN(WT0, fs);
4572
        GEN_LOAD_FREG_FTN(WT1, ft);
4573
        if (ctx->opcode & (1 << 6)) {
4574
            check_cp1_64bitmode(ctx);
4575
            gen_cmpabs_s(func-48, cc);
4576
            opn = condnames_abs[func-48];
4577
        } else {
4578
            gen_cmp_s(func-48, cc);
4579
            opn = condnames[func-48];
4580
        }
4581
        break;
4582
    case FOP(0, 17):
4583
        check_cp1_registers(ctx, fs | ft | fd);
4584
        GEN_LOAD_FREG_FTN(DT0, fs);
4585
        GEN_LOAD_FREG_FTN(DT1, ft);
4586
        gen_op_float_add_d();
4587
        GEN_STORE_FTN_FREG(fd, DT2);
4588
        opn = "add.d";
4589
        optype = BINOP;
4590
        break;
4591
    case FOP(1, 17):
4592
        check_cp1_registers(ctx, fs | ft | fd);
4593
        GEN_LOAD_FREG_FTN(DT0, fs);
4594
        GEN_LOAD_FREG_FTN(DT1, ft);
4595
        gen_op_float_sub_d();
4596
        GEN_STORE_FTN_FREG(fd, DT2);
4597
        opn = "sub.d";
4598
        optype = BINOP;
4599
        break;
4600
    case FOP(2, 17):
4601
        check_cp1_registers(ctx, fs | ft | fd);
4602
        GEN_LOAD_FREG_FTN(DT0, fs);
4603
        GEN_LOAD_FREG_FTN(DT1, ft);
4604
        gen_op_float_mul_d();
4605
        GEN_STORE_FTN_FREG(fd, DT2);
4606
        opn = "mul.d";
4607
        optype = BINOP;
4608
        break;
4609
    case FOP(3, 17):
4610
        check_cp1_registers(ctx, fs | ft | fd);
4611
        GEN_LOAD_FREG_FTN(DT0, fs);
4612
        GEN_LOAD_FREG_FTN(DT1, ft);
4613
        gen_op_float_div_d();
4614
        GEN_STORE_FTN_FREG(fd, DT2);
4615
        opn = "div.d";
4616
        optype = BINOP;
4617
        break;
4618
    case FOP(4, 17):
4619
        check_cp1_registers(ctx, fs | fd);
4620
        GEN_LOAD_FREG_FTN(DT0, fs);
4621
        gen_op_float_sqrt_d();
4622
        GEN_STORE_FTN_FREG(fd, DT2);
4623
        opn = "sqrt.d";
4624
        break;
4625
    case FOP(5, 17):
4626
        check_cp1_registers(ctx, fs | fd);
4627
        GEN_LOAD_FREG_FTN(DT0, fs);
4628
        gen_op_float_abs_d();
4629
        GEN_STORE_FTN_FREG(fd, DT2);
4630
        opn = "abs.d";
4631
        break;
4632
    case FOP(6, 17):
4633
        check_cp1_registers(ctx, fs | fd);
4634
        GEN_LOAD_FREG_FTN(DT0, fs);
4635
        gen_op_float_mov_d();
4636
        GEN_STORE_FTN_FREG(fd, DT2);
4637
        opn = "mov.d";
4638
        break;
4639
    case FOP(7, 17):
4640
        check_cp1_registers(ctx, fs | fd);
4641
        GEN_LOAD_FREG_FTN(DT0, fs);
4642
        gen_op_float_chs_d();
4643
        GEN_STORE_FTN_FREG(fd, DT2);
4644
        opn = "neg.d";
4645
        break;
4646
    case FOP(8, 17):
4647
        check_cp1_64bitmode(ctx);
4648
        GEN_LOAD_FREG_FTN(DT0, fs);
4649
        gen_op_float_roundl_d();
4650
        GEN_STORE_FTN_FREG(fd, DT2);
4651
        opn = "round.l.d";
4652
        break;
4653
    case FOP(9, 17):
4654
        check_cp1_64bitmode(ctx);
4655
        GEN_LOAD_FREG_FTN(DT0, fs);
4656
        gen_op_float_truncl_d();
4657
        GEN_STORE_FTN_FREG(fd, DT2);
4658