Statistics
| Branch: | Revision:

root / target-mips / translate.c @ beebb570

History | View | Annotate | Download (160.6 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
        GEN_STORE_TN_REG(rt, T0);
749
        opn = "scd";
750
        break;
751
    case OPC_LDL:
752
        op_ldst(ldl);
753
        GEN_STORE_TN_REG(rt, T0);
754
        opn = "ldl";
755
        break;
756
    case OPC_SDL:
757
        GEN_LOAD_REG_TN(T1, rt);
758
        op_ldst(sdl);
759
        opn = "sdl";
760
        break;
761
    case OPC_LDR:
762
        op_ldst(ldr);
763
        GEN_STORE_TN_REG(rt, T0);
764
        opn = "ldr";
765
        break;
766
    case OPC_SDR:
767
        GEN_LOAD_REG_TN(T1, rt);
768
        op_ldst(sdr);
769
        opn = "sdr";
770
        break;
771
#endif
772
    case OPC_LW:
773
        op_ldst(lw);
774
        GEN_STORE_TN_REG(rt, T0);
775
        opn = "lw";
776
        break;
777
    case OPC_LWU:
778
        op_ldst(lwu);
779
        GEN_STORE_TN_REG(rt, T0);
780
        opn = "lwu";
781
        break;
782
    case OPC_SW:
783
        GEN_LOAD_REG_TN(T1, rt);
784
        op_ldst(sw);
785
        opn = "sw";
786
        break;
787
    case OPC_LH:
788
        op_ldst(lh);
789
        GEN_STORE_TN_REG(rt, T0);
790
        opn = "lh";
791
        break;
792
    case OPC_SH:
793
        GEN_LOAD_REG_TN(T1, rt);
794
        op_ldst(sh);
795
        opn = "sh";
796
        break;
797
    case OPC_LHU:
798
        op_ldst(lhu);
799
        GEN_STORE_TN_REG(rt, T0);
800
        opn = "lhu";
801
        break;
802
    case OPC_LB:
803
        op_ldst(lb);
804
        GEN_STORE_TN_REG(rt, T0);
805
        opn = "lb";
806
        break;
807
    case OPC_SB:
808
        GEN_LOAD_REG_TN(T1, rt);
809
        op_ldst(sb);
810
        opn = "sb";
811
        break;
812
    case OPC_LBU:
813
        op_ldst(lbu);
814
        GEN_STORE_TN_REG(rt, T0);
815
        opn = "lbu";
816
        break;
817
    case OPC_LWL:
818
        GEN_LOAD_REG_TN(T1, rt);
819
        op_ldst(lwl);
820
        GEN_STORE_TN_REG(rt, T0);
821
        opn = "lwl";
822
        break;
823
    case OPC_SWL:
824
        GEN_LOAD_REG_TN(T1, rt);
825
        op_ldst(swl);
826
        opn = "swr";
827
        break;
828
    case OPC_LWR:
829
        GEN_LOAD_REG_TN(T1, rt);
830
        op_ldst(lwr);
831
        GEN_STORE_TN_REG(rt, T0);
832
        opn = "lwr";
833
        break;
834
    case OPC_SWR:
835
        GEN_LOAD_REG_TN(T1, rt);
836
        op_ldst(swr);
837
        opn = "swr";
838
        break;
839
    case OPC_LL:
840
        op_ldst(ll);
841
        GEN_STORE_TN_REG(rt, T0);
842
        opn = "ll";
843
        break;
844
    case OPC_SC:
845
        save_cpu_state(ctx, 1);
846
        GEN_LOAD_REG_TN(T1, rt);
847
        op_ldst(sc);
848
        GEN_STORE_TN_REG(rt, T0);
849
        opn = "sc";
850
        break;
851
    default:
852
        MIPS_INVAL("load/store");
853
        generate_exception(ctx, EXCP_RI);
854
        return;
855
    }
856
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
857
}
858

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4310
    return;
4311
}
4312

    
4313
/* Coprocessor 1 (FPU) */
4314

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5192
#ifdef TARGET_MIPS64
5193

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

    
5197
#endif
5198

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5898

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

    
5909
#undef printfpr
5910
}
5911

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

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

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

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

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

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

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

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

    
5971
    c0_status = env->CP0_Status;
5972

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

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

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

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

    
6000
    tlb_flush(env, 1);
6001

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

    
6033
#include "translate_init.c"