Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a6763a58

History | View | Annotate | Download (160.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_MFHC1    = (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_MTHC1    = (0x07 << 21) | OPC_CP1,
341
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
342
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
343
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
344
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
345
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
346
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
347
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
348
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
349
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
350
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
351
};
352

    
353
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
354
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
355

    
356
enum {
357
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
358
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
359
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
360
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
361
};
362

    
363
enum {
364
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
365
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
366
};
367

    
368
enum {
369
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
370
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
371
};
372

    
373
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
374

    
375
enum {
376
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
377
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
378
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
379
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
380
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
381
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
382
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
383
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
384
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
385
};
386

    
387
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
388

    
389
enum {
390
    OPC_LWXC1   = 0x00 | OPC_CP3,
391
    OPC_LDXC1   = 0x01 | OPC_CP3,
392
    OPC_LUXC1   = 0x05 | OPC_CP3,
393
    OPC_SWXC1   = 0x08 | OPC_CP3,
394
    OPC_SDXC1   = 0x09 | OPC_CP3,
395
    OPC_SUXC1   = 0x0D | OPC_CP3,
396
    OPC_PREFX   = 0x0F | OPC_CP3,
397
    OPC_ALNV_PS = 0x1E | OPC_CP3,
398
    OPC_MADD_S  = 0x20 | OPC_CP3,
399
    OPC_MADD_D  = 0x21 | OPC_CP3,
400
    OPC_MADD_PS = 0x26 | OPC_CP3,
401
    OPC_MSUB_S  = 0x28 | OPC_CP3,
402
    OPC_MSUB_D  = 0x29 | OPC_CP3,
403
    OPC_MSUB_PS = 0x2E | OPC_CP3,
404
    OPC_NMADD_S = 0x30 | OPC_CP3,
405
    OPC_NMADD_D = 0x32 | OPC_CP3,
406
    OPC_NMADD_PS= 0x36 | OPC_CP3,
407
    OPC_NMSUB_S = 0x38 | OPC_CP3,
408
    OPC_NMSUB_D = 0x39 | OPC_CP3,
409
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
410
};
411

    
412

    
413
const unsigned char *regnames[] =
414
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
415
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
416
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
417
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
418

    
419
/* Warning: no function for r0 register (hard wired to zero) */
420
#define GEN32(func, NAME)                        \
421
static GenOpFunc *NAME ## _table [32] = {        \
422
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
423
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
424
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
425
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
426
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
427
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
428
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
429
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
430
};                                               \
431
static inline void func(int n)                   \
432
{                                                \
433
    NAME ## _table[n]();                         \
434
}
435

    
436
/* General purpose registers moves */
437
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
438
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
439
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
440

    
441
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
443

    
444
static const char *fregnames[] =
445
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
446
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
447
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
448
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
449

    
450
#define FGEN32(func, NAME)                       \
451
static GenOpFunc *NAME ## _table [32] = {        \
452
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
453
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
454
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
455
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
456
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
457
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
458
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
459
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
460
};                                               \
461
static inline void func(int n)                   \
462
{                                                \
463
    NAME ## _table[n]();                         \
464
}
465

    
466
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
467
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
468

    
469
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
470
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
471

    
472
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
473
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
474

    
475
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
476
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
477

    
478
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
479
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
480

    
481
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
482
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
485
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
486

    
487
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
488
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
489

    
490
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
491
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492

    
493
#define FOP_CONDS(fmt) \
494
static GenOpFunc1 * cond_ ## fmt ## _table[16] = {                      \
495
    gen_op_cmp_ ## fmt ## _f,                                           \
496
    gen_op_cmp_ ## fmt ## _un,                                          \
497
    gen_op_cmp_ ## fmt ## _eq,                                          \
498
    gen_op_cmp_ ## fmt ## _ueq,                                         \
499
    gen_op_cmp_ ## fmt ## _olt,                                         \
500
    gen_op_cmp_ ## fmt ## _ult,                                         \
501
    gen_op_cmp_ ## fmt ## _ole,                                         \
502
    gen_op_cmp_ ## fmt ## _ule,                                         \
503
    gen_op_cmp_ ## fmt ## _sf,                                          \
504
    gen_op_cmp_ ## fmt ## _ngle,                                        \
505
    gen_op_cmp_ ## fmt ## _seq,                                         \
506
    gen_op_cmp_ ## fmt ## _ngl,                                         \
507
    gen_op_cmp_ ## fmt ## _lt,                                          \
508
    gen_op_cmp_ ## fmt ## _nge,                                         \
509
    gen_op_cmp_ ## fmt ## _le,                                          \
510
    gen_op_cmp_ ## fmt ## _ngt,                                         \
511
};                                                                      \
512
static inline void gen_cmp_ ## fmt(int n, long cc)                      \
513
{                                                                       \
514
    cond_ ## fmt ## _table[n](cc);                                      \
515
}
516

    
517
FOP_CONDS(d)
518
FOP_CONDS(s)
519
FOP_CONDS(ps)
520

    
521
typedef struct DisasContext {
522
    struct TranslationBlock *tb;
523
    target_ulong pc, saved_pc;
524
    uint32_t opcode;
525
    uint32_t fp_status, saved_fp_status;
526
    /* Routine used to access memory */
527
    int mem_idx;
528
    uint32_t hflags, saved_hflags;
529
    uint32_t CP0_Status;
530
    int bstate;
531
    target_ulong btarget;
532
} DisasContext;
533

    
534
enum {
535
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
536
                      * exception condition
537
                      */
538
    BS_STOP     = 1, /* We want to stop translation for any reason */
539
    BS_BRANCH   = 2, /* We reached a branch condition     */
540
    BS_EXCP     = 3, /* We reached an exception condition */
541
};
542

    
543
#if defined MIPS_DEBUG_DISAS
544
#define MIPS_DEBUG(fmt, args...)                                              \
545
do {                                                                          \
546
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
547
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
548
                ctx->pc, ctx->opcode , ##args);                               \
549
    }                                                                         \
550
} while (0)
551
#else
552
#define MIPS_DEBUG(fmt, args...) do { } while(0)
553
#endif
554

    
555
#define MIPS_INVAL(op)                                                        \
556
do {                                                                          \
557
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
558
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
559
} while (0)
560

    
561
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
562
do {                                                                          \
563
    if (Rn == 0) {                                                            \
564
        glue(gen_op_reset_, Tn)();                                            \
565
    } else {                                                                  \
566
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
567
    }                                                                         \
568
} while (0)
569

    
570
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
571
do {                                                                          \
572
    if (Imm == 0) {                                                           \
573
        glue(gen_op_reset_, Tn)();                                            \
574
    } else {                                                                  \
575
        glue(gen_op_set_, Tn)(Imm);                                           \
576
    }                                                                         \
577
} while (0)
578

    
579
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
580
do {                                                                          \
581
    if (Rn != 0) {                                                            \
582
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
583
    }                                                                         \
584
} while (0)
585

    
586
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
587
do {                                                                          \
588
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
589
} while (0)
590

    
591
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
592
do {                                                                          \
593
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
594
} while (0)
595

    
596
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
597
{
598
#if defined MIPS_DEBUG_DISAS
599
    if (loglevel & CPU_LOG_TB_IN_ASM) {
600
            fprintf(logfile, "hflags %08x saved %08x\n",
601
                    ctx->hflags, ctx->saved_hflags);
602
    }
603
#endif
604
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
605
        gen_op_save_pc(ctx->pc);
606
        ctx->saved_pc = ctx->pc;
607
    }
608
    if (ctx->hflags != ctx->saved_hflags) {
609
        gen_op_save_state(ctx->hflags);
610
        ctx->saved_hflags = ctx->hflags;
611
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
612
        case MIPS_HFLAG_BR:
613
            gen_op_save_breg_target();
614
            break;
615
        case MIPS_HFLAG_BC:
616
            gen_op_save_bcond();
617
            /* fall through */
618
        case MIPS_HFLAG_BL:
619
            /* bcond was already saved by the BL insn */
620
            /* fall through */
621
        case MIPS_HFLAG_B:
622
            gen_op_save_btarget(ctx->btarget);
623
            break;
624
        }
625
    }
626
}
627

    
628
static inline void save_fpu_state (DisasContext *ctx)
629
{
630
    if (ctx->fp_status != ctx->saved_fp_status) {
631
        gen_op_save_fp_status(ctx->fp_status);
632
        ctx->saved_fp_status = ctx->fp_status;
633
    }
634
}
635

    
636
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
637
{
638
#if defined MIPS_DEBUG_DISAS
639
    if (loglevel & CPU_LOG_TB_IN_ASM)
640
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
641
#endif
642
    save_cpu_state(ctx, 1);
643
    if (err == 0)
644
        gen_op_raise_exception(excp);
645
    else
646
        gen_op_raise_exception_err(excp, err);
647
    ctx->bstate = BS_EXCP;
648
}
649

    
650
static inline void generate_exception (DisasContext *ctx, int excp)
651
{
652
    generate_exception_err (ctx, excp, 0);
653
}
654

    
655
#if defined(CONFIG_USER_ONLY)
656
#define op_ldst(name)        gen_op_##name##_raw()
657
#define OP_LD_TABLE(width)
658
#define OP_ST_TABLE(width)
659
#else
660
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
661
#define OP_LD_TABLE(width)                                                    \
662
static GenOpFunc *gen_op_l##width[] = {                                       \
663
    &gen_op_l##width##_user,                                                  \
664
    &gen_op_l##width##_kernel,                                                \
665
}
666
#define OP_ST_TABLE(width)                                                    \
667
static GenOpFunc *gen_op_s##width[] = {                                       \
668
    &gen_op_s##width##_user,                                                  \
669
    &gen_op_s##width##_kernel,                                                \
670
}
671
#endif
672

    
673
#ifdef TARGET_MIPS64
674
OP_LD_TABLE(d);
675
OP_LD_TABLE(dl);
676
OP_LD_TABLE(dr);
677
OP_ST_TABLE(d);
678
OP_ST_TABLE(dl);
679
OP_ST_TABLE(dr);
680
OP_LD_TABLE(ld);
681
OP_ST_TABLE(cd);
682
#endif
683
OP_LD_TABLE(w);
684
OP_LD_TABLE(wu);
685
OP_LD_TABLE(wl);
686
OP_LD_TABLE(wr);
687
OP_ST_TABLE(w);
688
OP_ST_TABLE(wl);
689
OP_ST_TABLE(wr);
690
OP_LD_TABLE(h);
691
OP_LD_TABLE(hu);
692
OP_ST_TABLE(h);
693
OP_LD_TABLE(b);
694
OP_LD_TABLE(bu);
695
OP_ST_TABLE(b);
696
OP_LD_TABLE(l);
697
OP_ST_TABLE(c);
698
OP_LD_TABLE(wc1);
699
OP_ST_TABLE(wc1);
700
OP_LD_TABLE(dc1);
701
OP_ST_TABLE(dc1);
702
OP_LD_TABLE(wxc1);
703
OP_ST_TABLE(wxc1);
704
OP_LD_TABLE(dxc1);
705
OP_ST_TABLE(dxc1);
706
OP_LD_TABLE(uxc1);
707
OP_ST_TABLE(uxc1);
708

    
709
/* Load and store */
710
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
711
                      int base, int16_t offset)
