Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 97428a4d

History | View | Annotate | Download (141.8 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL,
146
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
147
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
148
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
149
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
150
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
151
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
152
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
153
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
154
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
156
    /* Multiplication / division */
157
    OPC_MULT     = 0x18 | OPC_SPECIAL,
158
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
159
    OPC_DIV      = 0x1A | OPC_SPECIAL,
160
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
161
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
162
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
163
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
164
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
165
    /* 2 registers arithmetic / logic */
166
    OPC_ADD      = 0x20 | OPC_SPECIAL,
167
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
168
    OPC_SUB      = 0x22 | OPC_SPECIAL,
169
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
170
    OPC_AND      = 0x24 | OPC_SPECIAL,
171
    OPC_OR       = 0x25 | OPC_SPECIAL,
172
    OPC_XOR      = 0x26 | OPC_SPECIAL,
173
    OPC_NOR      = 0x27 | OPC_SPECIAL,
174
    OPC_SLT      = 0x2A | OPC_SPECIAL,
175
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
176
    OPC_DADD     = 0x2C | OPC_SPECIAL,
177
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
178
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
179
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
180
    /* Jumps */
181
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
183
    /* Traps */
184
    OPC_TGE      = 0x30 | OPC_SPECIAL,
185
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
186
    OPC_TLT      = 0x32 | OPC_SPECIAL,
187
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
188
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
189
    OPC_TNE      = 0x36 | OPC_SPECIAL,
190
    /* HI / LO registers load & stores */
191
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
192
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
193
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
194
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
195
    /* Conditional moves */
196
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
198

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

    
201
    /* Special */
202
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
203
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
205
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
206
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
207

    
208
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215
};
216

    
217
/* REGIMM (rt field) opcodes */
218
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219

    
220
enum {
221
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
222
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
223
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
224
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
225
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
226
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
227
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
228
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
229
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
230
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
231
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
232
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
233
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
234
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
235
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
236
};
237

    
238
/* Special2 opcodes */
239
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
240

    
241
enum {
242
    /* Multiply & xxx operations */
243
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
244
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
245
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
246
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
247
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
248
    /* Misc */
249
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
250
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
251
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
252
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
253
    /* Special */
254
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
255
};
256

    
257
/* Special3 opcodes */
258
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
259

    
260
enum {
261
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
262
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
263
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
264
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
265
    OPC_INS      = 0x04 | OPC_SPECIAL3,
266
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
267
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
268
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
269
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
270
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
271
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
272
};
273

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

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

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

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

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

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

    
307
/* MFMC0 opcodes */
308
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & ((0x0C << 11) | (1 << 5)))
309

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

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

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

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

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

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

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

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

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

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

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

    
399

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
511
FOP_CONDS(d)
512
FOP_CONDS(s)
513

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2947
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2948
{
2949
    const char *rn = "invalid";
2950

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

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

    
3529
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3530
{
3531
    const char *rn = "invalid";
3532

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

    
4112
die:
4113
#if defined MIPS_DEBUG_DISAS
4114
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4115
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4116
                rn, reg, sel);
4117
    }
4118
#endif
4119
    generate_exception(ctx, EXCP_RI);
4120
}
4121

    
4122
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4123
{
4124
    const char *opn = "unk";
4125

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

    
4210
/* CP1 Branches (before delay slot) */
4211
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4212
                                 int32_t offset)
4213
{
4214
    target_ulong btarget;
4215

    
4216
    btarget = ctx->pc + 4 + offset;
4217

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

    
4246
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4247
               ctx->hflags, btarget);
4248
    ctx->btarget = btarget;
4249

    
4250
    return;
