Statistics
| Branch: | Revision:

root / target-mips / translate.c @ cbeb0857

History | View | Annotate | Download (141.2 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
    uimm = (uint16_t)imm;
853
    switch (opc) {
854
    case OPC_ADDI:
855
    case OPC_ADDIU:
856
#ifdef TARGET_MIPS64
857
    case OPC_DADDI:
858
    case OPC_DADDIU:
859
#endif
860
    case OPC_SLTI:
861
    case OPC_SLTIU:
862
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
863
        /* Fall through. */
864
    case OPC_ANDI:
865
    case OPC_ORI:
866
    case OPC_XORI:
867
        GEN_LOAD_REG_TN(T0, rs);
868
        GEN_LOAD_IMM_TN(T1, uimm);
869
        break;
870
    case OPC_LUI:
871
        uimm <<= 16;
872
        GEN_LOAD_IMM_TN(T0, uimm);
873
        break;
874
    case OPC_SLL:
875
    case OPC_SRA:
876
    case OPC_SRL:
877
#ifdef TARGET_MIPS64
878
    case OPC_DSLL:
879
    case OPC_DSRA:
880
    case OPC_DSRL:
881
    case OPC_DSLL32:
882
    case OPC_DSRA32:
883
    case OPC_DSRL32:
884
#endif
885
        uimm &= 0x1f;
886
        GEN_LOAD_REG_TN(T0, rs);
887
        GEN_LOAD_IMM_TN(T1, uimm);
888
        break;
889
    }
890
    switch (opc) {
891
    case OPC_ADDI:
892
        save_cpu_state(ctx, 1);
893
        gen_op_addo();
894
        opn = "addi";
895
        break;
896
    case OPC_ADDIU:
897
        gen_op_add();
898
        opn = "addiu";
899
        break;
900
#ifdef TARGET_MIPS64
901
    case OPC_DADDI:
902
        save_cpu_state(ctx, 1);
903
        gen_op_daddo();
904
        opn = "daddi";
905
        break;
906
    case OPC_DADDIU:
907
        gen_op_dadd();
908
        opn = "daddiu";
909
        break;
910
#endif
911
    case OPC_SLTI:
912
        gen_op_lt();
913
        opn = "slti";
914
        break;
915
    case OPC_SLTIU:
916
        gen_op_ltu();
917
        opn = "sltiu";
918
        break;
919
    case OPC_ANDI:
920
        gen_op_and();
921
        opn = "andi";
922
        break;
923
    case OPC_ORI:
924
        gen_op_or();
925
        opn = "ori";
926
        break;
927
    case OPC_XORI:
928
        gen_op_xor();
929
        opn = "xori";
930
        break;
931
    case OPC_LUI:
932
        opn = "lui";
933
        break;
934
    case OPC_SLL:
935
        gen_op_sll();
936
        opn = "sll";
937
        break;
938
    case OPC_SRA:
939
        gen_op_sra();
940
        opn = "sra";
941
        break;
942
    case OPC_SRL:
943
        switch ((ctx->opcode >> 21) & 0x1f) {
944
        case 0:
945
            gen_op_srl();
946
            opn = "srl";
947
            break;
948
        case 1:
949
            gen_op_rotr();
950
            opn = "rotr";
951
            break;
952
        default:
953
            MIPS_INVAL("invalid srl flag");
954
            generate_exception(ctx, EXCP_RI);
955
            break;
956
        }
957
        break;
958
#ifdef TARGET_MIPS64
959
    case OPC_DSLL:
960
        gen_op_dsll();
961
        opn = "dsll";
962
        break;
963
    case OPC_DSRA:
964
        gen_op_dsra();
965
        opn = "dsra";
966
        break;
967
    case OPC_DSRL:
968
        switch ((ctx->opcode >> 21) & 0x1f) {
969
        case 0:
970
            gen_op_dsrl();
971
            opn = "dsrl";
972
            break;
973
        case 1:
974
            gen_op_drotr();
975
            opn = "drotr";
976
            break;
977
        default:
978
            MIPS_INVAL("invalid dsrl flag");
979
            generate_exception(ctx, EXCP_RI);
980
            break;
981
        }
982
        break;
983
    case OPC_DSLL32:
984
        gen_op_dsll32();
985
        opn = "dsll32";
986
        break;
987
    case OPC_DSRA32:
988
        gen_op_dsra32();
989
        opn = "dsra32";
990
        break;
991
    case OPC_DSRL32:
992
        switch ((ctx->opcode >> 21) & 0x1f) {
993
        case 0:
994
            gen_op_dsrl32();
995
            opn = "dsrl32";
996
            break;
997
        case 1:
998
            gen_op_drotr32();
999
            opn = "drotr32";
1000
            break;
1001
        default:
1002
            MIPS_INVAL("invalid dsrl32 flag");
1003
            generate_exception(ctx, EXCP_RI);
1004
            break;
1005
        }
1006
        break;
1007
#endif
1008
    default:
1009
        MIPS_INVAL("imm arith");
1010
        generate_exception(ctx, EXCP_RI);
1011
        return;
1012
    }
1013
    GEN_STORE_TN_REG(rt, T0);
1014
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1015
}
1016

    
1017
/* Arithmetic */
1018
static void gen_arith (DisasContext *ctx, uint32_t opc,
1019
                       int rd, int rs, int rt)
1020
{
1021
    const char *opn = "unk";
1022

    
1023
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1024
       && opc != OPC_DADD && opc != OPC_DSUB) {
1025
        /* if no destination, treat it as a NOP 
1026
         * For add & sub, we must generate the overflow exception when needed.
1027
         */
1028
        MIPS_DEBUG("NOP");
1029
        return;
1030
    }
1031
    GEN_LOAD_REG_TN(T0, rs);
1032
    GEN_LOAD_REG_TN(T1, rt);
