Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 93b12ccc

History | View | Annotate | Download (167.9 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 = 0x31 | 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(type, fmt)                                            \
494
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
495
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
496
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
497
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
498
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
499
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
500
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
501
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
502
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
503
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
504
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
505
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
506
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
507
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
508
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
509
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
510
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
511
};                                                                      \
512
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)          \
513
{                                                                       \
514
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
515
}
516

    
517
FOP_CONDS(, d)
518
FOP_CONDS(abs, d)
519
FOP_CONDS(, s)
520
FOP_CONDS(abs, s)
521
FOP_CONDS(, ps)
522
FOP_CONDS(abs, ps)
523

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

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

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

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

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

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

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

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

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

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

    
630
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
631
{
632
    ctx->saved_hflags = ctx->hflags;
633
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
634
    case MIPS_HFLAG_BR:
635
        gen_op_restore_breg_target();
636
        break;
637
    case MIPS_HFLAG_B:
638
        ctx->btarget = env->btarget;
639
        break;
640
    case MIPS_HFLAG_BC:
641
    case MIPS_HFLAG_BL:
642
        ctx->btarget = env->btarget;
643
        gen_op_restore_bcond();
644
        break;
645
    }
646
}
647

    
648
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
649
{
650
#if defined MIPS_DEBUG_DISAS
651
    if (loglevel & CPU_LOG_TB_IN_ASM)
652
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
653
#endif
654
    save_cpu_state(ctx, 1);
655
    if (err == 0)
656
        gen_op_raise_exception(excp);
657
    else
658
        gen_op_raise_exception_err(excp, err);
659
    ctx->bstate = BS_EXCP;
660
}
661

    
662
static inline void generate_exception (DisasContext *ctx, int excp)
663
{
664
    generate_exception_err (ctx, excp, 0);
665
}
666

    
667
#if defined(CONFIG_USER_ONLY)
668
#define op_ldst(name)        gen_op_##name##_raw()
669
#define OP_LD_TABLE(width)
670
#define OP_ST_TABLE(width)
671
#else
672
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
673
#define OP_LD_TABLE(width)                                                    \
674
static GenOpFunc *gen_op_l##width[] = {                                       \
675
    &gen_op_l##width##_user,                                                  \
676
    &gen_op_l##width##_kernel,                                                \
677
}
678
#define OP_ST_TABLE(width)                                                    \
679
static GenOpFunc *gen_op_s##width[] = {                                       \
680
    &gen_op_s##width##_user,                                                  \
681
    &gen_op_s##width##_kernel,                                                \
682
}
683
#endif
684

    
685
#ifdef TARGET_MIPS64
686
OP_LD_TABLE(d);
687
OP_LD_TABLE(dl);
688
OP_LD_TABLE(dr);
689
OP_ST_TABLE(d);
690
OP_ST_TABLE(dl);
691
OP_ST_TABLE(dr);
692
OP_LD_TABLE(ld);
693
OP_ST_TABLE(cd);
694
#endif
695
OP_LD_TABLE(w);
696
OP_LD_TABLE(wu);
697
OP_LD_TABLE(wl);
698
OP_LD_TABLE(wr);
699
OP_ST_TABLE(w);
700
OP_ST_TABLE(wl);
701
OP_ST_TABLE(wr);
702
OP_LD_TABLE(h);
703
OP_LD_TABLE(hu);
704
OP_ST_TABLE(h);
705
OP_LD_TABLE(b);
706
OP_LD_TABLE(bu);
707
OP_ST_TABLE(b);
708
OP_LD_TABLE(l);
709
OP_ST_TABLE(c);
710
OP_LD_TABLE(wc1);
711
OP_ST_TABLE(wc1);
712
OP_LD_TABLE(dc1);
713
OP_ST_TABLE(dc1);
714
OP_LD_TABLE(uxc1);
715
OP_ST_TABLE(uxc1);
716

    
717
/* Load and store */
718
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
719
                      int base, int16_t offset)
720
{
721
    const char *opn = "ldst";
722

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

    
869
/* Load and store */
870
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
871
                      int base, int16_t offset)
872
{
873
    const char *opn = "flt_ldst";
874

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

    
916
/* Arithmetic with immediate operand */
917
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
918
                           int rs, int16_t imm)
919
{
920
    target_ulong uimm;
921
    const char *opn = "imm arith";
922

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

    
1094
/* Arithmetic */
1095
static void gen_arith (DisasContext *ctx, uint32_t opc,
1096
                       int rd, int rs, int rt)
1097
{
1098
    const char *opn = "arith";
1099

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

    
1245
/* Arithmetic on HI/LO registers */
1246
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1247
{
1248
    const char *opn = "hilo";
1249

    
1250
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1251
        /* Treat as a NOP */
1252
        MIPS_DEBUG("NOP");
1253
        return;
1254
    }
1255
    switch (opc) {
1256
    case OPC_MFHI:
1257
        gen_op_load_HI();
1258
        GEN_STORE_TN_REG(reg, T0);
1259
        opn = "mfhi";
1260
        break;
1261
    case OPC_MFLO:
1262
        gen_op_load_LO();
1263
        GEN_STORE_TN_REG(reg, T0);
1264
        opn = "mflo";
1265
        break;
1266
    case OPC_MTHI:
1267
        GEN_LOAD_REG_TN(T0, reg);
1268
        gen_op_store_HI();
1269
        opn = "mthi";
1270
        break;
1271
    case OPC_MTLO:
1272
        GEN_LOAD_REG_TN(T0, reg);
1273
        gen_op_store_LO();
1274
        opn = "mtlo";
1275
        break;
1276
    default:
1277
        MIPS_INVAL(opn);
1278
        generate_exception(ctx, EXCP_RI);
1279
        return;
1280
    }
1281
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1282
}
1283

    
1284
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1285
                        int rs, int rt)
1286
{
1287
    const char *opn = "mul/div";
1288

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

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

    
1388
/* Traps */
1389
static void gen_trap (DisasContext *ctx, uint32_t opc,
1390
                      int rs, int rt, int16_t imm)
1391
{
1392
    int cond;
1393

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

    
1485
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1486
{
1487
    TranslationBlock *tb;
1488
    tb = ctx->tb;
1489
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1490
        if (n == 0)
1491
            gen_op_goto_tb0(TBPARAM(tb));
1492
        else
1493
            gen_op_goto_tb1(TBPARAM(tb));
1494
        gen_op_save_pc(dest);
1495
        gen_op_set_T0((long)tb + n);
1496
    } else {
1497
        gen_op_save_pc(dest);
1498
        gen_op_reset_T0();
1499
    }
1500
    gen_op_exit_tb();
1501
}
1502

    
1503
/* Branches (before delay slot) */
1504
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1505
                                int rs, int rt, int32_t offset)
1506
{
1507
    target_ulong btarget = -1;
1508
    int blink = 0;
1509
    int bcond = 0;
1510

    
1511
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1512
#ifdef MIPS_DEBUG_DISAS
1513
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1514
            fprintf(logfile,
1515
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1516
                    ctx->pc);
1517
        }
1518
#endif
1519
        generate_exception(ctx, EXCP_RI);
1520
        return;
1521
    }
1522

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

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

    
1799
/* CP0 (MMU and control) */
1800
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1801
{
1802
    const char *rn = "invalid";
1803

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

    
2382
die:
2383
#if defined MIPS_DEBUG_DISAS
2384
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2385
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2386
                rn, reg, sel);
2387
    }
2388
#endif
2389
    generate_exception(ctx, EXCP_RI);
2390
}
2391

    
2392
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2393
{
2394
    const char *rn = "invalid";
2395

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

    
2987
die:
2988
#if defined MIPS_DEBUG_DISAS
2989
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2990
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2991
                rn, reg, sel);
2992
    }
2993
#endif
2994
    generate_exception(ctx, EXCP_RI);
2995
}
2996

    
2997
#ifdef TARGET_MIPS64
2998
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2999
{
3000
    const char *rn = "invalid";
3001

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

    
3571
die:
3572
#if defined MIPS_DEBUG_DISAS
3573
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3574
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3575
                rn, reg, sel);
3576
    }
3577
#endif
3578
    generate_exception(ctx, EXCP_RI);
3579
}
3580

    
3581
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3582
{
3583
    const char *rn = "invalid";
3584

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

    
4167
die:
4168
#if defined MIPS_DEBUG_DISAS
4169
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4170
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4171
                rn, reg, sel);
4172
    }
4173
#endif
4174
    generate_exception(ctx, EXCP_RI);
4175
}
4176
#endif /* TARGET_MIPS64 */
4177

    
4178
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4179
{
4180
    const char *opn = "ldst";
4181

    
4182
    switch (opc) {
4183
    case OPC_MFC0:
4184
        if (rt == 0) {
4185
            /* Treat as NOP */
4186
            return;
4187
        }
4188
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4189
        gen_op_store_T0_gpr(rt);
4190
        opn = "mfc0";
4191
        break;
4192
    case OPC_MTC0:
4193
        GEN_LOAD_REG_TN(T0, rt);
4194
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4195
        opn = "mtc0";
4196
        break;
4197
#ifdef TARGET_MIPS64
4198
    case OPC_DMFC0:
4199
        if (rt == 0) {
4200
            /* Treat as NOP */
4201
            return;
4202
        }
4203
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4204
        gen_op_store_T0_gpr(rt);
4205
        opn = "dmfc0";
4206
        break;
4207
    case OPC_DMTC0:
4208
        GEN_LOAD_REG_TN(T0, rt);
4209
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4210
        opn = "dmtc0";
4211
        break;
4212
#endif
4213
    case OPC_TLBWI:
4214
        opn = "tlbwi";
4215
        if (!env->do_tlbwi)
4216
            goto die;
4217
        gen_op_tlbwi();
4218
        break;
4219
    case OPC_TLBWR:
4220
        opn = "tlbwr";
4221
        if (!env->do_tlbwr)
4222
            goto die;
4223
        gen_op_tlbwr();
4224
        break;
4225
    case OPC_TLBP:
4226
        opn = "tlbp";
4227
        if (!env->do_tlbp)
4228
            goto die;
4229
        gen_op_tlbp();
4230
        break;
4231
    case OPC_TLBR:
4232
        opn = "tlbr";
4233
        if (!env->do_tlbr)
4234
            goto die;
4235
        gen_op_tlbr();
4236
        break;
4237
    case OPC_ERET:
4238
        opn = "eret";
4239
        save_cpu_state(ctx, 0);
4240
        gen_op_eret();
4241
        ctx->bstate = BS_EXCP;
4242
        break;
4243
    case OPC_DERET:
4244
        opn = "deret";
4245
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4246
            MIPS_INVAL(opn);
4247
            generate_exception(ctx, EXCP_RI);
4248
        } else {
4249
            save_cpu_state(ctx, 0);
4250
            gen_op_deret();
4251
            ctx->bstate = BS_EXCP;
4252
        }
4253
        break;
4254
    case OPC_WAIT:
4255
        opn = "wait";
4256
        /* If we get an exception, we want to restart at next instruction */
4257
        ctx->pc += 4;
4258
        save_cpu_state(ctx, 1);
4259
        ctx->pc -= 4;
4260
        gen_op_wait();
4261
        ctx->bstate = BS_EXCP;
4262
        break;
4263
    default:
4264
 die:
4265
        MIPS_INVAL(opn);
4266
        generate_exception(ctx, EXCP_RI);
4267
        return;
4268
    }
4269
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4270
}
4271

    
4272
/* CP1 Branches (before delay slot) */
4273
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4274
                                 int32_t cc, int32_t offset)