4251
}
4252

    
4253
/* Coprocessor 1 (FPU) */
4254
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4255
{
4256
    const char *opn = "unk";
4257

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

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

    
4325
#define FOP(func, fmt) (((fmt) << 21) | (func))
4326

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

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

    
4614
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4615
{
4616
    uint32_t ccbit;
4617

    
4618
    if (cc)
4619
        ccbit = 1 << (24 + cc);
4620
    else
4621
        ccbit = 1 << 23;
4622
    if (!tf)
4623
        gen_op_movf(ccbit, rd, rs);
4624
    else
4625
       gen_op_movt(ccbit, rd, rs);
4626
}
4627

    
4628
/* ISA extensions (ASEs) */
4629
/* MIPS16 extension to MIPS32 */
4630
/* SmartMIPS extension to MIPS32 */
4631

    
4632
#ifdef TARGET_MIPS64
4633
/* Coprocessor 3 (FPU) */
4634

    
4635
/* MDMX extension to MIPS64 */
4636
/* MIPS-3D extension to MIPS64 */
4637

    
4638
#endif
4639

    
4640
static void gen_blikely(DisasContext *ctx)
4641
{
4642
    int l1;
4643
    l1 = gen_new_label();
4644
    gen_op_jnz_T2(l1);
4645
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4646
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4647
    gen_set_label(l1);
4648
}
4649

    
4650
static void decode_opc (CPUState *env, DisasContext *ctx)
4651
{
4652
    int32_t offset;
4653
    int rs, rt, rd, sa;
4654
    uint32_t op, op1, op2;
4655
    int16_t imm;
4656

    
4657
    /* make sure instructions are on a word boundary */
4658
    if (ctx->pc & 0x3) {
4659
        env->CP0_BadVAddr = ctx->pc;
4660
        generate_exception(ctx, EXCP_AdEL);
4661
        return;
4662
    }
4663

    
4664
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4665
        /* Handle blikely not taken case */
4666
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4667
        gen_blikely(ctx);
4668
    }
4669
    op = MASK_OP_MAJOR(ctx->opcode);
4670
    rs = (ctx->opcode >> 21) & 0x1f;
4671
    rt = (ctx->opcode >> 16) & 0x1f;
4672
    rd = (ctx->opcode >> 11) & 0x1f;
4673
    sa = (ctx->opcode >> 6) & 0x1f;
4674
    imm = (int16_t)ctx->opcode;
4675
    switch (op) {
4676
    case OPC_SPECIAL:
4677
        op1 = MASK_SPECIAL(ctx->opcode);
4678
        switch (op1) {
4679
        case OPC_SLL:          /* Arithmetic with immediate */
4680
        case OPC_SRL ... OPC_SRA:
4681
            gen_arith_imm(ctx, op1, rd, rt, sa);
4682
            break;
4683
        case OPC_SLLV:         /* Arithmetic */
4684
        case OPC_SRLV ... OPC_SRAV:
4685
        case OPC_MOVZ ... OPC_MOVN:
4686
        case OPC_ADD ... OPC_NOR:
4687
        case OPC_SLT ... OPC_SLTU:
4688
            gen_arith(ctx, op1, rd, rs, rt);
4689
            break;
4690
        case OPC_MULT ... OPC_DIVU:
4691
            gen_muldiv(ctx, op1, rs, rt);
4692
            break;
4693
        case OPC_JR ... OPC_JALR:
4694
            gen_compute_branch(ctx, op1, rs, rd, sa);
4695
            return;
4696
        case OPC_TGE ... OPC_TEQ: /* Traps */
4697
        case OPC_TNE:
4698
            gen_trap(ctx, op1, rs, rt, -1);
4699
            break;
4700
        case OPC_MFHI:          /* Move from HI/LO */
4701
        case OPC_MFLO:
4702
            gen_HILO(ctx, op1, rd);
4703
            break;
4704
        case OPC_MTHI:
4705
        case OPC_MTLO:          /* Move to HI/LO */
4706
            gen_HILO(ctx, op1, rs);
4707
            break;
4708
        case OPC_PMON:          /* Pmon entry point */
4709
            gen_op_pmon(sa);
4710
            break;
4711
        case OPC_SYSCALL:
4712
            generate_exception(ctx, EXCP_SYSCALL);
4713
            ctx->bstate = BS_EXCP;
4714
            break;
4715
        case OPC_BREAK:
4716
            generate_exception(ctx, EXCP_BREAK);
4717
            break;
4718
        case OPC_SPIM:        /* SPIM ? */
4719
           /* Implemented as RI exception for now. */
4720
            MIPS_INVAL("spim (unofficial)");
4721
            generate_exception(ctx, EXCP_RI);
4722
            break;
4723
        case OPC_SYNC:
4724
            /* Treat as a noop. */
4725
            break;
4726

    
4727
        case OPC_MOVCI:
4728
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4729
                save_cpu_state(ctx, 1);
4730
                gen_op_cp1_enabled();
4731
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4732
                          (ctx->opcode >> 16) & 1);
4733
            } else {
4734
                generate_exception_err(ctx, EXCP_CpU, 1);
4735
            }
4736
            break;
4737

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

    
4979
    /* Floating point.  */
4980
    case OPC_LWC1:
4981
    case OPC_LDC1:
4982
    case OPC_SWC1:
4983
    case OPC_SDC1:
4984
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4985
            save_cpu_state(ctx, 1);
4986
            gen_op_cp1_enabled();
4987
            gen_flt_ldst(ctx, op, rt, rs, imm);
4988
        } else {
4989
            generate_exception_err(ctx, EXCP_CpU, 1);
4990
        }