712
{
713
    const char *opn = "unk";
714

    
715
    if (base == 0) {
716
        GEN_LOAD_IMM_TN(T0, offset);
717
    } else if (offset == 0) {
718
        gen_op_load_gpr_T0(base);
719
    } else {
720
        gen_op_load_gpr_T0(base);
721
        gen_op_set_T1(offset);
722
        gen_op_addr_add();
723
    }
724
    /* Don't do NOP if destination is zero: we must perform the actual
725
     * memory access
726
     */
727
    switch (opc) {
728
#ifdef TARGET_MIPS64
729
    case OPC_LD:
730
        op_ldst(ld);
731
        GEN_STORE_TN_REG(rt, T0);
732
        opn = "ld";
733
        break;
734
    case OPC_LLD:
735
        op_ldst(lld);
736
        GEN_STORE_TN_REG(rt, T0);
737
        opn = "lld";
738
        break;
739
    case OPC_SD:
740
        GEN_LOAD_REG_TN(T1, rt);
741
        op_ldst(sd);
742
        opn = "sd";
743
        break;
744
    case OPC_SCD:
745
        save_cpu_state(ctx, 1);
746
        GEN_LOAD_REG_TN(T1, rt);
747
        op_ldst(scd);
748
        opn = "scd";
749
        break;
750
    case OPC_LDL:
751
        op_ldst(ldl);
752
        GEN_STORE_TN_REG(rt, T0);
753
        opn = "ldl";
754
        break;
755
    case OPC_SDL:
756
        GEN_LOAD_REG_TN(T1, rt);
757
        op_ldst(sdl);
758
        opn = "sdl";
759
        break;
760
    case OPC_LDR:
761
        op_ldst(ldr);
762
        GEN_STORE_TN_REG(rt, T0);
763
        opn = "ldr";
764
        break;
765
    case OPC_SDR:
766
        GEN_LOAD_REG_TN(T1, rt);
767
        op_ldst(sdr);
768
        opn = "sdr";
769
        break;
770
#endif
771
    case OPC_LW:
772
        op_ldst(lw);
773
        GEN_STORE_TN_REG(rt, T0);
774
        opn = "lw";
775
        break;
776
    case OPC_LWU:
777
        op_ldst(lwu);
778
        GEN_STORE_TN_REG(rt, T0);
779
        opn = "lwu";
780
        break;
781
    case OPC_SW:
782
        GEN_LOAD_REG_TN(T1, rt);
783
        op_ldst(sw);
784
        opn = "sw";
785
        break;
786
    case OPC_LH:
787
        op_ldst(lh);
788
        GEN_STORE_TN_REG(rt, T0);
789
        opn = "lh";
790
        break;
791
    case OPC_SH:
792
        GEN_LOAD_REG_TN(T1, rt);
793
        op_ldst(sh);
794
        opn = "sh";
795
        break;
796
    case OPC_LHU:
797
        op_ldst(lhu);
798
        GEN_STORE_TN_REG(rt, T0);
799
        opn = "lhu";
800
        break;
801
    case OPC_LB:
802
        op_ldst(lb);
803
        GEN_STORE_TN_REG(rt, T0);
804
        opn = "lb";
805
        break;
806
    case OPC_SB:
807
        GEN_LOAD_REG_TN(T1, rt);
808
        op_ldst(sb);
809
        opn = "sb";
810
        break;
811
    case OPC_LBU:
812
        op_ldst(lbu);
813
        GEN_STORE_TN_REG(rt, T0);
814
        opn = "lbu";
815
        break;
816
    case OPC_LWL:
817
        GEN_LOAD_REG_TN(T1, rt);
818
        op_ldst(lwl);
819
        GEN_STORE_TN_REG(rt, T0);
820
        opn = "lwl";
821
        break;
822
    case OPC_SWL:
823
        GEN_LOAD_REG_TN(T1, rt);
824
        op_ldst(swl);
825
        opn = "swr";
826
        break;
827
    case OPC_LWR:
828
        GEN_LOAD_REG_TN(T1, rt);
829
        op_ldst(lwr);
830
        GEN_STORE_TN_REG(rt, T0);
831
        opn = "lwr";
832
        break;
833
    case OPC_SWR:
834
        GEN_LOAD_REG_TN(T1, rt);
835
        op_ldst(swr);
836
        opn = "swr";
837
        break;
838
    case OPC_LL:
839
        op_ldst(ll);
840
        GEN_STORE_TN_REG(rt, T0);
841
        opn = "ll";
842
        break;
843
    case OPC_SC:
844
        save_cpu_state(ctx, 1);
845
        GEN_LOAD_REG_TN(T1, rt);
846
        op_ldst(sc);
847
        GEN_STORE_TN_REG(rt, T0);
848
        opn = "sc";
849
        break;
850
    default:
851
        MIPS_INVAL("load/store");
852
        generate_exception(ctx, EXCP_RI);
853
        return;
854
    }
855
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
856
}
857

    
858
/* Load and store */
859
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
860
                      int base, int16_t offset)
861
{
862
    const char *opn = "unk";
863

    
864
    if (base == 0) {
865
        GEN_LOAD_IMM_TN(T0, offset);
866
    } else if (offset == 0) {
867
        gen_op_load_gpr_T0(base);
868
    } else {
869
        gen_op_load_gpr_T0(base);
870
        gen_op_set_T1(offset);
871
        gen_op_addr_add();
872
    }
873
    /* Don't do NOP if destination is zero: we must perform the actual
874
     * memory access
875
     */
876
    switch (opc) {
877
    case OPC_LWC1:
878
        op_ldst(lwc1);
879
        GEN_STORE_FTN_FREG(ft, WT0);
880
        opn = "lwc1";
881
        break;
882
    case OPC_SWC1:
883
        GEN_LOAD_FREG_FTN(WT0, ft);
884
        op_ldst(swc1);
885
        opn = "swc1";
886
        break;
887
    case OPC_LDC1:
888
        op_ldst(ldc1);
889
        GEN_STORE_FTN_FREG(ft, DT0);
890
        opn = "ldc1";
891
        break;
892
    case OPC_SDC1:
893
        GEN_LOAD_FREG_FTN(DT0, ft);
894
        op_ldst(sdc1);
895
        opn = "sdc1";
896
        break;
897
    default:
898
        MIPS_INVAL("float load/store");
899
        generate_exception(ctx, EXCP_RI);
900
        return;
901
    }
902
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
903
}
904

    
905
/* Arithmetic with immediate operand */
906
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
907
                           int rs, int16_t imm)
908
{
909
    uint32_t uimm;
910
    const char *opn = "unk";
911

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

    
1083
/* Arithmetic */
1084
static void gen_arith (DisasContext *ctx, uint32_t opc,
1085
                       int rd, int rs, int rt)
1086
{
1087
    const char *opn = "unk";
1088

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

    
1234
/* Arithmetic on HI/LO registers */
1235
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1236
{
1237
    const char *opn = "unk";
1238

    
1239
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1240
        /* Treat as a NOP */
1241
        MIPS_DEBUG("NOP");
1242
        return;
1243
    }
1244
    switch (opc) {
1245
    case OPC_MFHI:
1246
        gen_op_load_HI();
1247
        GEN_STORE_TN_REG(reg, T0);
1248
        opn = "mfhi";
1249
        break;
1250
    case OPC_MFLO:
1251
        gen_op_load_LO();
1252
        GEN_STORE_TN_REG(reg, T0);
1253
        opn = "mflo";
1254
        break;
1255
    case OPC_MTHI:
1256
        GEN_LOAD_REG_TN(T0, reg);
1257
        gen_op_store_HI();
1258
        opn = "mthi";
1259
        break;
1260
    case OPC_MTLO:
1261
        GEN_LOAD_REG_TN(T0, reg);
1262
        gen_op_store_LO();
1263
        opn = "mtlo";
1264
        break;
1265
    default:
1266
        MIPS_INVAL("HILO");
1267
        generate_exception(ctx, EXCP_RI);
1268
        return;
1269
    }
1270
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1271
}
1272

    
1273
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1274
                        int rs, int rt)
1275
{
1276
    const char *opn = "unk";
1277

    
1278
    GEN_LOAD_REG_TN(T0, rs);
1279
    GEN_LOAD_REG_TN(T1, rt);
1280
    switch (opc) {
1281
    case OPC_DIV:
1282
        gen_op_div();
1283
        opn = "div";
1284
        break;
1285
    case OPC_DIVU:
1286
        gen_op_divu();
1287
        opn = "divu";
1288
        break;
1289
    case OPC_MULT:
1290
        gen_op_mult();
1291
        opn = "mult";
1292
        break;
1293
    case OPC_MULTU:
1294
        gen_op_multu();
1295
        opn = "multu";
1296
        break;
1297
#ifdef TARGET_MIPS64
1298
    case OPC_DDIV:
1299
        gen_op_ddiv();
1300
        opn = "ddiv";
1301
        break;
1302
    case OPC_DDIVU:
1303
        gen_op_ddivu();
1304
        opn = "ddivu";
1305
        break;
1306
    case OPC_DMULT:
1307
        gen_op_dmult();
1308
        opn = "dmult";
1309
        break;
1310
    case OPC_DMULTU:
1311
        gen_op_dmultu();
1312
        opn = "dmultu";
1313
        break;
1314
#endif
1315
    case OPC_MADD:
1316
        gen_op_madd();
1317
        opn = "madd";
1318
        break;
1319
    case OPC_MADDU:
1320
        gen_op_maddu();
1321
        opn = "maddu";
1322
        break;
1323
    case OPC_MSUB:
1324
        gen_op_msub();
1325
        opn = "msub";
1326
        break;
1327
    case OPC_MSUBU:
1328
        gen_op_msubu();
1329
        opn = "msubu";
1330
        break;
1331
    default:
1332
        MIPS_INVAL("mul/div");
1333
        generate_exception(ctx, EXCP_RI);
1334
        return;
1335
    }
1336
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1337
}
1338

    
1339
static void gen_cl (DisasContext *ctx, uint32_t opc,
1340
                    int rd, int rs)
1341
{
1342
    const char *opn = "unk";
1343
    if (rd == 0) {
1344
        /* Treat as a NOP */
1345
        MIPS_DEBUG("NOP");
1346
        return;
1347
    }
1348
    GEN_LOAD_REG_TN(T0, rs);
1349
    switch (opc) {
1350
    case OPC_CLO:
1351
        gen_op_clo();
1352
        opn = "clo";
1353
        break;
1354
    case OPC_CLZ:
1355
        gen_op_clz();
1356
        opn = "clz";
1357
        break;
1358
#ifdef TARGET_MIPS64
1359
    case OPC_DCLO:
1360
        gen_op_dclo();
1361
        opn = "dclo";
1362
        break;
1363
    case OPC_DCLZ:
1364
        gen_op_dclz();
1365
        opn = "dclz";
1366
        break;
1367
#endif
1368
    default:
1369
        MIPS_INVAL("CLx");
1370
        generate_exception(ctx, EXCP_RI);
1371
        return;
1372
    }
1373
    gen_op_store_T0_gpr(rd);
1374
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1375
}
1376

    
1377
/* Traps */
1378
static void gen_trap (DisasContext *ctx, uint32_t opc,
1379
                      int rs, int rt, int16_t imm)
1380
{
1381
    int cond;
1382

    
1383
    cond = 0;
1384
    /* Load needed operands */
1385
    switch (opc) {
1386
    case OPC_TEQ:
1387
    case OPC_TGE:
1388
    case OPC_TGEU:
1389
    case OPC_TLT:
1390
    case OPC_TLTU:
1391
    case OPC_TNE:
1392
        /* Compare two registers */
1393
        if (rs != rt) {
1394
            GEN_LOAD_REG_TN(T0, rs);
1395
            GEN_LOAD_REG_TN(T1, rt);
1396
            cond = 1;
1397
        }
1398
        break;
1399
    case OPC_TEQI:
1400
    case OPC_TGEI:
1401
    case OPC_TGEIU:
1402
    case OPC_TLTI:
1403
    case OPC_TLTIU:
1404
    case OPC_TNEI:
1405
        /* Compare register to immediate */
1406
        if (rs != 0 || imm != 0) {
1407
            GEN_LOAD_REG_TN(T0, rs);
1408
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1409
            cond = 1;
1410
        }
1411
        break;
1412
    }
1413
    if (cond == 0) {
1414
        switch (opc) {
1415
        case OPC_TEQ:   /* rs == rs */
1416
        case OPC_TEQI:  /* r0 == 0  */
1417
        case OPC_TGE:   /* rs >= rs */
1418
        case OPC_TGEI:  /* r0 >= 0  */
1419
        case OPC_TGEU:  /* rs >= rs unsigned */
1420
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1421
            /* Always trap */
1422
            gen_op_set_T0(1);
1423
            break;
1424
        case OPC_TLT:   /* rs < rs           */
1425
        case OPC_TLTI:  /* r0 < 0            */
1426
        case OPC_TLTU:  /* rs < rs unsigned  */
1427
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1428
        case OPC_TNE:   /* rs != rs          */
1429
        case OPC_TNEI:  /* r0 != 0           */
1430
            /* Never trap: treat as NOP */
1431
            return;
1432
        default:
1433
            MIPS_INVAL("TRAP");
1434
            generate_exception(ctx, EXCP_RI);
1435
            return;
1436
        }
1437
    } else {
1438
        switch (opc) {
1439
        case OPC_TEQ:
1440
        case OPC_TEQI:
1441
            gen_op_eq();
1442
            break;
1443
        case OPC_TGE:
1444
        case OPC_TGEI:
1445
            gen_op_ge();
1446
            break;
1447
        case OPC_TGEU:
1448
        case OPC_TGEIU:
1449
            gen_op_geu();
1450
            break;
1451
        case OPC_TLT:
1452
        case OPC_TLTI:
1453
            gen_op_lt();
1454
            break;
1455
        case OPC_TLTU:
1456
        case OPC_TLTIU:
1457
            gen_op_ltu();
1458
            break;
1459
        case OPC_TNE:
1460
        case OPC_TNEI:
1461
            gen_op_ne();
1462
            break;
1463
        default:
1464
            MIPS_INVAL("TRAP");
1465
            generate_exception(ctx, EXCP_RI);
1466
            return;
1467
        }
1468
    }
1469
    save_cpu_state(ctx, 1);
1470
    gen_op_trap();
1471
    ctx->bstate = BS_STOP;
1472
}
1473

    
1474
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1475
{
1476
    TranslationBlock *tb;
1477
    tb = ctx->tb;
1478
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1479
        if (n == 0)
1480
            gen_op_goto_tb0(TBPARAM(tb));
1481
        else
1482
            gen_op_goto_tb1(TBPARAM(tb));
1483
        gen_op_save_pc(dest);
1484
        gen_op_set_T0((long)tb + n);
1485
    } else {
1486
        gen_op_save_pc(dest);
1487
        gen_op_reset_T0();
1488
    }
