Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c090a8f4

History | View | Annotate | Download (142 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
399

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
511
FOP_CONDS(d)
512
FOP_CONDS(s)
513

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4218
    btarget = ctx->pc + 4 + offset;
4219

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

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

    
4252
    return;
4253
}
4254

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

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

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

    
4327
#define FOP(func, fmt) (((fmt) << 21) | (func))
4328

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

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

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

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

    
4630
/* ISA extensions (ASEs) */
4631
/* MIPS16 extension to MIPS32 */
4632
/* SmartMIPS extension to MIPS32 */
4633

    
4634
#ifdef TARGET_MIPS64
4635
/* Coprocessor 3 (FPU) */
4636

    
4637
/* MDMX extension to MIPS64 */
4638
/* MIPS-3D extension to MIPS64 */
4639

    
4640
#endif
4641

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5207
        if (env->singlestep_enabled)
5208
            break;
5209

    
5210
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5211
            break;
5212

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

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

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

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

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

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

    
5295
#undef printfpr
5296
}
5297

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

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

    
5311
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5312

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

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

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

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

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

    
5357
    c0_status = env->CP0_Status;
5358

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

    
5370
CPUMIPSState *cpu_mips_init (void)
5371
{
5372
    CPUMIPSState *env;
5373

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

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

    
5386
    tlb_flush(env, 1);
5387

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

    
5426
#include "translate_init.c"