Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 876d4b07

History | View | Annotate | Download (139.3 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
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
362

    
363
const unsigned char *regnames[] =
364
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
365
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
366
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
367
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
368

    
369
/* Warning: no function for r0 register (hard wired to zero) */
370
#define GEN32(func, NAME) \
371
static GenOpFunc *NAME ## _table [32] = {                                     \
372
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
373
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
374
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
375
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
376
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
377
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
378
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
379
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
380
};                                                                            \
381
static inline void func(int n)                                                \
382
{                                                                             \
383
    NAME ## _table[n]();                                                      \
384
}
385

    
386
/* General purpose registers moves */
387
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
388
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
389
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
390

    
391
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
392
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
393

    
394
static const char *fregnames[] =
395
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
396
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
397
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
398
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
399

    
400
# define SFGEN32(func, NAME) \
401
static GenOpFunc *NAME ## _table [32] = {                                     \
402
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
403
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
404
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
405
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
406
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
407
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
408
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
409
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
410
};                                                                            \
411
static inline void func(int n)                                                \
412
{                                                                             \
413
    NAME ## _table[n]();                                                      \
414
}
415

    
416
# define DFGEN32(func, NAME) \
417
static GenOpFunc *NAME ## _table [32] = {                                     \
418
NAME ## 0,  0, NAME ## 2,  0,                                                 \
419
NAME ## 4,  0, NAME ## 6,  0,                                                 \
420
NAME ## 8,  0, NAME ## 10, 0,                                                 \
421
NAME ## 12, 0, NAME ## 14, 0,                                                 \
422
NAME ## 16, 0, NAME ## 18, 0,                                                 \
423
NAME ## 20, 0, NAME ## 22, 0,                                                 \
424
NAME ## 24, 0, NAME ## 26, 0,                                                 \
425
NAME ## 28, 0, NAME ## 30, 0,                                                 \
426
};                                                                            \
427
static inline void func(int n)                                                \
428
{                                                                             \
429
    NAME ## _table[n]();                                                      \
430
}
431

    
432
SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
433
SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
434

    
435
SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
436
SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
437

    
438
SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
439
SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
440

    
441
DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
442
DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
443

    
444
DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
445
DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
446

    
447
DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
448
DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
449

    
450
#define FOP_CONDS(fmt) \
451
static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
452
    gen_op_cmp_ ## fmt ## _f,                                           \
453
    gen_op_cmp_ ## fmt ## _un,                                          \
454
    gen_op_cmp_ ## fmt ## _eq,                                          \
455
    gen_op_cmp_ ## fmt ## _ueq,                                         \
456
    gen_op_cmp_ ## fmt ## _olt,                                         \
457
    gen_op_cmp_ ## fmt ## _ult,                                         \
458
    gen_op_cmp_ ## fmt ## _ole,                                         \
459
    gen_op_cmp_ ## fmt ## _ule,                                         \
460
    gen_op_cmp_ ## fmt ## _sf,                                          \
461
    gen_op_cmp_ ## fmt ## _ngle,                                        \
462
    gen_op_cmp_ ## fmt ## _seq,                                         \
463
    gen_op_cmp_ ## fmt ## _ngl,                                         \
464
    gen_op_cmp_ ## fmt ## _lt,                                          \
465
    gen_op_cmp_ ## fmt ## _nge,                                         \
466
    gen_op_cmp_ ## fmt ## _le,                                          \
467
    gen_op_cmp_ ## fmt ## _ngt,                                         \
468
};                                                                      \
469
static inline void gen_cmp_ ## fmt(int n)                               \
470
{                                                                       \
471
    cond_ ## fmt ## _table[n]();                                        \
472
}
473

    
474
FOP_CONDS(d)
475
FOP_CONDS(s)
476

    
477
typedef struct DisasContext {
478
    struct TranslationBlock *tb;
479
    target_ulong pc, saved_pc;
480
    uint32_t opcode;
481
    /* Routine used to access memory */
482
    int mem_idx;
483
    uint32_t hflags, saved_hflags;
484
    uint32_t CP0_Status;
485
    int bstate;
486
    target_ulong btarget;
487
} DisasContext;
488

    
489
enum {
490
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
491
                      * exception condition
492
                      */
493
    BS_STOP     = 1, /* We want to stop translation for any reason */
494
    BS_BRANCH   = 2, /* We reached a branch condition     */
495
    BS_EXCP     = 3, /* We reached an exception condition */
496
};
497

    
498
#if defined MIPS_DEBUG_DISAS
499
#define MIPS_DEBUG(fmt, args...)                                              \
500
do {                                                                          \
501
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
502
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
503
                ctx->pc, ctx->opcode , ##args);                               \
504
    }                                                                         \
505
} while (0)
506
#else
507
#define MIPS_DEBUG(fmt, args...) do { } while(0)
508
#endif
509

    
510
#define MIPS_INVAL(op)                                                        \
511
do {                                                                          \
512
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
513
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
514
} while (0)
515

    
516
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
517
do {                                                                          \
518
    if (Rn == 0) {                                                            \
519
        glue(gen_op_reset_, Tn)();                                            \
520
    } else {                                                                  \
521
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
522
    }                                                                         \
523
} while (0)
524

    
525
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
526
do {                                                                          \
527
    if (Imm == 0) {                                                           \
528
        glue(gen_op_reset_, Tn)();                                            \
529
    } else {                                                                  \
530
        glue(gen_op_set_, Tn)(Imm);                                           \
531
    }                                                                         \
532
} while (0)
533

    
534
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
535
do {                                                                          \
536
    if (Rn != 0) {                                                            \
537
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
538
    }                                                                         \
539
} while (0)
540

    
541
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
542
do {                                                                          \
543
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
544
} while (0)
545

    
546
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
547
do {                                                                          \
548
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
549
} while (0)
550

    
551
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
552
{
553
#if defined MIPS_DEBUG_DISAS
554
    if (loglevel & CPU_LOG_TB_IN_ASM) {
555
            fprintf(logfile, "hflags %08x saved %08x\n",
556
                    ctx->hflags, ctx->saved_hflags);
557
    }
558
#endif
559
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
560
        gen_op_save_pc(ctx->pc);
561
        ctx->saved_pc = ctx->pc;
562
    }
563
    if (ctx->hflags != ctx->saved_hflags) {
564
        gen_op_save_state(ctx->hflags);
565
        ctx->saved_hflags = ctx->hflags;
566
        if (ctx->hflags & MIPS_HFLAG_BR) {
567
            gen_op_save_breg_target();
568
        } else if (ctx->hflags & MIPS_HFLAG_B) {
569
            gen_op_save_btarget(ctx->btarget);
570
        } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
571
            gen_op_save_bcond();
572
            gen_op_save_btarget(ctx->btarget);
573
        }
574
    }
575
}
576

    
577
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
578
{
579
#if defined MIPS_DEBUG_DISAS
580
    if (loglevel & CPU_LOG_TB_IN_ASM)
581
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
582
#endif
583
    save_cpu_state(ctx, 1);
584
    if (err == 0)
585
        gen_op_raise_exception(excp);
586
    else
587
        gen_op_raise_exception_err(excp, err);
588
    ctx->bstate = BS_EXCP;
589
}
590

    
591
static inline void generate_exception (DisasContext *ctx, int excp)
592
{
593
    generate_exception_err (ctx, excp, 0);
594
}
595

    
596
#if defined(CONFIG_USER_ONLY)
597
#define op_ldst(name)        gen_op_##name##_raw()
598
#define OP_LD_TABLE(width)
599
#define OP_ST_TABLE(width)
600
#else
601
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
602
#define OP_LD_TABLE(width)                                                    \
603
static GenOpFunc *gen_op_l##width[] = {                                       \
604
    &gen_op_l##width##_user,                                                  \
605
    &gen_op_l##width##_kernel,                                                \
606
}
607
#define OP_ST_TABLE(width)                                                    \
608
static GenOpFunc *gen_op_s##width[] = {                                       \
609
    &gen_op_s##width##_user,                                                  \
610
    &gen_op_s##width##_kernel,                                                \
611
}
612
#endif
613

    
614
#ifdef TARGET_MIPS64
615
OP_LD_TABLE(d);
616
OP_LD_TABLE(dl);
617
OP_LD_TABLE(dr);
618
OP_ST_TABLE(d);
619
OP_ST_TABLE(dl);
620
OP_ST_TABLE(dr);
621
OP_LD_TABLE(ld);
622
OP_ST_TABLE(cd);
623
#endif
624
OP_LD_TABLE(w);
625
OP_LD_TABLE(wu);
626
OP_LD_TABLE(wl);
627
OP_LD_TABLE(wr);
628
OP_ST_TABLE(w);
629
OP_ST_TABLE(wl);
630
OP_ST_TABLE(wr);
631
OP_LD_TABLE(h);
632
OP_LD_TABLE(hu);
633
OP_ST_TABLE(h);
634
OP_LD_TABLE(b);
635
OP_LD_TABLE(bu);
636
OP_ST_TABLE(b);
637
OP_LD_TABLE(l);
638
OP_ST_TABLE(c);
639
OP_LD_TABLE(wc1);
640
OP_ST_TABLE(wc1);
641
OP_LD_TABLE(dc1);
642
OP_ST_TABLE(dc1);
643

    
644
/* Load and store */
645
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
646
                      int base, int16_t offset)
647
{
648
    const char *opn = "unk";
649

    
650
    if (base == 0) {
651
        GEN_LOAD_IMM_TN(T0, offset);
652
    } else if (offset == 0) {
653
        gen_op_load_gpr_T0(base);
654
    } else {
655
        gen_op_load_gpr_T0(base);
656
        gen_op_set_T1(offset);
657
        gen_op_add();
658
    }
659
    /* Don't do NOP if destination is zero: we must perform the actual
660
     * memory access
661
     */
662
    switch (opc) {
663
#ifdef TARGET_MIPS64
664
    case OPC_LD:
665
        op_ldst(ld);
666
        GEN_STORE_TN_REG(rt, T0);
667
        opn = "ld";
668
        break;
669
    case OPC_LLD:
670
        op_ldst(lld);
671
        GEN_STORE_TN_REG(rt, T0);
672
        opn = "lld";
673
        break;
674
    case OPC_SD:
675
        GEN_LOAD_REG_TN(T1, rt);
676
        op_ldst(sd);
677
        opn = "sd";
678
        break;
679
    case OPC_SCD:
680
        GEN_LOAD_REG_TN(T1, rt);
681
        op_ldst(scd);
682
        opn = "scd";
683
        break;
684
    case OPC_LDL:
685
        op_ldst(ldl);
686
        GEN_STORE_TN_REG(rt, T0);
687
        opn = "ldl";
688
        break;
689
    case OPC_SDL:
690
        GEN_LOAD_REG_TN(T1, rt);
691
        op_ldst(sdl);
692
        opn = "sdl";
693
        break;
694
    case OPC_LDR:
695
        op_ldst(ldr);
696
        GEN_STORE_TN_REG(rt, T0);
697
        opn = "ldr";
698
        break;
699
    case OPC_SDR:
700
        GEN_LOAD_REG_TN(T1, rt);
701
        op_ldst(sdr);
702
        opn = "sdr";
703
        break;
704
#endif
705
    case OPC_LW:
706
        op_ldst(lw);
707
        GEN_STORE_TN_REG(rt, T0);
708
        opn = "lw";
709
        break;
710
    case OPC_LWU:
711
        op_ldst(lwu);
712
        GEN_STORE_TN_REG(rt, T0);
713
        opn = "lwu";
714
        break;
715
    case OPC_SW:
716
        GEN_LOAD_REG_TN(T1, rt);
717
        op_ldst(sw);
718
        opn = "sw";
719
        break;
720
    case OPC_LH:
721
        op_ldst(lh);
722
        GEN_STORE_TN_REG(rt, T0);
723
        opn = "lh";
724
        break;
725
    case OPC_SH:
726
        GEN_LOAD_REG_TN(T1, rt);
727
        op_ldst(sh);
728
        opn = "sh";
729
        break;
730
    case OPC_LHU:
731
        op_ldst(lhu);
732
        GEN_STORE_TN_REG(rt, T0);
733
        opn = "lhu";
734
        break;
735
    case OPC_LB:
736
        op_ldst(lb);
737
        GEN_STORE_TN_REG(rt, T0);
738
        opn = "lb";
739
        break;
740
    case OPC_SB:
741
        GEN_LOAD_REG_TN(T1, rt);
742
        op_ldst(sb);
743
        opn = "sb";
744
        break;
745
    case OPC_LBU:
746
        op_ldst(lbu);
747
        GEN_STORE_TN_REG(rt, T0);
748
        opn = "lbu";
749
        break;
750
    case OPC_LWL:
751
        GEN_LOAD_REG_TN(T1, rt);
752
        op_ldst(lwl);
753
        GEN_STORE_TN_REG(rt, T0);
754
        opn = "lwl";
755
        break;
756
    case OPC_SWL:
757
        GEN_LOAD_REG_TN(T1, rt);
758
        op_ldst(swl);
759
        opn = "swr";
760
        break;
761
    case OPC_LWR:
762
        GEN_LOAD_REG_TN(T1, rt);
763
        op_ldst(lwr);
764
        GEN_STORE_TN_REG(rt, T0);
765
        opn = "lwr";
766
        break;
767
    case OPC_SWR:
768
        GEN_LOAD_REG_TN(T1, rt);
769
        op_ldst(swr);
770
        opn = "swr";
771
        break;
772
    case OPC_LL:
773
        op_ldst(ll);
774
        GEN_STORE_TN_REG(rt, T0);
775
        opn = "ll";
776
        break;
777
    case OPC_SC:
778
        GEN_LOAD_REG_TN(T1, rt);
779
        op_ldst(sc);
780
        GEN_STORE_TN_REG(rt, T0);
781
        opn = "sc";
782
        break;
783
    default:
784
        MIPS_INVAL("load/store");
785
        generate_exception(ctx, EXCP_RI);
786
        return;
787
    }
788
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
789
}
790

    
791
/* Load and store */
792
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
793
                      int base, int16_t offset)
794
{
795
    const char *opn = "unk";
796

    
797
    if (base == 0) {
798
        GEN_LOAD_IMM_TN(T0, offset);
799
    } else if (offset == 0) {
800
        gen_op_load_gpr_T0(base);
801
    } else {
802
        gen_op_load_gpr_T0(base);
803
        gen_op_set_T1(offset);
804
        gen_op_add();
805
    }
806
    /* Don't do NOP if destination is zero: we must perform the actual
807
     * memory access
808
     */
809
    switch (opc) {
810
    case OPC_LWC1:
811
        op_ldst(lwc1);
812
        GEN_STORE_FTN_FREG(ft, WT0);
813
        opn = "lwc1";
814
        break;
815
    case OPC_SWC1:
816
        GEN_LOAD_FREG_FTN(WT0, ft);
817
        op_ldst(swc1);
818
        opn = "swc1";
819
        break;
820
    case OPC_LDC1:
821
        op_ldst(ldc1);
822
        GEN_STORE_FTN_FREG(ft, DT0);
823
        opn = "ldc1";
824
        break;
825
    case OPC_SDC1:
826
        GEN_LOAD_FREG_FTN(DT0, ft);
827
        op_ldst(sdc1);
828
        opn = "sdc1";
829
        break;
830
    default:
831
        MIPS_INVAL("float load/store");
832
        generate_exception(ctx, EXCP_RI);
833
        return;
834
    }
835
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
836
}
837

    
838
/* Arithmetic with immediate operand */
839
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
840
                           int rs, int16_t imm)
841
{
842
    uint32_t uimm;
843
    const char *opn = "unk";
844

    
845
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
846
        /* if no destination, treat it as a NOP 
847
         * For addi, we must generate the overflow exception when needed.
848
         */
849
        MIPS_DEBUG("NOP");
850
        return;
851
    }
852
    if (opc == OPC_ADDI || opc == OPC_ADDIU ||
853
        opc == OPC_DADDI || opc == OPC_DADDIU ||
854
        opc == OPC_SLTI || opc == OPC_SLTIU)
855
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
856
    else
857
        uimm = (uint16_t)imm;
858
    if (opc != OPC_LUI) {
859
        GEN_LOAD_REG_TN(T0, rs);
860
        GEN_LOAD_IMM_TN(T1, uimm);
861
    } else {
862
        uimm = uimm << 16;
863
        GEN_LOAD_IMM_TN(T0, uimm);
864
    }
865
    switch (opc) {
866
    case OPC_ADDI:
867
        save_cpu_state(ctx, 1);
868
        gen_op_addo();
869
        opn = "addi";
870
        break;
871
    case OPC_ADDIU:
872
        gen_op_add();
873
        opn = "addiu";
874
        break;
875
#ifdef TARGET_MIPS64
876
    case OPC_DADDI:
877
        save_cpu_state(ctx, 1);
878
        gen_op_daddo();
879
        opn = "daddi";
880
        break;
881
    case OPC_DADDIU:
882
        gen_op_dadd();
883
        opn = "daddiu";
884
        break;
885
#endif
886
    case OPC_SLTI:
887
        gen_op_lt();
888
        opn = "slti";
889
        break;
890
    case OPC_SLTIU:
891
        gen_op_ltu();
892
        opn = "sltiu";
893
        break;
894
    case OPC_ANDI:
895
        gen_op_and();
896
        opn = "andi";
897
        break;
898
    case OPC_ORI:
899
        gen_op_or();
900
        opn = "ori";
901
        break;
902
    case OPC_XORI:
903
        gen_op_xor();
904
        opn = "xori";
905
        break;
906
    case OPC_LUI:
907
        opn = "lui";
908
        break;
909
    case OPC_SLL:
910
        gen_op_sll();
911
        opn = "sll";
912
        break;
913
    case OPC_SRA:
914
        gen_op_sra();
915
        opn = "sra";
916
        break;
917
    case OPC_SRL:
918
       if ((ctx->opcode >> 21) & 1) {
919
            gen_op_rotr();
920
            opn = "rotr";
921
       } else {
922
            gen_op_srl();
923
            opn = "srl";
924
       }
925
        break;
926
#ifdef TARGET_MIPS64
927
    case OPC_DSLL:
928
        gen_op_dsll();
929
        opn = "dsll";
930
        break;
931
    case OPC_DSRA:
932
        gen_op_dsra();
933
        opn = "dsra";
934
        break;
935
    case OPC_DSRL:
936
       if ((ctx->opcode >> 21) & 1) {
937
            gen_op_drotr();
938
            opn = "drotr";
939
       } else {
940
            gen_op_dsrl();
941
            opn = "dsrl";
942
       }
943
        break;
944
    case OPC_DSLL32:
945
        gen_op_dsll32();
946
        opn = "dsll32";
947
        break;
948
    case OPC_DSRA32:
949
        gen_op_dsra32();
950
        opn = "dsra32";
951
        break;
952
    case OPC_DSRL32:
953
       if ((ctx->opcode >> 21) & 1) {
954
            gen_op_drotr32();
955
            opn = "drotr32";
956
       } else {
957
            gen_op_dsrl32();
958
            opn = "dsrl32";
959
       }
960
        break;
961
#endif
962
    default:
963
        MIPS_INVAL("imm arith");
964
        generate_exception(ctx, EXCP_RI);
965
        return;
966
    }
967
    GEN_STORE_TN_REG(rt, T0);
968
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
969
}
970

    
971
/* Arithmetic */
972
static void gen_arith (DisasContext *ctx, uint32_t opc,
973
                       int rd, int rs, int rt)
974
{
975
    const char *opn = "unk";
976

    
977
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
978
       && opc != OPC_DADD && opc != OPC_DSUB) {
979
        /* if no destination, treat it as a NOP 
980
         * For add & sub, we must generate the overflow exception when needed.
981
         */
982
        MIPS_DEBUG("NOP");
983
        return;
984
    }