4991
        break;
4992

    
4993
    case OPC_CP1:
4994
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4995
            save_cpu_state(ctx, 1);
4996
            gen_op_cp1_enabled();
4997
            op1 = MASK_CP1(ctx->opcode);
4998
            switch (op1) {
4999
            case OPC_MFC1:
5000
            case OPC_CFC1:
5001
            case OPC_MTC1:
5002
            case OPC_CTC1:
5003
#ifdef TARGET_MIPS64
5004
            case OPC_DMFC1:
5005
            case OPC_DMTC1:
5006
#endif
5007
                gen_cp1(ctx, op1, rt, rd);
5008
                break;
5009
            case OPC_BC1:
5010
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
5011
                return;
5012
            case OPC_S_FMT:
5013
            case OPC_D_FMT:
5014
            case OPC_W_FMT:
5015
            case OPC_L_FMT:
5016
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
5017
                break;
5018
            default:
5019
                generate_exception (ctx, EXCP_RI);
5020
                break;
5021
            }
5022
        } else {
5023
            generate_exception_err(ctx, EXCP_CpU, 1);
5024
        }
5025
        break;
5026

    
5027
    /* COP2.  */
5028
    case OPC_LWC2:
5029
    case OPC_LDC2:
5030
    case OPC_SWC2:
5031
    case OPC_SDC2:
5032
    case OPC_CP2:
5033
        /* COP2: Not implemented. */
5034
        generate_exception_err(ctx, EXCP_CpU, 2);
5035
        break;
5036

    
5037
    case OPC_CP3:
5038
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5039
            save_cpu_state(ctx, 1);
5040
            gen_op_cp1_enabled();
5041
            op1 = MASK_CP3(ctx->opcode);
5042
            switch (op1) {
5043
            case OPC_PREFX:
5044
                /* treat as noop */
5045
                break;
5046
            /* Not implemented */
5047
            default:
5048
                generate_exception (ctx, EXCP_RI);
5049
                break;
5050
            }
5051
        } else {
5052
            generate_exception_err(ctx, EXCP_CpU, 1);
5053
        }
5054
        break;
5055

    
5056
#ifdef TARGET_MIPS64
5057
    /* MIPS64 opcodes */
5058
    case OPC_LWU:
5059
    case OPC_LDL ... OPC_LDR:
5060
    case OPC_SDL ... OPC_SDR:
5061
    case OPC_LLD:
5062
    case OPC_LD:
5063
    case OPC_SCD:
5064
    case OPC_SD:
5065
        gen_ldst(ctx, op, rt, rs, imm);
5066
        break;
5067
    case OPC_DADDI ... OPC_DADDIU:
5068
        gen_arith_imm(ctx, op, rt, rs, imm);
