Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 534ce69f

History | View | Annotate | Download (142.1 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 & ((0x0C << 11) | (1 << 5)))
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_MFHCI    = (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_MTHCI    = (0x07 << 21) | OPC_CP1,
341
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
342
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
343
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
344
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
345
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
346
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
347
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
348
};
349

    
350
enum {
351
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
352
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
353
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
354
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
355
};
356

    
357
#define MASK_CP1_BCOND(op)      MASK_CP1(op) | (op & (0x3 << 16))
358
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
359

    
360
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
361

    
362
enum {
363
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
364
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
365
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
366
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
367
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
368
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
369
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
370
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
371
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
372
};
373

    
374
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
375

    
376
enum {
377
    OPC_LWXC1   = 0x00 | OPC_CP3,
378
    OPC_LDXC1   = 0x01 | OPC_CP3,
379
    OPC_LUXC1   = 0x05 | OPC_CP3,
380
    OPC_SWXC1   = 0x08 | OPC_CP3,
381
    OPC_SDXC1   = 0x09 | OPC_CP3,
382
    OPC_SUXC1   = 0x0D | OPC_CP3,
383
    OPC_PREFX   = 0x0F | OPC_CP3,
384
    OPC_ALNV_PS = 0x1E | OPC_CP3,
385
    OPC_MADD_S  = 0x20 | OPC_CP3,
386
    OPC_MADD_D  = 0x21 | OPC_CP3,
387
    OPC_MADD_PS = 0x26 | OPC_CP3,
388
    OPC_MSUB_S  = 0x28 | OPC_CP3,
389
    OPC_MSUB_D  = 0x29 | OPC_CP3,
390
    OPC_MSUB_PS = 0x2E | OPC_CP3,
391
    OPC_NMADD_S = 0x30 | OPC_CP3,
392
    OPC_NMADD_D = 0x32 | OPC_CP3,
393
    OPC_NMADD_PS= 0x36 | OPC_CP3,
394
    OPC_NMSUB_S = 0x38 | OPC_CP3,
395
    OPC_NMSUB_D = 0x39 | OPC_CP3,
396
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
397
};
398

    
399

    
400
const unsigned char *regnames[] =
401
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
402
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
403
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
404
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
405

    
406
/* Warning: no function for r0 register (hard wired to zero) */
407
#define GEN32(func, NAME) \
408
static GenOpFunc *NAME ## _table [32] = {                                     \
409
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
410
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
411
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
412
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
413
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
414
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
415
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
416
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
417
};                                                                            \
418
static inline void func(int n)                                                \
419
{                                                                             \
420
    NAME ## _table[n]();                                                      \
421
}
422

    
423
/* General purpose registers moves */
424
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
425
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
426
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
427

    
428
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
429
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
430

    
431
static const char *fregnames[] =
432
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
433
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
434
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
435
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
436

    
437
# define SFGEN32(func, NAME) \
438
static GenOpFunc *NAME ## _table [32] = {                                     \
439
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
440
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
441
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
442
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
443
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
444
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
445
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
446
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
447
};                                                                            \
448
static inline void func(int n)                                                \
449
{                                                                             \
450
    NAME ## _table[n]();                                                      \
451
}
452

    
453
# define DFGEN32(func, NAME) \
454
static GenOpFunc *NAME ## _table [32] = {                                     \
455
NAME ## 0,  0, NAME ## 2,  0,                                                 \
456
NAME ## 4,  0, NAME ## 6,  0,                                                 \
457
NAME ## 8,  0, NAME ## 10, 0,                                                 \
458
NAME ## 12, 0, NAME ## 14, 0,                                                 \
459
NAME ## 16, 0, NAME ## 18, 0,                                                 \
460
NAME ## 20, 0, NAME ## 22, 0,                                                 \
461
NAME ## 24, 0, NAME ## 26, 0,                                                 \
462
NAME ## 28, 0, NAME ## 30, 0,                                                 \
463
};                                                                            \
464
static inline void func(int n)                                                \
465
{                                                                             \
466
    NAME ## _table[n]();                                                      \
467
}
468

    
469
SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
470
SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
471

    
472
SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
473
SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
474

    
475
SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
476
SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
477

    
478
DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
479
DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
480

    
481
DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
482
DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
483

    
484
DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
485
DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
486

    
487
#define FOP_CONDS(fmt) \
488
static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
489
    gen_op_cmp_ ## fmt ## _f,                                           \
490
    gen_op_cmp_ ## fmt ## _un,                                          \
491
    gen_op_cmp_ ## fmt ## _eq,                                          \
492
    gen_op_cmp_ ## fmt ## _ueq,                                         \
493
    gen_op_cmp_ ## fmt ## _olt,                                         \
494
    gen_op_cmp_ ## fmt ## _ult,                                         \
495
    gen_op_cmp_ ## fmt ## _ole,                                         \
496
    gen_op_cmp_ ## fmt ## _ule,                                         \
497
    gen_op_cmp_ ## fmt ## _sf,                                          \
498
    gen_op_cmp_ ## fmt ## _ngle,                                        \
499
    gen_op_cmp_ ## fmt ## _seq,                                         \
500
    gen_op_cmp_ ## fmt ## _ngl,                                         \
501
    gen_op_cmp_ ## fmt ## _lt,                                          \
502
    gen_op_cmp_ ## fmt ## _nge,                                         \
503
    gen_op_cmp_ ## fmt ## _le,                                          \
504
    gen_op_cmp_ ## fmt ## _ngt,                                         \
505
};                                                                      \
506
static inline void gen_cmp_ ## fmt(int n)                               \
507
{                                                                       \
508
    cond_ ## fmt ## _table[n]();                                        \
509
}
510

    
511
FOP_CONDS(d)
512
FOP_CONDS(s)
513

    
514
typedef struct DisasContext {
515
    struct TranslationBlock *tb;
516
    target_ulong pc, saved_pc;
517
    uint32_t opcode;
518
    /* Routine used to access memory */
519
    int mem_idx;
520
    uint32_t hflags, saved_hflags;
521
    uint32_t CP0_Status;
522
    int bstate;
523
    target_ulong btarget;
524
} DisasContext;
525

    
526
enum {
527
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
528
                      * exception condition
529
                      */
530
    BS_STOP     = 1, /* We want to stop translation for any reason */
531
    BS_BRANCH   = 2, /* We reached a branch condition     */
532
    BS_EXCP     = 3, /* We reached an exception condition */
533
};
534

    
535
#if defined MIPS_DEBUG_DISAS
536
#define MIPS_DEBUG(fmt, args...)                                              \
537
do {                                                                          \
538
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
539
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
540
                ctx->pc, ctx->opcode , ##args);                               \
541
    }                                                                         \
542
} while (0)
543
#else
544
#define MIPS_DEBUG(fmt, args...) do { } while(0)
545
#endif
546

    
547
#define MIPS_INVAL(op)                                                        \
548
do {                                                                          \
549
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
550
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
551
} while (0)
552

    
553
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
554
do {                                                                          \
555
    if (Rn == 0) {                                                            \
556
        glue(gen_op_reset_, Tn)();                                            \
557
    } else {                                                                  \
558
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
559
    }                                                                         \
560
} while (0)
561

    
562
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
563
do {                                                                          \
564
    if (Imm == 0) {                                                           \
565
        glue(gen_op_reset_, Tn)();                                            \
566
    } else {                                                                  \
567
        glue(gen_op_set_, Tn)(Imm);                                           \
568
    }                                                                         \
569
} while (0)
570

    
571
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
572
do {                                                                          \
573
    if (Rn != 0) {                                                            \
574
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
575
    }                                                                         \
576
} while (0)
577

    
578
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
579
do {                                                                          \
580
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
581
} while (0)
582

    
583
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
584
do {                                                                          \
585
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
586
} while (0)
587

    
588
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
589
{
590
#if defined MIPS_DEBUG_DISAS
591
    if (loglevel & CPU_LOG_TB_IN_ASM) {
592
            fprintf(logfile, "hflags %08x saved %08x\n",
593
                    ctx->hflags, ctx->saved_hflags);
594
    }
595
#endif
596
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
597
        gen_op_save_pc(ctx->pc);
598
        ctx->saved_pc = ctx->pc;
599
    }
600
    if (ctx->hflags != ctx->saved_hflags) {
601
        gen_op_save_state(ctx->hflags);
602
        ctx->saved_hflags = ctx->hflags;
603
        if (ctx->hflags & MIPS_HFLAG_BR) {
604
            gen_op_save_breg_target();
605
        } else if (ctx->hflags & MIPS_HFLAG_B) {
606
            gen_op_save_btarget(ctx->btarget);
607
        } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
608
            gen_op_save_bcond();
609
            gen_op_save_btarget(ctx->btarget);
610
        }
611
    }
612
}
613

    
614
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
615
{
616
#if defined MIPS_DEBUG_DISAS
617
    if (loglevel & CPU_LOG_TB_IN_ASM)
618
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
619
#endif
620
    save_cpu_state(ctx, 1);
621
    if (err == 0)
622
        gen_op_raise_exception(excp);
623
    else
624
        gen_op_raise_exception_err(excp, err);
625
    ctx->bstate = BS_EXCP;
626
}
627

    
628
static inline void generate_exception (DisasContext *ctx, int excp)
629
{
630
    generate_exception_err (ctx, excp, 0);
631
}
632

    
633
#if defined(CONFIG_USER_ONLY)
634
#define op_ldst(name)        gen_op_##name##_raw()
635
#define OP_LD_TABLE(width)
636
#define OP_ST_TABLE(width)
637
#else
638
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
639
#define OP_LD_TABLE(width)                                                    \
640
static GenOpFunc *gen_op_l##width[] = {                                       \
641
    &gen_op_l##width##_user,                                                  \
642
    &gen_op_l##width##_kernel,                                                \
643
}
644
#define OP_ST_TABLE(width)                                                    \
645
static GenOpFunc *gen_op_s##width[] = {                                       \
646
    &gen_op_s##width##_user,                                                  \
647
    &gen_op_s##width##_kernel,                                                \
648
}
649
#endif
650

    
651
#ifdef TARGET_MIPS64
652
OP_LD_TABLE(d);
653
OP_LD_TABLE(dl);
654
OP_LD_TABLE(dr);
655
OP_ST_TABLE(d);
656
OP_ST_TABLE(dl);
657
OP_ST_TABLE(dr);
658
OP_LD_TABLE(ld);
659
OP_ST_TABLE(cd);
660
#endif
661
OP_LD_TABLE(w);
662
OP_LD_TABLE(wu);
663
OP_LD_TABLE(wl);
664
OP_LD_TABLE(wr);
665
OP_ST_TABLE(w);
666
OP_ST_TABLE(wl);
667
OP_ST_TABLE(wr);
668
OP_LD_TABLE(h);
669
OP_LD_TABLE(hu);
670
OP_ST_TABLE(h);
671
OP_LD_TABLE(b);
672
OP_LD_TABLE(bu);
673
OP_ST_TABLE(b);
674
OP_LD_TABLE(l);
675
OP_ST_TABLE(c);
676
OP_LD_TABLE(wc1);
677
OP_ST_TABLE(wc1);
678
OP_LD_TABLE(dc1);
679
OP_ST_TABLE(dc1);
680

    
681
/* Load and store */
682
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
683
                      int base, int16_t offset)