985
    GEN_LOAD_REG_TN(T0, rs);
986
    GEN_LOAD_REG_TN(T1, rt);
987
    switch (opc) {
988
    case OPC_ADD:
989
        save_cpu_state(ctx, 1);
990
        gen_op_addo();
991
        opn = "add";
992
        break;
993
    case OPC_ADDU:
994
        gen_op_add();
995
        opn = "addu";
996
        break;
997
    case OPC_SUB:
998
        save_cpu_state(ctx, 1);
999
        gen_op_subo();
1000
        opn = "sub";
1001
        break;
1002
    case OPC_SUBU:
1003
        gen_op_sub();
1004
        opn = "subu";
1005
        break;
1006
#ifdef TARGET_MIPS64
1007
    case OPC_DADD:
1008
        save_cpu_state(ctx, 1);
1009
        gen_op_daddo();
1010
        opn = "dadd";
1011
        break;
1012
    case OPC_DADDU:
1013
        gen_op_dadd();
1014
        opn = "daddu";
1015
        break;
1016
    case OPC_DSUB:
1017
        save_cpu_state(ctx, 1);
1018
        gen_op_dsubo();
1019
        opn = "dsub";
1020
        break;
1021
    case OPC_DSUBU:
1022
        gen_op_dsub();
1023
        opn = "dsubu";
1024
        break;
1025
#endif
1026
    case OPC_SLT:
1027
        gen_op_lt();
1028
        opn = "slt";
1029
        break;
1030
    case OPC_SLTU:
1031
        gen_op_ltu();
1032
        opn = "sltu";
1033
        break;
1034
    case OPC_AND:
1035
        gen_op_and();
1036
        opn = "and";
1037
        break;
1038
    case OPC_NOR:
1039
        gen_op_nor();
1040
        opn = "nor";
1041
        break;
1042
    case OPC_OR:
1043
        gen_op_or();
1044
        opn = "or";
1045
        break;
1046
    case OPC_XOR:
1047
        gen_op_xor();
1048
        opn = "xor";
1049
        break;
1050
    case OPC_MUL:
1051
        gen_op_mul();
1052
        opn = "mul";
1053
        break;
1054
    case OPC_MOVN:
1055
        gen_op_movn(rd);
1056
        opn = "movn";
1057
        goto print;
1058
    case OPC_MOVZ:
1059
        gen_op_movz(rd);
1060
        opn = "movz";
1061
        goto print;
1062
    case OPC_SLLV:
1063
        gen_op_sllv();
1064
        opn = "sllv";
1065
        break;
1066
    case OPC_SRAV:
1067
        gen_op_srav();
1068
        opn = "srav";
1069
        break;
1070
    case OPC_SRLV:
1071
       if ((ctx->opcode >> 6) & 1) {
1072
            gen_op_rotrv();
1073
            opn = "rotrv";
1074
       } else {
1075
            gen_op_srlv();
1076
            opn = "srlv";
1077
       }
1078
        break;
1079
#ifdef TARGET_MIPS64
1080
    case OPC_DSLLV:
1081
        gen_op_dsllv();
1082
        opn = "dsllv";
1083
        break;
1084
    case OPC_DSRAV:
1085
        gen_op_dsrav();
1086
        opn = "dsrav";
1087
        break;
1088
    case OPC_DSRLV:
1089
       if ((ctx->opcode >> 6) & 1) {
1090
            gen_op_drotrv();
1091
            opn = "drotrv";
1092
       } else {
1093
            gen_op_dsrlv();
1094
            opn = "dsrlv";
1095
       }
1096
        break;
1097
#endif
1098
    default:
1099
        MIPS_INVAL("arith");
1100
        generate_exception(ctx, EXCP_RI);
1101
        return;
1102
    }
1103
    GEN_STORE_TN_REG(rd, T0);
1104
 print:
1105
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1106
}
1107

    
1108
/* Arithmetic on HI/LO registers */
1109
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1110
{
1111
    const char *opn = "unk";
1112

    
1113
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1114
        /* Treat as a NOP */
1115
        MIPS_DEBUG("NOP");
1116
        return;
1117
    }
1118
    switch (opc) {
1119
    case OPC_MFHI:
1120
        gen_op_load_HI();
1121
        GEN_STORE_TN_REG(reg, T0);
1122
        opn = "mfhi";
1123
        break;
1124
    case OPC_MFLO:
1125
        gen_op_load_LO();
1126
        GEN_STORE_TN_REG(reg, T0);
1127
        opn = "mflo";
1128
        break;
1129
    case OPC_MTHI:
1130
        GEN_LOAD_REG_TN(T0, reg);
1131
        gen_op_store_HI();
1132
        opn = "mthi";
1133
        break;
1134
    case OPC_MTLO:
1135
        GEN_LOAD_REG_TN(T0, reg);
1136
        gen_op_store_LO();
1137
        opn = "mtlo";
1138
        break;
1139
    default:
1140
        MIPS_INVAL("HILO");
1141
        generate_exception(ctx, EXCP_RI);
1142
        return;
1143
    }
1144
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1145
}
1146

    
1147
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1148
                        int rs, int rt)
1149
{
1150
    const char *opn = "unk";
1151

    
1152
    GEN_LOAD_REG_TN(T0, rs);
1153
    GEN_LOAD_REG_TN(T1, rt);
1154
    switch (opc) {
1155
    case OPC_DIV:
1156
        gen_op_div();
1157
        opn = "div";
1158
        break;
1159
    case OPC_DIVU:
1160
        gen_op_divu();
1161
        opn = "divu";
1162
        break;
1163
    case OPC_MULT:
1164
        gen_op_mult();
1165
        opn = "mult";
1166
        break;
1167
    case OPC_MULTU:
1168
        gen_op_multu();
1169
        opn = "multu";
1170
        break;
1171
#ifdef TARGET_MIPS64
1172
    case OPC_DDIV:
1173
        gen_op_ddiv();
1174
        opn = "ddiv";
1175
        break;
1176
    case OPC_DDIVU:
1177
        gen_op_ddivu();
1178
        opn = "ddivu";
1179
        break;
1180
    case OPC_DMULT:
1181
        gen_op_dmult();
1182
        opn = "dmult";
1183
        break;
1184
    case OPC_DMULTU:
1185
        gen_op_dmultu();
1186
        opn = "dmultu";
1187
        break;
1188
#endif
1189
    case OPC_MADD:
1190
        gen_op_madd();
1191
        opn = "madd";
1192
        break;
1193
    case OPC_MADDU:
1194
        gen_op_maddu();
1195
        opn = "maddu";
1196
        break;
1197
    case OPC_MSUB:
1198
        gen_op_msub();
1199
        opn = "msub";
1200
        break;
1201
    case OPC_MSUBU:
1202
        gen_op_msubu();
1203
        opn = "msubu";
1204
        break;
1205
    default:
1206
        MIPS_INVAL("mul/div");
1207
        generate_exception(ctx, EXCP_RI);
1208
        return;
1209
    }
1210
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1211
}
1212

    
1213
static void gen_cl (DisasContext *ctx, uint32_t opc,
1214
                    int rd, int rs)
1215
{
1216
    const char *opn = "unk";
1217
    if (rd == 0) {
1218
        /* Treat as a NOP */
1219
        MIPS_DEBUG("NOP");
1220
        return;
1221
    }
1222
    GEN_LOAD_REG_TN(T0, rs);
1223
    switch (opc) {
1224
    case OPC_CLO:
1225
        gen_op_clo();
1226
        opn = "clo";
1227
        break;
1228
    case OPC_CLZ:
1229
        gen_op_clz();
1230
        opn = "clz";
1231
        break;
1232
#ifdef TARGET_MIPS64
1233
    case OPC_DCLO:
1234
        gen_op_dclo();
1235
        opn = "dclo";
1236
        break;
1237
    case OPC_DCLZ:
1238
        gen_op_dclz();
1239
        opn = "dclz";
1240
        break;
1241
#endif
1242
    default:
1243
        MIPS_INVAL("CLx");
1244
        generate_exception(ctx, EXCP_RI);
1245
        return;
1246
    }
1247
    gen_op_store_T0_gpr(rd);
1248
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1249
}
1250

    
1251
/* Traps */
1252
static void gen_trap (DisasContext *ctx, uint32_t opc,
1253
                      int rs, int rt, int16_t imm)
1254
{
1255
    int cond;
1256

    
1257
    cond = 0;
1258
    /* Load needed operands */
1259
    switch (opc) {
1260
    case OPC_TEQ:
1261
    case OPC_TGE:
1262
    case OPC_TGEU:
1263
    case OPC_TLT:
1264
    case OPC_TLTU:
1265
    case OPC_TNE:
1266
        /* Compare two registers */
1267
        if (rs != rt) {
1268
            GEN_LOAD_REG_TN(T0, rs);
1269
            GEN_LOAD_REG_TN(T1, rt);
1270
            cond = 1;
1271
        }
1272
        break;
1273
    case OPC_TEQI:
1274
    case OPC_TGEI:
1275
    case OPC_TGEIU:
1276
    case OPC_TLTI:
1277
    case OPC_TLTIU:
1278
    case OPC_TNEI:
1279
        /* Compare register to immediate */
1280
        if (rs != 0 || imm != 0) {
1281
            GEN_LOAD_REG_TN(T0, rs);
1282
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1283
            cond = 1;
1284
        }
1285
        break;
1286
    }
1287
    if (cond == 0) {
1288
        switch (opc) {
1289
        case OPC_TEQ:   /* rs == rs */
1290
        case OPC_TEQI:  /* r0 == 0  */
1291
        case OPC_TGE:   /* rs >= rs */
1292
        case OPC_TGEI:  /* r0 >= 0  */
1293
        case OPC_TGEU:  /* rs >= rs unsigned */
1294
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1295
            /* Always trap */
1296
            gen_op_set_T0(1);
1297
            break;
1298
        case OPC_TLT:   /* rs < rs           */
1299
        case OPC_TLTI:  /* r0 < 0            */
1300
        case OPC_TLTU:  /* rs < rs unsigned  */
1301
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1302
        case OPC_TNE:   /* rs != rs          */
1303
        case OPC_TNEI:  /* r0 != 0           */
1304
            /* Never trap: treat as NOP */
1305
            return;
1306
        default:
1307
            MIPS_INVAL("TRAP");
1308
            generate_exception(ctx, EXCP_RI);
1309
            return;
1310
        }
1311
    } else {
1312
        switch (opc) {
1313
        case OPC_TEQ:
1314
        case OPC_TEQI:
1315
            gen_op_eq();
1316
            break;
1317
        case OPC_TGE:
1318
        case OPC_TGEI:
1319
            gen_op_ge();
1320
            break;
1321
        case OPC_TGEU:
1322
        case OPC_TGEIU:
1323
            gen_op_geu();
1324
            break;
1325
        case OPC_TLT:
1326
        case OPC_TLTI:
1327
            gen_op_lt();
1328
            break;
1329
        case OPC_TLTU:
1330
        case OPC_TLTIU:
1331
            gen_op_ltu();
1332
            break;
1333
        case OPC_TNE:
1334
        case OPC_TNEI:
1335
            gen_op_ne();
1336
            break;
1337
        default:
1338
            MIPS_INVAL("TRAP");
1339
            generate_exception(ctx, EXCP_RI);
1340
            return;
1341
        }
1342
    }
1343
    save_cpu_state(ctx, 1);
1344
    gen_op_trap();
1345
    ctx->bstate = BS_STOP;
1346
}
1347

    
1348
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1349
{
1350
    TranslationBlock *tb;
1351
    tb = ctx->tb;
1352
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1353
        if (n == 0)
1354
            gen_op_goto_tb0(TBPARAM(tb));
1355
        else
1356
            gen_op_goto_tb1(TBPARAM(tb));
1357
        gen_op_save_pc(dest);
1358
        gen_op_set_T0((long)tb + n);
1359
        gen_op_exit_tb();
1360
    } else {
1361
        gen_op_save_pc(dest);
1362
        gen_op_set_T0(0);
1363
        gen_op_exit_tb();
1364
    }
1365
}
1366

    
1367
/* Branches (before delay slot) */
1368
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1369
                                int rs, int rt, int32_t offset)
1370
{
1371
    target_ulong btarget = -1;
1372
    int blink = 0;
1373
    int bcond = 0;
1374

    
1375
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1376
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1377
            fprintf(logfile,
1378
                    "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1379
                    ctx->pc);
1380
        }
1381
        MIPS_INVAL("branch/jump in bdelay slot");
1382
        generate_exception(ctx, EXCP_RI);
1383
        return;
1384
    }
1385

    
1386
    /* Load needed operands */
1387
    switch (opc) {
1388
    case OPC_BEQ:
1389
    case OPC_BEQL:
1390
    case OPC_BNE:
1391
    case OPC_BNEL:
1392
        /* Compare two registers */
1393
        if (rs != rt) {
1394
            GEN_LOAD_REG_TN(T0, rs);
1395
            GEN_LOAD_REG_TN(T1, rt);
1396
            bcond = 1;
1397
        }
1398
        btarget = ctx->pc + 4 + offset;
1399
        break;
1400
    case OPC_BGEZ:
1401
    case OPC_BGEZAL:
1402
    case OPC_BGEZALL:
1403
    case OPC_BGEZL:
1404
    case OPC_BGTZ:
1405
    case OPC_BGTZL:
1406
    case OPC_BLEZ:
1407
    case OPC_BLEZL:
1408
    case OPC_BLTZ:
1409
    case OPC_BLTZAL:
1410
    case OPC_BLTZALL:
1411
    case OPC_BLTZL:
1412
        /* Compare to zero */
1413
        if (rs != 0) {
1414
            gen_op_load_gpr_T0(rs);
1415
            bcond = 1;
1416
        }
1417
        btarget = ctx->pc + 4 + offset;
1418
        break;
1419
    case OPC_J:
1420
    case OPC_JAL:
1421
        /* Jump to immediate */
1422
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1423
        break;
1424
    case OPC_JR:
1425
    case OPC_JALR:
1426
        /* Jump to register */
1427
        if (offset != 0 && offset != 16) {
1428
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1429
              others are reserved. */
1430
            generate_exception(ctx, EXCP_RI);
1431
            return;
1432
        }
1433
        GEN_LOAD_REG_TN(T2, rs);
1434
        break;
1435
    default:
1436
        MIPS_INVAL("branch/jump");
1437
        generate_exception(ctx, EXCP_RI);
1438
        return;
1439
    }
1440
    if (bcond == 0) {
1441
        /* No condition to be computed */
1442
        switch (opc) {
1443
        case OPC_BEQ:     /* rx == rx        */
1444
        case OPC_BEQL:    /* rx == rx likely */
1445
        case OPC_BGEZ:    /* 0 >= 0          */
1446
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1447
        case OPC_BLEZ:    /* 0 <= 0          */
1448
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1449
            /* Always take */
1450
            ctx->hflags |= MIPS_HFLAG_B;
1451
            MIPS_DEBUG("balways");
1452
            break;
1453
        case OPC_BGEZAL:  /* 0 >= 0          */
1454
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1455
            /* Always take and link */
1456
            blink = 31;
1457
            ctx->hflags |= MIPS_HFLAG_B;
1458
            MIPS_DEBUG("balways and link");
1459
            break;
1460
        case OPC_BNE:     /* rx != rx        */
1461
        case OPC_BGTZ:    /* 0 > 0           */
1462
        case OPC_BLTZ:    /* 0 < 0           */
1463
            /* Treated as NOP */
1464
            MIPS_DEBUG("bnever (NOP)");
1465
            return;
1466
        case OPC_BLTZAL:  /* 0 < 0           */
1467
            gen_op_set_T0(ctx->pc + 8);
1468
            gen_op_store_T0_gpr(31);
1469
            return;
1470
        case OPC_BLTZALL: /* 0 < 0 likely */
1471
            gen_op_set_T0(ctx->pc + 8);
1472
            gen_op_store_T0_gpr(31);
1473
            gen_goto_tb(ctx, 0, ctx->pc + 4);
1474
            return;
1475
        case OPC_BNEL:    /* rx != rx likely */
1476
        case OPC_BGTZL:   /* 0 > 0 likely */
1477
        case OPC_BLTZL:   /* 0 < 0 likely */
1478
            /* Skip the instruction in the delay slot */
1479
            MIPS_DEBUG("bnever and skip");
1480
            gen_goto_tb(ctx, 0, ctx->pc + 4);
1481
            return;
1482
        case OPC_J:
1483
            ctx->hflags |= MIPS_HFLAG_B;
1484
            MIPS_DEBUG("j %08x", btarget);
1485
            break;
1486
        case OPC_JAL:
1487
            blink = 31;
1488
            ctx->hflags |= MIPS_HFLAG_B;
1489
            MIPS_DEBUG("jal %08x", btarget);
1490
            break;
1491
        case OPC_JR:
1492
            ctx->hflags |= MIPS_HFLAG_BR;
1493
            MIPS_DEBUG("jr %s", regnames[rs]);
1494
            break;
1495
        case OPC_JALR:
1496
            blink = rt;
1497
            ctx->hflags |= MIPS_HFLAG_BR;
1498
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1499
            break;
1500
        default:
1501
            MIPS_INVAL("branch/jump");
1502
            generate_exception(ctx, EXCP_RI);
1503
            return;
1504
        }
1505
    } else {
1506
        switch (opc) {
1507
        case OPC_BEQ:
1508
            gen_op_eq();
1509
            MIPS_DEBUG("beq %s, %s, %08x",
1510
                       regnames[rs], regnames[rt], btarget);
1511
            goto not_likely;
1512
        case OPC_BEQL:
1513
            gen_op_eq();
1514
            MIPS_DEBUG("beql %s, %s, %08x",
1515
                       regnames[rs], regnames[rt], btarget);
1516
            goto likely;
1517
        case OPC_BNE:
1518
            gen_op_ne();
1519
            MIPS_DEBUG("bne %s, %s, %08x",
1520
                       regnames[rs], regnames[rt], btarget);
1521
            goto not_likely;
1522
        case OPC_BNEL:
1523
            gen_op_ne();
1524
            MIPS_DEBUG("bnel %s, %s, %08x",
1525
                       regnames[rs], regnames[rt], btarget);
1526
            goto likely;
1527
        case OPC_BGEZ:
1528
            gen_op_gez();
1529
            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1530
            goto not_likely;
1531
        case OPC_BGEZL:
1532
            gen_op_gez();
1533
            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1534
            goto likely;
1535
        case OPC_BGEZAL:
1536
            gen_op_gez();
1537
            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1538
            blink = 31;
1539
            goto not_likely;
1540
        case OPC_BGEZALL:
1541
            gen_op_gez();
1542
            blink = 31;
1543
            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1544
            goto likely;
1545
        case OPC_BGTZ:
1546
            gen_op_gtz();
1547
            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1548
            goto not_likely;
1549
        case OPC_BGTZL:
1550
            gen_op_gtz();
1551
            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1552
            goto likely;
1553
        case OPC_BLEZ:
1554
            gen_op_lez();
1555
            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1556
            goto not_likely;
1557
        case OPC_BLEZL:
1558
            gen_op_lez();
1559
            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1560
            goto likely;
1561
        case OPC_BLTZ:
1562
            gen_op_ltz();
1563
            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1564
            goto not_likely;
1565
        case OPC_BLTZL:
1566
            gen_op_ltz();
1567
            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1568
            goto likely;
1569
        case OPC_BLTZAL:
1570
            gen_op_ltz();
1571
            blink = 31;
1572
            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1573
        not_likely:
1574
            ctx->hflags |= MIPS_HFLAG_BC;
1575
            break;
1576
        case OPC_BLTZALL:
1577
            gen_op_ltz();
1578
            blink = 31;
1579
            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1580
        likely:
1581
            ctx->hflags |= MIPS_HFLAG_BL;
1582
            break;
1583
        }
1584
        gen_op_set_bcond();
1585
    }