1489
    gen_op_exit_tb();
1490
}
1491

    
1492
/* Branches (before delay slot) */
1493
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1494
                                int rs, int rt, int32_t offset)
1495
{
1496
    target_ulong btarget = -1;
1497
    int blink = 0;
1498
    int bcond = 0;
1499

    
1500
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1501
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1502
            fprintf(logfile,
1503
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1504
                    ctx->pc);
1505
        }
1506
        MIPS_INVAL("branch/jump in bdelay slot");
1507
        generate_exception(ctx, EXCP_RI);
1508
        return;
1509
    }
1510

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

    
1729
/* special3 bitfield operations */
1730
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1731
                       int rs, int lsb, int msb)
1732
{
1733
    GEN_LOAD_REG_TN(T1, rs);
1734
    switch (opc) {
1735
    case OPC_EXT:
1736
        if (lsb + msb > 31)
1737
            goto fail;
1738
        gen_op_ext(lsb, msb + 1);
1739
        break;
1740
    case OPC_DEXTM:
1741
        if (lsb + msb > 63)
1742
            goto fail;
1743
        gen_op_ext(lsb, msb + 1 + 32);
1744
        break;
1745
    case OPC_DEXTU:
1746
        if (lsb + msb > 63)
1747
            goto fail;
1748
        gen_op_ext(lsb + 32, msb + 1);
1749
        break;
1750
    case OPC_DEXT:
1751
        gen_op_ext(lsb, msb + 1);
1752
        break;
1753
    case OPC_INS:
1754
        if (lsb > msb)
1755
            goto fail;
1756
        GEN_LOAD_REG_TN(T0, rt);
1757
        gen_op_ins(lsb, msb - lsb + 1);
1758
        break;
1759
    case OPC_DINSM:
1760
        if (lsb > msb)
1761
            goto fail;
1762
        GEN_LOAD_REG_TN(T0, rt);
1763
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1764
        break;
1765
    case OPC_DINSU:
1766
        if (lsb > msb)
1767
            goto fail;
1768
        GEN_LOAD_REG_TN(T0, rt);
1769
        gen_op_ins(lsb + 32, msb - lsb + 1);
1770
        break;
1771
    case OPC_DINS:
1772
        if (lsb > msb)
1773
            goto fail;
1774
        GEN_LOAD_REG_TN(T0, rt);
1775
        gen_op_ins(lsb, msb - lsb + 1);
1776
        break;
1777
    default:
1778
fail:
1779
        MIPS_INVAL("bitops");
1780
        generate_exception(ctx, EXCP_RI);
1781
        return;
1782
    }
1783
    GEN_STORE_TN_REG(rt, T0);
1784
}
1785

    
1786
/* CP0 (MMU and control) */
1787
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1788
{
1789
    const char *rn = "invalid";
1790

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

    
2368
die:
2369
#if defined MIPS_DEBUG_DISAS
2370
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2371
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2372
                rn, reg, sel);
2373
    }
2374
#endif
2375
    generate_exception(ctx, EXCP_RI);
2376
}
2377

    
2378
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2379
{
2380
    const char *rn = "invalid";
2381

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

    
2972
die:
2973
#if defined MIPS_DEBUG_DISAS
2974
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2975
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2976
                rn, reg, sel);
2977
    }
2978
#endif
2979
    generate_exception(ctx, EXCP_RI);
2980
}
2981

    
2982
#ifdef TARGET_MIPS64
2983
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2984
{
2985
    const char *rn = "invalid";
2986

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

    
3555
die:
3556
#if defined MIPS_DEBUG_DISAS
3557
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3558
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3559
                rn, reg, sel);
3560
    }
3561
#endif
3562
    generate_exception(ctx, EXCP_RI);
3563
}
3564

    
3565
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3566
{
3567
    const char *rn = "invalid";
3568

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

    
4150
die:
4151
#if defined MIPS_DEBUG_DISAS
4152
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4153
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4154
                rn, reg, sel);
4155
    }
4156
#endif
4157
    generate_exception(ctx, EXCP_RI);
4158
}
4159
#endif /* TARGET_MIPS64 */
4160

    
4161
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4162
{
4163
    const char *opn = "unk";
4164

    
4165
    switch (opc) {
4166
    case OPC_MFC0:
4167
        if (rt == 0) {
4168
            /* Treat as NOP */
4169
            return;
4170
        }
4171
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4172
        gen_op_store_T0_gpr(rt);
4173
        opn = "mfc0";
4174
        break;
4175
    case OPC_MTC0:
4176
        GEN_LOAD_REG_TN(T0, rt);
4177
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4178
        opn = "mtc0";
4179
        break;
4180
#ifdef TARGET_MIPS64
4181
    case OPC_DMFC0:
4182
        if (rt == 0) {
4183
            /* Treat as NOP */
4184
            return;
4185
        }
4186
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4187
        gen_op_store_T0_gpr(rt);
4188
        opn = "dmfc0";
4189
        break;
4190
    case OPC_DMTC0:
4191
        GEN_LOAD_REG_TN(T0, rt);
4192
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4193
        opn = "dmtc0";
4194
        break;
4195
#endif
4196
#if defined(MIPS_USES_R4K_TLB)
4197
    case OPC_TLBWI:
4198
        gen_op_tlbwi();
4199
        opn = "tlbwi";
4200
        break;
4201
    case OPC_TLBWR:
4202
        gen_op_tlbwr();
4203
        opn = "tlbwr";
4204
        break;
4205
    case OPC_TLBP:
4206
        gen_op_tlbp();
4207
        opn = "tlbp";
4208
        break;
4209
    case OPC_TLBR:
4210
        gen_op_tlbr();
4211
        opn = "tlbr";
4212
        break;
4213
#endif
4214
    case OPC_ERET:
4215
        opn = "eret";
4216
        save_cpu_state(ctx, 0);
4217
        gen_op_eret();
4218
        ctx->bstate = BS_EXCP;
4219
        break;
4220
    case OPC_DERET:
4221
        opn = "deret";
4222
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4223
            generate_exception(ctx, EXCP_RI);
4224
        } else {
4225
            save_cpu_state(ctx, 0);
4226
            gen_op_deret();
4227
            ctx->bstate = BS_EXCP;
4228
        }
4229
        break;
4230
    case OPC_WAIT:
4231
        opn = "wait";
4232
        /* If we get an exception, we want to restart at next instruction */
4233
        ctx->pc += 4;
4234
        save_cpu_state(ctx, 1);
4235
        ctx->pc -= 4;
4236
        gen_op_wait();
4237
        ctx->bstate = BS_EXCP;
4238
        break;
4239
    default:
4240
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4241
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4242
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4243
                    ((ctx->opcode >> 16) & 0x1F));
4244
        }
4245
        generate_exception(ctx, EXCP_RI);
4246
        return;
4247
    }
4248
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4249
}
4250

    
4251
/* CP1 Branches (before delay slot) */
4252
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4253
                                 int32_t cc, int32_t offset)
4254
{
4255
    target_ulong btarget;
4256

    
4257
    btarget = ctx->pc + 4 + offset;
4258

    
4259
    switch (op) {
4260
    case OPC_BC1F:
4261
        gen_op_bc1f(cc);
4262
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4263
        goto not_likely;
4264
    case OPC_BC1FL:
4265
        gen_op_bc1f(cc);
4266
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4267
        goto likely;
4268
    case OPC_BC1T:
4269
        gen_op_bc1t(cc);
4270
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4271
        goto not_likely;
4272
    case OPC_BC1TL:
4273
        gen_op_bc1t(cc);
4274
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4275
    likely:
4276
        ctx->hflags |= MIPS_HFLAG_BL;
4277
        gen_op_set_bcond();
4278
        gen_op_save_bcond();
4279
        break;
4280
    case OPC_BC1FANY2:
4281
        gen_op_bc1fany2(cc);
4282
        MIPS_DEBUG("bc1fany2 " TARGET_FMT_lx, btarget);
4283
        goto not_likely;
4284
    case OPC_BC1TANY2:
4285
        gen_op_bc1tany2(cc);
4286
        MIPS_DEBUG("bc1tany2 " TARGET_FMT_lx, btarget);
4287
        goto not_likely;
4288
    case OPC_BC1FANY4:
4289
        gen_op_bc1fany4(cc);
4290
        MIPS_DEBUG("bc1fany4 " TARGET_FMT_lx, btarget);
4291
        goto not_likely;
4292
    case OPC_BC1TANY4:
4293
        gen_op_bc1tany4(cc);
4294
        MIPS_DEBUG("bc1tany4 " TARGET_FMT_lx, btarget);
4295
    not_likely:
4296
        ctx->hflags |= MIPS_HFLAG_BC;
4297
        gen_op_set_bcond();
4298
        break;
4299
    default:
4300
        MIPS_INVAL("cp1 branch");
4301
        generate_exception (ctx, EXCP_RI);
4302
        return;
4303
    }
4304

    
4305
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4306
               ctx->hflags, btarget);
4307
    ctx->btarget = btarget;
4308

    
4309
    return;
4310
}
4311

    
4312
/* Coprocessor 1 (FPU) */
4313

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

    
4334
#define FOP(func, fmt) (((fmt) << 21) | (func))
4335

    
4336
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4337
{
4338
    const char *opn = "unk";
4339

    
4340
    switch (opc) {
4341
    case OPC_MFC1:
4342
        GEN_LOAD_FREG_FTN(WT0, fs);
4343
        gen_op_mfc1();
4344
        GEN_STORE_TN_REG(rt, T0);
4345
        opn = "mfc1";
4346
        break;
4347
    case OPC_MTC1:
4348
        GEN_LOAD_REG_TN(T0, rt);
4349
        gen_op_mtc1();
4350
        GEN_STORE_FTN_FREG(fs, WT0);
4351
        opn = "mtc1";
4352
        break;
4353
    case OPC_CFC1:
4354
        GEN_LOAD_IMM_TN(T1, fs);
4355
        gen_op_cfc1();
4356
        GEN_STORE_TN_REG(rt, T0);
4357
        opn = "cfc1";
4358
        break;
4359
    case OPC_CTC1:
4360
        GEN_LOAD_IMM_TN(T1, fs);
4361
        GEN_LOAD_REG_TN(T0, rt);
4362
        gen_op_ctc1();
4363
        opn = "ctc1";
4364
        break;
4365
    case OPC_DMFC1:
4366
        GEN_LOAD_FREG_FTN(DT0, fs);
4367
        gen_op_dmfc1();
4368
        GEN_STORE_TN_REG(rt, T0);
4369
        opn = "dmfc1";
4370
        break;
4371
    case OPC_DMTC1:
4372
        GEN_LOAD_REG_TN(T0, rt);
4373
        gen_op_dmtc1();
4374
        GEN_STORE_FTN_FREG(fs, DT0);
4375
        opn = "dmtc1";
4376
        break;
4377
    case OPC_MFHC1:
4378
        CHECK_FR(ctx, fs);
4379
        GEN_LOAD_FREG_FTN(WTH0, fs);
4380
        gen_op_mfhc1();
4381
        GEN_STORE_TN_REG(rt, T0);
4382
        opn = "mfhc1";
4383
        break;
4384
    case OPC_MTHC1:
4385
        CHECK_FR(ctx, fs);
4386
        GEN_LOAD_REG_TN(T0, rt);
4387
        gen_op_mthc1();
4388
        GEN_STORE_FTN_FREG(fs, WTH0);
4389
        opn = "mthc1";
4390
        break;
4391
    default:
4392
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4393
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4394
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4395
                    ((ctx->opcode >> 16) & 0x1F));
4396
        }
4397
        generate_exception (ctx, EXCP_RI);
4398
        return;
4399
    }
4400
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4401
}
4402

    
4403
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4404
{
4405
    uint32_t ccbit;
4406

    
4407
    GEN_LOAD_REG_TN(T0, rd);
4408
    GEN_LOAD_REG_TN(T1, rs);
4409
    if (cc)
4410
        ccbit = 1 << (24 + cc);
4411
    else
4412
        ccbit = 1 << 23;
4413
    if (!tf)
4414
        gen_op_movf(ccbit);
4415
    else
4416
        gen_op_movt(ccbit);
4417
    GEN_STORE_TN_REG(rd, T0);
4418
}
4419

    
4420
#define GEN_MOVCF(fmt)                                                \
4421
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4422
{                                                                     \
4423
    uint32_t ccbit;                                                   \
4424
                                                                      \
4425
    if (cc)                                                           \
4426
        ccbit = 1 << (24 + cc);                                       \
4427
    else                                                              \
4428
        ccbit = 1 << 23;                                              \
4429
    if (!tf)                                                          \
4430
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4431
    else                                                              \
4432
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4433
}
4434
GEN_MOVCF(d);
4435
GEN_MOVCF(s);
4436
GEN_MOVCF(ps);
4437
#undef GEN_MOVCF
4438

    
4439
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4440
                        int fs, int fd, int cc)