5069
        break;
5070
#endif
5071
#ifdef MIPS_HAS_MIPS16
5072
    case OPC_JALX:
5073
        /* MIPS16: Not implemented. */
5074
#endif
5075
#ifdef MIPS_HAS_MDMX
5076
    case OPC_MDMX:
5077
        /* MDMX: Not implemented. */
5078
#endif
5079
    default:            /* Invalid */
5080
        MIPS_INVAL("");
5081
        generate_exception(ctx, EXCP_RI);
5082
        break;
5083
    }
5084
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5085
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5086
        /* Branches completion */
5087
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5088
        ctx->bstate = BS_BRANCH;
5089
        save_cpu_state(ctx, 0);
5090
        switch (hflags & MIPS_HFLAG_BMASK) {
5091
        case MIPS_HFLAG_B:
5092
            /* unconditional branch */
5093
            MIPS_DEBUG("unconditional branch");
5094
            gen_goto_tb(ctx, 0, ctx->btarget);
5095
            break;
5096
        case MIPS_HFLAG_BL:
5097
            /* blikely taken case */
5098
            MIPS_DEBUG("blikely branch taken");
5099
            gen_goto_tb(ctx, 0, ctx->btarget);
5100
            break;
5101
        case MIPS_HFLAG_BC:
5102
            /* Conditional branch */
5103
            MIPS_DEBUG("conditional branch");
5104
            {
5105
              int l1;
5106
              l1 = gen_new_label();
5107
              gen_op_jnz_T2(l1);
5108
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5109
              gen_set_label(l1);
5110
              gen_goto_tb(ctx, 0, ctx->btarget);
5111
            }
5112
            break;
5113
        case MIPS_HFLAG_BR:
5114
            /* unconditional branch to register */
5115
            MIPS_DEBUG("branch to register");
5116
            gen_op_breg();
5117
            break;
5118
        default:
5119
            MIPS_DEBUG("unknown branch");
5120
            break;
5121
        }
5122
    }
5123
}
5124

    
5125
static inline int
5126
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5127
                                int search_pc)
5128
{
5129
    DisasContext ctx, *ctxp = &ctx;
5130
    target_ulong pc_start;
5131
    uint16_t *gen_opc_end;
5132
    int j, lj = -1;
5133

    
5134
    if (search_pc && loglevel)
5135
        fprintf (logfile, "search pc %d\n", search_pc);
5136

    
5137
    pc_start = tb->pc;
5138
    gen_opc_ptr = gen_opc_buf;
5139
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5140
    gen_opparam_ptr = gen_opparam_buf;
5141
    nb_gen_labels = 0;
5142
    ctx.pc = pc_start;
5143
    ctx.saved_pc = -1;
5144
    ctx.tb = tb;
5145
    ctx.bstate = BS_NONE;
5146
    /* Restore delay slot state from the tb context.  */
5147
    ctx.hflags = tb->flags;
5148
    ctx.saved_hflags = ctx.hflags;
5149
    if (ctx.hflags & MIPS_HFLAG_BR) {
5150
        gen_op_restore_breg_target();
5151
    } else if (ctx.hflags & MIPS_HFLAG_B) {
5152
        ctx.btarget = env->btarget;
5153
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5154
        /* If we are in the delay slot of a conditional branch,
5155
         * restore the branch condition from env->bcond to T2
5156
         */
5157
        ctx.btarget = env->btarget;
5158
        gen_op_restore_bcond();
5159
    }
5160
#if defined(CONFIG_USER_ONLY)
5161
    ctx.mem_idx = 0;
5162
#else
5163
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5164
#endif
5165
    ctx.CP0_Status = env->CP0_Status;
5166
#ifdef DEBUG_DISAS
5167
    if (loglevel & CPU_LOG_TB_CPU) {
5168
        fprintf(logfile, "------------------------------------------------\n");
5169
        /* FIXME: This may print out stale hflags from env... */
5170
        cpu_dump_state(env, logfile, fprintf, 0);
5171
    }
5172
#endif
5173
#if defined MIPS_DEBUG_DISAS
5174
    if (loglevel & CPU_LOG_TB_IN_ASM)
5175
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5176
                tb, ctx.mem_idx, ctx.hflags);