684
{
685
    const char *opn = "unk";
686

    
687
    if (base == 0) {
688
        GEN_LOAD_IMM_TN(T0, offset);
689
    } else if (offset == 0) {
690
        gen_op_load_gpr_T0(base);
691
    } else {
692
        gen_op_load_gpr_T0(base);
693
        gen_op_set_T1(offset);
694
        gen_op_add();
695
    }
696
    /* Don't do NOP if destination is zero: we must perform the actual
697
     * memory access
698
     */
699
    switch (opc) {
700
#ifdef TARGET_MIPS64
701
    case OPC_LD:
702
        op_ldst(ld);
703
        GEN_STORE_TN_REG(rt, T0);
704
        opn = "ld";
705
        break;
706
    case OPC_LLD:
707
        op_ldst(lld);
708
        GEN_STORE_TN_REG(rt, T0);
709
        opn = "lld";
710
        break;
711
    case OPC_SD:
712
        GEN_LOAD_REG_TN(T1, rt);
713
        op_ldst(sd);
714
        opn = "sd";
715
        break;
716
    case OPC_SCD:
717
        save_cpu_state(ctx, 1);
718
        GEN_LOAD_REG_TN(T1, rt);
719
        op_ldst(scd);
720
        opn = "scd";
721
        break;
722
    case OPC_LDL:
723
        op_ldst(ldl);
724
        GEN_STORE_TN_REG(rt, T0);
725
        opn = "ldl";
726
        break;
727
    case OPC_SDL:
728
        GEN_LOAD_REG_TN(T1, rt);
729
        op_ldst(sdl);
730
        opn = "sdl";
731
        break;
732
    case OPC_LDR:
733
        op_ldst(ldr);
734
        GEN_STORE_TN_REG(rt, T0);
735
        opn = "ldr";
736
        break;
737
    case OPC_SDR:
738
        GEN_LOAD_REG_TN(T1, rt);
739
        op_ldst(sdr);
740
        opn = "sdr";
741
        break;
742
#endif
743
    case OPC_LW:
744
        op_ldst(lw);
745
        GEN_STORE_TN_REG(rt, T0);
746
        opn = "lw";
747
        break;
748
    case OPC_LWU:
749
        op_ldst(lwu);
750
        GEN_STORE_TN_REG(rt, T0);
751
        opn = "lwu";
752
        break;
753
    case OPC_SW:
754
        GEN_LOAD_REG_TN(T1, rt);
755
        op_ldst(sw);
756
        opn = "sw";
757
        break;
758
    case OPC_LH:
759
        op_ldst(lh);
760
        GEN_STORE_TN_REG(rt, T0);
761
        opn = "lh";
762
        break;
763
    case OPC_SH:
764
        GEN_LOAD_REG_TN(T1, rt);
765
        op_ldst(sh);
766
        opn = "sh";
767
        break;
768
    case OPC_LHU:
769
        op_ldst(lhu);
770
        GEN_STORE_TN_REG(rt, T0);
771
        opn = "lhu";
772
        break;
773
    case OPC_LB:
774
        op_ldst(lb);
775
        GEN_STORE_TN_REG(rt, T0);
776
        opn = "lb";
777
        break;
778
    case OPC_SB:
779
        GEN_LOAD_REG_TN(T1, rt);
780
        op_ldst(sb);
781
        opn = "sb";
782
        break;
783
    case OPC_LBU:
784
        op_ldst(lbu);
785
        GEN_STORE_TN_REG(rt, T0);
786
        opn = "lbu";
787
        break;
788
    case OPC_LWL:
789
        GEN_LOAD_REG_TN(T1, rt);
790
        op_ldst(lwl);
791
        GEN_STORE_TN_REG(rt, T0);
792
        opn = "lwl";
793
        break;
794
    case OPC_SWL:
795
        GEN_LOAD_REG_TN(T1, rt);
796
        op_ldst(swl);
797
        opn = "swr";
798
        break;
799
    case OPC_LWR:
800
        GEN_LOAD_REG_TN(T1, rt);
801
        op_ldst(lwr);
802
        GEN_STORE_TN_REG(rt, T0);
803
        opn = "lwr";
804
        break;
805
    case OPC_SWR:
806
        GEN_LOAD_REG_TN(T1, rt);
807
        op_ldst(swr);
808
        opn = "swr";
809
        break;
810
    case OPC_LL:
811
        op_ldst(ll);
812
        GEN_STORE_TN_REG(rt, T0);
813
        opn = "ll";
814
        break;
815
    case OPC_SC:
816
        save_cpu_state(ctx, 1);
817
        GEN_LOAD_REG_TN(T1, rt);
818
        op_ldst(sc);
819
        GEN_STORE_TN_REG(rt, T0);
820
        opn = "sc";
821
        break;
822
    default:
823
        MIPS_INVAL("load/store");
824
        generate_exception(ctx, EXCP_RI);
825
        return;
826
    }
827
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
828
}
829

    
830
/* Load and store */
831
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
832
                      int base, int16_t offset)
833
{
834
    const char *opn = "unk";
835

    
836
    if (base == 0) {
837
        GEN_LOAD_IMM_TN(T0, offset);
838
    } else if (offset == 0) {
839
        gen_op_load_gpr_T0(base);
840
    } else {
841
        gen_op_load_gpr_T0(base);
842
        gen_op_set_T1(offset);
843
        gen_op_add();
844
    }
845
    /* Don't do NOP if destination is zero: we must perform the actual
846
     * memory access
847
     */
848
    switch (opc) {
849
    case OPC_LWC1:
850
        op_ldst(lwc1);
851
        GEN_STORE_FTN_FREG(ft, WT0);
852
        opn = "lwc1";
853
        break;
854
    case OPC_SWC1:
855
        GEN_LOAD_FREG_FTN(WT0, ft);
856
        op_ldst(swc1);
857
        opn = "swc1";
858
        break;
859
    case OPC_LDC1:
860
        op_ldst(ldc1);
861
        GEN_STORE_FTN_FREG(ft, DT0);
862
        opn = "ldc1";
863
        break;
864
    case OPC_SDC1:
865
        GEN_LOAD_FREG_FTN(DT0, ft);
866
        op_ldst(sdc1);
867
        opn = "sdc1";
868
        break;
869
    default:
870
        MIPS_INVAL("float load/store");
871
        generate_exception(ctx, EXCP_RI);
872
        return;
873
    }
874
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
875
}
876

    
877
/* Arithmetic with immediate operand */
878
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
879
                           int rs, int16_t imm)
880
{
881
    uint32_t uimm;
882
    const char *opn = "unk";
883

    
884
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
885
        /* if no destination, treat it as a NOP 
886
         * For addi, we must generate the overflow exception when needed.
887
         */
888
        MIPS_DEBUG("NOP");
889
        return;
890
    }
891
    uimm = (uint16_t)imm;
892
    switch (opc) {
893
    case OPC_ADDI:
894
    case OPC_ADDIU:
895
#ifdef TARGET_MIPS64
896
    case OPC_DADDI:
897
    case OPC_DADDIU:
898
#endif
899
    case OPC_SLTI:
900
    case OPC_SLTIU:
901
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
902
        /* Fall through. */
903
    case OPC_ANDI:
904
    case OPC_ORI:
905
    case OPC_XORI:
906
        GEN_LOAD_REG_TN(T0, rs);
907
        GEN_LOAD_IMM_TN(T1, uimm);
908
        break;
909
    case OPC_LUI:
910
        uimm <<= 16;
911
        GEN_LOAD_IMM_TN(T0, uimm);
912
        break;
913
    case OPC_SLL:
914
    case OPC_SRA:
915
    case OPC_SRL:
916
#ifdef TARGET_MIPS64
917
    case OPC_DSLL:
918
    case OPC_DSRA:
919
    case OPC_DSRL:
920
    case OPC_DSLL32:
921
    case OPC_DSRA32:
922
    case OPC_DSRL32:
923
#endif
924
        uimm &= 0x1f;
925
        GEN_LOAD_REG_TN(T0, rs);
926
        GEN_LOAD_IMM_TN(T1, uimm);
927
        break;
928
    }
929
    switch (opc) {
930
    case OPC_ADDI:
931
        save_cpu_state(ctx, 1);
932
        gen_op_addo();
933
        opn = "addi";
934
        break;
935
    case OPC_ADDIU:
936
        gen_op_add();
937
        opn = "addiu";
938
        break;
939
#ifdef TARGET_MIPS64
940
    case OPC_DADDI:
941
        save_cpu_state(ctx, 1);
942
        gen_op_daddo();
943
        opn = "daddi";
944
        break;
945
    case OPC_DADDIU:
946
        gen_op_dadd();
947
        opn = "daddiu";
948
        break;
949
#endif
950
    case OPC_SLTI:
951
        gen_op_lt();
952
        opn = "slti";
953
        break;
954
    case OPC_SLTIU:
955
        gen_op_ltu();
956
        opn = "sltiu";
957
        break;
958
    case OPC_ANDI:
959
        gen_op_and();
960
        opn = "andi";
961
        break;
962
    case OPC_ORI:
963
        gen_op_or();
964
        opn = "ori";
965
        break;
966
    case OPC_XORI:
967
        gen_op_xor();
968
        opn = "xori";
969
        break;
970
    case OPC_LUI:
971
        opn = "lui";
972
        break;
973
    case OPC_SLL:
974
        gen_op_sll();
975
        opn = "sll";
976
        break;
977
    case OPC_SRA:
978
        gen_op_sra();
979
        opn = "sra";
980
        break;
981
    case OPC_SRL:
982
        switch ((ctx->opcode >> 21) & 0x1f) {
983
        case 0:
984
            gen_op_srl();
985
            opn = "srl";
986
            break;
987
        case 1:
988
            gen_op_rotr();
989
            opn = "rotr";
990
            break;
991
        default:
992
            MIPS_INVAL("invalid srl flag");
993
            generate_exception(ctx, EXCP_RI);
994
            break;
995
        }
996
        break;
997
#ifdef TARGET_MIPS64
998
    case OPC_DSLL:
999
        gen_op_dsll();
1000
        opn = "dsll";
1001
        break;
1002
    case OPC_DSRA:
1003
        gen_op_dsra();
1004
        opn = "dsra";
1005
        break;
1006
    case OPC_DSRL:
1007
        switch ((ctx->opcode >> 21) & 0x1f) {
1008
        case 0:
1009
            gen_op_dsrl();
1010
            opn = "dsrl";
1011
            break;
1012
        case 1:
1013
            gen_op_drotr();
1014
            opn = "drotr";
1015
            break;
1016
        default:
1017
            MIPS_INVAL("invalid dsrl flag");
1018
            generate_exception(ctx, EXCP_RI);
1019
            break;
1020
        }
1021
        break;
1022
    case OPC_DSLL32:
1023
        gen_op_dsll32();
1024
        opn = "dsll32";
1025
        break;
1026
    case OPC_DSRA32:
1027
        gen_op_dsra32();
1028
        opn = "dsra32";
1029
        break;
1030
    case OPC_DSRL32:
1031
        switch ((ctx->opcode >> 21) & 0x1f) {
1032
        case 0:
1033
            gen_op_dsrl32();
1034
            opn = "dsrl32";
1035
            break;
1036
        case 1:
1037
            gen_op_drotr32();
1038
            opn = "drotr32";
1039
            break;
1040
        default:
1041
            MIPS_INVAL("invalid dsrl32 flag");
1042
            generate_exception(ctx, EXCP_RI);
1043
            break;
1044
        }
1045
        break;
1046
#endif
1047
    default:
1048
        MIPS_INVAL("imm arith");
1049
        generate_exception(ctx, EXCP_RI);
1050
        return;
1051
    }
1052
    GEN_STORE_TN_REG(rt, T0);
1053
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1054
}
1055

    
1056
/* Arithmetic */
1057
static void gen_arith (DisasContext *ctx, uint32_t opc,
1058
                       int rd, int rs, int rt)
1059
{
1060
    const char *opn = "unk";
1061

    
1062
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1063
       && opc != OPC_DADD && opc != OPC_DSUB) {
1064
        /* if no destination, treat it as a NOP 
1065
         * For add & sub, we must generate the overflow exception when needed.
1066
         */
1067
        MIPS_DEBUG("NOP");
1068
        return;
1069
    }
1070
    GEN_LOAD_REG_TN(T0, rs);
1071
    GEN_LOAD_REG_TN(T1, rt);
