Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 923617a3

History | View | Annotate | Download (160.1 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
#ifdef 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 = "ldst";
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(opn);
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 = "flt_ldst";
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(opn);
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 = "imm arith";
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(opn);
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 = "arith";
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(opn);
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 = "hilo";
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(opn);
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 = "mul/div";
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(opn);
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 = "CLx";
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(opn);
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
#ifdef MIPS_DEBUG_DISAS
1503
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1504
            fprintf(logfile,
1505
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1506
                    ctx->pc);
1507
        }
1508
#endif
1509
        generate_exception(ctx, EXCP_RI);
1510
        return;
1511
    }
1512

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4251
/* CP1 Branches (before delay slot) */
4252
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4253
                                 int32_t cc, int32_t offset)
4254
{
4255
    target_ulong btarget;
4256
    const char *opn = "cp1 cond branch";
4257

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

    
4260
    switch (op) {
4261
    case OPC_BC1F:
4262
        gen_op_bc1f(cc);
4263
        opn = "bc1f";
4264
        goto not_likely;
4265
    case OPC_BC1FL:
4266
        gen_op_bc1f(cc);
4267
        opn = "bc1fl";
4268
        goto likely;
4269
    case OPC_BC1T:
4270
        gen_op_bc1t(cc);
4271
        opn = "bc1t";
4272
        goto not_likely;
4273
    case OPC_BC1TL:
4274
        gen_op_bc1t(cc);
4275
        opn = "bc1tl";
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
        opn = "bc1fany2";
4284
        goto not_likely;
4285
    case OPC_BC1TANY2:
4286
        gen_op_bc1tany2(cc);
4287
        opn = "bc1tany2";
4288
        goto not_likely;
4289
    case OPC_BC1FANY4:
4290
        gen_op_bc1fany4(cc);
4291
        opn = "bc1fany4";
4292
        goto not_likely;
4293
    case OPC_BC1TANY4:
4294
        gen_op_bc1tany4(cc);
4295
        opn = "bc1tany4";
4296
    not_likely:
4297
        ctx->hflags |= MIPS_HFLAG_BC;
4298
        gen_op_set_bcond();
4299
        break;
4300
    default:
4301
        MIPS_INVAL(opn);
4302
        generate_exception (ctx, EXCP_RI);
4303
        return;
4304
    }
4305
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4306
               ctx->hflags, btarget);
4307
    ctx->btarget = btarget;
4308
}
4309

    
4310
/* Coprocessor 1 (FPU) */
4311

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

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

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

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

    
4398
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4399
{
4400
    uint32_t ccbit;
4401

    
4402
    GEN_LOAD_REG_TN(T0, rd);
4403
    GEN_LOAD_REG_TN(T1, rs);
4404
    if (cc)
4405
        ccbit = 1 << (24 + cc);
4406
    else
4407
        ccbit = 1 << 23;
4408
    if (!tf)
4409
        gen_op_movf(ccbit);
4410
    else
4411
        gen_op_movt(ccbit);
4412
    GEN_STORE_TN_REG(rd, T0);
4413
}
4414

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

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

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

    
5048
/* Coprocessor 3 (FPU) */
5049
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5050
                           int base, int index)
5051
{
5052
    const char *opn = "extended float load/store";
5053

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

    
5098
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5099
                            int fr, int fs, int ft)