5177
#endif
5178
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5179
        if (env->nb_breakpoints > 0) {
5180
            for(j = 0; j < env->nb_breakpoints; j++) {
5181
                if (env->breakpoints[j] == ctx.pc) {
5182
                    save_cpu_state(ctxp, 1);
5183
                    ctx.bstate = BS_BRANCH;
5184
                    gen_op_debug();
5185
                    goto done_generating;
5186
                }
5187
            }
5188
        }
5189

    
5190
        if (search_pc) {
5191
            j = gen_opc_ptr - gen_opc_buf;
5192
            if (lj < j) {
5193
                lj++;
5194
                while (lj < j)
5195
                    gen_opc_instr_start[lj++] = 0;
5196
            }
5197
            gen_opc_pc[lj] = ctx.pc;
5198
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5199
            gen_opc_instr_start[lj] = 1;
5200
        }
5201
        ctx.opcode = ldl_code(ctx.pc);
5202
        decode_opc(env, &ctx);
5203
        ctx.pc += 4;
5204

    
5205
        if (env->singlestep_enabled)
5206
            break;
5207

    
5208
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5209
            break;
5210

    
5211
#if defined (MIPS_SINGLE_STEP)
5212
        break;
5213
#endif
5214
    }
5215
    if (env->singlestep_enabled) {
5216
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5217
        gen_op_debug();
5218
        goto done_generating;
5219
    }
5220
    else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
5221
        save_cpu_state(ctxp, 0);
5222
        gen_goto_tb(&ctx, 0, ctx.pc);
5223
    }
5224
    gen_op_reset_T0();
5225
    /* Generate the return instruction */
5226
    gen_op_exit_tb();
5227
done_generating:
5228
    *gen_opc_ptr = INDEX_op_end;
5229
    if (search_pc) {
5230
        j = gen_opc_ptr - gen_opc_buf;
5231
        lj++;
5232
        while (lj <= j)
5233
            gen_opc_instr_start[lj++] = 0;
5234
        tb->size = 0;
5235
    } else {
5236
        tb->size = ctx.pc - pc_start;
5237
    }
5238
#ifdef DEBUG_DISAS
5239
#if defined MIPS_DEBUG_DISAS
5240
    if (loglevel & CPU_LOG_TB_IN_ASM)
5241
        fprintf(logfile, "\n");
5242
#endif
5243
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5244
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5245
    target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5246
        fprintf(logfile, "\n");
5247
    }
5248
    if (loglevel & CPU_LOG_TB_OP) {
5249
        fprintf(logfile, "OP:\n");
5250
        dump_ops(gen_opc_buf, gen_opparam_buf);
5251
        fprintf(logfile, "\n");
5252
    }
5253
    if (loglevel & CPU_LOG_TB_CPU) {
5254
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5255
    }
5256
#endif
5257
    
5258
    return 0;
5259
}
5260

    
5261
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5262
{
5263
    return gen_intermediate_code_internal(env, tb, 0);
5264
}
5265

    
5266
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5267
{
5268
    return gen_intermediate_code_internal(env, tb, 1);
5269
}
5270

    
5271
void fpu_dump_state(CPUState *env, FILE *f, 
5272
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5273
                    int flags)
5274
{
5275
    int i;
5276

    
5277
#   define printfpr(fp) do { \
5278
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5279
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5280
    } while(0)
5281

    
5282
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5283
                env->fcr0, env->fcr31,
5284
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5285
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5286
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5287
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5288
    for(i = 0; i < 32; i += 2) {
5289
        fpu_fprintf(f, "%s: ", fregnames[i]);
5290
        printfpr(FPR(env, i));
5291
    }