1586
    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1587
               blink, ctx->hflags, btarget);
1588
    ctx->btarget = btarget;
1589
    if (blink > 0) {
1590
        gen_op_set_T0(ctx->pc + 8);
1591
        gen_op_store_T0_gpr(blink);
1592
    }
1593
    return;
1594
}
1595

    
1596
/* special3 bitfield operations */
1597
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1598
                       int rs, int lsb, int msb)
1599
{
1600
    GEN_LOAD_REG_TN(T1, rs);
1601
    switch (opc) {
1602
    case OPC_EXT:
1603
        if (lsb + msb > 31)
1604
            goto fail;
1605
        gen_op_ext(lsb, msb + 1);
1606
        break;
1607
    case OPC_DEXTM:
1608
        if (lsb + msb > 63)
1609
            goto fail;
1610
        gen_op_ext(lsb, msb + 1 + 32);
1611
        break;
1612
    case OPC_DEXTU:
1613
        if (lsb + msb > 63)
1614
            goto fail;
1615
        gen_op_ext(lsb + 32, msb + 1);
1616
        break;
1617
    case OPC_DEXT:
1618
        gen_op_ext(lsb, msb + 1);
1619
        break;
1620
    case OPC_INS:
1621
        if (lsb > msb)
1622
            goto fail;
1623
        GEN_LOAD_REG_TN(T2, rt);
1624
        gen_op_ins(lsb, msb - lsb + 1);
1625
        break;
1626
    case OPC_DINSM:
1627
        if (lsb > msb)
1628
            goto fail;
1629
        GEN_LOAD_REG_TN(T2, rt);
1630
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1631
        break;
1632
    case OPC_DINSU:
1633
        if (lsb > msb)
1634
            goto fail;
1635
        GEN_LOAD_REG_TN(T2, rt);
1636
        gen_op_ins(lsb + 32, msb - lsb + 1);
1637
        break;
1638
    case OPC_DINS:
1639
        if (lsb > msb)
1640
            goto fail;
1641
        GEN_LOAD_REG_TN(T2, rt);
1642
        gen_op_ins(lsb, msb - lsb + 1);
1643
        break;
1644
    default:
1645
fail:
1646
        MIPS_INVAL("bitops");
1647
        generate_exception(ctx, EXCP_RI);
1648
        return;
1649
    }
1650
    GEN_STORE_TN_REG(rt, T0);
1651
}
1652

    
1653
/* CP0 (MMU and control) */
1654
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1655
{
1656
    const char *rn = "invalid";
1657

    
1658
    switch (reg) {
1659
    case 0:
1660
        switch (sel) {
1661
        case 0:
1662
           gen_op_mfc0_index();
1663
            rn = "Index";
1664
            break;
1665
        case 1:
1666
//         gen_op_mfc0_mvpcontrol(); /* MT ASE */
1667
            rn = "MVPControl";
1668
//         break;
1669
        case 2:
1670
//         gen_op_mfc0_mvpconf0(); /* MT ASE */
1671
            rn = "MVPConf0";
1672
//         break;
1673
        case 3:
1674
//         gen_op_mfc0_mvpconf1(); /* MT ASE */
1675
            rn = "MVPConf1";
1676
//         break;
1677
        default:
1678
            goto die;
1679
        }
1680
        break;
1681
    case 1:
1682
        switch (sel) {
1683
        case 0:
1684
            gen_op_mfc0_random();
1685
            rn = "Random";
1686
           break;
1687
        case 1:
1688
//         gen_op_mfc0_vpecontrol(); /* MT ASE */
1689
            rn = "VPEControl";
1690
//         break;
1691
        case 2:
1692
//         gen_op_mfc0_vpeconf0(); /* MT ASE */
1693
            rn = "VPEConf0";
1694
//         break;
1695
        case 3:
1696
//         gen_op_mfc0_vpeconf1(); /* MT ASE */
1697
            rn = "VPEConf1";
1698
//         break;
1699
        case 4:
1700
//         gen_op_mfc0_YQMask(); /* MT ASE */
1701
            rn = "YQMask";
1702
//         break;
1703
        case 5:
1704
//         gen_op_mfc0_vpeschedule(); /* MT ASE */
1705
            rn = "VPESchedule";
1706
//         break;
1707
        case 6:
1708
//         gen_op_mfc0_vpeschefback(); /* MT ASE */
1709
            rn = "VPEScheFBack";
1710
//         break;
1711
        case 7:
1712
//         gen_op_mfc0_vpeopt(); /* MT ASE */
1713
            rn = "VPEOpt";
1714
//         break;
1715
        default:
1716
            goto die;
1717
        }
1718
        break;
1719
    case 2:
1720
        switch (sel) {
1721
        case 0:
1722
           gen_op_mfc0_entrylo0();
1723
           rn = "EntryLo0";
1724
           break;
1725
        case 1:
1726
//         gen_op_mfc0_tcstatus(); /* MT ASE */
1727
           rn = "TCStatus";
1728
//         break;
1729
        case 2:
1730
//         gen_op_mfc0_tcbind(); /* MT ASE */
1731
           rn = "TCBind";
1732
//         break;
1733
        case 3:
1734
//         gen_op_mfc0_tcrestart(); /* MT ASE */
1735
           rn = "TCRestart";
1736
//         break;
1737
        case 4:
1738
//         gen_op_mfc0_tchalt(); /* MT ASE */
1739
           rn = "TCHalt";
1740
//         break;
1741
        case 5:
1742
//         gen_op_mfc0_tccontext(); /* MT ASE */
1743
           rn = "TCContext";
1744
//         break;
1745
        case 6:
1746
//         gen_op_mfc0_tcschedule(); /* MT ASE */
1747
           rn = "TCSchedule";
1748
//         break;
1749
        case 7:
1750
//         gen_op_mfc0_tcschefback(); /* MT ASE */
1751
           rn = "TCScheFBack";
1752
//         break;
1753
        default:
1754
            goto die;
1755
        }
1756
        break;
1757
    case 3:
1758
        switch (sel) {
1759
        case 0:
1760
           gen_op_mfc0_entrylo1();
1761
           rn = "EntryLo1";
1762
           break;
1763
        default:
1764
            goto die;
1765
       }
1766
        break;
1767
    case 4:
1768
        switch (sel) {
1769
        case 0:
1770
           gen_op_mfc0_context();
1771
           rn = "Context";
1772
           break;
1773
        case 1:
1774
//         gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1775
           rn = "ContextConfig";
1776
//         break;
1777
        default:
1778
            goto die;
1779
       }
1780
        break;
1781
    case 5:
1782
        switch (sel) {
1783
        case 0:
1784
           gen_op_mfc0_pagemask();
1785
           rn = "PageMask";
1786
           break;
1787
        case 1:
1788
           gen_op_mfc0_pagegrain();
1789
           rn = "PageGrain";
1790
           break;
1791
        default:
1792
            goto die;
1793
       }
1794
        break;
1795
    case 6:
1796
        switch (sel) {
1797
        case 0:
1798
           gen_op_mfc0_wired();
1799
           rn = "Wired";
1800
           break;
1801
        case 1:
1802
//         gen_op_mfc0_srsconf0(); /* shadow registers */
1803
           rn = "SRSConf0";
1804
//         break;
1805
        case 2:
1806
//         gen_op_mfc0_srsconf1(); /* shadow registers */
1807
           rn = "SRSConf1";
1808
//         break;
1809
        case 3:
1810
//         gen_op_mfc0_srsconf2(); /* shadow registers */
1811
           rn = "SRSConf2";
1812
//         break;
1813
        case 4:
1814
//         gen_op_mfc0_srsconf3(); /* shadow registers */
1815
           rn = "SRSConf3";
1816
//         break;
1817
        case 5:
1818
//         gen_op_mfc0_srsconf4(); /* shadow registers */
1819
           rn = "SRSConf4";
1820
//         break;
1821
        default:
1822
            goto die;
1823
       }
1824
        break;
1825
    case 7:
1826
        switch (sel) {
1827
        case 0:
1828
           gen_op_mfc0_hwrena();
1829
           rn = "HWREna";
1830
           break;
1831
        default:
1832
            goto die;
1833
       }
1834
        break;
1835
    case 8:
1836
        switch (sel) {
1837
        case 0:
1838
           gen_op_mfc0_badvaddr();
1839
           rn = "BadVaddr";
1840
           break;
1841
        default:
1842
            goto die;
1843
       }
1844
        break;
1845
    case 9:
1846
        switch (sel) {
1847
        case 0:
1848
           gen_op_mfc0_count();
1849
           rn = "Count";
1850
           break;
1851
       /* 6,7 are implementation dependent */
1852
        default:
1853
            goto die;
1854
       }
1855
        break;
1856
    case 10:
1857
        switch (sel) {
1858
        case 0:
1859
           gen_op_mfc0_entryhi();
1860
           rn = "EntryHi";
1861
           break;
1862
        default:
1863
            goto die;
1864
       }
1865
        break;
1866
    case 11:
1867
        switch (sel) {
1868
        case 0:
1869
           gen_op_mfc0_compare();
1870
           rn = "Compare";
1871
           break;
1872
       /* 6,7 are implementation dependent */
1873
        default:
1874
            goto die;
1875
       }
1876
        break;
1877
    case 12:
1878
        switch (sel) {
1879
        case 0:
1880
           gen_op_mfc0_status();
1881
           rn = "Status";
1882
           break;
1883
        case 1:
1884
           gen_op_mfc0_intctl();
1885
           rn = "IntCtl";
1886
           break;
1887
        case 2:
1888
           gen_op_mfc0_srsctl();
1889
           rn = "SRSCtl";
1890
           break;
1891
        case 3:
1892
//         gen_op_mfc0_srsmap(); /* shadow registers */
1893
           rn = "SRSMap";
1894
//         break;
1895
        default:
1896
            goto die;
1897
       }
1898
        break;
1899
    case 13:
1900
        switch (sel) {
1901
        case 0:
1902
           gen_op_mfc0_cause();
1903
           rn = "Cause";
1904
           break;
1905
        default:
1906
            goto die;
1907
       }
1908
        break;
1909
    case 14:
1910
        switch (sel) {
1911
        case 0:
1912
           gen_op_mfc0_epc();
1913
           rn = "EPC";
1914
           break;
1915
        default:
1916
            goto die;
1917
       }
1918
        break;
1919
    case 15:
1920
        switch (sel) {
1921
        case 0:
1922
           gen_op_mfc0_prid();
1923
           rn = "PRid";
1924
           break;
1925
        case 1:
1926
           gen_op_mfc0_ebase();
1927
           rn = "EBase";
1928
           break;
1929
        default:
1930
            goto die;
1931
       }
1932
        break;
1933
    case 16:
1934
        switch (sel) {
1935
        case 0:
1936
            gen_op_mfc0_config0();
1937
            rn = "Config";
1938
            break;
1939
        case 1:
1940
            gen_op_mfc0_config1();
1941
            rn = "Config1";
1942
            break;
1943
        case 2:
1944
            gen_op_mfc0_config2();
1945
            rn = "Config2";
1946
            break;
1947
        case 3:
1948
            gen_op_mfc0_config3();
1949
            rn = "Config3";
1950
            break;
1951
        /* 4,5 are reserved */
1952
        /* 6,7 are implementation dependent */
1953
        case 6:
1954
            gen_op_mfc0_config6();
1955
            rn = "Config6";
1956
            break;
1957
        case 7:
1958
            gen_op_mfc0_config7();
1959
            rn = "Config7";
1960
            break;
1961
        default:
1962
            goto die;
1963
        }
1964
        break;
1965
    case 17:
1966
        switch (sel) {
1967
        case 0:
1968
           gen_op_mfc0_lladdr();
1969
           rn = "LLAddr";
1970
           break;
1971
        default:
1972
            goto die;
1973
        }
1974
        break;
1975
    case 18:
1976
        switch (sel) {
1977
        case 0:
1978
           gen_op_mfc0_watchlo0();
1979
           rn = "WatchLo";
1980
           break;
1981
        case 1:
1982
//         gen_op_mfc0_watchlo1();
1983
           rn = "WatchLo1";
1984
//         break;
1985
        case 2:
1986
//         gen_op_mfc0_watchlo2();
1987
           rn = "WatchLo2";
1988
//         break;
1989
        case 3:
1990
//         gen_op_mfc0_watchlo3();
1991
           rn = "WatchLo3";
1992
//         break;
1993
        case 4:
1994
//         gen_op_mfc0_watchlo4();
1995
           rn = "WatchLo4";
1996
//         break;
1997
        case 5:
1998
//         gen_op_mfc0_watchlo5();
1999
           rn = "WatchLo5";
2000
//         break;
2001
        case 6:
2002
//         gen_op_mfc0_watchlo6();
2003
           rn = "WatchLo6";
2004
//         break;
2005
        case 7:
2006
//         gen_op_mfc0_watchlo7();
2007
           rn = "WatchLo7";
2008
//         break;
2009
        default:
2010
            goto die;
2011
        }
2012
        break;
2013
    case 19:
2014
        switch (sel) {
2015
        case 0:
2016
           gen_op_mfc0_watchhi0();
2017
           rn = "WatchHi";
2018
           break;
2019
        case 1:
2020
//         gen_op_mfc0_watchhi1();
2021
           rn = "WatchHi1";
2022
//         break;
2023
        case 2:
2024
//         gen_op_mfc0_watchhi2();
2025
           rn = "WatchHi2";
2026
//         break;
2027
        case 3:
2028
//         gen_op_mfc0_watchhi3();
2029
           rn = "WatchHi3";
2030
//         break;
2031
        case 4:
2032
//         gen_op_mfc0_watchhi4();
2033
           rn = "WatchHi4";
2034
//         break;
2035
        case 5:
2036
//         gen_op_mfc0_watchhi5();
2037
           rn = "WatchHi5";
2038
//         break;
2039
        case 6:
2040
//         gen_op_mfc0_watchhi6();
2041
           rn = "WatchHi6";
2042
//         break;
2043
        case 7:
2044
//         gen_op_mfc0_watchhi7();
2045
           rn = "WatchHi7";
2046
//         break;
2047
        default:
2048
            goto die;
2049
        }
2050
        break;
2051
    case 20:
2052
        switch (sel) {
2053
        case 0:
2054
           /* 64 bit MMU only */
2055
           gen_op_mfc0_xcontext();
2056
           rn = "XContext";
2057
           break;
2058
        default:
2059
            goto die;
2060
        }
2061
        break;
2062
    case 21:
2063
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2064
        switch (sel) {
2065
        case 0:
2066
           gen_op_mfc0_framemask();
2067
           rn = "Framemask";
2068
           break;
2069
        default:
2070
            goto die;
2071
        }
2072
        break;
2073
    case 22:
2074
       /* ignored */
2075
       rn = "'Diagnostic"; /* implementation dependent */
2076
       break;
2077
    case 23:
2078
        switch (sel) {
2079
        case 0:
2080
           gen_op_mfc0_debug(); /* EJTAG support */
2081
           rn = "Debug";
2082
           break;
2083
        case 1:
2084
//         gen_op_mfc0_tracecontrol(); /* PDtrace support */
2085
           rn = "TraceControl";
2086
//         break;
2087
        case 2:
2088
//         gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2089
           rn = "TraceControl2";
2090
//         break;
2091
        case 3:
2092
//         gen_op_mfc0_usertracedata(); /* PDtrace support */
2093
           rn = "UserTraceData";
2094
//         break;
2095
        case 4:
2096
//         gen_op_mfc0_debug(); /* PDtrace support */
2097
           rn = "TraceBPC";
2098
//         break;
2099
        default:
2100
            goto die;
2101
        }
2102
        break;
2103
    case 24:
2104
        switch (sel) {
2105
        case 0:
2106
           gen_op_mfc0_depc(); /* EJTAG support */
2107
           rn = "DEPC";
2108
           break;
2109
        default:
2110
            goto die;
2111
        }
2112
        break;
2113
    case 25:
2114
        switch (sel) {
2115
        case 0:
2116
           gen_op_mfc0_performance0();
2117
           rn = "Performance0";
2118
            break;
2119
        case 1:
2120
//         gen_op_mfc0_performance1();
2121
           rn = "Performance1";
2122
//         break;
2123
        case 2:
2124
//         gen_op_mfc0_performance2();
2125
           rn = "Performance2";
2126
//         break;
2127
        case 3:
2128
//         gen_op_mfc0_performance3();
2129
           rn = "Performance3";
2130
//         break;
2131
        case 4:
2132
//         gen_op_mfc0_performance4();
2133
           rn = "Performance4";
2134
//         break;
2135
        case 5:
2136
//         gen_op_mfc0_performance5();
2137
           rn = "Performance5";
2138
//         break;
2139
        case 6:
2140
//         gen_op_mfc0_performance6();
2141
           rn = "Performance6";
2142
//         break;
2143
        case 7:
2144
//         gen_op_mfc0_performance7();
2145
           rn = "Performance7";
2146
//         break;
2147
        default:
2148
            goto die;
2149
        }
2150
        break;
2151
    case 26:
2152
       rn = "ECC";
2153
       break;
2154
    case 27:
2155
        switch (sel) {
2156
        /* ignored */
2157
        case 0 ... 3:
2158
           rn = "CacheErr";
2159
           break;
2160
        default:
2161
            goto die;
2162
        }
2163
        break;
2164
    case 28:
2165
        switch (sel) {
2166
        case 0:
2167
        case 2:
2168
        case 4:
2169
        case 6:
2170
            gen_op_mfc0_taglo();
2171
            rn = "TagLo";
2172
            break;
2173
        case 1:
2174
        case 3:
2175
        case 5:
2176
        case 7:
2177
            gen_op_mfc0_datalo();
2178
            rn = "DataLo";
2179
            break;
2180
        default:
2181
            goto die;
2182
        }
2183
        break;
2184
    case 29:
2185
        switch (sel) {
2186
        case 0:
2187
        case 2:
2188
        case 4:
2189
        case 6:
2190
            gen_op_mfc0_taghi();
2191
            rn = "TagHi";
2192
            break;
2193
        case 1:
2194
        case 3:
2195
        case 5:
2196
        case 7:
2197
            gen_op_mfc0_datahi();
2198
            rn = "DataHi";
2199
            break;
2200
        default:
2201
            goto die;
2202
        }
2203
        break;
2204
    case 30:
2205
        switch (sel) {
2206
        case 0:
2207
           gen_op_mfc0_errorepc();
2208
           rn = "ErrorEPC";
2209
           break;
2210
        default:
2211
            goto die;
2212
        }
2213
        break;
2214
    case 31:
2215
        switch (sel) {
2216
        case 0:
2217
           gen_op_mfc0_desave(); /* EJTAG support */
2218
           rn = "DESAVE";
2219
           break;
2220
        default:
2221
            goto die;
2222
        }
2223
        break;
2224
    default:
2225
       goto die;
2226
    }
2227
#if defined MIPS_DEBUG_DISAS
2228
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2229
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2230
                rn, reg, sel);
2231
    }
2232
#endif
2233
    return;
2234

    
2235
die:
2236
#if defined MIPS_DEBUG_DISAS
2237
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2238
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2239
                rn, reg, sel);
2240
    }
2241
#endif
2242
    generate_exception(ctx, EXCP_RI);