4275
{
4276
    target_ulong btarget;
4277
    const char *opn = "cp1 cond branch";
4278

    
4279
    btarget = ctx->pc + 4 + offset;
4280

    
4281
    switch (op) {
4282
    case OPC_BC1F:
4283
        gen_op_bc1f(cc);
4284
        opn = "bc1f";
4285
        goto not_likely;
4286
    case OPC_BC1FL:
4287
        gen_op_bc1f(cc);
4288
        opn = "bc1fl";
4289
        goto likely;
4290
    case OPC_BC1T:
4291
        gen_op_bc1t(cc);
4292
        opn = "bc1t";
4293
        goto not_likely;
4294
    case OPC_BC1TL:
4295
        gen_op_bc1t(cc);
4296
        opn = "bc1tl";
4297
    likely:
4298
        ctx->hflags |= MIPS_HFLAG_BL;
4299
        gen_op_set_bcond();
4300
        gen_op_save_bcond();
4301
        break;
4302
    case OPC_BC1FANY2:
4303
        gen_op_bc1any2f(cc);
4304
        opn = "bc1any2f";
4305
        goto not_likely;
4306
    case OPC_BC1TANY2:
4307
        gen_op_bc1any2t(cc);
4308
        opn = "bc1any2t";
4309
        goto not_likely;
4310
    case OPC_BC1FANY4:
4311
        gen_op_bc1any4f(cc);
4312
        opn = "bc1any4f";
4313
        goto not_likely;
4314
    case OPC_BC1TANY4:
4315
        gen_op_bc1any4t(cc);
4316
        opn = "bc1any4t";
4317
    not_likely:
4318
        ctx->hflags |= MIPS_HFLAG_BC;
4319
        gen_op_set_bcond();
4320
        break;
4321
    default:
4322
        MIPS_INVAL(opn);
4323
        generate_exception (ctx, EXCP_RI);
4324
        return;
4325
    }
4326
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4327
               ctx->hflags, btarget);
4328
    ctx->btarget = btarget;
4329
}
4330

    
4331
/* Coprocessor 1 (FPU) */
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
        GEN_LOAD_FREG_FTN(WTH0, fs);
4378
        gen_op_mfhc1();
4379
        GEN_STORE_TN_REG(rt, T0);
4380
        opn = "mfhc1";
4381
        break;
4382
    case OPC_MTHC1:
4383
        GEN_LOAD_REG_TN(T0, rt);
4384
        gen_op_mthc1();
4385
        GEN_STORE_FTN_FREG(fs, WTH0);
4386
        opn = "mthc1";
4387
        break;
4388
    default:
4389
        MIPS_INVAL(opn);
4390
        generate_exception (ctx, EXCP_RI);
4391
        return;
4392
    }
4393
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4394
}
4395

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

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

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

    
4432
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4433
                        int fs, int fd, int cc)