1033
    switch (opc) {
1034
    case OPC_ADD:
1035
        save_cpu_state(ctx, 1);
1036
        gen_op_addo();
1037
        opn = "add";
1038
        break;
1039
    case OPC_ADDU:
1040
        gen_op_add();
1041
        opn = "addu";
1042
        break;
1043
    case OPC_SUB:
1044
        save_cpu_state(ctx, 1);
1045
        gen_op_subo();
1046
        opn = "sub";
1047
        break;
1048
    case OPC_SUBU:
1049
        gen_op_sub();
1050
        opn = "subu";
1051
        break;
1052
#ifdef TARGET_MIPS64
1053
    case OPC_DADD:
1054
        save_cpu_state(ctx, 1);
1055
        gen_op_daddo();
1056
        opn = "dadd";
1057
        break;
1058
    case OPC_DADDU:
1059
        gen_op_dadd();
1060
        opn = "daddu";
1061
        break;
1062
    case OPC_DSUB:
1063
        save_cpu_state(ctx, 1);
1064
        gen_op_dsubo();
1065
        opn = "dsub";
1066
        break;
1067
    case OPC_DSUBU:
1068
        gen_op_dsub();
1069
        opn = "dsubu";
1070
        break;
1071
#endif
1072
    case OPC_SLT:
1073
        gen_op_lt();
1074
        opn = "slt";
1075
        break;
1076
    case OPC_SLTU:
1077
        gen_op_ltu();
1078
        opn = "sltu";
1079
        break;
1080
    case OPC_AND:
1081
        gen_op_and();
1082
        opn = "and";
1083
        break;
1084
    case OPC_NOR:
1085
        gen_op_nor();
1086
        opn = "nor";
1087
        break;
1088
    case OPC_OR:
1089
        gen_op_or();
1090
        opn = "or";
1091
        break;
1092
    case OPC_XOR:
1093
        gen_op_xor();
1094
        opn = "xor";
1095
        break;
1096
    case OPC_MUL:
1097
        gen_op_mul();
1098
        opn = "mul";
1099
        break;
1100
    case OPC_MOVN:
1101
        gen_op_movn(rd);
1102
        opn = "movn";
1103
        goto print;
1104
    case OPC_MOVZ:
1105
        gen_op_movz(rd);
1106
        opn = "movz";
1107
        goto print;
1108
    case OPC_SLLV:
1109
        gen_op_sllv();
1110
        opn = "sllv";
1111
        break;
1112
    case OPC_SRAV:
1113
        gen_op_srav();
1114
        opn = "srav";
1115
        break;
1116
    case OPC_SRLV:
1117
        switch ((ctx->opcode >> 6) & 0x1f) {
1118
        case 0:
1119
            gen_op_srlv();
1120
            opn = "srlv";
1121
            break;
1122
        case 1:
1123
            gen_op_rotrv();
1124
            opn = "rotrv";
1125
            break;
1126
        default:
1127
            MIPS_INVAL("invalid srlv flag");
1128
            generate_exception(ctx, EXCP_RI);
1129
            break;
1130
        }
1131
        break;
1132
#ifdef TARGET_MIPS64
1133
    case OPC_DSLLV:
1134
        gen_op_dsllv();
1135
        opn = "dsllv";
1136
        break;
1137
    case OPC_DSRAV:
1138
        gen_op_dsrav();
1139
        opn = "dsrav";
1140
        break;
1141
    case OPC_DSRLV:
1142
        switch ((ctx->opcode >> 6) & 0x1f) {
1143
        case 0:
1144
            gen_op_dsrlv();
1145
            opn = "dsrlv";
1146
            break;
1147
        case 1:
1148
            gen_op_drotrv();
1149
            opn = "drotrv";
1150
            break;
1151
        default:
1152
            MIPS_INVAL("invalid dsrlv flag");
1153
            generate_exception(ctx, EXCP_RI);
1154
            break;
1155
        }
1156
        break;
1157
#endif
1158
    default:
1159
        MIPS_INVAL("arith");
1160
        generate_exception(ctx, EXCP_RI);
1161
        return;
1162
    }
1163
    GEN_STORE_TN_REG(rd, T0);
1164
 print:
1165
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1166
}
1167

    
1168
/* Arithmetic on HI/LO registers */
1169
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1170
{
1171
    const char *opn = "unk";
1172

    
1173
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1174
        /* Treat as a NOP */
1175
        MIPS_DEBUG("NOP");
1176
        return;
1177
    }
1178
    switch (opc) {
1179
    case OPC_MFHI:
1180
        gen_op_load_HI();
1181
        GEN_STORE_TN_REG(reg, T0);
1182
        opn = "mfhi";
1183
        break;
1184
    case OPC_MFLO:
1185
        gen_op_load_LO();
1186
        GEN_STORE_TN_REG(reg, T0);
1187
        opn = "mflo";
1188
        break;
1189
    case OPC_MTHI:
1190
        GEN_LOAD_REG_TN(T0, reg);
1191
        gen_op_store_HI();
1192
        opn = "mthi";
1193
        break;
1194
    case OPC_MTLO:
1195
        GEN_LOAD_REG_TN(T0, reg);
1196
        gen_op_store_LO();
1197
        opn = "mtlo";
1198
        break;
1199
    default:
1200
        MIPS_INVAL("HILO");
1201
        generate_exception(ctx, EXCP_RI);
1202
        return;
1203
    }
1204
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1205
}
1206

    
1207
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1208
                        int rs, int rt)
1209
{
1210
    const char *opn = "unk";
1211

    
1212
    GEN_LOAD_REG_TN(T0, rs);
1213
    GEN_LOAD_REG_TN(T1, rt);
1214
    switch (opc) {
1215
    case OPC_DIV:
1216
        gen_op_div();
1217
        opn = "div";
1218
        break;
1219
    case OPC_DIVU:
1220
        gen_op_divu();
1221
        opn = "divu";
1222
        break;
1223
    case OPC_MULT:
1224
        gen_op_mult();
1225
        opn = "mult";
1226
        break;
1227
    case OPC_MULTU:
1228
        gen_op_multu();
1229
        opn = "multu";
1230
        break;
1231
#ifdef TARGET_MIPS64
1232
    case OPC_DDIV:
1233
        gen_op_ddiv();
1234
        opn = "ddiv";
1235
        break;
1236
    case OPC_DDIVU:
1237
        gen_op_ddivu();
1238
        opn = "ddivu";
1239
        break;
1240
    case OPC_DMULT:
1241
        gen_op_dmult();
1242
        opn = "dmult";
1243
        break;
1244
    case OPC_DMULTU:
1245
        gen_op_dmultu();
1246
        opn = "dmultu";
1247
        break;
1248
#endif
1249
    case OPC_MADD:
1250
        gen_op_madd();
1251
        opn = "madd";
1252
        break;
1253
    case OPC_MADDU:
1254
        gen_op_maddu();
1255
        opn = "maddu";
1256
        break;
1257
    case OPC_MSUB:
1258
        gen_op_msub();
1259
        opn = "msub";
1260
        break;
1261
    case OPC_MSUBU:
1262
        gen_op_msubu();
1263
        opn = "msubu";
1264
        break;
1265
    default:
1266
        MIPS_INVAL("mul/div");
1267
        generate_exception(ctx, EXCP_RI);
1268
        return;
1269
    }
1270
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1271
}
1272

    
1273
static void gen_cl (DisasContext *ctx, uint32_t opc,
1274
                    int rd, int rs)
1275
{
1276
    const char *opn = "unk";
1277
    if (rd == 0) {
1278
        /* Treat as a NOP */
1279
        MIPS_DEBUG("NOP");
1280
        return;
1281
    }
1282
    GEN_LOAD_REG_TN(T0, rs);
1283
    switch (opc) {
1284
    case OPC_CLO:
1285
        gen_op_clo();
1286
        opn = "clo";
1287
        break;
1288
    case OPC_CLZ:
1289
        gen_op_clz();
1290
        opn = "clz";
1291
        break;
1292
#ifdef TARGET_MIPS64
1293
    case OPC_DCLO:
1294
        gen_op_dclo();
1295
        opn = "dclo";
1296
        break;
1297
    case OPC_DCLZ:
1298
        gen_op_dclz();
1299
        opn = "dclz";
1300
        break;
1301
#endif
1302
    default:
1303
        MIPS_INVAL("CLx");
1304
        generate_exception(ctx, EXCP_RI);
1305
        return;
1306
    }
1307
    gen_op_store_T0_gpr(rd);
1308
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1309
}
1310

    
1311
/* Traps */
1312
static void gen_trap (DisasContext *ctx, uint32_t opc,
1313
                      int rs, int rt, int16_t imm)