2243
}
2244

    
2245
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2246
{
2247
    const char *rn = "invalid";
2248

    
2249
    switch (reg) {
2250
    case 0:
2251
        switch (sel) {
2252
        case 0:
2253
           gen_op_mtc0_index();
2254
            rn = "Index";
2255
            break;
2256
        case 1:
2257
//         gen_op_mtc0_mvpcontrol(); /* MT ASE */
2258
            rn = "MVPControl";
2259
//         break;
2260
        case 2:
2261
//         gen_op_mtc0_mvpconf0(); /* MT ASE */
2262
            rn = "MVPConf0";
2263
//         break;
2264
        case 3:
2265
//         gen_op_mtc0_mvpconf1(); /* MT ASE */
2266
            rn = "MVPConf1";
2267
//         break;
2268
        default:
2269
            goto die;
2270
        }
2271
        break;
2272
    case 1:
2273
        switch (sel) {
2274
        case 0:
2275
           /* ignored */
2276
            rn = "Random";
2277
           break;
2278
        case 1:
2279
//         gen_op_mtc0_vpecontrol(); /* MT ASE */
2280
            rn = "VPEControl";
2281
//         break;
2282
        case 2:
2283
//         gen_op_mtc0_vpeconf0(); /* MT ASE */
2284
            rn = "VPEConf0";
2285
//         break;
2286
        case 3:
2287
//         gen_op_mtc0_vpeconf1(); /* MT ASE */
2288
            rn = "VPEConf1";
2289
//         break;
2290
        case 4:
2291
//         gen_op_mtc0_YQMask(); /* MT ASE */
2292
            rn = "YQMask";
2293
//         break;
2294
        case 5:
2295
//         gen_op_mtc0_vpeschedule(); /* MT ASE */
2296
            rn = "VPESchedule";
2297
//         break;
2298
        case 6:
2299
//         gen_op_mtc0_vpeschefback(); /* MT ASE */
2300
            rn = "VPEScheFBack";
2301
//         break;
2302
        case 7:
2303
//         gen_op_mtc0_vpeopt(); /* MT ASE */
2304
            rn = "VPEOpt";
2305
//         break;
2306
        default:
2307
            goto die;
2308
        }
2309
        break;
2310
    case 2:
2311
        switch (sel) {
2312
        case 0:
2313
           gen_op_mtc0_entrylo0();
2314
           rn = "EntryLo0";
2315
           break;
2316
        case 1:
2317
//         gen_op_mtc0_tcstatus(); /* MT ASE */
2318
           rn = "TCStatus";
2319
//         break;
2320
        case 2:
2321
//         gen_op_mtc0_tcbind(); /* MT ASE */
2322
           rn = "TCBind";
2323
//         break;
2324
        case 3:
2325
//         gen_op_mtc0_tcrestart(); /* MT ASE */
2326
           rn = "TCRestart";
2327
//         break;
2328
        case 4:
2329
//         gen_op_mtc0_tchalt(); /* MT ASE */
2330
           rn = "TCHalt";
2331
//         break;
2332
        case 5:
2333
//         gen_op_mtc0_tccontext(); /* MT ASE */
2334
           rn = "TCContext";
2335
//         break;
2336
        case 6:
2337
//         gen_op_mtc0_tcschedule(); /* MT ASE */
2338
           rn = "TCSchedule";
2339
//         break;
2340
        case 7:
2341
//         gen_op_mtc0_tcschefback(); /* MT ASE */
2342
           rn = "TCScheFBack";
2343
//         break;
2344
        default:
2345
            goto die;
2346
        }
2347
        break;
2348
    case 3:
2349
        switch (sel) {
2350
        case 0:
2351
           gen_op_mtc0_entrylo1();
2352
           rn = "EntryLo1";
2353
           break;
2354
        default:
2355
            goto die;
2356
        }
2357
        break;
2358
    case 4:
2359
        switch (sel) {
2360
        case 0:
2361
           gen_op_mtc0_context();
2362
           rn = "Context";
2363
           break;
2364
        case 1:
2365
//         gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2366
           rn = "ContextConfig";
2367
//         break;
2368
        default:
2369
            goto die;
2370
        }
2371
        break;
2372
    case 5:
2373
        switch (sel) {
2374
        case 0:
2375
           gen_op_mtc0_pagemask();
2376
           rn = "PageMask";
2377
           break;
2378
        case 1:
2379
           gen_op_mtc0_pagegrain();
2380
           rn = "PageGrain";
2381
           break;
2382
        default:
2383
            goto die;
2384
        }
2385
        break;
2386
    case 6:
2387
        switch (sel) {
2388
        case 0:
2389
           gen_op_mtc0_wired();
2390
           rn = "Wired";
2391
           break;
2392
        case 1:
2393
//         gen_op_mtc0_srsconf0(); /* shadow registers */
2394
           rn = "SRSConf0";
2395
//         break;
2396
        case 2:
2397
//         gen_op_mtc0_srsconf1(); /* shadow registers */
2398
           rn = "SRSConf1";
2399
//         break;
2400
        case 3:
2401
//         gen_op_mtc0_srsconf2(); /* shadow registers */
2402
           rn = "SRSConf2";
2403
//         break;
2404
        case 4:
2405
//         gen_op_mtc0_srsconf3(); /* shadow registers */
2406
           rn = "SRSConf3";
2407
//         break;
2408
        case 5:
2409
//         gen_op_mtc0_srsconf4(); /* shadow registers */
2410
           rn = "SRSConf4";
2411
//         break;
2412
        default:
2413
            goto die;
2414
        }
2415
        break;
2416
    case 7:
2417
        switch (sel) {
2418
        case 0:
2419
           gen_op_mtc0_hwrena();
2420
           rn = "HWREna";
2421
           break;
2422
        default:
2423
            goto die;
2424
        }
2425
        break;
2426
    case 8:
2427
        /* ignored */
2428
        rn = "BadVaddr";
2429
        break;
2430
    case 9:
2431
        switch (sel) {
2432
        case 0:
2433
           gen_op_mtc0_count();
2434
           rn = "Count";
2435
           break;
2436
        /* 6,7 are implementation dependent */
2437
        default:
2438
            goto die;
2439
        }
2440
        /* Stop translation as we may have switched the execution mode */
2441
        ctx->bstate = BS_STOP;
2442
        break;
2443
    case 10:
2444
        switch (sel) {
2445
        case 0:
2446
           gen_op_mtc0_entryhi();
2447
           rn = "EntryHi";
2448
           break;
2449
        default:
2450
            goto die;
2451
        }
2452
        break;
2453
    case 11:
2454
        switch (sel) {
2455
        case 0:
2456
           gen_op_mtc0_compare();
2457
           rn = "Compare";
2458
           break;
2459
       /* 6,7 are implementation dependent */
2460
        default:
2461
            goto die;
2462
        }
2463
        /* Stop translation as we may have switched the execution mode */
2464
        ctx->bstate = BS_STOP;
2465
        break;
2466
    case 12:
2467
        switch (sel) {
2468
        case 0:
2469
           gen_op_mtc0_status();
2470
           rn = "Status";
2471
           break;
2472
        case 1:
2473
           gen_op_mtc0_intctl();
2474
           rn = "IntCtl";
2475
           break;
2476
        case 2:
2477
           gen_op_mtc0_srsctl();
2478
           rn = "SRSCtl";
2479
           break;
2480
        case 3:
2481
//         gen_op_mtc0_srsmap(); /* shadow registers */
2482
           rn = "SRSMap";
2483
//         break;
2484
        default:
2485
            goto die;
2486
        }
2487
        /* Stop translation as we may have switched the execution mode */
2488
        ctx->bstate = BS_STOP;
2489
        break;
2490
    case 13:
2491
        switch (sel) {
2492
        case 0:
2493
           gen_op_mtc0_cause();
2494
           rn = "Cause";
2495
           break;
2496
        default:
2497
            goto die;
2498
        }
2499
        /* Stop translation as we may have switched the execution mode */
2500
        ctx->bstate = BS_STOP;
2501
        break;
2502
    case 14:
2503
        switch (sel) {
2504
        case 0:
2505
           gen_op_mtc0_epc();
2506
           rn = "EPC";
2507
           break;
2508
        default:
2509
            goto die;
2510
        }
2511
        break;
2512
    case 15:
2513
        switch (sel) {
2514
        case 0:
2515
           /* ignored */
2516
           rn = "PRid";
2517
           break;
2518
        case 1:
2519
           gen_op_mtc0_ebase();
2520
           rn = "EBase";
2521
           break;
2522
        default:
2523
            goto die;
2524
       }
2525
        break;
2526
    case 16:
2527
        switch (sel) {
2528
        case 0:
2529
            gen_op_mtc0_config0();
2530
            rn = "Config";
2531
            break;
2532
        case 1:
2533
            /* ignored, read only */
2534
            rn = "Config1";
2535
            break;
2536
        case 2:
2537
            gen_op_mtc0_config2();
2538
            rn = "Config2";
2539
            break;
2540
        case 3:
2541
            /* ignored, read only */
2542
            rn = "Config3";
2543
            break;
2544
        /* 4,5 are reserved */
2545
        /* 6,7 are implementation dependent */
2546
        case 6:
2547
            /* ignored */
2548
            rn = "Config6";
2549
            break;
2550
        case 7:
2551
            /* ignored */
2552
            rn = "Config7";
2553
            break;
2554
        default:
2555
            rn = "Invalid config selector";
2556
            goto die;
2557
        }
2558
        /* Stop translation as we may have switched the execution mode */
2559
        ctx->bstate = BS_STOP;
2560
        break;
2561
    case 17:
2562
        switch (sel) {
2563
        case 0:
2564
           /* ignored */
2565
           rn = "LLAddr";
2566
           break;
2567
        default:
2568
            goto die;
2569
        }
2570
        break;
2571
    case 18:
2572
        switch (sel) {
2573
        case 0:
2574
           gen_op_mtc0_watchlo0();
2575
           rn = "WatchLo";
2576
           break;
2577
        case 1:
2578
//         gen_op_mtc0_watchlo1();
2579
           rn = "WatchLo1";
2580
//         break;
2581
        case 2:
2582
//         gen_op_mtc0_watchlo2();
2583
           rn = "WatchLo2";
2584
//         break;
2585
        case 3:
2586
//         gen_op_mtc0_watchlo3();
2587
           rn = "WatchLo3";
2588
//         break;
2589
        case 4:
2590
//         gen_op_mtc0_watchlo4();
2591
           rn = "WatchLo4";
2592
//         break;
2593
        case 5:
2594
//         gen_op_mtc0_watchlo5();
2595
           rn = "WatchLo5";
2596
//         break;
2597
        case 6:
2598
//         gen_op_mtc0_watchlo6();
2599
           rn = "WatchLo6";
2600
//         break;
2601
        case 7:
2602
//         gen_op_mtc0_watchlo7();
2603
           rn = "WatchLo7";
2604
//         break;
2605
        default:
2606
            goto die;
2607
        }
2608
        break;
2609
    case 19:
2610
        switch (sel) {
2611
        case 0:
2612
           gen_op_mtc0_watchhi0();
2613
           rn = "WatchHi";
2614
           break;
2615
        case 1:
2616
//         gen_op_mtc0_watchhi1();
2617
           rn = "WatchHi1";
2618
//         break;
2619
        case 2:
2620
//         gen_op_mtc0_watchhi2();
2621
           rn = "WatchHi2";
2622
//         break;
2623
        case 3:
2624
//         gen_op_mtc0_watchhi3();
2625
           rn = "WatchHi3";
2626
//         break;
2627
        case 4:
2628
//         gen_op_mtc0_watchhi4();
2629
           rn = "WatchHi4";
2630
//         break;
2631
        case 5:
2632
//         gen_op_mtc0_watchhi5();
2633
           rn = "WatchHi5";
2634
//         break;
2635
        case 6:
2636
//         gen_op_mtc0_watchhi6();
2637
           rn = "WatchHi6";
2638
//         break;
2639
        case 7:
2640
//         gen_op_mtc0_watchhi7();
2641
           rn = "WatchHi7";
2642
//         break;
2643
        default:
2644
            goto die;
2645
        }
2646
        break;
2647
    case 20:
2648
        switch (sel) {
2649
        case 0:
2650
           /* 64 bit MMU only */
2651
           gen_op_mtc0_xcontext();
2652
           rn = "XContext";
2653
           break;
2654
        default:
2655
            goto die;
2656
        }
2657
        break;
2658
    case 21:
2659
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2660
        switch (sel) {
2661
        case 0:
2662
           gen_op_mtc0_framemask();
2663
           rn = "Framemask";
2664
           break;
2665
        default:
2666
            goto die;
2667
        }
2668
        break;
2669
    case 22:
2670
        /* ignored */
2671
        rn = "Diagnostic"; /* implementation dependent */
2672
       break;
2673
    case 23:
2674
        switch (sel) {
2675
        case 0:
2676
           gen_op_mtc0_debug(); /* EJTAG support */
2677
           rn = "Debug";
2678
           break;
2679
        case 1:
2680
//         gen_op_mtc0_tracecontrol(); /* PDtrace support */
2681
           rn = "TraceControl";
2682
//         break;
2683
        case 2:
2684
//         gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2685
           rn = "TraceControl2";
2686
//         break;
2687
        case 3:
2688
//         gen_op_mtc0_usertracedata(); /* PDtrace support */
2689
           rn = "UserTraceData";
2690
//         break;
2691
        case 4:
2692
//         gen_op_mtc0_debug(); /* PDtrace support */
2693
           rn = "TraceBPC";
2694
//         break;
2695
        default:
2696
            goto die;
2697
        }
2698
       /* Stop translation as we may have switched the execution mode */
2699
       ctx->bstate = BS_STOP;
2700
        break;
2701
    case 24:
2702
        switch (sel) {
2703
        case 0:
2704
           gen_op_mtc0_depc(); /* EJTAG support */
2705
           rn = "DEPC";
2706
           break;
2707
        default:
2708
            goto die;
2709
        }
2710
        break;
2711
    case 25:
2712
        switch (sel) {
2713
        case 0:
2714
           gen_op_mtc0_performance0();
2715
           rn = "Performance0";
2716
           break;
2717
        case 1:
2718
//         gen_op_mtc0_performance1();
2719
           rn = "Performance1";
2720
//         break;
2721
        case 2:
2722
//         gen_op_mtc0_performance2();
2723
           rn = "Performance2";
2724
//         break;
2725
        case 3:
2726
//         gen_op_mtc0_performance3();
2727
           rn = "Performance3";
2728
//         break;
2729
        case 4:
2730
//         gen_op_mtc0_performance4();
2731
           rn = "Performance4";
2732
//         break;
2733
        case 5:
2734
//         gen_op_mtc0_performance5();
2735
           rn = "Performance5";
2736
//         break;
2737
        case 6:
2738
//         gen_op_mtc0_performance6();
2739
           rn = "Performance6";
2740
//         break;
2741
        case 7:
2742
//         gen_op_mtc0_performance7();
2743
           rn = "Performance7";
2744
//         break;
2745
        default:
2746
            goto die;
2747
        }
2748
       break;
2749
    case 26:
2750
       /* ignored */
2751
        rn = "ECC";
2752
       break;
2753
    case 27:
2754
        switch (sel) {
2755
        case 0 ... 3:
2756
           /* ignored */
2757
           rn = "CacheErr";
2758
           break;
2759
        default:
2760
            goto die;
2761
        }
2762
       break;
2763
    case 28:
2764
        switch (sel) {
2765
        case 0:
2766
        case 2:
2767
        case 4:
2768
        case 6:
2769
            gen_op_mtc0_taglo();
2770
            rn = "TagLo";
2771
            break;
2772
        case 1:
2773
        case 3:
2774
        case 5:
2775
        case 7:
2776
           gen_op_mtc0_datalo();
2777
            rn = "DataLo";
2778
            break;
2779
        default:
2780
            goto die;
2781
        }
2782
        break;
2783
    case 29:
2784
        switch (sel) {
2785
        case 0:
2786
        case 2:
2787
        case 4:
2788
        case 6:
2789
            gen_op_mtc0_taghi();
2790
            rn = "TagHi";
2791
            break;
2792
        case 1:
2793
        case 3:
2794
        case 5:
2795
        case 7:
2796
           gen_op_mtc0_datahi();
2797
            rn = "DataHi";
2798
            break;
2799
        default:
2800
            rn = "invalid sel";
2801
            goto die;
2802
        }
2803
       break;
2804
    case 30:
2805
        switch (sel) {
2806
        case 0:
2807
           gen_op_mtc0_errorepc();
2808
           rn = "ErrorEPC";
2809
           break;
2810
        default:
2811
            goto die;
2812
        }
2813
        break;
2814
    case 31:
2815
        switch (sel) {
2816
        case 0:
2817
           gen_op_mtc0_desave(); /* EJTAG support */
2818
           rn = "DESAVE";
2819
           break;
2820
        default:
2821
            goto die;
2822
        }
2823
       /* Stop translation as we may have switched the execution mode */
2824
       ctx->bstate = BS_STOP;
2825
        break;
2826
    default:
2827
       goto die;
2828
    }
2829
#if defined MIPS_DEBUG_DISAS
2830
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2831
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2832
                rn, reg, sel);
2833
    }
2834
#endif
2835
    return;
2836

    
2837
die:
2838
#if defined MIPS_DEBUG_DISAS
2839
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2840
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2841
                rn, reg, sel);
2842
    }
2843
#endif
2844
    generate_exception(ctx, EXCP_RI);