4434
{
4435
    const char *opn = "farith";
4436
    const char *condnames[] = {
4437
            "c.f",
4438
            "c.un",
4439
            "c.eq",
4440
            "c.ueq",
4441
            "c.olt",
4442
            "c.ult",
4443
            "c.ole",
4444
            "c.ule",
4445
            "c.sf",
4446
            "c.ngle",
4447
            "c.seq",
4448
            "c.ngl",
4449
            "c.lt",
4450
            "c.nge",
4451
            "c.le",
4452
            "c.ngt",
4453
    };
4454
    const char *condnames_abs[] = {
4455
            "cabs.f",
4456
            "cabs.un",
4457
            "cabs.eq",
4458
            "cabs.ueq",
4459
            "cabs.olt",
4460
            "cabs.ult",
4461
            "cabs.ole",
4462
            "cabs.ule",
4463
            "cabs.sf",
4464
            "cabs.ngle",
4465
            "cabs.seq",
4466
            "cabs.ngl",
4467
            "cabs.lt",
4468
            "cabs.nge",
4469
            "cabs.le",
4470
            "cabs.ngt",
4471
    };
4472
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4473
    uint32_t func = ctx->opcode & 0x3f;
4474

    
4475
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4476
    case FOP(0, 16):
4477
        GEN_LOAD_FREG_FTN(WT0, fs);
4478
        GEN_LOAD_FREG_FTN(WT1, ft);
4479
        gen_op_float_add_s();
4480
        GEN_STORE_FTN_FREG(fd, WT2);
4481
        opn = "add.s";
4482
        optype = BINOP;
4483
        break;
4484
    case FOP(1, 16):
4485
        GEN_LOAD_FREG_FTN(WT0, fs);
4486
        GEN_LOAD_FREG_FTN(WT1, ft);
4487
        gen_op_float_sub_s();
4488
        GEN_STORE_FTN_FREG(fd, WT2);
4489
        opn = "sub.s";
4490
        optype = BINOP;
4491
        break;
4492
    case FOP(2, 16):
4493
        GEN_LOAD_FREG_FTN(WT0, fs);
4494
        GEN_LOAD_FREG_FTN(WT1, ft);
4495
        gen_op_float_mul_s();
4496
        GEN_STORE_FTN_FREG(fd, WT2);
4497
        opn = "mul.s";
4498
        optype = BINOP;
4499
        break;
4500
    case FOP(3, 16):
4501
        GEN_LOAD_FREG_FTN(WT0, fs);
4502
        GEN_LOAD_FREG_FTN(WT1, ft);
4503
        gen_op_float_div_s();
4504
        GEN_STORE_FTN_FREG(fd, WT2);
4505
        opn = "div.s";
4506
        optype = BINOP;
4507
        break;
4508
    case FOP(4, 16):
4509
        GEN_LOAD_FREG_FTN(WT0, fs);
4510
        gen_op_float_sqrt_s();
4511
        GEN_STORE_FTN_FREG(fd, WT2);
4512
        opn = "sqrt.s";
4513
        break;
4514
    case FOP(5, 16):
4515
        GEN_LOAD_FREG_FTN(WT0, fs);
4516
        gen_op_float_abs_s();
4517
        GEN_STORE_FTN_FREG(fd, WT2);
4518
        opn = "abs.s";
4519
        break;
4520
    case FOP(6, 16):
4521
        GEN_LOAD_FREG_FTN(WT0, fs);
4522
        gen_op_float_mov_s();
4523
        GEN_STORE_FTN_FREG(fd, WT2);
4524
        opn = "mov.s";
4525
        break;
4526
    case FOP(7, 16):
4527
        GEN_LOAD_FREG_FTN(WT0, fs);
4528
        gen_op_float_chs_s();
4529
        GEN_STORE_FTN_FREG(fd, WT2);
4530
        opn = "neg.s";
4531
        break;
4532
    case FOP(8, 16):
4533
        gen_op_cp1_64bitmode();
4534
        GEN_LOAD_FREG_FTN(WT0, fs);
4535
        gen_op_float_roundl_s();
4536
        GEN_STORE_FTN_FREG(fd, DT2);
4537
        opn = "round.l.s";
4538
        break;
4539
    case FOP(9, 16):
4540
        gen_op_cp1_64bitmode();
4541
        GEN_LOAD_FREG_FTN(WT0, fs);
4542
        gen_op_float_truncl_s();
4543
        GEN_STORE_FTN_FREG(fd, DT2);
4544
        opn = "trunc.l.s";
4545
        break;
4546
    case FOP(10, 16):
4547
        gen_op_cp1_64bitmode();
4548
        GEN_LOAD_FREG_FTN(WT0, fs);
4549
        gen_op_float_ceill_s();
4550
        GEN_STORE_FTN_FREG(fd, DT2);
4551
        opn = "ceil.l.s";
4552
        break;
4553
    case FOP(11, 16):
4554
        gen_op_cp1_64bitmode();
4555
        GEN_LOAD_FREG_FTN(WT0, fs);
4556
        gen_op_float_floorl_s();
4557
        GEN_STORE_FTN_FREG(fd, DT2);
4558
        opn = "floor.l.s";
4559
        break;
4560
    case FOP(12, 16):
4561
        GEN_LOAD_FREG_FTN(WT0, fs);
4562
        gen_op_float_roundw_s();
4563
        GEN_STORE_FTN_FREG(fd, WT2);
4564
        opn = "round.w.s";
4565
        break;
4566
    case FOP(13, 16):
4567
        GEN_LOAD_FREG_FTN(WT0, fs);
4568
        gen_op_float_truncw_s();
4569
        GEN_STORE_FTN_FREG(fd, WT2);
4570
        opn = "trunc.w.s";
4571
        break;
4572
    case FOP(14, 16):
4573
        GEN_LOAD_FREG_FTN(WT0, fs);
4574
        gen_op_float_ceilw_s();
4575
        GEN_STORE_FTN_FREG(fd, WT2);
4576
        opn = "ceil.w.s";
4577
        break;
4578
    case FOP(15, 16):
4579
        GEN_LOAD_FREG_FTN(WT0, fs);
4580
        gen_op_float_floorw_s();
4581
        GEN_STORE_FTN_FREG(fd, WT2);
4582
        opn = "floor.w.s";
4583
        break;
4584
    case FOP(17, 16):
4585
        GEN_LOAD_REG_TN(T0, ft);
4586
        GEN_LOAD_FREG_FTN(WT0, fs);
4587
        GEN_LOAD_FREG_FTN(WT2, fd);
4588
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4589
        GEN_STORE_FTN_FREG(fd, WT2);
4590
        opn = "movcf.s";
4591
        break;
4592
    case FOP(18, 16):
4593
        GEN_LOAD_REG_TN(T0, ft);
4594
        GEN_LOAD_FREG_FTN(WT0, fs);
4595
        GEN_LOAD_FREG_FTN(WT2, fd);
4596
        gen_op_float_movz_s();
4597
        GEN_STORE_FTN_FREG(fd, WT2);
4598
        opn = "movz.s";
4599
        break;
4600
    case FOP(19, 16):
4601
        GEN_LOAD_REG_TN(T0, ft);
4602
        GEN_LOAD_FREG_FTN(WT0, fs);
4603
        GEN_LOAD_FREG_FTN(WT2, fd);
4604
        gen_op_float_movn_s();
4605
        GEN_STORE_FTN_FREG(fd, WT2);
4606
        opn = "movn.s";
4607
        break;
4608
    case FOP(21, 16):
4609
        GEN_LOAD_FREG_FTN(WT0, fs);
4610
        gen_op_float_recip_s();
4611
        GEN_STORE_FTN_FREG(fd, WT2);
4612
        opn = "recip.s";
4613
        break;
4614
    case FOP(22, 16):
4615
        GEN_LOAD_FREG_FTN(WT0, fs);
4616
        gen_op_float_rsqrt_s();
4617
        GEN_STORE_FTN_FREG(fd, WT2);
4618
        opn = "rsqrt.s";
4619
        break;
4620
    case FOP(28, 16):
4621
        gen_op_cp1_64bitmode();
4622
        GEN_LOAD_FREG_FTN(WT0, fs);
4623
        GEN_LOAD_FREG_FTN(WT2, fd);
4624
        gen_op_float_recip2_s();
4625
        GEN_STORE_FTN_FREG(fd, WT2);
4626
        opn = "recip2.s";
4627
        break;
4628
    case FOP(29, 16):
4629
        gen_op_cp1_64bitmode();
4630
        GEN_LOAD_FREG_FTN(WT0, fs);
4631
        gen_op_float_recip1_s();
4632
        GEN_STORE_FTN_FREG(fd, WT2);
4633
        opn = "recip1.s";
4634
        break;
4635
    case FOP(30, 16):
4636
        gen_op_cp1_64bitmode();
4637
        GEN_LOAD_FREG_FTN(WT0, fs);
4638
        gen_op_float_rsqrt1_s();
4639
        GEN_STORE_FTN_FREG(fd, WT2);
4640
        opn = "rsqrt1.s";
4641
        break;
4642
    case FOP(31, 16):
4643
        gen_op_cp1_64bitmode();
4644
        GEN_LOAD_FREG_FTN(WT0, fs);
4645
        GEN_LOAD_FREG_FTN(WT2, fd);
4646
        gen_op_float_rsqrt2_s();
4647
        GEN_STORE_FTN_FREG(fd, WT2);
4648
        opn = "rsqrt2.s";
4649
        break;
4650
    case FOP(33, 16):
4651
        gen_op_cp1_registers(fd);
4652
        GEN_LOAD_FREG_FTN(WT0, fs);
4653
        gen_op_float_cvtd_s();
4654
        GEN_STORE_FTN_FREG(fd, DT2);
4655
        opn = "cvt.d.s";
4656
        break;
4657
    case FOP(36, 16):
4658
        GEN_LOAD_FREG_FTN(WT0, fs);
4659
        gen_op_float_cvtw_s();
4660
        GEN_STORE_FTN_FREG(fd, WT2);
4661
        opn = "cvt.w.s";
4662
        break;
4663
    case FOP(37, 16):
4664
        gen_op_cp1_64bitmode();
4665
        GEN_LOAD_FREG_FTN(WT0, fs);
4666
        gen_op_float_cvtl_s();
4667
        GEN_STORE_FTN_FREG(fd, DT2);
4668
        opn = "cvt.l.s";
4669
        break;
4670
    case FOP(38, 16):
4671
        gen_op_cp1_64bitmode();
4672
        GEN_LOAD_FREG_FTN(WT1, fs);
4673
        GEN_LOAD_FREG_FTN(WT0, ft);
4674
        gen_op_float_cvtps_s();
4675
        GEN_STORE_FTN_FREG(fd, DT2);
4676
        opn = "cvt.ps.s";
4677
        break;
4678
    case FOP(48, 16):
4679
    case FOP(49, 16):
4680
    case FOP(50, 16):
4681
    case FOP(51, 16):
4682
    case FOP(52, 16):
4683
    case FOP(53, 16):
4684
    case FOP(54, 16):
4685
    case FOP(55, 16):
4686
    case FOP(56, 16):
4687
    case FOP(57, 16):
4688
    case FOP(58, 16):
4689
    case FOP(59, 16):
4690
    case FOP(60, 16):
4691
    case FOP(61, 16):
4692
    case FOP(62, 16):
4693
    case FOP(63, 16):
4694
        GEN_LOAD_FREG_FTN(WT0, fs);
4695
        GEN_LOAD_FREG_FTN(WT1, ft);
4696
        if (ctx->opcode & (1 << 6)) {
4697
            gen_op_cp1_64bitmode();
4698
            gen_cmpabs_s(func-48, cc);
4699
            opn = condnames_abs[func-48];
4700
        } else {
4701
            gen_cmp_s(func-48, cc);
4702
            opn = condnames[func-48];
4703
        }
4704
        break;
4705
    case FOP(0, 17):
4706
        gen_op_cp1_registers(fs | ft | fd);
4707
        GEN_LOAD_FREG_FTN(DT0, fs);
4708
        GEN_LOAD_FREG_FTN(DT1, ft);
4709
        gen_op_float_add_d();
4710
        GEN_STORE_FTN_FREG(fd, DT2);
4711
        opn = "add.d";
4712
        optype = BINOP;
4713
        break;
4714
    case FOP(1, 17):
4715
        gen_op_cp1_registers(fs | ft | fd);
4716
        GEN_LOAD_FREG_FTN(DT0, fs);
4717
        GEN_LOAD_FREG_FTN(DT1, ft);
4718
        gen_op_float_sub_d();
4719
        GEN_STORE_FTN_FREG(fd, DT2);
4720
        opn = "sub.d";
4721
        optype = BINOP;
4722
        break;
4723
    case FOP(2, 17):
4724
        gen_op_cp1_registers(fs | ft | fd);
4725
        GEN_LOAD_FREG_FTN(DT0, fs);
4726
        GEN_LOAD_FREG_FTN(DT1, ft);
4727
        gen_op_float_mul_d();
4728
        GEN_STORE_FTN_FREG(fd, DT2);
4729
        opn = "mul.d";
4730
        optype = BINOP;
4731
        break;
4732
    case FOP(3, 17):
4733
        gen_op_cp1_registers(fs | ft | fd);
4734
        GEN_LOAD_FREG_FTN(DT0, fs);
4735
        GEN_LOAD_FREG_FTN(DT1, ft);
4736
        gen_op_float_div_d();
4737
        GEN_STORE_FTN_FREG(fd, DT2);
4738
        opn = "div.d";
4739
        optype = BINOP;
4740
        break;
4741
    case FOP(4, 17):
4742
        gen_op_cp1_registers(fs | fd);
4743
        GEN_LOAD_FREG_FTN(DT0, fs);
4744
        gen_op_float_sqrt_d();
4745
        GEN_STORE_FTN_FREG(fd, DT2);
4746
        opn = "sqrt.d";
4747
        break;
4748
    case FOP(5, 17):
4749
        gen_op_cp1_registers(fs | fd);
4750
        GEN_LOAD_FREG_FTN(DT0, fs);
4751
        gen_op_float_abs_d();
4752
        GEN_STORE_FTN_FREG(fd, DT2);
4753
        opn = "abs.d";
4754
        break;
4755
    case FOP(6, 17):
4756
        gen_op_cp1_registers(fs | fd);
4757
        GEN_LOAD_FREG_FTN(DT0, fs);
4758
        gen_op_float_mov_d();
4759
        GEN_STORE_FTN_FREG(fd, DT2);
4760
        opn = "mov.d";
4761
        break;
4762
    case FOP(7, 17):
4763
        gen_op_cp1_registers(fs | fd);
4764
        GEN_LOAD_FREG_FTN(DT0, fs);
4765
        gen_op_float_chs_d();
4766
        GEN_STORE_FTN_FREG(fd, DT2);
4767
        opn = "neg.d";
4768
        break;
4769
    case FOP(8, 17):
4770
        gen_op_cp1_64bitmode();
4771
        GEN_LOAD_FREG_FTN(DT0, fs);
4772
        gen_op_float_roundl_d();
4773
        GEN_STORE_FTN_FREG(fd, DT2);
4774
        opn = "round.l.d";
4775
        break;
4776
    case FOP(9, 17):
4777
        gen_op_cp1_64bitmode();
4778
        GEN_LOAD_FREG_FTN(DT0, fs);
4779
        gen_op_float_truncl_d();
4780
        GEN_STORE_FTN_FREG(fd, DT2);
4781
        opn = "trunc.l.d";
4782
        break;
4783
    case FOP(10, 17):
4784
        gen_op_cp1_64bitmode();
4785
        GEN_LOAD_FREG_FTN(DT0, fs);
4786
        gen_op_float_ceill_d();
4787
        GEN_STORE_FTN_FREG(fd, DT2);
4788
        opn = "ceil.l.d";
4789
        break;
4790
    case FOP(11, 17):
4791
        gen_op_cp1_64bitmode();
4792
        GEN_LOAD_FREG_FTN(DT0, fs);
4793
        gen_op_float_floorl_d();
4794
        GEN_STORE_FTN_FREG(fd, DT2);
4795
        opn = "floor.l.d";
4796
        break;
4797
    case FOP(12, 17):
4798
        gen_op_cp1_registers(fs);
4799
        GEN_LOAD_FREG_FTN(DT0, fs);
4800
        gen_op_float_roundw_d();
4801
        GEN_STORE_FTN_FREG(fd, WT2);
4802
        opn = "round.w.d";
4803
        break;
4804
    case FOP(13, 17):
4805
        gen_op_cp1_registers(fs);
4806
        GEN_LOAD_FREG_FTN(DT0, fs);
4807
        gen_op_float_truncw_d();
4808
        GEN_STORE_FTN_FREG(fd, WT2);
4809
        opn = "trunc.w.d";
4810
        break;
4811
    case FOP(14, 17):
4812
        gen_op_cp1_registers(fs);
4813
        GEN_LOAD_FREG_FTN(DT0, fs);
4814
        gen_op_float_ceilw_d();
4815
        GEN_STORE_FTN_FREG(fd, WT2);
4816
        opn = "ceil.w.d";
4817
        break;
4818
    case FOP(15, 17):
4819
        gen_op_cp1_registers(fs);
4820
        GEN_LOAD_FREG_FTN(DT0, fs);
4821
        gen_op_float_floorw_d();
4822
        GEN_STORE_FTN_FREG(fd, WT2);
4823
        opn = "floor.w.d";
4824
        break;
4825
    case FOP(17, 17):
4826
        GEN_LOAD_REG_TN(T0, ft);
4827
        GEN_LOAD_FREG_FTN(DT0, fs);
4828
        GEN_LOAD_FREG_FTN(DT2, fd);
4829
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4830
        GEN_STORE_FTN_FREG(fd, DT2);
4831
        opn = "movcf.d";
4832
        break;
4833
    case FOP(18, 17):
4834
        GEN_LOAD_REG_TN(T0, ft);
4835
        GEN_LOAD_FREG_FTN(DT0, fs);
4836
        GEN_LOAD_FREG_FTN(DT2, fd);
4837
        gen_op_float_movz_d();
4838
        GEN_STORE_FTN_FREG(fd, DT2);
4839
        opn = "movz.d";
4840
        break;
4841
    case FOP(19, 17):
4842
        GEN_LOAD_REG_TN(T0, ft);
4843
        GEN_LOAD_FREG_FTN(DT0, fs);
4844
        GEN_LOAD_FREG_FTN(DT2, fd);
4845
        gen_op_float_movn_d();
4846
        GEN_STORE_FTN_FREG(fd, DT2);
4847
        opn = "movn.d";
4848
        break;
4849
    case FOP(21, 17):
4850
        gen_op_cp1_registers(fs | fd);
4851
        GEN_LOAD_FREG_FTN(DT0, fs);
4852
        gen_op_float_recip_d();
4853
        GEN_STORE_FTN_FREG(fd, DT2);
4854
        opn = "recip.d";
4855
        break;
4856
    case FOP(22, 17):
4857
        gen_op_cp1_registers(fs | fd);
4858
        GEN_LOAD_FREG_FTN(DT0, fs);
4859
        gen_op_float_rsqrt_d();
4860
        GEN_STORE_FTN_FREG(fd, DT2);
4861
        opn = "rsqrt.d";
4862
        break;
4863
    case FOP(28, 17):
4864
        gen_op_cp1_64bitmode();
4865
        GEN_LOAD_FREG_FTN(DT0, fs);
4866
        GEN_LOAD_FREG_FTN(DT2, ft);
4867
        gen_op_float_recip2_d();
4868
        GEN_STORE_FTN_FREG(fd, DT2);
4869
        opn = "recip2.d";
4870
        break;
4871
    case FOP(29, 17):
4872
        gen_op_cp1_64bitmode();
4873
        GEN_LOAD_FREG_FTN(DT0, fs);
4874
        gen_op_float_recip1_d();
4875
        GEN_STORE_FTN_FREG(fd, DT2);
4876
        opn = "recip1.d";
4877
        break;
4878
    case FOP(30, 17):
4879
        gen_op_cp1_64bitmode();
4880
        GEN_LOAD_FREG_FTN(DT0, fs);
4881
        gen_op_float_rsqrt1_d();
4882
        GEN_STORE_FTN_FREG(fd, DT2);
4883
        opn = "rsqrt1.d";
4884
        break;
4885
    case FOP(31, 17):
4886
        gen_op_cp1_64bitmode();
4887
        GEN_LOAD_FREG_FTN(DT0, fs);
4888
        GEN_LOAD_FREG_FTN(DT2, ft);
4889
        gen_op_float_rsqrt2_d();
4890
        GEN_STORE_FTN_FREG(fd, DT2);
4891
        opn = "rsqrt2.d";
4892
        break;
4893
    case FOP(48, 17):
4894
    case FOP(49, 17):
4895
    case FOP(50, 17):
4896
    case FOP(51, 17):
4897
    case FOP(52, 17):
4898
    case FOP(53, 17):
4899
    case FOP(54, 17):
4900
    case FOP(55, 17):
4901
    case FOP(56, 17):
4902
    case FOP(57, 17):
4903
    case FOP(58, 17):
4904
    case FOP(59, 17):
4905
    case FOP(60, 17):
4906
    case FOP(61, 17):
4907
    case FOP(62, 17):
4908
    case FOP(63, 17):
4909
        GEN_LOAD_FREG_FTN(DT0, fs);
4910
        GEN_LOAD_FREG_FTN(DT1, ft);
4911
        if (ctx->opcode & (1 << 6)) {
4912
            gen_op_cp1_64bitmode();
4913
            gen_cmpabs_d(func-48, cc);
4914
            opn = condnames_abs[func-48];
4915
        } else {
4916
            gen_op_cp1_registers(fs | ft);
4917
            gen_cmp_d(func-48, cc);
4918
            opn = condnames[func-48];
4919
        }
4920
        break;
4921
    case FOP(32, 17):
4922
        gen_op_cp1_registers(fs);
4923
        GEN_LOAD_FREG_FTN(DT0, fs);
4924
        gen_op_float_cvts_d();
4925
        GEN_STORE_FTN_FREG(fd, WT2);
4926
        opn = "cvt.s.d";
4927
        break;
4928
    case FOP(36, 17):
4929
        gen_op_cp1_registers(fs);
4930
        GEN_LOAD_FREG_FTN(DT0, fs);
4931
        gen_op_float_cvtw_d();
4932
        GEN_STORE_FTN_FREG(fd, WT2);
4933
        opn = "cvt.w.d";
4934
        break;
4935
    case FOP(37, 17):
4936
        gen_op_cp1_64bitmode();
4937
        GEN_LOAD_FREG_FTN(DT0, fs);
4938
        gen_op_float_cvtl_d();
4939
        GEN_STORE_FTN_FREG(fd, DT2);
4940
        opn = "cvt.l.d";
4941
        break;
4942
    case FOP(32, 20):
4943
        GEN_LOAD_FREG_FTN(WT0, fs);
4944
        gen_op_float_cvts_w();
4945
        GEN_STORE_FTN_FREG(fd, WT2);
4946
        opn = "cvt.s.w";
4947
        break;
4948
    case FOP(33, 20):
4949
        gen_op_cp1_registers(fd);
4950
        GEN_LOAD_FREG_FTN(WT0, fs);
4951
        gen_op_float_cvtd_w();
4952
        GEN_STORE_FTN_FREG(fd, DT2);
4953
        opn = "cvt.d.w";
4954
        break;
4955
    case FOP(32, 21):
4956
        gen_op_cp1_64bitmode();
4957
        GEN_LOAD_FREG_FTN(DT0, fs);
4958
        gen_op_float_cvts_l();
4959
        GEN_STORE_FTN_FREG(fd, WT2);
4960
        opn = "cvt.s.l";
4961
        break;
4962
    case FOP(33, 21):
4963
        gen_op_cp1_64bitmode();
4964
        GEN_LOAD_FREG_FTN(DT0, fs);
4965
        gen_op_float_cvtd_l();
4966
        GEN_STORE_FTN_FREG(fd, DT2);
4967
        opn = "cvt.d.l";
4968
        break;
4969
    case FOP(38, 20):
4970
    case FOP(38, 21):
4971
        gen_op_cp1_64bitmode();
4972
        GEN_LOAD_FREG_FTN(WT0, fs);
4973
        GEN_LOAD_FREG_FTN(WTH0, fs);
4974
        gen_op_float_cvtps_pw();
4975
        GEN_STORE_FTN_FREG(fd, WT2);
4976
        GEN_STORE_FTN_FREG(fd, WTH2);
4977
        opn = "cvt.ps.pw";
4978
        break;
4979
    case FOP(0, 22):
4980
        gen_op_cp1_64bitmode();
4981
        GEN_LOAD_FREG_FTN(WT0, fs);
4982
        GEN_LOAD_FREG_FTN(WTH0, fs);
4983
        GEN_LOAD_FREG_FTN(WT1, ft);
4984
        GEN_LOAD_FREG_FTN(WTH1, ft);
4985
        gen_op_float_add_ps();
4986
        GEN_STORE_FTN_FREG(fd, WT2);
4987
        GEN_STORE_FTN_FREG(fd, WTH2);
4988
        opn = "add.ps";
4989
        break;
4990
    case FOP(1, 22):
4991
        gen_op_cp1_64bitmode();
4992
        GEN_LOAD_FREG_FTN(WT0, fs);
4993
        GEN_LOAD_FREG_FTN(WTH0, fs);
4994
        GEN_LOAD_FREG_FTN(WT1, ft);
4995
        GEN_LOAD_FREG_FTN(WTH1, ft);
4996
        gen_op_float_sub_ps();
4997
        GEN_STORE_FTN_FREG(fd, WT2);
4998
        GEN_STORE_FTN_FREG(fd, WTH2);
4999
        opn = "sub.ps";
5000
        break;
5001
    case FOP(2, 22):
5002
        gen_op_cp1_64bitmode();
5003
        GEN_LOAD_FREG_FTN(WT0, fs);
5004
        GEN_LOAD_FREG_FTN(WTH0, fs);
5005
        GEN_LOAD_FREG_FTN(WT1, ft);
5006
        GEN_LOAD_FREG_FTN(WTH1, ft);
5007
        gen_op_float_mul_ps();
5008
        GEN_STORE_FTN_FREG(fd, WT2);
5009
        GEN_STORE_FTN_FREG(fd, WTH2);
5010
        opn = "mul.ps";
5011
        break;
5012
    case FOP(5, 22):
5013
        gen_op_cp1_64bitmode();
5014
        GEN_LOAD_FREG_FTN(WT0, fs);
5015
        GEN_LOAD_FREG_FTN(WTH0, fs);
5016
        gen_op_float_abs_ps();
5017
        GEN_STORE_FTN_FREG(fd, WT2);
5018
        GEN_STORE_FTN_FREG(fd, WTH2);
5019
        opn = "abs.ps";
5020
        break;
5021
    case FOP(6, 22):
5022
        gen_op_cp1_64bitmode();
5023
        GEN_LOAD_FREG_FTN(WT0, fs);
5024
        GEN_LOAD_FREG_FTN(WTH0, fs);
5025
        gen_op_float_mov_ps();
5026
        GEN_STORE_FTN_FREG(fd, WT2);
5027
        GEN_STORE_FTN_FREG(fd, WTH2);
5028
        opn = "mov.ps";
5029
        break;
5030
    case FOP(7, 22):
5031
        gen_op_cp1_64bitmode();
5032
        GEN_LOAD_FREG_FTN(WT0, fs);
5033
        GEN_LOAD_FREG_FTN(WTH0, fs);
5034
        gen_op_float_chs_ps();
5035
        GEN_STORE_FTN_FREG(fd, WT2);
5036
        GEN_STORE_FTN_FREG(fd, WTH2);
5037
        opn = "neg.ps";
5038
        break;
5039
    case FOP(17, 22):
5040
        gen_op_cp1_64bitmode();
5041
        GEN_LOAD_REG_TN(T0, ft);
5042
        GEN_LOAD_FREG_FTN(WT0, fs);
5043
        GEN_LOAD_FREG_FTN(WTH0, fs);
5044
        GEN_LOAD_FREG_FTN(WT2, fd);
5045
        GEN_LOAD_FREG_FTN(WTH2, fd);
5046
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5047
        GEN_STORE_FTN_FREG(fd, WT2);
5048
        GEN_STORE_FTN_FREG(fd, WTH2);
5049
        opn = "movcf.ps";
5050
        break;
5051
    case FOP(18, 22):
5052
        gen_op_cp1_64bitmode();
5053
        GEN_LOAD_REG_TN(T0, ft);
5054
        GEN_LOAD_FREG_FTN(WT0, fs);
5055
        GEN_LOAD_FREG_FTN(WTH0, fs);
5056
        GEN_LOAD_FREG_FTN(WT2, fd);
5057
        GEN_LOAD_FREG_FTN(WTH2, fd);
5058
        gen_op_float_movz_ps();
5059
        GEN_STORE_FTN_FREG(fd, WT2);
5060
        GEN_STORE_FTN_FREG(fd, WTH2);
5061
        opn = "movz.ps";
5062
        break;
5063
    case FOP(19, 22):
5064
        gen_op_cp1_64bitmode();
5065
        GEN_LOAD_REG_TN(T0, ft);
5066
        GEN_LOAD_FREG_FTN(WT0, fs);
5067
        GEN_LOAD_FREG_FTN(WTH0, fs);
5068
        GEN_LOAD_FREG_FTN(WT2, fd);
5069
        GEN_LOAD_FREG_FTN(WTH2, fd);
5070
        gen_op_float_movn_ps();
5071
        GEN_STORE_FTN_FREG(fd, WT2);
5072
        GEN_STORE_FTN_FREG(fd, WTH2);
5073
        opn = "movn.ps";
5074
        break;
5075
    case FOP(24, 22):
5076
        gen_op_cp1_64bitmode();
5077
        GEN_LOAD_FREG_FTN(WT0, fs);
5078
        GEN_LOAD_FREG_FTN(WTH0, fs);
5079
        GEN_LOAD_FREG_FTN(WT1, ft);
5080
        GEN_LOAD_FREG_FTN(WTH1, ft);
5081
        gen_op_float_addr_ps();
5082
        GEN_STORE_FTN_FREG(fd, WT2);
5083
        GEN_STORE_FTN_FREG(fd, WTH2);
5084
        opn = "addr.ps";
5085
        break;
5086
    case FOP(26, 22):
5087
        gen_op_cp1_64bitmode();
5088
        GEN_LOAD_FREG_FTN(WT0, fs);
5089
        GEN_LOAD_FREG_FTN(WTH0, fs);
5090
        GEN_LOAD_FREG_FTN(WT1, ft);
5091
        GEN_LOAD_FREG_FTN(WTH1, ft);
5092
        gen_op_float_mulr_ps();
5093
        GEN_STORE_FTN_FREG(fd, WT2);
5094
        GEN_STORE_FTN_FREG(fd, WTH2);
5095
        opn = "mulr.ps";
5096
        break;
5097
    case FOP(28, 22):
5098
        gen_op_cp1_64bitmode();
5099
        GEN_LOAD_FREG_FTN(WT0, fs);
5100
        GEN_LOAD_FREG_FTN(WTH0, fs);
5101
        GEN_LOAD_FREG_FTN(WT2, fd);
5102
        GEN_LOAD_FREG_FTN(WTH2, fd);
5103
        gen_op_float_recip2_ps();
5104
        GEN_STORE_FTN_FREG(fd, WT2);
5105
        GEN_STORE_FTN_FREG(fd, WTH2);
5106
        opn = "recip2.ps";
5107
        break;
5108
    case FOP(29, 22):
5109
        gen_op_cp1_64bitmode();
5110
        GEN_LOAD_FREG_FTN(WT0, fs);
5111
        GEN_LOAD_FREG_FTN(WTH0, fs);
5112
        gen_op_float_recip1_ps();
5113
        GEN_STORE_FTN_FREG(fd, WT2);
5114
        GEN_STORE_FTN_FREG(fd, WTH2);
5115
        opn = "recip1.ps";
5116
        break;
5117
    case FOP(30, 22):
5118
        gen_op_cp1_64bitmode();
5119
        GEN_LOAD_FREG_FTN(WT0, fs);
5120
        GEN_LOAD_FREG_FTN(WTH0, fs);
5121
        gen_op_float_rsqrt1_ps();
5122
        GEN_STORE_FTN_FREG(fd, WT2);
5123
        GEN_STORE_FTN_FREG(fd, WTH2);
5124
        opn = "rsqrt1.ps";
5125
        break;
5126
    case FOP(31, 22):
5127
        gen_op_cp1_64bitmode();
5128
        GEN_LOAD_FREG_FTN(WT0, fs);
5129
        GEN_LOAD_FREG_FTN(WTH0, fs);
5130
        GEN_LOAD_FREG_FTN(WT2, fd);
5131
        GEN_LOAD_FREG_FTN(WTH2, fd);
5132
        gen_op_float_rsqrt2_ps();
5133
        GEN_STORE_FTN_FREG(fd, WT2);
5134
        GEN_STORE_FTN_FREG(fd, WTH2);
5135
        opn = "rsqrt2.ps";
5136
        break;
5137
    case FOP(32, 22):
5138
        gen_op_cp1_64bitmode();
5139
        GEN_LOAD_FREG_FTN(WTH0, fs);
5140
        gen_op_float_cvts_pu();
5141
        GEN_STORE_FTN_FREG(fd, WT2);
5142
        opn = "cvt.s.pu";
5143
        break;
5144
    case FOP(36, 22):
5145
        gen_op_cp1_64bitmode();
5146
        GEN_LOAD_FREG_FTN(WT0, fs);
5147
        GEN_LOAD_FREG_FTN(WTH0, fs);
5148
        gen_op_float_cvtpw_ps();
5149
        GEN_STORE_FTN_FREG(fd, WT2);
5150
        GEN_STORE_FTN_FREG(fd, WTH2);
5151
        opn = "cvt.pw.ps";
5152
        break;
5153
    case FOP(40, 22):
5154
        gen_op_cp1_64bitmode();
5155
        GEN_LOAD_FREG_FTN(WT0, fs);
5156
        gen_op_float_cvts_pl();
5157
        GEN_STORE_FTN_FREG(fd, WT2);
5158
        opn = "cvt.s.pl";
5159
        break;
5160
    case FOP(44, 22):
5161
        gen_op_cp1_64bitmode();
5162
        GEN_LOAD_FREG_FTN(WT0, fs);
5163
        GEN_LOAD_FREG_FTN(WT1, ft);
5164
        gen_op_float_pll_ps();
5165
        GEN_STORE_FTN_FREG(fd, DT2);
5166
        opn = "pll.ps";
5167
        break;
5168
    case FOP(45, 22):
5169
        gen_op_cp1_64bitmode();
5170
        GEN_LOAD_FREG_FTN(WT0, fs);
5171
        GEN_LOAD_FREG_FTN(WTH1, ft);
5172
        gen_op_float_plu_ps();
5173
        GEN_STORE_FTN_FREG(fd, DT2);
5174
        opn = "plu.ps";
5175
        break;
5176
    case FOP(46, 22):
5177
        gen_op_cp1_64bitmode();
5178
        GEN_LOAD_FREG_FTN(WTH0, fs);
5179
        GEN_LOAD_FREG_FTN(WT1, ft);
5180
        gen_op_float_pul_ps();
5181
        GEN_STORE_FTN_FREG(fd, DT2);
5182
        opn = "pul.ps";
5183
        break;
5184
    case FOP(47, 22):
5185
        gen_op_cp1_64bitmode();
5186
        GEN_LOAD_FREG_FTN(WTH0, fs);
5187
        GEN_LOAD_FREG_FTN(WTH1, ft);
5188
        gen_op_float_puu_ps();
5189
        GEN_STORE_FTN_FREG(fd, DT2);
5190
        opn = "puu.ps";
5191
        break;
5192
    case FOP(48, 22):
5193
    case FOP(49, 22):
5194
    case FOP(50, 22):
5195
    case FOP(51, 22):
5196
    case FOP(52, 22):
5197
    case FOP(53, 22):
5198
    case FOP(54, 22):
5199
    case FOP(55, 22):
5200
    case FOP(56, 22):
5201
    case FOP(57, 22):
5202
    case FOP(58, 22):
5203
    case FOP(59, 22):
5204
    case FOP(60, 22):
5205
    case FOP(61, 22):
5206
    case FOP(62, 22):
5207
    case FOP(63, 22):
5208
        gen_op_cp1_64bitmode();
5209
        GEN_LOAD_FREG_FTN(WT0, fs);
5210
        GEN_LOAD_FREG_FTN(WTH0, fs);
5211
        GEN_LOAD_FREG_FTN(WT1, ft);
5212
        GEN_LOAD_FREG_FTN(WTH1, ft);
5213
        if (ctx->opcode & (1 << 6)) {
5214
            gen_cmpabs_ps(func-48, cc);
5215
            opn = condnames_abs[func-48];
5216
        } else {
5217
            gen_cmp_ps(func-48, cc);
5218
            opn = condnames[func-48];
5219
        }
5220
        break;
5221
    default:
5222
        MIPS_INVAL(opn);
5223
        generate_exception (ctx, EXCP_RI);
5224
        return;
5225
    }