1314
{
1315
    int cond;
1316

    
1317
    cond = 0;
1318
    /* Load needed operands */
1319
    switch (opc) {
1320
    case OPC_TEQ:
1321
    case OPC_TGE:
1322
    case OPC_TGEU:
1323
    case OPC_TLT:
1324
    case OPC_TLTU:
1325
    case OPC_TNE:
1326
        /* Compare two registers */
1327
        if (rs != rt) {
1328
            GEN_LOAD_REG_TN(T0, rs);
1329
            GEN_LOAD_REG_TN(T1, rt);
1330
            cond = 1;
1331
        }
1332
        break;
1333
    case OPC_TEQI:
1334
    case OPC_TGEI:
1335
    case OPC_TGEIU:
1336
    case OPC_TLTI:
1337
    case OPC_TLTIU:
1338
    case OPC_TNEI:
1339
        /* Compare register to immediate */
1340
        if (rs != 0 || imm != 0) {
1341
            GEN_LOAD_REG_TN(T0, rs);
1342
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1343
            cond = 1;
1344
        }
1345
        break;
1346
    }
1347
    if (cond == 0) {
1348
        switch (opc) {
1349
        case OPC_TEQ:   /* rs == rs */
1350
        case OPC_TEQI:  /* r0 == 0  */
1351
        case OPC_TGE:   /* rs >= rs */
1352
        case OPC_TGEI:  /* r0 >= 0  */
1353
        case OPC_TGEU:  /* rs >= rs unsigned */
1354
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1355
            /* Always trap */
1356
            gen_op_set_T0(1);
1357
            break;
1358
        case OPC_TLT:   /* rs < rs           */
1359
        case OPC_TLTI:  /* r0 < 0            */
1360
        case OPC_TLTU:  /* rs < rs unsigned  */
1361
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1362
        case OPC_TNE:   /* rs != rs          */
1363
        case OPC_TNEI:  /* r0 != 0           */
1364
            /* Never trap: treat as NOP */
1365
            return;
1366
        default:
1367
            MIPS_INVAL("TRAP");
1368
            generate_exception(ctx, EXCP_RI);
1369
            return;
1370
        }
1371
    } else {
1372
        switch (opc) {
1373
        case OPC_TEQ:
1374
        case OPC_TEQI:
1375
            gen_op_eq();
1376
            break;
1377
        case OPC_TGE:
1378
        case OPC_TGEI:
1379
            gen_op_ge();
1380
            break;
1381
        case OPC_TGEU:
1382
        case OPC_TGEIU:
1383
            gen_op_geu();
1384
            break;
1385
        case OPC_TLT:
1386
        case OPC_TLTI:
1387
            gen_op_lt();
1388
            break;
1389
        case OPC_TLTU:
1390
        case OPC_TLTIU:
1391
            gen_op_ltu();
1392
            break;
1393
        case OPC_TNE:
1394
        case OPC_TNEI:
1395
            gen_op_ne();
1396
            break;
1397
        default:
1398
            MIPS_INVAL("TRAP");
1399
            generate_exception(ctx, EXCP_RI);
1400
            return;
1401
        }
1402
    }
1403
    save_cpu_state(ctx, 1);
1404
    gen_op_trap();
1405
    ctx->bstate = BS_STOP;
1406
}
1407

    
1408
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1409
{
1410
    TranslationBlock *tb;
1411
    tb = ctx->tb;
1412
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1413
        if (n == 0)
1414
            gen_op_goto_tb0(TBPARAM(tb));
1415
        else
1416
            gen_op_goto_tb1(TBPARAM(tb));
1417
        gen_op_save_pc(dest);
1418
        gen_op_set_T0((long)tb + n);
1419
        gen_op_exit_tb();
1420
    } else {
1421
        gen_op_save_pc(dest);
1422
        gen_op_set_T0(0);
1423
        gen_op_exit_tb();
1424
    }
1425
}
1426

    
1427
/* Branches (before delay slot) */
1428
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1429
                                int rs, int rt, int32_t offset)
1430
{
1431
    target_ulong btarget = -1;
1432
    int blink = 0;
1433
    int bcond = 0;
1434

    
1435
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1436
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1437
            fprintf(logfile,
1438
                    "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1439
                    ctx->pc);
1440
        }
1441
        MIPS_INVAL("branch/jump in bdelay slot");
1442
        generate_exception(ctx, EXCP_RI);
1443
        return;
1444
    }
1445

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

    
1659
/* special3 bitfield operations */
1660
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1661
                       int rs, int lsb, int msb)
1662
{
1663
    GEN_LOAD_REG_TN(T1, rs);
1664
    switch (opc) {
1665
    case OPC_EXT:
1666
        if (lsb + msb > 31)
1667
            goto fail;
1668
        gen_op_ext(lsb, msb + 1);
1669
        break;
1670
    case OPC_DEXTM:
1671
        if (lsb + msb > 63)
1672
            goto fail;
1673
        gen_op_ext(lsb, msb + 1 + 32);
1674
        break;
1675
    case OPC_DEXTU:
1676
        if (lsb + msb > 63)
1677
            goto fail;
1678
        gen_op_ext(lsb + 32, msb + 1);
1679
        break;
1680
    case OPC_DEXT:
1681
        gen_op_ext(lsb, msb + 1);
1682
        break;
1683
    case OPC_INS:
1684
        if (lsb > msb)
1685
            goto fail;
1686
        GEN_LOAD_REG_TN(T2, rt);
1687
        gen_op_ins(lsb, msb - lsb + 1);
1688
        break;
1689
    case OPC_DINSM:
1690
        if (lsb > msb)
1691
            goto fail;
1692
        GEN_LOAD_REG_TN(T2, rt);
1693
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1694
        break;
1695
    case OPC_DINSU:
1696
        if (lsb > msb)
1697
            goto fail;
1698
        GEN_LOAD_REG_TN(T2, rt);
1699
        gen_op_ins(lsb + 32, msb - lsb + 1);
1700
        break;
1701
    case OPC_DINS:
1702
        if (lsb > msb)
1703
            goto fail;
1704
        GEN_LOAD_REG_TN(T2, rt);
1705
        gen_op_ins(lsb, msb - lsb + 1);
1706
        break;
1707
    default:
1708
fail:
1709
        MIPS_INVAL("bitops");
1710
        generate_exception(ctx, EXCP_RI);
1711
        return;
1712
    }
1713
    GEN_STORE_TN_REG(rt, T0);
1714
}
1715

    
1716
/* CP0 (MMU and control) */
1717
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1718
{
1719
    const char *rn = "invalid";
1720

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

    
2298
die:
2299
#if defined MIPS_DEBUG_DISAS
2300
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2301
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2302
                rn, reg, sel);
2303
    }
2304
#endif
2305
    generate_exception(ctx, EXCP_RI);
2306
}
2307

    
2308
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2309
{
2310
    const char *rn = "invalid";
2311

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

    
2900
die:
2901
#if defined MIPS_DEBUG_DISAS
2902
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2903
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2904
                rn, reg, sel);
2905
    }
2906
#endif
2907
    generate_exception(ctx, EXCP_RI);
2908
}
2909

    
2910
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2911
{
2912
    const char *rn = "invalid";
2913

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

    
3482
die:
3483
#if defined MIPS_DEBUG_DISAS
3484
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3485
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3486
                rn, reg, sel);
3487
    }
3488
#endif
3489
    generate_exception(ctx, EXCP_RI);
3490
}
3491

    
3492
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3493
{
3494
    const char *rn = "invalid";
3495

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

    
4075
die:
4076
#if defined MIPS_DEBUG_DISAS
4077
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4078
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4079
                rn, reg, sel);