4441
{
4442
    const char *opn = "unk";
4443
    const char *condnames[] = {
4444
            "c.f",
4445
            "c.un",
4446
            "c.eq",
4447
            "c.ueq",
4448
            "c.olt",
4449
            "c.ult",
4450
            "c.ole",
4451
            "c.ule",
4452
            "c.sf",
4453
            "c.ngle",
4454
            "c.seq",
4455
            "c.ngl",
4456
            "c.lt",
4457
            "c.nge",
4458
            "c.le",
4459
            "c.ngt",
4460
    };
4461
    int binary = 0;
4462
    uint32_t func = ctx->opcode & 0x3f;
4463

    
4464
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4465
    case FOP(0, 16):
4466
        GEN_LOAD_FREG_FTN(WT0, fs);
4467
        GEN_LOAD_FREG_FTN(WT1, ft);
4468
        gen_op_float_add_s();
4469
        GEN_STORE_FTN_FREG(fd, WT2);
4470
        opn = "add.s";
4471
        binary = 1;
4472
        break;
4473
    case FOP(1, 16):
4474
        GEN_LOAD_FREG_FTN(WT0, fs);
4475
        GEN_LOAD_FREG_FTN(WT1, ft);
4476
        gen_op_float_sub_s();
4477
        GEN_STORE_FTN_FREG(fd, WT2);
4478
        opn = "sub.s";
4479
        binary = 1;
4480
        break;
4481
    case FOP(2, 16):
4482
        GEN_LOAD_FREG_FTN(WT0, fs);
4483
        GEN_LOAD_FREG_FTN(WT1, ft);
4484
        gen_op_float_mul_s();
4485
        GEN_STORE_FTN_FREG(fd, WT2);
4486
        opn = "mul.s";
4487
        binary = 1;
4488
        break;
4489
    case FOP(3, 16):
4490
        GEN_LOAD_FREG_FTN(WT0, fs);
4491
        GEN_LOAD_FREG_FTN(WT1, ft);
4492
        gen_op_float_div_s();
4493
        GEN_STORE_FTN_FREG(fd, WT2);
4494
        opn = "div.s";
4495
        binary = 1;
4496
        break;
4497
    case FOP(4, 16):
4498
        GEN_LOAD_FREG_FTN(WT0, fs);
4499
        gen_op_float_sqrt_s();
4500
        GEN_STORE_FTN_FREG(fd, WT2);
4501
        opn = "sqrt.s";
4502
        break;
4503
    case FOP(5, 16):
4504
        GEN_LOAD_FREG_FTN(WT0, fs);
4505
        gen_op_float_abs_s();
4506
        GEN_STORE_FTN_FREG(fd, WT2);
4507
        opn = "abs.s";
4508
        break;
4509
    case FOP(6, 16):
4510
        GEN_LOAD_FREG_FTN(WT0, fs);
4511
        gen_op_float_mov_s();
4512
        GEN_STORE_FTN_FREG(fd, WT2);
4513
        opn = "mov.s";
4514
        break;
4515
    case FOP(7, 16):
4516
        GEN_LOAD_FREG_FTN(WT0, fs);
4517
        gen_op_float_chs_s();
4518
        GEN_STORE_FTN_FREG(fd, WT2);
4519
        opn = "neg.s";
4520
        break;
4521
    case FOP(8, 16):
4522
        CHECK_FR(ctx, fs);
4523
        GEN_LOAD_FREG_FTN(WT0, fs);
4524
        gen_op_float_roundl_s();
4525
        GEN_STORE_FTN_FREG(fd, DT2);
4526
        opn = "round.l.s";
4527
        break;
4528
    case FOP(9, 16):
4529
        CHECK_FR(ctx, fs);
4530
        GEN_LOAD_FREG_FTN(WT0, fs);
4531
        gen_op_float_truncl_s();
4532
        GEN_STORE_FTN_FREG(fd, DT2);
4533
        opn = "trunc.l.s";
4534
        break;
4535
    case FOP(10, 16):
4536
        CHECK_FR(ctx, fs);
4537
        GEN_LOAD_FREG_FTN(WT0, fs);
4538
        gen_op_float_ceill_s();
4539
        GEN_STORE_FTN_FREG(fd, DT2);
4540
        opn = "ceil.l.s";
4541
        break;
4542
    case FOP(11, 16):
4543
        CHECK_FR(ctx, fs);
4544
        GEN_LOAD_FREG_FTN(WT0, fs);
4545
        gen_op_float_floorl_s();
4546
        GEN_STORE_FTN_FREG(fd, DT2);
4547
        opn = "floor.l.s";
4548
        break;
4549
    case FOP(12, 16):
4550
        GEN_LOAD_FREG_FTN(WT0, fs);
4551
        gen_op_float_roundw_s();
4552
        GEN_STORE_FTN_FREG(fd, WT2);
4553
        opn = "round.w.s";
4554
        break;
4555
    case FOP(13, 16):
4556
        GEN_LOAD_FREG_FTN(WT0, fs);
4557
        gen_op_float_truncw_s();
4558
        GEN_STORE_FTN_FREG(fd, WT2);
4559
        opn = "trunc.w.s";
4560
        break;
4561
    case FOP(14, 16):
4562
        GEN_LOAD_FREG_FTN(WT0, fs);
4563
        gen_op_float_ceilw_s();
4564
        GEN_STORE_FTN_FREG(fd, WT2);
4565
        opn = "ceil.w.s";
4566
        break;
4567
    case FOP(15, 16):
4568
        GEN_LOAD_FREG_FTN(WT0, fs);
4569
        gen_op_float_floorw_s();
4570
        GEN_STORE_FTN_FREG(fd, WT2);
4571
        opn = "floor.w.s";
4572
        break;
4573
    case FOP(17, 16):
4574
        GEN_LOAD_REG_TN(T0, ft);
4575
        GEN_LOAD_FREG_FTN(WT0, fs);
4576
        GEN_LOAD_FREG_FTN(WT2, fd);
4577
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4578
        GEN_STORE_FTN_FREG(fd, WT2);
4579
        opn = "movcf.s";
4580
        break;
4581
    case FOP(18, 16):
4582
        GEN_LOAD_REG_TN(T0, ft);
4583
        GEN_LOAD_FREG_FTN(WT0, fs);
4584
        GEN_LOAD_FREG_FTN(WT2, fd);
4585
        gen_op_float_movz_s();
4586
        GEN_STORE_FTN_FREG(fd, WT2);
4587
        opn = "movz.s";
4588
        break;
4589
    case FOP(19, 16):
4590
        GEN_LOAD_REG_TN(T0, ft);
4591
        GEN_LOAD_FREG_FTN(WT0, fs);
4592
        GEN_LOAD_FREG_FTN(WT2, fd);
4593
        gen_op_float_movn_s();
4594
        GEN_STORE_FTN_FREG(fd, WT2);
4595
        opn = "movn.s";
4596
        break;
4597
    case FOP(33, 16):
4598
        CHECK_FR(ctx, fd);
4599
        GEN_LOAD_FREG_FTN(WT0, fs);
4600
        gen_op_float_cvtd_s();
4601
        GEN_STORE_FTN_FREG(fd, DT2);
4602
        opn = "cvt.d.s";
4603
        break;
4604
    case FOP(36, 16):
4605
        GEN_LOAD_FREG_FTN(WT0, fs);
4606
        gen_op_float_cvtw_s();
4607
        GEN_STORE_FTN_FREG(fd, WT2);
4608
        opn = "cvt.w.s";
4609
        break;
4610
    case FOP(37, 16):
4611
        CHECK_FR(ctx, fs | fd);
4612
        GEN_LOAD_FREG_FTN(WT0, fs);
4613
        gen_op_float_cvtl_s();
4614
        GEN_STORE_FTN_FREG(fd, DT2);
4615
        opn = "cvt.l.s";
4616
        break;
4617
    case FOP(38, 16):
4618
        CHECK_FR(ctx, fs | ft | fd);
4619
        GEN_LOAD_FREG_FTN(WT1, fs);
4620
        GEN_LOAD_FREG_FTN(WT0, ft);
4621
        gen_op_float_cvtps_s();
4622
        GEN_STORE_FTN_FREG(fd, DT2);
4623
        opn = "cvt.ps.s";
4624
        break;
4625
    case FOP(48, 16):
4626
    case FOP(49, 16):
4627
    case FOP(50, 16):
4628
    case FOP(51, 16):
4629
    case FOP(52, 16):
4630
    case FOP(53, 16):
4631
    case FOP(54, 16):
4632
    case FOP(55, 16):
4633
    case FOP(56, 16):
4634
    case FOP(57, 16):
4635
    case FOP(58, 16):
4636
    case FOP(59, 16):
4637
    case FOP(60, 16):
4638
    case FOP(61, 16):
4639
    case FOP(62, 16):
4640
    case FOP(63, 16):
4641
        GEN_LOAD_FREG_FTN(WT0, fs);
4642
        GEN_LOAD_FREG_FTN(WT1, ft);
4643
        gen_cmp_s(func-48, cc);
4644
        opn = condnames[func-48];
4645
        break;
4646
    case FOP(0, 17):
4647
        CHECK_FR(ctx, fs | ft | fd);
4648
        GEN_LOAD_FREG_FTN(DT0, fs);
4649
        GEN_LOAD_FREG_FTN(DT1, ft);
4650
        gen_op_float_add_d();
4651
        GEN_STORE_FTN_FREG(fd, DT2);
4652
        opn = "add.d";
4653
        binary = 1;
4654
        break;
4655
    case FOP(1, 17):
4656
        CHECK_FR(ctx, fs | ft | fd);
4657
        GEN_LOAD_FREG_FTN(DT0, fs);
4658
        GEN_LOAD_FREG_FTN(DT1, ft);
4659
        gen_op_float_sub_d();
4660
        GEN_STORE_FTN_FREG(fd, DT2);
4661
        opn = "sub.d";
4662
        binary = 1;
4663
        break;
4664
    case FOP(2, 17):
4665
        CHECK_FR(ctx, fs | ft | fd);
4666
        GEN_LOAD_FREG_FTN(DT0, fs);
4667
        GEN_LOAD_FREG_FTN(DT1, ft);
4668
        gen_op_float_mul_d();
4669
        GEN_STORE_FTN_FREG(fd, DT2);
4670
        opn = "mul.d";
4671
        binary = 1;
4672
        break;
4673
    case FOP(3, 17):
4674
        CHECK_FR(ctx, fs | ft | fd);
4675
        GEN_LOAD_FREG_FTN(DT0, fs);
4676
        GEN_LOAD_FREG_FTN(DT1, ft);
4677
        gen_op_float_div_d();
4678
        GEN_STORE_FTN_FREG(fd, DT2);
4679
        opn = "div.d";
4680
        binary = 1;
4681
        break;
4682
    case FOP(4, 17):
4683
        CHECK_FR(ctx, fs | fd);
4684
        GEN_LOAD_FREG_FTN(DT0, fs);
4685
        gen_op_float_sqrt_d();
4686
        GEN_STORE_FTN_FREG(fd, DT2);
4687
        opn = "sqrt.d";
4688
        break;
4689
    case FOP(5, 17):
4690
        CHECK_FR(ctx, fs | fd);
4691
        GEN_LOAD_FREG_FTN(DT0, fs);
4692
        gen_op_float_abs_d();
4693
        GEN_STORE_FTN_FREG(fd, DT2);
4694
        opn = "abs.d";
4695
        break;
4696
    case FOP(6, 17):
4697
        CHECK_FR(ctx, fs | fd);
4698
        GEN_LOAD_FREG_FTN(DT0, fs);
4699
        gen_op_float_mov_d();
4700
        GEN_STORE_FTN_FREG(fd, DT2);
4701
        opn = "mov.d";
4702
        break;
4703
    case FOP(7, 17):
4704
        CHECK_FR(ctx, fs | fd);
4705
        GEN_LOAD_FREG_FTN(DT0, fs);
4706
        gen_op_float_chs_d();
4707
        GEN_STORE_FTN_FREG(fd, DT2);
4708
        opn = "neg.d";
4709
        break;
4710
    case FOP(8, 17):
4711
        CHECK_FR(ctx, fs);
4712
        GEN_LOAD_FREG_FTN(DT0, fs);
4713
        gen_op_float_roundl_d();
4714
        GEN_STORE_FTN_FREG(fd, DT2);
4715
        opn = "round.l.d";
4716
        break;
4717
    case FOP(9, 17):
4718
        CHECK_FR(ctx, fs);
4719
        GEN_LOAD_FREG_FTN(DT0, fs);
4720
        gen_op_float_truncl_d();
4721
        GEN_STORE_FTN_FREG(fd, DT2);
4722
        opn = "trunc.l.d";
4723
        break;
4724
    case FOP(10, 17):
4725
        CHECK_FR(ctx, fs);
4726
        GEN_LOAD_FREG_FTN(DT0, fs);
4727
        gen_op_float_ceill_d();
4728
        GEN_STORE_FTN_FREG(fd, DT2);
4729
        opn = "ceil.l.d";
4730
        break;
4731
    case FOP(11, 17):
4732
        CHECK_FR(ctx, fs);
4733
        GEN_LOAD_FREG_FTN(DT0, fs);
4734
        gen_op_float_floorl_d();
4735
        GEN_STORE_FTN_FREG(fd, DT2);
4736
        opn = "floor.l.d";
4737
        break;
4738
    case FOP(12, 17):
4739
        CHECK_FR(ctx, fs);
4740
        GEN_LOAD_FREG_FTN(DT0, fs);
4741
        gen_op_float_roundw_d();
4742
        GEN_STORE_FTN_FREG(fd, WT2);
4743
        opn = "round.w.d";
4744
        break;
4745
    case FOP(13, 17):
4746
        CHECK_FR(ctx, fs);
4747
        GEN_LOAD_FREG_FTN(DT0, fs);
4748
        gen_op_float_truncw_d();
4749
        GEN_STORE_FTN_FREG(fd, WT2);
4750
        opn = "trunc.w.d";
4751
        break;
4752
    case FOP(14, 17):
4753
        CHECK_FR(ctx, fs);
4754
        GEN_LOAD_FREG_FTN(DT0, fs);
4755
        gen_op_float_ceilw_d();
4756
        GEN_STORE_FTN_FREG(fd, WT2);
4757
        opn = "ceil.w.d";
4758
        break;
4759
    case FOP(15, 17):
4760
        CHECK_FR(ctx, fs);
4761
        GEN_LOAD_FREG_FTN(DT0, fs);
4762
        gen_op_float_floorw_d();
4763
        GEN_STORE_FTN_FREG(fd, WT2);
4764
        opn = "floor.w.d";
4765
        break;
4766
    case FOP(17, 17):
4767
        GEN_LOAD_REG_TN(T0, ft);
4768
        GEN_LOAD_FREG_FTN(DT0, fs);
4769
        GEN_LOAD_FREG_FTN(DT2, fd);
4770
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4771
        GEN_STORE_FTN_FREG(fd, DT2);
4772
        opn = "movcf.d";
4773
        break;
4774
    case FOP(18, 17):
4775
        GEN_LOAD_REG_TN(T0, ft);
4776
        GEN_LOAD_FREG_FTN(DT0, fs);
4777
        GEN_LOAD_FREG_FTN(DT2, fd);
4778
        gen_op_float_movz_d();
4779
        GEN_STORE_FTN_FREG(fd, DT2);
4780
        opn = "movz.d";
4781
        break;
4782
    case FOP(19, 17):
4783
        GEN_LOAD_REG_TN(T0, ft);
4784
        GEN_LOAD_FREG_FTN(DT0, fs);
4785
        GEN_LOAD_FREG_FTN(DT2, fd);
4786
        gen_op_float_movn_d();
4787
        GEN_STORE_FTN_FREG(fd, DT2);
4788
        opn = "movn.d";
4789
        break;
4790
    case FOP(48, 17):
4791
    case FOP(49, 17):
4792
    case FOP(50, 17):
4793
    case FOP(51, 17):
4794
    case FOP(52, 17):
4795
    case FOP(53, 17):
4796
    case FOP(54, 17):
4797
    case FOP(55, 17):
4798
    case FOP(56, 17):
4799
    case FOP(57, 17):
4800
    case FOP(58, 17):
4801
    case FOP(59, 17):
4802
    case FOP(60, 17):
4803
    case FOP(61, 17):
4804
    case FOP(62, 17):
4805
    case FOP(63, 17):
4806
        CHECK_FR(ctx, fs | ft);
4807
        GEN_LOAD_FREG_FTN(DT0, fs);
4808
        GEN_LOAD_FREG_FTN(DT1, ft);
4809
        gen_cmp_d(func-48, cc);
4810
        opn = condnames[func-48];
4811
        break;
4812
    case FOP(32, 17):
4813
        CHECK_FR(ctx, fs);
4814
        GEN_LOAD_FREG_FTN(DT0, fs);
4815
        gen_op_float_cvts_d();
4816
        GEN_STORE_FTN_FREG(fd, WT2);
4817
        opn = "cvt.s.d";
4818
        break;
4819
    case FOP(36, 17):
4820
        CHECK_FR(ctx, fs);
4821
        GEN_LOAD_FREG_FTN(DT0, fs);
4822
        gen_op_float_cvtw_d();
4823
        GEN_STORE_FTN_FREG(fd, WT2);
4824
        opn = "cvt.w.d";
4825
        break;
4826
    case FOP(37, 17):
4827
        CHECK_FR(ctx, fs | fd);
4828
        GEN_LOAD_FREG_FTN(DT0, fs);
4829
        gen_op_float_cvtl_d();
4830
        GEN_STORE_FTN_FREG(fd, DT2);
4831
        opn = "cvt.l.d";
4832
        break;
4833
    case FOP(32, 20):
4834
        GEN_LOAD_FREG_FTN(WT0, fs);
4835
        gen_op_float_cvts_w();
4836
        GEN_STORE_FTN_FREG(fd, WT2);
4837
        opn = "cvt.s.w";
4838
        break;
4839
    case FOP(33, 20):
4840
        CHECK_FR(ctx, fd);
4841
        GEN_LOAD_FREG_FTN(WT0, fs);
4842
        gen_op_float_cvtd_w();
4843
        GEN_STORE_FTN_FREG(fd, DT2);
4844
        opn = "cvt.d.w";
4845
        break;
4846
    case FOP(32, 21):
4847
        CHECK_FR(ctx, fs);
4848
        GEN_LOAD_FREG_FTN(DT0, fs);
4849
        gen_op_float_cvts_l();
4850
        GEN_STORE_FTN_FREG(fd, WT2);
4851
        opn = "cvt.s.l";
4852
        break;
4853
    case FOP(33, 21):
4854
        CHECK_FR(ctx, fs | fd);
4855
        GEN_LOAD_FREG_FTN(DT0, fs);
4856
        gen_op_float_cvtd_l();
4857
        GEN_STORE_FTN_FREG(fd, DT2);
4858
        opn = "cvt.d.l";
4859
        break;
4860
    case FOP(38, 20):
4861
    case FOP(38, 21):
4862
        CHECK_FR(ctx, fs | fd);
4863
        GEN_LOAD_FREG_FTN(WT0, fs);
4864
        GEN_LOAD_FREG_FTN(WTH0, fs);
4865
        gen_op_float_cvtps_pw();
4866
        GEN_STORE_FTN_FREG(fd, WT2);
4867
        GEN_STORE_FTN_FREG(fd, WTH2);
4868
        opn = "cvt.ps.pw";
4869
        break;
4870
    case FOP(0, 22):
4871
        CHECK_FR(ctx, fs | ft | fd);
4872
        GEN_LOAD_FREG_FTN(WT0, fs);
4873
        GEN_LOAD_FREG_FTN(WTH0, fs);
4874
        GEN_LOAD_FREG_FTN(WT1, ft);
4875
        GEN_LOAD_FREG_FTN(WTH1, ft);
4876
        gen_op_float_add_ps();
4877
        GEN_STORE_FTN_FREG(fd, WT2);
4878
        GEN_STORE_FTN_FREG(fd, WTH2);
4879
        opn = "add.ps";
4880
        break;
4881
    case FOP(1, 22):
4882
        CHECK_FR(ctx, fs | ft | fd);
4883
        GEN_LOAD_FREG_FTN(WT0, fs);
4884
        GEN_LOAD_FREG_FTN(WTH0, fs);
4885
        GEN_LOAD_FREG_FTN(WT1, ft);
4886
        GEN_LOAD_FREG_FTN(WTH1, ft);
4887
        gen_op_float_sub_ps();
4888
        GEN_STORE_FTN_FREG(fd, WT2);
4889
        GEN_STORE_FTN_FREG(fd, WTH2);
4890
        opn = "sub.ps";
4891
        break;
4892
    case FOP(2, 22):
4893
        CHECK_FR(ctx, fs | ft | fd);
4894
        GEN_LOAD_FREG_FTN(WT0, fs);
4895
        GEN_LOAD_FREG_FTN(WTH0, fs);
4896
        GEN_LOAD_FREG_FTN(WT1, ft);
4897
        GEN_LOAD_FREG_FTN(WTH1, ft);
4898
        gen_op_float_mul_ps();
4899
        GEN_STORE_FTN_FREG(fd, WT2);
4900
        GEN_STORE_FTN_FREG(fd, WTH2);
4901
        opn = "mul.ps";
4902
        break;
4903
    case FOP(5, 22):
4904
        CHECK_FR(ctx, fs | fd);
4905
        GEN_LOAD_FREG_FTN(WT0, fs);
4906
        GEN_LOAD_FREG_FTN(WTH0, fs);
4907
        gen_op_float_abs_ps();
4908
        GEN_STORE_FTN_FREG(fd, WT2);
4909
        GEN_STORE_FTN_FREG(fd, WTH2);
4910
        opn = "abs.ps";
4911
        break;
4912
    case FOP(6, 22):
4913
        CHECK_FR(ctx, fs | fd);
4914
        GEN_LOAD_FREG_FTN(WT0, fs);
4915
        GEN_LOAD_FREG_FTN(WTH0, fs);
4916
        gen_op_float_mov_ps();
4917
        GEN_STORE_FTN_FREG(fd, WT2);
4918
        GEN_STORE_FTN_FREG(fd, WTH2);
4919
        opn = "mov.ps";
4920
        break;
4921
    case FOP(7, 22):
4922
        CHECK_FR(ctx, fs | fd);
4923
        GEN_LOAD_FREG_FTN(WT0, fs);
4924
        GEN_LOAD_FREG_FTN(WTH0, fs);
4925
        gen_op_float_chs_ps();
4926
        GEN_STORE_FTN_FREG(fd, WT2);
4927
        GEN_STORE_FTN_FREG(fd, WTH2);
4928
        opn = "neg.ps";
4929
        break;
4930
    case FOP(17, 22):
4931
        GEN_LOAD_REG_TN(T0, ft);
4932
        GEN_LOAD_FREG_FTN(WT0, fs);
4933
        GEN_LOAD_FREG_FTN(WTH0, fs);
4934
        GEN_LOAD_FREG_FTN(WT2, fd);
4935
        GEN_LOAD_FREG_FTN(WTH2, fd);
4936
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
4937
        GEN_STORE_FTN_FREG(fd, WT2);
4938
        GEN_STORE_FTN_FREG(fd, WTH2);
4939
        opn = "movcf.ps";
4940
        break;
4941
    case FOP(18, 22):
4942
        GEN_LOAD_REG_TN(T0, ft);
4943
        GEN_LOAD_FREG_FTN(WT0, fs);
4944
        GEN_LOAD_FREG_FTN(WTH0, fs);
4945
        GEN_LOAD_FREG_FTN(WT2, fd);
4946
        GEN_LOAD_FREG_FTN(WTH2, fd);
4947
        gen_op_float_movz_ps();
4948
        GEN_STORE_FTN_FREG(fd, WT2);
4949
        GEN_STORE_FTN_FREG(fd, WTH2);
4950
        opn = "movz.ps";
4951
        break;
4952
    case FOP(19, 22):
4953
        GEN_LOAD_REG_TN(T0, ft);
4954
        GEN_LOAD_FREG_FTN(WT0, fs);
4955
        GEN_LOAD_FREG_FTN(WTH0, fs);
4956
        GEN_LOAD_FREG_FTN(WT2, fd);
4957
        GEN_LOAD_FREG_FTN(WTH2, fd);
4958
        gen_op_float_movn_ps();
4959
        GEN_STORE_FTN_FREG(fd, WT2);
4960
        GEN_STORE_FTN_FREG(fd, WTH2);
4961
        opn = "movn.ps";
4962
        break;
4963
    case FOP(32, 22):
4964
        CHECK_FR(ctx, fs);
4965
        GEN_LOAD_FREG_FTN(WTH0, fs);
4966
        gen_op_float_cvts_pu();
4967
        GEN_STORE_FTN_FREG(fd, WT2);
4968
        opn = "cvt.s.pu";
4969
        break;
4970
    case FOP(36, 22):
4971
        CHECK_FR(ctx, fs | fd);
4972
        GEN_LOAD_FREG_FTN(WT0, fs);
4973
        GEN_LOAD_FREG_FTN(WTH0, fs);
4974
        gen_op_float_cvtpw_ps();
4975
        GEN_STORE_FTN_FREG(fd, WT2);
4976
        GEN_STORE_FTN_FREG(fd, WTH2);
4977
        opn = "cvt.pw.ps";
4978
        break;
4979
    case FOP(40, 22):
4980
        CHECK_FR(ctx, fs);
4981
        GEN_LOAD_FREG_FTN(WT0, fs);
4982
        gen_op_float_cvts_pl();
4983
        GEN_STORE_FTN_FREG(fd, WT2);
4984
        opn = "cvt.s.pl";
4985
        break;
4986
    case FOP(44, 22):
4987
        CHECK_FR(ctx, fs | ft | fd);
4988
        GEN_LOAD_FREG_FTN(WT0, fs);
4989
        GEN_LOAD_FREG_FTN(WT1, ft);
4990
        gen_op_float_pll_ps();
4991
        GEN_STORE_FTN_FREG(fd, DT2);
4992
        opn = "pll.ps";
4993
        break;
4994
    case FOP(45, 22):
4995
        CHECK_FR(ctx, fs | ft | fd);
4996
        GEN_LOAD_FREG_FTN(WT0, fs);
4997
        GEN_LOAD_FREG_FTN(WTH1, ft);
4998
        gen_op_float_plu_ps();
4999
        GEN_STORE_FTN_FREG(fd, DT2);
5000
        opn = "plu.ps";
5001
        break;
5002
    case FOP(46, 22):
5003
        CHECK_FR(ctx, fs | ft | fd);
5004
        GEN_LOAD_FREG_FTN(WTH0, fs);
5005
        GEN_LOAD_FREG_FTN(WT1, ft);
5006
        gen_op_float_pul_ps();
5007
        GEN_STORE_FTN_FREG(fd, DT2);
5008
        opn = "pul.ps";
5009
        break;
5010
    case FOP(47, 22):
5011
        CHECK_FR(ctx, fs | ft | fd);
5012
        GEN_LOAD_FREG_FTN(WTH0, fs);
5013
        GEN_LOAD_FREG_FTN(WTH1, ft);
5014
        gen_op_float_puu_ps();
5015
        GEN_STORE_FTN_FREG(fd, DT2);
5016
        opn = "puu.ps";
5017
        break;
5018
    case FOP(48, 22):
5019
    case FOP(49, 22):
5020
    case FOP(50, 22):
5021
    case FOP(51, 22):
5022
    case FOP(52, 22):
5023
    case FOP(53, 22):
5024
    case FOP(54, 22):
5025
    case FOP(55, 22):
5026
    case FOP(56, 22):
5027
    case FOP(57, 22):
5028
    case FOP(58, 22):
5029
    case FOP(59, 22):
5030
    case FOP(60, 22):
5031
    case FOP(61, 22):
5032
    case FOP(62, 22):
5033
    case FOP(63, 22):
5034
        CHECK_FR(ctx, fs | ft);
5035
        GEN_LOAD_FREG_FTN(WT0, fs);
5036
        GEN_LOAD_FREG_FTN(WTH0, fs);
5037
        GEN_LOAD_FREG_FTN(WT1, ft);
5038
        GEN_LOAD_FREG_FTN(WTH1, ft);
5039
        gen_cmp_ps(func-48, cc);
5040
        opn = condnames[func-48];
5041
        break;
5042
    default:
5043
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5044
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
5045
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
5046
                    ((ctx->opcode >> 16) & 0x1F));