2845
}
2846

    
2847
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2848
{
2849
    const char *rn = "invalid";
2850

    
2851
    switch (reg) {
2852
    case 0:
2853
        switch (sel) {
2854
        case 0:
2855
           gen_op_mfc0_index();
2856
            rn = "Index";
2857
            break;
2858
        case 1:
2859
//         gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2860
            rn = "MVPControl";
2861
//         break;
2862
        case 2:
2863
//         gen_op_dmfc0_mvpconf0(); /* MT ASE */
2864
            rn = "MVPConf0";
2865
//         break;
2866
        case 3:
2867
//         gen_op_dmfc0_mvpconf1(); /* MT ASE */
2868
            rn = "MVPConf1";
2869
//         break;
2870
        default:
2871
            goto die;
2872
        }
2873
        break;
2874
    case 1:
2875
        switch (sel) {
2876
        case 0:
2877
            gen_op_mfc0_random();
2878
            rn = "Random";
2879
           break;
2880
        case 1:
2881
//         gen_op_dmfc0_vpecontrol(); /* MT ASE */
2882
            rn = "VPEControl";
2883
//         break;
2884
        case 2:
2885
//         gen_op_dmfc0_vpeconf0(); /* MT ASE */
2886
            rn = "VPEConf0";
2887
//         break;
2888
        case 3:
2889
//         gen_op_dmfc0_vpeconf1(); /* MT ASE */
2890
            rn = "VPEConf1";
2891
//         break;
2892
        case 4:
2893
//         gen_op_dmfc0_YQMask(); /* MT ASE */
2894
            rn = "YQMask";
2895
//         break;
2896
        case 5:
2897
//         gen_op_dmfc0_vpeschedule(); /* MT ASE */
2898
            rn = "VPESchedule";
2899
//         break;
2900
        case 6:
2901
//         gen_op_dmfc0_vpeschefback(); /* MT ASE */
2902
            rn = "VPEScheFBack";
2903
//         break;
2904
        case 7:
2905
//         gen_op_dmfc0_vpeopt(); /* MT ASE */
2906
            rn = "VPEOpt";
2907
//         break;
2908
        default:
2909
            goto die;
2910
        }
2911
        break;
2912
    case 2:
2913
        switch (sel) {
2914
        case 0:
2915
           gen_op_dmfc0_entrylo0();
2916
           rn = "EntryLo0";
2917
           break;
2918
        case 1:
2919
//         gen_op_dmfc0_tcstatus(); /* MT ASE */
2920
           rn = "TCStatus";
2921
//         break;
2922
        case 2:
2923
//         gen_op_dmfc0_tcbind(); /* MT ASE */
2924
           rn = "TCBind";
2925
//         break;
2926
        case 3:
2927
//         gen_op_dmfc0_tcrestart(); /* MT ASE */
2928
           rn = "TCRestart";
2929
//         break;
2930
        case 4:
2931
//         gen_op_dmfc0_tchalt(); /* MT ASE */
2932
           rn = "TCHalt";
2933
//         break;
2934
        case 5:
2935
//         gen_op_dmfc0_tccontext(); /* MT ASE */
2936
           rn = "TCContext";
2937
//         break;
2938
        case 6:
2939
//         gen_op_dmfc0_tcschedule(); /* MT ASE */
2940
           rn = "TCSchedule";
2941
//         break;
2942
        case 7:
2943
//         gen_op_dmfc0_tcschefback(); /* MT ASE */
2944
           rn = "TCScheFBack";
2945
//         break;
2946
        default:
2947
            goto die;
2948
        }
2949
        break;
2950
    case 3:
2951
        switch (sel) {
2952
        case 0:
2953
           gen_op_dmfc0_entrylo1();
2954
           rn = "EntryLo1";
2955
           break;
2956
        default:
2957
            goto die;
2958
       }
2959
        break;
2960
    case 4:
2961
        switch (sel) {
2962
        case 0:
2963
           gen_op_dmfc0_context();
2964
           rn = "Context";
2965
           break;
2966
        case 1:
2967
//         gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
2968
           rn = "ContextConfig";
2969
//         break;
2970
        default:
2971
            goto die;
2972
        }
2973
        break;
2974
    case 5:
2975
        switch (sel) {
2976
        case 0:
2977
           gen_op_mfc0_pagemask();
2978
           rn = "PageMask";
2979
           break;
2980
        case 1:
2981
           gen_op_mfc0_pagegrain();
2982
           rn = "PageGrain";
2983
           break;
2984
        default:
2985
            goto die;
2986
        }
2987
        break;
2988
    case 6:
2989
        switch (sel) {
2990
        case 0:
2991
           gen_op_mfc0_wired();
2992
           rn = "Wired";
2993
           break;
2994
        case 1:
2995
//         gen_op_dmfc0_srsconf0(); /* shadow registers */
2996
           rn = "SRSConf0";
2997
//         break;
2998
        case 2:
2999
//         gen_op_dmfc0_srsconf1(); /* shadow registers */
3000
           rn = "SRSConf1";
3001
//         break;
3002
        case 3:
3003
//         gen_op_dmfc0_srsconf2(); /* shadow registers */
3004
           rn = "SRSConf2";
3005
//         break;
3006
        case 4:
3007
//         gen_op_dmfc0_srsconf3(); /* shadow registers */
3008
           rn = "SRSConf3";
3009
//         break;
3010
        case 5:
3011
//         gen_op_dmfc0_srsconf4(); /* shadow registers */
3012
           rn = "SRSConf4";
3013
//         break;
3014
        default:
3015
            goto die;
3016
        }
3017
        break;
3018
    case 7:
3019
        switch (sel) {
3020
        case 0:
3021
           gen_op_mfc0_hwrena();
3022
           rn = "HWREna";
3023
           break;
3024
        default:
3025
            goto die;
3026
        }
3027
        break;
3028
    case 8:
3029
        switch (sel) {
3030
        case 0:
3031
           gen_op_dmfc0_badvaddr();
3032
           rn = "BadVaddr";
3033
           break;
3034
        default:
3035
            goto die;
3036
        }
3037
        break;
3038
    case 9:
3039
        switch (sel) {
3040
        case 0:
3041
           gen_op_mfc0_count();
3042
           rn = "Count";
3043
           break;
3044
       /* 6,7 are implementation dependent */
3045
        default:
3046
            goto die;
3047
        }
3048
        break;
3049
    case 10:
3050
        switch (sel) {
3051
        case 0:
3052
           gen_op_dmfc0_entryhi();
3053
           rn = "EntryHi";
3054
           break;
3055
        default:
3056
            goto die;
3057
        }
3058
        break;
3059
    case 11:
3060
        switch (sel) {
3061
        case 0:
3062
           gen_op_mfc0_compare();
3063
           rn = "Compare";
3064
           break;
3065
        /* 6,7 are implementation dependent */
3066
        default:
3067
            goto die;
3068
        }
3069
        break;
3070
    case 12:
3071
        switch (sel) {
3072
        case 0:
3073
           gen_op_mfc0_status();
3074
           rn = "Status";
3075
           break;
3076
        case 1:
3077
           gen_op_mfc0_intctl();
3078
           rn = "IntCtl";
3079
           break;
3080
        case 2:
3081
           gen_op_mfc0_srsctl();
3082
           rn = "SRSCtl";
3083
           break;
3084
        case 3:
3085
           gen_op_mfc0_srsmap(); /* shadow registers */
3086
           rn = "SRSMap";
3087
           break;
3088
        default:
3089
            goto die;
3090
        }
3091
        break;
3092
    case 13:
3093
        switch (sel) {
3094
        case 0:
3095
           gen_op_mfc0_cause();
3096
           rn = "Cause";
3097
           break;
3098
        default:
3099
            goto die;
3100
        }
3101
        break;
3102
    case 14:
3103
        switch (sel) {
3104
        case 0:
3105
           gen_op_dmfc0_epc();
3106
           rn = "EPC";
3107
           break;
3108
        default:
3109
            goto die;
3110
        }
3111
        break;
3112
    case 15:
3113
        switch (sel) {
3114
        case 0:
3115
           gen_op_mfc0_prid();
3116
           rn = "PRid";
3117
           break;
3118
        case 1:
3119
           gen_op_mfc0_ebase();
3120
           rn = "EBase";
3121
           break;
3122
        default:
3123
            goto die;
3124
        }
3125
        break;
3126
    case 16:
3127
        switch (sel) {
3128
        case 0:
3129
           gen_op_mfc0_config0();
3130
            rn = "Config";
3131
            break;
3132
        case 1:
3133
           gen_op_mfc0_config1();
3134
            rn = "Config1";
3135
            break;
3136
        case 2:
3137
           gen_op_mfc0_config2();
3138
            rn = "Config2";
3139
            break;
3140
        case 3:
3141
           gen_op_mfc0_config3();
3142
            rn = "Config3";
3143
            break;
3144
       /* 6,7 are implementation dependent */
3145
        default:
3146
            goto die;
3147
        }
3148
        break;
3149
    case 17:
3150
        switch (sel) {
3151
        case 0:
3152
           gen_op_dmfc0_lladdr();
3153
           rn = "LLAddr";
3154
           break;
3155
        default:
3156
            goto die;
3157
        }
3158
        break;
3159
    case 18:
3160
        switch (sel) {
3161
        case 0:
3162
           gen_op_dmfc0_watchlo0();
3163
           rn = "WatchLo";
3164
           break;
3165
        case 1:
3166
//         gen_op_dmfc0_watchlo1();
3167
           rn = "WatchLo1";
3168
//         break;
3169
        case 2:
3170
//         gen_op_dmfc0_watchlo2();
3171
           rn = "WatchLo2";
3172
//         break;
3173
        case 3:
3174
//         gen_op_dmfc0_watchlo3();
3175
           rn = "WatchLo3";
3176
//         break;
3177
        case 4:
3178
//         gen_op_dmfc0_watchlo4();
3179
           rn = "WatchLo4";
3180
//         break;
3181
        case 5:
3182
//         gen_op_dmfc0_watchlo5();
3183
           rn = "WatchLo5";
3184
//         break;
3185
        case 6:
3186
//         gen_op_dmfc0_watchlo6();
3187
           rn = "WatchLo6";
3188
//         break;
3189
        case 7:
3190
//         gen_op_dmfc0_watchlo7();
3191
           rn = "WatchLo7";
3192
//         break;
3193
        default:
3194
            goto die;
3195
        }
3196
        break;
3197
    case 19:
3198
        switch (sel) {
3199
        case 0:
3200
           gen_op_mfc0_watchhi0();
3201
           rn = "WatchHi";
3202
           break;
3203
        case 1:
3204
//         gen_op_mfc0_watchhi1();
3205
           rn = "WatchHi1";
3206
//         break;
3207
        case 2:
3208
//         gen_op_mfc0_watchhi2();
3209
           rn = "WatchHi2";
3210
//         break;
3211
        case 3:
3212
//         gen_op_mfc0_watchhi3();
3213
           rn = "WatchHi3";
3214
//         break;
3215
        case 4:
3216
//         gen_op_mfc0_watchhi4();
3217
           rn = "WatchHi4";
3218
//         break;
3219
        case 5:
3220
//         gen_op_mfc0_watchhi5();
3221
           rn = "WatchHi5";
3222
//         break;
3223
        case 6:
3224
//         gen_op_mfc0_watchhi6();
3225
           rn = "WatchHi6";
3226
//         break;
3227
        case 7:
3228
//         gen_op_mfc0_watchhi7();
3229
           rn = "WatchHi7";
3230
//         break;
3231
        default:
3232
            goto die;
3233
        }
3234
        break;
3235
    case 20:
3236
        switch (sel) {
3237
        case 0:
3238
           /* 64 bit MMU only */
3239
           gen_op_dmfc0_xcontext();
3240
           rn = "XContext";
3241
           break;
3242
        default:
3243
            goto die;
3244
        }
3245
        break;
3246
    case 21:
3247
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3248
        switch (sel) {
3249
        case 0:
3250
           gen_op_mfc0_framemask();
3251
           rn = "Framemask";
3252
           break;
3253
        default:
3254
            goto die;
3255
        }
3256
        break;
3257
    case 22:
3258
       /* ignored */
3259
       rn = "'Diagnostic"; /* implementation dependent */
3260
       break;
3261
    case 23:
3262
        switch (sel) {
3263
        case 0:
3264
           gen_op_mfc0_debug(); /* EJTAG support */
3265
           rn = "Debug";
3266
           break;
3267
        case 1:
3268
//         gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3269
           rn = "TraceControl";
3270
//         break;
3271
        case 2:
3272
//         gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3273
           rn = "TraceControl2";
3274
//         break;
3275
        case 3:
3276
//         gen_op_dmfc0_usertracedata(); /* PDtrace support */
3277
           rn = "UserTraceData";
3278
//         break;
3279
        case 4:
3280
//         gen_op_dmfc0_debug(); /* PDtrace support */
3281
           rn = "TraceBPC";
3282
//         break;
3283
        default:
3284
            goto die;
3285
        }
3286
        break;
3287
    case 24:
3288
        switch (sel) {
3289
        case 0:
3290
           gen_op_dmfc0_depc(); /* EJTAG support */
3291
           rn = "DEPC";
3292
           break;
3293
        default:
3294
            goto die;
3295
        }
3296
        break;
3297
    case 25:
3298
        switch (sel) {
3299
        case 0:
3300
           gen_op_mfc0_performance0();
3301
           rn = "Performance0";
3302
            break;
3303
        case 1:
3304
//         gen_op_dmfc0_performance1();
3305
           rn = "Performance1";
3306
//         break;
3307
        case 2:
3308
//         gen_op_dmfc0_performance2();
3309
           rn = "Performance2";
3310
//         break;
3311
        case 3:
3312
//         gen_op_dmfc0_performance3();
3313
           rn = "Performance3";
3314
//         break;
3315
        case 4:
3316
//         gen_op_dmfc0_performance4();
3317
           rn = "Performance4";
3318
//         break;
3319
        case 5:
3320
//         gen_op_dmfc0_performance5();
3321
           rn = "Performance5";
3322
//         break;
3323
        case 6:
3324
//         gen_op_dmfc0_performance6();
3325
           rn = "Performance6";
3326
//         break;
3327
        case 7:
3328
//         gen_op_dmfc0_performance7();
3329
           rn = "Performance7";
3330
//         break;
3331
        default:
3332
            goto die;
3333
        }
3334
        break;
3335
    case 26:
3336
       rn = "ECC";
3337
       break;
3338
    case 27:
3339
        switch (sel) {
3340
        /* ignored */
3341
        case 0 ... 3:
3342
           rn = "CacheErr";
3343
           break;
3344
        default:
3345
            goto die;
3346
        }
3347
        break;
3348
    case 28:
3349
        switch (sel) {
3350
        case 0:
3351
        case 2:
3352
        case 4:
3353
        case 6:
3354
            gen_op_mfc0_taglo();
3355
            rn = "TagLo";
3356
            break;
3357
        case 1:
3358
        case 3:
3359
        case 5:
3360
        case 7:
3361
            gen_op_mfc0_datalo();
3362
            rn = "DataLo";
3363
            break;
3364
        default:
3365
            goto die;
3366
        }
3367
        break;
3368
    case 29:
3369
        switch (sel) {
3370
        case 0:
3371
        case 2:
3372
        case 4:
3373
        case 6:
3374
            gen_op_mfc0_taghi();
3375
            rn = "TagHi";
3376
            break;
3377
        case 1:
3378
        case 3:
3379
        case 5:
3380
        case 7:
3381
            gen_op_mfc0_datahi();
3382
            rn = "DataHi";
3383
            break;
3384
        default:
3385
            goto die;
3386
        }
3387
        break;
3388
    case 30:
3389
        switch (sel) {
3390
        case 0:
3391
           gen_op_dmfc0_errorepc();
3392
           rn = "ErrorEPC";
3393
           break;
3394
        default:
3395
            goto die;
3396
        }
3397
        break;
3398
    case 31:
3399
        switch (sel) {
3400
        case 0:
3401
           gen_op_mfc0_desave(); /* EJTAG support */
3402
           rn = "DESAVE";
3403
           break;
3404
        default:
3405
            goto die;
3406
        }
3407
        break;
3408
    default:
3409
        goto die;
3410
    }
3411
#if defined MIPS_DEBUG_DISAS
3412
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3413
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3414
                rn, reg, sel);
3415
    }
3416
#endif
3417
    return;
3418

    
3419
die:
3420
#if defined MIPS_DEBUG_DISAS
3421
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3422
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3423
                rn, reg, sel);
3424
    }
3425
#endif
3426
    generate_exception(ctx, EXCP_RI);