1072
    switch (opc) {
1073
    case OPC_ADD:
1074
        save_cpu_state(ctx, 1);
1075
        gen_op_addo();
1076
        opn = "add";
1077
        break;
1078
    case OPC_ADDU:
1079
        gen_op_add();
1080
        opn = "addu";
1081
        break;
1082
    case OPC_SUB:
1083
        save_cpu_state(ctx, 1);
1084
        gen_op_subo();
1085
        opn = "sub";
1086
        break;
1087
    case OPC_SUBU:
1088
        gen_op_sub();
1089
        opn = "subu";
1090
        break;
1091
#ifdef TARGET_MIPS64
1092
    case OPC_DADD:
1093
        save_cpu_state(ctx, 1);
1094
        gen_op_daddo();
1095
        opn = "dadd";
1096
        break;
1097
    case OPC_DADDU:
1098
        gen_op_dadd();
1099
        opn = "daddu";
1100
        break;
1101
    case OPC_DSUB:
1102
        save_cpu_state(ctx, 1);
1103
        gen_op_dsubo();
1104
        opn = "dsub";
1105
        break;
1106
    case OPC_DSUBU:
1107
        gen_op_dsub();
1108
        opn = "dsubu";
1109
        break;
1110
#endif
1111
    case OPC_SLT:
1112
        gen_op_lt();
1113
        opn = "slt";
1114
        break;
1115
    case OPC_SLTU:
1116
        gen_op_ltu();
1117
        opn = "sltu";
1118
        break;
1119
    case OPC_AND:
1120
        gen_op_and();
1121
        opn = "and";
1122
        break;
1123
    case OPC_NOR:
1124
        gen_op_nor();
1125
        opn = "nor";
1126
        break;
1127
    case OPC_OR:
1128
        gen_op_or();
1129
        opn = "or";
1130
        break;
1131
    case OPC_XOR:
1132
        gen_op_xor();
1133
        opn = "xor";
1134
        break;
1135
    case OPC_MUL:
1136
        gen_op_mul();
1137
        opn = "mul";
1138
        break;
1139
    case OPC_MOVN:
1140
        gen_op_movn(rd);
1141
        opn = "movn";
1142
        goto print;
1143
    case OPC_MOVZ:
1144
        gen_op_movz(rd);
1145
        opn = "movz";
1146
        goto print;
1147
    case OPC_SLLV:
1148
        gen_op_sllv();
1149
        opn = "sllv";
1150
        break;
1151
    case OPC_SRAV:
1152
        gen_op_srav();
1153
        opn = "srav";
1154
        break;
1155
    case OPC_SRLV:
1156
        switch ((ctx->opcode >> 6) & 0x1f) {
1157
        case 0:
1158
            gen_op_srlv();
1159
            opn = "srlv";
1160
            break;
1161
        case 1:
1162
            gen_op_rotrv();
1163
            opn = "rotrv";
1164
            break;
1165
        default:
1166
            MIPS_INVAL("invalid srlv flag");
1167
            generate_exception(ctx, EXCP_RI);
1168
            break;
1169
        }
1170
        break;
1171
#ifdef TARGET_MIPS64
1172
    case OPC_DSLLV:
1173
        gen_op_dsllv();
1174
        opn = "dsllv";
1175
        break;
1176
    case OPC_DSRAV:
1177
        gen_op_dsrav();
1178
        opn = "dsrav";
1179
        break;
1180
    case OPC_DSRLV:
1181
        switch ((ctx->opcode >> 6) & 0x1f) {
1182
        case 0:
1183
            gen_op_dsrlv();
1184
            opn = "dsrlv";
1185
            break;
1186
        case 1:
1187
            gen_op_drotrv();
1188
            opn = "drotrv";
1189
            break;
1190
        default:
1191
            MIPS_INVAL("invalid dsrlv flag");
1192
            generate_exception(ctx, EXCP_RI);
1193
            break;
1194
        }
1195
        break;
1196
#endif
1197
    default:
1198
        MIPS_INVAL("arith");
1199
        generate_exception(ctx, EXCP_RI);
1200
        return;
1201
    }
1202
    GEN_STORE_TN_REG(rd, T0);
1203
 print:
1204
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1205
}
1206

    
1207
/* Arithmetic on HI/LO registers */
1208
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1209
{
1210
    const char *opn = "unk";
1211

    
1212
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1213
        /* Treat as a NOP */
1214
        MIPS_DEBUG("NOP");
1215
        return;
1216
    }
1217
    switch (opc) {
1218
    case OPC_MFHI:
1219
        gen_op_load_HI();
1220
        GEN_STORE_TN_REG(reg, T0);
1221
        opn = "mfhi";
1222
        break;
1223
    case OPC_MFLO:
1224
        gen_op_load_LO();
1225
        GEN_STORE_TN_REG(reg, T0);
1226
        opn = "mflo";
1227
        break;
1228
    case OPC_MTHI:
1229
        GEN_LOAD_REG_TN(T0, reg);
1230
        gen_op_store_HI();
1231
        opn = "mthi";
1232
        break;
1233
    case OPC_MTLO:
1234
        GEN_LOAD_REG_TN(T0, reg);
1235
        gen_op_store_LO();
1236
        opn = "mtlo";
1237
        break;
1238
    default:
1239
        MIPS_INVAL("HILO");
1240
        generate_exception(ctx, EXCP_RI);
1241
        return;
1242
    }
1243
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1244
}
1245

    
1246
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1247
                        int rs, int rt)
1248
{
1249
    const char *opn = "unk";
1250

    
1251
    GEN_LOAD_REG_TN(T0, rs);
1252
    GEN_LOAD_REG_TN(T1, rt);
1253
    switch (opc) {
1254
    case OPC_DIV:
1255
        gen_op_div();
1256
        opn = "div";
1257
        break;
1258
    case OPC_DIVU:
1259
        gen_op_divu();
1260
        opn = "divu";
1261
        break;
1262
    case OPC_MULT:
1263
        gen_op_mult();
1264
        opn = "mult";
1265
        break;
1266
    case OPC_MULTU:
1267
        gen_op_multu();
1268
        opn = "multu";
1269
        break;
1270
#ifdef TARGET_MIPS64
1271
    case OPC_DDIV:
1272
        gen_op_ddiv();
1273
        opn = "ddiv";
1274
        break;
1275
    case OPC_DDIVU:
1276
        gen_op_ddivu();
1277
        opn = "ddivu";
1278
        break;
1279
    case OPC_DMULT:
1280
        gen_op_dmult();
1281
        opn = "dmult";
1282
        break;
1283
    case OPC_DMULTU:
1284
        gen_op_dmultu();
1285
        opn = "dmultu";
1286
        break;
1287
#endif
1288
    case OPC_MADD:
1289
        gen_op_madd();
1290
        opn = "madd";
1291
        break;
1292
    case OPC_MADDU:
1293
        gen_op_maddu();
1294
        opn = "maddu";
1295
        break;
1296
    case OPC_MSUB:
1297
        gen_op_msub();
1298
        opn = "msub";
1299
        break;
1300
    case OPC_MSUBU:
1301
        gen_op_msubu();
1302
        opn = "msubu";
1303
        break;
1304
    default:
1305
        MIPS_INVAL("mul/div");
1306
        generate_exception(ctx, EXCP_RI);
1307
        return;
1308
    }
1309
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1310
}
1311

    
1312
static void gen_cl (DisasContext *ctx, uint32_t opc,
1313
                    int rd, int rs)
1314
{
1315
    const char *opn = "unk";
1316
    if (rd == 0) {
1317
        /* Treat as a NOP */
1318
        MIPS_DEBUG("NOP");
1319
        return;
1320
    }
1321
    GEN_LOAD_REG_TN(T0, rs);
1322
    switch (opc) {
1323
    case OPC_CLO:
1324
        gen_op_clo();
1325
        opn = "clo";
1326
        break;
1327
    case OPC_CLZ:
1328
        gen_op_clz();
1329
        opn = "clz";
1330
        break;
1331
#ifdef TARGET_MIPS64
1332
    case OPC_DCLO:
1333
        gen_op_dclo();
1334
        opn = "dclo";
1335
        break;
1336
    case OPC_DCLZ:
1337
        gen_op_dclz();
1338
        opn = "dclz";
1339
        break;
1340
#endif
1341
    default:
1342
        MIPS_INVAL("CLx");
1343
        generate_exception(ctx, EXCP_RI);
1344
        return;
1345
    }
1346
    gen_op_store_T0_gpr(rd);
1347
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1348
}
1349

    
1350
/* Traps */
1351
static void gen_trap (DisasContext *ctx, uint32_t opc,
1352
                      int rs, int rt, int16_t imm)
1353
{
1354
    int cond;
1355

    
1356
    cond = 0;
1357
    /* Load needed operands */
1358
    switch (opc) {
1359
    case OPC_TEQ:
1360
    case OPC_TGE:
1361
    case OPC_TGEU:
1362
    case OPC_TLT:
1363
    case OPC_TLTU:
1364
    case OPC_TNE:
1365
        /* Compare two registers */
1366
        if (rs != rt) {
1367
            GEN_LOAD_REG_TN(T0, rs);
1368
            GEN_LOAD_REG_TN(T1, rt);
1369
            cond = 1;
1370
        }
1371
        break;
1372
    case OPC_TEQI:
1373
    case OPC_TGEI:
1374
    case OPC_TGEIU:
1375
    case OPC_TLTI:
1376
    case OPC_TLTIU:
1377
    case OPC_TNEI:
1378
        /* Compare register to immediate */
1379
        if (rs != 0 || imm != 0) {
1380
            GEN_LOAD_REG_TN(T0, rs);
1381
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1382
            cond = 1;
1383
        }
1384
        break;
1385
    }
1386
    if (cond == 0) {
1387
        switch (opc) {
1388
        case OPC_TEQ:   /* rs == rs */
1389
        case OPC_TEQI:  /* r0 == 0  */
1390
        case OPC_TGE:   /* rs >= rs */
1391
        case OPC_TGEI:  /* r0 >= 0  */
1392
        case OPC_TGEU:  /* rs >= rs unsigned */
1393
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1394
            /* Always trap */
1395
            gen_op_set_T0(1);
1396
            break;
1397
        case OPC_TLT:   /* rs < rs           */
1398
        case OPC_TLTI:  /* r0 < 0            */
1399
        case OPC_TLTU:  /* rs < rs unsigned  */
1400
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1401
        case OPC_TNE:   /* rs != rs          */
1402
        case OPC_TNEI:  /* r0 != 0           */
1403
            /* Never trap: treat as NOP */
1404
            return;
1405
        default:
1406
            MIPS_INVAL("TRAP");
1407
            generate_exception(ctx, EXCP_RI);
1408
            return;
1409
        }
1410
    } else {
1411
        switch (opc) {
1412
        case OPC_TEQ:
1413
        case OPC_TEQI:
1414
            gen_op_eq();
1415
            break;
1416
        case OPC_TGE:
1417
        case OPC_TGEI:
1418
            gen_op_ge();
1419
            break;
1420
        case OPC_TGEU:
1421
        case OPC_TGEIU:
1422
            gen_op_geu();
1423
            break;
1424
        case OPC_TLT:
1425
        case OPC_TLTI:
1426
            gen_op_lt();
1427
            break;
1428
        case OPC_TLTU:
1429
        case OPC_TLTIU:
1430
            gen_op_ltu();
1431
            break;
1432
        case OPC_TNE:
1433
        case OPC_TNEI:
1434
            gen_op_ne();
1435
            break;
1436
        default:
1437
            MIPS_INVAL("TRAP");
1438
            generate_exception(ctx, EXCP_RI);
1439
            return;
1440
        }
1441
    }
1442
    save_cpu_state(ctx, 1);
1443
    gen_op_trap();
1444
    ctx->bstate = BS_STOP;
1445
}
1446

    
1447
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1448
{
1449
    TranslationBlock *tb;
1450
    tb = ctx->tb;
1451
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1452
        if (n == 0)
1453
            gen_op_goto_tb0(TBPARAM(tb));
1454
        else
1455
            gen_op_goto_tb1(TBPARAM(tb));
1456
        gen_op_save_pc(dest);
1457
        gen_op_set_T0((long)tb + n);
1458
        gen_op_exit_tb();
1459
    } else {
1460
        gen_op_save_pc(dest);
1461
        gen_op_set_T0(0);
1462
        gen_op_exit_tb();
1463
    }
1464
}
1465

    
1466
/* Branches (before delay slot) */
1467
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1468
                                int rs, int rt, int32_t offset)
1469
{
1470
    target_ulong btarget = -1;
1471
    int blink = 0;
1472
    int bcond = 0;
1473

    
1474
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1475
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1476
            fprintf(logfile,
1477
                    "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1478
                    ctx->pc);
1479
        }
1480
        MIPS_INVAL("branch/jump in bdelay slot");
1481
        generate_exception(ctx, EXCP_RI);
1482
        return;
1483
    }
1484

    
1485
    /* Load needed operands */
1486
    switch (opc) {
1487
    case OPC_BEQ:
1488
    case OPC_BEQL:
1489
    case OPC_BNE:
1490
    case OPC_BNEL:
1491
        /* Compare two registers */
1492
        if (rs != rt) {
1493
            GEN_LOAD_REG_TN(T0, rs);
1494
            GEN_LOAD_REG_TN(T1, rt);
1495
            bcond = 1;
1496
        }
1497
        btarget = ctx->pc + 4 + offset;
1498
        break;
1499
    case OPC_BGEZ:
1500
    case OPC_BGEZAL:
1501
    case OPC_BGEZALL:
1502
    case OPC_BGEZL:
1503
    case OPC_BGTZ:
1504
    case OPC_BGTZL:
1505
    case OPC_BLEZ:
1506
    case OPC_BLEZL:
1507
    case OPC_BLTZ:
1508
    case OPC_BLTZAL:
1509
    case OPC_BLTZALL:
1510
    case OPC_BLTZL:
1511
        /* Compare to zero */
1512
        if (rs != 0) {
1513
            gen_op_load_gpr_T0(rs);
1514
            bcond = 1;
1515
        }
1516
        btarget = ctx->pc + 4 + offset;
1517
        break;
1518
    case OPC_J:
1519
    case OPC_JAL:
1520
        /* Jump to immediate */
1521
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1522
        break;
1523
    case OPC_JR:
1524
    case OPC_JALR:
1525
        /* Jump to register */
1526
        if (offset != 0 && offset != 16) {
1527
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1528
               others are reserved. */
1529
            generate_exception(ctx, EXCP_RI);
1530
            return;
1531
        }
1532
        GEN_LOAD_REG_TN(T2, rs);
1533
        break;
1534
    default:
1535
        MIPS_INVAL("branch/jump");
1536
        generate_exception(ctx, EXCP_RI);
1537
        return;
1538
    }