5047
        }
5048
        generate_exception (ctx, EXCP_RI);
5049
        return;
5050
    }
5051
    if (binary)
5052
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5053
    else
5054
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5055
}
5056

    
5057
/* Coprocessor 3 (FPU) */
5058
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5059
                           int base, int index)
5060
{
5061
    const char *opn = "unk";
5062

    
5063
    GEN_LOAD_REG_TN(T0, base);
5064
    GEN_LOAD_REG_TN(T1, index);
5065
    /* Don't do NOP if destination is zero: we must perform the actual
5066
     * memory access
5067
     */
5068
    switch (opc) {
5069
    case OPC_LWXC1:
5070
        op_ldst(lwxc1);
5071
        GEN_STORE_FTN_FREG(fd, WT0);
5072
        opn = "lwxc1";
5073
        break;
5074
    case OPC_LDXC1:
5075
        op_ldst(ldxc1);
5076
        GEN_STORE_FTN_FREG(fd, DT0);
5077
        opn = "ldxc1";
5078
        break;
5079
    case OPC_LUXC1:
5080
        op_ldst(luxc1);
5081
        GEN_STORE_FTN_FREG(fd, DT0);
5082
        opn = "luxc1";
5083
        break;
5084
    case OPC_SWXC1:
5085
        GEN_LOAD_FREG_FTN(WT0, fd);
5086
        op_ldst(swxc1);
5087
        opn = "swxc1";
5088
        break;
5089
    case OPC_SDXC1:
5090
        GEN_LOAD_FREG_FTN(DT0, fd);
5091
        op_ldst(sdxc1);
5092
        opn = "sdxc1";
5093
        break;
5094
    case OPC_SUXC1:
5095
        GEN_LOAD_FREG_FTN(DT0, fd);
5096
        op_ldst(suxc1);
5097
        opn = "suxc1";
5098
        break;
5099
    default:
5100
        MIPS_INVAL("extended float load/store");
5101
        generate_exception(ctx, EXCP_RI);
5102
        return;
5103
    }
5104
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
5105
}
5106

    
5107
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5108
                            int fr, int fs, int ft)
