Statistics
| Branch: | Revision:

root / target-mips / translate.c @ b29a0341

History | View | Annotate | Download (138.9 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
#ifdef MIPS_USES_FPU
395

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

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

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

    
434
SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
435
SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
436

    
437
SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
438
SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
439

    
440
SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
441
SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
442

    
443
DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
444
DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
445

    
446
DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
447
DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
448

    
449
DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
450
DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
451

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

    
476
FOP_CONDS(d)
477
FOP_CONDS(s)
478

    
479
#endif /* MIPS_USES_FPU */
480

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

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

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

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

    
520
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
521
do {                                                                          \
522
    if (Rn == 0) {                                                            \
523
        glue(gen_op_reset_, Tn)();                                            \
524
    } else {                                                                  \
525
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
526
    }                                                                         \
527
} while (0)
528

    
529
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
530
do {                                                                          \
531
    if (Imm == 0) {                                                           \
532
        glue(gen_op_reset_, Tn)();                                            \
533
    } else {                                                                  \
534
        glue(gen_op_set_, Tn)(Imm);                                           \
535
    }                                                                         \
536
} while (0)
537

    
538
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
539
do {                                                                          \
540
    if (Rn != 0) {                                                            \
541
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
542
    }                                                                         \
543
} while (0)
544

    
545
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
546
do {                                                                          \
547
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
548
} while (0)
549

    
550
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
551
do {                                                                          \
552
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
553
} while (0)
554

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

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

    
595
static inline void generate_exception (DisasContext *ctx, int excp)
596
{
597
    generate_exception_err (ctx, excp, 0);
598
}
599

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

    
618
#ifdef MIPS_HAS_MIPS64
619
OP_LD_TABLE(d);
620
OP_LD_TABLE(dl);
621
OP_LD_TABLE(dr);
622
OP_ST_TABLE(d);
623
OP_ST_TABLE(dl);
624
OP_ST_TABLE(dr);
625
OP_LD_TABLE(ld);
626
OP_ST_TABLE(cd);
627
#endif
628
OP_LD_TABLE(w);
629
OP_LD_TABLE(wu);
630
OP_LD_TABLE(wl);
631
OP_LD_TABLE(wr);
632
OP_ST_TABLE(w);
633
OP_ST_TABLE(wl);
634
OP_ST_TABLE(wr);
635
OP_LD_TABLE(h);
636
OP_LD_TABLE(hu);
637
OP_ST_TABLE(h);
638
OP_LD_TABLE(b);
639
OP_LD_TABLE(bu);
640
OP_ST_TABLE(b);
641
OP_LD_TABLE(l);
642
OP_ST_TABLE(c);
643
#ifdef MIPS_USES_FPU
644
OP_LD_TABLE(wc1);
645
OP_ST_TABLE(wc1);
646
OP_LD_TABLE(dc1);
647
OP_ST_TABLE(dc1);
648
#endif
649

    
650
/* Load and store */
651
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
652
                      int base, int16_t offset)
653
{
654
    const char *opn = "unk";
655

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

    
797
#ifdef MIPS_USES_FPU
798

    
799
/* Load and store */
800
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
801
                      int base, int16_t offset)
802
{
803
    const char *opn = "unk";
804

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

    
846
#endif /* MIPS_USES_FPU */
847

    
848
/* Arithmetic with immediate operand */
849
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
850
                           int rs, int16_t imm)
