Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d6929309

History | View | Annotate | Download (144.4 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 & 0xFFFF)
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
        GEN_LOAD_IMM_TN(T0, uimm << 16);
911
        break;
912
    case OPC_SLL:
913
    case OPC_SRA:
914
    case OPC_SRL:
915
#ifdef TARGET_MIPS64
916
    case OPC_DSLL:
917
    case OPC_DSRA:
918
    case OPC_DSRL:
919
    case OPC_DSLL32:
920
    case OPC_DSRA32:
921
    case OPC_DSRL32:
922
#endif
923
        uimm &= 0x1f;
924
        GEN_LOAD_REG_TN(T0, rs);
925
        GEN_LOAD_IMM_TN(T1, uimm);
926
        break;
927
    }
928
    switch (opc) {
929
    case OPC_ADDI:
930
        save_cpu_state(ctx, 1);
931
        gen_op_addo();
932
        opn = "addi";
933
        break;
934
    case OPC_ADDIU:
935
        gen_op_add();
936
        opn = "addiu";
937
        break;
938
#ifdef TARGET_MIPS64
939
    case OPC_DADDI:
940
        save_cpu_state(ctx, 1);
941
        gen_op_daddo();
942
        opn = "daddi";
943
        break;
944
    case OPC_DADDIU:
945
        gen_op_dadd();
946
        opn = "daddiu";
947
        break;
948
#endif
949
    case OPC_SLTI:
950
        gen_op_lt();
951
        opn = "slti";
952
        break;
953
    case OPC_SLTIU:
954
        gen_op_ltu();
955
        opn = "sltiu";
956
        break;
957
    case OPC_ANDI:
958
        gen_op_and();
959
        opn = "andi";
960
        break;
961
    case OPC_ORI:
962
        gen_op_or();
963
        opn = "ori";
964
        break;
965
    case OPC_XORI:
966
        gen_op_xor();
967
        opn = "xori";
968
        break;
969
    case OPC_LUI:
970
        opn = "lui";
971
        break;
972
    case OPC_SLL:
973
        gen_op_sll();
974
        opn = "sll";
975
        break;
976
    case OPC_SRA:
977
        gen_op_sra();
978
        opn = "sra";
979
        break;
980
    case OPC_SRL:
981
        switch ((ctx->opcode >> 21) & 0x1f) {
982
        case 0:
983
            gen_op_srl();
984
            opn = "srl";
985
            break;
986
        case 1:
987
            gen_op_rotr();
988
            opn = "rotr";
989
            break;
990
        default:
991
            MIPS_INVAL("invalid srl flag");
992
            generate_exception(ctx, EXCP_RI);
993
            break;
994
        }
995
        break;
996
#ifdef TARGET_MIPS64
997
    case OPC_DSLL:
998
        gen_op_dsll();
999
        opn = "dsll";
1000
        break;
1001
    case OPC_DSRA:
1002
        gen_op_dsra();
1003
        opn = "dsra";
1004
        break;
1005
    case OPC_DSRL:
1006
        switch ((ctx->opcode >> 21) & 0x1f) {
1007
        case 0:
1008
            gen_op_dsrl();
1009
            opn = "dsrl";
1010
            break;
1011
        case 1:
1012
            gen_op_drotr();
1013
            opn = "drotr";
1014
            break;
1015
        default:
1016
            MIPS_INVAL("invalid dsrl flag");
1017
            generate_exception(ctx, EXCP_RI);
1018
            break;
1019
        }
1020
        break;
1021
    case OPC_DSLL32:
1022
        gen_op_dsll32();
1023
        opn = "dsll32";
1024
        break;
1025
    case OPC_DSRA32:
1026
        gen_op_dsra32();
1027
        opn = "dsra32";
1028
        break;
1029
    case OPC_DSRL32:
1030
        switch ((ctx->opcode >> 21) & 0x1f) {
1031
        case 0:
1032
            gen_op_dsrl32();
1033
            opn = "dsrl32";
1034
            break;
1035
        case 1:
1036
            gen_op_drotr32();
1037
            opn = "drotr32";
1038
            break;
1039
        default:
1040
            MIPS_INVAL("invalid dsrl32 flag");
1041
            generate_exception(ctx, EXCP_RI);
1042
            break;
1043
        }
1044
        break;
1045
#endif
1046
    default:
1047
        MIPS_INVAL("imm arith");
1048
        generate_exception(ctx, EXCP_RI);
1049
        return;
1050
    }
1051
    GEN_STORE_TN_REG(rt, T0);