3427
}
3428

    
3429
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3430
{
3431
    const char *rn = "invalid";
3432

    
3433
    switch (reg) {
3434
    case 0:
3435
        switch (sel) {
3436
        case 0:
3437
            gen_op_mtc0_index();
3438
            rn = "Index";
3439
            break;
3440
        case 1:
3441
//         gen_op_dmtc0_mvpcontrol(); /* MT ASE */
3442
            rn = "MVPControl";
3443
//         break;
3444
        case 2:
3445
//         gen_op_dmtc0_mvpconf0(); /* MT ASE */
3446
            rn = "MVPConf0";
3447
//         break;
3448
        case 3:
3449
//         gen_op_dmtc0_mvpconf1(); /* MT ASE */
3450
            rn = "MVPConf1";
3451
//         break;
3452
        default:
3453
            goto die;
3454
        }
3455
        break;
3456
    case 1:
3457
        switch (sel) {
3458
        case 0:
3459
           /* ignored */
3460
            rn = "Random";
3461
           break;
3462
        case 1:
3463
//         gen_op_dmtc0_vpecontrol(); /* MT ASE */
3464
            rn = "VPEControl";
3465
//         break;
3466
        case 2:
3467
//         gen_op_dmtc0_vpeconf0(); /* MT ASE */
3468
            rn = "VPEConf0";
3469
//         break;
3470
        case 3:
3471
//         gen_op_dmtc0_vpeconf1(); /* MT ASE */
3472
            rn = "VPEConf1";
3473
//         break;
3474
        case 4:
3475
//         gen_op_dmtc0_YQMask(); /* MT ASE */
3476
            rn = "YQMask";
3477
//         break;
3478
        case 5:
3479
//         gen_op_dmtc0_vpeschedule(); /* MT ASE */
3480
            rn = "VPESchedule";
3481
//         break;
3482
        case 6:
3483
//         gen_op_dmtc0_vpeschefback(); /* MT ASE */
3484
            rn = "VPEScheFBack";
3485
//         break;
3486
        case 7:
3487
//         gen_op_dmtc0_vpeopt(); /* MT ASE */
3488
            rn = "VPEOpt";
3489
//         break;
3490
        default:
3491
            goto die;
3492
        }
3493
        break;
3494
    case 2:
3495
        switch (sel) {
3496
        case 0:
3497
           gen_op_dmtc0_entrylo0();
3498
           rn = "EntryLo0";
3499
           break;
3500
        case 1:
3501
//         gen_op_dmtc0_tcstatus(); /* MT ASE */
3502
           rn = "TCStatus";
3503
//         break;
3504
        case 2:
3505
//         gen_op_dmtc0_tcbind(); /* MT ASE */
3506
           rn = "TCBind";
3507
//         break;
3508
        case 3:
3509
//         gen_op_dmtc0_tcrestart(); /* MT ASE */
3510
           rn = "TCRestart";
3511
//         break;
3512
        case 4:
3513
//         gen_op_dmtc0_tchalt(); /* MT ASE */
3514
           rn = "TCHalt";
3515
//         break;
3516
        case 5:
3517
//         gen_op_dmtc0_tccontext(); /* MT ASE */
3518
           rn = "TCContext";
3519
//         break;
3520
        case 6:
3521
//         gen_op_dmtc0_tcschedule(); /* MT ASE */
3522
           rn = "TCSchedule";
3523
//         break;
3524
        case 7:
3525
//         gen_op_dmtc0_tcschefback(); /* MT ASE */
3526
           rn = "TCScheFBack";
3527
//         break;
3528
        default:
3529
            goto die;
3530
        }
3531
        break;
3532
    case 3:
3533
        switch (sel) {
3534
        case 0:
3535
           gen_op_dmtc0_entrylo1();
3536
           rn = "EntryLo1";
3537
           break;
3538
        default:
3539
            goto die;
3540
        }
3541
        break;
3542
    case 4:
3543
        switch (sel) {
3544
        case 0:
3545
           gen_op_dmtc0_context();
3546
           rn = "Context";
3547
           break;
3548
        case 1:
3549
//         gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3550
           rn = "ContextConfig";
3551
//         break;
3552
        default:
3553
            goto die;
3554
        }
3555
        break;
3556
    case 5:
3557
        switch (sel) {
3558
        case 0:
3559
           gen_op_mtc0_pagemask();
3560
           rn = "PageMask";
3561
           break;
3562
        case 1:
3563
           gen_op_mtc0_pagegrain();
3564
           rn = "PageGrain";
3565
           break;
3566
        default:
3567
            goto die;
3568
        }
3569
        break;
3570
    case 6:
3571
        switch (sel) {
3572
        case 0:
3573
           gen_op_mtc0_wired();
3574
           rn = "Wired";
3575
           break;
3576
        case 1:
3577
//         gen_op_dmtc0_srsconf0(); /* shadow registers */
3578
           rn = "SRSConf0";
3579
//         break;
3580
        case 2:
3581
//         gen_op_dmtc0_srsconf1(); /* shadow registers */
3582
           rn = "SRSConf1";
3583
//         break;
3584
        case 3:
3585
//         gen_op_dmtc0_srsconf2(); /* shadow registers */
3586
           rn = "SRSConf2";
3587
//         break;
3588
        case 4:
3589
//         gen_op_dmtc0_srsconf3(); /* shadow registers */
3590
           rn = "SRSConf3";
3591
//         break;
3592
        case 5:
3593
//         gen_op_dmtc0_srsconf4(); /* shadow registers */
3594
           rn = "SRSConf4";
3595
//         break;
3596
        default:
3597
            goto die;
3598
        }
3599
        break;
3600
    case 7:
3601
        switch (sel) {
3602
        case 0:
3603
           gen_op_mtc0_hwrena();
3604
           rn = "HWREna";
3605
           break;
3606
        default:
3607
            goto die;
3608
        }
3609
        break;
3610
    case 8:
3611
        /* ignored */
3612
        rn = "BadVaddr";
3613
        break;
3614
    case 9:
3615
        switch (sel) {
3616
        case 0:
3617
           gen_op_mtc0_count();
3618
           rn = "Count";
3619
           break;
3620
        /* 6,7 are implementation dependent */
3621
        default:
3622
            goto die;
3623
        }
3624
        /* Stop translation as we may have switched the execution mode */
3625
        ctx->bstate = BS_STOP;
3626
        break;
3627
    case 10:
3628
        switch (sel) {
3629
        case 0:
3630
           gen_op_mtc0_entryhi();
3631
           rn = "EntryHi";
3632
           break;
3633
        default:
3634
            goto die;
3635
        }
3636
        break;
3637
    case 11:
3638
        switch (sel) {
3639
        case 0:
3640
           gen_op_mtc0_compare();
3641
           rn = "Compare";
3642
           break;
3643
        /* 6,7 are implementation dependent */
3644
        default:
3645
            goto die;
3646
        }
3647
        /* Stop translation as we may have switched the execution mode */
3648
        ctx->bstate = BS_STOP;
3649
        break;
3650
    case 12:
3651
        switch (sel) {
3652
        case 0:
3653
           gen_op_mtc0_status();
3654
           rn = "Status";
3655
           break;
3656
        case 1:
3657
           gen_op_mtc0_intctl();
3658
           rn = "IntCtl";
3659
           break;
3660
        case 2:
3661
           gen_op_mtc0_srsctl();
3662
           rn = "SRSCtl";
3663
           break;
3664
        case 3:
3665
         gen_op_mtc0_srsmap(); /* shadow registers */
3666
           rn = "SRSMap";
3667
         break;
3668
         default:
3669
            goto die;
3670
        }
3671
        /* Stop translation as we may have switched the execution mode */
3672
        ctx->bstate = BS_STOP;
3673
        break;
3674
    case 13:
3675
        switch (sel) {
3676
        case 0:
3677
           gen_op_mtc0_cause();
3678
           rn = "Cause";
3679
           break;
3680
        default:
3681
            goto die;
3682
        }
3683
        /* Stop translation as we may have switched the execution mode */
3684
        ctx->bstate = BS_STOP;
3685
        break;
3686
    case 14:
3687
        switch (sel) {
3688
        case 0:
3689
           gen_op_dmtc0_epc();
3690
           rn = "EPC";
3691
           break;
3692
        default:
3693
            goto die;
3694
        }
3695
        break;
3696
    case 15:
3697
        switch (sel) {
3698
        case 0:
3699
           /* ignored */
3700
           rn = "PRid";
3701
           break;
3702
        case 1:
3703
           gen_op_mtc0_ebase();
3704
           rn = "EBase";
3705
           break;
3706
        default:
3707
            goto die;
3708
        }
3709
        break;
3710
    case 16:
3711
        switch (sel) {
3712
        case 0:
3713
            gen_op_mtc0_config0();
3714
            rn = "Config";
3715
            break;
3716
        case 1:
3717
           /* ignored */
3718
            rn = "Config1";
3719
            break;
3720
        case 2:
3721
            gen_op_mtc0_config2();
3722
            rn = "Config2";
3723
            break;
3724
        case 3:
3725
           /* ignored */
3726
            rn = "Config3";
3727
            break;
3728
        /* 6,7 are implementation dependent */
3729
        default:
3730
            rn = "Invalid config selector";
3731
            goto die;
3732
        }
3733
        /* Stop translation as we may have switched the execution mode */
3734
        ctx->bstate = BS_STOP;
3735
        break;
3736
    case 17:
3737
        switch (sel) {
3738
        case 0:
3739
           /* ignored */
3740
           rn = "LLAddr";
3741
           break;
3742
        default:
3743
            goto die;
3744
        }
3745
        break;
3746
    case 18:
3747
        switch (sel) {
3748
        case 0:
3749
           gen_op_dmtc0_watchlo0();
3750
           rn = "WatchLo";
3751
           break;
3752
        case 1:
3753
//         gen_op_dmtc0_watchlo1();
3754
           rn = "WatchLo1";
3755
//         break;
3756
        case 2:
3757
//         gen_op_dmtc0_watchlo2();
3758
           rn = "WatchLo2";
3759
//         break;
3760
        case 3:
3761
//         gen_op_dmtc0_watchlo3();
3762
           rn = "WatchLo3";
3763
//         break;
3764
        case 4:
3765
//         gen_op_dmtc0_watchlo4();
3766
           rn = "WatchLo4";
3767
//         break;
3768
        case 5:
3769
//         gen_op_dmtc0_watchlo5();
3770
           rn = "WatchLo5";
3771
//         break;
3772
        case 6:
3773
//         gen_op_dmtc0_watchlo6();
3774
           rn = "WatchLo6";
3775
//         break;
3776
        case 7:
3777
//         gen_op_dmtc0_watchlo7();
3778
           rn = "WatchLo7";
3779
//         break;
3780
        default:
3781
            goto die;
3782
        }
3783
        break;
3784
    case 19:
3785
        switch (sel) {
3786
        case 0:
3787
           gen_op_mtc0_watchhi0();
3788
           rn = "WatchHi";
3789
           break;
3790
        case 1:
3791
//         gen_op_dmtc0_watchhi1();
3792
           rn = "WatchHi1";
3793
//         break;
3794
        case 2:
3795
//         gen_op_dmtc0_watchhi2();
3796
           rn = "WatchHi2";
3797
//         break;
3798
        case 3:
3799
//         gen_op_dmtc0_watchhi3();
3800
           rn = "WatchHi3";
3801
//         break;
3802
        case 4:
3803
//         gen_op_dmtc0_watchhi4();
3804
           rn = "WatchHi4";
3805
//         break;
3806
        case 5:
3807
//         gen_op_dmtc0_watchhi5();
3808
           rn = "WatchHi5";
3809
//         break;
3810
        case 6:
3811
//         gen_op_dmtc0_watchhi6();
3812
           rn = "WatchHi6";
3813
//         break;
3814
        case 7:
3815
//         gen_op_dmtc0_watchhi7();
3816
           rn = "WatchHi7";
3817
//         break;
3818
        default:
3819
            goto die;
3820
        }
3821
        break;
3822
    case 20:
3823
        switch (sel) {
3824
        case 0:
3825
           /* 64 bit MMU only */
3826
           gen_op_dmtc0_xcontext();
3827
           rn = "XContext";
3828
           break;
3829
        default:
3830
            goto die;
3831
        }
3832
        break;
3833
    case 21:
3834
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3835
        switch (sel) {
3836
        case 0:
3837
           gen_op_mtc0_framemask();
3838
           rn = "Framemask";
3839
           break;
3840
        default:
3841
            goto die;
3842
        }
3843
        break;
3844
    case 22:
3845
        /* ignored */
3846
        rn = "Diagnostic"; /* implementation dependent */
3847
        break;
3848
    case 23:
3849
        switch (sel) {
3850
        case 0:
3851
           gen_op_mtc0_debug(); /* EJTAG support */
3852
           rn = "Debug";
3853
           break;
3854
        case 1:
3855
//         gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3856
           rn = "TraceControl";
3857
//         break;
3858
        case 2:
3859
//         gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3860
           rn = "TraceControl2";
3861
//         break;
3862
        case 3:
3863
//         gen_op_dmtc0_usertracedata(); /* PDtrace support */
3864
           rn = "UserTraceData";
3865
//         break;
3866
        case 4:
3867
//         gen_op_dmtc0_debug(); /* PDtrace support */
3868
           rn = "TraceBPC";
3869
//         break;
3870
        default:
3871
            goto die;
3872
        }
3873
       /* Stop translation as we may have switched the execution mode */
3874
       ctx->bstate = BS_STOP;
3875
        break;
3876
    case 24:
3877
        switch (sel) {
3878
        case 0:
3879
           gen_op_dmtc0_depc(); /* EJTAG support */
3880
           rn = "DEPC";
3881
           break;
3882
        default:
3883
            goto die;
3884
        }
3885
        break;
3886
    case 25:
3887
        switch (sel) {
3888
        case 0:
3889
           gen_op_mtc0_performance0();
3890
           rn = "Performance0";
3891
           break;
3892
        case 1:
3893
//         gen_op_dmtc0_performance1();
3894
           rn = "Performance1";
3895
//         break;
3896
        case 2:
3897
//         gen_op_dmtc0_performance2();
3898
           rn = "Performance2";
3899
//         break;
3900
        case 3:
3901
//         gen_op_dmtc0_performance3();
3902
           rn = "Performance3";
3903
//         break;
3904
        case 4:
3905
//         gen_op_dmtc0_performance4();
3906
           rn = "Performance4";
3907
//         break;
3908
        case 5:
3909
//         gen_op_dmtc0_performance5();
3910
           rn = "Performance5";
3911
//         break;
3912
        case 6:
3913
//         gen_op_dmtc0_performance6();
3914
           rn = "Performance6";
3915
//         break;
3916
        case 7:
3917
//         gen_op_dmtc0_performance7();
3918
           rn = "Performance7";
3919
//         break;
3920
        default:
3921
            goto die;
3922
        }
3923
        break;
3924
    case 26:
3925
        /* ignored */
3926
        rn = "ECC";
3927
        break;
3928
    case 27:
3929
        switch (sel) {
3930
        case 0 ... 3:
3931
           /* ignored */
3932
           rn = "CacheErr";
3933
           break;
3934
        default:
3935
            goto die;
3936
        }
3937
        break;
3938
    case 28:
3939
        switch (sel) {
3940
        case 0:
3941
        case 2:
3942
        case 4:
3943
        case 6:
3944
            gen_op_mtc0_taglo();
3945
            rn = "TagLo";
3946
            break;
3947
        case 1:
3948
        case 3:
3949
        case 5:
3950
        case 7:
3951
           gen_op_mtc0_datalo();
3952
            rn = "DataLo";
3953
            break;
3954
        default:
3955
            goto die;
3956
        }
3957
        break;
3958
    case 29:
3959
        switch (sel) {
3960
        case 0:
3961
        case 2:
3962
        case 4:
3963
        case 6:
3964
            gen_op_mtc0_taghi();
3965
            rn = "TagHi";
3966
            break;
3967
        case 1:
3968
        case 3:
3969
        case 5:
3970
        case 7:
3971
           gen_op_mtc0_datahi();
3972
            rn = "DataHi";
3973
            break;
3974
        default:
3975
            rn = "invalid sel";
3976
            goto die;
3977
        }
3978
        break;
3979
    case 30:
3980
        switch (sel) {
3981
        case 0:
3982
           gen_op_dmtc0_errorepc();
3983
           rn = "ErrorEPC";
3984
           break;
3985
        default:
3986
            goto die;
3987
        }
3988
        break;
3989
    case 31:
3990
        switch (sel) {
3991
        case 0:
3992
           gen_op_mtc0_desave(); /* EJTAG support */
3993
           rn = "DESAVE";
3994
           break;
3995
        default:
3996
            goto die;
3997
        }
3998
        /* Stop translation as we may have switched the execution mode */
3999
        ctx->bstate = BS_STOP;
4000
        break;
4001
    default:
4002
        goto die;
4003
    }
4004
#if defined MIPS_DEBUG_DISAS
4005
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4006
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4007
                rn, reg, sel);
4008
    }
4009
#endif
4010
    return;
4011

    
4012
die:
4013
#if defined MIPS_DEBUG_DISAS
4014
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4015
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4016
                rn, reg, sel);
4017
    }
4018
#endif
4019
    generate_exception(ctx, EXCP_RI);
4020
}
4021

    
4022
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4023
{
4024
    const char *opn = "unk";
4025

    
4026
    switch (opc) {
4027
    case OPC_MFC0:
4028
        if (rt == 0) {
4029
            /* Treat as NOP */
4030
            return;
4031
        }
4032
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4033
        gen_op_store_T0_gpr(rt);
4034
        opn = "mfc0";
4035
        break;
4036
    case OPC_MTC0:
4037
        /* If we get an exception, we want to restart at next instruction */
4038
        /* XXX: breaks for mtc in delay slot */
4039
        ctx->pc += 4;
4040
        save_cpu_state(ctx, 1);
4041
        ctx->pc -= 4;
4042
        GEN_LOAD_REG_TN(T0, rt);
4043
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4044
        opn = "mtc0";
4045
        break;
4046
    case OPC_DMFC0:
4047
        if (rt == 0) {
4048
            /* Treat as NOP */
4049
            return;
4050
        }
4051
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4052
        gen_op_store_T0_gpr(rt);
4053
        opn = "dmfc0";
4054
        break;
4055
    case OPC_DMTC0:
4056
        /* If we get an exception, we want to restart at next instruction */
4057
        /* XXX: breaks for dmtc in delay slot */
4058
        ctx->pc += 4;
4059
        save_cpu_state(ctx, 1);
4060
        ctx->pc -= 4;
4061
        GEN_LOAD_REG_TN(T0, rt);
4062
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4063
        opn = "dmtc0";
4064
        break;
4065
#if defined(MIPS_USES_R4K_TLB)
4066
    case OPC_TLBWI:
4067
        gen_op_tlbwi();
4068
        opn = "tlbwi";
4069
        break;
4070
    case OPC_TLBWR:
4071
        gen_op_tlbwr();
4072
        opn = "tlbwr";
4073
        break;
4074
    case OPC_TLBP:
4075
        gen_op_tlbp();
4076
        opn = "tlbp";
4077
        break;
4078
    case OPC_TLBR:
4079
        gen_op_tlbr();
4080
        opn = "tlbr";
4081
        break;
4082
#endif
4083
    case OPC_ERET:
4084
        opn = "eret";
4085
        save_cpu_state(ctx, 0);
4086
        gen_op_eret();
4087
        ctx->bstate = BS_EXCP;
4088
        break;
4089
    case OPC_DERET:
4090
        opn = "deret";
4091
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4092
            generate_exception(ctx, EXCP_RI);
4093
        } else {
4094
            save_cpu_state(ctx, 0);
4095
            gen_op_deret();
4096
            ctx->bstate = BS_EXCP;
4097
        }
4098
        break;
4099
    case OPC_WAIT:
4100
        opn = "wait";
4101
        /* If we get an exception, we want to restart at next instruction */
4102
        ctx->pc += 4;
4103
        save_cpu_state(ctx, 1);
4104
        ctx->pc -= 4;
4105
        gen_op_wait();
4106
        ctx->bstate = BS_EXCP;
4107
        break;
4108
    default:
4109
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4110
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4111
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4112
                    ((ctx->opcode >> 16) & 0x1F));
4113
        }
4114
        generate_exception(ctx, EXCP_RI);
4115
        return;
4116
    }
4117
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4118
}
4119

    
4120
/* CP1 Branches (before delay slot) */
4121
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4122
                                 int32_t offset)
4123
{
4124
    target_ulong btarget;
4125

    
4126
    btarget = ctx->pc + 4 + offset;
4127

    
4128
    switch (op) {
4129
    case OPC_BC1F:
4130
        gen_op_bc1f();
4131
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4132
        goto not_likely;
4133
    case OPC_BC1FL:
4134
        gen_op_bc1f();
4135
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4136
        goto likely;
4137
    case OPC_BC1T:
4138
        gen_op_bc1t();
4139
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4140
    not_likely:
4141
        ctx->hflags |= MIPS_HFLAG_BC;
4142
        break;
4143
    case OPC_BC1TL:
4144
        gen_op_bc1t();
4145
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4146
    likely:
4147
        ctx->hflags |= MIPS_HFLAG_BL;
4148
        break;
4149
    default:    
4150
        MIPS_INVAL("cp1 branch/jump");
4151
        generate_exception (ctx, EXCP_RI);
4152
        return;
4153
    }
4154
    gen_op_set_bcond();
4155

    
4156
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4157
               ctx->hflags, btarget);
4158
    ctx->btarget = btarget;
4159

    
4160
    return;
4161
}
4162

    
4163
/* Coprocessor 1 (FPU) */
4164
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4165
{
4166
    const char *opn = "unk";
4167

    
4168
    switch (opc) {
4169
    case OPC_MFC1:
4170
        GEN_LOAD_FREG_FTN(WT0, fs);
4171
        gen_op_mfc1();
4172
        GEN_STORE_TN_REG(rt, T0);
4173
        opn = "mfc1";
4174
        break;
4175
    case OPC_MTC1:
4176
        GEN_LOAD_REG_TN(T0, rt);
4177
        gen_op_mtc1();
4178
        GEN_STORE_FTN_FREG(fs, WT0);
4179
        opn = "mtc1";
4180
        break;
4181
    case OPC_CFC1:
4182
        if (fs != 0 && fs != 31) {
4183
            MIPS_INVAL("cfc1 freg");
4184
            generate_exception (ctx, EXCP_RI);
4185
            return;
4186
        }
4187
        GEN_LOAD_IMM_TN(T1, fs);
4188
        gen_op_cfc1();
4189
        GEN_STORE_TN_REG(rt, T0);
4190
        opn = "cfc1";
4191
        break;
4192
    case OPC_CTC1:
4193
         if (fs != 0 && fs != 31) {
4194
            MIPS_INVAL("ctc1 freg");
4195
            generate_exception (ctx, EXCP_RI);
4196
            return;
4197
        }
4198
        GEN_LOAD_IMM_TN(T1, fs);
4199
        GEN_LOAD_REG_TN(T0, rt);
4200
        gen_op_ctc1();
4201
        opn = "ctc1";
4202
        break;
4203
    case OPC_DMFC1:
4204
    case OPC_DMTC1:
4205
        /* Not implemented, fallthrough. */
4206
    default:
4207
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4208
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4209
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4210
                    ((ctx->opcode >> 16) & 0x1F));
4211
        }
4212
        generate_exception (ctx, EXCP_RI);
4213
        return;
4214
    }
4215
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4216
}
4217

    
4218
/* verify if floating point register is valid; an operation is not defined
4219
 * if bit 0 of any register specification is set and the FR bit in the
4220
 * Status register equals zero, since the register numbers specify an
4221
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4222
 * in the Status register equals one, both even and odd register numbers
4223
 * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4224
 * 
4225
 * Multiple 64 bit wide registers can be checked by calling
4226
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4227
 */
4228
#define CHECK_FR(ctx, freg) do { \
4229
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4230
            generate_exception (ctx, EXCP_RI); \
4231
            return; \
4232
        } \
4233
    } while(0)