5226
    switch (optype) {
5227
    case BINOP:
5228
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5229
        break;
5230
    case CMPOP:
5231
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5232
        break;
5233
    default:
5234
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5235
        break;
5236
    }
5237
}
5238

    
5239
/* Coprocessor 3 (FPU) */
5240
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5241
                           int fs, int base, int index)
5242
{
5243
    const char *opn = "extended float load/store";
5244
    int store = 0;
5245

    
5246
    /* All of those work only on 64bit FPUs. */
5247
    gen_op_cp1_64bitmode();
5248
    if (base == 0) {
5249
        if (index == 0)
5250
            gen_op_reset_T0();
5251
        else
5252
            GEN_LOAD_REG_TN(T0, index);
5253
    } else if (index == 0) {
5254
        GEN_LOAD_REG_TN(T0, base);
5255
    } else {
5256
        GEN_LOAD_REG_TN(T0, base);
5257
        GEN_LOAD_REG_TN(T1, index);
5258
        gen_op_addr_add();
5259
    }
5260
    /* Don't do NOP if destination is zero: we must perform the actual
5261
     * memory access
5262
     */
5263
    switch (opc) {
5264
    case OPC_LWXC1:
5265
        op_ldst(lwc1);
5266
        GEN_STORE_FTN_FREG(fd, WT0);
5267
        opn = "lwxc1";
5268
        break;
5269
    case OPC_LDXC1:
5270
        op_ldst(ldc1);
5271
        GEN_STORE_FTN_FREG(fd, DT0);
5272
        opn = "ldxc1";
5273
        break;
5274
    case OPC_LUXC1:
5275
        op_ldst(luxc1);
5276
        GEN_STORE_FTN_FREG(fd, DT0);
5277
        opn = "luxc1";
5278
        break;
5279
    case OPC_SWXC1:
5280
        GEN_LOAD_FREG_FTN(WT0, fs);
5281
        op_ldst(swc1);
5282
        opn = "swxc1";
5283
        store = 1;
5284
        break;
5285
    case OPC_SDXC1:
5286
        GEN_LOAD_FREG_FTN(DT0, fs);
5287
        op_ldst(sdc1);
5288
        opn = "sdxc1";
5289
        store = 1;
5290
        break;
5291
    case OPC_SUXC1:
5292
        GEN_LOAD_FREG_FTN(DT0, fs);
5293
        op_ldst(suxc1);
5294
        opn = "suxc1";
5295
        store = 1;
5296
        break;
5297
    default:
5298
        MIPS_INVAL(opn);
5299
        generate_exception(ctx, EXCP_RI);
5300
        return;
5301
    }
5302
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5303
               regnames[index], regnames[base]);