1052
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1053
}
1054

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2952
#ifdef TARGET_MIPS64
2953
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2954
{
2955
    const char *rn = "invalid";
2956

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

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

    
3535
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3536
{
3537
    const char *rn = "invalid";
3538

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

    
4120
die:
4121
#if defined MIPS_DEBUG_DISAS
4122
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4123
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4124
                rn, reg, sel);
4125
    }
4126
#endif
4127
    generate_exception(ctx, EXCP_RI);
4128
}
4129
#endif /* TARGET_MIPS64 */
4130

    
4131
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4132
{
4133
    const char *opn = "unk";
4134

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

    
4221
/* CP1 Branches (before delay slot) */
4222
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4223
                                 int32_t offset)
4224
{
4225
    target_ulong btarget;
4226

    
4227
    btarget = ctx->pc + 4 + offset;
4228

    
4229
    switch (op) {
4230
    case OPC_BC1F:
4231
        gen_op_bc1f();
4232
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4233
        goto not_likely;
4234
    case OPC_BC1FL:
4235
        gen_op_bc1f();
4236
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4237
        goto likely;
4238
    case OPC_BC1T:
4239
        gen_op_bc1t();
4240
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4241
    not_likely:
4242
        ctx->hflags |= MIPS_HFLAG_BC;
4243
        break;
4244
    case OPC_BC1TL:
4245
        gen_op_bc1t();
4246
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4247
    likely:
4248
        ctx->hflags |= MIPS_HFLAG_BL;
4249
        break;
4250
    default:    
4251
        MIPS_INVAL("cp1 branch/jump");
4252
        generate_exception (ctx, EXCP_RI);
4253
        return;
4254
    }
4255
    gen_op_set_bcond();
4256

    
4257
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4258
               ctx->hflags, btarget);
4259
    ctx->btarget = btarget;
4260

    
4261
    return;
4262
}
4263

    
4264
/* Coprocessor 1 (FPU) */
4265
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4266
{
4267
    const char *opn = "unk";
4268

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

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

    
4336
#define FOP(func, fmt) (((fmt) << 21) | (func))
4337

    
4338
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4339
{
4340
    const char *opn = "unk";
4341
    const char *condnames[] = {
4342
            "c.f",
4343
            "c.un",
4344
            "c.eq",
4345
            "c.ueq",
4346
            "c.olt",
4347
            "c.ult",
4348
            "c.ole",
4349
            "c.ule",
4350
            "c.sf",
4351
            "c.ngle",
4352
            "c.seq",
4353
            "c.ngl",
4354
            "c.lt",
4355
            "c.nge",
4356
            "c.le",
4357
            "c.ngt",
4358
    };
4359
    int binary = 0;
4360
    uint32_t func = ctx->opcode & 0x3f;
4361

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

    
4625
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4626
{
4627
    uint32_t ccbit;
4628

    
4629
    if (cc)
4630
        ccbit = 1 << (24 + cc);
4631
    else
4632
        ccbit = 1 << 23;
4633
    if (!tf)
4634
        gen_op_movf(ccbit, rd, rs);
4635
    else
4636
       gen_op_movt(ccbit, rd, rs);
4637
}
4638

    
4639
/* ISA extensions (ASEs) */
4640
/* MIPS16 extension to MIPS32 */
4641
/* SmartMIPS extension to MIPS32 */
4642

    
4643
#ifdef TARGET_MIPS64
4644
/* Coprocessor 3 (FPU) */
4645

    
4646
/* MDMX extension to MIPS64 */
4647
/* MIPS-3D extension to MIPS64 */
4648

    
4649
#endif
4650

    
4651
static void gen_blikely(DisasContext *ctx)
4652
{
4653
    int l1;
4654
    l1 = gen_new_label();
4655
    gen_op_jnz_T2(l1);
4656
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4657
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4658
    gen_set_label(l1);
4659
}
4660

    
4661
static void decode_opc (CPUState *env, DisasContext *ctx)
4662
{
4663
    int32_t offset;
4664
    int rs, rt, rd, sa;
4665
    uint32_t op, op1, op2;
4666
    int16_t imm;
4667

    
4668
    /* make sure instructions are on a word boundary */
4669
    if (ctx->pc & 0x3) {
4670
        env->CP0_BadVAddr = ctx->pc;
4671
        generate_exception(ctx, EXCP_AdEL);
4672
        return;
4673
    }
4674

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

    
4747
        case OPC_MOVCI:
4748
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4749
                save_cpu_state(ctx, 1);
4750
                gen_op_cp1_enabled();
4751
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4752
                          (ctx->opcode >> 16) & 1);
4753
            } else {
4754
                generate_exception_err(ctx, EXCP_CpU, 1);
4755
            }
4756
            break;
4757

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

    
4999
    /* Floating point.  */
5000
    case OPC_LWC1:
5001
    case OPC_LDC1:
5002
    case OPC_SWC1:
5003
    case OPC_SDC1:
5004
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5005
            save_cpu_state(ctx, 1);
5006
            gen_op_cp1_enabled();
5007
            gen_flt_ldst(ctx, op, rt, rs, imm);
5008
        } else {
5009
            generate_exception_err(ctx, EXCP_CpU, 1);
5010
        }