4234

    
4235
#define FOP(func, fmt) (((fmt) << 21) | (func))
4236

    
4237
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4238
{
4239
    const char *opn = "unk";
4240
    const char *condnames[] = {
4241
            "c.f",
4242
            "c.un",
4243
            "c.eq",
4244
            "c.ueq",
4245
            "c.olt",
4246
            "c.ult",
4247
            "c.ole",
4248
            "c.ule",
4249
            "c.sf",
4250
            "c.ngle",
4251
            "c.seq",
4252
            "c.ngl",
4253
            "c.lt",
4254
            "c.nge",
4255
            "c.le",
4256
            "c.ngt",
4257
    };
4258
    int binary = 0;
4259
    uint32_t func = ctx->opcode & 0x3f;
4260

    
4261
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4262
    case FOP(0, 17):
4263
        CHECK_FR(ctx, fs | ft | fd);
4264
        GEN_LOAD_FREG_FTN(DT0, fs);
4265
        GEN_LOAD_FREG_FTN(DT1, ft);
4266
        gen_op_float_add_d();
4267
        GEN_STORE_FTN_FREG(fd, DT2);
4268
        opn = "add.d";
4269
        binary = 1;
4270
        break;
4271
    case FOP(1, 17):
4272
        CHECK_FR(ctx, fs | ft | fd);
4273
        GEN_LOAD_FREG_FTN(DT0, fs);
4274
        GEN_LOAD_FREG_FTN(DT1, ft);
4275
        gen_op_float_sub_d();
4276
        GEN_STORE_FTN_FREG(fd, DT2);
4277
        opn = "sub.d";
4278
        binary = 1;
4279
        break;
4280
    case FOP(2, 17):
4281
        CHECK_FR(ctx, fs | ft | fd);
4282
        GEN_LOAD_FREG_FTN(DT0, fs);
4283
        GEN_LOAD_FREG_FTN(DT1, ft);
4284
        gen_op_float_mul_d();
4285
        GEN_STORE_FTN_FREG(fd, DT2);
4286
        opn = "mul.d";
4287
        binary = 1;
4288
        break;
4289
    case FOP(3, 17):
4290
        CHECK_FR(ctx, fs | ft | fd);
4291
        GEN_LOAD_FREG_FTN(DT0, fs);
4292
        GEN_LOAD_FREG_FTN(DT1, ft);
4293
        gen_op_float_div_d();
4294
        GEN_STORE_FTN_FREG(fd, DT2);
4295
        opn = "div.d";
4296
        binary = 1;
4297
        break;
4298
    case FOP(4, 17):
4299
        CHECK_FR(ctx, fs | fd);
4300
        GEN_LOAD_FREG_FTN(DT0, fs);
4301
        gen_op_float_sqrt_d();
4302
        GEN_STORE_FTN_FREG(fd, DT2);
4303
        opn = "sqrt.d";
4304
        break;
4305
    case FOP(5, 17):
4306
        CHECK_FR(ctx, fs | fd);
4307
        GEN_LOAD_FREG_FTN(DT0, fs);
4308
        gen_op_float_abs_d();
4309
        GEN_STORE_FTN_FREG(fd, DT2);
4310
        opn = "abs.d";
4311
        break;
4312
    case FOP(6, 17):
4313
        CHECK_FR(ctx, fs | fd);
4314
        GEN_LOAD_FREG_FTN(DT0, fs);
4315
        gen_op_float_mov_d();
4316
        GEN_STORE_FTN_FREG(fd, DT2);
4317
        opn = "mov.d";
4318
        break;
4319
    case FOP(7, 17):
4320
        CHECK_FR(ctx, fs | fd);
4321
        GEN_LOAD_FREG_FTN(DT0, fs);
4322
        gen_op_float_chs_d();
4323
        GEN_STORE_FTN_FREG(fd, DT2);
4324
        opn = "neg.d";
4325
        break;
4326
    /*  8 - round.l */
4327
    /*  9 - trunc.l */
4328
    /* 10 - ceil.l  */
4329
    /* 11 - floor.l */
4330
    case FOP(12, 17):
4331
        CHECK_FR(ctx, fs);
4332
        GEN_LOAD_FREG_FTN(DT0, fs);
4333
        gen_op_float_roundw_d();
4334
        GEN_STORE_FTN_FREG(fd, WT2);
4335
        opn = "round.w.d";
4336
        break;
4337
    case FOP(13, 17):
4338
        CHECK_FR(ctx, fs);
4339
        GEN_LOAD_FREG_FTN(DT0, fs);
4340
        gen_op_float_truncw_d();
4341
        GEN_STORE_FTN_FREG(fd, WT2);
4342
        opn = "trunc.w.d";
4343
        break;
4344
    case FOP(14, 17):
4345
        CHECK_FR(ctx, fs);
4346
        GEN_LOAD_FREG_FTN(DT0, fs);
4347
        gen_op_float_ceilw_d();
4348
        GEN_STORE_FTN_FREG(fd, WT2);
4349
        opn = "ceil.w.d";
4350
        break;
4351
    case FOP(15, 17):
4352
        CHECK_FR(ctx, fs);
4353
        GEN_LOAD_FREG_FTN(DT0, fs);
4354
        gen_op_float_floorw_d();
4355
        GEN_STORE_FTN_FREG(fd, WT2);
4356
        opn = "floor.w.d";
4357
        break;
4358
    case FOP(33, 16):
4359
        CHECK_FR(ctx, fd);
4360
        GEN_LOAD_FREG_FTN(WT0, fs);
4361
        gen_op_float_cvtd_s();
4362
        GEN_STORE_FTN_FREG(fd, DT2);
4363
        opn = "cvt.d.s";
4364
        break;
4365
    case FOP(33, 20):
4366
        CHECK_FR(ctx, fd);
4367
        GEN_LOAD_FREG_FTN(WT0, fs);
4368
        gen_op_float_cvtd_w();
4369
        GEN_STORE_FTN_FREG(fd, DT2);
4370
        opn = "cvt.d.w";
4371
        break;
4372
    case FOP(48, 17):
4373
    case FOP(49, 17):
4374
    case FOP(50, 17):
4375
    case FOP(51, 17):
4376
    case FOP(52, 17):
4377
    case FOP(53, 17):
4378
    case FOP(54, 17):
4379
    case FOP(55, 17):
4380
    case FOP(56, 17):
4381
    case FOP(57, 17):
4382
    case FOP(58, 17):
4383
    case FOP(59, 17):
4384
    case FOP(60, 17):
4385
    case FOP(61, 17):
4386
    case FOP(62, 17):
4387
    case FOP(63, 17):
4388
        CHECK_FR(ctx, fs | ft);
4389
        GEN_LOAD_FREG_FTN(DT0, fs);
4390
        GEN_LOAD_FREG_FTN(DT1, ft);
4391
        gen_cmp_d(func-48);
4392
        opn = condnames[func-48];
4393
        break;
4394
    case FOP(0, 16):
4395
        GEN_LOAD_FREG_FTN(WT0, fs);
4396
        GEN_LOAD_FREG_FTN(WT1, ft);
4397
        gen_op_float_add_s();
4398
        GEN_STORE_FTN_FREG(fd, WT2);
4399
        opn = "add.s";
4400
        binary = 1;
4401
        break;
4402
    case FOP(1, 16):
4403
        GEN_LOAD_FREG_FTN(WT0, fs);
4404
        GEN_LOAD_FREG_FTN(WT1, ft);
4405
        gen_op_float_sub_s();
4406
        GEN_STORE_FTN_FREG(fd, WT2);
4407
        opn = "sub.s";
4408
        binary = 1;
4409
        break;
4410
    case FOP(2, 16):
4411
        GEN_LOAD_FREG_FTN(WT0, fs);
4412
        GEN_LOAD_FREG_FTN(WT1, ft);
4413
        gen_op_float_mul_s();
4414
        GEN_STORE_FTN_FREG(fd, WT2);
4415
        opn = "mul.s";
4416
        binary = 1;
4417
        break;
4418
    case FOP(3, 16):
4419
        GEN_LOAD_FREG_FTN(WT0, fs);
4420
        GEN_LOAD_FREG_FTN(WT1, ft);
4421
        gen_op_float_div_s();
4422
        GEN_STORE_FTN_FREG(fd, WT2);
4423
        opn = "div.s";
4424
        binary = 1;
4425
        break;
4426
    case FOP(4, 16):
4427
        GEN_LOAD_FREG_FTN(WT0, fs);
4428
        gen_op_float_sqrt_s();
4429
        GEN_STORE_FTN_FREG(fd, WT2);
4430
        opn = "sqrt.s";
4431
        break;
4432
    case FOP(5, 16):
4433
        GEN_LOAD_FREG_FTN(WT0, fs);
4434
        gen_op_float_abs_s();
4435
        GEN_STORE_FTN_FREG(fd, WT2);
4436
        opn = "abs.s";
4437
        break;
4438
    case FOP(6, 16):
4439
        GEN_LOAD_FREG_FTN(WT0, fs);
4440
        gen_op_float_mov_s();
4441
        GEN_STORE_FTN_FREG(fd, WT2);
4442
        opn = "mov.s";
4443
        break;
4444
    case FOP(7, 16):
4445
        GEN_LOAD_FREG_FTN(WT0, fs);
4446
        gen_op_float_chs_s();
4447
        GEN_STORE_FTN_FREG(fd, WT2);
4448
        opn = "neg.s";
4449
        break;
4450
    case FOP(12, 16):
4451
        GEN_LOAD_FREG_FTN(WT0, fs);
4452
        gen_op_float_roundw_s();
4453
        GEN_STORE_FTN_FREG(fd, WT2);
4454
        opn = "round.w.s";
4455
        break;
4456
    case FOP(13, 16):
4457
        GEN_LOAD_FREG_FTN(WT0, fs);
4458
        gen_op_float_truncw_s();
4459
        GEN_STORE_FTN_FREG(fd, WT2);
4460
        opn = "trunc.w.s";
4461
        break;
4462
    case FOP(32, 17):
4463
        CHECK_FR(ctx, fs);
4464
        GEN_LOAD_FREG_FTN(DT0, fs);
4465
        gen_op_float_cvts_d();
4466
        GEN_STORE_FTN_FREG(fd, WT2);
4467
        opn = "cvt.s.d";
4468
        break;
4469
    case FOP(32, 20):
4470
        GEN_LOAD_FREG_FTN(WT0, fs);
4471
        gen_op_float_cvts_w();
4472
        GEN_STORE_FTN_FREG(fd, WT2);
4473
        opn = "cvt.s.w";
4474
        break;
4475
    case FOP(36, 16):
4476
        GEN_LOAD_FREG_FTN(WT0, fs);
4477
        gen_op_float_cvtw_s();
4478
        GEN_STORE_FTN_FREG(fd, WT2);
4479
        opn = "cvt.w.s";
4480
        break;
4481
    case FOP(36, 17):
4482
        CHECK_FR(ctx, fs);
4483
        GEN_LOAD_FREG_FTN(DT0, fs);
4484
        gen_op_float_cvtw_d();
4485
        GEN_STORE_FTN_FREG(fd, WT2);
4486
        opn = "cvt.w.d";
4487
        break;
4488
    case FOP(48, 16):
4489
    case FOP(49, 16):
4490
    case FOP(50, 16):
4491
    case FOP(51, 16):
4492
    case FOP(52, 16):
4493
    case FOP(53, 16):
4494
    case FOP(54, 16):
4495
    case FOP(55, 16):
4496
    case FOP(56, 16):
4497
    case FOP(57, 16):
4498
    case FOP(58, 16):
4499
    case FOP(59, 16):
4500
    case FOP(60, 16):
4501
    case FOP(61, 16):
4502
    case FOP(62, 16):
4503
    case FOP(63, 16):
4504
        GEN_LOAD_FREG_FTN(WT0, fs);
4505
        GEN_LOAD_FREG_FTN(WT1, ft);
4506
        gen_cmp_s(func-48);
4507
        opn = condnames[func-48];
4508
        break;
4509
    default:    
4510
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4511
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
4512
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4513
                    ((ctx->opcode >> 16) & 0x1F));
4514
        }
4515
        generate_exception (ctx, EXCP_RI);
4516
        return;
4517
    }
4518
    if (binary)
4519
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
4520
    else
4521
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
4522
}
4523

    
4524
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4525
{
4526
    uint32_t ccbit;
4527

    
4528
    if (cc)
4529
        ccbit = 1 << (24 + cc);
4530
    else
4531
        ccbit = 1 << 23;
4532
    if (!tf)
4533
        gen_op_movf(ccbit, rd, rs);
4534
    else
4535
       gen_op_movt(ccbit, rd, rs);
4536
}
4537

    
4538
/* ISA extensions (ASEs) */
4539
/* MIPS16 extension to MIPS32 */
4540
/* SmartMIPS extension to MIPS32 */
4541

    
4542
#ifdef TARGET_MIPS64
4543
/* Coprocessor 3 (FPU) */
4544

    
4545
/* MDMX extension to MIPS64 */
4546
/* MIPS-3D extension to MIPS64 */
4547

    
4548
#endif
4549

    
4550
static void gen_blikely(DisasContext *ctx)
4551
{
4552
    int l1;
4553
    l1 = gen_new_label();
4554
    gen_op_jnz_T2(l1);
4555
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4556
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4557
    gen_set_label(l1);
4558
}
4559

    
4560
static void decode_opc (CPUState *env, DisasContext *ctx)
4561
{
4562
    int32_t offset;
4563
    int rs, rt, rd, sa;
4564
    uint32_t op, op1, op2;
4565
    int16_t imm;
4566

    
4567
    /* make sure instructions are on a word boundary */
4568
    if (ctx->pc & 0x3) {
4569
        generate_exception(ctx, EXCP_AdEL);
4570
        return;
4571
    }
4572

    
4573
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4574
        /* Handle blikely not taken case */
4575
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4576
        gen_blikely(ctx);
4577
    }
4578
    op = MASK_OP_MAJOR(ctx->opcode);
4579
    rs = (ctx->opcode >> 21) & 0x1f;
4580
    rt = (ctx->opcode >> 16) & 0x1f;
4581
    rd = (ctx->opcode >> 11) & 0x1f;
4582
    sa = (ctx->opcode >> 6) & 0x1f;
4583
    imm = (int16_t)ctx->opcode;
4584
    switch (op) {
4585
    case OPC_SPECIAL:
4586
        op1 = MASK_SPECIAL(ctx->opcode);
4587
        switch (op1) {
4588
        case OPC_SLL:          /* Arithmetic with immediate */
4589
        case OPC_SRL ... OPC_SRA:
4590
            gen_arith_imm(ctx, op1, rd, rt, sa);
4591
            break;
4592
        case OPC_SLLV:         /* Arithmetic */
4593
        case OPC_SRLV ... OPC_SRAV:
4594
        case OPC_MOVZ ... OPC_MOVN:
4595
        case OPC_ADD ... OPC_NOR:
4596
        case OPC_SLT ... OPC_SLTU:
4597
            gen_arith(ctx, op1, rd, rs, rt);
4598
            break;
4599
        case OPC_MULT ... OPC_DIVU:
4600
            gen_muldiv(ctx, op1, rs, rt);
4601
            break;
4602
        case OPC_JR ... OPC_JALR:
4603
            gen_compute_branch(ctx, op1, rs, rd, sa);
4604
            return;
4605
        case OPC_TGE ... OPC_TEQ: /* Traps */
4606
        case OPC_TNE:
4607
            gen_trap(ctx, op1, rs, rt, -1);
4608
            break;
4609
        case OPC_MFHI:          /* Move from HI/LO */
4610
        case OPC_MFLO:
4611
            gen_HILO(ctx, op1, rd);
4612
            break;
4613
        case OPC_MTHI:
4614
        case OPC_MTLO:          /* Move to HI/LO */
4615
            gen_HILO(ctx, op1, rs);
4616
            break;
4617
        case OPC_PMON:          /* Pmon entry point */
4618
            gen_op_pmon(sa);
4619
            break;
4620
        case OPC_SYSCALL:
4621
            generate_exception(ctx, EXCP_SYSCALL);
4622
            ctx->bstate = BS_EXCP;
4623
            break;
4624
        case OPC_BREAK:
4625
            generate_exception(ctx, EXCP_BREAK);
4626
            break;
4627
        case OPC_SPIM:        /* SPIM ? */
4628
           /* Implemented as RI exception for now. */
4629
            MIPS_INVAL("spim (unofficial)");
4630
            generate_exception(ctx, EXCP_RI);
4631
            break;
4632
        case OPC_SYNC:
4633
            /* Treat as a noop. */
4634
            break;
4635

    
4636
        case OPC_MOVCI:
4637
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4638
                save_cpu_state(ctx, 1);
4639
                gen_op_cp1_enabled();
4640
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4641
                          (ctx->opcode >> 16) & 1);
4642
            } else {
4643
                generate_exception_err(ctx, EXCP_CpU, 1);
4644
            }
4645
            break;
4646

    
4647
#ifdef TARGET_MIPS64
4648
       /* MIPS64 specific opcodes */
4649
        case OPC_DSLL:
4650
        case OPC_DSRL ... OPC_DSRA:
4651
        case OPC_DSLL32:
4652
        case OPC_DSRL32 ... OPC_DSRA32:
4653
            gen_arith_imm(ctx, op1, rd, rt, sa);
4654
            break;
4655
        case OPC_DSLLV:
4656
        case OPC_DSRLV ... OPC_DSRAV:
4657
        case OPC_DADD ... OPC_DSUBU:
4658
            gen_arith(ctx, op1, rd, rs, rt);
4659
            break;
4660
        case OPC_DMULT ... OPC_DDIVU:
4661
            gen_muldiv(ctx, op1, rs, rt);
4662
            break;
4663
#endif
4664
        default:            /* Invalid */
4665
            MIPS_INVAL("special");
4666
            generate_exception(ctx, EXCP_RI);
4667
            break;
4668
        }
4669
        break;
4670
    case OPC_SPECIAL2:
4671
        op1 = MASK_SPECIAL2(ctx->opcode);
4672
        switch (op1) {
4673
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
4674
        case OPC_MSUB ... OPC_MSUBU:
4675
            gen_muldiv(ctx, op1, rs, rt);
4676
            break;
4677
        case OPC_MUL:
4678
            gen_arith(ctx, op1, rd, rs, rt);
4679
            break;
4680
        case OPC_CLZ ... OPC_CLO:
4681
            gen_cl(ctx, op1, rd, rs);
4682
            break;
4683
        case OPC_SDBBP:
4684
            /* XXX: not clear which exception should be raised
4685
             *      when in debug mode...
4686
             */
4687
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4688
                generate_exception(ctx, EXCP_DBp);
4689
            } else {
4690
                generate_exception(ctx, EXCP_DBp);
4691
            }
4692
            /* Treat as a noop */
4693
            break;
4694
#ifdef TARGET_MIPS64
4695
        case OPC_DCLZ ... OPC_DCLO:
4696
            gen_cl(ctx, op1, rd, rs);
4697
            break;
4698
#endif
4699
        default:            /* Invalid */
4700
            MIPS_INVAL("special2");
4701
            generate_exception(ctx, EXCP_RI);
4702
            break;
4703
        }
4704
        break;
4705
    case OPC_SPECIAL3:
4706
        op1 = MASK_SPECIAL3(ctx->opcode);