5304
}
5305

    
5306
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5307
                            int fr, int fs, int ft)
5308
{
5309
    const char *opn = "flt3_arith";
5310

    
5311
    /* All of those work only on 64bit FPUs. */
5312
    gen_op_cp1_64bitmode();
5313
    switch (opc) {
5314
    case OPC_ALNV_PS:
5315
        GEN_LOAD_REG_TN(T0, fr);
5316
        GEN_LOAD_FREG_FTN(DT0, fs);
5317
        GEN_LOAD_FREG_FTN(DT1, ft);
5318
        gen_op_float_alnv_ps();
5319
        GEN_STORE_FTN_FREG(fd, DT2);
5320
        opn = "alnv.ps";
5321
        break;
5322
    case OPC_MADD_S:
5323
        GEN_LOAD_FREG_FTN(WT0, fs);
5324
        GEN_LOAD_FREG_FTN(WT1, ft);
5325
        GEN_LOAD_FREG_FTN(WT2, fr);
5326
        gen_op_float_muladd_s();
5327
        GEN_STORE_FTN_FREG(fd, WT2);
5328
        opn = "madd.s";
5329
        break;
5330
    case OPC_MADD_D:
5331
        GEN_LOAD_FREG_FTN(DT0, fs);
5332
        GEN_LOAD_FREG_FTN(DT1, ft);
5333
        GEN_LOAD_FREG_FTN(DT2, fr);
5334
        gen_op_float_muladd_d();
5335
        GEN_STORE_FTN_FREG(fd, DT2);
5336
        opn = "madd.d";
5337
        break;
5338
    case OPC_MADD_PS:
5339
        GEN_LOAD_FREG_FTN(WT0, fs);
5340
        GEN_LOAD_FREG_FTN(WTH0, fs);
5341
        GEN_LOAD_FREG_FTN(WT1, ft);
5342
        GEN_LOAD_FREG_FTN(WTH1, ft);
5343
        GEN_LOAD_FREG_FTN(WT2, fr);
5344
        GEN_LOAD_FREG_FTN(WTH2, fr);
5345
        gen_op_float_muladd_ps();
5346
        GEN_STORE_FTN_FREG(fd, WT2);
5347
        GEN_STORE_FTN_FREG(fd, WTH2);
5348
        opn = "madd.ps";
5349
        break;
5350
    case OPC_MSUB_S:
5351
        GEN_LOAD_FREG_FTN(WT0, fs);
5352
        GEN_LOAD_FREG_FTN(WT1, ft);
5353
        GEN_LOAD_FREG_FTN(WT2, fr);
5354
        gen_op_float_mulsub_s();
5355
        GEN_STORE_FTN_FREG(fd, WT2);
5356
        opn = "msub.s";
5357
        break;
5358
    case OPC_MSUB_D:
5359
        GEN_LOAD_FREG_FTN(DT0, fs);
5360
        GEN_LOAD_FREG_FTN(DT1, ft);
5361
        GEN_LOAD_FREG_FTN(DT2, fr);
5362
        gen_op_float_mulsub_d();
5363
        GEN_STORE_FTN_FREG(fd, DT2);
5364
        opn = "msub.d";
5365
        break;
5366
    case OPC_MSUB_PS:
5367
        GEN_LOAD_FREG_FTN(WT0, fs);
5368
        GEN_LOAD_FREG_FTN(WTH0, fs);
5369
        GEN_LOAD_FREG_FTN(WT1, ft);
5370
        GEN_LOAD_FREG_FTN(WTH1, ft);
5371
        GEN_LOAD_FREG_FTN(WT2, fr);
5372
        GEN_LOAD_FREG_FTN(WTH2, fr);
5373
        gen_op_float_mulsub_ps();
5374
        GEN_STORE_FTN_FREG(fd, WT2);
5375
        GEN_STORE_FTN_FREG(fd, WTH2);
5376
        opn = "msub.ps";
5377
        break;
5378
    case OPC_NMADD_S:
5379
        GEN_LOAD_FREG_FTN(WT0, fs);
5380
        GEN_LOAD_FREG_FTN(WT1, ft);
5381
        GEN_LOAD_FREG_FTN(WT2, fr);
5382
        gen_op_float_nmuladd_s();
5383
        GEN_STORE_FTN_FREG(fd, WT2);
5384
        opn = "nmadd.s";
5385
        break;
5386
    case OPC_NMADD_D:
5387
        GEN_LOAD_FREG_FTN(DT0, fs);
5388
        GEN_LOAD_FREG_FTN(DT1, ft);
5389
        GEN_LOAD_FREG_FTN(DT2, fr);
5390
        gen_op_float_nmuladd_d();
5391
        GEN_STORE_FTN_FREG(fd, DT2);
5392
        opn = "nmadd.d";
5393
        break;
5394
    case OPC_NMADD_PS:
5395
        GEN_LOAD_FREG_FTN(WT0, fs);
5396
        GEN_LOAD_FREG_FTN(WTH0, fs);
5397
        GEN_LOAD_FREG_FTN(WT1, ft);
5398
        GEN_LOAD_FREG_FTN(WTH1, ft);
5399
        GEN_LOAD_FREG_FTN(WT2, fr);
5400
        GEN_LOAD_FREG_FTN(WTH2, fr);
5401
        gen_op_float_nmuladd_ps();
5402
        GEN_STORE_FTN_FREG(fd, WT2);
5403
        GEN_STORE_FTN_FREG(fd, WTH2);
5404
        opn = "nmadd.ps";
5405
        break;
5406
    case OPC_NMSUB_S:
5407
        GEN_LOAD_FREG_FTN(WT0, fs);
5408
        GEN_LOAD_FREG_FTN(WT1, ft);
5409
        GEN_LOAD_FREG_FTN(WT2, fr);
5410
        gen_op_float_nmulsub_s();
5411
        GEN_STORE_FTN_FREG(fd, WT2);
5412
        opn = "nmsub.s";
5413
        break;
5414
    case OPC_NMSUB_D:
5415
        GEN_LOAD_FREG_FTN(DT0, fs);
5416
        GEN_LOAD_FREG_FTN(DT1, ft);
5417
        GEN_LOAD_FREG_FTN(DT2, fr);
5418
        gen_op_float_nmulsub_d();
5419
        GEN_STORE_FTN_FREG(fd, DT2);
5420
        opn = "nmsub.d";
5421
        break;
5422
    case OPC_NMSUB_PS:
5423
        GEN_LOAD_FREG_FTN(WT0, fs);
5424
        GEN_LOAD_FREG_FTN(WTH0, fs);
5425
        GEN_LOAD_FREG_FTN(WT1, ft);
5426
        GEN_LOAD_FREG_FTN(WTH1, ft);
5427
        GEN_LOAD_FREG_FTN(WT2, fr);
5428
        GEN_LOAD_FREG_FTN(WTH2, fr);
5429
        gen_op_float_nmulsub_ps();
5430
        GEN_STORE_FTN_FREG(fd, WT2);
5431
        GEN_STORE_FTN_FREG(fd, WTH2);
5432
        opn = "nmsub.ps";
5433
        break;
5434
    default:
5435
        MIPS_INVAL(opn);
5436
        generate_exception (ctx, EXCP_RI);
5437
        return;
5438
    }
5439
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5440
               fregnames[fs], fregnames[ft]);