5100
{
5101
    const char *opn = "flt3_arith";
5102

    
5103
    /* All of those work only on 64bit FPUs. */
5104
    CHECK_FR(ctx, fd | fr | fs | ft);
5105
    switch (opc) {
5106
    case OPC_ALNV_PS:
5107
        GEN_LOAD_REG_TN(T0, fr);
5108
        GEN_LOAD_FREG_FTN(DT0, fs);
5109
        GEN_LOAD_FREG_FTN(DT1, ft);
5110
        gen_op_float_alnv_ps();
5111
        GEN_STORE_FTN_FREG(fd, DT2);
5112
        opn = "alnv.ps";
5113
        break;
5114
    case OPC_MADD_S:
5115
        GEN_LOAD_FREG_FTN(WT0, fs);
5116
        GEN_LOAD_FREG_FTN(WT1, ft);
5117
        GEN_LOAD_FREG_FTN(WT2, fr);
5118
        gen_op_float_muladd_s();
5119
        GEN_STORE_FTN_FREG(fd, WT2);
5120
        opn = "madd.s";
5121
        break;
5122
    case OPC_MADD_D:
5123
        generate_exception (ctx, EXCP_RI);
5124
        opn = "madd.d";
5125
        break;
5126
    case OPC_MADD_PS:
5127
        generate_exception (ctx, EXCP_RI);
5128
        opn = "madd.ps";
5129
        break;
5130
    case OPC_MSUB_S:
5131
        generate_exception (ctx, EXCP_RI);
5132
        opn = "msub.s";
5133
        break;
5134
    case OPC_MSUB_D:
5135
        generate_exception (ctx, EXCP_RI);
5136
        opn = "msub.d";
5137
        break;
5138
    case OPC_MSUB_PS:
5139
        generate_exception (ctx, EXCP_RI);
5140
        opn = "msub.ps";
5141
        break;
5142
    case OPC_NMADD_S:
5143
        generate_exception (ctx, EXCP_RI);
5144
        opn = "nmadd.s";
5145
        break;
5146
    case OPC_NMADD_D:
5147
        generate_exception (ctx, EXCP_RI);
5148
        opn = "nmadd.d";
5149
        break;
5150
    case OPC_NMADD_PS:
5151
        generate_exception (ctx, EXCP_RI);
5152
        opn = "nmadd.ps";
5153
        break;
5154
    case OPC_NMSUB_S:
5155
        generate_exception (ctx, EXCP_RI);
5156
        opn = "nmsub.s";
5157
        break;
5158
    case OPC_NMSUB_D:
5159
        generate_exception (ctx, EXCP_RI);
5160
        opn = "nmsub.d";
5161
        break;
5162
    case OPC_NMSUB_PS:
5163
        generate_exception (ctx, EXCP_RI);
5164
        opn = "nmsub.ps";
5165
        break;
5166
    default:
5167
        MIPS_INVAL(opn);
5168
        generate_exception (ctx, EXCP_RI);
5169
        return;
5170
    }
5171
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5172
               fregnames[fs], fregnames[ft]);
5173
}
5174

    
5175
/* ISA extensions (ASEs) */
5176
/* MIPS16 extension to MIPS32 */
5177
/* SmartMIPS extension to MIPS32 */
5178

    
5179
#ifdef TARGET_MIPS64
5180

    
5181
/* MDMX extension to MIPS64 */
5182
/* MIPS-3D extension to MIPS64 */
5183

    
5184
#endif
5185

    
5186
static void decode_opc (CPUState *env, DisasContext *ctx)
5187
{
5188
    int32_t offset;
5189
    int rs, rt, rd, sa;
5190
    uint32_t op, op1, op2;
5191
    int16_t imm;
5192

    
5193
    /* make sure instructions are on a word boundary */
5194
    if (ctx->pc & 0x3) {
5195
        env->CP0_BadVAddr = ctx->pc;
5196
        generate_exception(ctx, EXCP_AdEL);
5197
        return;
5198
    }
5199

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

    
5277
        case OPC_MOVCI:
5278
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5279
                save_cpu_state(ctx, 1);
5280
                gen_op_cp1_enabled();
5281
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5282
                          (ctx->opcode >> 16) & 1);
5283
            } else {
5284
                generate_exception_err(ctx, EXCP_CpU, 1);
5285
            }
5286
            break;
5287

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

    
5532
    /* Floating point (COP1). */
5533
    case OPC_LWC1:
5534
    case OPC_LDC1:
5535
    case OPC_SWC1:
5536
    case OPC_SDC1:
5537
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5538
            save_cpu_state(ctx, 1);
5539
            gen_op_cp1_enabled();
5540
            gen_flt_ldst(ctx, op, rt, rs, imm);
5541
        } else {
5542
            generate_exception_err(ctx, EXCP_CpU, 1);
5543
        }
5544
        break;
5545

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

    
5586
    /* COP2.  */
5587
    case OPC_LWC2:
5588
    case OPC_LDC2:
5589
    case OPC_SWC2:
5590
    case OPC_SDC2:
5591
    case OPC_CP2:
5592
        /* COP2: Not implemented. */
5593
        generate_exception_err(ctx, EXCP_CpU, 2);
5594
        break;
5595

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

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

    
5709
static inline int
5710
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5711
                                int search_pc)
5712
{
5713
    DisasContext ctx, *ctxp = &ctx;
5714
    target_ulong pc_start;
5715
    uint16_t *gen_opc_end;
5716
    int j, lj = -1;
5717

    
5718
    if (search_pc && loglevel)
5719
        fprintf (logfile, "search pc %d\n", search_pc);
5720

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

    
5776
        if (search_pc) {
5777
            j = gen_opc_ptr - gen_opc_buf;
5778
            if (lj < j) {
5779
                lj++;
5780
                while (lj < j)
5781
                    gen_opc_instr_start[lj++] = 0;
5782
            }
5783
            gen_opc_pc[lj] = ctx.pc;
5784
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5785
            gen_opc_instr_start[lj] = 1;
5786
        }
5787
        ctx.opcode = ldl_code(ctx.pc);
5788
        decode_opc(env, &ctx);
5789
        ctx.pc += 4;
5790

    
5791
        if (env->singlestep_enabled)
5792
            break;
5793

    
5794
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5795
            break;
5796

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

    
5857
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5858
{
5859
    return gen_intermediate_code_internal(env, tb, 0);
5860
}
5861

    
5862
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5863
{
5864
    return gen_intermediate_code_internal(env, tb, 1);
5865
}
5866

    
5867
void fpu_dump_state(CPUState *env, FILE *f, 
5868
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5869
                    int flags)
5870
{
5871
    int i;
5872
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5873

    
5874
#define printfpr(fp)                                                        \
5875
    do {                                                                    \
5876
        if (is_fpu64)                                                       \
5877
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5878
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5879
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5880
        else {                                                              \
5881
            fpr_t tmp;                                                      \
5882
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
5883
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
5884
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
5885
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
5886
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
5887
        }                                                                   \
5888
    } while(0)
5889

    
5890

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

    
5901
#undef printfpr
5902
}
5903

    
5904
void dump_fpu (CPUState *env)
5905
{
5906
    if (loglevel) { 
5907
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5908
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5909
       fpu_dump_state(env, logfile, fprintf, 0);
5910
    }
5911
}
5912

    
5913
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5914
/* Debug help: The architecture requires 32bit code to maintain proper
5915
   sign-extened values on 64bit machines.  */
5916

    
5917
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5918

    
5919
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5920
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5921
                     int flags)
5922
{
5923
    int i;
5924

    
5925
    if (!SIGN_EXT_P(env->PC))
5926
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5927
    if (!SIGN_EXT_P(env->HI))
5928
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5929
    if (!SIGN_EXT_P(env->LO))
5930
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5931
    if (!SIGN_EXT_P(env->btarget))
5932
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5933

    
5934
    for (i = 0; i < 32; i++) {
5935
        if (!SIGN_EXT_P(env->gpr[i]))
5936
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5937
    }
5938

    
5939
    if (!SIGN_EXT_P(env->CP0_EPC))
5940
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5941
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5942
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5943
}
5944
#endif
5945

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

    
5963
    c0_status = env->CP0_Status;
5964

    
5965
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5966
                c0_status, env->CP0_Cause, env->CP0_EPC);
5967
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5968
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5969
    if (c0_status & (1 << CP0St_CU1))
5970
        fpu_dump_state(env, f, cpu_fprintf, flags);
5971
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5972
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5973
#endif
5974
}
5975

    
5976
CPUMIPSState *cpu_mips_init (void)
5977
{
5978
    CPUMIPSState *env;
5979

    
5980
    env = qemu_mallocz(sizeof(CPUMIPSState));
5981
    if (!env)
5982
        return NULL;
5983
    cpu_exec_init(env);
5984
    cpu_reset(env);
5985
    return env;
5986
}
5987

    
5988
void cpu_reset (CPUMIPSState *env)
5989
{
5990
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5991

    
5992
    tlb_flush(env, 1);
5993

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

    
6025
#include "translate_init.c"