5011
        break;
5012

    
5013
    case OPC_CP1:
5014
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5015
            save_cpu_state(ctx, 1);
5016
            gen_op_cp1_enabled();
5017
            op1 = MASK_CP1(ctx->opcode);
5018
            switch (op1) {
5019
            case OPC_MFC1:
5020
            case OPC_CFC1:
5021
            case OPC_MTC1:
5022
            case OPC_CTC1:
5023
#ifdef TARGET_MIPS64
5024
            case OPC_DMFC1:
5025
            case OPC_DMTC1:
5026
#endif
5027
                gen_cp1(ctx, op1, rt, rd);
5028
                break;
5029
            case OPC_BC1:
5030
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
5031
                return;
5032
            case OPC_S_FMT:
5033
            case OPC_D_FMT:
5034
            case OPC_W_FMT:
5035
            case OPC_L_FMT:
5036
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
5037
                break;
5038
            default:
5039
                generate_exception (ctx, EXCP_RI);
5040
                break;
5041
            }
5042
        } else {
5043
            generate_exception_err(ctx, EXCP_CpU, 1);
5044
        }
5045
        break;
5046

    
5047
    /* COP2.  */
5048
    case OPC_LWC2:
5049
    case OPC_LDC2:
5050
    case OPC_SWC2:
5051
    case OPC_SDC2:
5052
    case OPC_CP2:
5053
        /* COP2: Not implemented. */
5054
        generate_exception_err(ctx, EXCP_CpU, 2);
5055
        break;
5056

    
5057
    case OPC_CP3:
5058
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5059
            save_cpu_state(ctx, 1);
5060
            gen_op_cp1_enabled();
5061
            op1 = MASK_CP3(ctx->opcode);
5062
            switch (op1) {
5063
            case OPC_PREFX:
5064
                /* treat as noop */
5065
                break;
5066
            /* Not implemented */
5067
            default:
5068
                generate_exception (ctx, EXCP_RI);
5069
                break;
5070
            }
5071
        } else {
5072
            generate_exception_err(ctx, EXCP_CpU, 1);
5073
        }
5074
        break;
5075

    
5076
#ifdef TARGET_MIPS64
5077
    /* MIPS64 opcodes */
5078
    case OPC_LWU:
5079
    case OPC_LDL ... OPC_LDR:
5080
    case OPC_SDL ... OPC_SDR:
5081
    case OPC_LLD:
5082
    case OPC_LD:
5083
    case OPC_SCD:
5084
    case OPC_SD:
5085
        gen_ldst(ctx, op, rt, rs, imm);
5086
        break;
5087
    case OPC_DADDI ... OPC_DADDIU:
5088
        gen_arith_imm(ctx, op, rt, rs, imm);
5089
        break;
5090
#endif
5091
#ifdef MIPS_HAS_MIPS16
5092
    case OPC_JALX:
5093
        /* MIPS16: Not implemented. */
5094
#endif
5095
#ifdef MIPS_HAS_MDMX
5096
    case OPC_MDMX:
5097
        /* MDMX: Not implemented. */
5098
#endif
5099
    default:            /* Invalid */
5100
        MIPS_INVAL("");
5101
        generate_exception(ctx, EXCP_RI);
5102
        break;
5103
    }
5104
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5105
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5106
        /* Branches completion */
5107
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5108
        ctx->bstate = BS_BRANCH;
5109
        save_cpu_state(ctx, 0);