4080
    }
4081
#endif
4082
    generate_exception(ctx, EXCP_RI);
4083
}
4084

    
4085
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4086
{
4087
    const char *opn = "unk";
4088

    
4089
    switch (opc) {
4090
    case OPC_MFC0:
4091
        if (rt == 0) {
4092
            /* Treat as NOP */
4093
            return;
4094
        }
4095
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4096
        gen_op_store_T0_gpr(rt);
4097
        opn = "mfc0";
4098
        break;
4099
    case OPC_MTC0:
4100
        /* If we get an exception, we want to restart at next instruction */
4101
        /* XXX: breaks for mtc in delay slot */
4102
        ctx->pc += 4;
4103
        save_cpu_state(ctx, 1);
4104
        ctx->pc -= 4;
4105
        GEN_LOAD_REG_TN(T0, rt);
4106
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4107
        opn = "mtc0";
4108
        break;
4109
    case OPC_DMFC0:
4110
        if (rt == 0) {
4111
            /* Treat as NOP */
4112
            return;
4113
        }
4114
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4115
        gen_op_store_T0_gpr(rt);
4116
        opn = "dmfc0";
4117
        break;
4118
    case OPC_DMTC0:
4119
        /* If we get an exception, we want to restart at next instruction */
4120
        /* XXX: breaks for dmtc in delay slot */
4121
        ctx->pc += 4;
4122
        save_cpu_state(ctx, 1);
4123
        ctx->pc -= 4;
4124
        GEN_LOAD_REG_TN(T0, rt);
4125
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4126
        opn = "dmtc0";
4127
        break;
4128
#if defined(MIPS_USES_R4K_TLB)
4129
    case OPC_TLBWI:
4130
        gen_op_tlbwi();
4131
        opn = "tlbwi";
4132
        break;
4133
    case OPC_TLBWR:
4134
        gen_op_tlbwr();
4135
        opn = "tlbwr";
4136
        break;
4137
    case OPC_TLBP:
4138
        gen_op_tlbp();
4139
        opn = "tlbp";
4140
        break;
4141
    case OPC_TLBR:
4142
        gen_op_tlbr();
4143
        opn = "tlbr";
4144
        break;
4145
#endif
4146
    case OPC_ERET:
4147
        opn = "eret";
4148
        save_cpu_state(ctx, 0);
4149
        gen_op_eret();
4150
        ctx->bstate = BS_EXCP;
4151
        break;
4152
    case OPC_DERET:
4153
        opn = "deret";
4154
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4155
            generate_exception(ctx, EXCP_RI);
4156
        } else {
4157
            save_cpu_state(ctx, 0);
4158
            gen_op_deret();
4159
            ctx->bstate = BS_EXCP;
4160
        }
4161
        break;
4162
    case OPC_WAIT:
4163
        opn = "wait";
4164
        /* If we get an exception, we want to restart at next instruction */
4165
        ctx->pc += 4;
4166
        save_cpu_state(ctx, 1);
4167
        ctx->pc -= 4;
4168
        gen_op_wait();
4169
        ctx->bstate = BS_EXCP;
4170
        break;
4171
    default:
4172
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4173
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4174
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4175
                    ((ctx->opcode >> 16) & 0x1F));
4176
        }
4177
        generate_exception(ctx, EXCP_RI);
4178
        return;
4179
    }
4180
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4181
}
4182

    
4183
/* CP1 Branches (before delay slot) */
4184
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4185
                                 int32_t offset)
4186
{
4187
    target_ulong btarget;
4188

    
4189
    btarget = ctx->pc + 4 + offset;
4190

    
4191
    switch (op) {
4192
    case OPC_BC1F:
4193
        gen_op_bc1f();
4194
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4195
        goto not_likely;
4196
    case OPC_BC1FL:
4197
        gen_op_bc1f();
4198
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4199
        goto likely;
4200
    case OPC_BC1T:
4201
        gen_op_bc1t();
4202
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4203
    not_likely:
4204
        ctx->hflags |= MIPS_HFLAG_BC;
4205
        break;
4206
    case OPC_BC1TL:
4207
        gen_op_bc1t();
4208
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4209
    likely:
4210
        ctx->hflags |= MIPS_HFLAG_BL;
4211
        break;
4212
    default:    
4213
        MIPS_INVAL("cp1 branch/jump");
4214
        generate_exception (ctx, EXCP_RI);
4215
        return;
4216
    }
4217
    gen_op_set_bcond();
4218

    
4219
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4220
               ctx->hflags, btarget);
4221
    ctx->btarget = btarget;
4222

    
4223
    return;
4224
}
4225

    
4226
/* Coprocessor 1 (FPU) */
4227
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4228
{
4229
    const char *opn = "unk";
4230

    
4231
    switch (opc) {
4232
    case OPC_MFC1:
4233
        GEN_LOAD_FREG_FTN(WT0, fs);
4234
        gen_op_mfc1();
4235
        GEN_STORE_TN_REG(rt, T0);
4236
        opn = "mfc1";
4237
        break;
4238
    case OPC_MTC1:
4239
        GEN_LOAD_REG_TN(T0, rt);
4240
        gen_op_mtc1();
4241
        GEN_STORE_FTN_FREG(fs, WT0);
4242
        opn = "mtc1";
4243
        break;
4244
    case OPC_CFC1:
4245
        if (fs != 0 && fs != 31) {
4246
            MIPS_INVAL("cfc1 freg");
4247
            generate_exception (ctx, EXCP_RI);
4248
            return;
4249
        }
4250
        GEN_LOAD_IMM_TN(T1, fs);
4251
        gen_op_cfc1();
4252
        GEN_STORE_TN_REG(rt, T0);
4253
        opn = "cfc1";
4254
        break;
4255
    case OPC_CTC1:
4256
         if (fs != 0 && fs != 31) {
4257
            MIPS_INVAL("ctc1 freg");
4258
            generate_exception (ctx, EXCP_RI);
4259
            return;
4260
        }
4261
        GEN_LOAD_IMM_TN(T1, fs);
4262
        GEN_LOAD_REG_TN(T0, rt);
4263
        gen_op_ctc1();
4264
        opn = "ctc1";
4265
        break;
4266
    case OPC_DMFC1:
4267
    case OPC_DMTC1:
4268
        /* Not implemented, fallthrough. */
4269
    default:
4270
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4271
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4272
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4273
                    ((ctx->opcode >> 16) & 0x1F));
4274
        }
4275
        generate_exception (ctx, EXCP_RI);
4276
        return;
4277
    }
4278
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4279
}
4280

    
4281
/* verify if floating point register is valid; an operation is not defined
4282
 * if bit 0 of any register specification is set and the FR bit in the
4283
 * Status register equals zero, since the register numbers specify an
4284
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4285
 * in the Status register equals one, both even and odd register numbers
4286
 * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4287
 * 
4288
 * Multiple 64 bit wide registers can be checked by calling
4289
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4290
 */
4291
#define CHECK_FR(ctx, freg) do { \
4292
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4293
            generate_exception (ctx, EXCP_RI); \
4294
            return; \
4295
        } \
4296
    } while(0)