1539
    if (bcond == 0) {
1540
        /* No condition to be computed */
1541
        switch (opc) {
1542
        case OPC_BEQ:     /* rx == rx        */
1543
        case OPC_BEQL:    /* rx == rx likely */
1544
        case OPC_BGEZ:    /* 0 >= 0          */
1545
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1546
        case OPC_BLEZ:    /* 0 <= 0          */
1547
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1548
            /* Always take */
1549
            ctx->hflags |= MIPS_HFLAG_B;
1550
            MIPS_DEBUG("balways");
1551
            break;
1552
        case OPC_BGEZAL:  /* 0 >= 0          */
1553
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1554
            /* Always take and link */
1555
            blink = 31;
1556
            ctx->hflags |= MIPS_HFLAG_B;
1557
            MIPS_DEBUG("balways and link");
1558
            break;
1559
        case OPC_BNE:     /* rx != rx        */
1560
        case OPC_BGTZ:    /* 0 > 0           */
1561
        case OPC_BLTZ:    /* 0 < 0           */
1562
            /* Treated as NOP */
1563
            MIPS_DEBUG("bnever (NOP)");
1564
            return;
1565
        case OPC_BLTZAL:  /* 0 < 0           */
1566
            gen_op_set_T0(ctx->pc + 8);
1567
            gen_op_store_T0_gpr(31);
1568
            return;
1569
        case OPC_BLTZALL: /* 0 < 0 likely */
1570
            gen_op_set_T0(ctx->pc + 8);
1571
            gen_op_store_T0_gpr(31);
1572
            gen_goto_tb(ctx, 0, ctx->pc + 8);
1573
            return;
1574
        case OPC_BNEL:    /* rx != rx likely */
1575
        case OPC_BGTZL:   /* 0 > 0 likely */
1576
        case OPC_BLTZL:   /* 0 < 0 likely */
1577
            /* Skip the instruction in the delay slot */
1578
            MIPS_DEBUG("bnever and skip");
1579
            gen_goto_tb(ctx, 0, ctx->pc + 8);
1580
            return;
1581
        case OPC_J:
1582
            ctx->hflags |= MIPS_HFLAG_B;
1583
            MIPS_DEBUG("j %08x", btarget);
1584
            break;
1585
        case OPC_JAL:
1586
            blink = 31;
1587
            ctx->hflags |= MIPS_HFLAG_B;
1588
            MIPS_DEBUG("jal %08x", btarget);
1589
            break;
1590
        case OPC_JR:
1591
            ctx->hflags |= MIPS_HFLAG_BR;
1592
            MIPS_DEBUG("jr %s", regnames[rs]);
1593
            break;
1594
        case OPC_JALR:
1595
            blink = rt;
1596
            ctx->hflags |= MIPS_HFLAG_BR;
1597
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1598
            break;
1599
        default:
1600
            MIPS_INVAL("branch/jump");
1601
            generate_exception(ctx, EXCP_RI);
1602
            return;
1603
        }
1604
    } else {
1605
        switch (opc) {
1606
        case OPC_BEQ:
1607
            gen_op_eq();
1608
            MIPS_DEBUG("beq %s, %s, %08x",
1609
                       regnames[rs], regnames[rt], btarget);
1610
            goto not_likely;
1611
        case OPC_BEQL:
1612
            gen_op_eq();
1613
            MIPS_DEBUG("beql %s, %s, %08x",
1614
                       regnames[rs], regnames[rt], btarget);
1615
            goto likely;
1616
        case OPC_BNE:
1617
            gen_op_ne();
1618
            MIPS_DEBUG("bne %s, %s, %08x",
1619
                       regnames[rs], regnames[rt], btarget);
1620
            goto not_likely;
1621
        case OPC_BNEL:
1622
            gen_op_ne();
1623
            MIPS_DEBUG("bnel %s, %s, %08x",
1624
                       regnames[rs], regnames[rt], btarget);
1625
            goto likely;
1626
        case OPC_BGEZ:
1627
            gen_op_gez();
1628
            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1629
            goto not_likely;
1630
        case OPC_BGEZL:
1631
            gen_op_gez();
1632
            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1633
            goto likely;
1634
        case OPC_BGEZAL:
1635
            gen_op_gez();
1636
            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1637
            blink = 31;
1638
            goto not_likely;
1639
        case OPC_BGEZALL:
1640
            gen_op_gez();
1641
            blink = 31;
1642
            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1643
            goto likely;
1644
        case OPC_BGTZ:
1645
            gen_op_gtz();
1646
            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1647
            goto not_likely;
1648
        case OPC_BGTZL:
1649
            gen_op_gtz();
1650
            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1651
            goto likely;
1652
        case OPC_BLEZ:
1653
            gen_op_lez();
1654
            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1655
            goto not_likely;
1656
        case OPC_BLEZL:
1657
            gen_op_lez();
1658
            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1659
            goto likely;
1660
        case OPC_BLTZ:
1661
            gen_op_ltz();
1662
            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1663
            goto not_likely;
1664
        case OPC_BLTZL:
1665
            gen_op_ltz();
1666
            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1667
            goto likely;
1668
        case OPC_BLTZAL:
1669
            gen_op_ltz();
1670
            blink = 31;
1671
            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1672
        not_likely:
1673
            ctx->hflags |= MIPS_HFLAG_BC;
1674
            break;
1675
        case OPC_BLTZALL:
1676
            gen_op_ltz();
1677
            blink = 31;
1678
            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1679
        likely:
1680
            ctx->hflags |= MIPS_HFLAG_BL;
1681
            break;
1682
        default:
1683
            MIPS_INVAL("conditional branch/jump");
1684
            generate_exception(ctx, EXCP_RI);
1685
            return;
1686
        }
1687
        gen_op_set_bcond();
1688
    }
1689
    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1690
               blink, ctx->hflags, btarget);
1691
    ctx->btarget = btarget;
1692
    if (blink > 0) {
1693
        gen_op_set_T0(ctx->pc + 8);
1694
        gen_op_store_T0_gpr(blink);
1695
    }
1696
}
1697

    
1698
/* special3 bitfield operations */
1699
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1700
                       int rs, int lsb, int msb)