4707
        switch (op1) {
4708
        case OPC_EXT:
4709
        case OPC_INS:
4710
            gen_bitops(ctx, op1, rt, rs, sa, rd);
4711
            break;
4712
        case OPC_BSHFL:
4713
            op2 = MASK_BSHFL(ctx->opcode);
4714
            switch (op2) {
4715
            case OPC_WSBH:
4716
                GEN_LOAD_REG_TN(T1, rt);
4717
                gen_op_wsbh();
4718
                break;
4719
            case OPC_SEB:
4720
                GEN_LOAD_REG_TN(T1, rt);
4721
                gen_op_seb();
4722
                break;
4723
            case OPC_SEH:
4724
                GEN_LOAD_REG_TN(T1, rt);
4725
                gen_op_seh();
4726
                break;
4727
             default:            /* Invalid */
4728
                MIPS_INVAL("bshfl");
4729
                generate_exception(ctx, EXCP_RI);
4730
                break;
4731
           }
4732
           GEN_STORE_TN_REG(rd, T0);
4733
           break;
4734
       case OPC_RDHWR:
4735
           switch (rd) {
4736
           case 0:
4737
               gen_op_rdhwr_cpunum();
4738
               break;
4739
           case 1:
4740
               gen_op_rdhwr_synci_step();
4741
               break;
4742
           case 2:
4743
               gen_op_rdhwr_cc();
4744
               break;
4745
           case 3:
4746
               gen_op_rdhwr_ccres();
4747
               break;
4748
#if defined (CONFIG_USER_ONLY)
4749
           case 29:
4750
               gen_op_tls_value ();
4751
               GEN_STORE_TN_REG(rt, T0);
4752
               break;
4753
#endif
4754
           default:            /* Invalid */
4755
               MIPS_INVAL("rdhwr");
4756
               generate_exception(ctx, EXCP_RI);
4757
               break;
4758
           }
4759
           GEN_STORE_TN_REG(rt, T0);
4760
           break;
4761
#ifdef TARGET_MIPS64
4762
       case OPC_DEXTM ... OPC_DEXT:
4763
       case OPC_DINSM ... OPC_DINS:
4764
           gen_bitops(ctx, op1, rt, rs, sa, rd);
4765
            break;
4766
       case OPC_DBSHFL:
4767
           op2 = MASK_DBSHFL(ctx->opcode);
4768
           switch (op2) {
4769
           case OPC_DSBH:
4770
               GEN_LOAD_REG_TN(T1, rt);
4771
               gen_op_dsbh();
4772
               break;
4773
           case OPC_DSHD:
4774
               GEN_LOAD_REG_TN(T1, rt);
4775
               gen_op_dshd();
4776
               break;
4777
            default:            /* Invalid */
4778
                MIPS_INVAL("dbshfl");
4779
                generate_exception(ctx, EXCP_RI);
4780
                break;
4781
           }
4782
           GEN_STORE_TN_REG(rd, T0);
4783
#endif
4784
        default:            /* Invalid */
4785
            MIPS_INVAL("special3");
4786
            generate_exception(ctx, EXCP_RI);
4787
            break;
4788
        }
4789
        break;
4790
    case OPC_REGIMM:
4791
        op1 = MASK_REGIMM(ctx->opcode);
4792
        switch (op1) {
4793
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
4794
        case OPC_BLTZAL ... OPC_BGEZALL:
4795
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
4796
            return;
4797
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
4798
        case OPC_TNEI:
4799
            gen_trap(ctx, op1, rs, -1, imm);
4800
            break;
4801
        case OPC_SYNCI:
4802
            /* treat as noop */
4803
            break;
4804
        default:            /* Invalid */
4805
            MIPS_INVAL("REGIMM");
4806
            generate_exception(ctx, EXCP_RI);
4807
            break;
4808
        }
4809
        break;
4810
    case OPC_CP0:
4811
        gen_op_cp0_enabled();
4812
        op1 = MASK_CP0(ctx->opcode);
4813
        switch (op1) {
4814
        case OPC_MFC0:
4815
        case OPC_MTC0:
4816
#ifdef TARGET_MIPS64
4817
        case OPC_DMFC0:
4818
        case OPC_DMTC0:
4819
#endif
4820
            gen_cp0(ctx, op1, rt, rd);
4821
            break;
4822
        case OPC_C0_FIRST ... OPC_C0_LAST:
4823
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
4824
            break;
4825
        case OPC_MFMC0:
4826
            op2 = MASK_MFMC0(ctx->opcode);
4827
            switch (op2) {
4828
            case OPC_DI:
4829
                gen_op_di();
4830
                /* Stop translation as we may have switched the execution mode */
4831
                ctx->bstate = BS_STOP;
4832
                break;
4833
            case OPC_EI:
4834
                gen_op_ei();
4835
                /* Stop translation as we may have switched the execution mode */
4836
                ctx->bstate = BS_STOP;
4837
                break;
4838
            default:            /* Invalid */
4839
                MIPS_INVAL("MFMC0");
4840
                generate_exception(ctx, EXCP_RI);
4841
                break;
4842
            }
4843
            GEN_STORE_TN_REG(rt, T0);
4844
            break;
4845
        case OPC_RDPGPR:
4846
        case OPC_WRPGPR:
4847
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
4848
                /* Shadow registers not implemented. */
4849
                GEN_LOAD_REG_TN(T0, rt);
4850
                GEN_STORE_TN_REG(rd, T0);
4851
            } else
4852
                generate_exception(ctx, EXCP_RI);
4853
            break;
4854
        default:
4855
            generate_exception(ctx, EXCP_RI);
4856
            break;
4857
        }
4858
        break;
4859
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
4860
         gen_arith_imm(ctx, op, rt, rs, imm);
4861
         break;
4862
    case OPC_J ... OPC_JAL: /* Jump */
4863
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
4864
         gen_compute_branch(ctx, op, rs, rt, offset);
4865
         return;
4866
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
4867
    case OPC_BEQL ... OPC_BGTZL:
4868
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
4869
         return;
4870
    case OPC_LB ... OPC_LWR: /* Load and stores */
4871
    case OPC_SB ... OPC_SW:
4872
    case OPC_SWR:
4873
    case OPC_LL:
4874
    case OPC_SC:
4875
         gen_ldst(ctx, op, rt, rs, imm);
4876
         break;
4877
    case OPC_CACHE:
4878
         /* Treat as a noop */
4879
         break;
4880
    case OPC_PREF:
4881
        /* Treat as a noop */
4882
        break;
4883

    
4884
    /* Floating point.  */
4885
    case OPC_LWC1:
4886
    case OPC_LDC1:
4887
    case OPC_SWC1:
4888
    case OPC_SDC1:
4889
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4890
            save_cpu_state(ctx, 1);
4891
            gen_op_cp1_enabled();
4892
            gen_flt_ldst(ctx, op, rt, rs, imm);
4893
        } else {
4894
            generate_exception_err(ctx, EXCP_CpU, 1);
4895
        }
4896
        break;
4897

    
4898
    case OPC_CP1:
4899
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4900
            save_cpu_state(ctx, 1);
4901
            gen_op_cp1_enabled();
4902
            op1 = MASK_CP1(ctx->opcode);
4903
            switch (op1) {
4904
            case OPC_MFC1:
4905
            case OPC_CFC1:
4906
            case OPC_MTC1:
4907
            case OPC_CTC1:
4908
#ifdef TARGET_MIPS64
4909
            case OPC_DMFC1:
4910
            case OPC_DMTC1:
4911
#endif
4912
                gen_cp1(ctx, op1, rt, rd);
4913
                break;
4914
            case OPC_BC1:
4915
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
4916
                return;
4917
            case OPC_S_FMT:
4918
            case OPC_D_FMT:
4919
            case OPC_W_FMT:
4920
            case OPC_L_FMT:
4921
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
4922
                break;
4923
            default:
4924
                generate_exception (ctx, EXCP_RI);
4925
                break;
4926
            }
4927
        } else {
4928
            generate_exception_err(ctx, EXCP_CpU, 1);
4929
        }
4930
        break;
4931

    
4932
    /* COP2.  */
4933
    case OPC_LWC2:
4934
    case OPC_LDC2:
4935
    case OPC_SWC2:
4936
    case OPC_SDC2:
4937
    case OPC_CP2:
4938
        /* COP2: Not implemented. */
4939
        generate_exception_err(ctx, EXCP_CpU, 2);
4940
        break;
4941

    
4942
    case OPC_CP3:
4943
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4944
            save_cpu_state(ctx, 1);
4945
            gen_op_cp1_enabled();
4946
            op1 = MASK_CP3(ctx->opcode);
4947
            switch (op1) {
4948
            /* Not implemented */
4949
            default:
4950
                generate_exception (ctx, EXCP_RI);
4951
                break;
4952
            }
4953
        } else {
4954
            generate_exception_err(ctx, EXCP_CpU, 1);
4955
        }
4956
        break;
4957

    
4958
#ifdef TARGET_MIPS64
4959
    /* MIPS64 opcodes */
4960
    case OPC_LWU:
4961
    case OPC_LDL ... OPC_LDR:
4962
    case OPC_SDL ... OPC_SDR:
4963
    case OPC_LLD:
4964
    case OPC_LD:
4965
    case OPC_SCD:
4966
    case OPC_SD:
4967
        gen_ldst(ctx, op, rt, rs, imm);
4968
        break;
4969
    case OPC_DADDI ... OPC_DADDIU:
4970
        gen_arith_imm(ctx, op, rt, rs, imm);
4971
        break;
4972
#endif
4973
#ifdef MIPS_HAS_MIPS16
4974
    case OPC_JALX:
4975
        /* MIPS16: Not implemented. */
4976
#endif
4977
#ifdef MIPS_HAS_MDMX
4978
    case OPC_MDMX:
4979
        /* MDMX: Not implemented. */
4980
#endif
4981
    default:            /* Invalid */
4982
        MIPS_INVAL("");
4983
        generate_exception(ctx, EXCP_RI);
4984
        break;
4985
    }
4986
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4987
        int hflags = ctx->hflags;
4988
        /* Branches completion */
4989
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
4990
        ctx->bstate = BS_BRANCH;
4991
        save_cpu_state(ctx, 0);
4992
        switch (hflags & MIPS_HFLAG_BMASK) {
4993
        case MIPS_HFLAG_B:
4994
            /* unconditional branch */
4995
            MIPS_DEBUG("unconditional branch");
4996
            gen_goto_tb(ctx, 0, ctx->btarget);
4997
            break;
4998
        case MIPS_HFLAG_BL:
4999
            /* blikely taken case */
5000
            MIPS_DEBUG("blikely branch taken");
5001
            gen_goto_tb(ctx, 0, ctx->btarget);
5002
            break;
5003
        case MIPS_HFLAG_BC:
5004
            /* Conditional branch */
5005
            MIPS_DEBUG("conditional branch");
5006
            {
5007
              int l1;
5008
              l1 = gen_new_label();
5009
              gen_op_jnz_T2(l1);
5010
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5011
              gen_set_label(l1);
5012
              gen_goto_tb(ctx, 0, ctx->btarget);
5013
            }
5014
            break;
5015
        case MIPS_HFLAG_BR:
5016
            /* unconditional branch to register */
5017
            MIPS_DEBUG("branch to register");
5018
            gen_op_breg();
5019
            break;
5020
        default:
5021
            MIPS_DEBUG("unknown branch");
5022
            break;
5023
        }
5024
    }
5025
}
5026

    
5027
static inline int
5028
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5029
                                int search_pc)
5030
{
5031
    DisasContext ctx, *ctxp = &ctx;
5032
    target_ulong pc_start;
5033
    uint16_t *gen_opc_end;
5034
    int j, lj = -1;
5035

    
5036
    if (search_pc && loglevel)
5037
        fprintf (logfile, "search pc %d\n", search_pc);
5038

    
5039
    pc_start = tb->pc;
5040
    gen_opc_ptr = gen_opc_buf;
5041
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5042
    gen_opparam_ptr = gen_opparam_buf;
5043
    nb_gen_labels = 0;
5044
    ctx.pc = pc_start;
5045
    ctx.saved_pc = -1;
5046
    ctx.tb = tb;
5047
    ctx.bstate = BS_NONE;
5048
    /* Restore delay slot state from the tb context.  */
5049
    ctx.hflags = tb->flags;
5050
    ctx.saved_hflags = ctx.hflags;
5051
    if (ctx.hflags & MIPS_HFLAG_BR) {
5052
        gen_op_restore_breg_target();
5053
    } else if (ctx.hflags & MIPS_HFLAG_B) {
5054
        ctx.btarget = env->btarget;
5055
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5056
        /* If we are in the delay slot of a conditional branch,
5057
         * restore the branch condition from env->bcond to T2
5058
         */
5059
        ctx.btarget = env->btarget;
5060
        gen_op_restore_bcond();
5061
    }
5062
#if defined(CONFIG_USER_ONLY)
5063
    ctx.mem_idx = 0;
5064
#else
5065
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5066
#endif
5067
    ctx.CP0_Status = env->CP0_Status;
5068
#ifdef DEBUG_DISAS
5069
    if (loglevel & CPU_LOG_TB_CPU) {
5070
        fprintf(logfile, "------------------------------------------------\n");
5071
        /* FIXME: This may print out stale hflags from env... */
5072
        cpu_dump_state(env, logfile, fprintf, 0);
5073
    }
5074
#endif
5075
#if defined MIPS_DEBUG_DISAS
5076
    if (loglevel & CPU_LOG_TB_IN_ASM)
5077
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5078
                tb, ctx.mem_idx, ctx.hflags);
5079
#endif
5080
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5081
        if (env->nb_breakpoints > 0) {
5082
            for(j = 0; j < env->nb_breakpoints; j++) {
5083
                if (env->breakpoints[j] == ctx.pc) {
5084
                    save_cpu_state(ctxp, 1);
5085
                    ctx.bstate = BS_BRANCH;
5086
                    gen_op_debug();
5087
                    goto done_generating;
5088
                }
5089
            }
5090
        }
5091

    
5092
        if (search_pc) {
5093
            j = gen_opc_ptr - gen_opc_buf;
5094
            if (lj < j) {
5095
                lj++;
5096
                while (lj < j)
5097
                    gen_opc_instr_start[lj++] = 0;
5098
            }
5099
            gen_opc_pc[lj] = ctx.pc;
5100
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5101
            gen_opc_instr_start[lj] = 1;
5102
        }
5103
        ctx.opcode = ldl_code(ctx.pc);
5104
        decode_opc(env, &ctx);
5105
        ctx.pc += 4;
5106

    
5107
        if (env->singlestep_enabled)
5108
            break;
5109

    
5110
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5111
            break;
5112

    
5113
#if defined (MIPS_SINGLE_STEP)
5114
        break;
5115
#endif
5116
    }
5117
    if (env->singlestep_enabled) {
5118
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5119
        gen_op_debug();
5120
        goto done_generating;
5121
    }
5122
    else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
5123
        save_cpu_state(ctxp, 0);
5124
        gen_goto_tb(&ctx, 0, ctx.pc);
5125
    }
5126
    gen_op_reset_T0();
5127
    /* Generate the return instruction */
5128
    gen_op_exit_tb();
5129
done_generating:
5130
    *gen_opc_ptr = INDEX_op_end;
5131
    if (search_pc) {
5132
        j = gen_opc_ptr - gen_opc_buf;
5133
        lj++;
5134
        while (lj <= j)
5135
            gen_opc_instr_start[lj++] = 0;
5136
        tb->size = 0;
5137
    } else {
5138
        tb->size = ctx.pc - pc_start;
5139
    }
5140
#ifdef DEBUG_DISAS
5141
#if defined MIPS_DEBUG_DISAS
5142
    if (loglevel & CPU_LOG_TB_IN_ASM)
5143
        fprintf(logfile, "\n");
5144
#endif
5145
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5146
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5147
    target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5148
        fprintf(logfile, "\n");
5149
    }
5150
    if (loglevel & CPU_LOG_TB_OP) {
5151
        fprintf(logfile, "OP:\n");
5152
        dump_ops(gen_opc_buf, gen_opparam_buf);
5153
        fprintf(logfile, "\n");
5154
    }
5155
    if (loglevel & CPU_LOG_TB_CPU) {
5156
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5157
    }
5158
#endif
5159
    
5160
    return 0;
5161
}
5162

    
5163
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5164
{
5165
    return gen_intermediate_code_internal(env, tb, 0);
5166
}
5167

    
5168
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5169
{
5170
    return gen_intermediate_code_internal(env, tb, 1);
5171
}
5172

    
5173
void fpu_dump_state(CPUState *env, FILE *f, 
5174
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5175
                    int flags)
5176
{
5177
    int i;
5178

    
5179
#   define printfpr(fp) do { \
5180
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5181
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5182
    } while(0)
5183

    
5184
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5185
                env->fcr0, env->fcr31,
5186
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5187
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5188
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5189
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5190
    for(i = 0; i < 32; i += 2) {
5191
        fpu_fprintf(f, "%s: ", fregnames[i]);
5192
        printfpr(FPR(env, i));
5193
    }
5194

    
5195
#undef printfpr
5196
}
5197

    
5198
void dump_fpu (CPUState *env)
5199
{
5200
    if (loglevel) { 
5201
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5202
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5203
       fpu_dump_state(env, logfile, fprintf, 0);
5204
    }
5205
}
5206

    
5207
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5208
/* Debug help: The architecture requires 32bit code to maintain proper
5209
   sign-extened values on 64bit machines.  */
5210

    
5211
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5212

    
5213
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5214
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5215
                     int flags)
5216
{
5217
    int i;
5218

    
5219
    if (!SIGN_EXT_P(env->PC))
5220
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5221
    if (!SIGN_EXT_P(env->HI))
5222
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5223
    if (!SIGN_EXT_P(env->LO))
5224
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5225
    if (!SIGN_EXT_P(env->btarget))
5226
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5227

    
5228
    for (i = 0; i < 32; i++) {
5229
        if (!SIGN_EXT_P(env->gpr[i]))
5230
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5231
    }
5232

    
5233
    if (!SIGN_EXT_P(env->CP0_EPC))
5234
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5235
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5236
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5237
}
5238
#endif
5239

    
5240
void cpu_dump_state (CPUState *env, FILE *f, 
5241
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5242
                     int flags)
5243
{
5244
    uint32_t c0_status;
5245
    int i;
5246
    
5247
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5248
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5249
    for (i = 0; i < 32; i++) {
5250
        if ((i & 3) == 0)
5251
            cpu_fprintf(f, "GPR%02d:", i);
5252
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5253
        if ((i & 3) == 3)
5254
            cpu_fprintf(f, "\n");
5255
    }
5256

    
5257
    c0_status = env->CP0_Status;
5258

    
5259
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5260
                c0_status, env->CP0_Cause, env->CP0_EPC);
5261
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5262
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5263
    if (c0_status & (1 << CP0St_CU1))
5264
        fpu_dump_state(env, f, cpu_fprintf, flags);
5265
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5266
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5267
#endif
5268
}
5269

    
5270
CPUMIPSState *cpu_mips_init (void)
5271
{
5272
    CPUMIPSState *env;
5273

    
5274
    env = qemu_mallocz(sizeof(CPUMIPSState));
5275
    if (!env)
5276
        return NULL;
5277
    cpu_exec_init(env);
5278
    cpu_reset(env);
5279
    return env;
5280
}
5281

    
5282
void cpu_reset (CPUMIPSState *env)
5283
{
5284
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5285

    
5286
    tlb_flush(env, 1);
5287

    
5288
    /* Minimal init */
5289
#if !defined(CONFIG_USER_ONLY)
5290
    if (env->hflags & MIPS_HFLAG_BMASK) {
5291
        /* If the exception was raised from a delay slot,
5292
         * come back to the jump.  */
5293
        env->CP0_ErrorEPC = env->PC - 4;
5294
        env->hflags &= ~MIPS_HFLAG_BMASK;
5295
    } else {
5296
        env->CP0_ErrorEPC = env->PC;
5297
    }
5298
    env->hflags = 0;
5299
    env->PC = (int32_t)0xBFC00000;
5300
#if defined (MIPS_USES_R4K_TLB)
5301
    env->CP0_Random = MIPS_TLB_NB - 1;
5302
    env->tlb_in_use = MIPS_TLB_NB;
5303
#endif
5304
    env->CP0_Wired = 0;
5305
    /* SMP not implemented */
5306
    env->CP0_EBase = 0x80000000;
5307
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5308
    env->CP0_WatchLo = 0;
5309
    /* Count register increments in debug mode, EJTAG version 1 */
5310
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5311
#endif
5312
    env->exception_index = EXCP_NONE;
5313
#if defined(CONFIG_USER_ONLY)
5314
    env->hflags |= MIPS_HFLAG_UM;
5315
    env->user_mode_only = 1;
5316
#endif
5317
    /* XXX some guesswork here, values are CPU specific */
5318
    env->SYNCI_Step = 16;
5319
    env->CCRes = 2;
5320
}
5321

    
5322
#include "translate_init.c"