5110
        switch (hflags & MIPS_HFLAG_BMASK) {
5111
        case MIPS_HFLAG_B:
5112
            /* unconditional branch */
5113
            MIPS_DEBUG("unconditional branch");
5114
            gen_goto_tb(ctx, 0, ctx->btarget);
5115
            break;
5116
        case MIPS_HFLAG_BL:
5117
            /* blikely taken case */
5118
            MIPS_DEBUG("blikely branch taken");
5119
            gen_goto_tb(ctx, 0, ctx->btarget);
5120
            break;
5121
        case MIPS_HFLAG_BC:
5122
            /* Conditional branch */
5123
            MIPS_DEBUG("conditional branch");
5124
            {
5125
              int l1;
5126
              l1 = gen_new_label();
5127
              gen_op_jnz_T2(l1);
5128
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5129
              gen_set_label(l1);
5130
              gen_goto_tb(ctx, 0, ctx->btarget);
5131
            }
5132
            break;
5133
        case MIPS_HFLAG_BR:
5134
            /* unconditional branch to register */
5135
            MIPS_DEBUG("branch to register");
5136
            gen_op_breg();
5137
            break;
5138
        default:
5139
            MIPS_DEBUG("unknown branch");
5140
            break;
5141
        }
5142
    }
5143
}
5144

    
5145
static inline int
5146
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5147
                                int search_pc)
5148
{
5149
    DisasContext ctx, *ctxp = &ctx;
5150
    target_ulong pc_start;
5151
    uint16_t *gen_opc_end;
5152
    int j, lj = -1;
5153

    
5154
    if (search_pc && loglevel)
5155
        fprintf (logfile, "search pc %d\n", search_pc);
5156

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

    
5210
        if (search_pc) {
5211
            j = gen_opc_ptr - gen_opc_buf;
5212
            if (lj < j) {
5213
                lj++;
5214
                while (lj < j)
5215
                    gen_opc_instr_start[lj++] = 0;
5216
            }
5217
            gen_opc_pc[lj] = ctx.pc;
5218
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5219
            gen_opc_instr_start[lj] = 1;
5220
        }
5221
        ctx.opcode = ldl_code(ctx.pc);
5222
        decode_opc(env, &ctx);
5223
        ctx.pc += 4;
5224

    
5225
        if (env->singlestep_enabled)
5226
            break;
5227

    
5228
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5229
            break;
5230

    
5231
#if defined (MIPS_SINGLE_STEP)
5232
        break;
5233
#endif
5234
    }
5235
    if (env->singlestep_enabled) {
5236
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5237
        gen_op_debug();
5238
    } else {
5239
        switch (ctx.bstate) {
5240
        case BS_EXCP:
5241
            gen_op_interrupt_restart();
5242
            gen_op_reset_T0();
5243
            /* Generate the return instruction. */
5244
            gen_op_exit_tb();
5245
            break;
5246
        case BS_STOP:
5247
            gen_op_interrupt_restart();
5248
            /* Fall through. */
5249
        case BS_NONE:
5250
            save_cpu_state(ctxp, 0);
5251
            gen_goto_tb(&ctx, 0, ctx.pc);
5252
            break;
5253
        case BS_BRANCH:
5254
        default:
5255
            gen_op_reset_T0();
5256
            /* Generate the return instruction. */
5257
            gen_op_exit_tb();
5258
            break;
5259
        }
5260
    }
5261
done_generating:
5262
    *gen_opc_ptr = INDEX_op_end;
5263
    if (search_pc) {
5264
        j = gen_opc_ptr - gen_opc_buf;
5265
        lj++;
5266
        while (lj <= j)
5267
            gen_opc_instr_start[lj++] = 0;
5268
        tb->size = 0;
5269
    } else {
5270
        tb->size = ctx.pc - pc_start;
5271
    }
5272
#ifdef DEBUG_DISAS
5273
#if defined MIPS_DEBUG_DISAS
5274
    if (loglevel & CPU_LOG_TB_IN_ASM)
5275
        fprintf(logfile, "\n");
5276
#endif
5277
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5278
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5279
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5280
        fprintf(logfile, "\n");
5281
    }
5282
    if (loglevel & CPU_LOG_TB_OP) {
5283
        fprintf(logfile, "OP:\n");
5284
        dump_ops(gen_opc_buf, gen_opparam_buf);
5285
        fprintf(logfile, "\n");
5286
    }
5287
    if (loglevel & CPU_LOG_TB_CPU) {
5288
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5289
    }
5290
#endif
5291
    
5292
    return 0;
5293
}
5294

    
5295
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5296
{
5297
    return gen_intermediate_code_internal(env, tb, 0);
5298
}
5299

    
5300
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5301
{
5302
    return gen_intermediate_code_internal(env, tb, 1);
5303
}
5304

    
5305
void fpu_dump_state(CPUState *env, FILE *f, 
5306
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5307
                    int flags)