5109
{
5110
    const char *opn = "unk";
5111

    
5112
    /* All of those work only on 64bit FPUs. */
5113
    CHECK_FR(ctx, fd | fr | fs | ft);
5114
    switch (opc) {
5115
    case OPC_ALNV_PS:
5116
        GEN_LOAD_REG_TN(T0, fr);
5117
        GEN_LOAD_FREG_FTN(DT0, fs);
5118
        GEN_LOAD_FREG_FTN(DT1, ft);
5119
        gen_op_float_alnv_ps();
5120
        GEN_STORE_FTN_FREG(fd, DT2);
5121
        opn = "alnv.ps";
5122
        break;
5123
    case OPC_MADD_S:
5124
        GEN_LOAD_FREG_FTN(WT0, fs);
5125
        GEN_LOAD_FREG_FTN(WT1, ft);
5126
        GEN_LOAD_FREG_FTN(WT2, fr);
5127
        gen_op_float_muladd_s();
5128
        GEN_STORE_FTN_FREG(fd, WT2);
5129
        opn = "madd.s";
5130
        break;
5131
    case OPC_MADD_D:
5132
        generate_exception (ctx, EXCP_RI);
5133
        opn = "madd.d";
5134
        break;
5135
    case OPC_MADD_PS:
5136
        generate_exception (ctx, EXCP_RI);
5137
        opn = "madd.ps";
5138
        break;
5139
    case OPC_MSUB_S:
5140
        generate_exception (ctx, EXCP_RI);
5141
        opn = "msub.s";
5142
        break;
5143
    case OPC_MSUB_D:
5144
        generate_exception (ctx, EXCP_RI);
5145
        opn = "msub.d";
5146
        break;
5147
    case OPC_MSUB_PS:
5148
        generate_exception (ctx, EXCP_RI);
5149
        opn = "msub.ps";
5150
        break;
5151
    case OPC_NMADD_S:
5152
        generate_exception (ctx, EXCP_RI);
5153
        opn = "nmadd.s";
5154
        break;
5155
    case OPC_NMADD_D:
5156
        generate_exception (ctx, EXCP_RI);
5157
        opn = "nmadd.d";
5158
        break;
5159
    case OPC_NMADD_PS:
5160
        generate_exception (ctx, EXCP_RI);
5161
        opn = "nmadd.ps";
5162
        break;
5163
    case OPC_NMSUB_S:
5164
        generate_exception (ctx, EXCP_RI);
5165
        opn = "nmsub.s";
5166
        break;
5167
    case OPC_NMSUB_D:
5168
        generate_exception (ctx, EXCP_RI);
5169
        opn = "nmsub.d";
5170
        break;
5171
    case OPC_NMSUB_PS:
5172
        generate_exception (ctx, EXCP_RI);
5173
        opn = "nmsub.ps";
5174
        break;
5175
    default:    
5176
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5177
            fprintf(logfile, "Invalid extended FP arith function: %08x %03x %03x\n",
5178
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F);
5179
        }
5180
        generate_exception (ctx, EXCP_RI);
5181
        return;
5182
    }
5183
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5184
               fregnames[fs], fregnames[ft]);
5185
}
5186

    
5187
/* ISA extensions (ASEs) */
5188
/* MIPS16 extension to MIPS32 */
5189
/* SmartMIPS extension to MIPS32 */
5190

    
5191
#ifdef TARGET_MIPS64
5192

    
5193
/* MDMX extension to MIPS64 */
5194
/* MIPS-3D extension to MIPS64 */
5195

    
5196
#endif
5197

    
5198
static void decode_opc (CPUState *env, DisasContext *ctx)
5199
{
5200
    int32_t offset;
5201
    int rs, rt, rd, sa;
5202
    uint32_t op, op1, op2;
5203
    int16_t imm;
5204

    
5205
    /* make sure instructions are on a word boundary */
5206
    if (ctx->pc & 0x3) {
5207
        env->CP0_BadVAddr = ctx->pc;
5208
        generate_exception(ctx, EXCP_AdEL);
5209
        return;
5210
    }
5211

    
5212
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5213
        int l1;
5214
        /* Handle blikely not taken case */
5215
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5216
        l1 = gen_new_label();
5217
        gen_op_jnz_T2(l1);
5218
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5219
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5220
        gen_set_label(l1);
5221
    }
5222
    op = MASK_OP_MAJOR(ctx->opcode);
5223
    rs = (ctx->opcode >> 21) & 0x1f;
5224
    rt = (ctx->opcode >> 16) & 0x1f;
5225
    rd = (ctx->opcode >> 11) & 0x1f;
5226
    sa = (ctx->opcode >> 6) & 0x1f;
5227
    imm = (int16_t)ctx->opcode;
5228
    switch (op) {
5229
    case OPC_SPECIAL:
5230
        op1 = MASK_SPECIAL(ctx->opcode);
5231
        switch (op1) {
5232
        case OPC_SLL:          /* Arithmetic with immediate */
5233
        case OPC_SRL ... OPC_SRA:
5234
            gen_arith_imm(ctx, op1, rd, rt, sa);
5235
            break;
5236
        case OPC_SLLV:         /* Arithmetic */
5237
        case OPC_SRLV ... OPC_SRAV:
5238
        case OPC_MOVZ ... OPC_MOVN:
5239
        case OPC_ADD ... OPC_NOR:
5240
        case OPC_SLT ... OPC_SLTU:
5241
            gen_arith(ctx, op1, rd, rs, rt);
5242
            break;
5243
        case OPC_MULT ... OPC_DIVU:
5244
            gen_muldiv(ctx, op1, rs, rt);
5245
            break;
5246
        case OPC_JR ... OPC_JALR:
5247
            gen_compute_branch(ctx, op1, rs, rd, sa);
5248
            return;
5249
        case OPC_TGE ... OPC_TEQ: /* Traps */
5250
        case OPC_TNE:
5251
            gen_trap(ctx, op1, rs, rt, -1);
5252
            break;
5253
        case OPC_MFHI:          /* Move from HI/LO */
5254
        case OPC_MFLO:
5255
            gen_HILO(ctx, op1, rd);
5256
            break;
5257
        case OPC_MTHI:
5258
        case OPC_MTLO:          /* Move to HI/LO */
5259
            gen_HILO(ctx, op1, rs);
5260
            break;
5261
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5262
#ifdef MIPS_STRICT_STANDARD
5263
            MIPS_INVAL("PMON / selsl");
5264
            generate_exception(ctx, EXCP_RI);
5265
#else
5266
            gen_op_pmon(sa);
5267
#endif
5268
            break;
5269
        case OPC_SYSCALL:
5270
            generate_exception(ctx, EXCP_SYSCALL);
5271
            break;
5272
        case OPC_BREAK:
5273
            generate_exception(ctx, EXCP_BREAK);
5274
            break;
5275
        case OPC_SPIM:
5276
#ifdef MIPS_STRICT_STANDARD
5277
            MIPS_INVAL("SPIM");
5278
            generate_exception(ctx, EXCP_RI);
5279
#else
5280
           /* Implemented as RI exception for now. */
5281
            MIPS_INVAL("spim (unofficial)");
5282
            generate_exception(ctx, EXCP_RI);
5283
#endif
5284
            break;
5285
        case OPC_SYNC:
5286
            /* Treat as a noop. */
5287
            break;
5288

    
5289
        case OPC_MOVCI:
5290
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5291
                save_cpu_state(ctx, 1);
5292
                gen_op_cp1_enabled();
5293
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5294
                          (ctx->opcode >> 16) & 1);
5295
            } else {
5296
                generate_exception_err(ctx, EXCP_CpU, 1);
5297
            }