1701
{
1702
    GEN_LOAD_REG_TN(T1, rs);
1703
    switch (opc) {
1704
    case OPC_EXT:
1705
        if (lsb + msb > 31)
1706
            goto fail;
1707
        gen_op_ext(lsb, msb + 1);
1708
        break;
1709
    case OPC_DEXTM:
1710
        if (lsb + msb > 63)
1711
            goto fail;
1712
        gen_op_ext(lsb, msb + 1 + 32);
1713
        break;
1714
    case OPC_DEXTU:
1715
        if (lsb + msb > 63)
1716
            goto fail;
1717
        gen_op_ext(lsb + 32, msb + 1);
1718
        break;
1719
    case OPC_DEXT:
1720
        gen_op_ext(lsb, msb + 1);
1721
        break;
1722
    case OPC_INS:
1723
        if (lsb > msb)
1724
            goto fail;
1725
        GEN_LOAD_REG_TN(T2, rt);
1726
        gen_op_ins(lsb, msb - lsb + 1);
1727
        break;
1728
    case OPC_DINSM:
1729
        if (lsb > msb)
1730
            goto fail;
1731
        GEN_LOAD_REG_TN(T2, rt);
1732
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1733
        break;
1734
    case OPC_DINSU:
1735
        if (lsb > msb)
1736
            goto fail;
1737
        GEN_LOAD_REG_TN(T2, rt);
1738
        gen_op_ins(lsb + 32, msb - lsb + 1);
1739
        break;
1740
    case OPC_DINS:
1741
        if (lsb > msb)
1742
            goto fail;
1743
        GEN_LOAD_REG_TN(T2, rt);
1744
        gen_op_ins(lsb, msb - lsb + 1);
1745
        break;
1746
    default:
1747
fail:
1748
        MIPS_INVAL("bitops");
1749
        generate_exception(ctx, EXCP_RI);
1750
        return;
1751
    }
1752
    GEN_STORE_TN_REG(rt, T0);
1753
}
1754

    
1755
/* CP0 (MMU and control) */
1756
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1757
{
1758
    const char *rn = "invalid";
1759

    
1760
    switch (reg) {
1761
    case 0:
1762
        switch (sel) {
1763
        case 0:
1764
           gen_op_mfc0_index();
1765
            rn = "Index";
1766
            break;
1767
        case 1:
1768
//         gen_op_mfc0_mvpcontrol(); /* MT ASE */
1769
            rn = "MVPControl";
1770
//         break;
1771
        case 2:
1772
//         gen_op_mfc0_mvpconf0(); /* MT ASE */
1773
            rn = "MVPConf0";
1774
//         break;
1775
        case 3:
1776
//         gen_op_mfc0_mvpconf1(); /* MT ASE */
1777
            rn = "MVPConf1";
1778
//         break;
1779
        default:
1780
            goto die;
1781
        }
1782
        break;
1783
    case 1:
1784
        switch (sel) {
1785
        case 0:
1786
            gen_op_mfc0_random();
1787
            rn = "Random";
1788
           break;
1789
        case 1:
1790
//         gen_op_mfc0_vpecontrol(); /* MT ASE */
1791
            rn = "VPEControl";
1792
//         break;
1793
        case 2:
1794
//         gen_op_mfc0_vpeconf0(); /* MT ASE */
1795
            rn = "VPEConf0";
1796
//         break;
1797
        case 3:
1798
//         gen_op_mfc0_vpeconf1(); /* MT ASE */
1799
            rn = "VPEConf1";
1800
//         break;
1801
        case 4:
1802
//         gen_op_mfc0_YQMask(); /* MT ASE */
1803
            rn = "YQMask";
1804
//         break;
1805
        case 5:
1806
//         gen_op_mfc0_vpeschedule(); /* MT ASE */
1807
            rn = "VPESchedule";
1808
//         break;
1809
        case 6:
1810
//         gen_op_mfc0_vpeschefback(); /* MT ASE */
1811
            rn = "VPEScheFBack";
1812
//         break;
1813
        case 7:
1814
//         gen_op_mfc0_vpeopt(); /* MT ASE */
1815
            rn = "VPEOpt";
1816
//         break;
1817
        default:
1818
            goto die;
1819
        }
1820
        break;
1821
    case 2:
1822
        switch (sel) {
1823
        case 0:
1824
           gen_op_mfc0_entrylo0();
1825
           rn = "EntryLo0";
1826
           break;
1827
        case 1:
1828
//         gen_op_mfc0_tcstatus(); /* MT ASE */
1829
           rn = "TCStatus";
1830
//         break;
1831
        case 2:
1832
//         gen_op_mfc0_tcbind(); /* MT ASE */
1833
           rn = "TCBind";
1834
//         break;
1835
        case 3:
1836
//         gen_op_mfc0_tcrestart(); /* MT ASE */
1837
           rn = "TCRestart";
1838
//         break;
1839
        case 4:
1840
//         gen_op_mfc0_tchalt(); /* MT ASE */
1841
           rn = "TCHalt";
1842
//         break;
1843
        case 5:
1844
//         gen_op_mfc0_tccontext(); /* MT ASE */
1845
           rn = "TCContext";
1846
//         break;
1847
        case 6:
1848
//         gen_op_mfc0_tcschedule(); /* MT ASE */
1849
           rn = "TCSchedule";
1850
//         break;
1851
        case 7:
1852
//         gen_op_mfc0_tcschefback(); /* MT ASE */
1853
           rn = "TCScheFBack";
1854
//         break;
1855
        default:
1856
            goto die;
1857
        }
1858
        break;
1859
    case 3:
1860
        switch (sel) {
1861
        case 0:
1862
           gen_op_mfc0_entrylo1();
1863
           rn = "EntryLo1";
1864
           break;
1865
        default:
1866
            goto die;
1867
        }
1868
        break;
1869
    case 4:
1870
        switch (sel) {
1871
        case 0:
1872
           gen_op_mfc0_context();
1873
           rn = "Context";
1874
           break;
1875
        case 1:
1876
//         gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1877
           rn = "ContextConfig";
1878
//         break;
1879
        default:
1880
            goto die;
1881
        }
1882
        break;
1883
    case 5:
1884
        switch (sel) {
1885
        case 0:
1886
           gen_op_mfc0_pagemask();
1887
           rn = "PageMask";
1888
           break;
1889
        case 1:
1890
           gen_op_mfc0_pagegrain();
1891
           rn = "PageGrain";
1892
           break;
1893
        default:
1894
            goto die;
1895
        }
1896
        break;
1897
    case 6:
1898
        switch (sel) {
1899
        case 0:
1900
           gen_op_mfc0_wired();
1901
           rn = "Wired";
1902
           break;
1903
        case 1:
1904
//         gen_op_mfc0_srsconf0(); /* shadow registers */
1905
           rn = "SRSConf0";
1906
//         break;
1907
        case 2:
1908
//         gen_op_mfc0_srsconf1(); /* shadow registers */
1909
           rn = "SRSConf1";
1910
//         break;
1911
        case 3:
1912
//         gen_op_mfc0_srsconf2(); /* shadow registers */
1913
           rn = "SRSConf2";
1914
//         break;
1915
        case 4:
1916
//         gen_op_mfc0_srsconf3(); /* shadow registers */
1917
           rn = "SRSConf3";
1918
//         break;
1919
        case 5:
1920
//         gen_op_mfc0_srsconf4(); /* shadow registers */
1921
           rn = "SRSConf4";
1922
//         break;
1923
        default:
1924
            goto die;
1925
        }
1926
        break;
1927
    case 7:
1928
        switch (sel) {
1929
        case 0:
1930
           gen_op_mfc0_hwrena();
1931
           rn = "HWREna";
1932
           break;
1933
        default:
1934
            goto die;
1935
        }
1936
        break;
1937
    case 8:
1938
        switch (sel) {
1939
        case 0:
1940
           gen_op_mfc0_badvaddr();
1941
           rn = "BadVaddr";
1942
           break;
1943
        default:
1944
            goto die;
1945
       }
1946
        break;
1947
    case 9:
1948
        switch (sel) {
1949
        case 0:
1950
           gen_op_mfc0_count();
1951
           rn = "Count";
1952
           break;
1953
       /* 6,7 are implementation dependent */
1954
        default:
1955
            goto die;
1956
       }
1957
        break;
1958
    case 10:
1959
        switch (sel) {
1960
        case 0:
1961
           gen_op_mfc0_entryhi();
1962
           rn = "EntryHi";
1963
           break;
1964
        default:
1965
            goto die;
1966
        }
1967
        break;
1968
    case 11:
1969
        switch (sel) {
1970
        case 0:
1971
           gen_op_mfc0_compare();
1972
           rn = "Compare";
1973
           break;
1974
       /* 6,7 are implementation dependent */
1975
        default:
1976
            goto die;
1977
       }
1978
        break;
1979
    case 12:
1980
        switch (sel) {
1981
        case 0:
1982
           gen_op_mfc0_status();
1983
           rn = "Status";
1984
           break;
1985
        case 1:
1986
           gen_op_mfc0_intctl();
1987
           rn = "IntCtl";
1988
           break;
1989
        case 2:
1990
           gen_op_mfc0_srsctl();
1991
           rn = "SRSCtl";
1992
           break;
1993
        case 3:
1994
//         gen_op_mfc0_srsmap(); /* shadow registers */
1995
           rn = "SRSMap";
1996
//         break;
1997
        default:
1998
            goto die;
1999
       }
2000
        break;
2001
    case 13:
2002
        switch (sel) {
2003
        case 0:
2004
           gen_op_mfc0_cause();
2005
           rn = "Cause";
2006
           break;
2007
        default:
2008
            goto die;
2009
       }
2010
        break;
2011
    case 14:
2012
        switch (sel) {
2013
        case 0:
2014
           gen_op_mfc0_epc();
2015
           rn = "EPC";
2016
           break;
2017
        default:
2018
            goto die;
2019
        }
2020
        break;
2021
    case 15:
2022
        switch (sel) {
2023
        case 0:
2024
           gen_op_mfc0_prid();
2025
           rn = "PRid";
2026
           break;
2027
        case 1:
2028
           gen_op_mfc0_ebase();
2029
           rn = "EBase";
2030
           break;
2031
        default:
2032
            goto die;
2033
       }
2034
        break;
2035
    case 16:
2036
        switch (sel) {
2037
        case 0:
2038
            gen_op_mfc0_config0();
2039
            rn = "Config";
2040
            break;
2041
        case 1:
2042
            gen_op_mfc0_config1();
2043
            rn = "Config1";
2044
            break;
2045
        case 2:
2046
            gen_op_mfc0_config2();
2047
            rn = "Config2";
2048
            break;
2049
        case 3:
2050
            gen_op_mfc0_config3();
2051
            rn = "Config3";
2052
            break;
2053
        /* 4,5 are reserved */
2054
        /* 6,7 are implementation dependent */
2055
        case 6:
2056
            gen_op_mfc0_config6();
2057
            rn = "Config6";
2058
            break;
2059
        case 7:
2060
            gen_op_mfc0_config7();
2061
            rn = "Config7";
2062
            break;
2063
        default:
2064
            goto die;
2065
        }
2066
        break;
2067
    case 17:
2068
        switch (sel) {
2069
        case 0:
2070
           gen_op_mfc0_lladdr();
2071
           rn = "LLAddr";
2072
           break;
2073
        default:
2074
            goto die;
2075
        }
2076
        break;
2077
    case 18:
2078
        switch (sel) {
2079
        case 0:
2080
           gen_op_mfc0_watchlo0();
2081
           rn = "WatchLo";
2082
           break;
2083
        case 1:
2084
//         gen_op_mfc0_watchlo1();
2085
           rn = "WatchLo1";
2086
//         break;
2087
        case 2:
2088
//         gen_op_mfc0_watchlo2();
2089
           rn = "WatchLo2";
2090
//         break;
2091
        case 3:
2092
//         gen_op_mfc0_watchlo3();
2093
           rn = "WatchLo3";
2094
//         break;
2095
        case 4:
2096
//         gen_op_mfc0_watchlo4();
2097
           rn = "WatchLo4";
2098
//         break;
2099
        case 5:
2100
//         gen_op_mfc0_watchlo5();
2101
           rn = "WatchLo5";
2102
//         break;
2103
        case 6:
2104
//         gen_op_mfc0_watchlo6();
2105
           rn = "WatchLo6";
2106
//         break;
2107
        case 7:
2108
//         gen_op_mfc0_watchlo7();
2109
           rn = "WatchLo7";
2110
//         break;
2111
        default:
2112
            goto die;
2113
        }
2114
        break;
2115
    case 19:
2116
        switch (sel) {
2117
        case 0:
2118
           gen_op_mfc0_watchhi0();
2119
           rn = "WatchHi";
2120
           break;
2121
        case 1:
2122
//         gen_op_mfc0_watchhi1();
2123
           rn = "WatchHi1";
2124
//         break;
2125
        case 2:
2126
//         gen_op_mfc0_watchhi2();
2127
           rn = "WatchHi2";
2128
//         break;
2129
        case 3:
2130
//         gen_op_mfc0_watchhi3();
2131
           rn = "WatchHi3";
2132
//         break;
2133
        case 4:
2134
//         gen_op_mfc0_watchhi4();
2135
           rn = "WatchHi4";
2136
//         break;
2137
        case 5:
2138
//         gen_op_mfc0_watchhi5();
2139
           rn = "WatchHi5";
2140
//         break;
2141
        case 6:
2142
//         gen_op_mfc0_watchhi6();
2143
           rn = "WatchHi6";
2144
//         break;
2145
        case 7:
2146
//         gen_op_mfc0_watchhi7();
2147
           rn = "WatchHi7";
2148
//         break;
2149
        default:
2150
            goto die;
2151
        }
2152
        break;
2153
    case 20:
2154
        switch (sel) {
2155
        case 0:
2156
           /* 64 bit MMU only */
2157
           gen_op_mfc0_xcontext();
2158
           rn = "XContext";
2159
           break;
2160
        default:
2161
            goto die;
2162
        }
2163
        break;
2164
    case 21:
2165
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2166
        switch (sel) {
2167
        case 0:
2168
           gen_op_mfc0_framemask();
2169
           rn = "Framemask";
2170
           break;
2171
        default:
2172
            goto die;
2173
        }
2174
        break;
2175
    case 22:
2176
       /* ignored */
2177
       rn = "'Diagnostic"; /* implementation dependent */
2178
       break;
2179
    case 23:
2180
        switch (sel) {
2181
        case 0:
2182
           gen_op_mfc0_debug(); /* EJTAG support */
2183
           rn = "Debug";
2184
           break;
2185
        case 1:
2186
//         gen_op_mfc0_tracecontrol(); /* PDtrace support */
2187
           rn = "TraceControl";
2188
//         break;
2189
        case 2:
2190
//         gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2191
           rn = "TraceControl2";
2192
//         break;
2193
        case 3:
2194
//         gen_op_mfc0_usertracedata(); /* PDtrace support */
2195
           rn = "UserTraceData";
2196
//         break;
2197
        case 4:
2198
//         gen_op_mfc0_debug(); /* PDtrace support */
2199
           rn = "TraceBPC";
2200
//         break;
2201
        default:
2202
            goto die;
2203
        }
2204
        break;
2205
    case 24:
2206
        switch (sel) {
2207
        case 0:
2208
           gen_op_mfc0_depc(); /* EJTAG support */
2209
           rn = "DEPC";
2210
           break;
2211
        default:
2212
            goto die;
2213
        }
2214
        break;
2215
    case 25:
2216
        switch (sel) {
2217
        case 0:
2218
           gen_op_mfc0_performance0();
2219
           rn = "Performance0";
2220
            break;
2221
        case 1:
2222
//         gen_op_mfc0_performance1();
2223
           rn = "Performance1";
2224
//         break;
2225
        case 2:
2226
//         gen_op_mfc0_performance2();
2227
           rn = "Performance2";
2228
//         break;
2229
        case 3:
2230
//         gen_op_mfc0_performance3();
2231
           rn = "Performance3";
2232
//         break;
2233
        case 4:
2234
//         gen_op_mfc0_performance4();
2235
           rn = "Performance4";
2236
//         break;
2237
        case 5:
2238
//         gen_op_mfc0_performance5();
2239
           rn = "Performance5";
2240
//         break;
2241
        case 6:
2242
//         gen_op_mfc0_performance6();
2243
           rn = "Performance6";
2244
//         break;
2245
        case 7:
2246
//         gen_op_mfc0_performance7();
2247
           rn = "Performance7";
2248
//         break;
2249
        default:
2250
            goto die;
2251
        }
2252
        break;
2253
    case 26:
2254
       rn = "ECC";
2255
       break;
2256
    case 27:
2257
        switch (sel) {
2258
        /* ignored */
2259
        case 0 ... 3:
2260
           rn = "CacheErr";
2261
           break;
2262
        default:
2263
            goto die;
2264
        }
2265
        break;
2266
    case 28:
2267
        switch (sel) {
2268
        case 0:
2269
        case 2:
2270
        case 4:
2271
        case 6:
2272
            gen_op_mfc0_taglo();
2273
            rn = "TagLo";
2274
            break;
2275
        case 1:
2276
        case 3:
2277
        case 5:
2278
        case 7:
2279
            gen_op_mfc0_datalo();
2280
            rn = "DataLo";
2281
            break;
2282
        default:
2283
            goto die;
2284
        }
2285
        break;
2286
    case 29:
2287
        switch (sel) {
2288
        case 0:
2289
        case 2:
2290
        case 4:
2291
        case 6:
2292
            gen_op_mfc0_taghi();
2293
            rn = "TagHi";
2294
            break;
2295
        case 1:
2296
        case 3:
2297
        case 5:
2298
        case 7:
2299
            gen_op_mfc0_datahi();
2300
            rn = "DataHi";
2301
            break;
2302
        default:
2303
            goto die;
2304
        }
2305
        break;
2306
    case 30:
2307
        switch (sel) {
2308
        case 0:
2309
           gen_op_mfc0_errorepc();
2310
           rn = "ErrorEPC";
2311
           break;
2312
        default:
2313
            goto die;
2314
        }
2315
        break;
2316
    case 31:
2317
        switch (sel) {
2318
        case 0:
2319
           gen_op_mfc0_desave(); /* EJTAG support */
2320
           rn = "DESAVE";
2321
           break;
2322
        default:
2323
            goto die;
2324
        }
2325
        break;
2326
    default:
2327
       goto die;
2328
    }
2329
#if defined MIPS_DEBUG_DISAS
2330
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2331
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2332
                rn, reg, sel);