851
{
852
    uint32_t uimm;
853
    const char *opn = "unk";
854

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

    
981
/* Arithmetic */
982
static void gen_arith (DisasContext *ctx, uint32_t opc,
983
                       int rd, int rs, int rt)
984
{
985
    const char *opn = "unk";
986

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

    
1118
/* Arithmetic on HI/LO registers */
1119
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1120
{
1121
    const char *opn = "unk";
1122

    
1123
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1124
        /* Treat as a NOP */
1125
        MIPS_DEBUG("NOP");
1126
        return;
1127
    }
1128
    switch (opc) {
1129
    case OPC_MFHI:
1130
        gen_op_load_HI();
1131
        GEN_STORE_TN_REG(reg, T0);
1132
        opn = "mfhi";
1133
        break;
1134
    case OPC_MFLO:
1135
        gen_op_load_LO();
1136
        GEN_STORE_TN_REG(reg, T0);
1137
        opn = "mflo";
1138
        break;
1139
    case OPC_MTHI:
1140
        GEN_LOAD_REG_TN(T0, reg);
1141
        gen_op_store_HI();
1142
        opn = "mthi";
1143
        break;
1144
    case OPC_MTLO:
1145
        GEN_LOAD_REG_TN(T0, reg);
1146
        gen_op_store_LO();
1147
        opn = "mtlo";
1148
        break;
1149
    default:
1150
        MIPS_INVAL("HILO");
1151
        generate_exception(ctx, EXCP_RI);
1152
        return;
1153
    }
1154
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1155
}
1156

    
1157
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1158
                        int rs, int rt)
1159
{
1160
    const char *opn = "unk";
1161

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

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

    
1261
/* Traps */
1262
static void gen_trap (DisasContext *ctx, uint32_t opc,
1263
                      int rs, int rt, int16_t imm)
1264
{
1265
    int cond;
1266

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

    
1358
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1359
{
1360
    TranslationBlock *tb;
1361
    tb = ctx->tb;
1362
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1363
        if (n == 0)
1364
            gen_op_goto_tb0(TBPARAM(tb));
1365
        else
1366
            gen_op_goto_tb1(TBPARAM(tb));
1367
        gen_op_save_pc(dest);
1368
        gen_op_set_T0((long)tb + n);
1369
        gen_op_exit_tb();
1370
    } else {
1371
        gen_op_save_pc(dest);
1372
        gen_op_set_T0(0);
1373
        gen_op_exit_tb();
1374
    }
1375
}
1376

    
1377
/* Branches (before delay slot) */
1378
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1379
                                int rs, int rt, int32_t offset)
1380
{
1381
    target_ulong btarget;
1382
    int blink, bcond;
1383

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

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

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

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

    
2227
die:
2228
#if defined MIPS_DEBUG_DISAS
2229
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2230
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2231
                rn, reg, sel);
2232
    }
2233
#endif
2234
    generate_exception(ctx, EXCP_RI);
2235
}
2236

    
2237
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2238
{
2239
    const char *rn = "invalid";
2240

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

    
2820
die:
2821
#if defined MIPS_DEBUG_DISAS
2822
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2823
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2824
                rn, reg, sel);
2825
    }
2826
#endif
2827
    generate_exception(ctx, EXCP_RI);
2828
}
2829

    
2830
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2831
{
2832
    const char *rn = "invalid";
2833

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

    
3402
die:
3403
#if defined MIPS_DEBUG_DISAS
3404
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3405
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3406
                rn, reg, sel);
3407
    }
3408
#endif
3409
    generate_exception(ctx, EXCP_RI);
3410
}
3411

    
3412
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3413
{
3414
    const char *rn = "invalid";
3415

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

    
3995
die:
3996
#if defined MIPS_DEBUG_DISAS
3997
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3998
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
3999
                rn, reg, sel);
4000
    }
4001
#endif
4002
    generate_exception(ctx, EXCP_RI);
4003
}
4004

    
4005
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4006
{
4007
    const char *opn = "unk";
4008

    
4009
    if ((!ctx->CP0_Status & (1 << CP0St_CU0) &&
4010
          (ctx->hflags & MIPS_HFLAG_UM)) &&
4011
        !(ctx->hflags & MIPS_HFLAG_ERL) &&
4012
        !(ctx->hflags & MIPS_HFLAG_EXL)) {
4013
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4014
            fprintf(logfile, "CP0 is not usable\n");
4015
        }
4016
        generate_exception (ctx, EXCP_CpU);
4017
        return;
4018
    }
4019

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

    
4114
#ifdef MIPS_USES_FPU
4115

    
4116
/* CP1 Branches (before delay slot) */
4117
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4118
                                 int32_t offset)