5308
{
5309
    int i;
5310

    
5311
#   define printfpr(fp) do { \
5312
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5313
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5314
    } while(0)
5315

    
5316
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5317
                env->fcr0, env->fcr31,
5318
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5319
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5320
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5321
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5322
    for(i = 0; i < 32; i += 2) {
5323
        fpu_fprintf(f, "%s: ", fregnames[i]);
5324
        printfpr(FPR(env, i));
5325
    }
5326

    
5327
#undef printfpr
5328
}
5329

    
5330
void dump_fpu (CPUState *env)
5331
{
5332
    if (loglevel) { 
5333
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5334
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5335
       fpu_dump_state(env, logfile, fprintf, 0);
5336
    }
5337
}
5338

    
5339
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5340
/* Debug help: The architecture requires 32bit code to maintain proper
5341
   sign-extened values on 64bit machines.  */
5342

    
5343
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5344

    
5345
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5346
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5347
                     int flags)
5348
{
5349
    int i;
5350

    
5351
    if (!SIGN_EXT_P(env->PC))
5352
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5353
    if (!SIGN_EXT_P(env->HI))
5354
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5355
    if (!SIGN_EXT_P(env->LO))
5356
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5357
    if (!SIGN_EXT_P(env->btarget))
5358
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5359

    
5360
    for (i = 0; i < 32; i++) {
5361
        if (!SIGN_EXT_P(env->gpr[i]))
5362
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5363
    }
5364

    
5365
    if (!SIGN_EXT_P(env->CP0_EPC))
5366
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5367
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5368
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5369
}
5370
#endif
5371

    
5372
void cpu_dump_state (CPUState *env, FILE *f, 
5373
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5374
                     int flags)
5375
{
5376
    uint32_t c0_status;
5377
    int i;
5378
    
5379
    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",
5380
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5381
    for (i = 0; i < 32; i++) {
5382
        if ((i & 3) == 0)
5383
            cpu_fprintf(f, "GPR%02d:", i);
5384
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5385
        if ((i & 3) == 3)
5386
            cpu_fprintf(f, "\n");
5387
    }
5388

    
5389
    c0_status = env->CP0_Status;
5390

    
5391
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5392
                c0_status, env->CP0_Cause, env->CP0_EPC);
5393
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5394
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5395
    if (c0_status & (1 << CP0St_CU1))
5396
        fpu_dump_state(env, f, cpu_fprintf, flags);
5397
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5398
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5399
#endif
5400
}
5401

    
5402
CPUMIPSState *cpu_mips_init (void)
5403
{
5404
    CPUMIPSState *env;
5405

    
5406
    env = qemu_mallocz(sizeof(CPUMIPSState));
5407
    if (!env)
5408
        return NULL;
5409
    cpu_exec_init(env);
5410
    cpu_reset(env);
5411
    return env;
5412
}
5413

    
5414
void cpu_reset (CPUMIPSState *env)
5415
{
5416
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5417

    
5418
    tlb_flush(env, 1);
5419

    
5420
    /* Minimal init */
5421
#if !defined(CONFIG_USER_ONLY)
5422
    if (env->hflags & MIPS_HFLAG_BMASK) {
5423
        /* If the exception was raised from a delay slot,
5424
         * come back to the jump.  */
5425
        env->CP0_ErrorEPC = env->PC - 4;
5426
        env->hflags &= ~MIPS_HFLAG_BMASK;
5427
    } else {
5428
        env->CP0_ErrorEPC = env->PC;
5429
    }
5430
    env->hflags = 0;
5431
    env->PC = (int32_t)0xBFC00000;
5432
    env->CP0_Wired = 0;
5433
    /* SMP not implemented */
5434
    env->CP0_EBase = 0x80000000;
5435
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5436
    /* vectored interrupts not implemented, timer on int 7,
5437
       no performance counters. */
5438
    env->CP0_IntCtl = 0xe0000000;
5439
    env->CP0_WatchLo = 0;
5440
    env->CP0_WatchHi = 0;
5441
    /* Count register increments in debug mode, EJTAG version 1 */
5442
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5443
#endif
5444
    env->exception_index = EXCP_NONE;
5445
#if defined(CONFIG_USER_ONLY)
5446
    env->hflags |= MIPS_HFLAG_UM;
5447
    env->user_mode_only = 1;
5448
#endif
5449
}
5450

    
5451
#include "translate_init.c"