2333
    }
2334
#endif
2335
    return;
2336

    
2337
die:
2338
#if defined MIPS_DEBUG_DISAS
2339
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2340
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2341
                rn, reg, sel);
2342
    }
2343
#endif
2344
    generate_exception(ctx, EXCP_RI);
2345
}
2346

    
2347
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2348
{
2349
    const char *rn = "invalid";
2350

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

    
2939
die:
2940
#if defined MIPS_DEBUG_DISAS
2941
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2942
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2943
                rn, reg, sel);
2944
    }
2945
#endif
2946
    generate_exception(ctx, EXCP_RI);
2947
}
2948

    
2949
#ifdef TARGET_MIPS64
2950
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2951
{
2952
    const char *rn = "invalid";
2953

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

    
3522
die:
3523
#if defined MIPS_DEBUG_DISAS
3524
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3525
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3526
                rn, reg, sel);
3527
    }
3528
#endif
3529
    generate_exception(ctx, EXCP_RI);
3530
}
3531

    
3532
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3533
{
3534
    const char *rn = "invalid";
3535

    
3536
    switch (reg) {
3537
    case 0:
3538
        switch (sel) {
3539
        case 0:
3540
            gen_op_mtc0_index();
3541
            rn = "Index";
3542
            break;
3543
        case 1:
3544
//         gen_op_dmtc0_mvpcontrol(); /* MT ASE */
3545
            rn = "MVPControl";
3546
//         break;
3547
        case 2:
3548
//         gen_op_dmtc0_mvpconf0(); /* MT ASE */
3549
            rn = "MVPConf0";
3550
//         break;
3551
        case 3:
3552
//         gen_op_dmtc0_mvpconf1(); /* MT ASE */
3553
            rn = "MVPConf1";
3554
//         break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 1:
3560
        switch (sel) {
3561
        case 0:
3562
           /* ignored */
3563
            rn = "Random";
3564
           break;
3565
        case 1:
3566
//         gen_op_dmtc0_vpecontrol(); /* MT ASE */
3567
            rn = "VPEControl";
3568
//         break;
3569
        case 2:
3570
//         gen_op_dmtc0_vpeconf0(); /* MT ASE */
3571
            rn = "VPEConf0";
3572
//         break;
3573
        case 3:
3574
//         gen_op_dmtc0_vpeconf1(); /* MT ASE */
3575
            rn = "VPEConf1";
3576
//         break;
3577
        case 4:
3578
//         gen_op_dmtc0_YQMask(); /* MT ASE */
3579
            rn = "YQMask";
3580
//         break;
3581
        case 5:
3582
//         gen_op_dmtc0_vpeschedule(); /* MT ASE */
3583
            rn = "VPESchedule";
3584
//         break;
3585
        case 6:
3586
//         gen_op_dmtc0_vpeschefback(); /* MT ASE */
3587
            rn = "VPEScheFBack";
3588
//         break;
3589
        case 7:
3590
//         gen_op_dmtc0_vpeopt(); /* MT ASE */
3591
            rn = "VPEOpt";
3592
//         break;
3593
        default:
3594
            goto die;
3595
        }
3596
        break;
3597
    case 2:
3598
        switch (sel) {
3599
        case 0:
3600
           gen_op_dmtc0_entrylo0();
3601
           rn = "EntryLo0";
3602
           break;
3603
        case 1:
3604
//         gen_op_dmtc0_tcstatus(); /* MT ASE */
3605
           rn = "TCStatus";
3606
//         break;
3607
        case 2:
3608
//         gen_op_dmtc0_tcbind(); /* MT ASE */
3609
           rn = "TCBind";
3610
//         break;
3611
        case 3:
3612
//         gen_op_dmtc0_tcrestart(); /* MT ASE */
3613
           rn = "TCRestart";
3614
//         break;
3615
        case 4:
3616
//         gen_op_dmtc0_tchalt(); /* MT ASE */
3617
           rn = "TCHalt";
3618
//         break;
3619
        case 5:
3620
//         gen_op_dmtc0_tccontext(); /* MT ASE */
3621
           rn = "TCContext";
3622
//         break;
3623
        case 6:
3624
//         gen_op_dmtc0_tcschedule(); /* MT ASE */
3625
           rn = "TCSchedule";
3626
//         break;
3627
        case 7:
3628
//         gen_op_dmtc0_tcschefback(); /* MT ASE */
3629
           rn = "TCScheFBack";
3630
//         break;
3631
        default:
3632
            goto die;
3633
        }
3634
        break;
3635
    case 3:
3636
        switch (sel) {
3637
        case 0:
3638
           gen_op_dmtc0_entrylo1();
3639
           rn = "EntryLo1";
3640
           break;
3641
        default:
3642
            goto die;
3643
        }
3644
        break;
3645
    case 4:
3646
        switch (sel) {
3647
        case 0:
3648
           gen_op_dmtc0_context();
3649
           rn = "Context";
3650
           break;
3651
        case 1:
3652
//         gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3653
           rn = "ContextConfig";
3654
//         break;
3655
        default:
3656
            goto die;
3657
        }
3658
        break;
3659
    case 5:
3660
        switch (sel) {
3661
        case 0:
3662
           gen_op_mtc0_pagemask();
3663
           rn = "PageMask";
3664
           break;
3665
        case 1:
3666
           gen_op_mtc0_pagegrain();
3667
           rn = "PageGrain";
3668
           break;
3669
        default:
3670
            goto die;
3671
        }
3672
        break;
3673
    case 6:
3674
        switch (sel) {
3675
        case 0:
3676
           gen_op_mtc0_wired();
3677
           rn = "Wired";
3678
           break;
3679
        case 1:
3680
//         gen_op_dmtc0_srsconf0(); /* shadow registers */
3681
           rn = "SRSConf0";
3682
//         break;
3683
        case 2:
3684
//         gen_op_dmtc0_srsconf1(); /* shadow registers */
3685
           rn = "SRSConf1";
3686
//         break;
3687
        case 3:
3688
//         gen_op_dmtc0_srsconf2(); /* shadow registers */
3689
           rn = "SRSConf2";
3690
//         break;
3691
        case 4:
3692
//         gen_op_dmtc0_srsconf3(); /* shadow registers */
3693
           rn = "SRSConf3";
3694
//         break;
3695
        case 5:
3696
//         gen_op_dmtc0_srsconf4(); /* shadow registers */
3697
           rn = "SRSConf4";
3698
//         break;
3699
        default:
3700
            goto die;
3701
        }
3702
        break;
3703
    case 7:
3704
        switch (sel) {
3705
        case 0:
3706
           gen_op_mtc0_hwrena();
3707
           rn = "HWREna";
3708
           break;
3709
        default:
3710
            goto die;
3711
        }
3712
        break;
3713
    case 8:
3714
        /* ignored */
3715
        rn = "BadVaddr";
3716
        break;
3717
    case 9:
3718
        switch (sel) {
3719
        case 0:
3720
           gen_op_mtc0_count();
3721
           rn = "Count";
3722
           break;
3723
        /* 6,7 are implementation dependent */
3724
        default:
3725
            goto die;
3726
        }
3727
        /* Stop translation as we may have switched the execution mode */
3728
        ctx->bstate = BS_STOP;
3729
        break;
3730
    case 10:
3731
        switch (sel) {
3732
        case 0:
3733
           gen_op_mtc0_entryhi();
3734
           rn = "EntryHi";
3735
           break;
3736
        default:
3737
            goto die;
3738
        }
3739
        break;
3740
    case 11:
3741
        switch (sel) {
3742
        case 0:
3743
           gen_op_mtc0_compare();
3744
           rn = "Compare";
3745
           break;
3746
        /* 6,7 are implementation dependent */
3747
        default:
3748
            goto die;
3749
        }
3750
        /* Stop translation as we may have switched the execution mode */
3751
        ctx->bstate = BS_STOP;
3752
        break;
3753
    case 12:
3754
        switch (sel) {
3755
        case 0:
3756
           gen_op_mtc0_status();
3757
           rn = "Status";
3758
           break;
3759
        case 1:
3760
           gen_op_mtc0_intctl();
3761
           rn = "IntCtl";
3762
           break;
3763
        case 2:
3764
           gen_op_mtc0_srsctl();
3765
           rn = "SRSCtl";
3766
           break;
3767
        case 3:
3768
         gen_op_mtc0_srsmap(); /* shadow registers */
3769
           rn = "SRSMap";
3770
         break;
3771
         default:
3772
            goto die;
3773
        }
3774
        /* Stop translation as we may have switched the execution mode */
3775
        ctx->bstate = BS_STOP;
3776
        break;
3777
    case 13:
3778
        switch (sel) {
3779
        case 0:
3780
           gen_op_mtc0_cause();
3781
           rn = "Cause";
3782
           break;
3783
        default:
3784
            goto die;
3785
        }
3786
        /* Stop translation as we may have switched the execution mode */
3787
        ctx->bstate = BS_STOP;
3788
        break;
3789
    case 14:
3790
        switch (sel) {
3791
        case 0:
3792
           gen_op_dmtc0_epc();
3793
           rn = "EPC";
3794
           break;
3795
        default:
3796
            goto die;
3797
        }
3798
        break;
3799
    case 15:
3800
        switch (sel) {
3801
        case 0:
3802
           /* ignored */
3803
           rn = "PRid";
3804
           break;
3805
        case 1:
3806
           gen_op_mtc0_ebase();
3807
           rn = "EBase";
3808
           break;
3809
        default:
3810
            goto die;
3811
        }
3812
        break;
3813
    case 16:
3814
        switch (sel) {
3815
        case 0:
3816
            gen_op_mtc0_config0();
3817
            rn = "Config";
3818
            break;
3819
        case 1:
3820
           /* ignored */
3821
            rn = "Config1";
3822
            break;
3823
        case 2:
3824
            gen_op_mtc0_config2();
3825
            rn = "Config2";
3826
            break;
3827
        case 3:
3828
           /* ignored */
3829
            rn = "Config3";
3830
            break;
3831
        /* 6,7 are implementation dependent */
3832
        default:
3833
            rn = "Invalid config selector";
3834
            goto die;
3835
        }
3836
        /* Stop translation as we may have switched the execution mode */
3837
        ctx->bstate = BS_STOP;
3838
        break;
3839
    case 17:
3840
        switch (sel) {
3841
        case 0:
3842
           /* ignored */
3843
           rn = "LLAddr";
3844
           break;
3845
        default:
3846
            goto die;
3847
        }
3848
        break;
3849
    case 18:
3850
        switch (sel) {
3851
        case 0:
3852
           gen_op_dmtc0_watchlo0();
3853
           rn = "WatchLo";
3854
           break;
3855
        case 1:
3856
//         gen_op_dmtc0_watchlo1();
3857
           rn = "WatchLo1";
3858
//         break;
3859
        case 2:
3860
//         gen_op_dmtc0_watchlo2();
3861
           rn = "WatchLo2";
3862
//         break;
3863
        case 3:
3864
//         gen_op_dmtc0_watchlo3();
3865
           rn = "WatchLo3";
3866
//         break;
3867
        case 4:
3868
//         gen_op_dmtc0_watchlo4();
3869
           rn = "WatchLo4";
3870
//         break;
3871
        case 5:
3872
//         gen_op_dmtc0_watchlo5();
3873
           rn = "WatchLo5";
3874
//         break;
3875
        case 6:
3876
//         gen_op_dmtc0_watchlo6();
3877
           rn = "WatchLo6";
3878
//         break;
3879
        case 7:
3880
//         gen_op_dmtc0_watchlo7();
3881
           rn = "WatchLo7";
3882
//         break;
3883
        default:
3884
            goto die;
3885
        }
3886
        break;
3887
    case 19:
3888
        switch (sel) {
3889
        case 0:
3890
           gen_op_mtc0_watchhi0();
3891
           rn = "WatchHi";
3892
           break;
3893
        case 1:
3894
//         gen_op_dmtc0_watchhi1();
3895
           rn = "WatchHi1";
3896
//         break;
3897
        case 2:
3898
//         gen_op_dmtc0_watchhi2();
3899
           rn = "WatchHi2";
3900
//         break;
3901
        case 3:
3902
//         gen_op_dmtc0_watchhi3();
3903
           rn = "WatchHi3";
3904
//         break;
3905
        case 4:
3906
//         gen_op_dmtc0_watchhi4();
3907
           rn = "WatchHi4";
3908
//         break;
3909
        case 5:
3910
//         gen_op_dmtc0_watchhi5();
3911
           rn = "WatchHi5";
3912
//         break;
3913
        case 6:
3914
//         gen_op_dmtc0_watchhi6();
3915
           rn = "WatchHi6";
3916
//         break;
3917
        case 7:
3918
//         gen_op_dmtc0_watchhi7();
3919
           rn = "WatchHi7";
3920
//         break;
3921
        default:
3922
            goto die;
3923
        }
3924
        break;
3925
    case 20:
3926
        switch (sel) {
3927
        case 0:
3928
           /* 64 bit MMU only */
3929
           gen_op_dmtc0_xcontext();
3930
           rn = "XContext";
3931
           break;
3932
        default:
3933
            goto die;
3934
        }
3935
        break;
3936
    case 21:
3937
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3938
        switch (sel) {
3939
        case 0:
3940
           gen_op_mtc0_framemask();
3941
           rn = "Framemask";
3942
           break;
3943
        default:
3944
            goto die;
3945
        }
3946
        break;
3947
    case 22:
3948
        /* ignored */
3949
        rn = "Diagnostic"; /* implementation dependent */
3950
        break;
3951
    case 23:
3952
        switch (sel) {
3953
        case 0:
3954
           gen_op_mtc0_debug(); /* EJTAG support */
3955
           rn = "Debug";
3956
           break;
3957
        case 1:
3958
//         gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3959
           rn = "TraceControl";
3960
//         break;
3961
        case 2:
3962
//         gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3963
           rn = "TraceControl2";
3964
//         break;
3965
        case 3:
3966
//         gen_op_dmtc0_usertracedata(); /* PDtrace support */
3967
           rn = "UserTraceData";
3968
//         break;
3969
        case 4:
3970
//         gen_op_dmtc0_debug(); /* PDtrace support */
3971
           rn = "TraceBPC";
3972
//         break;
3973
        default:
3974
            goto die;
3975
        }
3976
       /* Stop translation as we may have switched the execution mode */
3977
       ctx->bstate = BS_STOP;
3978
        break;
3979
    case 24:
3980
        switch (sel) {
3981
        case 0:
3982
           gen_op_dmtc0_depc(); /* EJTAG support */
3983
           rn = "DEPC";
3984
           break;
3985
        default:
3986
            goto die;
3987
        }
3988
        break;
3989
    case 25:
3990
        switch (sel) {
3991
        case 0:
3992
           gen_op_mtc0_performance0();
3993
           rn = "Performance0";
3994
           break;
3995
        case 1:
3996
//         gen_op_dmtc0_performance1();
3997
           rn = "Performance1";
3998
//         break;
3999
        case 2:
4000
//         gen_op_dmtc0_performance2();
4001
           rn = "Performance2";
4002
//         break;
4003
        case 3:
4004
//         gen_op_dmtc0_performance3();
4005
           rn = "Performance3";
4006
//         break;
4007
        case 4:
4008
//         gen_op_dmtc0_performance4();
4009
           rn = "Performance4";
4010
//         break;
4011
        case 5:
4012
//         gen_op_dmtc0_performance5();
4013
           rn = "Performance5";
4014
//         break;
4015
        case 6:
4016
//         gen_op_dmtc0_performance6();
4017
           rn = "Performance6";
4018
//         break;
4019
        case 7:
4020
//         gen_op_dmtc0_performance7();
4021
           rn = "Performance7";
4022
//         break;
4023
        default:
4024
            goto die;
4025
        }
4026
        break;
4027
    case 26:
4028
        /* ignored */
4029
        rn = "ECC";
4030
        break;
4031
    case 27:
4032
        switch (sel) {
4033
        case 0 ... 3:
4034
           /* ignored */
4035
           rn = "CacheErr";
4036
           break;
4037
        default:
4038
            goto die;
4039
        }
4040
        break;
4041
    case 28:
4042
        switch (sel) {
4043
        case 0:
4044
        case 2:
4045
        case 4:
4046
        case 6:
4047
            gen_op_mtc0_taglo();
4048
            rn = "TagLo";
4049
            break;
4050
        case 1:
4051
        case 3:
4052
        case 5:
4053
        case 7:
4054
           gen_op_mtc0_datalo();
4055
            rn = "DataLo";
4056
            break;
4057
        default:
4058
            goto die;
4059
        }
4060
        break;
4061
    case 29:
4062
        switch (sel) {
4063
        case 0:
4064
        case 2:
4065
        case 4:
4066
        case 6:
4067
            gen_op_mtc0_taghi();
4068
            rn = "TagHi";
4069
            break;
4070
        case 1:
4071
        case 3:
4072
        case 5:
4073
        case 7:
4074
           gen_op_mtc0_datahi();
4075
            rn = "DataHi";
4076
            break;
4077
        default:
4078
            rn = "invalid sel";
4079
            goto die;
4080
        }
4081
        break;
4082
    case 30:
4083
        switch (sel) {
4084
        case 0:
4085
           gen_op_dmtc0_errorepc();
4086
           rn = "ErrorEPC";
4087
           break;
4088
        default:
4089
            goto die;
4090
        }
4091
        break;
4092
    case 31:
4093
        switch (sel) {
4094
        case 0:
4095
           gen_op_mtc0_desave(); /* EJTAG support */
4096
           rn = "DESAVE";
4097
           break;
4098
        default:
4099
            goto die;
4100
        }
4101
        /* Stop translation as we may have switched the execution mode */
4102
        ctx->bstate = BS_STOP;
4103
        break;
4104
    default:
4105
        goto die;
4106
    }
4107
#if defined MIPS_DEBUG_DISAS
4108
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4109
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4110
                rn, reg, sel);
4111
    }