5441
}
5442

    
5443
/* ISA extensions (ASEs) */
5444
/* MIPS16 extension to MIPS32 */
5445
/* SmartMIPS extension to MIPS32 */
5446

    
5447
#ifdef TARGET_MIPS64
5448

    
5449
/* MDMX extension to MIPS64 */
5450
/* MIPS-3D extension to MIPS64 */
5451

    
5452
#endif
5453

    
5454
static void decode_opc (CPUState *env, DisasContext *ctx)
5455
{
5456
    int32_t offset;
5457
    int rs, rt, rd, sa;
5458
    uint32_t op, op1, op2;
5459
    int16_t imm;
5460

    
5461
    /* make sure instructions are on a word boundary */
5462
    if (ctx->pc & 0x3) {
5463
        env->CP0_BadVAddr = ctx->pc;
5464
        generate_exception(ctx, EXCP_AdEL);
5465
        return;
5466
    }
5467

    
5468
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5469
        int l1;
5470
        /* Handle blikely not taken case */
5471
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5472
        l1 = gen_new_label();
5473
        gen_op_jnz_T2(l1);
5474
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5475
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5476
        gen_set_label(l1);
5477
    }
5478
    op = MASK_OP_MAJOR(ctx->opcode);
5479
    rs = (ctx->opcode >> 21) & 0x1f;
5480
    rt = (ctx->opcode >> 16) & 0x1f;
5481
    rd = (ctx->opcode >> 11) & 0x1f;
5482
    sa = (ctx->opcode >> 6) & 0x1f;
5483
    imm = (int16_t)ctx->opcode;
5484
    switch (op) {
5485
    case OPC_SPECIAL:
5486
        op1 = MASK_SPECIAL(ctx->opcode);
5487
        switch (op1) {
5488
        case OPC_SLL:          /* Arithmetic with immediate */
5489
        case OPC_SRL ... OPC_SRA:
5490
            gen_arith_imm(ctx, op1, rd, rt, sa);
5491
            break;
5492
        case OPC_SLLV:         /* Arithmetic */
5493
        case OPC_SRLV ... OPC_SRAV:
5494
        case OPC_MOVZ ... OPC_MOVN:
5495
        case OPC_ADD ... OPC_NOR:
5496
        case OPC_SLT ... OPC_SLTU:
5497
            gen_arith(ctx, op1, rd, rs, rt);
5498
            break;
5499
        case OPC_MULT ... OPC_DIVU:
5500
            gen_muldiv(ctx, op1, rs, rt);
5501
            break;
5502
        case OPC_JR ... OPC_JALR:
5503
            gen_compute_branch(ctx, op1, rs, rd, sa);
5504
            return;
5505
        case OPC_TGE ... OPC_TEQ: /* Traps */
5506
        case OPC_TNE:
5507
            gen_trap(ctx, op1, rs, rt, -1);
5508
            break;
5509
        case OPC_MFHI:          /* Move from HI/LO */
5510
        case OPC_MFLO:
5511
            gen_HILO(ctx, op1, rd);
5512
            break;
5513
        case OPC_MTHI:
5514
        case OPC_MTLO:          /* Move to HI/LO */
5515
            gen_HILO(ctx, op1, rs);
5516
            break;
5517
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5518
#ifdef MIPS_STRICT_STANDARD
5519
            MIPS_INVAL("PMON / selsl");
5520
            generate_exception(ctx, EXCP_RI);
5521
#else
5522
            gen_op_pmon(sa);
5523
#endif
5524
            break;
5525
        case OPC_SYSCALL:
5526
            generate_exception(ctx, EXCP_SYSCALL);
5527
            break;
5528
        case OPC_BREAK:
5529
            generate_exception(ctx, EXCP_BREAK);
5530
            break;
5531
        case OPC_SPIM:
5532
#ifdef MIPS_STRICT_STANDARD
5533
            MIPS_INVAL("SPIM");
5534
            generate_exception(ctx, EXCP_RI);
5535
#else
5536
           /* Implemented as RI exception for now. */
5537
            MIPS_INVAL("spim (unofficial)");
5538
            generate_exception(ctx, EXCP_RI);
5539
#endif
5540
            break;
5541
        case OPC_SYNC:
5542
            /* Treat as a noop. */
5543
            break;
5544

    
5545
        case OPC_MOVCI:
5546
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5547
                save_cpu_state(ctx, 1);
5548
                gen_op_cp1_enabled();
5549
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5550
                          (ctx->opcode >> 16) & 1);
5551
            } else {
5552
                generate_exception_err(ctx, EXCP_CpU, 1);
5553
            }
5554
            break;
5555

    
5556
#ifdef TARGET_MIPS64
5557
       /* MIPS64 specific opcodes */
5558
        case OPC_DSLL:
5559
        case OPC_DSRL ... OPC_DSRA:
5560
        case OPC_DSLL32:
5561
        case OPC_DSRL32 ... OPC_DSRA32:
5562
            gen_arith_imm(ctx, op1, rd, rt, sa);
5563
            break;
5564
        case OPC_DSLLV:
5565
        case OPC_DSRLV ... OPC_DSRAV:
5566
        case OPC_DADD ... OPC_DSUBU:
5567
            gen_arith(ctx, op1, rd, rs, rt);
5568
            break;
5569
        case OPC_DMULT ... OPC_DDIVU:
5570
            gen_muldiv(ctx, op1, rs, rt);
5571
            break;
5572
#endif
5573
        default:            /* Invalid */
5574
            MIPS_INVAL("special");
5575
            generate_exception(ctx, EXCP_RI);
5576
            break;
5577
        }
5578
        break;
5579
    case OPC_SPECIAL2:
5580
        op1 = MASK_SPECIAL2(ctx->opcode);
5581
        switch (op1) {
5582
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5583
        case OPC_MSUB ... OPC_MSUBU:
5584
            gen_muldiv(ctx, op1, rs, rt);
5585
            break;
5586
        case OPC_MUL:
5587
            gen_arith(ctx, op1, rd, rs, rt);
5588
            break;
5589
        case OPC_CLZ ... OPC_CLO:
5590
            gen_cl(ctx, op1, rd, rs);
5591
            break;
5592
        case OPC_SDBBP:
5593
            /* XXX: not clear which exception should be raised
5594
             *      when in debug mode...
5595
             */
5596
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5597
                generate_exception(ctx, EXCP_DBp);
5598
            } else {
5599
                generate_exception(ctx, EXCP_DBp);
5600
            }
5601
            /* Treat as a noop */
5602
            break;
5603
#ifdef TARGET_MIPS64
5604
        case OPC_DCLZ ... OPC_DCLO:
5605
            gen_cl(ctx, op1, rd, rs);
5606
            break;
5607
#endif
5608
        default:            /* Invalid */
5609
            MIPS_INVAL("special2");
5610
            generate_exception(ctx, EXCP_RI);
5611
            break;
5612
        }
5613
        break;
5614
    case OPC_SPECIAL3:
5615
         op1 = MASK_SPECIAL3(ctx->opcode);