4297

    
4298
#define FOP(func, fmt) (((fmt) << 21) | (func))
4299

    
4300
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4301
{
4302
    const char *opn = "unk";
4303
    const char *condnames[] = {
4304
            "c.f",
4305
            "c.un",
4306
            "c.eq",
4307
            "c.ueq",
4308
            "c.olt",
4309
            "c.ult",
4310
            "c.ole",
4311
            "c.ule",
4312
            "c.sf",
4313
            "c.ngle",
4314
            "c.seq",
4315
            "c.ngl",
4316
            "c.lt",
4317
            "c.nge",
4318
            "c.le",
4319
            "c.ngt",
4320
    };
4321
    int binary = 0;
4322
    uint32_t func = ctx->opcode & 0x3f;
4323

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

    
4587
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4588
{
4589
    uint32_t ccbit;
4590

    
4591
    if (cc)
4592
        ccbit = 1 << (24 + cc);
4593
    else
4594
        ccbit = 1 << 23;
4595
    if (!tf)
4596
        gen_op_movf(ccbit, rd, rs);
4597
    else
4598
       gen_op_movt(ccbit, rd, rs);
4599
}
4600

    
4601
/* ISA extensions (ASEs) */
4602
/* MIPS16 extension to MIPS32 */
4603
/* SmartMIPS extension to MIPS32 */
4604

    
4605
#ifdef TARGET_MIPS64
4606
/* Coprocessor 3 (FPU) */
4607

    
4608
/* MDMX extension to MIPS64 */
4609
/* MIPS-3D extension to MIPS64 */
4610

    
4611
#endif
4612

    
4613
static void gen_blikely(DisasContext *ctx)
4614
{
4615
    int l1;
4616
    l1 = gen_new_label();
4617
    gen_op_jnz_T2(l1);
4618
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4619
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4620
    gen_set_label(l1);
4621
}
4622

    
4623
static void decode_opc (CPUState *env, DisasContext *ctx)
4624
{
4625
    int32_t offset;
4626
    int rs, rt, rd, sa;
4627
    uint32_t op, op1, op2;
4628
    int16_t imm;
4629

    
4630
    /* make sure instructions are on a word boundary */
4631
    if (ctx->pc & 0x3) {
4632
        env->CP0_BadVAddr = ctx->pc;
4633
        generate_exception(ctx, EXCP_AdEL);
4634
        return;
4635
    }
4636

    
4637
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4638
        /* Handle blikely not taken case */
4639
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4640
        gen_blikely(ctx);
4641
    }
4642
    op = MASK_OP_MAJOR(ctx->opcode);
4643
    rs = (ctx->opcode >> 21) & 0x1f;
4644
    rt = (ctx->opcode >> 16) & 0x1f;
4645
    rd = (ctx->opcode >> 11) & 0x1f;
4646
    sa = (ctx->opcode >> 6) & 0x1f;
4647
    imm = (int16_t)ctx->opcode;
4648
    switch (op) {
4649
    case OPC_SPECIAL:
4650
        op1 = MASK_SPECIAL(ctx->opcode);
4651
        switch (op1) {
4652
        case OPC_SLL:          /* Arithmetic with immediate */
4653
        case OPC_SRL ... OPC_SRA:
4654
            gen_arith_imm(ctx, op1, rd, rt, sa);
4655
            break;
4656
        case OPC_SLLV:         /* Arithmetic */
4657
        case OPC_SRLV ... OPC_SRAV:
4658
        case OPC_MOVZ ... OPC_MOVN:
4659
        case OPC_ADD ... OPC_NOR:
4660
        case OPC_SLT ... OPC_SLTU:
4661
            gen_arith(ctx, op1, rd, rs, rt);
4662
            break;
4663
        case OPC_MULT ... OPC_DIVU:
4664
            gen_muldiv(ctx, op1, rs, rt);
4665
            break;
4666
        case OPC_JR ... OPC_JALR:
4667
            gen_compute_branch(ctx, op1, rs, rd, sa);
4668
            return;
4669
        case OPC_TGE ... OPC_TEQ: /* Traps */
4670
        case OPC_TNE:
4671
            gen_trap(ctx, op1, rs, rt, -1);
4672
            break;
4673
        case OPC_MFHI:          /* Move from HI/LO */
4674
        case OPC_MFLO:
4675
            gen_HILO(ctx, op1, rd);
4676
            break;
4677
        case OPC_MTHI:
4678
        case OPC_MTLO:          /* Move to HI/LO */
4679
            gen_HILO(ctx, op1, rs);
4680
            break;
4681
        case OPC_PMON:          /* Pmon entry point */
4682
            gen_op_pmon(sa);
4683
            break;
4684
        case OPC_SYSCALL:
4685
            generate_exception(ctx, EXCP_SYSCALL);
4686
            ctx->bstate = BS_EXCP;
4687
            break;
4688
        case OPC_BREAK:
4689
            generate_exception(ctx, EXCP_BREAK);
4690
            break;
4691
        case OPC_SPIM:        /* SPIM ? */
4692
           /* Implemented as RI exception for now. */
4693
            MIPS_INVAL("spim (unofficial)");
4694
            generate_exception(ctx, EXCP_RI);
4695
            break;
4696
        case OPC_SYNC:
4697
            /* Treat as a noop. */
4698
            break;
4699

    
4700
        case OPC_MOVCI:
4701
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4702
                save_cpu_state(ctx, 1);
4703
                gen_op_cp1_enabled();
4704
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4705
                          (ctx->opcode >> 16) & 1);
4706
            } else {
4707
                generate_exception_err(ctx, EXCP_CpU, 1);
4708
            }
4709
            break;
4710

    
4711
#ifdef TARGET_MIPS64
4712
       /* MIPS64 specific opcodes */
4713
        case OPC_DSLL:
4714
        case OPC_DSRL ... OPC_DSRA:
4715
        case OPC_DSLL32:
4716
        case OPC_DSRL32 ... OPC_DSRA32:
4717
            gen_arith_imm(ctx, op1, rd, rt, sa);
4718
            break;
4719
        case OPC_DSLLV:
4720
        case OPC_DSRLV ... OPC_DSRAV:
4721
        case OPC_DADD ... OPC_DSUBU:
4722
            gen_arith(ctx, op1, rd, rs, rt);
4723
            break;
4724
        case OPC_DMULT ... OPC_DDIVU:
4725
            gen_muldiv(ctx, op1, rs, rt);
4726
            break;
4727
#endif
4728
        default:            /* Invalid */
4729
            MIPS_INVAL("special");
4730
            generate_exception(ctx, EXCP_RI);
4731
            break;
4732
        }
4733
        break;
4734
    case OPC_SPECIAL2:
4735
        op1 = MASK_SPECIAL2(ctx->opcode);
4736
        switch (op1) {
4737
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
4738
        case OPC_MSUB ... OPC_MSUBU:
4739
            gen_muldiv(ctx, op1, rs, rt);
4740
            break;
4741
        case OPC_MUL:
4742
            gen_arith(ctx, op1, rd, rs, rt);
4743
            break;
4744
        case OPC_CLZ ... OPC_CLO:
4745
            gen_cl(ctx, op1, rd, rs);
4746
            break;
4747
        case OPC_SDBBP:
4748
            /* XXX: not clear which exception should be raised
4749
             *      when in debug mode...
4750
             */
4751
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4752
                generate_exception(ctx, EXCP_DBp);
4753
            } else {
4754
                generate_exception(ctx, EXCP_DBp);
4755
            }
4756
            /* Treat as a noop */
4757
            break;
4758
#ifdef TARGET_MIPS64
4759
        case OPC_DCLZ ... OPC_DCLO:
4760
            gen_cl(ctx, op1, rd, rs);
4761
            break;
4762
#endif
4763
        default:            /* Invalid */
4764
            MIPS_INVAL("special2");
4765
            generate_exception(ctx, EXCP_RI);
4766
            break;
4767
        }
4768
        break;
4769
    case OPC_SPECIAL3:
4770
         op1 = MASK_SPECIAL3(ctx->opcode);
4771
         switch (op1) {
4772
         case OPC_EXT:
4773
         case OPC_INS:
4774
             gen_bitops(ctx, op1, rt, rs, sa, rd);
4775
             break;
4776
         case OPC_BSHFL:
4777
             op2 = MASK_BSHFL(ctx->opcode);
4778
             switch (op2) {
4779
             case OPC_WSBH:
4780
                 GEN_LOAD_REG_TN(T1, rt);
4781
                 gen_op_wsbh();
4782
                 break;
4783
             case OPC_SEB:
4784
                 GEN_LOAD_REG_TN(T1, rt);
4785
                 gen_op_seb();
4786
                 break;
4787
             case OPC_SEH:
4788
                 GEN_LOAD_REG_TN(T1, rt);
4789
                 gen_op_seh();
4790
                 break;
4791
             default:            /* Invalid */
4792
                 MIPS_INVAL("bshfl");
4793
                 generate_exception(ctx, EXCP_RI);
4794
                 break;
4795
            }
4796
            GEN_STORE_TN_REG(rd, T0);
4797
            break;
4798
        case OPC_RDHWR:
4799
            switch (rd) {
4800
            case 0:
4801
                gen_op_rdhwr_cpunum();
4802
                break;
4803
            case 1:
4804
                gen_op_rdhwr_synci_step();
4805
                break;
4806
            case 2:
4807
                gen_op_rdhwr_cc();
4808
                break;
4809
            case 3:
4810
                gen_op_rdhwr_ccres();
4811
                break;
4812
            case 29:
4813
#if defined (CONFIG_USER_ONLY)
4814
                gen_op_tls_value ();
4815
#else
4816
                generate_exception(ctx, EXCP_RI);
4817
#endif
4818
                break;
4819
            case 30:
4820
                /* Implementation dependent */;
4821
                gen_op_rdhwr_unimpl30();
4822
                break;
4823
            case 31:
4824
                /* Implementation dependent */;
4825
                gen_op_rdhwr_unimpl31();
4826
                break;
4827
            default:            /* Invalid */
4828
                MIPS_INVAL("rdhwr");
4829
                generate_exception(ctx, EXCP_RI);
4830
                break;
4831
            }
4832
            GEN_STORE_TN_REG(rt, T0);
4833
            break;
4834
#ifdef TARGET_MIPS64
4835
        case OPC_DEXTM ... OPC_DEXT:
4836
        case OPC_DINSM ... OPC_DINS:
4837
            gen_bitops(ctx, op1, rt, rs, sa, rd);
4838
            break;
4839
        case OPC_DBSHFL:
4840
            op2 = MASK_DBSHFL(ctx->opcode);
4841
            switch (op2) {
4842
            case OPC_DSBH:
4843
                GEN_LOAD_REG_TN(T1, rt);
4844
                gen_op_dsbh();
4845
                break;
4846
            case OPC_DSHD:
4847
                GEN_LOAD_REG_TN(T1, rt);
4848
                gen_op_dshd();
4849
                break;
4850
            default:            /* Invalid */
4851
                MIPS_INVAL("dbshfl");
4852
                generate_exception(ctx, EXCP_RI);
4853
                break;
4854
            }
4855
            GEN_STORE_TN_REG(rd, T0);
4856
#endif
4857
        default:            /* Invalid */
4858
            MIPS_INVAL("special3");
4859
            generate_exception(ctx, EXCP_RI);
4860
            break;
4861
        }
4862
        break;
4863
    case OPC_REGIMM:
4864
        op1 = MASK_REGIMM(ctx->opcode);
4865
        switch (op1) {
4866
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
4867
        case OPC_BLTZAL ... OPC_BGEZALL:
4868
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
4869
            return;
4870
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
4871
        case OPC_TNEI:
4872
            gen_trap(ctx, op1, rs, -1, imm);
4873
            break;
4874
        case OPC_SYNCI:
4875
            /* treat as noop */
4876
            break;
4877
        default:            /* Invalid */
4878
            MIPS_INVAL("REGIMM");
4879
            generate_exception(ctx, EXCP_RI);
4880
            break;
4881
        }
4882
        break;
4883
    case OPC_CP0:
4884
        save_cpu_state(ctx, 1);
4885
        gen_op_cp0_enabled();
4886
        op1 = MASK_CP0(ctx->opcode);
4887
        switch (op1) {
4888
        case OPC_MFC0:
4889
        case OPC_MTC0:
4890
#ifdef TARGET_MIPS64
4891
        case OPC_DMFC0:
4892
        case OPC_DMTC0:
4893
#endif
4894
            gen_cp0(ctx, op1, rt, rd);
4895
            break;
4896
        case OPC_C0_FIRST ... OPC_C0_LAST:
4897
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
4898
            break;
4899
        case OPC_MFMC0:
4900
            op2 = MASK_MFMC0(ctx->opcode);
4901
            switch (op2) {
4902
            case OPC_DI:
4903
                gen_op_di();
4904
                /* Stop translation as we may have switched the execution mode */
4905
                ctx->bstate = BS_STOP;
4906
                break;
4907
            case OPC_EI:
4908
                gen_op_ei();
4909
                /* Stop translation as we may have switched the execution mode */
4910
                ctx->bstate = BS_STOP;
4911
                break;
4912
            default:            /* Invalid */
4913
                MIPS_INVAL("MFMC0");
4914
                generate_exception(ctx, EXCP_RI);
4915
                break;
4916
            }
4917
            GEN_STORE_TN_REG(rt, T0);
4918
            break;
4919
        case OPC_RDPGPR:
4920
        case OPC_WRPGPR:
4921
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
4922
                /* Shadow registers not implemented. */
4923
                GEN_LOAD_REG_TN(T0, rt);
4924
                GEN_STORE_TN_REG(rd, T0);
4925
            } else
4926
                generate_exception(ctx, EXCP_RI);
4927
            break;
4928
        default:
4929
            generate_exception(ctx, EXCP_RI);
4930
            break;
4931
        }
4932
        break;
4933
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
4934
         gen_arith_imm(ctx, op, rt, rs, imm);
4935
         break;
4936
    case OPC_J ... OPC_JAL: /* Jump */
4937
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
4938
         gen_compute_branch(ctx, op, rs, rt, offset);
4939
         return;
4940
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
4941
    case OPC_BEQL ... OPC_BGTZL:
4942
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
4943
         return;
4944
    case OPC_LB ... OPC_LWR: /* Load and stores */
4945
    case OPC_SB ... OPC_SW:
4946
    case OPC_SWR:
4947
    case OPC_LL:
4948
    case OPC_SC:
4949
         gen_ldst(ctx, op, rt, rs, imm);
4950
         break;
4951
    case OPC_CACHE:
4952
         /* Treat as a noop */
4953
         break;
4954
    case OPC_PREF:
4955
        /* Treat as a noop */
4956
        break;
4957

    
4958
    /* Floating point.  */
4959
    case OPC_LWC1:
4960
    case OPC_LDC1:
4961
    case OPC_SWC1:
4962
    case OPC_SDC1:
4963
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4964
            save_cpu_state(ctx, 1);
4965
            gen_op_cp1_enabled();
4966
            gen_flt_ldst(ctx, op, rt, rs, imm);
4967
        } else {
4968
            generate_exception_err(ctx, EXCP_CpU, 1);
4969
        }
4970
        break;
4971

    
4972
    case OPC_CP1:
4973
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4974
            save_cpu_state(ctx, 1);
4975
            gen_op_cp1_enabled();
4976
            op1 = MASK_CP1(ctx->opcode);
4977
            switch (op1) {
4978
            case OPC_MFC1:
4979
            case OPC_CFC1:
4980
            case OPC_MTC1:
4981
            case OPC_CTC1:
4982
#ifdef TARGET_MIPS64
4983
            case OPC_DMFC1:
4984
            case OPC_DMTC1:
4985
#endif
4986
                gen_cp1(ctx, op1, rt, rd);
4987
                break;
4988
            case OPC_BC1:
4989
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
4990
                return;
4991
            case OPC_S_FMT:
4992
            case OPC_D_FMT:
4993
            case OPC_W_FMT:
4994
            case OPC_L_FMT:
4995
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
4996
                break;
4997
            default:
4998
                generate_exception (ctx, EXCP_RI);
4999
                break;
5000
            }
5001
        } else {
5002
            generate_exception_err(ctx, EXCP_CpU, 1);
5003
        }
5004
        break;
5005

    
5006
    /* COP2.  */
5007
    case OPC_LWC2:
5008
    case OPC_LDC2:
5009
    case OPC_SWC2:
5010
    case OPC_SDC2:
5011
    case OPC_CP2:
5012
        /* COP2: Not implemented. */
5013
        generate_exception_err(ctx, EXCP_CpU, 2);
5014
        break;
5015

    
5016
    case OPC_CP3:
5017
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5018
            save_cpu_state(ctx, 1);
5019
            gen_op_cp1_enabled();
5020
            op1 = MASK_CP3(ctx->opcode);
5021
            switch (op1) {
5022
            /* Not implemented */
5023
            default:
5024
                generate_exception (ctx, EXCP_RI);
5025
                break;
5026
            }
5027
        } else {
5028
            generate_exception_err(ctx, EXCP_CpU, 1);
5029
        }
5030
        break;
5031

    
5032
#ifdef TARGET_MIPS64
5033
    /* MIPS64 opcodes */
5034
    case OPC_LWU:
5035
    case OPC_LDL ... OPC_LDR:
5036
    case OPC_SDL ... OPC_SDR:
5037
    case OPC_LLD:
5038
    case OPC_LD:
5039
    case OPC_SCD:
5040
    case OPC_SD:
5041
        gen_ldst(ctx, op, rt, rs, imm);
5042
        break;
5043
    case OPC_DADDI ... OPC_DADDIU:
5044
        gen_arith_imm(ctx, op, rt, rs, imm);
5045
        break;
5046
#endif
5047
#ifdef MIPS_HAS_MIPS16
5048
    case OPC_JALX:
5049
        /* MIPS16: Not implemented. */
5050
#endif
5051
#ifdef MIPS_HAS_MDMX
5052
    case OPC_MDMX:
5053
        /* MDMX: Not implemented. */
5054
#endif
5055
    default:            /* Invalid */
5056
        MIPS_INVAL("");
5057
        generate_exception(ctx, EXCP_RI);
5058
        break;
5059
    }
5060
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5061
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5062
        /* Branches completion */
5063
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5064
        ctx->bstate = BS_BRANCH;
5065
        save_cpu_state(ctx, 0);
5066
        switch (hflags & MIPS_HFLAG_BMASK) {
5067
        case MIPS_HFLAG_B:
5068
            /* unconditional branch */
5069
            MIPS_DEBUG("unconditional branch");
5070
            gen_goto_tb(ctx, 0, ctx->btarget);
5071
            break;
5072
        case MIPS_HFLAG_BL:
5073
            /* blikely taken case */
5074
            MIPS_DEBUG("blikely branch taken");
5075
            gen_goto_tb(ctx, 0, ctx->btarget);
5076
            break;
5077
        case MIPS_HFLAG_BC:
5078
            /* Conditional branch */
5079
            MIPS_DEBUG("conditional branch");
5080
            {
5081
              int l1;
5082
              l1 = gen_new_label();
5083
              gen_op_jnz_T2(l1);
5084
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5085
              gen_set_label(l1);
5086
              gen_goto_tb(ctx, 0, ctx->btarget);
5087
            }
5088
            break;
5089
        case MIPS_HFLAG_BR:
5090
            /* unconditional branch to register */
5091
            MIPS_DEBUG("branch to register");
5092
            gen_op_breg();
5093
            break;
5094
        default:
5095
            MIPS_DEBUG("unknown branch");
5096
            break;
5097
        }
5098
    }
5099
}
5100

    
5101
static inline int
5102
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5103
                                int search_pc)
5104
{
5105
    DisasContext ctx, *ctxp = &ctx;
5106
    target_ulong pc_start;
5107
    uint16_t *gen_opc_end;
5108
    int j, lj = -1;
5109

    
5110
    if (search_pc && loglevel)
5111
        fprintf (logfile, "search pc %d\n", search_pc);
5112

    
5113
    pc_start = tb->pc;
5114
    gen_opc_ptr = gen_opc_buf;
5115
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5116
    gen_opparam_ptr = gen_opparam_buf;
5117
    nb_gen_labels = 0;
5118
    ctx.pc = pc_start;
5119
    ctx.saved_pc = -1;
5120
    ctx.tb = tb;
5121
    ctx.bstate = BS_NONE;
5122
    /* Restore delay slot state from the tb context.  */
5123
    ctx.hflags = tb->flags;
5124
    ctx.saved_hflags = ctx.hflags;
5125
    if (ctx.hflags & MIPS_HFLAG_BR) {
5126
        gen_op_restore_breg_target();
5127
    } else if (ctx.hflags & MIPS_HFLAG_B) {
5128
        ctx.btarget = env->btarget;
5129
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5130
        /* If we are in the delay slot of a conditional branch,
5131
         * restore the branch condition from env->bcond to T2
5132
         */
5133
        ctx.btarget = env->btarget;
5134
        gen_op_restore_bcond();
5135
    }
5136
#if defined(CONFIG_USER_ONLY)
5137
    ctx.mem_idx = 0;
5138
#else
5139
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5140
#endif
5141
    ctx.CP0_Status = env->CP0_Status;
5142
#ifdef DEBUG_DISAS
5143
    if (loglevel & CPU_LOG_TB_CPU) {
5144
        fprintf(logfile, "------------------------------------------------\n");
5145
        /* FIXME: This may print out stale hflags from env... */
5146
        cpu_dump_state(env, logfile, fprintf, 0);
5147
    }
5148
#endif
5149
#if defined MIPS_DEBUG_DISAS
5150
    if (loglevel & CPU_LOG_TB_IN_ASM)
5151
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5152
                tb, ctx.mem_idx, ctx.hflags);
5153
#endif
5154
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5155
        if (env->nb_breakpoints > 0) {
5156
            for(j = 0; j < env->nb_breakpoints; j++) {
5157
                if (env->breakpoints[j] == ctx.pc) {
5158
                    save_cpu_state(ctxp, 1);
5159
                    ctx.bstate = BS_BRANCH;
5160
                    gen_op_debug();
5161
                    goto done_generating;
5162
                }
5163
            }
5164
        }