4112
#endif
4113
    return;
4114

    
4115
die:
4116
#if defined MIPS_DEBUG_DISAS
4117
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4118
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4119
                rn, reg, sel);
4120
    }
4121
#endif
4122
    generate_exception(ctx, EXCP_RI);
4123
}
4124
#endif /* TARGET_MIPS64 */
4125

    
4126
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4127
{
4128
    const char *opn = "unk";
4129

    
4130
    switch (opc) {
4131
    case OPC_MFC0:
4132
        if (rt == 0) {
4133
            /* Treat as NOP */
4134
            return;
4135
        }
4136
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4137
        gen_op_store_T0_gpr(rt);
4138
        opn = "mfc0";
4139
        break;
4140
    case OPC_MTC0:
4141
        GEN_LOAD_REG_TN(T0, rt);
4142
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4143
        opn = "mtc0";
4144
        break;
4145
#ifdef TARGET_MIPS64
4146
    case OPC_DMFC0:
4147
        if (rt == 0) {
4148
            /* Treat as NOP */
4149
            return;
4150
        }
4151
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4152
        gen_op_store_T0_gpr(rt);
4153
        opn = "dmfc0";
4154
        break;
4155
    case OPC_DMTC0:
4156
        GEN_LOAD_REG_TN(T0, rt);
4157
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4158
        opn = "dmtc0";
4159
        break;
4160
#endif
4161
#if defined(MIPS_USES_R4K_TLB)
4162
    case OPC_TLBWI:
4163
        gen_op_tlbwi();
4164
        opn = "tlbwi";
4165
        break;
4166
    case OPC_TLBWR:
4167
        gen_op_tlbwr();
4168
        opn = "tlbwr";
4169
        break;
4170
    case OPC_TLBP:
4171
        gen_op_tlbp();
4172
        opn = "tlbp";
4173
        break;
4174
    case OPC_TLBR:
4175
        gen_op_tlbr();
4176
        opn = "tlbr";
4177
        break;
4178
#endif
4179
    case OPC_ERET:
4180
        opn = "eret";
4181
        save_cpu_state(ctx, 0);
4182
        gen_op_eret();
4183
        ctx->bstate = BS_EXCP;
4184
        break;
4185
    case OPC_DERET:
4186
        opn = "deret";
4187
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4188
            generate_exception(ctx, EXCP_RI);
4189
        } else {
4190
            save_cpu_state(ctx, 0);
4191
            gen_op_deret();
4192
            ctx->bstate = BS_EXCP;
4193
        }
4194
        break;
4195
    case OPC_WAIT:
4196
        opn = "wait";
4197
        /* If we get an exception, we want to restart at next instruction */
4198
        ctx->pc += 4;
4199
        save_cpu_state(ctx, 1);
4200
        ctx->pc -= 4;
4201
        gen_op_wait();
4202
        ctx->bstate = BS_EXCP;
4203
        break;
4204
    default:
4205
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4206
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4207
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4208
                    ((ctx->opcode >> 16) & 0x1F));
4209
        }
4210
        generate_exception(ctx, EXCP_RI);
4211
        return;
4212
    }
4213
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4214
}
4215

    
4216
/* CP1 Branches (before delay slot) */
4217
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4218
                                 int32_t offset)
4219
{
4220
    target_ulong btarget;
4221

    
4222
    btarget = ctx->pc + 4 + offset;
4223

    
4224
    switch (op) {
4225
    case OPC_BC1F:
4226
        gen_op_bc1f();
4227
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4228
        goto not_likely;
4229
    case OPC_BC1FL:
4230
        gen_op_bc1f();
4231
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4232
        goto likely;
4233
    case OPC_BC1T:
4234
        gen_op_bc1t();
4235
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4236
    not_likely:
4237
        ctx->hflags |= MIPS_HFLAG_BC;
4238
        break;
4239
    case OPC_BC1TL:
4240
        gen_op_bc1t();
4241
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4242
    likely:
4243
        ctx->hflags |= MIPS_HFLAG_BL;
4244
        break;
4245
    default:    
4246
        MIPS_INVAL("cp1 branch/jump");
4247
        generate_exception (ctx, EXCP_RI);
4248
        return;
4249
    }
4250
    gen_op_set_bcond();
4251

    
4252
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4253
               ctx->hflags, btarget);
4254
    ctx->btarget = btarget;
4255

    
4256
    return;
4257
}
4258

    
4259
/* Coprocessor 1 (FPU) */
4260
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4261
{
4262
    const char *opn = "unk";
4263

    
4264
    switch (opc) {
4265
    case OPC_MFC1:
4266
        GEN_LOAD_FREG_FTN(WT0, fs);
4267
        gen_op_mfc1();
4268
        GEN_STORE_TN_REG(rt, T0);
4269
        opn = "mfc1";
4270
        break;
4271
    case OPC_MTC1:
4272
        GEN_LOAD_REG_TN(T0, rt);
4273
        gen_op_mtc1();
4274
        GEN_STORE_FTN_FREG(fs, WT0);
4275
        opn = "mtc1";
4276
        break;
4277
    case OPC_CFC1:
4278
        if (fs != 0 && fs != 31) {
4279
            MIPS_INVAL("cfc1 freg");
4280
            generate_exception (ctx, EXCP_RI);
4281
            return;
4282
        }
4283
        GEN_LOAD_IMM_TN(T1, fs);
4284
        gen_op_cfc1();
4285
        GEN_STORE_TN_REG(rt, T0);
4286
        opn = "cfc1";
4287
        break;
4288
    case OPC_CTC1:
4289
         if (fs != 0 && fs != 31) {
4290
            MIPS_INVAL("ctc1 freg");
4291
            generate_exception (ctx, EXCP_RI);
4292
            return;
4293
        }
4294
        GEN_LOAD_IMM_TN(T1, fs);
4295
        GEN_LOAD_REG_TN(T0, rt);
4296
        gen_op_ctc1();
4297
        opn = "ctc1";
4298
        break;
4299
    case OPC_DMFC1:
4300
    case OPC_DMTC1:
4301
        /* Not implemented, fallthrough. */
4302
    default:
4303
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4304
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4305
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4306
                    ((ctx->opcode >> 16) & 0x1F));
4307
        }
4308
        generate_exception (ctx, EXCP_RI);
4309
        return;
4310
    }
4311
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4312
}
4313

    
4314
/* verify if floating point register is valid; an operation is not defined
4315
 * if bit 0 of any register specification is set and the FR bit in the
4316
 * Status register equals zero, since the register numbers specify an
4317
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4318
 * in the Status register equals one, both even and odd register numbers
4319
 * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4320
 * 
4321
 * Multiple 64 bit wide registers can be checked by calling
4322
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4323
 */
4324
#define CHECK_FR(ctx, freg) do { \
4325
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4326
            generate_exception (ctx, EXCP_RI); \
4327
            return; \
4328
        } \
4329
    } while(0)