4119
{
4120
    target_ulong btarget;
4121

    
4122
    btarget = ctx->pc + 4 + offset;
4123

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

    
4152
    MIPS_DEBUG("enter ds: cond %02x target " TLSZ,
4153
               ctx->hflags, btarget);
4154
    ctx->btarget = btarget;
4155

    
4156
    return;
4157
}
4158

    
4159
/* Coprocessor 1 (FPU) */
4160
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4161
{
4162
    const char *opn = "unk";
4163

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

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

    
4231
#define FOP(func, fmt) (((fmt) << 21) | (func))
4232

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

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

    
4533
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4534
{
4535
    uint32_t ccbit;
4536

    
4537
    if (cc)
4538
        ccbit = 1 << (24 + cc);
4539
    else
4540
        ccbit = 1 << 23;
4541
    if (!tf)
4542
        gen_op_movf(ccbit, rd, rs);
4543
    else
4544
       gen_op_movt(ccbit, rd, rs);
4545
}
4546

    
4547
#endif /* MIPS_USES_FPU */
4548

    
4549
/* ISA extensions (ASEs) */
4550
/* MIPS16 extension to MIPS32 */
4551
/* SmartMIPS extension to MIPS32 */
4552

    
4553
#ifdef MIPS_HAS_MIPS64
4554
/* Coprocessor 3 (FPU) */
4555

    
4556
/* MDMX extension to MIPS64 */
4557
/* MIPS-3D extension to MIPS64 */
4558

    
4559
#endif
4560

    
4561
static void gen_blikely(DisasContext *ctx)
4562
{
4563
    int l1;
4564
    l1 = gen_new_label();
4565
    gen_op_jnz_T2(l1);
4566
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4567
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4568
    gen_set_label(l1);
4569
}
4570

    
4571
static void decode_opc (DisasContext *ctx)
4572
{
4573
    int32_t offset;
4574
    int rs, rt, rd, sa;
4575
    uint32_t op, op1, op2;
4576
    int16_t imm;
4577

    
4578
    /* make sure instructions are on a word boundary */
4579
    if (ctx->pc & 0x3) {
4580
        generate_exception(ctx, EXCP_AdEL);
4581
        return;
4582
    }
4583

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

    
4647
#ifdef MIPS_USES_FPU
4648
        case OPC_MOVCI:
4649
            gen_op_cp1_enabled();
4650
            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4651
                      (ctx->opcode >> 16) & 1);
4652
            break;
4653
#endif
4654

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

    
4879
    /* Floating point.  */
4880
    case OPC_LWC1:
4881
    case OPC_LDC1:
4882
    case OPC_SWC1:
4883
    case OPC_SDC1:
4884
#if defined(MIPS_USES_FPU)
4885
        save_cpu_state(ctx, 1);
4886
        gen_op_cp1_enabled();
4887
        gen_flt_ldst(ctx, op, rt, rs, imm);
4888
#else
4889
        generate_exception_err(ctx, EXCP_CpU, 1);
4890
#endif
4891
        break;
4892

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

    
4927
    /* COP2.  */
4928
    case OPC_LWC2:
4929
    case OPC_LDC2:
4930
    case OPC_SWC2:
4931
    case OPC_SDC2:
4932
    case OPC_CP2:
4933
        /* COP2: Not implemented. */
4934
        generate_exception_err(ctx, EXCP_CpU, 2);
4935
        break;
4936

    
4937
#ifdef MIPS_USES_FPU
4938
    case OPC_CP3:
4939
        gen_op_cp1_enabled();
4940
        op1 = MASK_CP3(ctx->opcode);
4941
        switch (op1) {
4942
        /* Not implemented */
4943
        default:
4944
            generate_exception_err(ctx, EXCP_RI, 1);
4945
            break;
4946
        }
4947
        break;
4948
#endif
4949

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

    
5019
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5020
                                    int search_pc)