5292

    
5293
#undef printfpr
5294
}
5295

    
5296
void dump_fpu (CPUState *env)
5297
{
5298
    if (loglevel) { 
5299
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5300
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5301
       fpu_dump_state(env, logfile, fprintf, 0);
5302
    }
5303
}
5304

    
5305
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5306
/* Debug help: The architecture requires 32bit code to maintain proper
5307
   sign-extened values on 64bit machines.  */
5308

    
5309
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5310

    
5311
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5312
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5313
                     int flags)
5314
{
5315
    int i;
5316

    
5317
    if (!SIGN_EXT_P(env->PC))
5318
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5319
    if (!SIGN_EXT_P(env->HI))
5320
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5321
    if (!SIGN_EXT_P(env->LO))
5322
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5323
    if (!SIGN_EXT_P(env->btarget))
5324
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5325

    
5326
    for (i = 0; i < 32; i++) {
5327
        if (!SIGN_EXT_P(env->gpr[i]))
5328
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5329
    }
5330

    
5331
    if (!SIGN_EXT_P(env->CP0_EPC))
5332
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5333
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5334
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5335
}
5336
#endif
5337

    
5338
void cpu_dump_state (CPUState *env, FILE *f, 
5339
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5340
                     int flags)
5341
{
5342
    uint32_t c0_status;
5343
    int i;
5344
    
5345
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5346
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5347
    for (i = 0; i < 32; i++) {
5348
        if ((i & 3) == 0)
5349
            cpu_fprintf(f, "GPR%02d:", i);
5350
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5351
        if ((i & 3) == 3)
5352
            cpu_fprintf(f, "\n");
5353
    }
5354

    
5355
    c0_status = env->CP0_Status;
5356

    
5357
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5358
                c0_status, env->CP0_Cause, env->CP0_EPC);
5359
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5360
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5361
    if (c0_status & (1 << CP0St_CU1))
5362
        fpu_dump_state(env, f, cpu_fprintf, flags);
5363
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5364
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5365
#endif
5366
}
5367

    
5368
CPUMIPSState *cpu_mips_init (void)
5369
{
5370
    CPUMIPSState *env;
5371

    
5372
    env = qemu_mallocz(sizeof(CPUMIPSState));
5373
    if (!env)
5374
        return NULL;
5375
    cpu_exec_init(env);
5376
    cpu_reset(env);
5377
    return env;
5378
}
5379

    
5380
void cpu_reset (CPUMIPSState *env)
5381
{
5382
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5383

    
5384
    tlb_flush(env, 1);
5385

    
5386
    /* Minimal init */
5387
#if !defined(CONFIG_USER_ONLY)
5388
    if (env->hflags & MIPS_HFLAG_BMASK) {
5389
        /* If the exception was raised from a delay slot,
5390
         * come back to the jump.  */
5391
        env->CP0_ErrorEPC = env->PC - 4;
5392
        env->hflags &= ~MIPS_HFLAG_BMASK;
5393
    } else {
5394
        env->CP0_ErrorEPC = env->PC;
5395
    }
5396
    env->hflags = 0;
5397
    env->PC = (int32_t)0xBFC00000;
5398
#if defined (MIPS_USES_R4K_TLB)
5399
    env->CP0_Random = MIPS_TLB_NB - 1;
5400
    env->tlb_in_use = MIPS_TLB_NB;
5401
#endif
5402
    env->CP0_Wired = 0;
5403
    /* SMP not implemented */
5404
    env->CP0_EBase = 0x80000000;
5405
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5406
    env->CP0_WatchLo = 0;
5407
    /* Count register increments in debug mode, EJTAG version 1 */
5408
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5409
#endif
5410
    env->exception_index = EXCP_NONE;
5411
#if defined(CONFIG_USER_ONLY)
5412
    env->hflags |= MIPS_HFLAG_UM;
5413
    env->user_mode_only = 1;
5414
#endif
5415
    /* XXX some guesswork here, values are CPU specific */
5416
    env->SYNCI_Step = 16;
5417
    env->CCRes = 2;
5418
}
5419

    
5420
#include "translate_init.c"