Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 9898128f

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4262
    return;
4263
}
4264

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

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

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

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

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

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

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

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

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

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

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

    
4650
#endif
4651

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5328
#undef printfpr
5329
}
5330

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

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

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

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

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

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

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

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

    
5390
    c0_status = env->CP0_Status;
5391

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

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

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

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

    
5419
    tlb_flush(env, 1);
5420

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

    
5456
#include "translate_init.c"