5021
{
5022
    DisasContext ctx, *ctxp = &ctx;
5023
    target_ulong pc_start;
5024
    uint16_t *gen_opc_end;
5025
    int j, lj = -1;
5026

    
5027
    if (search_pc && loglevel)
5028
        fprintf (logfile, "search pc %d\n", search_pc);
5029

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

    
5083
        if (search_pc) {
5084
            j = gen_opc_ptr - gen_opc_buf;
5085
            if (lj < j) {
5086
                lj++;
5087
                while (lj < j)
5088
                    gen_opc_instr_start[lj++] = 0;
5089
            }
5090
            gen_opc_pc[lj] = ctx.pc;
5091
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5092
            gen_opc_instr_start[lj] = 1;
5093
        }
5094
        ctx.opcode = ldl_code(ctx.pc);
5095
        decode_opc(&ctx);
5096
        ctx.pc += 4;
5097

    
5098
        if (env->singlestep_enabled)
5099
            break;
5100

    
5101
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5102
            break;
5103

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

    
5154
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5155
{
5156
    return gen_intermediate_code_internal(env, tb, 0);
5157
}
5158

    
5159
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5160
{
5161
    return gen_intermediate_code_internal(env, tb, 1);
5162
}
5163

    
5164
#ifdef MIPS_USES_FPU
5165

    
5166
void fpu_dump_state(CPUState *env, FILE *f, 
5167
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5168
                    int flags)
5169
{
5170
    int i;
5171

    
5172
#   define printfpr(fp) do { \
5173
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5174
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5175
    } while(0)
5176

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

    
5188
#undef printfpr
5189
}
5190

    
5191
void dump_fpu (CPUState *env)
5192
{
5193
    if (loglevel) { 
5194
       fprintf(logfile, "pc=0x" TLSZ " HI=0x" TLSZ " LO=0x" TLSZ " ds %04x " TLSZ " %d\n",
5195
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5196
       fpu_dump_state(env, logfile, fprintf, 0);
5197
    }
5198
}
5199

    
5200
#endif /* MIPS_USES_FPU */
5201

    
5202
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5203
/* Debug help: The architecture requires 32bit code to maintain proper
5204
   sign-extened values on 64bit machines.  */
5205

    
5206
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5207

    
5208
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5209
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5210
                     int flags)
5211
{
5212
    int i;
5213

    
5214
    if (!SIGN_EXT_P(env->PC))
5215
        cpu_fprintf(f, "BROKEN: pc=0x" TLSZ "\n", env->PC);
5216
    if (!SIGN_EXT_P(env->HI))
5217
        cpu_fprintf(f, "BROKEN: HI=0x" TLSZ "\n", env->HI);
5218
    if (!SIGN_EXT_P(env->LO))
5219
        cpu_fprintf(f, "BROKEN: LO=0x" TLSZ "\n", env->LO);
5220
    if (!SIGN_EXT_P(env->btarget))
5221
        cpu_fprintf(f, "BROKEN: btarget=0x" TLSZ "\n", env->btarget);
5222

    
5223
    for (i = 0; i < 32; i++) {
5224
        if (!SIGN_EXT_P(env->gpr[i]))
5225
            cpu_fprintf(f, "BROKEN: %s=0x" TLSZ "\n", regnames[i], env->gpr[i]);
5226
    }
5227

    
5228
    if (!SIGN_EXT_P(env->CP0_EPC))
5229
        cpu_fprintf(f, "BROKEN: EPC=0x" TLSZ "\n", env->CP0_EPC);
5230
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5231
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TLSZ "\n", env->CP0_LLAddr);
5232
}
5233
#endif
5234

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

    
5252
    c0_status = env->CP0_Status;
5253
    if (env->hflags & MIPS_HFLAG_UM)
5254
        c0_status |= (1 << CP0St_UM);
5255
    if (env->hflags & MIPS_HFLAG_ERL)
5256
        c0_status |= (1 << CP0St_ERL);
5257
    if (env->hflags & MIPS_HFLAG_EXL)
5258
        c0_status |= (1 << CP0St_EXL);
5259

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

    
5273
CPUMIPSState *cpu_mips_init (void)
5274
{
5275
    CPUMIPSState *env;
5276

    
5277
    env = qemu_mallocz(sizeof(CPUMIPSState));
5278
    if (!env)
5279
        return NULL;
5280
    cpu_exec_init(env);
5281
    cpu_reset(env);
5282
    return env;
5283
}
5284

    
5285
void cpu_reset (CPUMIPSState *env)
5286
{
5287
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5288

    
5289
    tlb_flush(env, 1);
5290

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