5616
         switch (op1) {
5617
         case OPC_EXT:
5618
         case OPC_INS:
5619
             gen_bitops(ctx, op1, rt, rs, sa, rd);
5620
             break;
5621
         case OPC_BSHFL:
5622
             op2 = MASK_BSHFL(ctx->opcode);
5623
             switch (op2) {
5624
             case OPC_WSBH:
5625
                 GEN_LOAD_REG_TN(T1, rt);
5626
                 gen_op_wsbh();
5627
                 break;
5628
             case OPC_SEB:
5629
                 GEN_LOAD_REG_TN(T1, rt);
5630
                 gen_op_seb();
5631
                 break;
5632
             case OPC_SEH:
5633
                 GEN_LOAD_REG_TN(T1, rt);
5634
                 gen_op_seh();
5635
                 break;
5636
             default:            /* Invalid */
5637
                 MIPS_INVAL("bshfl");
5638
                 generate_exception(ctx, EXCP_RI);
5639
                 break;
5640
            }
5641
            GEN_STORE_TN_REG(rd, T0);
5642
            break;
5643
        case OPC_RDHWR:
5644
            switch (rd) {
5645
            case 0:
5646
                save_cpu_state(ctx, 1);
5647
                gen_op_rdhwr_cpunum();
5648
                break;
5649
            case 1:
5650
                save_cpu_state(ctx, 1);
5651
                gen_op_rdhwr_synci_step();
5652
                break;
5653
            case 2:
5654
                save_cpu_state(ctx, 1);
5655
                gen_op_rdhwr_cc();
5656
                break;
5657
            case 3:
5658
                save_cpu_state(ctx, 1);
5659
                gen_op_rdhwr_ccres();
5660
                break;
5661
            case 29:
5662
#if defined (CONFIG_USER_ONLY)
5663
                gen_op_tls_value ();
5664
                break;
5665
#endif
5666
            default:            /* Invalid */
5667
                MIPS_INVAL("rdhwr");
5668
                generate_exception(ctx, EXCP_RI);
5669
                break;
5670
            }
5671
            GEN_STORE_TN_REG(rt, T0);
5672
            break;
5673
#ifdef TARGET_MIPS64
5674
        case OPC_DEXTM ... OPC_DEXT:
5675
        case OPC_DINSM ... OPC_DINS:
5676
            gen_bitops(ctx, op1, rt, rs, sa, rd);
5677
            break;
5678
        case OPC_DBSHFL:
5679
            op2 = MASK_DBSHFL(ctx->opcode);
5680
            switch (op2) {
5681
            case OPC_DSBH:
5682
                GEN_LOAD_REG_TN(T1, rt);
5683
                gen_op_dsbh();
5684
                break;
5685
            case OPC_DSHD:
5686
                GEN_LOAD_REG_TN(T1, rt);
5687
                gen_op_dshd();
5688
                break;
5689
            default:            /* Invalid */
5690
                MIPS_INVAL("dbshfl");
5691
                generate_exception(ctx, EXCP_RI);
5692
                break;
5693
            }
5694
            GEN_STORE_TN_REG(rd, T0);
5695
#endif
5696
        default:            /* Invalid */
5697
            MIPS_INVAL("special3");
5698
            generate_exception(ctx, EXCP_RI);
5699
            break;
5700
        }
5701
        break;
5702
    case OPC_REGIMM:
5703
        op1 = MASK_REGIMM(ctx->opcode);
5704
        switch (op1) {
5705
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5706
        case OPC_BLTZAL ... OPC_BGEZALL:
5707
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
5708
            return;
5709
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5710
        case OPC_TNEI:
5711
            gen_trap(ctx, op1, rs, -1, imm);
5712
            break;
5713
        case OPC_SYNCI:
5714
            /* treat as noop */
5715
            break;
5716
        default:            /* Invalid */
5717
            MIPS_INVAL("regimm");
5718
            generate_exception(ctx, EXCP_RI);
5719
            break;
5720
        }
5721
        break;
5722
    case OPC_CP0:
5723
        save_cpu_state(ctx, 1);
5724
        gen_op_cp0_enabled();
5725
        op1 = MASK_CP0(ctx->opcode);
5726
        switch (op1) {
5727
        case OPC_MFC0:
5728
        case OPC_MTC0:
5729
#ifdef TARGET_MIPS64
5730
        case OPC_DMFC0:
5731
        case OPC_DMTC0:
5732
#endif
5733
            gen_cp0(env, ctx, op1, rt, rd);
5734
            break;
5735
        case OPC_C0_FIRST ... OPC_C0_LAST:
5736
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
5737
            break;
5738
        case OPC_MFMC0:
5739
            op2 = MASK_MFMC0(ctx->opcode);
5740
            switch (op2) {
5741
            case OPC_DI:
5742
                gen_op_di();
5743
                /* Stop translation as we may have switched the execution mode */
5744
                ctx->bstate = BS_STOP;
5745
                break;
5746
            case OPC_EI:
5747
                gen_op_ei();
5748
                /* Stop translation as we may have switched the execution mode */
5749
                ctx->bstate = BS_STOP;
5750
                break;
5751
            default:            /* Invalid */
5752
                MIPS_INVAL("mfmc0");
5753
                generate_exception(ctx, EXCP_RI);
5754
                break;
5755
            }
5756
            GEN_STORE_TN_REG(rt, T0);
5757
            break;
5758
        case OPC_RDPGPR:
5759
        case OPC_WRPGPR:
5760
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5761
                /* Shadow registers not implemented. */
5762
                GEN_LOAD_REG_TN(T0, rt);
5763
                GEN_STORE_TN_REG(rd, T0);
5764
            } else {
5765
                MIPS_INVAL("shadow register move");
5766
                generate_exception(ctx, EXCP_RI);
5767
            }
5768
            break;
5769
        default:
5770
            MIPS_INVAL("cp0");
5771
            generate_exception(ctx, EXCP_RI);
5772
            break;
5773
        }
5774
        break;
5775
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5776
         gen_arith_imm(ctx, op, rt, rs, imm);
5777
         break;
5778
    case OPC_J ... OPC_JAL: /* Jump */
5779
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5780
         gen_compute_branch(ctx, op, rs, rt, offset);
5781
         return;
5782
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
5783
    case OPC_BEQL ... OPC_BGTZL:
5784
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
5785
         return;
5786
    case OPC_LB ... OPC_LWR: /* Load and stores */
5787
    case OPC_SB ... OPC_SW:
5788
    case OPC_SWR:
5789
    case OPC_LL:
5790
    case OPC_SC:
5791
         gen_ldst(ctx, op, rt, rs, imm);
5792
         break;
5793
    case OPC_CACHE:
5794
        /* FIXME: This works around self-modifying code, but only
5795
           if the guest OS handles it properly, and if there's no
5796
           such code executed in uncached space. */
5797
        if (!(rt & 0x3))
5798
            switch ((rt >> 2) & 0x7) {
5799
            case 4:
5800
                GEN_LOAD_REG_TN(T0, rs);
5801
                GEN_LOAD_IMM_TN(T1, imm);
5802
                gen_op_flush_icache_range();
5803
                break;
5804
            case 2:
5805
            case 1:
5806
            case 0:
5807
                /* Can be very inefficient. */
5808
                gen_op_flush_icache_all();
5809
                break;
5810
            default:
5811
                break;
5812
            }
5813
        break;
5814
    case OPC_PREF:
5815
        /* Treat as a noop */
5816
        break;
5817

    
5818
    /* Floating point (COP1). */
5819
    case OPC_LWC1:
5820
    case OPC_LDC1:
5821
    case OPC_SWC1:
5822
    case OPC_SDC1:
5823
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5824
            save_cpu_state(ctx, 1);
5825
            gen_op_cp1_enabled();
5826
            gen_flt_ldst(ctx, op, rt, rs, imm);
5827
        } else {
5828
            generate_exception_err(ctx, EXCP_CpU, 1);
5829
        }
5830
        break;
5831

    
5832
    case OPC_CP1:
5833
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5834
            save_cpu_state(ctx, 1);
5835
            gen_op_cp1_enabled();
5836
            op1 = MASK_CP1(ctx->opcode);
5837
            switch (op1) {
5838
            case OPC_MFC1:
5839
            case OPC_CFC1:
5840
            case OPC_MTC1:
5841
            case OPC_CTC1:
5842
#ifdef TARGET_MIPS64
5843
            case OPC_DMFC1:
5844
            case OPC_DMTC1:
5845
#endif
5846
            case OPC_MFHC1:
5847
            case OPC_MTHC1:
5848
                gen_cp1(ctx, op1, rt, rd);
5849
                break;
5850
            case OPC_BC1:
5851
            case OPC_BC1ANY2:
5852
            case OPC_BC1ANY4:
5853
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5854
                                    (rt >> 2) & 0x7, imm << 2);
5855
                return;
5856
            case OPC_S_FMT:
5857
            case OPC_D_FMT:
5858
            case OPC_W_FMT:
5859
            case OPC_L_FMT:
5860
            case OPC_PS_FMT:
5861
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5862
                           (imm >> 8) & 0x7);
5863
                break;
5864
            default:
5865
                MIPS_INVAL("cp1");
5866
                generate_exception (ctx, EXCP_RI);
5867
                break;
5868
            }
5869
        } else {
5870
            generate_exception_err(ctx, EXCP_CpU, 1);
5871
        }
5872
        break;
5873

    
5874
    /* COP2.  */
5875
    case OPC_LWC2:
5876
    case OPC_LDC2:
5877
    case OPC_SWC2:
5878
    case OPC_SDC2:
5879
    case OPC_CP2:
5880
        /* COP2: Not implemented. */
5881
        generate_exception_err(ctx, EXCP_CpU, 2);
5882
        break;
5883

    
5884
    case OPC_CP3:
5885
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5886
            save_cpu_state(ctx, 1);
5887
            gen_op_cp1_enabled();
5888
            op1 = MASK_CP3(ctx->opcode);
5889
            switch (op1) {
5890
            case OPC_LWXC1:
5891
            case OPC_LDXC1:
5892
            case OPC_LUXC1:
5893
            case OPC_SWXC1:
5894
            case OPC_SDXC1:
5895
            case OPC_SUXC1:
5896
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5897
                break;
5898
            case OPC_PREFX:
5899
                /* treat as noop */
5900
                break;
5901
            case OPC_ALNV_PS:
5902
            case OPC_MADD_S:
5903
            case OPC_MADD_D:
5904
            case OPC_MADD_PS:
5905
            case OPC_MSUB_S:
5906
            case OPC_MSUB_D:
5907
            case OPC_MSUB_PS:
5908
            case OPC_NMADD_S:
5909
            case OPC_NMADD_D:
5910
            case OPC_NMADD_PS:
5911
            case OPC_NMSUB_S:
5912
            case OPC_NMSUB_D:
5913
            case OPC_NMSUB_PS:
5914
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5915
                break;
5916
            default:
5917
                MIPS_INVAL("cp3");
5918
                generate_exception (ctx, EXCP_RI);
5919
                break;
5920
            }
5921
        } else {
5922
            generate_exception_err(ctx, EXCP_CpU, 1);
5923
        }
5924
        break;
5925

    
5926
#ifdef TARGET_MIPS64
5927
    /* MIPS64 opcodes */
5928
    case OPC_LWU:
5929
    case OPC_LDL ... OPC_LDR:
5930
    case OPC_SDL ... OPC_SDR:
5931
    case OPC_LLD:
5932
    case OPC_LD:
5933
    case OPC_SCD:
5934
    case OPC_SD:
5935
        gen_ldst(ctx, op, rt, rs, imm);
5936
        break;
5937
    case OPC_DADDI ... OPC_DADDIU:
5938
        gen_arith_imm(ctx, op, rt, rs, imm);
5939
        break;
5940
#endif
5941
#ifdef MIPS_HAS_MIPS16
5942
    case OPC_JALX:
5943
        /* MIPS16: Not implemented. */
5944
#endif
5945
#ifdef MIPS_HAS_MDMX
5946
    case OPC_MDMX:
5947
        /* MDMX: Not implemented. */
5948
#endif
5949
    default:            /* Invalid */
5950
        MIPS_INVAL("major opcode");
5951
        generate_exception(ctx, EXCP_RI);
5952
        break;
5953
    }
5954
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5955
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5956
        /* Branches completion */
5957
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5958
        ctx->bstate = BS_BRANCH;
5959
        save_cpu_state(ctx, 0);
5960
        switch (hflags) {
5961
        case MIPS_HFLAG_B:
5962
            /* unconditional branch */
5963
            MIPS_DEBUG("unconditional branch");
5964
            gen_goto_tb(ctx, 0, ctx->btarget);
5965
            break;
5966
        case MIPS_HFLAG_BL:
5967
            /* blikely taken case */
5968
            MIPS_DEBUG("blikely branch taken");
5969
            gen_goto_tb(ctx, 0, ctx->btarget);
5970
            break;
5971
        case MIPS_HFLAG_BC:
5972
            /* Conditional branch */
5973
            MIPS_DEBUG("conditional branch");
5974
            {
5975
              int l1;
5976
              l1 = gen_new_label();
5977
              gen_op_jnz_T2(l1);
5978
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5979
              gen_set_label(l1);
5980
              gen_goto_tb(ctx, 0, ctx->btarget);
5981
            }
5982
            break;
5983
        case MIPS_HFLAG_BR:
5984
            /* unconditional branch to register */
5985
            MIPS_DEBUG("branch to register");
5986
            gen_op_breg();
5987
            gen_op_reset_T0();
5988
            gen_op_exit_tb();
5989
            break;
5990
        default:
5991
            MIPS_DEBUG("unknown branch");
5992
            break;
5993
        }
5994
    }
5995
}
5996

    
5997
static inline int
5998
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5999
                                int search_pc)
6000
{
6001
    DisasContext ctx, *ctxp = &ctx;
6002
    target_ulong pc_start;
6003
    uint16_t *gen_opc_end;
6004
    int j, lj = -1;
6005

    
6006
    if (search_pc && loglevel)
6007
        fprintf (logfile, "search pc %d\n", search_pc);
6008

    
6009
    pc_start = tb->pc;
6010
    gen_opc_ptr = gen_opc_buf;
6011
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6012
    gen_opparam_ptr = gen_opparam_buf;
6013
    nb_gen_labels = 0;
6014
    ctx.pc = pc_start;
6015
    ctx.saved_pc = -1;
6016
    ctx.tb = tb;
6017
    ctx.bstate = BS_NONE;
6018
    /* Restore delay slot state from the tb context.  */
6019
    ctx.hflags = tb->flags;
6020
    restore_cpu_state(env, &ctx);
6021
#if defined(CONFIG_USER_ONLY)
6022
    ctx.mem_idx = 0;
6023
#else
6024
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
6025
#endif
6026
#ifdef DEBUG_DISAS
6027
    if (loglevel & CPU_LOG_TB_CPU) {
6028
        fprintf(logfile, "------------------------------------------------\n");
6029
        /* FIXME: This may print out stale hflags from env... */
6030
        cpu_dump_state(env, logfile, fprintf, 0);
6031
    }
6032
#endif
6033
#ifdef MIPS_DEBUG_DISAS
6034
    if (loglevel & CPU_LOG_TB_IN_ASM)
6035
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
6036
                tb, ctx.mem_idx, ctx.hflags);
6037
#endif
6038
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6039
        if (env->nb_breakpoints > 0) {
6040
            for(j = 0; j < env->nb_breakpoints; j++) {
6041
                if (env->breakpoints[j] == ctx.pc) {
6042
                    save_cpu_state(ctxp, 1);
6043
                    ctx.bstate = BS_BRANCH;
6044
                    gen_op_debug();
6045
                    goto done_generating;
6046
                }
6047
            }
6048
        }
6049

    
6050
        if (search_pc) {
6051
            j = gen_opc_ptr - gen_opc_buf;
6052
            if (lj < j) {
6053
                lj++;
6054
                while (lj < j)
6055
                    gen_opc_instr_start[lj++] = 0;
6056
            }
6057
            gen_opc_pc[lj] = ctx.pc;
6058
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6059
            gen_opc_instr_start[lj] = 1;
6060
        }
6061
        ctx.opcode = ldl_code(ctx.pc);
6062
        decode_opc(env, &ctx);
6063
        ctx.pc += 4;
6064

    
6065
        if (env->singlestep_enabled)
6066
            break;
6067

    
6068
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6069
            break;
6070

    
6071
#if defined (MIPS_SINGLE_STEP)
6072
        break;
6073
#endif
6074
    }
6075
    if (env->singlestep_enabled) {
6076
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
6077
        gen_op_debug();
6078
    } else {
6079
        switch (ctx.bstate) {
6080
        case BS_STOP:
6081
            gen_op_interrupt_restart();
6082
            /* Fall through. */
6083
        case BS_NONE:
6084
            save_cpu_state(ctxp, 0);
6085
            gen_goto_tb(&ctx, 0, ctx.pc);
6086
            break;
6087
        case BS_EXCP:
6088
            gen_op_interrupt_restart();
6089
            gen_op_reset_T0();
6090
            gen_op_exit_tb();
6091
            break;
6092
        case BS_BRANCH:
6093
        default:
6094
            break;
6095
        }
6096
    }
6097
done_generating:
6098
    *gen_opc_ptr = INDEX_op_end;
6099
    if (search_pc) {
6100
        j = gen_opc_ptr - gen_opc_buf;
6101
        lj++;
6102
        while (lj <= j)
6103
            gen_opc_instr_start[lj++] = 0;
6104
        tb->size = 0;
6105
    } else {
6106
        tb->size = ctx.pc - pc_start;
6107
    }
6108
#ifdef DEBUG_DISAS
6109
#if defined MIPS_DEBUG_DISAS
6110
    if (loglevel & CPU_LOG_TB_IN_ASM)
6111
        fprintf(logfile, "\n");
6112
#endif
6113
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6114
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6115
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6116
        fprintf(logfile, "\n");
6117
    }
6118
    if (loglevel & CPU_LOG_TB_OP) {
6119
        fprintf(logfile, "OP:\n");
6120
        dump_ops(gen_opc_buf, gen_opparam_buf);
6121
        fprintf(logfile, "\n");
6122
    }
6123
    if (loglevel & CPU_LOG_TB_CPU) {
6124
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6125
    }
6126
#endif
6127
    
6128
    return 0;
6129
}
6130

    
6131
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6132
{
6133
    return gen_intermediate_code_internal(env, tb, 0);
6134
}
6135

    
6136
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6137
{
6138
    return gen_intermediate_code_internal(env, tb, 1);
6139
}
6140

    
6141
void fpu_dump_state(CPUState *env, FILE *f, 
6142
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6143
                    int flags)
6144
{
6145
    int i;
6146
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
6147

    
6148
#define printfpr(fp)                                                        \
6149
    do {                                                                    \
6150
        if (is_fpu64)                                                       \
6151
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6152
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6153
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6154
        else {                                                              \
6155
            fpr_t tmp;                                                      \
6156
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6157
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6158
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6159
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6160
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6161
        }                                                                   \
6162
    } while(0)
6163

    
6164

    
6165
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6166
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6167
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6168
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6169
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
6170
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6171
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6172
        printfpr(&env->fpr[i]);
6173
    }
6174

    
6175
#undef printfpr
6176
}
6177

    
6178
void dump_fpu (CPUState *env)
6179
{
6180
    if (loglevel) { 
6181
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6182
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6183
       fpu_dump_state(env, logfile, fprintf, 0);
6184
    }
6185
}
6186

    
6187
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6188
/* Debug help: The architecture requires 32bit code to maintain proper
6189
   sign-extened values on 64bit machines.  */
6190

    
6191
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6192

    
6193
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6194
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6195
                     int flags)
6196
{
6197
    int i;
6198

    
6199
    if (!SIGN_EXT_P(env->PC))
6200
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6201
    if (!SIGN_EXT_P(env->HI))
6202
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6203
    if (!SIGN_EXT_P(env->LO))
6204
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6205
    if (!SIGN_EXT_P(env->btarget))
6206
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6207

    
6208
    for (i = 0; i < 32; i++) {
6209
        if (!SIGN_EXT_P(env->gpr[i]))
6210
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6211
    }
6212

    
6213
    if (!SIGN_EXT_P(env->CP0_EPC))
6214
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6215
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6216
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6217
}
6218
#endif
6219

    
6220
void cpu_dump_state (CPUState *env, FILE *f, 
6221
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6222
                     int flags)
6223
{
6224
    uint32_t c0_status;
6225
    int i;
6226
    
6227
    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",
6228
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6229
    for (i = 0; i < 32; i++) {
6230
        if ((i & 3) == 0)
6231
            cpu_fprintf(f, "GPR%02d:", i);
6232
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6233
        if ((i & 3) == 3)
6234
            cpu_fprintf(f, "\n");
6235
    }
6236

    
6237
    c0_status = env->CP0_Status;
6238

    
6239
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6240
                c0_status, env->CP0_Cause, env->CP0_EPC);
6241
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6242
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6243
    if (c0_status & (1 << CP0St_CU1))
6244
        fpu_dump_state(env, f, cpu_fprintf, flags);
6245
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6246
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6247
#endif
6248
}
6249

    
6250
CPUMIPSState *cpu_mips_init (void)
6251
{
6252
    CPUMIPSState *env;
6253

    
6254
    env = qemu_mallocz(sizeof(CPUMIPSState));
6255
    if (!env)
6256
        return NULL;
6257
    cpu_exec_init(env);
6258
    cpu_reset(env);
6259
    return env;
6260
}
6261

    
6262
void cpu_reset (CPUMIPSState *env)
6263
{
6264
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6265

    
6266
    tlb_flush(env, 1);
6267

    
6268
    /* Minimal init */
6269
#if !defined(CONFIG_USER_ONLY)
6270
    if (env->hflags & MIPS_HFLAG_BMASK) {
6271
        /* If the exception was raised from a delay slot,
6272
         * come back to the jump.  */
6273
        env->CP0_ErrorEPC = env->PC - 4;
6274
        env->hflags &= ~MIPS_HFLAG_BMASK;
6275
    } else {
6276
        env->CP0_ErrorEPC = env->PC;
6277
    }
6278
    env->hflags = 0;
6279
    env->PC = (int32_t)0xBFC00000;
6280
    env->CP0_Wired = 0;
6281
    /* SMP not implemented */
6282
    env->CP0_EBase = 0x80000000;
6283
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6284
    /* vectored interrupts not implemented, timer on int 7,
6285
       no performance counters. */
6286
    env->CP0_IntCtl = 0xe0000000;
6287
    env->CP0_WatchLo = 0;
6288
    env->CP0_WatchHi = 0;
6289
    /* Count register increments in debug mode, EJTAG version 1 */
6290
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6291
#endif
6292
    env->exception_index = EXCP_NONE;
6293
#if defined(CONFIG_USER_ONLY)
6294
    env->hflags |= MIPS_HFLAG_UM;
6295
    env->user_mode_only = 1;
6296
#endif
6297
}
6298

    
6299
#include "translate_init.c"