5165

    
5166
        if (search_pc) {
5167
            j = gen_opc_ptr - gen_opc_buf;
5168
            if (lj < j) {
5169
                lj++;
5170
                while (lj < j)
5171
                    gen_opc_instr_start[lj++] = 0;
5172
            }
5173
            gen_opc_pc[lj] = ctx.pc;
5174
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5175
            gen_opc_instr_start[lj] = 1;
5176
        }
5177
        ctx.opcode = ldl_code(ctx.pc);
5178
        decode_opc(env, &ctx);
5179
        ctx.pc += 4;
5180

    
5181
        if (env->singlestep_enabled)
5182
            break;
5183

    
5184
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5185
            break;
5186

    
5187
#if defined (MIPS_SINGLE_STEP)
5188
        break;
5189
#endif
5190
    }
5191
    if (env->singlestep_enabled) {
5192
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5193
        gen_op_debug();
5194
        goto done_generating;
5195
    }
5196
    else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
5197
        save_cpu_state(ctxp, 0);
5198
        gen_goto_tb(&ctx, 0, ctx.pc);
5199
    }
5200
    gen_op_reset_T0();
5201
    /* Generate the return instruction */
5202
    gen_op_exit_tb();
5203
done_generating:
5204
    *gen_opc_ptr = INDEX_op_end;
5205
    if (search_pc) {
5206
        j = gen_opc_ptr - gen_opc_buf;
5207
        lj++;
5208
        while (lj <= j)
5209
            gen_opc_instr_start[lj++] = 0;
5210
        tb->size = 0;
5211
    } else {
5212
        tb->size = ctx.pc - pc_start;
5213
    }
5214
#ifdef DEBUG_DISAS
5215
#if defined MIPS_DEBUG_DISAS
5216
    if (loglevel & CPU_LOG_TB_IN_ASM)
5217
        fprintf(logfile, "\n");
5218
#endif
5219
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5220
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5221
    target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5222
        fprintf(logfile, "\n");
5223
    }
5224
    if (loglevel & CPU_LOG_TB_OP) {
5225
        fprintf(logfile, "OP:\n");
5226
        dump_ops(gen_opc_buf, gen_opparam_buf);
5227
        fprintf(logfile, "\n");
5228
    }
5229
    if (loglevel & CPU_LOG_TB_CPU) {
5230
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5231
    }
5232
#endif
5233
    
5234
    return 0;
5235
}
5236

    
5237
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5238
{
5239
    return gen_intermediate_code_internal(env, tb, 0);
5240
}
5241

    
5242
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5243
{
5244
    return gen_intermediate_code_internal(env, tb, 1);
5245
}
5246

    
5247
void fpu_dump_state(CPUState *env, FILE *f, 
5248
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5249
                    int flags)
5250
{
5251
    int i;
5252

    
5253
#   define printfpr(fp) do { \
5254
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5255
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5256
    } while(0)
5257

    
5258
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5259
                env->fcr0, env->fcr31,
5260
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5261
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5262
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5263
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5264
    for(i = 0; i < 32; i += 2) {
5265
        fpu_fprintf(f, "%s: ", fregnames[i]);
5266
        printfpr(FPR(env, i));
5267
    }
5268

    
5269
#undef printfpr
5270
}
5271

    
5272
void dump_fpu (CPUState *env)
5273
{
5274
    if (loglevel) { 
5275
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5276
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5277
       fpu_dump_state(env, logfile, fprintf, 0);
5278
    }
5279
}
5280

    
5281
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5282
/* Debug help: The architecture requires 32bit code to maintain proper
5283
   sign-extened values on 64bit machines.  */
5284

    
5285
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5286

    
5287
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5288
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5289
                     int flags)
5290
{
5291
    int i;
5292

    
5293
    if (!SIGN_EXT_P(env->PC))
5294
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5295
    if (!SIGN_EXT_P(env->HI))
5296
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5297
    if (!SIGN_EXT_P(env->LO))
5298
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5299
    if (!SIGN_EXT_P(env->btarget))
5300
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5301

    
5302
    for (i = 0; i < 32; i++) {
5303
        if (!SIGN_EXT_P(env->gpr[i]))
5304
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5305
    }
5306

    
5307
    if (!SIGN_EXT_P(env->CP0_EPC))
5308
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5309
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5310
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5311
}
5312
#endif
5313

    
5314
void cpu_dump_state (CPUState *env, FILE *f, 
5315
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5316
                     int flags)
5317
{
5318
    uint32_t c0_status;
5319
    int i;
5320
    
5321
    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",
5322
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5323
    for (i = 0; i < 32; i++) {
5324
        if ((i & 3) == 0)
5325
            cpu_fprintf(f, "GPR%02d:", i);
5326
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5327
        if ((i & 3) == 3)
5328
            cpu_fprintf(f, "\n");
5329
    }
5330

    
5331
    c0_status = env->CP0_Status;
5332

    
5333
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5334
                c0_status, env->CP0_Cause, env->CP0_EPC);
5335
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5336
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5337
    if (c0_status & (1 << CP0St_CU1))
5338
        fpu_dump_state(env, f, cpu_fprintf, flags);
5339
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5340
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5341
#endif
5342
}
5343

    
5344
CPUMIPSState *cpu_mips_init (void)
5345
{
5346
    CPUMIPSState *env;
5347

    
5348
    env = qemu_mallocz(sizeof(CPUMIPSState));
5349
    if (!env)
5350
        return NULL;
5351
    cpu_exec_init(env);
5352
    cpu_reset(env);
5353
    return env;
5354
}
5355

    
5356
void cpu_reset (CPUMIPSState *env)
5357
{
5358
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5359

    
5360
    tlb_flush(env, 1);
5361

    
5362
    /* Minimal init */
5363
#if !defined(CONFIG_USER_ONLY)
5364
    if (env->hflags & MIPS_HFLAG_BMASK) {
5365
        /* If the exception was raised from a delay slot,
5366
         * come back to the jump.  */
5367
        env->CP0_ErrorEPC = env->PC - 4;
5368
        env->hflags &= ~MIPS_HFLAG_BMASK;
5369
    } else {
5370
        env->CP0_ErrorEPC = env->PC;
5371
    }
5372
    env->hflags = 0;
5373
    env->PC = (int32_t)0xBFC00000;
5374
#if defined (MIPS_USES_R4K_TLB)
5375
    env->CP0_Random = MIPS_TLB_NB - 1;
5376
    env->tlb_in_use = MIPS_TLB_NB;
5377
#endif
5378
    env->CP0_Wired = 0;
5379
    /* SMP not implemented */
5380
    env->CP0_EBase = 0x80000000;
5381
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5382
    env->CP0_WatchLo = 0;
5383
    /* Count register increments in debug mode, EJTAG version 1 */
5384
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5385
#endif
5386
    env->exception_index = EXCP_NONE;
5387
#if defined(CONFIG_USER_ONLY)
5388
    env->hflags |= MIPS_HFLAG_UM;
5389
    env->user_mode_only = 1;
5390
#endif
5391
    /* XXX some guesswork here, values are CPU specific */
5392
    env->SYNCI_Step = 16;
5393
    env->CCRes = 2;
5394
}
5395

    
5396
#include "translate_init.c"