4330

    
4331
#define FOP(func, fmt) (((fmt) << 21) | (func))
4332

    
4333
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4334
{
4335
    const char *opn = "unk";
4336
    const char *condnames[] = {
4337
            "c.f",
4338
            "c.un",
4339
            "c.eq",
4340
            "c.ueq",
4341
            "c.olt",
4342
            "c.ult",
4343
            "c.ole",
4344
            "c.ule",
4345
            "c.sf",
4346
            "c.ngle",
4347
            "c.seq",
4348
            "c.ngl",
4349
            "c.lt",
4350
            "c.nge",
4351
            "c.le",
4352
            "c.ngt",
4353
    };
4354
    int binary = 0;
4355
    uint32_t func = ctx->opcode & 0x3f;
4356

    
4357
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4358
    case FOP(0, 17):
4359
        CHECK_FR(ctx, fs | ft | fd);
4360
        GEN_LOAD_FREG_FTN(DT0, fs);
4361
        GEN_LOAD_FREG_FTN(DT1, ft);
4362
        gen_op_float_add_d();
4363
        GEN_STORE_FTN_FREG(fd, DT2);
4364
        opn = "add.d";
4365
        binary = 1;
4366
        break;
4367
    case FOP(1, 17):
4368
        CHECK_FR(ctx, fs | ft | fd);
4369
        GEN_LOAD_FREG_FTN(DT0, fs);
4370
        GEN_LOAD_FREG_FTN(DT1, ft);
4371
        gen_op_float_sub_d();
4372
        GEN_STORE_FTN_FREG(fd, DT2);
4373
        opn = "sub.d";
4374
        binary = 1;
4375
        break;
4376
    case FOP(2, 17):
4377
        CHECK_FR(ctx, fs | ft | fd);
4378
        GEN_LOAD_FREG_FTN(DT0, fs);
4379
        GEN_LOAD_FREG_FTN(DT1, ft);
4380
        gen_op_float_mul_d();
4381
        GEN_STORE_FTN_FREG(fd, DT2);
4382
        opn = "mul.d";
4383
        binary = 1;
4384
        break;
4385
    case FOP(3, 17):
4386
        CHECK_FR(ctx, fs | ft | fd);
4387
        GEN_LOAD_FREG_FTN(DT0, fs);
4388
        GEN_LOAD_FREG_FTN(DT1, ft);
4389
        gen_op_float_div_d();
4390
        GEN_STORE_FTN_FREG(fd, DT2);
4391
        opn = "div.d";
4392
        binary = 1;
4393
        break;
4394
    case FOP(4, 17):
4395
        CHECK_FR(ctx, fs | fd);
4396
        GEN_LOAD_FREG_FTN(DT0, fs);
4397
        gen_op_float_sqrt_d();
4398
        GEN_STORE_FTN_FREG(fd, DT2);
4399
        opn = "sqrt.d";
4400
        break;
4401
    case FOP(5, 17):
4402
        CHECK_FR(ctx, fs | fd);
4403
        GEN_LOAD_FREG_FTN(DT0, fs);
4404
        gen_op_float_abs_d();
4405
        GEN_STORE_FTN_FREG(fd, DT2);
4406
        opn = "abs.d";
4407
        break;
4408
    case FOP(6, 17):
4409
        CHECK_FR(ctx, fs | fd);
4410
        GEN_LOAD_FREG_FTN(DT0, fs);
4411
        gen_op_float_mov_d();
4412
        GEN_STORE_FTN_FREG(fd, DT2);
4413
        opn = "mov.d";
4414
        break;
4415
    case FOP(7, 17):
4416
        CHECK_FR(ctx, fs | fd);
4417
        GEN_LOAD_FREG_FTN(DT0, fs);
4418
        gen_op_float_chs_d();
4419
        GEN_STORE_FTN_FREG(fd, DT2);
4420
        opn = "neg.d";
4421
        break;
4422
    /*  8 - round.l */
4423
    /*  9 - trunc.l */
4424
    /* 10 - ceil.l  */
4425
    /* 11 - floor.l */
4426
    case FOP(12, 17):
4427
        CHECK_FR(ctx, fs);
4428
        GEN_LOAD_FREG_FTN(DT0, fs);
4429
        gen_op_float_roundw_d();
4430
        GEN_STORE_FTN_FREG(fd, WT2);
4431
        opn = "round.w.d";
4432
        break;
4433
    case FOP(13, 17):
4434
        CHECK_FR(ctx, fs);
4435
        GEN_LOAD_FREG_FTN(DT0, fs);
4436
        gen_op_float_truncw_d();
4437
        GEN_STORE_FTN_FREG(fd, WT2);
4438
        opn = "trunc.w.d";
4439
        break;
4440
    case FOP(14, 17):
4441
        CHECK_FR(ctx, fs);
4442
        GEN_LOAD_FREG_FTN(DT0, fs);
4443
        gen_op_float_ceilw_d();
4444
        GEN_STORE_FTN_FREG(fd, WT2);
4445
        opn = "ceil.w.d";
4446
        break;
4447
    case FOP(15, 17):
4448
        CHECK_FR(ctx, fs);
4449
        GEN_LOAD_FREG_FTN(DT0, fs);
4450
        gen_op_float_floorw_d();
4451
        GEN_STORE_FTN_FREG(fd, WT2);
4452
        opn = "floor.w.d";
4453
        break;
4454
    case FOP(33, 16):
4455
        CHECK_FR(ctx, fd);
4456
        GEN_LOAD_FREG_FTN(WT0, fs);
4457
        gen_op_float_cvtd_s();
4458
        GEN_STORE_FTN_FREG(fd, DT2);
4459
        opn = "cvt.d.s";
4460
        break;
4461
    case FOP(33, 20):
4462
        CHECK_FR(ctx, fd);
4463
        GEN_LOAD_FREG_FTN(WT0, fs);
4464
        gen_op_float_cvtd_w();
4465
        GEN_STORE_FTN_FREG(fd, DT2);
4466
        opn = "cvt.d.w";
4467
        break;
4468
    case FOP(48, 17):
4469
    case FOP(49, 17):
4470
    case FOP(50, 17):
4471
    case FOP(51, 17):
4472
    case FOP(52, 17):
4473
    case FOP(53, 17):
4474
    case FOP(54, 17):
4475
    case FOP(55, 17):
4476
    case FOP(56, 17):
4477
    case FOP(57, 17):
4478
    case FOP(58, 17):
4479
    case FOP(59, 17):
4480
    case FOP(60, 17):
4481
    case FOP(61, 17):
4482
    case FOP(62, 17):
4483
    case FOP(63, 17):
4484
        CHECK_FR(ctx, fs | ft);
4485
        GEN_LOAD_FREG_FTN(DT0, fs);
4486
        GEN_LOAD_FREG_FTN(DT1, ft);
4487
        gen_cmp_d(func-48);
4488
        opn = condnames[func-48];
4489
        break;
4490
    case FOP(0, 16):
4491
        GEN_LOAD_FREG_FTN(WT0, fs);
4492
        GEN_LOAD_FREG_FTN(WT1, ft);
4493
        gen_op_float_add_s();
4494
        GEN_STORE_FTN_FREG(fd, WT2);
4495
        opn = "add.s";
4496
        binary = 1;
4497
        break;
4498
    case FOP(1, 16):
4499
        GEN_LOAD_FREG_FTN(WT0, fs);
4500
        GEN_LOAD_FREG_FTN(WT1, ft);
4501
        gen_op_float_sub_s();
4502
        GEN_STORE_FTN_FREG(fd, WT2);
4503
        opn = "sub.s";
4504
        binary = 1;
4505
        break;
4506
    case FOP(2, 16):
4507
        GEN_LOAD_FREG_FTN(WT0, fs);
4508
        GEN_LOAD_FREG_FTN(WT1, ft);
4509
        gen_op_float_mul_s();
4510
        GEN_STORE_FTN_FREG(fd, WT2);
4511
        opn = "mul.s";
4512
        binary = 1;
4513
        break;
4514
    case FOP(3, 16):
4515
        GEN_LOAD_FREG_FTN(WT0, fs);
4516
        GEN_LOAD_FREG_FTN(WT1, ft);
4517
        gen_op_float_div_s();
4518
        GEN_STORE_FTN_FREG(fd, WT2);
4519
        opn = "div.s";
4520
        binary = 1;
4521
        break;
4522
    case FOP(4, 16):
4523
        GEN_LOAD_FREG_FTN(WT0, fs);
4524
        gen_op_float_sqrt_s();
4525
        GEN_STORE_FTN_FREG(fd, WT2);
4526
        opn = "sqrt.s";
4527
        break;
4528
    case FOP(5, 16):
4529
        GEN_LOAD_FREG_FTN(WT0, fs);
4530
        gen_op_float_abs_s();
4531
        GEN_STORE_FTN_FREG(fd, WT2);
4532
        opn = "abs.s";
4533
        break;
4534
    case FOP(6, 16):
4535
        GEN_LOAD_FREG_FTN(WT0, fs);
4536
        gen_op_float_mov_s();
4537
        GEN_STORE_FTN_FREG(fd, WT2);
4538
        opn = "mov.s";
4539
        break;
4540
    case FOP(7, 16):
4541
        GEN_LOAD_FREG_FTN(WT0, fs);
4542
        gen_op_float_chs_s();
4543
        GEN_STORE_FTN_FREG(fd, WT2);
4544
        opn = "neg.s";
4545
        break;
4546
    case FOP(12, 16):
4547
        GEN_LOAD_FREG_FTN(WT0, fs);
4548
        gen_op_float_roundw_s();
4549
        GEN_STORE_FTN_FREG(fd, WT2);
4550
        opn = "round.w.s";
4551
        break;
4552
    case FOP(13, 16):
4553
        GEN_LOAD_FREG_FTN(WT0, fs);
4554
        gen_op_float_truncw_s();
4555
        GEN_STORE_FTN_FREG(fd, WT2);
4556
        opn = "trunc.w.s";
4557
        break;
4558
    case FOP(32, 17):
4559
        CHECK_FR(ctx, fs);
4560
        GEN_LOAD_FREG_FTN(DT0, fs);
4561
        gen_op_float_cvts_d();
4562
        GEN_STORE_FTN_FREG(fd, WT2);
4563
        opn = "cvt.s.d";
4564
        break;
4565
    case FOP(32, 20):
4566
        GEN_LOAD_FREG_FTN(WT0, fs);
4567
        gen_op_float_cvts_w();
4568
        GEN_STORE_FTN_FREG(fd, WT2);
4569
        opn = "cvt.s.w";
4570
        break;
4571
    case FOP(36, 16):
4572
        GEN_LOAD_FREG_FTN(WT0, fs);
4573
        gen_op_float_cvtw_s();
4574
        GEN_STORE_FTN_FREG(fd, WT2);
4575
        opn = "cvt.w.s";
4576
        break;
4577
    case FOP(36, 17):
4578
        CHECK_FR(ctx, fs);
4579
        GEN_LOAD_FREG_FTN(DT0, fs);
4580
        gen_op_float_cvtw_d();
4581
        GEN_STORE_FTN_FREG(fd, WT2);
4582
        opn = "cvt.w.d";
4583
        break;
4584
    case FOP(48, 16):
4585
    case FOP(49, 16):
4586
    case FOP(50, 16):
4587
    case FOP(51, 16):
4588
    case FOP(52, 16):
4589
    case FOP(53, 16):
4590
    case FOP(54, 16):
4591
    case FOP(55, 16):
4592
    case FOP(56, 16):
4593
    case FOP(57, 16):
4594
    case FOP(58, 16):
4595
    case FOP(59, 16):
4596
    case FOP(60, 16):
4597
    case FOP(61, 16):
4598
    case FOP(62, 16):
4599
    case FOP(63, 16):
4600
        GEN_LOAD_FREG_FTN(WT0, fs);
4601
        GEN_LOAD_FREG_FTN(WT1, ft);
4602
        gen_cmp_s(func-48);
4603
        opn = condnames[func-48];
4604
        break;
4605
    default:    
4606
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4607
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
4608
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4609
                    ((ctx->opcode >> 16) & 0x1F));
4610
        }
4611
        generate_exception (ctx, EXCP_RI);
4612
        return;
4613
    }
4614
    if (binary)
4615
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
4616
    else
4617
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
4618
}
4619

    
4620
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4621
{
4622
    uint32_t ccbit;
4623

    
4624
    if (cc)
4625
        ccbit = 1 << (24 + cc);
4626
    else
4627
        ccbit = 1 << 23;
4628
    if (!tf)
4629
        gen_op_movf(ccbit, rd, rs);
4630