5298
            break;
5299

    
5300
#ifdef TARGET_MIPS64
5301
       /* MIPS64 specific opcodes */
5302
        case OPC_DSLL:
5303
        case OPC_DSRL ... OPC_DSRA:
5304
        case OPC_DSLL32:
5305
        case OPC_DSRL32 ... OPC_DSRA32:
5306
            gen_arith_imm(ctx, op1, rd, rt, sa);
5307
            break;
5308
        case OPC_DSLLV:
5309
        case OPC_DSRLV ... OPC_DSRAV:
5310
        case OPC_DADD ... OPC_DSUBU:
5311
            gen_arith(ctx, op1, rd, rs, rt);
5312
            break;
5313
        case OPC_DMULT ... OPC_DDIVU:
5314
            gen_muldiv(ctx, op1, rs, rt);
5315
            break;
5316
#endif
5317
        default:            /* Invalid */
5318
            MIPS_INVAL("special");
5319
            generate_exception(ctx, EXCP_RI);
5320
            break;
5321
        }
5322
        break;
5323
    case OPC_SPECIAL2:
5324
        op1 = MASK_SPECIAL2(ctx->opcode);
5325
        switch (op1) {
5326
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5327
        case OPC_MSUB ... OPC_MSUBU:
5328
            gen_muldiv(ctx, op1, rs, rt);
5329
            break;
5330
        case OPC_MUL:
5331
            gen_arith(ctx, op1, rd, rs, rt);
5332
            break;
5333
        case OPC_CLZ ... OPC_CLO:
5334
            gen_cl(ctx, op1, rd, rs);
5335
            break;
5336
        case OPC_SDBBP:
5337
            /* XXX: not clear which exception should be raised
5338
             *      when in debug mode...
5339
             */
5340
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5341
                generate_exception(ctx, EXCP_DBp);
5342
            } else {
5343
                generate_exception(ctx, EXCP_DBp);
5344
            }
5345
            /* Treat as a noop */
5346
            break;
5347
#ifdef TARGET_MIPS64
5348
        case OPC_DCLZ ... OPC_DCLO:
5349
            gen_cl(ctx, op1, rd, rs);
5350
            break;
5351
#endif
5352
        default:            /* Invalid */
5353
            MIPS_INVAL("special2");
5354
            generate_exception(ctx, EXCP_RI);
5355
            break;
5356
        }
5357
        break;
5358
    case OPC_SPECIAL3:
5359
         op1 = MASK_SPECIAL3(ctx->opcode);
5360
         switch (op1) {
5361
         case OPC_EXT:
5362
         case OPC_INS:
5363
             gen_bitops(ctx, op1, rt, rs, sa, rd);
5364
             break;
5365
         case OPC_BSHFL:
5366
             op2 = MASK_BSHFL(ctx->opcode);
5367
             switch (op2) {
5368
             case OPC_WSBH:
5369
                 GEN_LOAD_REG_TN(T1, rt);
5370
                 gen_op_wsbh();
5371
                 break;
5372
             case OPC_SEB:
5373
                 GEN_LOAD_REG_TN(T1, rt);
5374
                 gen_op_seb();
5375
                 break;
5376
             case OPC_SEH:
5377
                 GEN_LOAD_REG_TN(T1, rt);
5378
                 gen_op_seh();
5379
                 break;
5380
             default:            /* Invalid */
5381
                 MIPS_INVAL("bshfl");
5382
                 generate_exception(ctx, EXCP_RI);
5383
                 break;
5384
            }
5385
            GEN_STORE_TN_REG(rd, T0);
5386
            break;
5387
        case OPC_RDHWR:
5388
            switch (rd) {
5389
            case 0:
5390
                save_cpu_state(ctx, 1);
5391
                gen_op_rdhwr_cpunum();
5392
                break;
5393
            case 1:
5394
                save_cpu_state(ctx, 1);
5395
                gen_op_rdhwr_synci_step();
5396
                break;
5397
            case 2:
5398
                save_cpu_state(ctx, 1);
5399
                gen_op_rdhwr_cc();
5400
                break;
5401
            case 3:
5402
                save_cpu_state(ctx, 1);
5403
                gen_op_rdhwr_ccres();
5404
                break;
5405
            case 29:
5406
#if defined (CONFIG_USER_ONLY)
5407
                gen_op_tls_value ();
5408
                break;
5409
#endif
5410
            default:            /* Invalid */
5411
                MIPS_INVAL("rdhwr");
5412
                generate_exception(ctx, EXCP_RI);
5413
                break;
5414
            }
5415
            GEN_STORE_TN_REG(rt, T0);
5416
            break;
5417
#ifdef TARGET_MIPS64
5418
        case OPC_DEXTM ... OPC_DEXT:
5419
        case OPC_DINSM ... OPC_DINS:
5420
            gen_bitops(ctx, op1, rt, rs, sa, rd);
5421
            break;
5422
        case OPC_DBSHFL:
5423
            op2 = MASK_DBSHFL(ctx->opcode);
5424
            switch (op2) {
5425
            case OPC_DSBH:
5426
                GEN_LOAD_REG_TN(T1, rt);
5427
                gen_op_dsbh();
5428
                break;
5429
            case OPC_DSHD:
5430
                GEN_LOAD_REG_TN(T1, rt);
5431
                gen_op_dshd();
5432
                break;
5433
            default:            /* Invalid */
5434
                MIPS_INVAL("dbshfl");
5435
                generate_exception(ctx, EXCP_RI);
5436
                break;
5437
            }
5438
            GEN_STORE_TN_REG(rd, T0);
5439
#endif
5440
        default:            /* Invalid */
5441
            MIPS_INVAL("special3");
5442
            generate_exception(ctx, EXCP_RI);
5443
            break;
5444
        }
5445
        break;
5446
    case OPC_REGIMM:
5447
        op1 = MASK_REGIMM(ctx->opcode);
5448
        switch (op1) {
5449
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5450
        case OPC_BLTZAL ... OPC_BGEZALL:
5451
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
5452
            return;
5453
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5454
        case OPC_TNEI:
5455
            gen_trap(ctx, op1, rs, -1, imm);
5456
            break;
5457
        case OPC_SYNCI:
5458
            /* treat as noop */
5459
            break;
5460
        default:            /* Invalid */
5461
            MIPS_INVAL("REGIMM");
5462
            generate_exception(ctx, EXCP_RI);
5463
            break;
5464
        }
5465
        break;
5466
    case OPC_CP0:
5467
        save_cpu_state(ctx, 1);
5468
        gen_op_cp0_enabled();
5469
        op1 = MASK_CP0(ctx->opcode);
5470
        switch (op1) {
5471
        case OPC_MFC0:
5472
        case OPC_MTC0:
5473
#ifdef TARGET_MIPS64
5474
        case OPC_DMFC0:
5475
        case OPC_DMTC0:
5476
#endif
5477
            gen_cp0(ctx, op1, rt, rd);
5478
            break;
5479
        case OPC_C0_FIRST ... OPC_C0_LAST:
5480
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
5481
            break;
5482
        case OPC_MFMC0:
5483
            op2 = MASK_MFMC0(ctx->opcode);
5484
            switch (op2) {
5485
            case OPC_DI:
5486
                gen_op_di();
5487
                /* Stop translation as we may have switched the execution mode */
5488
                ctx->bstate = BS_STOP;
5489
                break;
5490
            case OPC_EI:
5491
                gen_op_ei();
5492
                /* Stop translation as we may have switched the execution mode */
5493
                ctx->bstate = BS_STOP;
5494
                break;
5495
            default:            /* Invalid */
5496
                MIPS_INVAL("MFMC0");
5497
                generate_exception(ctx, EXCP_RI);
5498
                break;
5499
            }
5500
            GEN_STORE_TN_REG(rt, T0);
5501
            break;
5502
        case OPC_RDPGPR:
5503
        case OPC_WRPGPR:
5504
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5505
                /* Shadow registers not implemented. */
5506
                GEN_LOAD_REG_TN(T0, rt);
5507
                GEN_STORE_TN_REG(rd, T0);
5508
            } else
5509
                generate_exception(ctx, EXCP_RI);
5510
            break;
5511
        default:
5512
            generate_exception(ctx, EXCP_RI);
5513
            break;
5514
        }
5515
        break;
5516
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5517
         gen_arith_imm(ctx, op, rt, rs, imm);
5518
         break;
5519
    case OPC_J ... OPC_JAL: /* Jump */
5520
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5521
         gen_compute_branch(ctx, op, rs, rt, offset);
5522
         return;
5523
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
5524
    case OPC_BEQL ... OPC_BGTZL:
5525
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
5526
         return;
5527
    case OPC_LB ... OPC_LWR: /* Load and stores */
5528
    case OPC_SB ... OPC_SW:
5529
    case OPC_SWR:
5530
    case OPC_LL:
5531
    case OPC_SC:
5532
         gen_ldst(ctx, op, rt, rs, imm);
5533
         break;
5534
    case OPC_CACHE:
5535
         /* Treat as a noop */
5536
         break;
5537
    case OPC_PREF:
5538
        /* Treat as a noop */
5539
        break;
5540

    
5541
    /* Floating point.  */
5542
    case OPC_LWC1:
5543
    case OPC_LDC1:
5544
    case OPC_SWC1:
5545
    case OPC_SDC1:
5546
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5547
            save_cpu_state(ctx, 1);
5548
            gen_op_cp1_enabled();
5549
            gen_flt_ldst(ctx, op, rt, rs, imm);
5550
        } else {
5551
            generate_exception_err(ctx, EXCP_CpU, 1);
5552
        }
5553
        break;
5554

    
5555
    case OPC_CP1:
5556
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5557
            save_cpu_state(ctx, 1);
5558
            gen_op_cp1_enabled();
5559
            op1 = MASK_CP1(ctx->opcode);
5560
            switch (op1) {
5561
            case OPC_MFC1:
5562
            case OPC_CFC1:
5563
            case OPC_MTC1:
5564
            case OPC_CTC1:
5565
#ifdef TARGET_MIPS64
5566
            case OPC_DMFC1:
5567
            case OPC_DMTC1:
5568
#endif
5569
            case OPC_MFHC1:
5570
            case OPC_MTHC1:
5571
                gen_cp1(ctx, op1, rt, rd);
5572
                break;
5573
            case OPC_BC1:
5574
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5575
                                    (rt >> 2) & 0x7, imm << 2);
5576
                return;
5577
            case OPC_S_FMT:
5578
            case OPC_D_FMT:
5579
            case OPC_W_FMT:
5580
            case OPC_L_FMT:
5581
            case OPC_PS_FMT:
5582
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5583
                           (imm >> 8) & 0x7);
5584
                break;
5585
            default:
5586
                generate_exception (ctx, EXCP_RI);
5587
                break;
5588
            }
5589
        } else {
5590
            generate_exception_err(ctx, EXCP_CpU, 1);
5591
        }
5592
        break;
5593

    
5594
    /* COP2.  */
5595
    case OPC_LWC2:
5596
    case OPC_LDC2:
5597
    case OPC_SWC2:
5598
    case OPC_SDC2:
5599
    case OPC_CP2:
5600
        /* COP2: Not implemented. */
5601
        generate_exception_err(ctx, EXCP_CpU, 2);
5602
        break;
5603

    
5604
    case OPC_CP3:
5605
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5606
            save_cpu_state(ctx, 1);
5607
            gen_op_cp1_enabled();
5608
            op1 = MASK_CP3(ctx->opcode);
5609
            switch (op1) {
5610
            case OPC_LWXC1:
5611
            case OPC_LDXC1:
5612
            case OPC_LUXC1:
5613
            case OPC_SWXC1:
5614
            case OPC_SDXC1:
5615
            case OPC_SUXC1:
5616
                gen_flt3_ldst(ctx, op1, sa, rs, rt);
5617
                break;
5618
            case OPC_PREFX:
5619
                /* treat as noop */
5620
                break;
5621
            case OPC_ALNV_PS:
5622
            case OPC_MADD_S:
5623
            case OPC_MADD_D:
5624
            case OPC_MADD_PS:
5625
            case OPC_MSUB_S:
5626
            case OPC_MSUB_D:
5627
            case OPC_MSUB_PS:
5628
            case OPC_NMADD_S:
5629
            case OPC_NMADD_D:
5630
            case OPC_NMADD_PS:
5631
            case OPC_NMSUB_S:
5632
            case OPC_NMSUB_D:
5633
            case OPC_NMSUB_PS:
5634
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5635
                break;
5636
            default:
5637
                generate_exception (ctx, EXCP_RI);
5638
                break;
5639
            }
5640
        } else {
5641
            generate_exception_err(ctx, EXCP_CpU, 1);
5642
        }
5643
        break;
5644

    
5645
#ifdef TARGET_MIPS64
5646
    /* MIPS64 opcodes */
5647
    case OPC_LWU:
5648
    case OPC_LDL ... OPC_LDR:
5649
    case OPC_SDL ... OPC_SDR:
5650
    case OPC_LLD:
5651
    case OPC_LD:
5652
    case OPC_SCD:
5653
    case OPC_SD:
5654
        gen_ldst(ctx, op, rt, rs, imm);
5655
        break;
5656
    case OPC_DADDI ... OPC_DADDIU:
5657
        gen_arith_imm(ctx, op, rt, rs, imm);
5658
        break;
5659
#endif
5660
#ifdef MIPS_HAS_MIPS16
5661
    case OPC_JALX:
5662
        /* MIPS16: Not implemented. */
5663
#endif
5664
#ifdef MIPS_HAS_MDMX
5665
    case OPC_MDMX:
5666
        /* MDMX: Not implemented. */
5667
#endif
5668
    default:            /* Invalid */
5669
        MIPS_INVAL("");
5670
        generate_exception(ctx, EXCP_RI);
5671
        break;
5672
    }
5673
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5674
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5675
        /* Branches completion */
5676
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5677
        ctx->bstate = BS_BRANCH;
5678
        save_cpu_state(ctx, 0);
5679
        switch (hflags) {
5680
        case MIPS_HFLAG_B:
5681
            /* unconditional branch */
5682
            MIPS_DEBUG("unconditional branch");
5683
            gen_goto_tb(ctx, 0, ctx->btarget);
5684
            break;
5685
        case MIPS_HFLAG_BL:
5686
            /* blikely taken case */
5687
            MIPS_DEBUG("blikely branch taken");
5688
            gen_goto_tb(ctx, 0, ctx->btarget);
5689
            break;
5690
        case MIPS_HFLAG_BC:
5691
            /* Conditional branch */
5692
            MIPS_DEBUG("conditional branch");
5693
            {
5694
              int l1;
5695
              l1 = gen_new_label();
5696
              gen_op_jnz_T2(l1);
5697
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5698
              gen_set_label(l1);
5699
              gen_goto_tb(ctx, 0, ctx->btarget);
5700
            }
5701
            break;
5702
        case MIPS_HFLAG_BR:
5703
            /* unconditional branch to register */
5704
            MIPS_DEBUG("branch to register");
5705
            gen_op_breg();
5706
            gen_op_reset_T0();
5707
            gen_op_exit_tb();
5708
            break;
5709
        default:
5710
            MIPS_DEBUG("unknown branch");
5711
            break;
5712
        }
5713
    }
5714
}
5715

    
5716
static inline int
5717
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5718
                                int search_pc)
5719
{
5720
    DisasContext ctx, *ctxp = &ctx;
5721
    target_ulong pc_start;
5722
    uint16_t *gen_opc_end;
5723
    int j, lj = -1;
5724

    
5725
    if (search_pc && loglevel)
5726
        fprintf (logfile, "search pc %d\n", search_pc);
5727

    
5728
    pc_start = tb->pc;
5729
    gen_opc_ptr = gen_opc_buf;
5730
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5731
    gen_opparam_ptr = gen_opparam_buf;
5732
    nb_gen_labels = 0;
5733
    ctx.pc = pc_start;
5734
    ctx.saved_pc = -1;
5735
    ctx.tb = tb;
5736
    ctx.bstate = BS_NONE;
5737
    /* Restore delay slot state from the tb context.  */
5738
    ctx.hflags = tb->flags;
5739
    ctx.saved_hflags = ctx.hflags;
5740
    switch (ctx.hflags & MIPS_HFLAG_BMASK) {
5741
    case MIPS_HFLAG_BR:
5742
        gen_op_restore_breg_target();
5743
        break;
5744
    case MIPS_HFLAG_B:
5745
        ctx.btarget = env->btarget;
5746
        break;
5747
    case MIPS_HFLAG_BC:
5748
    case MIPS_HFLAG_BL:
5749
        ctx.btarget = env->btarget;
5750
        gen_op_restore_bcond();
5751
        break;
5752
    }
5753
#if defined(CONFIG_USER_ONLY)
5754
    ctx.mem_idx = 0;
5755
#else
5756
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5757
#endif
5758
    ctx.CP0_Status = env->CP0_Status;
5759
#ifdef DEBUG_DISAS
5760
    if (loglevel & CPU_LOG_TB_CPU) {
5761
        fprintf(logfile, "------------------------------------------------\n");
5762
        /* FIXME: This may print out stale hflags from env... */
5763
        cpu_dump_state(env, logfile, fprintf, 0);
5764
    }
5765
#endif
5766
#if defined MIPS_DEBUG_DISAS
5767
    if (loglevel & CPU_LOG_TB_IN_ASM)
5768
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5769
                tb, ctx.mem_idx, ctx.hflags);
5770
#endif
5771
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5772
        if (env->nb_breakpoints > 0) {
5773
            for(j = 0; j < env->nb_breakpoints; j++) {
5774
                if (env->breakpoints[j] == ctx.pc) {
5775
                    save_cpu_state(ctxp, 1);
5776
                    ctx.bstate = BS_BRANCH;
5777
                    gen_op_debug();
5778
                    goto done_generating;
5779
                }
5780
            }
5781
        }
5782

    
5783
        if (search_pc) {
5784
            j = gen_opc_ptr - gen_opc_buf;
5785
            if (lj < j) {
5786
                lj++;
5787
                while (lj < j)
5788
                    gen_opc_instr_start[lj++] = 0;
5789
            }
5790
            gen_opc_pc[lj] = ctx.pc;
5791
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5792
            gen_opc_instr_start[lj] = 1;
5793
        }
5794
        ctx.opcode = ldl_code(ctx.pc);
5795
        decode_opc(env, &ctx);
5796
        ctx.pc += 4;
5797

    
5798
        if (env->singlestep_enabled)
5799
            break;
5800

    
5801
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5802
            break;
5803

    
5804
#if defined (MIPS_SINGLE_STEP)
5805
        break;
5806
#endif
5807
    }
5808
    if (env->singlestep_enabled) {
5809
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5810
        gen_op_debug();
5811
    } else {
5812
        switch (ctx.bstate) {
5813
        case BS_STOP:
5814
            gen_op_interrupt_restart();
5815
            /* Fall through. */
5816
        case BS_NONE:
5817
            save_cpu_state(ctxp, 0);
5818
            gen_goto_tb(&ctx, 0, ctx.pc);
5819
            break;
5820
        case BS_EXCP:
5821
            gen_op_interrupt_restart();
5822
            gen_op_reset_T0();
5823
            gen_op_exit_tb();
5824
            break;
5825
        case BS_BRANCH:
5826
        default:
5827
            break;
5828
        }
5829
    }
5830
done_generating:
5831
    *gen_opc_ptr = INDEX_op_end;
5832
    if (search_pc) {
5833
        j = gen_opc_ptr - gen_opc_buf;
5834
        lj++;
5835
        while (lj <= j)
5836
            gen_opc_instr_start[lj++] = 0;
5837
        tb->size = 0;
5838
    } else {
5839
        tb->size = ctx.pc - pc_start;
5840
    }
5841
#ifdef DEBUG_DISAS
5842
#if defined MIPS_DEBUG_DISAS
5843
    if (loglevel & CPU_LOG_TB_IN_ASM)
5844
        fprintf(logfile, "\n");
5845
#endif
5846
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5847
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5848
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5849
        fprintf(logfile, "\n");
5850
    }
5851
    if (loglevel & CPU_LOG_TB_OP) {
5852
        fprintf(logfile, "OP:\n");
5853
        dump_ops(gen_opc_buf, gen_opparam_buf);
5854
        fprintf(logfile, "\n");
5855
    }
5856
    if (loglevel & CPU_LOG_TB_CPU) {
5857
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5858
    }
5859
#endif
5860
    
5861
    return 0;
5862
}
5863

    
5864
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5865
{
5866
    return gen_intermediate_code_internal(env, tb, 0);
5867
}
5868

    
5869
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5870
{
5871
    return gen_intermediate_code_internal(env, tb, 1);
5872
}
5873

    
5874
void fpu_dump_state(CPUState *env, FILE *f, 
5875
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5876
                    int flags)
5877
{
5878
    int i;
5879
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5880

    
5881
#define printfpr(fp)                                                        \
5882
    do {                                                                    \
5883
        if (is_fpu64)                                                       \
5884
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5885
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5886
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5887
        else {                                                              \
5888
            fpr_t tmp;                                                      \
5889
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
5890
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
5891
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
5892
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
5893
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
5894
        }                                                                   \
5895
    } while(0)
5896

    
5897

    
5898
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
5899
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
5900
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5901
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5902
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5903
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
5904
        fpu_fprintf(f, "%3s: ", fregnames[i]);
5905
        printfpr(&env->fpr[i]);
5906
    }
5907

    
5908
#undef printfpr
5909
}
5910

    
5911
void dump_fpu (CPUState *env)
5912
{
5913
    if (loglevel) { 
5914
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5915
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5916
       fpu_dump_state(env, logfile, fprintf, 0);
5917
    }
5918
}
5919

    
5920
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5921
/* Debug help: The architecture requires 32bit code to maintain proper
5922
   sign-extened values on 64bit machines.  */
5923

    
5924
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5925

    
5926
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5927
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5928
                     int flags)
5929
{
5930
    int i;
5931

    
5932
    if (!SIGN_EXT_P(env->PC))
5933
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5934
    if (!SIGN_EXT_P(env->HI))
5935
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5936
    if (!SIGN_EXT_P(env->LO))
5937
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5938
    if (!SIGN_EXT_P(env->btarget))
5939
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5940

    
5941
    for (i = 0; i < 32; i++) {
5942
        if (!SIGN_EXT_P(env->gpr[i]))
5943
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5944
    }
5945

    
5946
    if (!SIGN_EXT_P(env->CP0_EPC))
5947
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5948
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5949
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5950
}
5951
#endif
5952

    
5953
void cpu_dump_state (CPUState *env, FILE *f, 
5954
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5955
                     int flags)
5956
{
5957
    uint32_t c0_status;
5958
    int i;
5959
    
5960
    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",
5961
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5962
    for (i = 0; i < 32; i++) {
5963
        if ((i & 3) == 0)
5964
            cpu_fprintf(f, "GPR%02d:", i);
5965
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5966
        if ((i & 3) == 3)
5967
            cpu_fprintf(f, "\n");
5968
    }
5969

    
5970
    c0_status = env->CP0_Status;
5971

    
5972
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5973
                c0_status, env->CP0_Cause, env->CP0_EPC);
5974
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5975
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5976
    if (c0_status & (1 << CP0St_CU1))
5977
        fpu_dump_state(env, f, cpu_fprintf, flags);
5978
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5979
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5980
#endif
5981
}
5982

    
5983
CPUMIPSState *cpu_mips_init (void)
5984
{
5985
    CPUMIPSState *env;
5986

    
5987
    env = qemu_mallocz(sizeof(CPUMIPSState));
5988
    if (!env)
5989
        return NULL;
5990
    cpu_exec_init(env);
5991
    cpu_reset(env);
5992
    return env;
5993
}
5994

    
5995
void cpu_reset (CPUMIPSState *env)
5996
{
5997
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5998

    
5999
    tlb_flush(env, 1);
6000

    
6001
    /* Minimal init */
6002
#if !defined(CONFIG_USER_ONLY)
6003
    if (env->hflags & MIPS_HFLAG_BMASK) {
6004
        /* If the exception was raised from a delay slot,
6005
         * come back to the jump.  */
6006
        env->CP0_ErrorEPC = env->PC - 4;
6007
        env->hflags &= ~MIPS_HFLAG_BMASK;
6008
    } else {
6009
        env->CP0_ErrorEPC = env->PC;
6010
    }
6011
    env->hflags = 0;
6012
    env->PC = (int32_t)0xBFC00000;
6013
    env->CP0_Wired = 0;
6014
    /* SMP not implemented */
6015
    env->CP0_EBase = 0x80000000;
6016
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6017
    /* vectored interrupts not implemented, timer on int 7,
6018
       no performance counters. */
6019
    env->CP0_IntCtl = 0xe0000000;
6020
    env->CP0_WatchLo = 0;
6021
    env->CP0_WatchHi = 0;
6022
    /* Count register increments in debug mode, EJTAG version 1 */
6023
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6024
#endif
6025
    env->exception_index = EXCP_NONE;
6026
#if defined(CONFIG_USER_ONLY)
6027
    env->hflags |= MIPS_HFLAG_UM;
6028
    env->user_mode_only = 1;
6029
#endif
6030
}
6031

    
6032
#include "translate_init.c"