Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d26bc211

History | View | Annotate | Download (185.1 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

    
29
#include "cpu.h"
30
#include "exec-all.h"
31
#include "disas.h"
32

    
33
//#define MIPS_DEBUG_DISAS
34
//#define MIPS_DEBUG_SIGN_EXTENSIONS
35
//#define MIPS_SINGLE_STEP
36

    
37
#ifdef USE_DIRECT_JUMP
38
#define TBPARAM(x)
39
#else
40
#define TBPARAM(x) (long)(x)
41
#endif
42

    
43
enum {
44
#define DEF(s, n, copy_size) INDEX_op_ ## s,
45
#include "opc.h"
46
#undef DEF
47
    NB_OPS,
48
};
49

    
50
static uint16_t *gen_opc_ptr;
51
static uint32_t *gen_opparam_ptr;
52

    
53
#include "gen-op.h"
54

    
55
/* MIPS major opcodes */
56
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
57

    
58
enum {
59
    /* indirect opcode tables */
60
    OPC_SPECIAL  = (0x00 << 26),
61
    OPC_REGIMM   = (0x01 << 26),
62
    OPC_CP0      = (0x10 << 26),
63
    OPC_CP1      = (0x11 << 26),
64
    OPC_CP2      = (0x12 << 26),
65
    OPC_CP3      = (0x13 << 26),
66
    OPC_SPECIAL2 = (0x1C << 26),
67
    OPC_SPECIAL3 = (0x1F << 26),
68
    /* arithmetic with immediate */
69
    OPC_ADDI     = (0x08 << 26),
70
    OPC_ADDIU    = (0x09 << 26),
71
    OPC_SLTI     = (0x0A << 26),
72
    OPC_SLTIU    = (0x0B << 26),
73
    OPC_ANDI     = (0x0C << 26),
74
    OPC_ORI      = (0x0D << 26),
75
    OPC_XORI     = (0x0E << 26),
76
    OPC_LUI      = (0x0F << 26),
77
    OPC_DADDI    = (0x18 << 26),
78
    OPC_DADDIU   = (0x19 << 26),
79
    /* Jump and branches */
80
    OPC_J        = (0x02 << 26),
81
    OPC_JAL      = (0x03 << 26),
82
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
83
    OPC_BEQL     = (0x14 << 26),
84
    OPC_BNE      = (0x05 << 26),
85
    OPC_BNEL     = (0x15 << 26),
86
    OPC_BLEZ     = (0x06 << 26),
87
    OPC_BLEZL    = (0x16 << 26),
88
    OPC_BGTZ     = (0x07 << 26),
89
    OPC_BGTZL    = (0x17 << 26),
90
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
91
    /* Load and stores */
92
    OPC_LDL      = (0x1A << 26),
93
    OPC_LDR      = (0x1B << 26),
94
    OPC_LB       = (0x20 << 26),
95
    OPC_LH       = (0x21 << 26),
96
    OPC_LWL      = (0x22 << 26),
97
    OPC_LW       = (0x23 << 26),
98
    OPC_LBU      = (0x24 << 26),
99
    OPC_LHU      = (0x25 << 26),
100
    OPC_LWR      = (0x26 << 26),
101
    OPC_LWU      = (0x27 << 26),
102
    OPC_SB       = (0x28 << 26),
103
    OPC_SH       = (0x29 << 26),
104
    OPC_SWL      = (0x2A << 26),
105
    OPC_SW       = (0x2B << 26),
106
    OPC_SDL      = (0x2C << 26),
107
    OPC_SDR      = (0x2D << 26),
108
    OPC_SWR      = (0x2E << 26),
109
    OPC_LL       = (0x30 << 26),
110
    OPC_LLD      = (0x34 << 26),
111
    OPC_LD       = (0x37 << 26),
112
    OPC_SC       = (0x38 << 26),
113
    OPC_SCD      = (0x3C << 26),
114
    OPC_SD       = (0x3F << 26),
115
    /* Floating point load/store */
116
    OPC_LWC1     = (0x31 << 26),
117
    OPC_LWC2     = (0x32 << 26),
118
    OPC_LDC1     = (0x35 << 26),
119
    OPC_LDC2     = (0x36 << 26),
120
    OPC_SWC1     = (0x39 << 26),
121
    OPC_SWC2     = (0x3A << 26),
122
    OPC_SDC1     = (0x3D << 26),
123
    OPC_SDC2     = (0x3E << 26),
124
    /* MDMX ASE specific */
125
    OPC_MDMX     = (0x1E << 26),
126
    /* Cache and prefetch */
127
    OPC_CACHE    = (0x2F << 26),
128
    OPC_PREF     = (0x33 << 26),
129
    /* Reserved major opcode */
130
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
131
};
132

    
133
/* MIPS special opcodes */
134
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
135

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
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_FORK     = 0x08 | OPC_SPECIAL3,
270
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
271
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
272
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
273
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
274
};
275

    
276
/* BSHFL opcodes */
277
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
278

    
279
enum {
280
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
281
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
282
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
283
};
284

    
285
/* DBSHFL opcodes */
286
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
287

    
288
enum {
289
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
290
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
291
};
292

    
293
/* Coprocessor 0 (rs field) */
294
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
295

    
296
enum {
297
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
298
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
299
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
300
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
301
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
302
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
303
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
304
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
305
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
306
    OPC_C0       = (0x10 << 21) | OPC_CP0,
307
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
308
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
309
};
310

    
311
/* MFMC0 opcodes */
312
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
313

    
314
enum {
315
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
316
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
317
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
318
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
319
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
320
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
321
};
322

    
323
/* Coprocessor 0 (with rs == C0) */
324
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
325

    
326
enum {
327
    OPC_TLBR     = 0x01 | OPC_C0,
328
    OPC_TLBWI    = 0x02 | OPC_C0,
329
    OPC_TLBWR    = 0x06 | OPC_C0,
330
    OPC_TLBP     = 0x08 | OPC_C0,
331
    OPC_RFE      = 0x10 | OPC_C0,
332
    OPC_ERET     = 0x18 | OPC_C0,
333
    OPC_DERET    = 0x1F | OPC_C0,
334
    OPC_WAIT     = 0x20 | OPC_C0,
335
};
336

    
337
/* Coprocessor 1 (rs field) */
338
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
339

    
340
enum {
341
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
342
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
343
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
344
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
345
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
346
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
347
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
348
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
349
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
350
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
351
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
352
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
353
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
354
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
355
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
356
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
357
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
358
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
359
};
360

    
361
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
362
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
363

    
364
enum {
365
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
366
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
367
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
368
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
369
};
370

    
371
enum {
372
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
373
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
374
};
375

    
376
enum {
377
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
378
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
379
};
380

    
381
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
382

    
383
enum {
384
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
385
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
386
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
387
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
388
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
389
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
390
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
391
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
392
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
393
};
394

    
395
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
396

    
397
enum {
398
    OPC_LWXC1   = 0x00 | OPC_CP3,
399
    OPC_LDXC1   = 0x01 | OPC_CP3,
400
    OPC_LUXC1   = 0x05 | OPC_CP3,
401
    OPC_SWXC1   = 0x08 | OPC_CP3,
402
    OPC_SDXC1   = 0x09 | OPC_CP3,
403
    OPC_SUXC1   = 0x0D | OPC_CP3,
404
    OPC_PREFX   = 0x0F | OPC_CP3,
405
    OPC_ALNV_PS = 0x1E | OPC_CP3,
406
    OPC_MADD_S  = 0x20 | OPC_CP3,
407
    OPC_MADD_D  = 0x21 | OPC_CP3,
408
    OPC_MADD_PS = 0x26 | OPC_CP3,
409
    OPC_MSUB_S  = 0x28 | OPC_CP3,
410
    OPC_MSUB_D  = 0x29 | OPC_CP3,
411
    OPC_MSUB_PS = 0x2E | OPC_CP3,
412
    OPC_NMADD_S = 0x30 | OPC_CP3,
413
    OPC_NMADD_D = 0x31 | OPC_CP3,
414
    OPC_NMADD_PS= 0x36 | OPC_CP3,
415
    OPC_NMSUB_S = 0x38 | OPC_CP3,
416
    OPC_NMSUB_D = 0x39 | OPC_CP3,
417
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
418
};
419

    
420

    
421
const unsigned char *regnames[] =
422
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
423
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
424
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
425
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
426

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

    
444
/* General purpose registers moves */
445
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
446
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
447
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
448

    
449
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
450
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
451

    
452
/* Moves to/from shadow registers */
453
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
454
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
455

    
456
static const char *fregnames[] =
457
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
458
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
459
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
460
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
461

    
462
#define FGEN32(func, NAME)                       \
463
static GenOpFunc *NAME ## _table [32] = {        \
464
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
465
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
466
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
467
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
468
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
469
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
470
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
471
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
472
};                                               \
473
static always_inline void func(int n)            \
474
{                                                \
475
    NAME ## _table[n]();                         \
476
}
477

    
478
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
479
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
480

    
481
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
482
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
485
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
486

    
487
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
488
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
489

    
490
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
491
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
492

    
493
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
494
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
495

    
496
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
497
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
498

    
499
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
500
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
501

    
502
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
503
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
504

    
505
#define FOP_CONDS(type, fmt)                                            \
506
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
507
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
508
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
509
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
510
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
511
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
512
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
513
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
514
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
515
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
516
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
517
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
518
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
519
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
520
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
521
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
522
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
523
};                                                                      \
524
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
525
{                                                                       \
526
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
527
}
528

    
529
FOP_CONDS(, d)
530
FOP_CONDS(abs, d)
531
FOP_CONDS(, s)
532
FOP_CONDS(abs, s)
533
FOP_CONDS(, ps)
534
FOP_CONDS(abs, ps)
535

    
536
typedef struct DisasContext {
537
    struct TranslationBlock *tb;
538
    target_ulong pc, saved_pc;
539
    uint32_t opcode;
540
    uint32_t fp_status;
541
    /* Routine used to access memory */
542
    int mem_idx;
543
    uint32_t hflags, saved_hflags;
544
    int bstate;
545
    target_ulong btarget;
546
} DisasContext;
547

    
548
enum {
549
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
550
                      * exception condition
551
                      */
552
    BS_STOP     = 1, /* We want to stop translation for any reason */
553
    BS_BRANCH   = 2, /* We reached a branch condition     */
554
    BS_EXCP     = 3, /* We reached an exception condition */
555
};
556

    
557
#ifdef MIPS_DEBUG_DISAS
558
#define MIPS_DEBUG(fmt, args...)                                              \
559
do {                                                                          \
560
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
561
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
562
                ctx->pc, ctx->opcode , ##args);                               \
563
    }                                                                         \
564
} while (0)
565
#else
566
#define MIPS_DEBUG(fmt, args...) do { } while(0)
567
#endif
568

    
569
#define MIPS_INVAL(op)                                                        \
570
do {                                                                          \
571
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
572
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
573
} while (0)
574

    
575
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
576
do {                                                                          \
577
    if (Rn == 0) {                                                            \
578
        glue(gen_op_reset_, Tn)();                                            \
579
    } else {                                                                  \
580
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
581
    }                                                                         \
582
} while (0)
583

    
584
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
585
do {                                                                          \
586
    if (Rn == 0) {                                                            \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
590
    }                                                                         \
591
} while (0)
592

    
593
#if defined(TARGET_MIPS64)
594
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
595
do {                                                                          \
596
    if (Imm == 0) {                                                           \
597
        glue(gen_op_reset_, Tn)();                                            \
598
    } else if ((int32_t)Imm == Imm) {                                         \
599
        glue(gen_op_set_, Tn)(Imm);                                           \
600
    } else {                                                                  \
601
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
602
    }                                                                         \
603
} while (0)
604
#else
605
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
606
do {                                                                          \
607
    if (Imm == 0) {                                                           \
608
        glue(gen_op_reset_, Tn)();                                            \
609
    } else {                                                                  \
610
        glue(gen_op_set_, Tn)(Imm);                                           \
611
    }                                                                         \
612
} while (0)
613
#endif
614

    
615
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
616
do {                                                                          \
617
    if (Rn != 0) {                                                            \
618
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
619
    }                                                                         \
620
} while (0)
621

    
622
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
623
do {                                                                          \
624
    if (Rn != 0) {                                                            \
625
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
626
    }                                                                         \
627
} while (0)
628

    
629
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
630
do {                                                                          \
631
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
632
} while (0)
633

    
634
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
635
do {                                                                          \
636
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
637
} while (0)
638

    
639
static always_inline void gen_save_pc(target_ulong pc)
640
{
641
#if defined(TARGET_MIPS64)
642
    if (pc == (int32_t)pc) {
643
        gen_op_save_pc(pc);
644
    } else {
645
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
646
    }
647
#else
648
    gen_op_save_pc(pc);
649
#endif
650
}
651

    
652
static always_inline void gen_save_btarget(target_ulong btarget)
653
{
654
#if defined(TARGET_MIPS64)
655
    if (btarget == (int32_t)btarget) {
656
        gen_op_save_btarget(btarget);
657
    } else {
658
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
659
    }
660
#else
661
    gen_op_save_btarget(btarget);
662
#endif
663
}
664

    
665
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
666
{
667
#if defined MIPS_DEBUG_DISAS
668
    if (loglevel & CPU_LOG_TB_IN_ASM) {
669
            fprintf(logfile, "hflags %08x saved %08x\n",
670
                    ctx->hflags, ctx->saved_hflags);
671
    }
672
#endif
673
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
674
        gen_save_pc(ctx->pc);
675
        ctx->saved_pc = ctx->pc;
676
    }
677
    if (ctx->hflags != ctx->saved_hflags) {
678
        gen_op_save_state(ctx->hflags);
679
        ctx->saved_hflags = ctx->hflags;
680
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
681
        case MIPS_HFLAG_BR:
682
            gen_op_save_breg_target();
683
            break;
684
        case MIPS_HFLAG_BC:
685
            gen_op_save_bcond();
686
            /* fall through */
687
        case MIPS_HFLAG_BL:
688
            /* bcond was already saved by the BL insn */
689
            /* fall through */
690
        case MIPS_HFLAG_B:
691
            gen_save_btarget(ctx->btarget);
692
            break;
693
        }
694
    }
695
}
696

    
697
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
698
{
699
    ctx->saved_hflags = ctx->hflags;
700
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
701
    case MIPS_HFLAG_BR:
702
        gen_op_restore_breg_target();
703
        break;
704
    case MIPS_HFLAG_B:
705
        ctx->btarget = env->btarget;
706
        break;
707
    case MIPS_HFLAG_BC:
708
    case MIPS_HFLAG_BL:
709
        ctx->btarget = env->btarget;
710
        gen_op_restore_bcond();
711
        break;
712
    }
713
}
714

    
715
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
716
{
717
#if defined MIPS_DEBUG_DISAS
718
    if (loglevel & CPU_LOG_TB_IN_ASM)
719
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
720
#endif
721
    save_cpu_state(ctx, 1);
722
    if (err == 0)
723
        gen_op_raise_exception(excp);
724
    else
725
        gen_op_raise_exception_err(excp, err);
726
    ctx->bstate = BS_EXCP;
727
}
728

    
729
static always_inline void generate_exception (DisasContext *ctx, int excp)
730
{
731
    generate_exception_err (ctx, excp, 0);
732
}
733

    
734
static always_inline void check_cp0_enabled(DisasContext *ctx)
735
{
736
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
737
        generate_exception_err(ctx, EXCP_CpU, 1);
738
}
739

    
740
static always_inline void check_cp1_enabled(DisasContext *ctx)
741
{
742
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
743
        generate_exception_err(ctx, EXCP_CpU, 1);
744
}
745

    
746
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
747
{
748
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64)))
749
        generate_exception(ctx, EXCP_RI);
750
}
751

    
752
/*
753
 * Verify if floating point register is valid; an operation is not defined
754
 * if bit 0 of any register specification is set and the FR bit in the
755
 * Status register equals zero, since the register numbers specify an
756
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
757
 * in the Status register equals one, both even and odd register numbers
758
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
759
 *
760
 * Multiple 64 bit wide registers can be checked by calling
761
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
762
 */
763
void check_cp1_registers(DisasContext *ctx, int regs)
764
{
765
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
766
        generate_exception(ctx, EXCP_RI);
767
}
768

    
769
/* This code generates a "reserved instruction" exception if the
770
   CPU does not support the instruction set corresponding to flags. */
771
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
772
{
773
    if (unlikely(!(env->insn_flags & flags)))
774
        generate_exception(ctx, EXCP_RI);
775
}
776

    
777
/* This code generates a "reserved instruction" exception if 64-bit
778
   instructions are not enabled. */
779
static always_inline void check_mips_64(DisasContext *ctx)
780
{
781
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
782
        generate_exception(ctx, EXCP_RI);
783
}
784

    
785
#if defined(CONFIG_USER_ONLY)
786
#define op_ldst(name)        gen_op_##name##_raw()
787
#define OP_LD_TABLE(width)
788
#define OP_ST_TABLE(width)
789
#else
790
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
791
#define OP_LD_TABLE(width)                                                    \
792
static GenOpFunc *gen_op_l##width[] = {                                       \
793
    &gen_op_l##width##_kernel,                                                \
794
    &gen_op_l##width##_super,                                                 \
795
    &gen_op_l##width##_user,                                                  \
796
}
797
#define OP_ST_TABLE(width)                                                    \
798
static GenOpFunc *gen_op_s##width[] = {                                       \
799
    &gen_op_s##width##_kernel,                                                \
800
    &gen_op_s##width##_super,                                                 \
801
    &gen_op_s##width##_user,                                                  \
802
}
803
#endif
804

    
805
#if defined(TARGET_MIPS64)
806
OP_LD_TABLE(d);
807
OP_LD_TABLE(dl);
808
OP_LD_TABLE(dr);
809
OP_ST_TABLE(d);
810
OP_ST_TABLE(dl);
811
OP_ST_TABLE(dr);
812
OP_LD_TABLE(ld);
813
OP_ST_TABLE(cd);
814
OP_LD_TABLE(wu);
815
#endif
816
OP_LD_TABLE(w);
817
OP_LD_TABLE(wl);
818
OP_LD_TABLE(wr);
819
OP_ST_TABLE(w);
820
OP_ST_TABLE(wl);
821
OP_ST_TABLE(wr);
822
OP_LD_TABLE(h);
823
OP_LD_TABLE(hu);
824
OP_ST_TABLE(h);
825
OP_LD_TABLE(b);
826
OP_LD_TABLE(bu);
827
OP_ST_TABLE(b);
828
OP_LD_TABLE(l);
829
OP_ST_TABLE(c);
830
OP_LD_TABLE(wc1);
831
OP_ST_TABLE(wc1);
832
OP_LD_TABLE(dc1);
833
OP_ST_TABLE(dc1);
834
OP_LD_TABLE(uxc1);
835
OP_ST_TABLE(uxc1);
836

    
837
/* Load and store */
838
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
839
                      int base, int16_t offset)
840
{
841
    const char *opn = "ldst";
842

    
843
    if (base == 0) {
844
        GEN_LOAD_IMM_TN(T0, offset);
845
    } else if (offset == 0) {
846
        gen_op_load_gpr_T0(base);
847
    } else {
848
        gen_op_load_gpr_T0(base);
849
        gen_op_set_T1(offset);
850
        gen_op_addr_add();
851
    }
852
    /* Don't do NOP if destination is zero: we must perform the actual
853
       memory access. */
854
    switch (opc) {
855
#if defined(TARGET_MIPS64)
856
    case OPC_LWU:
857
        op_ldst(lwu);
858
        GEN_STORE_TN_REG(rt, T0);
859
        opn = "lwu";
860
        break;
861
    case OPC_LD:
862
        op_ldst(ld);
863
        GEN_STORE_TN_REG(rt, T0);
864
        opn = "ld";
865
        break;
866
    case OPC_LLD:
867
        op_ldst(lld);
868
        GEN_STORE_TN_REG(rt, T0);
869
        opn = "lld";
870
        break;
871
    case OPC_SD:
872
        GEN_LOAD_REG_TN(T1, rt);
873
        op_ldst(sd);
874
        opn = "sd";
875
        break;
876
    case OPC_SCD:
877
        save_cpu_state(ctx, 1);
878
        GEN_LOAD_REG_TN(T1, rt);
879
        op_ldst(scd);
880
        GEN_STORE_TN_REG(rt, T0);
881
        opn = "scd";
882
        break;
883
    case OPC_LDL:
884
        GEN_LOAD_REG_TN(T1, rt);
885
        op_ldst(ldl);
886
        GEN_STORE_TN_REG(rt, T1);
887
        opn = "ldl";
888
        break;
889
    case OPC_SDL:
890
        GEN_LOAD_REG_TN(T1, rt);
891
        op_ldst(sdl);
892
        opn = "sdl";
893
        break;
894
    case OPC_LDR:
895
        GEN_LOAD_REG_TN(T1, rt);
896
        op_ldst(ldr);
897
        GEN_STORE_TN_REG(rt, T1);
898
        opn = "ldr";
899
        break;
900
    case OPC_SDR:
901
        GEN_LOAD_REG_TN(T1, rt);
902
        op_ldst(sdr);
903
        opn = "sdr";
904
        break;
905
#endif
906
    case OPC_LW:
907
        op_ldst(lw);
908
        GEN_STORE_TN_REG(rt, T0);
909
        opn = "lw";
910
        break;
911
    case OPC_SW:
912
        GEN_LOAD_REG_TN(T1, rt);
913
        op_ldst(sw);
914
        opn = "sw";
915
        break;
916
    case OPC_LH:
917
        op_ldst(lh);
918
        GEN_STORE_TN_REG(rt, T0);
919
        opn = "lh";
920
        break;
921
    case OPC_SH:
922
        GEN_LOAD_REG_TN(T1, rt);
923
        op_ldst(sh);
924
        opn = "sh";
925
        break;
926
    case OPC_LHU:
927
        op_ldst(lhu);
928
        GEN_STORE_TN_REG(rt, T0);
929
        opn = "lhu";
930
        break;
931
    case OPC_LB:
932
        op_ldst(lb);
933
        GEN_STORE_TN_REG(rt, T0);
934
        opn = "lb";
935
        break;
936
    case OPC_SB:
937
        GEN_LOAD_REG_TN(T1, rt);
938
        op_ldst(sb);
939
        opn = "sb";
940
        break;
941
    case OPC_LBU:
942
        op_ldst(lbu);
943
        GEN_STORE_TN_REG(rt, T0);
944
        opn = "lbu";
945
        break;
946
    case OPC_LWL:
947
        GEN_LOAD_REG_TN(T1, rt);
948
        op_ldst(lwl);
949
        GEN_STORE_TN_REG(rt, T1);
950
        opn = "lwl";
951
        break;
952
    case OPC_SWL:
953
        GEN_LOAD_REG_TN(T1, rt);
954
        op_ldst(swl);
955
        opn = "swr";
956
        break;
957
    case OPC_LWR:
958
        GEN_LOAD_REG_TN(T1, rt);
959
        op_ldst(lwr);
960
        GEN_STORE_TN_REG(rt, T1);
961
        opn = "lwr";
962
        break;
963
    case OPC_SWR:
964
        GEN_LOAD_REG_TN(T1, rt);
965
        op_ldst(swr);
966
        opn = "swr";
967
        break;
968
    case OPC_LL:
969
        op_ldst(ll);
970
        GEN_STORE_TN_REG(rt, T0);
971
        opn = "ll";
972
        break;
973
    case OPC_SC:
974
        save_cpu_state(ctx, 1);
975
        GEN_LOAD_REG_TN(T1, rt);
976
        op_ldst(sc);
977
        GEN_STORE_TN_REG(rt, T0);
978
        opn = "sc";
979
        break;
980
    default:
981
        MIPS_INVAL(opn);
982
        generate_exception(ctx, EXCP_RI);
983
        return;
984
    }
985
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
986
}
987

    
988
/* Load and store */
989
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
990
                      int base, int16_t offset)
991
{
992
    const char *opn = "flt_ldst";
993

    
994
    if (base == 0) {
995
        GEN_LOAD_IMM_TN(T0, offset);
996
    } else if (offset == 0) {
997
        gen_op_load_gpr_T0(base);
998
    } else {
999
        gen_op_load_gpr_T0(base);
1000
        gen_op_set_T1(offset);
1001
        gen_op_addr_add();
1002
    }
1003
    /* Don't do NOP if destination is zero: we must perform the actual
1004
       memory access. */
1005
    switch (opc) {
1006
    case OPC_LWC1:
1007
        op_ldst(lwc1);
1008
        GEN_STORE_FTN_FREG(ft, WT0);
1009
        opn = "lwc1";
1010
        break;
1011
    case OPC_SWC1:
1012
        GEN_LOAD_FREG_FTN(WT0, ft);
1013
        op_ldst(swc1);
1014
        opn = "swc1";
1015
        break;
1016
    case OPC_LDC1:
1017
        op_ldst(ldc1);
1018
        GEN_STORE_FTN_FREG(ft, DT0);
1019
        opn = "ldc1";
1020
        break;
1021
    case OPC_SDC1:
1022
        GEN_LOAD_FREG_FTN(DT0, ft);
1023
        op_ldst(sdc1);
1024
        opn = "sdc1";
1025
        break;
1026
    default:
1027
        MIPS_INVAL(opn);
1028
        generate_exception(ctx, EXCP_RI);
1029
        return;
1030
    }
1031
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1032
}
1033

    
1034
/* Arithmetic with immediate operand */
1035
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1036
                           int rt, int rs, int16_t imm)
1037
{
1038
    target_ulong uimm;
1039
    const char *opn = "imm arith";
1040

    
1041
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1042
        /* If no destination, treat it as a NOP.
1043
           For addi, we must generate the overflow exception when needed. */
1044
        MIPS_DEBUG("NOP");
1045
        return;
1046
    }
1047
    uimm = (uint16_t)imm;
1048
    switch (opc) {
1049
    case OPC_ADDI:
1050
    case OPC_ADDIU:
1051
#if defined(TARGET_MIPS64)
1052
    case OPC_DADDI:
1053
    case OPC_DADDIU:
1054
#endif
1055
    case OPC_SLTI:
1056
    case OPC_SLTIU:
1057
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1058
        /* Fall through. */
1059
    case OPC_ANDI:
1060
    case OPC_ORI:
1061
    case OPC_XORI:
1062
        GEN_LOAD_REG_TN(T0, rs);
1063
        GEN_LOAD_IMM_TN(T1, uimm);
1064
        break;
1065
    case OPC_LUI:
1066
        GEN_LOAD_IMM_TN(T0, imm << 16);
1067
        break;
1068
    case OPC_SLL:
1069
    case OPC_SRA:
1070
    case OPC_SRL:
1071
#if defined(TARGET_MIPS64)
1072
    case OPC_DSLL:
1073
    case OPC_DSRA:
1074
    case OPC_DSRL:
1075
    case OPC_DSLL32:
1076
    case OPC_DSRA32:
1077
    case OPC_DSRL32:
1078
#endif
1079
        uimm &= 0x1f;
1080
        GEN_LOAD_REG_TN(T0, rs);
1081
        GEN_LOAD_IMM_TN(T1, uimm);
1082
        break;
1083
    }
1084
    switch (opc) {
1085
    case OPC_ADDI:
1086
        save_cpu_state(ctx, 1);
1087
        gen_op_addo();
1088
        opn = "addi";
1089
        break;
1090
    case OPC_ADDIU:
1091
        gen_op_add();
1092
        opn = "addiu";
1093
        break;
1094
#if defined(TARGET_MIPS64)
1095
    case OPC_DADDI:
1096
        save_cpu_state(ctx, 1);
1097
        gen_op_daddo();
1098
        opn = "daddi";
1099
        break;
1100
    case OPC_DADDIU:
1101
        gen_op_dadd();
1102
        opn = "daddiu";
1103
        break;
1104
#endif
1105
    case OPC_SLTI:
1106
        gen_op_lt();
1107
        opn = "slti";
1108
        break;
1109
    case OPC_SLTIU:
1110
        gen_op_ltu();
1111
        opn = "sltiu";
1112
        break;
1113
    case OPC_ANDI:
1114
        gen_op_and();
1115
        opn = "andi";
1116
        break;
1117
    case OPC_ORI:
1118
        gen_op_or();
1119
        opn = "ori";
1120
        break;
1121
    case OPC_XORI:
1122
        gen_op_xor();
1123
        opn = "xori";
1124
        break;
1125
    case OPC_LUI:
1126
        opn = "lui";
1127
        break;
1128
    case OPC_SLL:
1129
        gen_op_sll();
1130
        opn = "sll";
1131
        break;
1132
    case OPC_SRA:
1133
        gen_op_sra();
1134
        opn = "sra";
1135
        break;
1136
    case OPC_SRL:
1137
        switch ((ctx->opcode >> 21) & 0x1f) {
1138
        case 0:
1139
            gen_op_srl();
1140
            opn = "srl";
1141
            break;
1142
        case 1:
1143
            /* rotr is decoded as srl on non-R2 CPUs */
1144
            if (env->insn_flags & ISA_MIPS32R2) {
1145
                gen_op_rotr();
1146
                opn = "rotr";
1147
            } else {
1148
                gen_op_srl();
1149
                opn = "srl";
1150
            }
1151
            break;
1152
        default:
1153
            MIPS_INVAL("invalid srl flag");
1154
            generate_exception(ctx, EXCP_RI);
1155
            break;
1156
        }
1157
        break;
1158
#if defined(TARGET_MIPS64)
1159
    case OPC_DSLL:
1160
        gen_op_dsll();
1161
        opn = "dsll";
1162
        break;
1163
    case OPC_DSRA:
1164
        gen_op_dsra();
1165
        opn = "dsra";
1166
        break;
1167
    case OPC_DSRL:
1168
        switch ((ctx->opcode >> 21) & 0x1f) {
1169
        case 0:
1170
            gen_op_dsrl();
1171
            opn = "dsrl";
1172
            break;
1173
        case 1:
1174
            /* drotr is decoded as dsrl on non-R2 CPUs */
1175
            if (env->insn_flags & ISA_MIPS32R2) {
1176
                gen_op_drotr();
1177
                opn = "drotr";
1178
            } else {
1179
                gen_op_dsrl();
1180
                opn = "dsrl";
1181
            }
1182
            break;
1183
        default:
1184
            MIPS_INVAL("invalid dsrl flag");
1185
            generate_exception(ctx, EXCP_RI);
1186
            break;
1187
        }
1188
        break;
1189
    case OPC_DSLL32:
1190
        gen_op_dsll32();
1191
        opn = "dsll32";
1192
        break;
1193
    case OPC_DSRA32:
1194
        gen_op_dsra32();
1195
        opn = "dsra32";
1196
        break;
1197
    case OPC_DSRL32:
1198
        switch ((ctx->opcode >> 21) & 0x1f) {
1199
        case 0:
1200
            gen_op_dsrl32();
1201
            opn = "dsrl32";
1202
            break;
1203
        case 1:
1204
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1205
            if (env->insn_flags & ISA_MIPS32R2) {
1206
                gen_op_drotr32();
1207
                opn = "drotr32";
1208
            } else {
1209
                gen_op_dsrl32();
1210
                opn = "dsrl32";
1211
            }
1212
            break;
1213
        default:
1214
            MIPS_INVAL("invalid dsrl32 flag");
1215
            generate_exception(ctx, EXCP_RI);
1216
            break;
1217
        }
1218
        break;
1219
#endif
1220
    default:
1221
        MIPS_INVAL(opn);
1222
        generate_exception(ctx, EXCP_RI);
1223
        return;
1224
    }
1225
    GEN_STORE_TN_REG(rt, T0);
1226
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1227
}
1228

    
1229
/* Arithmetic */
1230
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1231
                       int rd, int rs, int rt)
1232
{
1233
    const char *opn = "arith";
1234

    
1235
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1236
       && opc != OPC_DADD && opc != OPC_DSUB) {
1237
        /* If no destination, treat it as a NOP.
1238
           For add & sub, we must generate the overflow exception when needed. */
1239
        MIPS_DEBUG("NOP");
1240
        return;
1241
    }
1242
    GEN_LOAD_REG_TN(T0, rs);
1243
    GEN_LOAD_REG_TN(T1, rt);
1244
    switch (opc) {
1245
    case OPC_ADD:
1246
        save_cpu_state(ctx, 1);
1247
        gen_op_addo();
1248
        opn = "add";
1249
        break;
1250
    case OPC_ADDU:
1251
        gen_op_add();
1252
        opn = "addu";
1253
        break;
1254
    case OPC_SUB:
1255
        save_cpu_state(ctx, 1);
1256
        gen_op_subo();
1257
        opn = "sub";
1258
        break;
1259
    case OPC_SUBU:
1260
        gen_op_sub();
1261
        opn = "subu";
1262
        break;
1263
#if defined(TARGET_MIPS64)
1264
    case OPC_DADD:
1265
        save_cpu_state(ctx, 1);
1266
        gen_op_daddo();
1267
        opn = "dadd";
1268
        break;
1269
    case OPC_DADDU:
1270
        gen_op_dadd();
1271
        opn = "daddu";
1272
        break;
1273
    case OPC_DSUB:
1274
        save_cpu_state(ctx, 1);
1275
        gen_op_dsubo();
1276
        opn = "dsub";
1277
        break;
1278
    case OPC_DSUBU:
1279
        gen_op_dsub();
1280
        opn = "dsubu";
1281
        break;
1282
#endif
1283
    case OPC_SLT:
1284
        gen_op_lt();
1285
        opn = "slt";
1286
        break;
1287
    case OPC_SLTU:
1288
        gen_op_ltu();
1289
        opn = "sltu";
1290
        break;
1291
    case OPC_AND:
1292
        gen_op_and();
1293
        opn = "and";
1294
        break;
1295
    case OPC_NOR:
1296
        gen_op_nor();
1297
        opn = "nor";
1298
        break;
1299
    case OPC_OR:
1300
        gen_op_or();
1301
        opn = "or";
1302
        break;
1303
    case OPC_XOR:
1304
        gen_op_xor();
1305
        opn = "xor";
1306
        break;
1307
    case OPC_MUL:
1308
        gen_op_mul();
1309
        opn = "mul";
1310
        break;
1311
    case OPC_MOVN:
1312
        gen_op_movn(rd);
1313
        opn = "movn";
1314
        goto print;
1315
    case OPC_MOVZ:
1316
        gen_op_movz(rd);
1317
        opn = "movz";
1318
        goto print;
1319
    case OPC_SLLV:
1320
        gen_op_sllv();
1321
        opn = "sllv";
1322
        break;
1323
    case OPC_SRAV:
1324
        gen_op_srav();
1325
        opn = "srav";
1326
        break;
1327
    case OPC_SRLV:
1328
        switch ((ctx->opcode >> 6) & 0x1f) {
1329
        case 0:
1330
            gen_op_srlv();
1331
            opn = "srlv";
1332
            break;
1333
        case 1:
1334
            /* rotrv is decoded as srlv on non-R2 CPUs */
1335
            if (env->insn_flags & ISA_MIPS32R2) {
1336
                gen_op_rotrv();
1337
                opn = "rotrv";
1338
            } else {
1339
                gen_op_srlv();
1340
                opn = "srlv";
1341
            }
1342
            break;
1343
        default:
1344
            MIPS_INVAL("invalid srlv flag");
1345
            generate_exception(ctx, EXCP_RI);
1346
            break;
1347
        }
1348
        break;
1349
#if defined(TARGET_MIPS64)
1350
    case OPC_DSLLV:
1351
        gen_op_dsllv();
1352
        opn = "dsllv";
1353
        break;
1354
    case OPC_DSRAV:
1355
        gen_op_dsrav();
1356
        opn = "dsrav";
1357
        break;
1358
    case OPC_DSRLV:
1359
        switch ((ctx->opcode >> 6) & 0x1f) {
1360
        case 0:
1361
            gen_op_dsrlv();
1362
            opn = "dsrlv";
1363
            break;
1364
        case 1:
1365
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1366
            if (env->insn_flags & ISA_MIPS32R2) {
1367
                gen_op_drotrv();
1368
                opn = "drotrv";
1369
            } else {
1370
                gen_op_dsrlv();
1371
                opn = "dsrlv";
1372
            }
1373
            break;
1374
        default:
1375
            MIPS_INVAL("invalid dsrlv flag");
1376
            generate_exception(ctx, EXCP_RI);
1377
            break;
1378
        }
1379
        break;
1380
#endif
1381
    default:
1382
        MIPS_INVAL(opn);
1383
        generate_exception(ctx, EXCP_RI);
1384
        return;
1385
    }
1386
    GEN_STORE_TN_REG(rd, T0);
1387
 print:
1388
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1389
}
1390

    
1391
/* Arithmetic on HI/LO registers */
1392
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1393
{
1394
    const char *opn = "hilo";
1395

    
1396
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1397
        /* Treat as NOP. */
1398
        MIPS_DEBUG("NOP");
1399
        return;
1400
    }
1401
    switch (opc) {
1402
    case OPC_MFHI:
1403
        gen_op_load_HI(0);
1404
        GEN_STORE_TN_REG(reg, T0);
1405
        opn = "mfhi";
1406
        break;
1407
    case OPC_MFLO:
1408
        gen_op_load_LO(0);
1409
        GEN_STORE_TN_REG(reg, T0);
1410
        opn = "mflo";
1411
        break;
1412
    case OPC_MTHI:
1413
        GEN_LOAD_REG_TN(T0, reg);
1414
        gen_op_store_HI(0);
1415
        opn = "mthi";
1416
        break;
1417
    case OPC_MTLO:
1418
        GEN_LOAD_REG_TN(T0, reg);
1419
        gen_op_store_LO(0);
1420
        opn = "mtlo";
1421
        break;
1422
    default:
1423
        MIPS_INVAL(opn);
1424
        generate_exception(ctx, EXCP_RI);
1425
        return;
1426
    }
1427
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1428
}
1429

    
1430
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1431
                        int rs, int rt)
1432
{
1433
    const char *opn = "mul/div";
1434

    
1435
    GEN_LOAD_REG_TN(T0, rs);
1436
    GEN_LOAD_REG_TN(T1, rt);
1437
    switch (opc) {
1438
    case OPC_DIV:
1439
        gen_op_div();
1440
        opn = "div";
1441
        break;
1442
    case OPC_DIVU:
1443
        gen_op_divu();
1444
        opn = "divu";
1445
        break;
1446
    case OPC_MULT:
1447
        gen_op_mult();
1448
        opn = "mult";
1449
        break;
1450
    case OPC_MULTU:
1451
        gen_op_multu();
1452
        opn = "multu";
1453
        break;
1454
#if defined(TARGET_MIPS64)
1455
    case OPC_DDIV:
1456
        gen_op_ddiv();
1457
        opn = "ddiv";
1458
        break;
1459
    case OPC_DDIVU:
1460
        gen_op_ddivu();
1461
        opn = "ddivu";
1462
        break;
1463
    case OPC_DMULT:
1464
        gen_op_dmult();
1465
        opn = "dmult";
1466
        break;
1467
    case OPC_DMULTU:
1468
        gen_op_dmultu();
1469
        opn = "dmultu";
1470
        break;
1471
#endif
1472
    case OPC_MADD:
1473
        gen_op_madd();
1474
        opn = "madd";
1475
        break;
1476
    case OPC_MADDU:
1477
        gen_op_maddu();
1478
        opn = "maddu";
1479
        break;
1480
    case OPC_MSUB:
1481
        gen_op_msub();
1482
        opn = "msub";
1483
        break;
1484
    case OPC_MSUBU:
1485
        gen_op_msubu();
1486
        opn = "msubu";
1487
        break;
1488
    default:
1489
        MIPS_INVAL(opn);
1490
        generate_exception(ctx, EXCP_RI);
1491
        return;
1492
    }
1493
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1494
}
1495

    
1496
static void gen_cl (DisasContext *ctx, uint32_t opc,
1497
                    int rd, int rs)
1498
{
1499
    const char *opn = "CLx";
1500
    if (rd == 0) {
1501
        /* Treat as NOP. */
1502
        MIPS_DEBUG("NOP");
1503
        return;
1504
    }
1505
    GEN_LOAD_REG_TN(T0, rs);
1506
    switch (opc) {
1507
    case OPC_CLO:
1508
        gen_op_clo();
1509
        opn = "clo";
1510
        break;
1511
    case OPC_CLZ:
1512
        gen_op_clz();
1513
        opn = "clz";
1514
        break;
1515
#if defined(TARGET_MIPS64)
1516
    case OPC_DCLO:
1517
        gen_op_dclo();
1518
        opn = "dclo";
1519
        break;
1520
    case OPC_DCLZ:
1521
        gen_op_dclz();
1522
        opn = "dclz";
1523
        break;
1524
#endif
1525
    default:
1526
        MIPS_INVAL(opn);
1527
        generate_exception(ctx, EXCP_RI);
1528
        return;
1529
    }
1530
    gen_op_store_T0_gpr(rd);
1531
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1532
}
1533

    
1534
/* Traps */
1535
static void gen_trap (DisasContext *ctx, uint32_t opc,
1536
                      int rs, int rt, int16_t imm)
1537
{
1538
    int cond;
1539

    
1540
    cond = 0;
1541
    /* Load needed operands */
1542
    switch (opc) {
1543
    case OPC_TEQ:
1544
    case OPC_TGE:
1545
    case OPC_TGEU:
1546
    case OPC_TLT:
1547
    case OPC_TLTU:
1548
    case OPC_TNE:
1549
        /* Compare two registers */
1550
        if (rs != rt) {
1551
            GEN_LOAD_REG_TN(T0, rs);
1552
            GEN_LOAD_REG_TN(T1, rt);
1553
            cond = 1;
1554
        }
1555
        break;
1556
    case OPC_TEQI:
1557
    case OPC_TGEI:
1558
    case OPC_TGEIU:
1559
    case OPC_TLTI:
1560
    case OPC_TLTIU:
1561
    case OPC_TNEI:
1562
        /* Compare register to immediate */
1563
        if (rs != 0 || imm != 0) {
1564
            GEN_LOAD_REG_TN(T0, rs);
1565
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1566
            cond = 1;
1567
        }
1568
        break;
1569
    }
1570
    if (cond == 0) {
1571
        switch (opc) {
1572
        case OPC_TEQ:   /* rs == rs */
1573
        case OPC_TEQI:  /* r0 == 0  */
1574
        case OPC_TGE:   /* rs >= rs */
1575
        case OPC_TGEI:  /* r0 >= 0  */
1576
        case OPC_TGEU:  /* rs >= rs unsigned */
1577
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1578
            /* Always trap */
1579
            gen_op_set_T0(1);
1580
            break;
1581
        case OPC_TLT:   /* rs < rs           */
1582
        case OPC_TLTI:  /* r0 < 0            */
1583
        case OPC_TLTU:  /* rs < rs unsigned  */
1584
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1585
        case OPC_TNE:   /* rs != rs          */
1586
        case OPC_TNEI:  /* r0 != 0           */
1587
            /* Never trap: treat as NOP. */
1588
            return;
1589
        default:
1590
            MIPS_INVAL("trap");
1591
            generate_exception(ctx, EXCP_RI);
1592
            return;
1593
        }
1594
    } else {
1595
        switch (opc) {
1596
        case OPC_TEQ:
1597
        case OPC_TEQI:
1598
            gen_op_eq();
1599
            break;
1600
        case OPC_TGE:
1601
        case OPC_TGEI:
1602
            gen_op_ge();
1603
            break;
1604
        case OPC_TGEU:
1605
        case OPC_TGEIU:
1606
            gen_op_geu();
1607
            break;
1608
        case OPC_TLT:
1609
        case OPC_TLTI:
1610
            gen_op_lt();
1611
            break;
1612
        case OPC_TLTU:
1613
        case OPC_TLTIU:
1614
            gen_op_ltu();
1615
            break;
1616
        case OPC_TNE:
1617
        case OPC_TNEI:
1618
            gen_op_ne();
1619
            break;
1620
        default:
1621
            MIPS_INVAL("trap");
1622
            generate_exception(ctx, EXCP_RI);
1623
            return;
1624
        }
1625
    }
1626
    save_cpu_state(ctx, 1);
1627
    gen_op_trap();
1628
    ctx->bstate = BS_STOP;
1629
}
1630

    
1631
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1632
{
1633
    TranslationBlock *tb;
1634
    tb = ctx->tb;
1635
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1636
        if (n == 0)
1637
            gen_op_goto_tb0(TBPARAM(tb));
1638
        else
1639
            gen_op_goto_tb1(TBPARAM(tb));
1640
        gen_save_pc(dest);
1641
        gen_op_set_T0((long)tb + n);
1642
    } else {
1643
        gen_save_pc(dest);
1644
        gen_op_reset_T0();
1645
    }
1646
    gen_op_exit_tb();
1647
}
1648

    
1649
/* Branches (before delay slot) */
1650
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1651
                                int rs, int rt, int32_t offset)
1652
{
1653
    target_ulong btarget = -1;
1654
    int blink = 0;
1655
    int bcond = 0;
1656

    
1657
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1658
#ifdef MIPS_DEBUG_DISAS
1659
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1660
            fprintf(logfile,
1661
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1662
                    ctx->pc);
1663
        }
1664
#endif
1665
        generate_exception(ctx, EXCP_RI);
1666
        return;
1667
    }
1668

    
1669
    /* Load needed operands */
1670
    switch (opc) {
1671
    case OPC_BEQ:
1672
    case OPC_BEQL:
1673
    case OPC_BNE:
1674
    case OPC_BNEL:
1675
        /* Compare two registers */
1676
        if (rs != rt) {
1677
            GEN_LOAD_REG_TN(T0, rs);
1678
            GEN_LOAD_REG_TN(T1, rt);
1679
            bcond = 1;
1680
        }
1681
        btarget = ctx->pc + 4 + offset;
1682
        break;
1683
    case OPC_BGEZ:
1684
    case OPC_BGEZAL:
1685
    case OPC_BGEZALL:
1686
    case OPC_BGEZL:
1687
    case OPC_BGTZ:
1688
    case OPC_BGTZL:
1689
    case OPC_BLEZ:
1690
    case OPC_BLEZL:
1691
    case OPC_BLTZ:
1692
    case OPC_BLTZAL:
1693
    case OPC_BLTZALL:
1694
    case OPC_BLTZL:
1695
        /* Compare to zero */
1696
        if (rs != 0) {
1697
            gen_op_load_gpr_T0(rs);
1698
            bcond = 1;
1699
        }
1700
        btarget = ctx->pc + 4 + offset;
1701
        break;
1702
    case OPC_J:
1703
    case OPC_JAL:
1704
        /* Jump to immediate */
1705
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1706
        break;
1707
    case OPC_JR:
1708
    case OPC_JALR:
1709
        /* Jump to register */
1710
        if (offset != 0 && offset != 16) {
1711
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1712
               others are reserved. */
1713
            MIPS_INVAL("jump hint");
1714
            generate_exception(ctx, EXCP_RI);
1715
            return;
1716
        }
1717
        GEN_LOAD_REG_TN(T2, rs);
1718
        break;
1719
    default:
1720
        MIPS_INVAL("branch/jump");
1721
        generate_exception(ctx, EXCP_RI);
1722
        return;
1723
    }
1724
    if (bcond == 0) {
1725
        /* No condition to be computed */
1726
        switch (opc) {
1727
        case OPC_BEQ:     /* rx == rx        */
1728
        case OPC_BEQL:    /* rx == rx likely */
1729
        case OPC_BGEZ:    /* 0 >= 0          */
1730
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1731
        case OPC_BLEZ:    /* 0 <= 0          */
1732
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1733
            /* Always take */
1734
            ctx->hflags |= MIPS_HFLAG_B;
1735
            MIPS_DEBUG("balways");
1736
            break;
1737
        case OPC_BGEZAL:  /* 0 >= 0          */
1738
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1739
            /* Always take and link */
1740
            blink = 31;
1741
            ctx->hflags |= MIPS_HFLAG_B;
1742
            MIPS_DEBUG("balways and link");
1743
            break;
1744
        case OPC_BNE:     /* rx != rx        */
1745
        case OPC_BGTZ:    /* 0 > 0           */
1746
        case OPC_BLTZ:    /* 0 < 0           */
1747
            /* Treat as NOP. */
1748
            MIPS_DEBUG("bnever (NOP)");
1749
            return;
1750
        case OPC_BLTZAL:  /* 0 < 0           */
1751
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1752
            gen_op_store_T0_gpr(31);
1753
            MIPS_DEBUG("bnever and link");
1754
            return;
1755
        case OPC_BLTZALL: /* 0 < 0 likely */
1756
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1757
            gen_op_store_T0_gpr(31);
1758
            /* Skip the instruction in the delay slot */
1759
            MIPS_DEBUG("bnever, link and skip");
1760
            ctx->pc += 4;
1761
            return;
1762
        case OPC_BNEL:    /* rx != rx likely */
1763
        case OPC_BGTZL:   /* 0 > 0 likely */
1764
        case OPC_BLTZL:   /* 0 < 0 likely */
1765
            /* Skip the instruction in the delay slot */
1766
            MIPS_DEBUG("bnever and skip");
1767
            ctx->pc += 4;
1768
            return;
1769
        case OPC_J:
1770
            ctx->hflags |= MIPS_HFLAG_B;
1771
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1772
            break;
1773
        case OPC_JAL:
1774
            blink = 31;
1775
            ctx->hflags |= MIPS_HFLAG_B;
1776
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1777
            break;
1778
        case OPC_JR:
1779
            ctx->hflags |= MIPS_HFLAG_BR;
1780
            MIPS_DEBUG("jr %s", regnames[rs]);
1781
            break;
1782
        case OPC_JALR:
1783
            blink = rt;
1784
            ctx->hflags |= MIPS_HFLAG_BR;
1785
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1786
            break;
1787
        default:
1788
            MIPS_INVAL("branch/jump");
1789
            generate_exception(ctx, EXCP_RI);
1790
            return;
1791
        }
1792
    } else {
1793
        switch (opc) {
1794
        case OPC_BEQ:
1795
            gen_op_eq();
1796
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1797
                       regnames[rs], regnames[rt], btarget);
1798
            goto not_likely;
1799
        case OPC_BEQL:
1800
            gen_op_eq();
1801
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1802
                       regnames[rs], regnames[rt], btarget);
1803
            goto likely;
1804
        case OPC_BNE:
1805
            gen_op_ne();
1806
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1807
                       regnames[rs], regnames[rt], btarget);
1808
            goto not_likely;
1809
        case OPC_BNEL:
1810
            gen_op_ne();
1811
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1812
                       regnames[rs], regnames[rt], btarget);
1813
            goto likely;
1814
        case OPC_BGEZ:
1815
            gen_op_gez();
1816
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1817
            goto not_likely;
1818
        case OPC_BGEZL:
1819
            gen_op_gez();
1820
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1821
            goto likely;
1822
        case OPC_BGEZAL:
1823
            gen_op_gez();
1824
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1825
            blink = 31;
1826
            goto not_likely;
1827
        case OPC_BGEZALL:
1828
            gen_op_gez();
1829
            blink = 31;
1830
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1831
            goto likely;
1832
        case OPC_BGTZ:
1833
            gen_op_gtz();
1834
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1835
            goto not_likely;
1836
        case OPC_BGTZL:
1837
            gen_op_gtz();
1838
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1839
            goto likely;
1840
        case OPC_BLEZ:
1841
            gen_op_lez();
1842
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1843
            goto not_likely;
1844
        case OPC_BLEZL:
1845
            gen_op_lez();
1846
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1847
            goto likely;
1848
        case OPC_BLTZ:
1849
            gen_op_ltz();
1850
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1851
            goto not_likely;
1852
        case OPC_BLTZL:
1853
            gen_op_ltz();
1854
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1855
            goto likely;
1856
        case OPC_BLTZAL:
1857
            gen_op_ltz();
1858
            blink = 31;
1859
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1860
        not_likely:
1861
            ctx->hflags |= MIPS_HFLAG_BC;
1862
            gen_op_set_bcond();
1863
            break;
1864
        case OPC_BLTZALL:
1865
            gen_op_ltz();
1866
            blink = 31;
1867
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1868
        likely:
1869
            ctx->hflags |= MIPS_HFLAG_BL;
1870
            gen_op_set_bcond();
1871
            gen_op_save_bcond();
1872
            break;
1873
        default:
1874
            MIPS_INVAL("conditional branch/jump");
1875
            generate_exception(ctx, EXCP_RI);
1876
            return;
1877
        }
1878
    }
1879
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1880
               blink, ctx->hflags, btarget);
1881

    
1882
    ctx->btarget = btarget;
1883
    if (blink > 0) {
1884
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1885
        gen_op_store_T0_gpr(blink);
1886
    }
1887
}
1888

    
1889
/* special3 bitfield operations */
1890
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1891
                       int rs, int lsb, int msb)
1892
{
1893
    GEN_LOAD_REG_TN(T1, rs);
1894
    switch (opc) {
1895
    case OPC_EXT:
1896
        if (lsb + msb > 31)
1897
            goto fail;
1898
        gen_op_ext(lsb, msb + 1);
1899
        break;
1900
    case OPC_DEXTM:
1901
        if (lsb + msb > 63)
1902
            goto fail;
1903
        gen_op_ext(lsb, msb + 1 + 32);
1904
        break;
1905
    case OPC_DEXTU:
1906
        if (lsb + msb > 63)
1907
            goto fail;
1908
        gen_op_ext(lsb + 32, msb + 1);
1909
        break;
1910
    case OPC_DEXT:
1911
        gen_op_ext(lsb, msb + 1);
1912
        break;
1913
    case OPC_INS:
1914
        if (lsb > msb)
1915
            goto fail;
1916
        GEN_LOAD_REG_TN(T0, rt);
1917
        gen_op_ins(lsb, msb - lsb + 1);
1918
        break;
1919
    case OPC_DINSM:
1920
        if (lsb > msb)
1921
            goto fail;
1922
        GEN_LOAD_REG_TN(T0, rt);
1923
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1924
        break;
1925
    case OPC_DINSU:
1926
        if (lsb > msb)
1927
            goto fail;
1928
        GEN_LOAD_REG_TN(T0, rt);
1929
        gen_op_ins(lsb + 32, msb - lsb + 1);
1930
        break;
1931
    case OPC_DINS:
1932
        if (lsb > msb)
1933
            goto fail;
1934
        GEN_LOAD_REG_TN(T0, rt);
1935
        gen_op_ins(lsb, msb - lsb + 1);
1936
        break;
1937
    default:
1938
fail:
1939
        MIPS_INVAL("bitops");
1940
        generate_exception(ctx, EXCP_RI);
1941
        return;
1942
    }
1943
    GEN_STORE_TN_REG(rt, T0);
1944
}
1945

    
1946
/* CP0 (MMU and control) */
1947
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1948
{
1949
    const char *rn = "invalid";
1950

    
1951
    if (sel != 0)
1952
        check_insn(env, ctx, ISA_MIPS32);
1953

    
1954
    switch (reg) {
1955
    case 0:
1956
        switch (sel) {
1957
        case 0:
1958
            gen_op_mfc0_index();
1959
            rn = "Index";
1960
            break;
1961
        case 1:
1962
            check_insn(env, ctx, ASE_MT);
1963
            gen_op_mfc0_mvpcontrol();
1964
            rn = "MVPControl";
1965
            break;
1966
        case 2:
1967
            check_insn(env, ctx, ASE_MT);
1968
            gen_op_mfc0_mvpconf0();
1969
            rn = "MVPConf0";
1970
            break;
1971
        case 3:
1972
            check_insn(env, ctx, ASE_MT);
1973
            gen_op_mfc0_mvpconf1();
1974
            rn = "MVPConf1";
1975
            break;
1976
        default:
1977
            goto die;
1978
        }
1979
        break;
1980
    case 1:
1981
        switch (sel) {
1982
        case 0:
1983
            gen_op_mfc0_random();
1984
            rn = "Random";
1985
            break;
1986
        case 1:
1987
            check_insn(env, ctx, ASE_MT);
1988
            gen_op_mfc0_vpecontrol();
1989
            rn = "VPEControl";
1990
            break;
1991
        case 2:
1992
            check_insn(env, ctx, ASE_MT);
1993
            gen_op_mfc0_vpeconf0();
1994
            rn = "VPEConf0";
1995
            break;
1996
        case 3:
1997
            check_insn(env, ctx, ASE_MT);
1998
            gen_op_mfc0_vpeconf1();
1999
            rn = "VPEConf1";
2000
            break;
2001
        case 4:
2002
            check_insn(env, ctx, ASE_MT);
2003
            gen_op_mfc0_yqmask();
2004
            rn = "YQMask";
2005
            break;
2006
        case 5:
2007
            check_insn(env, ctx, ASE_MT);
2008
            gen_op_mfc0_vpeschedule();
2009
            rn = "VPESchedule";
2010
            break;
2011
        case 6:
2012
            check_insn(env, ctx, ASE_MT);
2013
            gen_op_mfc0_vpeschefback();
2014
            rn = "VPEScheFBack";
2015
            break;
2016
        case 7:
2017
            check_insn(env, ctx, ASE_MT);
2018
            gen_op_mfc0_vpeopt();
2019
            rn = "VPEOpt";
2020
            break;
2021
        default:
2022
            goto die;
2023
        }
2024
        break;
2025
    case 2:
2026
        switch (sel) {
2027
        case 0:
2028
            gen_op_mfc0_entrylo0();
2029
            rn = "EntryLo0";
2030
            break;
2031
        case 1:
2032
            check_insn(env, ctx, ASE_MT);
2033
            gen_op_mfc0_tcstatus();
2034
            rn = "TCStatus";
2035
            break;
2036
        case 2:
2037
            check_insn(env, ctx, ASE_MT);
2038
            gen_op_mfc0_tcbind();
2039
            rn = "TCBind";
2040
            break;
2041
        case 3:
2042
            check_insn(env, ctx, ASE_MT);
2043
            gen_op_mfc0_tcrestart();
2044
            rn = "TCRestart";
2045
            break;
2046
        case 4:
2047
            check_insn(env, ctx, ASE_MT);
2048
            gen_op_mfc0_tchalt();
2049
            rn = "TCHalt";
2050
            break;
2051
        case 5:
2052
            check_insn(env, ctx, ASE_MT);
2053
            gen_op_mfc0_tccontext();
2054
            rn = "TCContext";
2055
            break;
2056
        case 6:
2057
            check_insn(env, ctx, ASE_MT);
2058
            gen_op_mfc0_tcschedule();
2059
            rn = "TCSchedule";
2060
            break;
2061
        case 7:
2062
            check_insn(env, ctx, ASE_MT);
2063
            gen_op_mfc0_tcschefback();
2064
            rn = "TCScheFBack";
2065
            break;
2066
        default:
2067
            goto die;
2068
        }
2069
        break;
2070
    case 3:
2071
        switch (sel) {
2072
        case 0:
2073
            gen_op_mfc0_entrylo1();
2074
            rn = "EntryLo1";
2075
            break;
2076
        default:
2077
            goto die;
2078
        }
2079
        break;
2080
    case 4:
2081
        switch (sel) {
2082
        case 0:
2083
            gen_op_mfc0_context();
2084
            rn = "Context";
2085
            break;
2086
        case 1:
2087
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2088
            rn = "ContextConfig";
2089
//            break;
2090
        default:
2091
            goto die;
2092
        }
2093
        break;
2094
    case 5:
2095
        switch (sel) {
2096
        case 0:
2097
            gen_op_mfc0_pagemask();
2098
            rn = "PageMask";
2099
            break;
2100
        case 1:
2101
            check_insn(env, ctx, ISA_MIPS32R2);
2102
            gen_op_mfc0_pagegrain();
2103
            rn = "PageGrain";
2104
            break;
2105
        default:
2106
            goto die;
2107
        }
2108
        break;
2109
    case 6:
2110
        switch (sel) {
2111
        case 0:
2112
            gen_op_mfc0_wired();
2113
            rn = "Wired";
2114
            break;
2115
        case 1:
2116
            check_insn(env, ctx, ISA_MIPS32R2);
2117
            gen_op_mfc0_srsconf0();
2118
            rn = "SRSConf0";
2119
            break;
2120
        case 2:
2121
            check_insn(env, ctx, ISA_MIPS32R2);
2122
            gen_op_mfc0_srsconf1();
2123
            rn = "SRSConf1";
2124
            break;
2125
        case 3:
2126
            check_insn(env, ctx, ISA_MIPS32R2);
2127
            gen_op_mfc0_srsconf2();
2128
            rn = "SRSConf2";
2129
            break;
2130
        case 4:
2131
            check_insn(env, ctx, ISA_MIPS32R2);
2132
            gen_op_mfc0_srsconf3();
2133
            rn = "SRSConf3";
2134
            break;
2135
        case 5:
2136
            check_insn(env, ctx, ISA_MIPS32R2);
2137
            gen_op_mfc0_srsconf4();
2138
            rn = "SRSConf4";
2139
            break;
2140
        default:
2141
            goto die;
2142
        }
2143
        break;
2144
    case 7:
2145
        switch (sel) {
2146
        case 0:
2147
            check_insn(env, ctx, ISA_MIPS32R2);
2148
            gen_op_mfc0_hwrena();
2149
            rn = "HWREna";
2150
            break;
2151
        default:
2152
            goto die;
2153
        }
2154
        break;
2155
    case 8:
2156
        switch (sel) {
2157
        case 0:
2158
            gen_op_mfc0_badvaddr();
2159
            rn = "BadVaddr";
2160
            break;
2161
        default:
2162
            goto die;
2163
       }
2164
        break;
2165
    case 9:
2166
        switch (sel) {
2167
        case 0:
2168
            gen_op_mfc0_count();
2169
            rn = "Count";
2170
            break;
2171
        /* 6,7 are implementation dependent */
2172
        default:
2173
            goto die;
2174
        }
2175
        break;
2176
    case 10:
2177
        switch (sel) {
2178
        case 0:
2179
            gen_op_mfc0_entryhi();
2180
            rn = "EntryHi";
2181
            break;
2182
        default:
2183
            goto die;
2184
        }
2185
        break;
2186
    case 11:
2187
        switch (sel) {
2188
        case 0:
2189
            gen_op_mfc0_compare();
2190
            rn = "Compare";
2191
            break;
2192
        /* 6,7 are implementation dependent */
2193
        default:
2194
            goto die;
2195
        }
2196
        break;
2197
    case 12:
2198
        switch (sel) {
2199
        case 0:
2200
            gen_op_mfc0_status();
2201
            rn = "Status";
2202
            break;
2203
        case 1:
2204
            check_insn(env, ctx, ISA_MIPS32R2);
2205
            gen_op_mfc0_intctl();
2206
            rn = "IntCtl";
2207
            break;
2208
        case 2:
2209
            check_insn(env, ctx, ISA_MIPS32R2);
2210
            gen_op_mfc0_srsctl();
2211
            rn = "SRSCtl";
2212
            break;
2213
        case 3:
2214
            check_insn(env, ctx, ISA_MIPS32R2);
2215
            gen_op_mfc0_srsmap();
2216
            rn = "SRSMap";
2217
            break;
2218
        default:
2219
            goto die;
2220
       }
2221
        break;
2222
    case 13:
2223
        switch (sel) {
2224
        case 0:
2225
            gen_op_mfc0_cause();
2226
            rn = "Cause";
2227
            break;
2228
        default:
2229
            goto die;
2230
       }
2231
        break;
2232
    case 14:
2233
        switch (sel) {
2234
        case 0:
2235
            gen_op_mfc0_epc();
2236
            rn = "EPC";
2237
            break;
2238
        default:
2239
            goto die;
2240
        }
2241
        break;
2242
    case 15:
2243
        switch (sel) {
2244
        case 0:
2245
            gen_op_mfc0_prid();
2246
            rn = "PRid";
2247
            break;
2248
        case 1:
2249
            check_insn(env, ctx, ISA_MIPS32R2);
2250
            gen_op_mfc0_ebase();
2251
            rn = "EBase";
2252
            break;
2253
        default:
2254
            goto die;
2255
       }
2256
        break;
2257
    case 16:
2258
        switch (sel) {
2259
        case 0:
2260
            gen_op_mfc0_config0();
2261
            rn = "Config";
2262
            break;
2263
        case 1:
2264
            gen_op_mfc0_config1();
2265
            rn = "Config1";
2266
            break;
2267
        case 2:
2268
            gen_op_mfc0_config2();
2269
            rn = "Config2";
2270
            break;
2271
        case 3:
2272
            gen_op_mfc0_config3();
2273
            rn = "Config3";
2274
            break;
2275
        /* 4,5 are reserved */
2276
        /* 6,7 are implementation dependent */
2277
        case 6:
2278
            gen_op_mfc0_config6();
2279
            rn = "Config6";
2280
            break;
2281
        case 7:
2282
            gen_op_mfc0_config7();
2283
            rn = "Config7";
2284
            break;
2285
        default:
2286
            goto die;
2287
        }
2288
        break;
2289
    case 17:
2290
        switch (sel) {
2291
        case 0:
2292
            gen_op_mfc0_lladdr();
2293
            rn = "LLAddr";
2294
            break;
2295
        default:
2296
            goto die;
2297
        }
2298
        break;
2299
    case 18:
2300
        switch (sel) {
2301
        case 0 ... 7:
2302
            gen_op_mfc0_watchlo(sel);
2303
            rn = "WatchLo";
2304
            break;
2305
        default:
2306
            goto die;
2307
        }
2308
        break;
2309
    case 19:
2310
        switch (sel) {
2311
        case 0 ...7:
2312
            gen_op_mfc0_watchhi(sel);
2313
            rn = "WatchHi";
2314
            break;
2315
        default:
2316
            goto die;
2317
        }
2318
        break;
2319
    case 20:
2320
        switch (sel) {
2321
        case 0:
2322
#if defined(TARGET_MIPS64)
2323
            check_insn(env, ctx, ISA_MIPS3);
2324
            gen_op_mfc0_xcontext();
2325
            rn = "XContext";
2326
            break;
2327
#endif
2328
        default:
2329
            goto die;
2330
        }
2331
        break;
2332
    case 21:
2333
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2334
        switch (sel) {
2335
        case 0:
2336
            gen_op_mfc0_framemask();
2337
            rn = "Framemask";
2338
            break;
2339
        default:
2340
            goto die;
2341
        }
2342
        break;
2343
    case 22:
2344
        /* ignored */
2345
        rn = "'Diagnostic"; /* implementation dependent */
2346
        break;
2347
    case 23:
2348
        switch (sel) {
2349
        case 0:
2350
            gen_op_mfc0_debug(); /* EJTAG support */
2351
            rn = "Debug";
2352
            break;
2353
        case 1:
2354
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2355
            rn = "TraceControl";
2356
//            break;
2357
        case 2:
2358
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2359
            rn = "TraceControl2";
2360
//            break;
2361
        case 3:
2362
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2363
            rn = "UserTraceData";
2364
//            break;
2365
        case 4:
2366
//            gen_op_mfc0_debug(); /* PDtrace support */
2367
            rn = "TraceBPC";
2368
//            break;
2369
        default:
2370
            goto die;
2371
        }
2372
        break;
2373
    case 24:
2374
        switch (sel) {
2375
        case 0:
2376
            gen_op_mfc0_depc(); /* EJTAG support */
2377
            rn = "DEPC";
2378
            break;
2379
        default:
2380
            goto die;
2381
        }
2382
        break;
2383
    case 25:
2384
        switch (sel) {
2385
        case 0:
2386
            gen_op_mfc0_performance0();
2387
            rn = "Performance0";
2388
            break;
2389
        case 1:
2390
//            gen_op_mfc0_performance1();
2391
            rn = "Performance1";
2392
//            break;
2393
        case 2:
2394
//            gen_op_mfc0_performance2();
2395
            rn = "Performance2";
2396
//            break;
2397
        case 3:
2398
//            gen_op_mfc0_performance3();
2399
            rn = "Performance3";
2400
//            break;
2401
        case 4:
2402
//            gen_op_mfc0_performance4();
2403
            rn = "Performance4";
2404
//            break;
2405
        case 5:
2406
//            gen_op_mfc0_performance5();
2407
            rn = "Performance5";
2408
//            break;
2409
        case 6:
2410
//            gen_op_mfc0_performance6();
2411
            rn = "Performance6";
2412
//            break;
2413
        case 7:
2414
//            gen_op_mfc0_performance7();
2415
            rn = "Performance7";
2416
//            break;
2417
        default:
2418
            goto die;
2419
        }
2420
        break;
2421
    case 26:
2422
       rn = "ECC";
2423
       break;
2424
    case 27:
2425
        switch (sel) {
2426
        /* ignored */
2427
        case 0 ... 3:
2428
            rn = "CacheErr";
2429
            break;
2430
        default:
2431
            goto die;
2432
        }
2433
        break;
2434
    case 28:
2435
        switch (sel) {
2436
        case 0:
2437
        case 2:
2438
        case 4:
2439
        case 6:
2440
            gen_op_mfc0_taglo();
2441
            rn = "TagLo";
2442
            break;
2443
        case 1:
2444
        case 3:
2445
        case 5:
2446
        case 7:
2447
            gen_op_mfc0_datalo();
2448
            rn = "DataLo";
2449
            break;
2450
        default:
2451
            goto die;
2452
        }
2453
        break;
2454
    case 29:
2455
        switch (sel) {
2456
        case 0:
2457
        case 2:
2458
        case 4:
2459
        case 6:
2460
            gen_op_mfc0_taghi();
2461
            rn = "TagHi";
2462
            break;
2463
        case 1:
2464
        case 3:
2465
        case 5:
2466
        case 7:
2467
            gen_op_mfc0_datahi();
2468
            rn = "DataHi";
2469
            break;
2470
        default:
2471
            goto die;
2472
        }
2473
        break;
2474
    case 30:
2475
        switch (sel) {
2476
        case 0:
2477
            gen_op_mfc0_errorepc();
2478
            rn = "ErrorEPC";
2479
            break;
2480
        default:
2481
            goto die;
2482
        }
2483
        break;
2484
    case 31:
2485
        switch (sel) {
2486
        case 0:
2487
            gen_op_mfc0_desave(); /* EJTAG support */
2488
            rn = "DESAVE";
2489
            break;
2490
        default:
2491
            goto die;
2492
        }
2493
        break;
2494
    default:
2495
       goto die;
2496
    }
2497
#if defined MIPS_DEBUG_DISAS
2498
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2499
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2500
                rn, reg, sel);
2501
    }
2502
#endif
2503
    return;
2504

    
2505
die:
2506
#if defined MIPS_DEBUG_DISAS
2507
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2508
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2509
                rn, reg, sel);
2510
    }
2511
#endif
2512
    generate_exception(ctx, EXCP_RI);
2513
}
2514

    
2515
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2516
{
2517
    const char *rn = "invalid";
2518

    
2519
    if (sel != 0)
2520
        check_insn(env, ctx, ISA_MIPS32);
2521

    
2522
    switch (reg) {
2523
    case 0:
2524
        switch (sel) {
2525
        case 0:
2526
            gen_op_mtc0_index();
2527
            rn = "Index";
2528
            break;
2529
        case 1:
2530
            check_insn(env, ctx, ASE_MT);
2531
            gen_op_mtc0_mvpcontrol();
2532
            rn = "MVPControl";
2533
            break;
2534
        case 2:
2535
            check_insn(env, ctx, ASE_MT);
2536
            /* ignored */
2537
            rn = "MVPConf0";
2538
            break;
2539
        case 3:
2540
            check_insn(env, ctx, ASE_MT);
2541
            /* ignored */
2542
            rn = "MVPConf1";
2543
            break;
2544
        default:
2545
            goto die;
2546
        }
2547
        break;
2548
    case 1:
2549
        switch (sel) {
2550
        case 0:
2551
            /* ignored */
2552
            rn = "Random";
2553
            break;
2554
        case 1:
2555
            check_insn(env, ctx, ASE_MT);
2556
            gen_op_mtc0_vpecontrol();
2557
            rn = "VPEControl";
2558
            break;
2559
        case 2:
2560
            check_insn(env, ctx, ASE_MT);
2561
            gen_op_mtc0_vpeconf0();
2562
            rn = "VPEConf0";
2563
            break;
2564
        case 3:
2565
            check_insn(env, ctx, ASE_MT);
2566
            gen_op_mtc0_vpeconf1();
2567
            rn = "VPEConf1";
2568
            break;
2569
        case 4:
2570
            check_insn(env, ctx, ASE_MT);
2571
            gen_op_mtc0_yqmask();
2572
            rn = "YQMask";
2573
            break;
2574
        case 5:
2575
            check_insn(env, ctx, ASE_MT);
2576
            gen_op_mtc0_vpeschedule();
2577
            rn = "VPESchedule";
2578
            break;
2579
        case 6:
2580
            check_insn(env, ctx, ASE_MT);
2581
            gen_op_mtc0_vpeschefback();
2582
            rn = "VPEScheFBack";
2583
            break;
2584
        case 7:
2585
            check_insn(env, ctx, ASE_MT);
2586
            gen_op_mtc0_vpeopt();
2587
            rn = "VPEOpt";
2588
            break;
2589
        default:
2590
            goto die;
2591
        }
2592
        break;
2593
    case 2:
2594
        switch (sel) {
2595
        case 0:
2596
            gen_op_mtc0_entrylo0();
2597
            rn = "EntryLo0";
2598
            break;
2599
        case 1:
2600
            check_insn(env, ctx, ASE_MT);
2601
            gen_op_mtc0_tcstatus();
2602
            rn = "TCStatus";
2603
            break;
2604
        case 2:
2605
            check_insn(env, ctx, ASE_MT);
2606
            gen_op_mtc0_tcbind();
2607
            rn = "TCBind";
2608
            break;
2609
        case 3:
2610
            check_insn(env, ctx, ASE_MT);
2611
            gen_op_mtc0_tcrestart();
2612
            rn = "TCRestart";
2613
            break;
2614
        case 4:
2615
            check_insn(env, ctx, ASE_MT);
2616
            gen_op_mtc0_tchalt();
2617
            rn = "TCHalt";
2618
            break;
2619
        case 5:
2620
            check_insn(env, ctx, ASE_MT);
2621
            gen_op_mtc0_tccontext();
2622
            rn = "TCContext";
2623
            break;
2624
        case 6:
2625
            check_insn(env, ctx, ASE_MT);
2626
            gen_op_mtc0_tcschedule();
2627
            rn = "TCSchedule";
2628
            break;
2629
        case 7:
2630
            check_insn(env, ctx, ASE_MT);
2631
            gen_op_mtc0_tcschefback();
2632
            rn = "TCScheFBack";
2633
            break;
2634
        default:
2635
            goto die;
2636
        }
2637
        break;
2638
    case 3:
2639
        switch (sel) {
2640
        case 0:
2641
            gen_op_mtc0_entrylo1();
2642
            rn = "EntryLo1";
2643
            break;
2644
        default:
2645
            goto die;
2646
        }
2647
        break;
2648
    case 4:
2649
        switch (sel) {
2650
        case 0:
2651
            gen_op_mtc0_context();
2652
            rn = "Context";
2653
            break;
2654
        case 1:
2655
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2656
            rn = "ContextConfig";
2657
//            break;
2658
        default:
2659
            goto die;
2660
        }
2661
        break;
2662
    case 5:
2663
        switch (sel) {
2664
        case 0:
2665
            gen_op_mtc0_pagemask();
2666
            rn = "PageMask";
2667
            break;
2668
        case 1:
2669
            check_insn(env, ctx, ISA_MIPS32R2);
2670
            gen_op_mtc0_pagegrain();
2671
            rn = "PageGrain";
2672
            break;
2673
        default:
2674
            goto die;
2675
        }
2676
        break;
2677
    case 6:
2678
        switch (sel) {
2679
        case 0:
2680
            gen_op_mtc0_wired();
2681
            rn = "Wired";
2682
            break;
2683
        case 1:
2684
            check_insn(env, ctx, ISA_MIPS32R2);
2685
            gen_op_mtc0_srsconf0();
2686
            rn = "SRSConf0";
2687
            break;
2688
        case 2:
2689
            check_insn(env, ctx, ISA_MIPS32R2);
2690
            gen_op_mtc0_srsconf1();
2691
            rn = "SRSConf1";
2692
            break;
2693
        case 3:
2694
            check_insn(env, ctx, ISA_MIPS32R2);
2695
            gen_op_mtc0_srsconf2();
2696
            rn = "SRSConf2";
2697
            break;
2698
        case 4:
2699
            check_insn(env, ctx, ISA_MIPS32R2);
2700
            gen_op_mtc0_srsconf3();
2701
            rn = "SRSConf3";
2702
            break;
2703
        case 5:
2704
            check_insn(env, ctx, ISA_MIPS32R2);
2705
            gen_op_mtc0_srsconf4();
2706
            rn = "SRSConf4";
2707
            break;
2708
        default:
2709
            goto die;
2710
        }
2711
        break;
2712
    case 7:
2713
        switch (sel) {
2714
        case 0:
2715
            check_insn(env, ctx, ISA_MIPS32R2);
2716
            gen_op_mtc0_hwrena();
2717
            rn = "HWREna";
2718
            break;
2719
        default:
2720
            goto die;
2721
        }
2722
        break;
2723
    case 8:
2724
        /* ignored */
2725
        rn = "BadVaddr";
2726
        break;
2727
    case 9:
2728
        switch (sel) {
2729
        case 0:
2730
            gen_op_mtc0_count();
2731
            rn = "Count";
2732
            break;
2733
        /* 6,7 are implementation dependent */
2734
        default:
2735
            goto die;
2736
        }
2737
        /* Stop translation as we may have switched the execution mode */
2738
        ctx->bstate = BS_STOP;
2739
        break;
2740
    case 10:
2741
        switch (sel) {
2742
        case 0:
2743
            gen_op_mtc0_entryhi();
2744
            rn = "EntryHi";
2745
            break;
2746
        default:
2747
            goto die;
2748
        }
2749
        break;
2750
    case 11:
2751
        switch (sel) {
2752
        case 0:
2753
            gen_op_mtc0_compare();
2754
            rn = "Compare";
2755
            break;
2756
        /* 6,7 are implementation dependent */
2757
        default:
2758
            goto die;
2759
        }
2760
        /* Stop translation as we may have switched the execution mode */
2761
        ctx->bstate = BS_STOP;
2762
        break;
2763
    case 12:
2764
        switch (sel) {
2765
        case 0:
2766
            gen_op_mtc0_status();
2767
            /* BS_STOP isn't good enough here, hflags may have changed. */
2768
            gen_save_pc(ctx->pc + 4);
2769
            ctx->bstate = BS_EXCP;
2770
            rn = "Status";
2771
            break;
2772
        case 1:
2773
            check_insn(env, ctx, ISA_MIPS32R2);
2774
            gen_op_mtc0_intctl();
2775
            /* Stop translation as we may have switched the execution mode */
2776
            ctx->bstate = BS_STOP;
2777
            rn = "IntCtl";
2778
            break;
2779
        case 2:
2780
            check_insn(env, ctx, ISA_MIPS32R2);
2781
            gen_op_mtc0_srsctl();
2782
            /* Stop translation as we may have switched the execution mode */
2783
            ctx->bstate = BS_STOP;
2784
            rn = "SRSCtl";
2785
            break;
2786
        case 3:
2787
            check_insn(env, ctx, ISA_MIPS32R2);
2788
            gen_op_mtc0_srsmap();
2789
            /* Stop translation as we may have switched the execution mode */
2790
            ctx->bstate = BS_STOP;
2791
            rn = "SRSMap";
2792
            break;
2793
        default:
2794
            goto die;
2795
        }
2796
        break;
2797
    case 13:
2798
        switch (sel) {
2799
        case 0:
2800
            gen_op_mtc0_cause();
2801
            rn = "Cause";
2802
            break;
2803
        default:
2804
            goto die;
2805
        }
2806
        /* Stop translation as we may have switched the execution mode */
2807
        ctx->bstate = BS_STOP;
2808
        break;
2809
    case 14:
2810
        switch (sel) {
2811
        case 0:
2812
            gen_op_mtc0_epc();
2813
            rn = "EPC";
2814
            break;
2815
        default:
2816
            goto die;
2817
        }
2818
        break;
2819
    case 15:
2820
        switch (sel) {
2821
        case 0:
2822
            /* ignored */
2823
            rn = "PRid";
2824
            break;
2825
        case 1:
2826
            check_insn(env, ctx, ISA_MIPS32R2);
2827
            gen_op_mtc0_ebase();
2828
            rn = "EBase";
2829
            break;
2830
        default:
2831
            goto die;
2832
        }
2833
        break;
2834
    case 16:
2835
        switch (sel) {
2836
        case 0:
2837
            gen_op_mtc0_config0();
2838
            rn = "Config";
2839
            /* Stop translation as we may have switched the execution mode */
2840
            ctx->bstate = BS_STOP;
2841
            break;
2842
        case 1:
2843
            /* ignored, read only */
2844
            rn = "Config1";
2845
            break;
2846
        case 2:
2847
            gen_op_mtc0_config2();
2848
            rn = "Config2";
2849
            /* Stop translation as we may have switched the execution mode */
2850
            ctx->bstate = BS_STOP;
2851
            break;
2852
        case 3:
2853
            /* ignored, read only */
2854
            rn = "Config3";
2855
            break;
2856
        /* 4,5 are reserved */
2857
        /* 6,7 are implementation dependent */
2858
        case 6:
2859
            /* ignored */
2860
            rn = "Config6";
2861
            break;
2862
        case 7:
2863
            /* ignored */
2864
            rn = "Config7";
2865
            break;
2866
        default:
2867
            rn = "Invalid config selector";
2868
            goto die;
2869
        }
2870
        break;
2871
    case 17:
2872
        switch (sel) {
2873
        case 0:
2874
            /* ignored */
2875
            rn = "LLAddr";
2876
            break;
2877
        default:
2878
            goto die;
2879
        }
2880
        break;
2881
    case 18:
2882
        switch (sel) {
2883
        case 0 ... 7:
2884
            gen_op_mtc0_watchlo(sel);
2885
            rn = "WatchLo";
2886
            break;
2887
        default:
2888
            goto die;
2889
        }
2890
        break;
2891
    case 19:
2892
        switch (sel) {
2893
        case 0 ... 7:
2894
            gen_op_mtc0_watchhi(sel);
2895
            rn = "WatchHi";
2896
            break;
2897
        default:
2898
            goto die;
2899
        }
2900
        break;
2901
    case 20:
2902
        switch (sel) {
2903
        case 0:
2904
#if defined(TARGET_MIPS64)
2905
            check_insn(env, ctx, ISA_MIPS3);
2906
            gen_op_mtc0_xcontext();
2907
            rn = "XContext";
2908
            break;
2909
#endif
2910
        default:
2911
            goto die;
2912
        }
2913
        break;
2914
    case 21:
2915
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2916
        switch (sel) {
2917
        case 0:
2918
            gen_op_mtc0_framemask();
2919
            rn = "Framemask";
2920
            break;
2921
        default:
2922
            goto die;
2923
        }
2924
        break;
2925
    case 22:
2926
        /* ignored */
2927
        rn = "Diagnostic"; /* implementation dependent */
2928
        break;
2929
    case 23:
2930
        switch (sel) {
2931
        case 0:
2932
            gen_op_mtc0_debug(); /* EJTAG support */
2933
            /* BS_STOP isn't good enough here, hflags may have changed. */
2934
            gen_save_pc(ctx->pc + 4);
2935
            ctx->bstate = BS_EXCP;
2936
            rn = "Debug";
2937
            break;
2938
        case 1:
2939
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2940
            rn = "TraceControl";
2941
            /* Stop translation as we may have switched the execution mode */
2942
            ctx->bstate = BS_STOP;
2943
//            break;
2944
        case 2:
2945
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2946
            rn = "TraceControl2";
2947
            /* Stop translation as we may have switched the execution mode */
2948
            ctx->bstate = BS_STOP;
2949
//            break;
2950
        case 3:
2951
            /* Stop translation as we may have switched the execution mode */
2952
            ctx->bstate = BS_STOP;
2953
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2954
            rn = "UserTraceData";
2955
            /* Stop translation as we may have switched the execution mode */
2956
            ctx->bstate = BS_STOP;
2957
//            break;
2958
        case 4:
2959
//            gen_op_mtc0_debug(); /* PDtrace support */
2960
            /* Stop translation as we may have switched the execution mode */
2961
            ctx->bstate = BS_STOP;
2962
            rn = "TraceBPC";
2963
//            break;
2964
        default:
2965
            goto die;
2966
        }
2967
        break;
2968
    case 24:
2969
        switch (sel) {
2970
        case 0:
2971
            gen_op_mtc0_depc(); /* EJTAG support */
2972
            rn = "DEPC";
2973
            break;
2974
        default:
2975
            goto die;
2976
        }
2977
        break;
2978
    case 25:
2979
        switch (sel) {
2980
        case 0:
2981
            gen_op_mtc0_performance0();
2982
            rn = "Performance0";
2983
            break;
2984
        case 1:
2985
//            gen_op_mtc0_performance1();
2986
            rn = "Performance1";
2987
//            break;
2988
        case 2:
2989
//            gen_op_mtc0_performance2();
2990
            rn = "Performance2";
2991
//            break;
2992
        case 3:
2993
//            gen_op_mtc0_performance3();
2994
            rn = "Performance3";
2995
//            break;
2996
        case 4:
2997
//            gen_op_mtc0_performance4();
2998
            rn = "Performance4";
2999
//            break;
3000
        case 5:
3001
//            gen_op_mtc0_performance5();
3002
            rn = "Performance5";
3003
//            break;
3004
        case 6:
3005
//            gen_op_mtc0_performance6();
3006
            rn = "Performance6";
3007
//            break;
3008
        case 7:
3009
//            gen_op_mtc0_performance7();
3010
            rn = "Performance7";
3011
//            break;
3012
        default:
3013
            goto die;
3014
        }
3015
       break;
3016
    case 26:
3017
        /* ignored */
3018
        rn = "ECC";
3019
        break;
3020
    case 27:
3021
        switch (sel) {
3022
        case 0 ... 3:
3023
            /* ignored */
3024
            rn = "CacheErr";
3025
            break;
3026
        default:
3027
            goto die;
3028
        }
3029
       break;
3030
    case 28:
3031
        switch (sel) {
3032
        case 0:
3033
        case 2:
3034
        case 4:
3035
        case 6:
3036
            gen_op_mtc0_taglo();
3037
            rn = "TagLo";
3038
            break;
3039
        case 1:
3040
        case 3:
3041
        case 5:
3042
        case 7:
3043
            gen_op_mtc0_datalo();
3044
            rn = "DataLo";
3045
            break;
3046
        default:
3047
            goto die;
3048
        }
3049
        break;
3050
    case 29:
3051
        switch (sel) {
3052
        case 0:
3053
        case 2:
3054
        case 4:
3055
        case 6:
3056
            gen_op_mtc0_taghi();
3057
            rn = "TagHi";
3058
            break;
3059
        case 1:
3060
        case 3:
3061
        case 5:
3062
        case 7:
3063
            gen_op_mtc0_datahi();
3064
            rn = "DataHi";
3065
            break;
3066
        default:
3067
            rn = "invalid sel";
3068
            goto die;
3069
        }
3070
       break;
3071
    case 30:
3072
        switch (sel) {
3073
        case 0:
3074
            gen_op_mtc0_errorepc();
3075
            rn = "ErrorEPC";
3076
            break;
3077
        default:
3078
            goto die;
3079
        }
3080
        break;
3081
    case 31:
3082
        switch (sel) {
3083
        case 0:
3084
            gen_op_mtc0_desave(); /* EJTAG support */
3085
            rn = "DESAVE";
3086
            break;
3087
        default:
3088
            goto die;
3089
        }
3090
        /* Stop translation as we may have switched the execution mode */
3091
        ctx->bstate = BS_STOP;
3092
        break;
3093
    default:
3094
       goto die;
3095
    }
3096
#if defined MIPS_DEBUG_DISAS
3097
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3098
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3099
                rn, reg, sel);
3100
    }
3101
#endif
3102
    return;
3103

    
3104
die:
3105
#if defined MIPS_DEBUG_DISAS
3106
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3107
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3108
                rn, reg, sel);
3109
    }
3110
#endif
3111
    generate_exception(ctx, EXCP_RI);
3112
}
3113

    
3114
#if defined(TARGET_MIPS64)
3115
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3116
{
3117
    const char *rn = "invalid";
3118

    
3119
    if (sel != 0)
3120
        check_insn(env, ctx, ISA_MIPS64);
3121

    
3122
    switch (reg) {
3123
    case 0:
3124
        switch (sel) {
3125
        case 0:
3126
            gen_op_mfc0_index();
3127
            rn = "Index";
3128
            break;
3129
        case 1:
3130
            check_insn(env, ctx, ASE_MT);
3131
            gen_op_mfc0_mvpcontrol();
3132
            rn = "MVPControl";
3133
            break;
3134
        case 2:
3135
            check_insn(env, ctx, ASE_MT);
3136
            gen_op_mfc0_mvpconf0();
3137
            rn = "MVPConf0";
3138
            break;
3139
        case 3:
3140
            check_insn(env, ctx, ASE_MT);
3141
            gen_op_mfc0_mvpconf1();
3142
            rn = "MVPConf1";
3143
            break;
3144
        default:
3145
            goto die;
3146
        }
3147
        break;
3148
    case 1:
3149
        switch (sel) {
3150
        case 0:
3151
            gen_op_mfc0_random();
3152
            rn = "Random";
3153
            break;
3154
        case 1:
3155
            check_insn(env, ctx, ASE_MT);
3156
            gen_op_mfc0_vpecontrol();
3157
            rn = "VPEControl";
3158
            break;
3159
        case 2:
3160
            check_insn(env, ctx, ASE_MT);
3161
            gen_op_mfc0_vpeconf0();
3162
            rn = "VPEConf0";
3163
            break;
3164
        case 3:
3165
            check_insn(env, ctx, ASE_MT);
3166
            gen_op_mfc0_vpeconf1();
3167
            rn = "VPEConf1";
3168
            break;
3169
        case 4:
3170
            check_insn(env, ctx, ASE_MT);
3171
            gen_op_dmfc0_yqmask();
3172
            rn = "YQMask";
3173
            break;
3174
        case 5:
3175
            check_insn(env, ctx, ASE_MT);
3176
            gen_op_dmfc0_vpeschedule();
3177
            rn = "VPESchedule";
3178
            break;
3179
        case 6:
3180
            check_insn(env, ctx, ASE_MT);
3181
            gen_op_dmfc0_vpeschefback();
3182
            rn = "VPEScheFBack";
3183
            break;
3184
        case 7:
3185
            check_insn(env, ctx, ASE_MT);
3186
            gen_op_mfc0_vpeopt();
3187
            rn = "VPEOpt";
3188
            break;
3189
        default:
3190
            goto die;
3191
        }
3192
        break;
3193
    case 2:
3194
        switch (sel) {
3195
        case 0:
3196
            gen_op_dmfc0_entrylo0();
3197
            rn = "EntryLo0";
3198
            break;
3199
        case 1:
3200
            check_insn(env, ctx, ASE_MT);
3201
            gen_op_mfc0_tcstatus();
3202
            rn = "TCStatus";
3203
            break;
3204
        case 2:
3205
            check_insn(env, ctx, ASE_MT);
3206
            gen_op_mfc0_tcbind();
3207
            rn = "TCBind";
3208
            break;
3209
        case 3:
3210
            check_insn(env, ctx, ASE_MT);
3211
            gen_op_dmfc0_tcrestart();
3212
            rn = "TCRestart";
3213
            break;
3214
        case 4:
3215
            check_insn(env, ctx, ASE_MT);
3216
            gen_op_dmfc0_tchalt();
3217
            rn = "TCHalt";
3218
            break;
3219
        case 5:
3220
            check_insn(env, ctx, ASE_MT);
3221
            gen_op_dmfc0_tccontext();
3222
            rn = "TCContext";
3223
            break;
3224
        case 6:
3225
            check_insn(env, ctx, ASE_MT);
3226
            gen_op_dmfc0_tcschedule();
3227
            rn = "TCSchedule";
3228
            break;
3229
        case 7:
3230
            check_insn(env, ctx, ASE_MT);
3231
            gen_op_dmfc0_tcschefback();
3232
            rn = "TCScheFBack";
3233
            break;
3234
        default:
3235
            goto die;
3236
        }
3237
        break;
3238
    case 3:
3239
        switch (sel) {
3240
        case 0:
3241
            gen_op_dmfc0_entrylo1();
3242
            rn = "EntryLo1";
3243
            break;
3244
        default:
3245
            goto die;
3246
        }
3247
        break;
3248
    case 4:
3249
        switch (sel) {
3250
        case 0:
3251
            gen_op_dmfc0_context();
3252
            rn = "Context";
3253
            break;
3254
        case 1:
3255
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3256
            rn = "ContextConfig";
3257
//            break;
3258
        default:
3259
            goto die;
3260
        }
3261
        break;
3262
    case 5:
3263
        switch (sel) {
3264
        case 0:
3265
            gen_op_mfc0_pagemask();
3266
            rn = "PageMask";
3267
            break;
3268
        case 1:
3269
            check_insn(env, ctx, ISA_MIPS32R2);
3270
            gen_op_mfc0_pagegrain();
3271
            rn = "PageGrain";
3272
            break;
3273
        default:
3274
            goto die;
3275
        }
3276
        break;
3277
    case 6:
3278
        switch (sel) {
3279
        case 0:
3280
            gen_op_mfc0_wired();
3281
            rn = "Wired";
3282
            break;
3283
        case 1:
3284
            check_insn(env, ctx, ISA_MIPS32R2);
3285
            gen_op_mfc0_srsconf0();
3286
            rn = "SRSConf0";
3287
            break;
3288
        case 2:
3289
            check_insn(env, ctx, ISA_MIPS32R2);
3290
            gen_op_mfc0_srsconf1();
3291
            rn = "SRSConf1";
3292
            break;
3293
        case 3:
3294
            check_insn(env, ctx, ISA_MIPS32R2);
3295
            gen_op_mfc0_srsconf2();
3296
            rn = "SRSConf2";
3297
            break;
3298
        case 4:
3299
            check_insn(env, ctx, ISA_MIPS32R2);
3300
            gen_op_mfc0_srsconf3();
3301
            rn = "SRSConf3";
3302
            break;
3303
        case 5:
3304
            check_insn(env, ctx, ISA_MIPS32R2);
3305
            gen_op_mfc0_srsconf4();
3306
            rn = "SRSConf4";
3307
            break;
3308
        default:
3309
            goto die;
3310
        }
3311
        break;
3312
    case 7:
3313
        switch (sel) {
3314
        case 0:
3315
            check_insn(env, ctx, ISA_MIPS32R2);
3316
            gen_op_mfc0_hwrena();
3317
            rn = "HWREna";
3318
            break;
3319
        default:
3320
            goto die;
3321
        }
3322
        break;
3323
    case 8:
3324
        switch (sel) {
3325
        case 0:
3326
            gen_op_dmfc0_badvaddr();
3327
            rn = "BadVaddr";
3328
            break;
3329
        default:
3330
            goto die;
3331
        }
3332
        break;
3333
    case 9:
3334
        switch (sel) {
3335
        case 0:
3336
            gen_op_mfc0_count();
3337
            rn = "Count";
3338
            break;
3339
        /* 6,7 are implementation dependent */
3340
        default:
3341
            goto die;
3342
        }
3343
        break;
3344
    case 10:
3345
        switch (sel) {
3346
        case 0:
3347
            gen_op_dmfc0_entryhi();
3348
            rn = "EntryHi";
3349
            break;
3350
        default:
3351
            goto die;
3352
        }
3353
        break;
3354
    case 11:
3355
        switch (sel) {
3356
        case 0:
3357
            gen_op_mfc0_compare();
3358
            rn = "Compare";
3359
            break;
3360
        /* 6,7 are implementation dependent */
3361
        default:
3362
            goto die;
3363
        }
3364
        break;
3365
    case 12:
3366
        switch (sel) {
3367
        case 0:
3368
            gen_op_mfc0_status();
3369
            rn = "Status";
3370
            break;
3371
        case 1:
3372
            check_insn(env, ctx, ISA_MIPS32R2);
3373
            gen_op_mfc0_intctl();
3374
            rn = "IntCtl";
3375
            break;
3376
        case 2:
3377
            check_insn(env, ctx, ISA_MIPS32R2);
3378
            gen_op_mfc0_srsctl();
3379
            rn = "SRSCtl";
3380
            break;
3381
        case 3:
3382
            check_insn(env, ctx, ISA_MIPS32R2);
3383
            gen_op_mfc0_srsmap();
3384
            rn = "SRSMap";
3385
            break;
3386
        default:
3387
            goto die;
3388
        }
3389
        break;
3390
    case 13:
3391
        switch (sel) {
3392
        case 0:
3393
            gen_op_mfc0_cause();
3394
            rn = "Cause";
3395
            break;
3396
        default:
3397
            goto die;
3398
        }
3399
        break;
3400
    case 14:
3401
        switch (sel) {
3402
        case 0:
3403
            gen_op_dmfc0_epc();
3404
            rn = "EPC";
3405
            break;
3406
        default:
3407
            goto die;
3408
        }
3409
        break;
3410
    case 15:
3411
        switch (sel) {
3412
        case 0:
3413
            gen_op_mfc0_prid();
3414
            rn = "PRid";
3415
            break;
3416
        case 1:
3417
            check_insn(env, ctx, ISA_MIPS32R2);
3418
            gen_op_mfc0_ebase();
3419
            rn = "EBase";
3420
            break;
3421
        default:
3422
            goto die;
3423
        }
3424
        break;
3425
    case 16:
3426
        switch (sel) {
3427
        case 0:
3428
            gen_op_mfc0_config0();
3429
            rn = "Config";
3430
            break;
3431
        case 1:
3432
            gen_op_mfc0_config1();
3433
            rn = "Config1";
3434
            break;
3435
        case 2:
3436
            gen_op_mfc0_config2();
3437
            rn = "Config2";
3438
            break;
3439
        case 3:
3440
            gen_op_mfc0_config3();
3441
            rn = "Config3";
3442
            break;
3443
       /* 6,7 are implementation dependent */
3444
        default:
3445
            goto die;
3446
        }
3447
        break;
3448
    case 17:
3449
        switch (sel) {
3450
        case 0:
3451
            gen_op_dmfc0_lladdr();
3452
            rn = "LLAddr";
3453
            break;
3454
        default:
3455
            goto die;
3456
        }
3457
        break;
3458
    case 18:
3459
        switch (sel) {
3460
        case 0 ... 7:
3461
            gen_op_dmfc0_watchlo(sel);
3462
            rn = "WatchLo";
3463
            break;
3464
        default:
3465
            goto die;
3466
        }
3467
        break;
3468
    case 19:
3469
        switch (sel) {
3470
        case 0 ... 7:
3471
            gen_op_mfc0_watchhi(sel);
3472
            rn = "WatchHi";
3473
            break;
3474
        default:
3475
            goto die;
3476
        }
3477
        break;
3478
    case 20:
3479
        switch (sel) {
3480
        case 0:
3481
            check_insn(env, ctx, ISA_MIPS3);
3482
            gen_op_dmfc0_xcontext();
3483
            rn = "XContext";
3484
            break;
3485
        default:
3486
            goto die;
3487
        }
3488
        break;
3489
    case 21:
3490
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3491
        switch (sel) {
3492
        case 0:
3493
            gen_op_mfc0_framemask();
3494
            rn = "Framemask";
3495
            break;
3496
        default:
3497
            goto die;
3498
        }
3499
        break;
3500
    case 22:
3501
        /* ignored */
3502
        rn = "'Diagnostic"; /* implementation dependent */
3503
        break;
3504
    case 23:
3505
        switch (sel) {
3506
        case 0:
3507
            gen_op_mfc0_debug(); /* EJTAG support */
3508
            rn = "Debug";
3509
            break;
3510
        case 1:
3511
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3512
            rn = "TraceControl";
3513
//            break;
3514
        case 2:
3515
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3516
            rn = "TraceControl2";
3517
//            break;
3518
        case 3:
3519
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3520
            rn = "UserTraceData";
3521
//            break;
3522
        case 4:
3523
//            gen_op_dmfc0_debug(); /* PDtrace support */
3524
            rn = "TraceBPC";
3525
//            break;
3526
        default:
3527
            goto die;
3528
        }
3529
        break;
3530
    case 24:
3531
        switch (sel) {
3532
        case 0:
3533
            gen_op_dmfc0_depc(); /* EJTAG support */
3534
            rn = "DEPC";
3535
            break;
3536
        default:
3537
            goto die;
3538
        }
3539
        break;
3540
    case 25:
3541
        switch (sel) {
3542
        case 0:
3543
            gen_op_mfc0_performance0();
3544
            rn = "Performance0";
3545
            break;
3546
        case 1:
3547
//            gen_op_dmfc0_performance1();
3548
            rn = "Performance1";
3549
//            break;
3550
        case 2:
3551
//            gen_op_dmfc0_performance2();
3552
            rn = "Performance2";
3553
//            break;
3554
        case 3:
3555
//            gen_op_dmfc0_performance3();
3556
            rn = "Performance3";
3557
//            break;
3558
        case 4:
3559
//            gen_op_dmfc0_performance4();
3560
            rn = "Performance4";
3561
//            break;
3562
        case 5:
3563
//            gen_op_dmfc0_performance5();
3564
            rn = "Performance5";
3565
//            break;
3566
        case 6:
3567
//            gen_op_dmfc0_performance6();
3568
            rn = "Performance6";
3569
//            break;
3570
        case 7:
3571
//            gen_op_dmfc0_performance7();
3572
            rn = "Performance7";
3573
//            break;
3574
        default:
3575
            goto die;
3576
        }
3577
        break;
3578
    case 26:
3579
       rn = "ECC";
3580
       break;
3581
    case 27:
3582
        switch (sel) {
3583
        /* ignored */
3584
        case 0 ... 3:
3585
            rn = "CacheErr";
3586
            break;
3587
        default:
3588
            goto die;
3589
        }
3590
        break;
3591
    case 28:
3592
        switch (sel) {
3593
        case 0:
3594
        case 2:
3595
        case 4:
3596
        case 6:
3597
            gen_op_mfc0_taglo();
3598
            rn = "TagLo";
3599
            break;
3600
        case 1:
3601
        case 3:
3602
        case 5:
3603
        case 7:
3604
            gen_op_mfc0_datalo();
3605
            rn = "DataLo";
3606
            break;
3607
        default:
3608
            goto die;
3609
        }
3610
        break;
3611
    case 29:
3612
        switch (sel) {
3613
        case 0:
3614
        case 2:
3615
        case 4:
3616
        case 6:
3617
            gen_op_mfc0_taghi();
3618
            rn = "TagHi";
3619
            break;
3620
        case 1:
3621
        case 3:
3622
        case 5:
3623
        case 7:
3624
            gen_op_mfc0_datahi();
3625
            rn = "DataHi";
3626
            break;
3627
        default:
3628
            goto die;
3629
        }
3630
        break;
3631
    case 30:
3632
        switch (sel) {
3633
        case 0:
3634
            gen_op_dmfc0_errorepc();
3635
            rn = "ErrorEPC";
3636
            break;
3637
        default:
3638
            goto die;
3639
        }
3640
        break;
3641
    case 31:
3642
        switch (sel) {
3643
        case 0:
3644
            gen_op_mfc0_desave(); /* EJTAG support */
3645
            rn = "DESAVE";
3646
            break;
3647
        default:
3648
            goto die;
3649
        }
3650
        break;
3651
    default:
3652
        goto die;
3653
    }
3654
#if defined MIPS_DEBUG_DISAS
3655
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3656
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3657
                rn, reg, sel);
3658
    }
3659
#endif
3660
    return;
3661

    
3662
die:
3663
#if defined MIPS_DEBUG_DISAS
3664
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3665
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3666
                rn, reg, sel);
3667
    }
3668
#endif
3669
    generate_exception(ctx, EXCP_RI);
3670
}
3671

    
3672
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3673
{
3674
    const char *rn = "invalid";
3675

    
3676
    if (sel != 0)
3677
        check_insn(env, ctx, ISA_MIPS64);
3678

    
3679
    switch (reg) {
3680
    case 0:
3681
        switch (sel) {
3682
        case 0:
3683
            gen_op_mtc0_index();
3684
            rn = "Index";
3685
            break;
3686
        case 1:
3687
            check_insn(env, ctx, ASE_MT);
3688
            gen_op_mtc0_mvpcontrol();
3689
            rn = "MVPControl";
3690
            break;
3691
        case 2:
3692
            check_insn(env, ctx, ASE_MT);
3693
            /* ignored */
3694
            rn = "MVPConf0";
3695
            break;
3696
        case 3:
3697
            check_insn(env, ctx, ASE_MT);
3698
            /* ignored */
3699
            rn = "MVPConf1";
3700
            break;
3701
        default:
3702
            goto die;
3703
        }
3704
        break;
3705
    case 1:
3706
        switch (sel) {
3707
        case 0:
3708
            /* ignored */
3709
            rn = "Random";
3710
            break;
3711
        case 1:
3712
            check_insn(env, ctx, ASE_MT);
3713
            gen_op_mtc0_vpecontrol();
3714
            rn = "VPEControl";
3715
            break;
3716
        case 2:
3717
            check_insn(env, ctx, ASE_MT);
3718
            gen_op_mtc0_vpeconf0();
3719
            rn = "VPEConf0";
3720
            break;
3721
        case 3:
3722
            check_insn(env, ctx, ASE_MT);
3723
            gen_op_mtc0_vpeconf1();
3724
            rn = "VPEConf1";
3725
            break;
3726
        case 4:
3727
            check_insn(env, ctx, ASE_MT);
3728
            gen_op_mtc0_yqmask();
3729
            rn = "YQMask";
3730
            break;
3731
        case 5:
3732
            check_insn(env, ctx, ASE_MT);
3733
            gen_op_mtc0_vpeschedule();
3734
            rn = "VPESchedule";
3735
            break;
3736
        case 6:
3737
            check_insn(env, ctx, ASE_MT);
3738
            gen_op_mtc0_vpeschefback();
3739
            rn = "VPEScheFBack";
3740
            break;
3741
        case 7:
3742
            check_insn(env, ctx, ASE_MT);
3743
            gen_op_mtc0_vpeopt();
3744
            rn = "VPEOpt";
3745
            break;
3746
        default:
3747
            goto die;
3748
        }
3749
        break;
3750
    case 2:
3751
        switch (sel) {
3752
        case 0:
3753
            gen_op_mtc0_entrylo0();
3754
            rn = "EntryLo0";
3755
            break;
3756
        case 1:
3757
            check_insn(env, ctx, ASE_MT);
3758
            gen_op_mtc0_tcstatus();
3759
            rn = "TCStatus";
3760
            break;
3761
        case 2:
3762
            check_insn(env, ctx, ASE_MT);
3763
            gen_op_mtc0_tcbind();
3764
            rn = "TCBind";
3765
            break;
3766
        case 3:
3767
            check_insn(env, ctx, ASE_MT);
3768
            gen_op_mtc0_tcrestart();
3769
            rn = "TCRestart";
3770
            break;
3771
        case 4:
3772
            check_insn(env, ctx, ASE_MT);
3773
            gen_op_mtc0_tchalt();
3774
            rn = "TCHalt";
3775
            break;
3776
        case 5:
3777
            check_insn(env, ctx, ASE_MT);
3778
            gen_op_mtc0_tccontext();
3779
            rn = "TCContext";
3780
            break;
3781
        case 6:
3782
            check_insn(env, ctx, ASE_MT);
3783
            gen_op_mtc0_tcschedule();
3784
            rn = "TCSchedule";
3785
            break;
3786
        case 7:
3787
            check_insn(env, ctx, ASE_MT);
3788
            gen_op_mtc0_tcschefback();
3789
            rn = "TCScheFBack";
3790
            break;
3791
        default:
3792
            goto die;
3793
        }
3794
        break;
3795
    case 3:
3796
        switch (sel) {
3797
        case 0:
3798
            gen_op_mtc0_entrylo1();
3799
            rn = "EntryLo1";
3800
            break;
3801
        default:
3802
            goto die;
3803
        }
3804
        break;
3805
    case 4:
3806
        switch (sel) {
3807
        case 0:
3808
            gen_op_mtc0_context();
3809
            rn = "Context";
3810
            break;
3811
        case 1:
3812
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3813
            rn = "ContextConfig";
3814
//           break;
3815
        default:
3816
            goto die;
3817
        }
3818
        break;
3819
    case 5:
3820
        switch (sel) {
3821
        case 0:
3822
            gen_op_mtc0_pagemask();
3823
            rn = "PageMask";
3824
            break;
3825
        case 1:
3826
            check_insn(env, ctx, ISA_MIPS32R2);
3827
            gen_op_mtc0_pagegrain();
3828
            rn = "PageGrain";
3829
            break;
3830
        default:
3831
            goto die;
3832
        }
3833
        break;
3834
    case 6:
3835
        switch (sel) {
3836
        case 0:
3837
            gen_op_mtc0_wired();
3838
            rn = "Wired";
3839
            break;
3840
        case 1:
3841
            check_insn(env, ctx, ISA_MIPS32R2);
3842
            gen_op_mtc0_srsconf0();
3843
            rn = "SRSConf0";
3844
            break;
3845
        case 2:
3846
            check_insn(env, ctx, ISA_MIPS32R2);
3847
            gen_op_mtc0_srsconf1();
3848
            rn = "SRSConf1";
3849
            break;
3850
        case 3:
3851
            check_insn(env, ctx, ISA_MIPS32R2);
3852
            gen_op_mtc0_srsconf2();
3853
            rn = "SRSConf2";
3854
            break;
3855
        case 4:
3856
            check_insn(env, ctx, ISA_MIPS32R2);
3857
            gen_op_mtc0_srsconf3();
3858
            rn = "SRSConf3";
3859
            break;
3860
        case 5:
3861
            check_insn(env, ctx, ISA_MIPS32R2);
3862
            gen_op_mtc0_srsconf4();
3863
            rn = "SRSConf4";
3864
            break;
3865
        default:
3866
            goto die;
3867
        }
3868
        break;
3869
    case 7:
3870
        switch (sel) {
3871
        case 0:
3872
            check_insn(env, ctx, ISA_MIPS32R2);
3873
            gen_op_mtc0_hwrena();
3874
            rn = "HWREna";
3875
            break;
3876
        default:
3877
            goto die;
3878
        }
3879
        break;
3880
    case 8:
3881
        /* ignored */
3882
        rn = "BadVaddr";
3883
        break;
3884
    case 9:
3885
        switch (sel) {
3886
        case 0:
3887
            gen_op_mtc0_count();
3888
            rn = "Count";
3889
            break;
3890
        /* 6,7 are implementation dependent */
3891
        default:
3892
            goto die;
3893
        }
3894
        /* Stop translation as we may have switched the execution mode */
3895
        ctx->bstate = BS_STOP;
3896
        break;
3897
    case 10:
3898
        switch (sel) {
3899
        case 0:
3900
            gen_op_mtc0_entryhi();
3901
            rn = "EntryHi";
3902
            break;
3903
        default:
3904
            goto die;
3905
        }
3906
        break;
3907
    case 11:
3908
        switch (sel) {
3909
        case 0:
3910
            gen_op_mtc0_compare();
3911
            rn = "Compare";
3912
            break;
3913
        /* 6,7 are implementation dependent */
3914
        default:
3915
            goto die;
3916
        }
3917
        /* Stop translation as we may have switched the execution mode */
3918
        ctx->bstate = BS_STOP;
3919
        break;
3920
    case 12:
3921
        switch (sel) {
3922
        case 0:
3923
            gen_op_mtc0_status();
3924
            /* BS_STOP isn't good enough here, hflags may have changed. */
3925
            gen_save_pc(ctx->pc + 4);
3926
            ctx->bstate = BS_EXCP;
3927
            rn = "Status";
3928
            break;
3929
        case 1:
3930
            check_insn(env, ctx, ISA_MIPS32R2);
3931
            gen_op_mtc0_intctl();
3932
            /* Stop translation as we may have switched the execution mode */
3933
            ctx->bstate = BS_STOP;
3934
            rn = "IntCtl";
3935
            break;
3936
        case 2:
3937
            check_insn(env, ctx, ISA_MIPS32R2);
3938
            gen_op_mtc0_srsctl();
3939
            /* Stop translation as we may have switched the execution mode */
3940
            ctx->bstate = BS_STOP;
3941
            rn = "SRSCtl";
3942
            break;
3943
        case 3:
3944
            check_insn(env, ctx, ISA_MIPS32R2);
3945
            gen_op_mtc0_srsmap();
3946
            /* Stop translation as we may have switched the execution mode */
3947
            ctx->bstate = BS_STOP;
3948
            rn = "SRSMap";
3949
            break;
3950
        default:
3951
            goto die;
3952
        }
3953
        break;
3954
    case 13:
3955
        switch (sel) {
3956
        case 0:
3957
            gen_op_mtc0_cause();
3958
            rn = "Cause";
3959
            break;
3960
        default:
3961
            goto die;
3962
        }
3963
        /* Stop translation as we may have switched the execution mode */
3964
        ctx->bstate = BS_STOP;
3965
        break;
3966
    case 14:
3967
        switch (sel) {
3968
        case 0:
3969
            gen_op_mtc0_epc();
3970
            rn = "EPC";
3971
            break;
3972
        default:
3973
            goto die;
3974
        }
3975
        break;
3976
    case 15:
3977
        switch (sel) {
3978
        case 0:
3979
            /* ignored */
3980
            rn = "PRid";
3981
            break;
3982
        case 1:
3983
            check_insn(env, ctx, ISA_MIPS32R2);
3984
            gen_op_mtc0_ebase();
3985
            rn = "EBase";
3986
            break;
3987
        default:
3988
            goto die;
3989
        }
3990
        break;
3991
    case 16:
3992
        switch (sel) {
3993
        case 0:
3994
            gen_op_mtc0_config0();
3995
            rn = "Config";
3996
            /* Stop translation as we may have switched the execution mode */
3997
            ctx->bstate = BS_STOP;
3998
            break;
3999
        case 1:
4000
            /* ignored */
4001
            rn = "Config1";
4002
            break;
4003
        case 2:
4004
            gen_op_mtc0_config2();
4005
            rn = "Config2";
4006
            /* Stop translation as we may have switched the execution mode */
4007
            ctx->bstate = BS_STOP;
4008
            break;
4009
        case 3:
4010
            /* ignored */
4011
            rn = "Config3";
4012
            break;
4013
        /* 6,7 are implementation dependent */
4014
        default:
4015
            rn = "Invalid config selector";
4016
            goto die;
4017
        }
4018
        break;
4019
    case 17:
4020
        switch (sel) {
4021
        case 0:
4022
            /* ignored */
4023
            rn = "LLAddr";
4024
            break;
4025
        default:
4026
            goto die;
4027
        }
4028
        break;
4029
    case 18:
4030
        switch (sel) {
4031
        case 0 ... 7:
4032
            gen_op_mtc0_watchlo(sel);
4033
            rn = "WatchLo";
4034
            break;
4035
        default:
4036
            goto die;
4037
        }
4038
        break;
4039
    case 19:
4040
        switch (sel) {
4041
        case 0 ... 7:
4042
            gen_op_mtc0_watchhi(sel);
4043
            rn = "WatchHi";
4044
            break;
4045
        default:
4046
            goto die;
4047
        }
4048
        break;
4049
    case 20:
4050
        switch (sel) {
4051
        case 0:
4052
            check_insn(env, ctx, ISA_MIPS3);
4053
            gen_op_mtc0_xcontext();
4054
            rn = "XContext";
4055
            break;
4056
        default:
4057
            goto die;
4058
        }
4059
        break;
4060
    case 21:
4061
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4062
        switch (sel) {
4063
        case 0:
4064
            gen_op_mtc0_framemask();
4065
            rn = "Framemask";
4066
            break;
4067
        default:
4068
            goto die;
4069
        }
4070
        break;
4071
    case 22:
4072
        /* ignored */
4073
        rn = "Diagnostic"; /* implementation dependent */
4074
        break;
4075
    case 23:
4076
        switch (sel) {
4077
        case 0:
4078
            gen_op_mtc0_debug(); /* EJTAG support */
4079
            /* BS_STOP isn't good enough here, hflags may have changed. */
4080
            gen_save_pc(ctx->pc + 4);
4081
            ctx->bstate = BS_EXCP;
4082
            rn = "Debug";
4083
            break;
4084
        case 1:
4085
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4086
            /* Stop translation as we may have switched the execution mode */
4087
            ctx->bstate = BS_STOP;
4088
            rn = "TraceControl";
4089
//            break;
4090
        case 2:
4091
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4092
            /* Stop translation as we may have switched the execution mode */
4093
            ctx->bstate = BS_STOP;
4094
            rn = "TraceControl2";
4095
//            break;
4096
        case 3:
4097
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4098
            /* Stop translation as we may have switched the execution mode */
4099
            ctx->bstate = BS_STOP;
4100
            rn = "UserTraceData";
4101
//            break;
4102
        case 4:
4103
//            gen_op_mtc0_debug(); /* PDtrace support */
4104
            /* Stop translation as we may have switched the execution mode */
4105
            ctx->bstate = BS_STOP;
4106
            rn = "TraceBPC";
4107
//            break;
4108
        default:
4109
            goto die;
4110
        }
4111
        break;
4112
    case 24:
4113
        switch (sel) {
4114
        case 0:
4115
            gen_op_mtc0_depc(); /* EJTAG support */
4116
            rn = "DEPC";
4117
            break;
4118
        default:
4119
            goto die;
4120
        }
4121
        break;
4122
    case 25:
4123
        switch (sel) {
4124
        case 0:
4125
            gen_op_mtc0_performance0();
4126
            rn = "Performance0";
4127
            break;
4128
        case 1:
4129
//            gen_op_mtc0_performance1();
4130
            rn = "Performance1";
4131
//            break;
4132
        case 2:
4133
//            gen_op_mtc0_performance2();
4134
            rn = "Performance2";
4135
//            break;
4136
        case 3:
4137
//            gen_op_mtc0_performance3();
4138
            rn = "Performance3";
4139
//            break;
4140
        case 4:
4141
//            gen_op_mtc0_performance4();
4142
            rn = "Performance4";
4143
//            break;
4144
        case 5:
4145
//            gen_op_mtc0_performance5();
4146
            rn = "Performance5";
4147
//            break;
4148
        case 6:
4149
//            gen_op_mtc0_performance6();
4150
            rn = "Performance6";
4151
//            break;
4152
        case 7:
4153
//            gen_op_mtc0_performance7();
4154
            rn = "Performance7";
4155
//            break;
4156
        default:
4157
            goto die;
4158
        }
4159
        break;
4160
    case 26:
4161
        /* ignored */
4162
        rn = "ECC";
4163
        break;
4164
    case 27:
4165
        switch (sel) {
4166
        case 0 ... 3:
4167
            /* ignored */
4168
            rn = "CacheErr";
4169
            break;
4170
        default:
4171
            goto die;
4172
        }
4173
        break;
4174
    case 28:
4175
        switch (sel) {
4176
        case 0:
4177
        case 2:
4178
        case 4:
4179
        case 6:
4180
            gen_op_mtc0_taglo();
4181
            rn = "TagLo";
4182
            break;
4183
        case 1:
4184
        case 3:
4185
        case 5:
4186
        case 7:
4187
            gen_op_mtc0_datalo();
4188
            rn = "DataLo";
4189
            break;
4190
        default:
4191
            goto die;
4192
        }
4193
        break;
4194
    case 29:
4195
        switch (sel) {
4196
        case 0:
4197
        case 2:
4198
        case 4:
4199
        case 6:
4200
            gen_op_mtc0_taghi();
4201
            rn = "TagHi";
4202
            break;
4203
        case 1:
4204
        case 3:
4205
        case 5:
4206
        case 7:
4207
            gen_op_mtc0_datahi();
4208
            rn = "DataHi";
4209
            break;
4210
        default:
4211
            rn = "invalid sel";
4212
            goto die;
4213
        }
4214
        break;
4215
    case 30:
4216
        switch (sel) {
4217
        case 0:
4218
            gen_op_mtc0_errorepc();
4219
            rn = "ErrorEPC";
4220
            break;
4221
        default:
4222
            goto die;
4223
        }
4224
        break;
4225
    case 31:
4226
        switch (sel) {
4227
        case 0:
4228
            gen_op_mtc0_desave(); /* EJTAG support */
4229
            rn = "DESAVE";
4230
            break;
4231
        default:
4232
            goto die;
4233
        }
4234
        /* Stop translation as we may have switched the execution mode */
4235
        ctx->bstate = BS_STOP;
4236
        break;
4237
    default:
4238
        goto die;
4239
    }
4240
#if defined MIPS_DEBUG_DISAS
4241
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4242
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4243
                rn, reg, sel);
4244
    }
4245
#endif
4246
    return;
4247

    
4248
die:
4249
#if defined MIPS_DEBUG_DISAS
4250
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4251
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4252
                rn, reg, sel);
4253
    }
4254
#endif
4255
    generate_exception(ctx, EXCP_RI);
4256
}
4257
#endif /* TARGET_MIPS64 */
4258

    
4259
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4260
                     int u, int sel, int h)
4261
{
4262
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4263

    
4264
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4265
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4266
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4267
        gen_op_set_T0(-1);
4268
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4269
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4270
        gen_op_set_T0(-1);
4271
    else if (u == 0) {
4272
        switch (rt) {
4273
        case 2:
4274
            switch (sel) {
4275
            case 1:
4276
                gen_op_mftc0_tcstatus();
4277
                break;
4278
            case 2:
4279
                gen_op_mftc0_tcbind();
4280
                break;
4281
            case 3:
4282
                gen_op_mftc0_tcrestart();
4283
                break;
4284
            case 4:
4285
                gen_op_mftc0_tchalt();
4286
                break;
4287
            case 5:
4288
                gen_op_mftc0_tccontext();
4289
                break;
4290
            case 6:
4291
                gen_op_mftc0_tcschedule();
4292
                break;
4293
            case 7:
4294
                gen_op_mftc0_tcschefback();
4295
                break;
4296
            default:
4297
                gen_mfc0(env, ctx, rt, sel);
4298
                break;
4299
            }
4300
            break;
4301
        case 10:
4302
            switch (sel) {
4303
            case 0:
4304
                gen_op_mftc0_entryhi();
4305
                break;
4306
            default:
4307
                gen_mfc0(env, ctx, rt, sel);
4308
                break;
4309
            }
4310
        case 12:
4311
            switch (sel) {
4312
            case 0:
4313
                gen_op_mftc0_status();
4314
                break;
4315
            default:
4316
                gen_mfc0(env, ctx, rt, sel);
4317
                break;
4318
            }
4319
        case 23:
4320
            switch (sel) {
4321
            case 0:
4322
                gen_op_mftc0_debug();
4323
                break;
4324
            default:
4325
                gen_mfc0(env, ctx, rt, sel);
4326
                break;
4327
            }
4328
            break;
4329
        default:
4330
            gen_mfc0(env, ctx, rt, sel);
4331
        }
4332
    } else switch (sel) {
4333
    /* GPR registers. */
4334
    case 0:
4335
        gen_op_mftgpr(rt);
4336
        break;
4337
    /* Auxiliary CPU registers */
4338
    case 1:
4339
        switch (rt) {
4340
        case 0:
4341
            gen_op_mftlo(0);
4342
            break;
4343
        case 1:
4344
            gen_op_mfthi(0);
4345
            break;
4346
        case 2:
4347
            gen_op_mftacx(0);
4348
            break;
4349
        case 4:
4350
            gen_op_mftlo(1);
4351
            break;
4352
        case 5:
4353
            gen_op_mfthi(1);
4354
            break;
4355
        case 6:
4356
            gen_op_mftacx(1);
4357
            break;
4358
        case 8:
4359
            gen_op_mftlo(2);
4360
            break;
4361
        case 9:
4362
            gen_op_mfthi(2);
4363
            break;
4364
        case 10:
4365
            gen_op_mftacx(2);
4366
            break;
4367
        case 12:
4368
            gen_op_mftlo(3);
4369
            break;
4370
        case 13:
4371
            gen_op_mfthi(3);
4372
            break;
4373
        case 14:
4374
            gen_op_mftacx(3);
4375
            break;
4376
        case 16:
4377
            gen_op_mftdsp();
4378
            break;
4379
        default:
4380
            goto die;
4381
        }
4382
        break;
4383
    /* Floating point (COP1). */
4384
    case 2:
4385
        /* XXX: For now we support only a single FPU context. */
4386
        if (h == 0) {
4387
            GEN_LOAD_FREG_FTN(WT0, rt);
4388
            gen_op_mfc1();
4389
        } else {
4390
            GEN_LOAD_FREG_FTN(WTH0, rt);
4391
            gen_op_mfhc1();
4392
        }
4393
        break;
4394
    case 3:
4395
        /* XXX: For now we support only a single FPU context. */
4396
        gen_op_cfc1(rt);
4397
        break;
4398
    /* COP2: Not implemented. */
4399
    case 4:
4400
    case 5:
4401
        /* fall through */
4402
    default:
4403
        goto die;
4404
    }
4405
#if defined MIPS_DEBUG_DISAS
4406
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4407
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4408
                rt, u, sel, h);
4409
    }
4410
#endif
4411
    return;
4412

    
4413
die:
4414
#if defined MIPS_DEBUG_DISAS
4415
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4416
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4417
                rt, u, sel, h);
4418
    }
4419
#endif
4420
    generate_exception(ctx, EXCP_RI);
4421
}
4422

    
4423
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4424
                     int u, int sel, int h)
4425
{
4426
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4427

    
4428
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4429
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4430
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4431
        /* NOP */ ;
4432
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4433
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4434
        /* NOP */ ;
4435
    else if (u == 0) {
4436
        switch (rd) {
4437
        case 2:
4438
            switch (sel) {
4439
            case 1:
4440
                gen_op_mttc0_tcstatus();
4441
                break;
4442
            case 2:
4443
                gen_op_mttc0_tcbind();
4444
                break;
4445
            case 3:
4446
                gen_op_mttc0_tcrestart();
4447
                break;
4448
            case 4:
4449
                gen_op_mttc0_tchalt();
4450
                break;
4451
            case 5:
4452
                gen_op_mttc0_tccontext();
4453
                break;
4454
            case 6:
4455
                gen_op_mttc0_tcschedule();
4456
                break;
4457
            case 7:
4458
                gen_op_mttc0_tcschefback();
4459
                break;
4460
            default:
4461
                gen_mtc0(env, ctx, rd, sel);
4462
                break;
4463
            }
4464
            break;
4465
        case 10:
4466
            switch (sel) {
4467
            case 0:
4468
                gen_op_mttc0_entryhi();
4469
                break;
4470
            default:
4471
                gen_mtc0(env, ctx, rd, sel);
4472
                break;
4473
            }
4474
        case 12:
4475
            switch (sel) {
4476
            case 0:
4477
                gen_op_mttc0_status();
4478
                break;
4479
            default:
4480
                gen_mtc0(env, ctx, rd, sel);
4481
                break;
4482
            }
4483
        case 23:
4484
            switch (sel) {
4485
            case 0:
4486
                gen_op_mttc0_debug();
4487
                break;
4488
            default:
4489
                gen_mtc0(env, ctx, rd, sel);
4490
                break;
4491
            }
4492
            break;
4493
        default:
4494
            gen_mtc0(env, ctx, rd, sel);
4495
        }
4496
    } else switch (sel) {
4497
    /* GPR registers. */
4498
    case 0:
4499
        gen_op_mttgpr(rd);
4500
        break;
4501
    /* Auxiliary CPU registers */
4502
    case 1:
4503
        switch (rd) {
4504
        case 0:
4505
            gen_op_mttlo(0);
4506
            break;
4507
        case 1:
4508
            gen_op_mtthi(0);
4509
            break;
4510
        case 2:
4511
            gen_op_mttacx(0);
4512
            break;
4513
        case 4:
4514
            gen_op_mttlo(1);
4515
            break;
4516
        case 5:
4517
            gen_op_mtthi(1);
4518
            break;
4519
        case 6:
4520
            gen_op_mttacx(1);
4521
            break;
4522
        case 8:
4523
            gen_op_mttlo(2);
4524
            break;
4525
        case 9:
4526
            gen_op_mtthi(2);
4527
            break;
4528
        case 10:
4529
            gen_op_mttacx(2);
4530
            break;
4531
        case 12:
4532
            gen_op_mttlo(3);
4533
            break;
4534
        case 13:
4535
            gen_op_mtthi(3);
4536
            break;
4537
        case 14:
4538
            gen_op_mttacx(3);
4539
            break;
4540
        case 16:
4541
            gen_op_mttdsp();
4542
            break;
4543
        default:
4544
            goto die;
4545
        }
4546
        break;
4547
    /* Floating point (COP1). */
4548
    case 2:
4549
        /* XXX: For now we support only a single FPU context. */
4550
        if (h == 0) {
4551
            gen_op_mtc1();
4552
            GEN_STORE_FTN_FREG(rd, WT0);
4553
        } else {
4554
            gen_op_mthc1();
4555
            GEN_STORE_FTN_FREG(rd, WTH0);
4556
        }
4557
        break;
4558
    case 3:
4559
        /* XXX: For now we support only a single FPU context. */
4560
        gen_op_ctc1(rd);
4561
        break;
4562
    /* COP2: Not implemented. */
4563
    case 4:
4564
    case 5:
4565
        /* fall through */
4566
    default:
4567
        goto die;
4568
    }
4569
#if defined MIPS_DEBUG_DISAS
4570
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4571
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4572
                rd, u, sel, h);
4573
    }
4574
#endif
4575
    return;
4576

    
4577
die:
4578
#if defined MIPS_DEBUG_DISAS
4579
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4580
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4581
                rd, u, sel, h);
4582
    }
4583
#endif
4584
    generate_exception(ctx, EXCP_RI);
4585
}
4586

    
4587
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4588
{
4589
    const char *opn = "ldst";
4590

    
4591
    switch (opc) {
4592
    case OPC_MFC0:
4593
        if (rt == 0) {
4594
            /* Treat as NOP. */
4595
            return;
4596
        }
4597
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4598
        gen_op_store_T0_gpr(rt);
4599
        opn = "mfc0";
4600
        break;
4601
    case OPC_MTC0:
4602
        GEN_LOAD_REG_TN(T0, rt);
4603
        save_cpu_state(ctx, 1);
4604
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4605
        opn = "mtc0";
4606
        break;
4607
#if defined(TARGET_MIPS64)
4608
    case OPC_DMFC0:
4609
        check_insn(env, ctx, ISA_MIPS3);
4610
        if (rt == 0) {
4611
            /* Treat as NOP. */
4612
            return;
4613
        }
4614
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4615
        gen_op_store_T0_gpr(rt);
4616
        opn = "dmfc0";
4617
        break;
4618
    case OPC_DMTC0:
4619
        check_insn(env, ctx, ISA_MIPS3);
4620
        GEN_LOAD_REG_TN(T0, rt);
4621
        save_cpu_state(ctx, 1);
4622
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4623
        opn = "dmtc0";
4624
        break;
4625
#endif
4626
    case OPC_MFTR:
4627
        check_insn(env, ctx, ASE_MT);
4628
        if (rd == 0) {
4629
            /* Treat as NOP. */
4630
            return;
4631
        }
4632
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4633
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4634
        gen_op_store_T0_gpr(rd);
4635
        opn = "mftr";
4636
        break;
4637
    case OPC_MTTR:
4638
        check_insn(env, ctx, ASE_MT);
4639
        GEN_LOAD_REG_TN(T0, rt);
4640
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4641
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4642
        opn = "mttr";
4643
        break;
4644
    case OPC_TLBWI:
4645
        opn = "tlbwi";
4646
        if (!env->tlb->do_tlbwi)
4647
            goto die;
4648
        gen_op_tlbwi();
4649
        break;
4650
    case OPC_TLBWR:
4651
        opn = "tlbwr";
4652
        if (!env->tlb->do_tlbwr)
4653
            goto die;
4654
        gen_op_tlbwr();
4655
        break;
4656
    case OPC_TLBP:
4657
        opn = "tlbp";
4658
        if (!env->tlb->do_tlbp)
4659
            goto die;
4660
        gen_op_tlbp();
4661
        break;
4662
    case OPC_TLBR:
4663
        opn = "tlbr";
4664
        if (!env->tlb->do_tlbr)
4665
            goto die;
4666
        gen_op_tlbr();
4667
        break;
4668
    case OPC_ERET:
4669
        opn = "eret";
4670
        check_insn(env, ctx, ISA_MIPS2);
4671
        save_cpu_state(ctx, 1);
4672
        gen_op_eret();
4673
        ctx->bstate = BS_EXCP;
4674
        break;
4675
    case OPC_DERET:
4676
        opn = "deret";
4677
        check_insn(env, ctx, ISA_MIPS32);
4678
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4679
            MIPS_INVAL(opn);
4680
            generate_exception(ctx, EXCP_RI);
4681
        } else {
4682
            save_cpu_state(ctx, 1);
4683
            gen_op_deret();
4684
            ctx->bstate = BS_EXCP;
4685
        }
4686
        break;
4687
    case OPC_WAIT:
4688
        opn = "wait";
4689
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4690
        /* If we get an exception, we want to restart at next instruction */
4691
        ctx->pc += 4;
4692
        save_cpu_state(ctx, 1);
4693
        ctx->pc -= 4;
4694
        gen_op_wait();
4695
        ctx->bstate = BS_EXCP;
4696
        break;
4697
    default:
4698
 die:
4699
        MIPS_INVAL(opn);
4700
        generate_exception(ctx, EXCP_RI);
4701
        return;
4702
    }
4703
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4704
}
4705

    
4706
/* CP1 Branches (before delay slot) */
4707
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4708
                                 int32_t cc, int32_t offset)
4709
{
4710
    target_ulong btarget;
4711
    const char *opn = "cp1 cond branch";
4712

    
4713
    if (cc != 0)
4714
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4715

    
4716
    btarget = ctx->pc + 4 + offset;
4717

    
4718
    switch (op) {
4719
    case OPC_BC1F:
4720
        gen_op_bc1f(cc);
4721
        opn = "bc1f";
4722
        goto not_likely;
4723
    case OPC_BC1FL:
4724
        gen_op_bc1f(cc);
4725
        opn = "bc1fl";
4726
        goto likely;
4727
    case OPC_BC1T:
4728
        gen_op_bc1t(cc);
4729
        opn = "bc1t";
4730
        goto not_likely;
4731
    case OPC_BC1TL:
4732
        gen_op_bc1t(cc);
4733
        opn = "bc1tl";
4734
    likely:
4735
        ctx->hflags |= MIPS_HFLAG_BL;
4736
        gen_op_set_bcond();
4737
        gen_op_save_bcond();
4738
        break;
4739
    case OPC_BC1FANY2:
4740
        gen_op_bc1any2f(cc);
4741
        opn = "bc1any2f";
4742
        goto not_likely;
4743
    case OPC_BC1TANY2:
4744
        gen_op_bc1any2t(cc);
4745
        opn = "bc1any2t";
4746
        goto not_likely;
4747
    case OPC_BC1FANY4:
4748
        gen_op_bc1any4f(cc);
4749
        opn = "bc1any4f";
4750
        goto not_likely;
4751
    case OPC_BC1TANY4:
4752
        gen_op_bc1any4t(cc);
4753
        opn = "bc1any4t";
4754
    not_likely:
4755
        ctx->hflags |= MIPS_HFLAG_BC;
4756
        gen_op_set_bcond();
4757
        break;
4758
    default:
4759
        MIPS_INVAL(opn);
4760
        generate_exception (ctx, EXCP_RI);
4761
        return;
4762
    }
4763
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4764
               ctx->hflags, btarget);
4765
    ctx->btarget = btarget;
4766
}
4767

    
4768
/* Coprocessor 1 (FPU) */
4769

    
4770
#define FOP(func, fmt) (((fmt) << 21) | (func))
4771

    
4772
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4773
{
4774
    const char *opn = "cp1 move";
4775

    
4776
    switch (opc) {
4777
    case OPC_MFC1:
4778
        GEN_LOAD_FREG_FTN(WT0, fs);
4779
        gen_op_mfc1();
4780
        GEN_STORE_TN_REG(rt, T0);
4781
        opn = "mfc1";
4782
        break;
4783
    case OPC_MTC1:
4784
        GEN_LOAD_REG_TN(T0, rt);
4785
        gen_op_mtc1();
4786
        GEN_STORE_FTN_FREG(fs, WT0);
4787
        opn = "mtc1";
4788
        break;
4789
    case OPC_CFC1:
4790
        gen_op_cfc1(fs);
4791
        GEN_STORE_TN_REG(rt, T0);
4792
        opn = "cfc1";
4793
        break;
4794
    case OPC_CTC1:
4795
        GEN_LOAD_REG_TN(T0, rt);
4796
        gen_op_ctc1(fs);
4797
        opn = "ctc1";
4798
        break;
4799
    case OPC_DMFC1:
4800
        GEN_LOAD_FREG_FTN(DT0, fs);
4801
        gen_op_dmfc1();
4802
        GEN_STORE_TN_REG(rt, T0);
4803
        opn = "dmfc1";
4804
        break;
4805
    case OPC_DMTC1:
4806
        GEN_LOAD_REG_TN(T0, rt);
4807
        gen_op_dmtc1();
4808
        GEN_STORE_FTN_FREG(fs, DT0);
4809
        opn = "dmtc1";
4810
        break;
4811
    case OPC_MFHC1:
4812
        GEN_LOAD_FREG_FTN(WTH0, fs);
4813
        gen_op_mfhc1();
4814
        GEN_STORE_TN_REG(rt, T0);
4815
        opn = "mfhc1";
4816
        break;
4817
    case OPC_MTHC1:
4818
        GEN_LOAD_REG_TN(T0, rt);
4819
        gen_op_mthc1();
4820
        GEN_STORE_FTN_FREG(fs, WTH0);
4821
        opn = "mthc1";
4822
        break;
4823
    default:
4824
        MIPS_INVAL(opn);
4825
        generate_exception (ctx, EXCP_RI);
4826
        return;
4827
    }
4828
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4829
}
4830

    
4831
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4832
{
4833
    uint32_t ccbit;
4834

    
4835
    GEN_LOAD_REG_TN(T0, rd);
4836
    GEN_LOAD_REG_TN(T1, rs);
4837
    if (cc) {
4838
        ccbit = 1 << (24 + cc);
4839
    } else
4840
        ccbit = 1 << 23;
4841
    if (!tf)
4842
        gen_op_movf(ccbit);
4843
    else
4844
        gen_op_movt(ccbit);
4845
    GEN_STORE_TN_REG(rd, T0);
4846
}
4847

    
4848
#define GEN_MOVCF(fmt)                                                \
4849
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4850
{                                                                     \
4851
    uint32_t ccbit;                                                   \
4852
                                                                      \
4853
    if (cc) {                                                         \
4854
        ccbit = 1 << (24 + cc);                                       \
4855
    } else                                                            \
4856
        ccbit = 1 << 23;                                              \
4857
    if (!tf)                                                          \
4858
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4859
    else                                                              \
4860
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4861
}
4862
GEN_MOVCF(d);
4863
GEN_MOVCF(s);
4864
GEN_MOVCF(ps);
4865
#undef GEN_MOVCF
4866

    
4867
static void gen_farith (DisasContext *ctx, uint32_t op1,
4868
                        int ft, int fs, int fd, int cc)
4869
{
4870
    const char *opn = "farith";
4871
    const char *condnames[] = {
4872
            "c.f",
4873
            "c.un",
4874
            "c.eq",
4875
            "c.ueq",
4876
            "c.olt",
4877
            "c.ult",
4878
            "c.ole",
4879
            "c.ule",
4880
            "c.sf",
4881
            "c.ngle",
4882
            "c.seq",
4883
            "c.ngl",
4884
            "c.lt",
4885
            "c.nge",
4886
            "c.le",
4887
            "c.ngt",
4888
    };
4889
    const char *condnames_abs[] = {
4890
            "cabs.f",
4891
            "cabs.un",
4892
            "cabs.eq",
4893
            "cabs.ueq",
4894
            "cabs.olt",
4895
            "cabs.ult",
4896
            "cabs.ole",
4897
            "cabs.ule",
4898
            "cabs.sf",
4899
            "cabs.ngle",
4900
            "cabs.seq",
4901
            "cabs.ngl",
4902
            "cabs.lt",
4903
            "cabs.nge",
4904
            "cabs.le",
4905
            "cabs.ngt",
4906
    };
4907
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4908
    uint32_t func = ctx->opcode & 0x3f;
4909

    
4910
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4911
    case FOP(0, 16):
4912
        GEN_LOAD_FREG_FTN(WT0, fs);
4913
        GEN_LOAD_FREG_FTN(WT1, ft);
4914
        gen_op_float_add_s();
4915
        GEN_STORE_FTN_FREG(fd, WT2);
4916
        opn = "add.s";
4917
        optype = BINOP;
4918
        break;
4919
    case FOP(1, 16):
4920
        GEN_LOAD_FREG_FTN(WT0, fs);
4921
        GEN_LOAD_FREG_FTN(WT1, ft);
4922
        gen_op_float_sub_s();
4923
        GEN_STORE_FTN_FREG(fd, WT2);
4924
        opn = "sub.s";
4925
        optype = BINOP;
4926
        break;
4927
    case FOP(2, 16):
4928
        GEN_LOAD_FREG_FTN(WT0, fs);
4929
        GEN_LOAD_FREG_FTN(WT1, ft);
4930
        gen_op_float_mul_s();
4931
        GEN_STORE_FTN_FREG(fd, WT2);
4932
        opn = "mul.s";
4933
        optype = BINOP;
4934
        break;
4935
    case FOP(3, 16):
4936
        GEN_LOAD_FREG_FTN(WT0, fs);
4937
        GEN_LOAD_FREG_FTN(WT1, ft);
4938
        gen_op_float_div_s();
4939
        GEN_STORE_FTN_FREG(fd, WT2);
4940
        opn = "div.s";
4941
        optype = BINOP;
4942
        break;
4943
    case FOP(4, 16):
4944
        GEN_LOAD_FREG_FTN(WT0, fs);
4945
        gen_op_float_sqrt_s();
4946
        GEN_STORE_FTN_FREG(fd, WT2);
4947
        opn = "sqrt.s";
4948
        break;
4949
    case FOP(5, 16):
4950
        GEN_LOAD_FREG_FTN(WT0, fs);
4951
        gen_op_float_abs_s();
4952
        GEN_STORE_FTN_FREG(fd, WT2);
4953
        opn = "abs.s";
4954
        break;
4955
    case FOP(6, 16):
4956
        GEN_LOAD_FREG_FTN(WT0, fs);
4957
        gen_op_float_mov_s();
4958
        GEN_STORE_FTN_FREG(fd, WT2);
4959
        opn = "mov.s";
4960
        break;
4961
    case FOP(7, 16):
4962
        GEN_LOAD_FREG_FTN(WT0, fs);
4963
        gen_op_float_chs_s();
4964
        GEN_STORE_FTN_FREG(fd, WT2);
4965
        opn = "neg.s";
4966
        break;
4967
    case FOP(8, 16):
4968
        check_cp1_64bitmode(ctx);
4969
        GEN_LOAD_FREG_FTN(WT0, fs);
4970
        gen_op_float_roundl_s();
4971
        GEN_STORE_FTN_FREG(fd, DT2);
4972
        opn = "round.l.s";
4973
        break;
4974
    case FOP(9, 16):
4975
        check_cp1_64bitmode(ctx);
4976
        GEN_LOAD_FREG_FTN(WT0, fs);
4977
        gen_op_float_truncl_s();
4978
        GEN_STORE_FTN_FREG(fd, DT2);
4979
        opn = "trunc.l.s";
4980
        break;
4981
    case FOP(10, 16):
4982
        check_cp1_64bitmode(ctx);
4983
        GEN_LOAD_FREG_FTN(WT0, fs);
4984
        gen_op_float_ceill_s();
4985
        GEN_STORE_FTN_FREG(fd, DT2);
4986
        opn = "ceil.l.s";
4987
        break;
4988
    case FOP(11, 16):
4989
        check_cp1_64bitmode(ctx);
4990
        GEN_LOAD_FREG_FTN(WT0, fs);
4991
        gen_op_float_floorl_s();
4992
        GEN_STORE_FTN_FREG(fd, DT2);
4993
        opn = "floor.l.s";
4994
        break;
4995
    case FOP(12, 16):
4996
        GEN_LOAD_FREG_FTN(WT0, fs);
4997
        gen_op_float_roundw_s();
4998
        GEN_STORE_FTN_FREG(fd, WT2);
4999
        opn = "round.w.s";
5000
        break;
5001
    case FOP(13, 16):
5002
        GEN_LOAD_FREG_FTN(WT0, fs);
5003
        gen_op_float_truncw_s();
5004
        GEN_STORE_FTN_FREG(fd, WT2);
5005
        opn = "trunc.w.s";
5006
        break;
5007
    case FOP(14, 16):
5008
        GEN_LOAD_FREG_FTN(WT0, fs);
5009
        gen_op_float_ceilw_s();
5010
        GEN_STORE_FTN_FREG(fd, WT2);
5011
        opn = "ceil.w.s";
5012
        break;
5013
    case FOP(15, 16):
5014
        GEN_LOAD_FREG_FTN(WT0, fs);
5015
        gen_op_float_floorw_s();
5016
        GEN_STORE_FTN_FREG(fd, WT2);
5017
        opn = "floor.w.s";
5018
        break;
5019
    case FOP(17, 16):
5020
        GEN_LOAD_REG_TN(T0, ft);
5021
        GEN_LOAD_FREG_FTN(WT0, fs);
5022
        GEN_LOAD_FREG_FTN(WT2, fd);
5023
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5024
        GEN_STORE_FTN_FREG(fd, WT2);
5025
        opn = "movcf.s";
5026
        break;
5027
    case FOP(18, 16):
5028
        GEN_LOAD_REG_TN(T0, ft);
5029
        GEN_LOAD_FREG_FTN(WT0, fs);
5030
        GEN_LOAD_FREG_FTN(WT2, fd);
5031
        gen_op_float_movz_s();
5032
        GEN_STORE_FTN_FREG(fd, WT2);
5033
        opn = "movz.s";
5034
        break;
5035
    case FOP(19, 16):
5036
        GEN_LOAD_REG_TN(T0, ft);
5037
        GEN_LOAD_FREG_FTN(WT0, fs);
5038
        GEN_LOAD_FREG_FTN(WT2, fd);
5039
        gen_op_float_movn_s();
5040
        GEN_STORE_FTN_FREG(fd, WT2);
5041
        opn = "movn.s";
5042
        break;
5043
    case FOP(21, 16):
5044
        GEN_LOAD_FREG_FTN(WT0, fs);
5045
        gen_op_float_recip_s();
5046
        GEN_STORE_FTN_FREG(fd, WT2);
5047
        opn = "recip.s";
5048
        break;
5049
    case FOP(22, 16):
5050
        GEN_LOAD_FREG_FTN(WT0, fs);
5051
        gen_op_float_rsqrt_s();
5052
        GEN_STORE_FTN_FREG(fd, WT2);
5053
        opn = "rsqrt.s";
5054
        break;
5055
    case FOP(28, 16):
5056
        check_cp1_64bitmode(ctx);
5057
        GEN_LOAD_FREG_FTN(WT0, fs);
5058
        GEN_LOAD_FREG_FTN(WT2, fd);
5059
        gen_op_float_recip2_s();
5060
        GEN_STORE_FTN_FREG(fd, WT2);
5061
        opn = "recip2.s";
5062
        break;
5063
    case FOP(29, 16):
5064
        check_cp1_64bitmode(ctx);
5065
        GEN_LOAD_FREG_FTN(WT0, fs);
5066
        gen_op_float_recip1_s();
5067
        GEN_STORE_FTN_FREG(fd, WT2);
5068
        opn = "recip1.s";
5069
        break;
5070
    case FOP(30, 16):
5071
        check_cp1_64bitmode(ctx);
5072
        GEN_LOAD_FREG_FTN(WT0, fs);
5073
        gen_op_float_rsqrt1_s();
5074
        GEN_STORE_FTN_FREG(fd, WT2);
5075
        opn = "rsqrt1.s";
5076
        break;
5077
    case FOP(31, 16):
5078
        check_cp1_64bitmode(ctx);
5079
        GEN_LOAD_FREG_FTN(WT0, fs);
5080
        GEN_LOAD_FREG_FTN(WT2, ft);
5081
        gen_op_float_rsqrt2_s();
5082
        GEN_STORE_FTN_FREG(fd, WT2);
5083
        opn = "rsqrt2.s";
5084
        break;
5085
    case FOP(33, 16):
5086
        check_cp1_registers(ctx, fd);
5087
        GEN_LOAD_FREG_FTN(WT0, fs);
5088
        gen_op_float_cvtd_s();
5089
        GEN_STORE_FTN_FREG(fd, DT2);
5090
        opn = "cvt.d.s";
5091
        break;
5092
    case FOP(36, 16):
5093
        GEN_LOAD_FREG_FTN(WT0, fs);
5094
        gen_op_float_cvtw_s();
5095
        GEN_STORE_FTN_FREG(fd, WT2);
5096
        opn = "cvt.w.s";
5097
        break;
5098
    case FOP(37, 16):
5099
        check_cp1_64bitmode(ctx);
5100
        GEN_LOAD_FREG_FTN(WT0, fs);
5101
        gen_op_float_cvtl_s();
5102
        GEN_STORE_FTN_FREG(fd, DT2);
5103
        opn = "cvt.l.s";
5104
        break;
5105
    case FOP(38, 16):
5106
        check_cp1_64bitmode(ctx);
5107
        GEN_LOAD_FREG_FTN(WT1, fs);
5108
        GEN_LOAD_FREG_FTN(WT0, ft);
5109
        gen_op_float_cvtps_s();
5110
        GEN_STORE_FTN_FREG(fd, DT2);
5111
        opn = "cvt.ps.s";
5112
        break;
5113
    case FOP(48, 16):
5114
    case FOP(49, 16):
5115
    case FOP(50, 16):
5116
    case FOP(51, 16):
5117
    case FOP(52, 16):
5118
    case FOP(53, 16):
5119
    case FOP(54, 16):
5120
    case FOP(55, 16):
5121
    case FOP(56, 16):
5122
    case FOP(57, 16):
5123
    case FOP(58, 16):
5124
    case FOP(59, 16):
5125
    case FOP(60, 16):
5126
    case FOP(61, 16):
5127
    case FOP(62, 16):
5128
    case FOP(63, 16):
5129
        GEN_LOAD_FREG_FTN(WT0, fs);
5130
        GEN_LOAD_FREG_FTN(WT1, ft);
5131
        if (ctx->opcode & (1 << 6)) {
5132
            check_cp1_64bitmode(ctx);
5133
            gen_cmpabs_s(func-48, cc);
5134
            opn = condnames_abs[func-48];
5135
        } else {
5136
            gen_cmp_s(func-48, cc);
5137
            opn = condnames[func-48];
5138
        }
5139
        break;
5140
    case FOP(0, 17):
5141
        check_cp1_registers(ctx, fs | ft | fd);
5142
        GEN_LOAD_FREG_FTN(DT0, fs);
5143
        GEN_LOAD_FREG_FTN(DT1, ft);
5144
        gen_op_float_add_d();
5145
        GEN_STORE_FTN_FREG(fd, DT2);
5146
        opn = "add.d";
5147
        optype = BINOP;
5148
        break;
5149
    case FOP(1, 17):
5150
        check_cp1_registers(ctx, fs | ft | fd);
5151
        GEN_LOAD_FREG_FTN(DT0, fs);
5152
        GEN_LOAD_FREG_FTN(DT1, ft);
5153
        gen_op_float_sub_d();
5154
        GEN_STORE_FTN_FREG(fd, DT2);
5155
        opn = "sub.d";
5156
        optype = BINOP;
5157
        break;
5158
    case FOP(2, 17):
5159
        check_cp1_registers(ctx, fs | ft | fd);
5160
        GEN_LOAD_FREG_FTN(DT0, fs);
5161
        GEN_LOAD_FREG_FTN(DT1, ft);
5162
        gen_op_float_mul_d();
5163
        GEN_STORE_FTN_FREG(fd, DT2);
5164
        opn = "mul.d";
5165
        optype = BINOP;
5166
        break;
5167
    case FOP(3, 17):
5168
        check_cp1_registers(ctx, fs | ft | fd);
5169
        GEN_LOAD_FREG_FTN(DT0, fs);
5170
        GEN_LOAD_FREG_FTN(DT1, ft);
5171
        gen_op_float_div_d();
5172
        GEN_STORE_FTN_FREG(fd, DT2);
5173
        opn = "div.d";
5174
        optype = BINOP;
5175
        break;
5176
    case FOP(4, 17):
5177
        check_cp1_registers(ctx, fs | fd);
5178
        GEN_LOAD_FREG_FTN(DT0, fs);
5179
        gen_op_float_sqrt_d();
5180
        GEN_STORE_FTN_FREG(fd, DT2);
5181
        opn = "sqrt.d";
5182
        break;
5183
    case FOP(5, 17):
5184
        check_cp1_registers(ctx, fs | fd);
5185
        GEN_LOAD_FREG_FTN(DT0, fs);
5186
        gen_op_float_abs_d();
5187
        GEN_STORE_FTN_FREG(fd, DT2);
5188
        opn = "abs.d";
5189
        break;
5190
    case FOP(6, 17):
5191
        check_cp1_registers(ctx, fs | fd);
5192
        GEN_LOAD_FREG_FTN(DT0, fs);
5193
        gen_op_float_mov_d();
5194
        GEN_STORE_FTN_FREG(fd, DT2);
5195
        opn = "mov.d";
5196
        break;
5197
    case FOP(7, 17):
5198
        check_cp1_registers(ctx, fs | fd);
5199
        GEN_LOAD_FREG_FTN(DT0, fs);
5200
        gen_op_float_chs_d();
5201
        GEN_STORE_FTN_FREG(fd, DT2);
5202
        opn = "neg.d";
5203
        break;
5204
    case FOP(8, 17):
5205
        check_cp1_64bitmode(ctx);
5206
        GEN_LOAD_FREG_FTN(DT0, fs);
5207
        gen_op_float_roundl_d();
5208
        GEN_STORE_FTN_FREG(fd, DT2);
5209
        opn = "round.l.d";
5210
        break;
5211
    case FOP(9, 17):
5212
        check_cp1_64bitmode(ctx);
5213
        GEN_LOAD_FREG_FTN(DT0, fs);
5214
        gen_op_float_truncl_d();
5215
        GEN_STORE_FTN_FREG(fd, DT2);
5216
        opn = "trunc.l.d";
5217
        break;
5218
    case FOP(10, 17):
5219
        check_cp1_64bitmode(ctx);
5220
        GEN_LOAD_FREG_FTN(DT0, fs);
5221
        gen_op_float_ceill_d();
5222
        GEN_STORE_FTN_FREG(fd, DT2);
5223
        opn = "ceil.l.d";
5224
        break;
5225
    case FOP(11, 17):
5226
        check_cp1_64bitmode(ctx);
5227
        GEN_LOAD_FREG_FTN(DT0, fs);
5228
        gen_op_float_floorl_d();
5229
        GEN_STORE_FTN_FREG(fd, DT2);
5230
        opn = "floor.l.d";
5231
        break;
5232
    case FOP(12, 17):
5233
        check_cp1_registers(ctx, fs);
5234
        GEN_LOAD_FREG_FTN(DT0, fs);
5235
        gen_op_float_roundw_d();
5236
        GEN_STORE_FTN_FREG(fd, WT2);
5237
        opn = "round.w.d";
5238
        break;
5239
    case FOP(13, 17):
5240
        check_cp1_registers(ctx, fs);
5241
        GEN_LOAD_FREG_FTN(DT0, fs);
5242
        gen_op_float_truncw_d();
5243
        GEN_STORE_FTN_FREG(fd, WT2);
5244
        opn = "trunc.w.d";
5245
        break;
5246
    case FOP(14, 17):
5247
        check_cp1_registers(ctx, fs);
5248
        GEN_LOAD_FREG_FTN(DT0, fs);
5249
        gen_op_float_ceilw_d();
5250
        GEN_STORE_FTN_FREG(fd, WT2);
5251
        opn = "ceil.w.d";
5252
        break;
5253
    case FOP(15, 17):
5254
        check_cp1_registers(ctx, fs);
5255
        GEN_LOAD_FREG_FTN(DT0, fs);
5256
        gen_op_float_floorw_d();
5257
        GEN_STORE_FTN_FREG(fd, WT2);
5258
        opn = "floor.w.d";
5259
        break;
5260
    case FOP(17, 17):
5261
        GEN_LOAD_REG_TN(T0, ft);
5262
        GEN_LOAD_FREG_FTN(DT0, fs);
5263
        GEN_LOAD_FREG_FTN(DT2, fd);
5264
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5265
        GEN_STORE_FTN_FREG(fd, DT2);
5266
        opn = "movcf.d";
5267
        break;
5268
    case FOP(18, 17):
5269
        GEN_LOAD_REG_TN(T0, ft);
5270
        GEN_LOAD_FREG_FTN(DT0, fs);
5271
        GEN_LOAD_FREG_FTN(DT2, fd);
5272
        gen_op_float_movz_d();
5273
        GEN_STORE_FTN_FREG(fd, DT2);
5274
        opn = "movz.d";
5275
        break;
5276
    case FOP(19, 17):
5277
        GEN_LOAD_REG_TN(T0, ft);
5278
        GEN_LOAD_FREG_FTN(DT0, fs);
5279
        GEN_LOAD_FREG_FTN(DT2, fd);
5280
        gen_op_float_movn_d();
5281
        GEN_STORE_FTN_FREG(fd, DT2);
5282
        opn = "movn.d";
5283
        break;
5284
    case FOP(21, 17):
5285
        check_cp1_registers(ctx, fs | fd);
5286
        GEN_LOAD_FREG_FTN(DT0, fs);
5287
        gen_op_float_recip_d();
5288
        GEN_STORE_FTN_FREG(fd, DT2);
5289
        opn = "recip.d";
5290
        break;
5291
    case FOP(22, 17):
5292
        check_cp1_registers(ctx, fs | fd);
5293
        GEN_LOAD_FREG_FTN(DT0, fs);
5294
        gen_op_float_rsqrt_d();
5295
        GEN_STORE_FTN_FREG(fd, DT2);
5296
        opn = "rsqrt.d";
5297
        break;
5298
    case FOP(28, 17):
5299
        check_cp1_64bitmode(ctx);
5300
        GEN_LOAD_FREG_FTN(DT0, fs);
5301
        GEN_LOAD_FREG_FTN(DT2, ft);
5302
        gen_op_float_recip2_d();
5303
        GEN_STORE_FTN_FREG(fd, DT2);
5304
        opn = "recip2.d";
5305
        break;
5306
    case FOP(29, 17):
5307
        check_cp1_64bitmode(ctx);
5308
        GEN_LOAD_FREG_FTN(DT0, fs);
5309
        gen_op_float_recip1_d();
5310
        GEN_STORE_FTN_FREG(fd, DT2);
5311
        opn = "recip1.d";
5312
        break;
5313
    case FOP(30, 17):
5314
        check_cp1_64bitmode(ctx);
5315
        GEN_LOAD_FREG_FTN(DT0, fs);
5316
        gen_op_float_rsqrt1_d();
5317
        GEN_STORE_FTN_FREG(fd, DT2);
5318
        opn = "rsqrt1.d";
5319
        break;
5320
    case FOP(31, 17):
5321
        check_cp1_64bitmode(ctx);
5322
        GEN_LOAD_FREG_FTN(DT0, fs);
5323
        GEN_LOAD_FREG_FTN(DT2, ft);
5324
        gen_op_float_rsqrt2_d();
5325
        GEN_STORE_FTN_FREG(fd, DT2);
5326
        opn = "rsqrt2.d";
5327
        break;
5328
    case FOP(48, 17):
5329
    case FOP(49, 17):
5330
    case FOP(50, 17):
5331
    case FOP(51, 17):
5332
    case FOP(52, 17):
5333
    case FOP(53, 17):
5334
    case FOP(54, 17):
5335
    case FOP(55, 17):
5336
    case FOP(56, 17):
5337
    case FOP(57, 17):
5338
    case FOP(58, 17):
5339
    case FOP(59, 17):
5340
    case FOP(60, 17):
5341
    case FOP(61, 17):
5342
    case FOP(62, 17):
5343
    case FOP(63, 17):
5344
        GEN_LOAD_FREG_FTN(DT0, fs);
5345
        GEN_LOAD_FREG_FTN(DT1, ft);
5346
        if (ctx->opcode & (1 << 6)) {
5347
            check_cp1_64bitmode(ctx);
5348
            gen_cmpabs_d(func-48, cc);
5349
            opn = condnames_abs[func-48];
5350
        } else {
5351
            check_cp1_registers(ctx, fs | ft);
5352
            gen_cmp_d(func-48, cc);
5353
            opn = condnames[func-48];
5354
        }
5355
        break;
5356
    case FOP(32, 17):
5357
        check_cp1_registers(ctx, fs);
5358
        GEN_LOAD_FREG_FTN(DT0, fs);
5359
        gen_op_float_cvts_d();
5360
        GEN_STORE_FTN_FREG(fd, WT2);
5361
        opn = "cvt.s.d";
5362
        break;
5363
    case FOP(36, 17):
5364
        check_cp1_registers(ctx, fs);
5365
        GEN_LOAD_FREG_FTN(DT0, fs);
5366
        gen_op_float_cvtw_d();
5367
        GEN_STORE_FTN_FREG(fd, WT2);
5368
        opn = "cvt.w.d";
5369
        break;
5370
    case FOP(37, 17):
5371
        check_cp1_64bitmode(ctx);
5372
        GEN_LOAD_FREG_FTN(DT0, fs);
5373
        gen_op_float_cvtl_d();
5374
        GEN_STORE_FTN_FREG(fd, DT2);
5375
        opn = "cvt.l.d";
5376
        break;
5377
    case FOP(32, 20):
5378
        GEN_LOAD_FREG_FTN(WT0, fs);
5379
        gen_op_float_cvts_w();
5380
        GEN_STORE_FTN_FREG(fd, WT2);
5381
        opn = "cvt.s.w";
5382
        break;
5383
    case FOP(33, 20):
5384
        check_cp1_registers(ctx, fd);
5385
        GEN_LOAD_FREG_FTN(WT0, fs);
5386
        gen_op_float_cvtd_w();
5387
        GEN_STORE_FTN_FREG(fd, DT2);
5388
        opn = "cvt.d.w";
5389
        break;
5390
    case FOP(32, 21):
5391
        check_cp1_64bitmode(ctx);
5392
        GEN_LOAD_FREG_FTN(DT0, fs);
5393
        gen_op_float_cvts_l();
5394
        GEN_STORE_FTN_FREG(fd, WT2);
5395
        opn = "cvt.s.l";
5396
        break;
5397
    case FOP(33, 21):
5398
        check_cp1_64bitmode(ctx);
5399
        GEN_LOAD_FREG_FTN(DT0, fs);
5400
        gen_op_float_cvtd_l();
5401
        GEN_STORE_FTN_FREG(fd, DT2);
5402
        opn = "cvt.d.l";
5403
        break;
5404
    case FOP(38, 20):
5405
        check_cp1_64bitmode(ctx);
5406
        GEN_LOAD_FREG_FTN(WT0, fs);
5407
        GEN_LOAD_FREG_FTN(WTH0, fs);
5408
        gen_op_float_cvtps_pw();
5409
        GEN_STORE_FTN_FREG(fd, WT2);
5410
        GEN_STORE_FTN_FREG(fd, WTH2);
5411
        opn = "cvt.ps.pw";
5412
        break;
5413
    case FOP(0, 22):
5414
        check_cp1_64bitmode(ctx);
5415
        GEN_LOAD_FREG_FTN(WT0, fs);
5416
        GEN_LOAD_FREG_FTN(WTH0, fs);
5417
        GEN_LOAD_FREG_FTN(WT1, ft);
5418
        GEN_LOAD_FREG_FTN(WTH1, ft);
5419
        gen_op_float_add_ps();
5420
        GEN_STORE_FTN_FREG(fd, WT2);
5421
        GEN_STORE_FTN_FREG(fd, WTH2);
5422
        opn = "add.ps";
5423
        break;
5424
    case FOP(1, 22):
5425
        check_cp1_64bitmode(ctx);
5426
        GEN_LOAD_FREG_FTN(WT0, fs);
5427
        GEN_LOAD_FREG_FTN(WTH0, fs);
5428
        GEN_LOAD_FREG_FTN(WT1, ft);
5429
        GEN_LOAD_FREG_FTN(WTH1, ft);
5430
        gen_op_float_sub_ps();
5431
        GEN_STORE_FTN_FREG(fd, WT2);
5432
        GEN_STORE_FTN_FREG(fd, WTH2);
5433
        opn = "sub.ps";
5434
        break;
5435
    case FOP(2, 22):
5436
        check_cp1_64bitmode(ctx);
5437
        GEN_LOAD_FREG_FTN(WT0, fs);
5438
        GEN_LOAD_FREG_FTN(WTH0, fs);
5439
        GEN_LOAD_FREG_FTN(WT1, ft);
5440
        GEN_LOAD_FREG_FTN(WTH1, ft);
5441
        gen_op_float_mul_ps();
5442
        GEN_STORE_FTN_FREG(fd, WT2);
5443
        GEN_STORE_FTN_FREG(fd, WTH2);
5444
        opn = "mul.ps";
5445
        break;
5446
    case FOP(5, 22):
5447
        check_cp1_64bitmode(ctx);
5448
        GEN_LOAD_FREG_FTN(WT0, fs);
5449
        GEN_LOAD_FREG_FTN(WTH0, fs);
5450
        gen_op_float_abs_ps();
5451
        GEN_STORE_FTN_FREG(fd, WT2);
5452
        GEN_STORE_FTN_FREG(fd, WTH2);
5453
        opn = "abs.ps";
5454
        break;
5455
    case FOP(6, 22):
5456
        check_cp1_64bitmode(ctx);
5457
        GEN_LOAD_FREG_FTN(WT0, fs);
5458
        GEN_LOAD_FREG_FTN(WTH0, fs);
5459
        gen_op_float_mov_ps();
5460
        GEN_STORE_FTN_FREG(fd, WT2);
5461
        GEN_STORE_FTN_FREG(fd, WTH2);
5462
        opn = "mov.ps";
5463
        break;
5464
    case FOP(7, 22):
5465
        check_cp1_64bitmode(ctx);
5466
        GEN_LOAD_FREG_FTN(WT0, fs);
5467
        GEN_LOAD_FREG_FTN(WTH0, fs);
5468
        gen_op_float_chs_ps();
5469
        GEN_STORE_FTN_FREG(fd, WT2);
5470
        GEN_STORE_FTN_FREG(fd, WTH2);
5471
        opn = "neg.ps";
5472
        break;
5473
    case FOP(17, 22):
5474
        check_cp1_64bitmode(ctx);
5475
        GEN_LOAD_REG_TN(T0, ft);
5476
        GEN_LOAD_FREG_FTN(WT0, fs);
5477
        GEN_LOAD_FREG_FTN(WTH0, fs);
5478
        GEN_LOAD_FREG_FTN(WT2, fd);
5479
        GEN_LOAD_FREG_FTN(WTH2, fd);
5480
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5481
        GEN_STORE_FTN_FREG(fd, WT2);
5482
        GEN_STORE_FTN_FREG(fd, WTH2);
5483
        opn = "movcf.ps";
5484
        break;
5485
    case FOP(18, 22):
5486
        check_cp1_64bitmode(ctx);
5487
        GEN_LOAD_REG_TN(T0, ft);
5488
        GEN_LOAD_FREG_FTN(WT0, fs);
5489
        GEN_LOAD_FREG_FTN(WTH0, fs);
5490
        GEN_LOAD_FREG_FTN(WT2, fd);
5491
        GEN_LOAD_FREG_FTN(WTH2, fd);
5492
        gen_op_float_movz_ps();
5493
        GEN_STORE_FTN_FREG(fd, WT2);
5494
        GEN_STORE_FTN_FREG(fd, WTH2);
5495
        opn = "movz.ps";
5496
        break;
5497
    case FOP(19, 22):
5498
        check_cp1_64bitmode(ctx);
5499
        GEN_LOAD_REG_TN(T0, ft);
5500
        GEN_LOAD_FREG_FTN(WT0, fs);
5501
        GEN_LOAD_FREG_FTN(WTH0, fs);
5502
        GEN_LOAD_FREG_FTN(WT2, fd);
5503
        GEN_LOAD_FREG_FTN(WTH2, fd);
5504
        gen_op_float_movn_ps();
5505
        GEN_STORE_FTN_FREG(fd, WT2);
5506
        GEN_STORE_FTN_FREG(fd, WTH2);
5507
        opn = "movn.ps";
5508
        break;
5509
    case FOP(24, 22):
5510
        check_cp1_64bitmode(ctx);
5511
        GEN_LOAD_FREG_FTN(WT0, ft);
5512
        GEN_LOAD_FREG_FTN(WTH0, ft);
5513
        GEN_LOAD_FREG_FTN(WT1, fs);
5514
        GEN_LOAD_FREG_FTN(WTH1, fs);
5515
        gen_op_float_addr_ps();
5516
        GEN_STORE_FTN_FREG(fd, WT2);
5517
        GEN_STORE_FTN_FREG(fd, WTH2);
5518
        opn = "addr.ps";
5519
        break;
5520
    case FOP(26, 22):
5521
        check_cp1_64bitmode(ctx);
5522
        GEN_LOAD_FREG_FTN(WT0, ft);
5523
        GEN_LOAD_FREG_FTN(WTH0, ft);
5524
        GEN_LOAD_FREG_FTN(WT1, fs);
5525
        GEN_LOAD_FREG_FTN(WTH1, fs);
5526
        gen_op_float_mulr_ps();
5527
        GEN_STORE_FTN_FREG(fd, WT2);
5528
        GEN_STORE_FTN_FREG(fd, WTH2);
5529
        opn = "mulr.ps";
5530
        break;
5531
    case FOP(28, 22):
5532
        check_cp1_64bitmode(ctx);
5533
        GEN_LOAD_FREG_FTN(WT0, fs);
5534
        GEN_LOAD_FREG_FTN(WTH0, fs);
5535
        GEN_LOAD_FREG_FTN(WT2, fd);
5536
        GEN_LOAD_FREG_FTN(WTH2, fd);
5537
        gen_op_float_recip2_ps();
5538
        GEN_STORE_FTN_FREG(fd, WT2);
5539
        GEN_STORE_FTN_FREG(fd, WTH2);
5540
        opn = "recip2.ps";
5541
        break;
5542
    case FOP(29, 22):
5543
        check_cp1_64bitmode(ctx);
5544
        GEN_LOAD_FREG_FTN(WT0, fs);
5545
        GEN_LOAD_FREG_FTN(WTH0, fs);
5546
        gen_op_float_recip1_ps();
5547
        GEN_STORE_FTN_FREG(fd, WT2);
5548
        GEN_STORE_FTN_FREG(fd, WTH2);
5549
        opn = "recip1.ps";
5550
        break;
5551
    case FOP(30, 22):
5552
        check_cp1_64bitmode(ctx);
5553
        GEN_LOAD_FREG_FTN(WT0, fs);
5554
        GEN_LOAD_FREG_FTN(WTH0, fs);
5555
        gen_op_float_rsqrt1_ps();
5556
        GEN_STORE_FTN_FREG(fd, WT2);
5557
        GEN_STORE_FTN_FREG(fd, WTH2);
5558
        opn = "rsqrt1.ps";
5559
        break;
5560
    case FOP(31, 22):
5561
        check_cp1_64bitmode(ctx);
5562
        GEN_LOAD_FREG_FTN(WT0, fs);
5563
        GEN_LOAD_FREG_FTN(WTH0, fs);
5564
        GEN_LOAD_FREG_FTN(WT2, ft);
5565
        GEN_LOAD_FREG_FTN(WTH2, ft);
5566
        gen_op_float_rsqrt2_ps();
5567
        GEN_STORE_FTN_FREG(fd, WT2);
5568
        GEN_STORE_FTN_FREG(fd, WTH2);
5569
        opn = "rsqrt2.ps";
5570
        break;
5571
    case FOP(32, 22):
5572
        check_cp1_64bitmode(ctx);
5573
        GEN_LOAD_FREG_FTN(WTH0, fs);
5574
        gen_op_float_cvts_pu();
5575
        GEN_STORE_FTN_FREG(fd, WT2);
5576
        opn = "cvt.s.pu";
5577
        break;
5578
    case FOP(36, 22):
5579
        check_cp1_64bitmode(ctx);
5580
        GEN_LOAD_FREG_FTN(WT0, fs);
5581
        GEN_LOAD_FREG_FTN(WTH0, fs);
5582
        gen_op_float_cvtpw_ps();
5583
        GEN_STORE_FTN_FREG(fd, WT2);
5584
        GEN_STORE_FTN_FREG(fd, WTH2);
5585
        opn = "cvt.pw.ps";
5586
        break;
5587
    case FOP(40, 22):
5588
        check_cp1_64bitmode(ctx);
5589
        GEN_LOAD_FREG_FTN(WT0, fs);
5590
        gen_op_float_cvts_pl();
5591
        GEN_STORE_FTN_FREG(fd, WT2);
5592
        opn = "cvt.s.pl";
5593
        break;
5594
    case FOP(44, 22):
5595
        check_cp1_64bitmode(ctx);
5596
        GEN_LOAD_FREG_FTN(WT0, fs);
5597
        GEN_LOAD_FREG_FTN(WT1, ft);
5598
        gen_op_float_pll_ps();
5599
        GEN_STORE_FTN_FREG(fd, DT2);
5600
        opn = "pll.ps";
5601
        break;
5602
    case FOP(45, 22):
5603
        check_cp1_64bitmode(ctx);
5604
        GEN_LOAD_FREG_FTN(WT0, fs);
5605
        GEN_LOAD_FREG_FTN(WTH1, ft);
5606
        gen_op_float_plu_ps();
5607
        GEN_STORE_FTN_FREG(fd, DT2);
5608
        opn = "plu.ps";
5609
        break;
5610
    case FOP(46, 22):
5611
        check_cp1_64bitmode(ctx);
5612
        GEN_LOAD_FREG_FTN(WTH0, fs);
5613
        GEN_LOAD_FREG_FTN(WT1, ft);
5614
        gen_op_float_pul_ps();
5615
        GEN_STORE_FTN_FREG(fd, DT2);
5616
        opn = "pul.ps";
5617
        break;
5618
    case FOP(47, 22):
5619
        check_cp1_64bitmode(ctx);
5620
        GEN_LOAD_FREG_FTN(WTH0, fs);
5621
        GEN_LOAD_FREG_FTN(WTH1, ft);
5622
        gen_op_float_puu_ps();
5623
        GEN_STORE_FTN_FREG(fd, DT2);
5624
        opn = "puu.ps";
5625
        break;
5626
    case FOP(48, 22):
5627
    case FOP(49, 22):
5628
    case FOP(50, 22):
5629
    case FOP(51, 22):
5630
    case FOP(52, 22):
5631
    case FOP(53, 22):
5632
    case FOP(54, 22):
5633
    case FOP(55, 22):
5634
    case FOP(56, 22):
5635
    case FOP(57, 22):
5636
    case FOP(58, 22):
5637
    case FOP(59, 22):
5638
    case FOP(60, 22):
5639
    case FOP(61, 22):
5640
    case FOP(62, 22):
5641
    case FOP(63, 22):
5642
        check_cp1_64bitmode(ctx);
5643
        GEN_LOAD_FREG_FTN(WT0, fs);
5644
        GEN_LOAD_FREG_FTN(WTH0, fs);
5645
        GEN_LOAD_FREG_FTN(WT1, ft);
5646
        GEN_LOAD_FREG_FTN(WTH1, ft);
5647
        if (ctx->opcode & (1 << 6)) {
5648
            gen_cmpabs_ps(func-48, cc);
5649
            opn = condnames_abs[func-48];
5650
        } else {
5651
            gen_cmp_ps(func-48, cc);
5652
            opn = condnames[func-48];
5653
        }
5654
        break;
5655
    default:
5656
        MIPS_INVAL(opn);
5657
        generate_exception (ctx, EXCP_RI);
5658
        return;
5659
    }
5660
    switch (optype) {
5661
    case BINOP:
5662
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5663
        break;
5664
    case CMPOP:
5665
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5666
        break;
5667
    default:
5668
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5669
        break;
5670
    }
5671
}
5672

    
5673
/* Coprocessor 3 (FPU) */
5674
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5675
                           int fd, int fs, int base, int index)
5676
{
5677
    const char *opn = "extended float load/store";
5678
    int store = 0;
5679

    
5680
    /* All of those work only on 64bit FPUs. */
5681
    check_cp1_64bitmode(ctx);
5682
    if (base == 0) {
5683
        if (index == 0)
5684
            gen_op_reset_T0();
5685
        else
5686
            GEN_LOAD_REG_TN(T0, index);
5687
    } else if (index == 0) {
5688
        GEN_LOAD_REG_TN(T0, base);
5689
    } else {
5690
        GEN_LOAD_REG_TN(T0, base);
5691
        GEN_LOAD_REG_TN(T1, index);
5692
        gen_op_addr_add();
5693
    }
5694
    /* Don't do NOP if destination is zero: we must perform the actual
5695
       memory access. */
5696
    switch (opc) {
5697
    case OPC_LWXC1:
5698
        op_ldst(lwc1);
5699
        GEN_STORE_FTN_FREG(fd, WT0);
5700
        opn = "lwxc1";
5701
        break;
5702
    case OPC_LDXC1:
5703
        op_ldst(ldc1);
5704
        GEN_STORE_FTN_FREG(fd, DT0);
5705
        opn = "ldxc1";
5706
        break;
5707
    case OPC_LUXC1:
5708
        op_ldst(luxc1);
5709
        GEN_STORE_FTN_FREG(fd, DT0);
5710
        opn = "luxc1";
5711
        break;
5712
    case OPC_SWXC1:
5713
        GEN_LOAD_FREG_FTN(WT0, fs);
5714
        op_ldst(swc1);
5715
        opn = "swxc1";
5716
        store = 1;
5717
        break;
5718
    case OPC_SDXC1:
5719
        GEN_LOAD_FREG_FTN(DT0, fs);
5720
        op_ldst(sdc1);
5721
        opn = "sdxc1";
5722
        store = 1;
5723
        break;
5724
    case OPC_SUXC1:
5725
        GEN_LOAD_FREG_FTN(DT0, fs);
5726
        op_ldst(suxc1);
5727
        opn = "suxc1";
5728
        store = 1;
5729
        break;
5730
    default:
5731
        MIPS_INVAL(opn);
5732
        generate_exception(ctx, EXCP_RI);
5733
        return;
5734
    }
5735
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5736
               regnames[index], regnames[base]);
5737
}
5738

    
5739
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5740
                            int fd, int fr, int fs, int ft)
5741
{
5742
    const char *opn = "flt3_arith";
5743

    
5744
    /* All of those work only on 64bit FPUs. */
5745
    check_cp1_64bitmode(ctx);
5746
    switch (opc) {
5747
    case OPC_ALNV_PS:
5748
        GEN_LOAD_REG_TN(T0, fr);
5749
        GEN_LOAD_FREG_FTN(DT0, fs);
5750
        GEN_LOAD_FREG_FTN(DT1, ft);
5751
        gen_op_float_alnv_ps();
5752
        GEN_STORE_FTN_FREG(fd, DT2);
5753
        opn = "alnv.ps";
5754
        break;
5755
    case OPC_MADD_S:
5756
        GEN_LOAD_FREG_FTN(WT0, fs);
5757
        GEN_LOAD_FREG_FTN(WT1, ft);
5758
        GEN_LOAD_FREG_FTN(WT2, fr);
5759
        gen_op_float_muladd_s();
5760
        GEN_STORE_FTN_FREG(fd, WT2);
5761
        opn = "madd.s";
5762
        break;
5763
    case OPC_MADD_D:
5764
        GEN_LOAD_FREG_FTN(DT0, fs);
5765
        GEN_LOAD_FREG_FTN(DT1, ft);
5766
        GEN_LOAD_FREG_FTN(DT2, fr);
5767
        gen_op_float_muladd_d();
5768
        GEN_STORE_FTN_FREG(fd, DT2);
5769
        opn = "madd.d";
5770
        break;
5771
    case OPC_MADD_PS:
5772
        GEN_LOAD_FREG_FTN(WT0, fs);
5773
        GEN_LOAD_FREG_FTN(WTH0, fs);
5774
        GEN_LOAD_FREG_FTN(WT1, ft);
5775
        GEN_LOAD_FREG_FTN(WTH1, ft);
5776
        GEN_LOAD_FREG_FTN(WT2, fr);
5777
        GEN_LOAD_FREG_FTN(WTH2, fr);
5778
        gen_op_float_muladd_ps();
5779
        GEN_STORE_FTN_FREG(fd, WT2);
5780
        GEN_STORE_FTN_FREG(fd, WTH2);
5781
        opn = "madd.ps";
5782
        break;
5783
    case OPC_MSUB_S:
5784
        GEN_LOAD_FREG_FTN(WT0, fs);
5785
        GEN_LOAD_FREG_FTN(WT1, ft);
5786
        GEN_LOAD_FREG_FTN(WT2, fr);
5787
        gen_op_float_mulsub_s();
5788
        GEN_STORE_FTN_FREG(fd, WT2);
5789
        opn = "msub.s";
5790
        break;
5791
    case OPC_MSUB_D:
5792
        GEN_LOAD_FREG_FTN(DT0, fs);
5793
        GEN_LOAD_FREG_FTN(DT1, ft);
5794
        GEN_LOAD_FREG_FTN(DT2, fr);
5795
        gen_op_float_mulsub_d();
5796
        GEN_STORE_FTN_FREG(fd, DT2);
5797
        opn = "msub.d";
5798
        break;
5799
    case OPC_MSUB_PS:
5800
        GEN_LOAD_FREG_FTN(WT0, fs);
5801
        GEN_LOAD_FREG_FTN(WTH0, fs);
5802
        GEN_LOAD_FREG_FTN(WT1, ft);
5803
        GEN_LOAD_FREG_FTN(WTH1, ft);
5804
        GEN_LOAD_FREG_FTN(WT2, fr);
5805
        GEN_LOAD_FREG_FTN(WTH2, fr);
5806
        gen_op_float_mulsub_ps();
5807
        GEN_STORE_FTN_FREG(fd, WT2);
5808
        GEN_STORE_FTN_FREG(fd, WTH2);
5809
        opn = "msub.ps";
5810
        break;
5811
    case OPC_NMADD_S:
5812
        GEN_LOAD_FREG_FTN(WT0, fs);
5813
        GEN_LOAD_FREG_FTN(WT1, ft);
5814
        GEN_LOAD_FREG_FTN(WT2, fr);
5815
        gen_op_float_nmuladd_s();
5816
        GEN_STORE_FTN_FREG(fd, WT2);
5817
        opn = "nmadd.s";
5818
        break;
5819
    case OPC_NMADD_D:
5820
        GEN_LOAD_FREG_FTN(DT0, fs);
5821
        GEN_LOAD_FREG_FTN(DT1, ft);
5822
        GEN_LOAD_FREG_FTN(DT2, fr);
5823
        gen_op_float_nmuladd_d();
5824
        GEN_STORE_FTN_FREG(fd, DT2);
5825
        opn = "nmadd.d";
5826
        break;
5827
    case OPC_NMADD_PS:
5828
        GEN_LOAD_FREG_FTN(WT0, fs);
5829
        GEN_LOAD_FREG_FTN(WTH0, fs);
5830
        GEN_LOAD_FREG_FTN(WT1, ft);
5831
        GEN_LOAD_FREG_FTN(WTH1, ft);
5832
        GEN_LOAD_FREG_FTN(WT2, fr);
5833
        GEN_LOAD_FREG_FTN(WTH2, fr);
5834
        gen_op_float_nmuladd_ps();
5835
        GEN_STORE_FTN_FREG(fd, WT2);
5836
        GEN_STORE_FTN_FREG(fd, WTH2);
5837
        opn = "nmadd.ps";
5838
        break;
5839
    case OPC_NMSUB_S:
5840
        GEN_LOAD_FREG_FTN(WT0, fs);
5841
        GEN_LOAD_FREG_FTN(WT1, ft);
5842
        GEN_LOAD_FREG_FTN(WT2, fr);
5843
        gen_op_float_nmulsub_s();
5844
        GEN_STORE_FTN_FREG(fd, WT2);
5845
        opn = "nmsub.s";
5846
        break;
5847
    case OPC_NMSUB_D:
5848
        GEN_LOAD_FREG_FTN(DT0, fs);
5849
        GEN_LOAD_FREG_FTN(DT1, ft);
5850
        GEN_LOAD_FREG_FTN(DT2, fr);
5851
        gen_op_float_nmulsub_d();
5852
        GEN_STORE_FTN_FREG(fd, DT2);
5853
        opn = "nmsub.d";
5854
        break;
5855
    case OPC_NMSUB_PS:
5856
        GEN_LOAD_FREG_FTN(WT0, fs);
5857
        GEN_LOAD_FREG_FTN(WTH0, fs);
5858
        GEN_LOAD_FREG_FTN(WT1, ft);
5859
        GEN_LOAD_FREG_FTN(WTH1, ft);
5860
        GEN_LOAD_FREG_FTN(WT2, fr);
5861
        GEN_LOAD_FREG_FTN(WTH2, fr);
5862
        gen_op_float_nmulsub_ps();
5863
        GEN_STORE_FTN_FREG(fd, WT2);
5864
        GEN_STORE_FTN_FREG(fd, WTH2);
5865
        opn = "nmsub.ps";
5866
        break;
5867
    default:
5868
        MIPS_INVAL(opn);
5869
        generate_exception (ctx, EXCP_RI);
5870
        return;
5871
    }
5872
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5873
               fregnames[fs], fregnames[ft]);
5874
}
5875

    
5876
/* ISA extensions (ASEs) */
5877
/* MIPS16 extension to MIPS32 */
5878
/* SmartMIPS extension to MIPS32 */
5879

    
5880
#if defined(TARGET_MIPS64)
5881

    
5882
/* MDMX extension to MIPS64 */
5883

    
5884
#endif
5885

    
5886
static void decode_opc (CPUState *env, DisasContext *ctx)
5887
{
5888
    int32_t offset;
5889
    int rs, rt, rd, sa;
5890
    uint32_t op, op1, op2;
5891
    int16_t imm;
5892

    
5893
    /* make sure instructions are on a word boundary */
5894
    if (ctx->pc & 0x3) {
5895
        env->CP0_BadVAddr = ctx->pc;
5896
        generate_exception(ctx, EXCP_AdEL);
5897
        return;
5898
    }
5899

    
5900
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5901
        int l1;
5902
        /* Handle blikely not taken case */
5903
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5904
        l1 = gen_new_label();
5905
        gen_op_jnz_T2(l1);
5906
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5907
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5908
        gen_set_label(l1);
5909
    }
5910
    op = MASK_OP_MAJOR(ctx->opcode);
5911
    rs = (ctx->opcode >> 21) & 0x1f;
5912
    rt = (ctx->opcode >> 16) & 0x1f;
5913
    rd = (ctx->opcode >> 11) & 0x1f;
5914
    sa = (ctx->opcode >> 6) & 0x1f;
5915
    imm = (int16_t)ctx->opcode;
5916
    switch (op) {
5917
    case OPC_SPECIAL:
5918
        op1 = MASK_SPECIAL(ctx->opcode);
5919
        switch (op1) {
5920
        case OPC_SLL:          /* Arithmetic with immediate */
5921
        case OPC_SRL ... OPC_SRA:
5922
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
5923
            break;
5924
        case OPC_MOVZ ... OPC_MOVN:
5925
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5926
        case OPC_SLLV:         /* Arithmetic */
5927
        case OPC_SRLV ... OPC_SRAV:
5928
        case OPC_ADD ... OPC_NOR:
5929
        case OPC_SLT ... OPC_SLTU:
5930
            gen_arith(env, ctx, op1, rd, rs, rt);
5931
            break;
5932
        case OPC_MULT ... OPC_DIVU:
5933
            gen_muldiv(ctx, op1, rs, rt);
5934
            break;
5935
        case OPC_JR ... OPC_JALR:
5936
            gen_compute_branch(ctx, op1, rs, rd, sa);
5937
            return;
5938
        case OPC_TGE ... OPC_TEQ: /* Traps */
5939
        case OPC_TNE:
5940
            gen_trap(ctx, op1, rs, rt, -1);
5941
            break;
5942
        case OPC_MFHI:          /* Move from HI/LO */
5943
        case OPC_MFLO:
5944
            gen_HILO(ctx, op1, rd);
5945
            break;
5946
        case OPC_MTHI:
5947
        case OPC_MTLO:          /* Move to HI/LO */
5948
            gen_HILO(ctx, op1, rs);
5949
            break;
5950
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5951
#ifdef MIPS_STRICT_STANDARD
5952
            MIPS_INVAL("PMON / selsl");
5953
            generate_exception(ctx, EXCP_RI);
5954
#else
5955
            gen_op_pmon(sa);
5956
#endif
5957
            break;
5958
        case OPC_SYSCALL:
5959
            generate_exception(ctx, EXCP_SYSCALL);
5960
            break;
5961
        case OPC_BREAK:
5962
            generate_exception(ctx, EXCP_BREAK);
5963
            break;
5964
        case OPC_SPIM:
5965
#ifdef MIPS_STRICT_STANDARD
5966
            MIPS_INVAL("SPIM");
5967
            generate_exception(ctx, EXCP_RI);
5968
#else
5969
           /* Implemented as RI exception for now. */
5970
            MIPS_INVAL("spim (unofficial)");
5971
            generate_exception(ctx, EXCP_RI);
5972
#endif
5973
            break;
5974
        case OPC_SYNC:
5975
            /* Treat as NOP. */
5976
            break;
5977

    
5978
        case OPC_MOVCI:
5979
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5980
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5981
                save_cpu_state(ctx, 1);
5982
                check_cp1_enabled(ctx);
5983
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5984
                          (ctx->opcode >> 16) & 1);
5985
            } else {
5986
                generate_exception_err(ctx, EXCP_CpU, 1);
5987
            }
5988
            break;
5989

    
5990
#if defined(TARGET_MIPS64)
5991
       /* MIPS64 specific opcodes */
5992
        case OPC_DSLL:
5993
        case OPC_DSRL ... OPC_DSRA:
5994
        case OPC_DSLL32:
5995
        case OPC_DSRL32 ... OPC_DSRA32:
5996
            check_insn(env, ctx, ISA_MIPS3);
5997
            check_mips_64(ctx);
5998
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
5999
            break;
6000
        case OPC_DSLLV:
6001
        case OPC_DSRLV ... OPC_DSRAV:
6002
        case OPC_DADD ... OPC_DSUBU:
6003
            check_insn(env, ctx, ISA_MIPS3);
6004
            check_mips_64(ctx);
6005
            gen_arith(env, ctx, op1, rd, rs, rt);
6006
            break;
6007
        case OPC_DMULT ... OPC_DDIVU:
6008
            check_insn(env, ctx, ISA_MIPS3);
6009
            check_mips_64(ctx);
6010
            gen_muldiv(ctx, op1, rs, rt);
6011
            break;
6012
#endif
6013
        default:            /* Invalid */
6014
            MIPS_INVAL("special");
6015
            generate_exception(ctx, EXCP_RI);
6016
            break;
6017
        }
6018
        break;
6019
    case OPC_SPECIAL2:
6020
        op1 = MASK_SPECIAL2(ctx->opcode);
6021
        switch (op1) {
6022
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6023
        case OPC_MSUB ... OPC_MSUBU:
6024
            check_insn(env, ctx, ISA_MIPS32);
6025
            gen_muldiv(ctx, op1, rs, rt);
6026
            break;
6027
        case OPC_MUL:
6028
            gen_arith(env, ctx, op1, rd, rs, rt);
6029
            break;
6030
        case OPC_CLZ ... OPC_CLO:
6031
            check_insn(env, ctx, ISA_MIPS32);
6032
            gen_cl(ctx, op1, rd, rs);
6033
            break;
6034
        case OPC_SDBBP:
6035
            /* XXX: not clear which exception should be raised
6036
             *      when in debug mode...
6037
             */
6038
            check_insn(env, ctx, ISA_MIPS32);
6039
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6040
                generate_exception(ctx, EXCP_DBp);
6041
            } else {
6042
                generate_exception(ctx, EXCP_DBp);
6043
            }
6044
            /* Treat as NOP. */
6045
            break;
6046
#if defined(TARGET_MIPS64)
6047
        case OPC_DCLZ ... OPC_DCLO:
6048
            check_insn(env, ctx, ISA_MIPS64);
6049
            check_mips_64(ctx);
6050
            gen_cl(ctx, op1, rd, rs);
6051
            break;
6052
#endif
6053
        default:            /* Invalid */
6054
            MIPS_INVAL("special2");
6055
            generate_exception(ctx, EXCP_RI);
6056
            break;
6057
        }
6058
        break;
6059
    case OPC_SPECIAL3:
6060
         op1 = MASK_SPECIAL3(ctx->opcode);
6061
         switch (op1) {
6062
         case OPC_EXT:
6063
         case OPC_INS:
6064
             check_insn(env, ctx, ISA_MIPS32R2);
6065
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6066
             break;
6067
         case OPC_BSHFL:
6068
             check_insn(env, ctx, ISA_MIPS32R2);
6069
             op2 = MASK_BSHFL(ctx->opcode);
6070
             switch (op2) {
6071
             case OPC_WSBH:
6072
                 GEN_LOAD_REG_TN(T1, rt);
6073
                 gen_op_wsbh();
6074
                 break;
6075
             case OPC_SEB:
6076
                 GEN_LOAD_REG_TN(T1, rt);
6077
                 gen_op_seb();
6078
                 break;
6079
             case OPC_SEH:
6080
                 GEN_LOAD_REG_TN(T1, rt);
6081
                 gen_op_seh();
6082
                 break;
6083
             default:            /* Invalid */
6084
                 MIPS_INVAL("bshfl");
6085
                 generate_exception(ctx, EXCP_RI);
6086
                 break;
6087
            }
6088
            GEN_STORE_TN_REG(rd, T0);
6089
            break;
6090
        case OPC_RDHWR:
6091
            check_insn(env, ctx, ISA_MIPS32R2);
6092
            switch (rd) {
6093
            case 0:
6094
                save_cpu_state(ctx, 1);
6095
                gen_op_rdhwr_cpunum();
6096
                break;
6097
            case 1:
6098
                save_cpu_state(ctx, 1);
6099
                gen_op_rdhwr_synci_step();
6100
                break;
6101
            case 2:
6102
                save_cpu_state(ctx, 1);
6103
                gen_op_rdhwr_cc();
6104
                break;
6105
            case 3:
6106
                save_cpu_state(ctx, 1);
6107
                gen_op_rdhwr_ccres();
6108
                break;
6109
            case 29:
6110
#if defined (CONFIG_USER_ONLY)
6111
                gen_op_tls_value();
6112
                break;
6113
#endif
6114
            default:            /* Invalid */
6115
                MIPS_INVAL("rdhwr");
6116
                generate_exception(ctx, EXCP_RI);
6117
                break;
6118
            }
6119
            GEN_STORE_TN_REG(rt, T0);
6120
            break;
6121
        case OPC_FORK:
6122
            check_insn(env, ctx, ASE_MT);
6123
            GEN_LOAD_REG_TN(T0, rt);
6124
            GEN_LOAD_REG_TN(T1, rs);
6125
            gen_op_fork();
6126
            break;
6127
        case OPC_YIELD:
6128
            check_insn(env, ctx, ASE_MT);
6129
            GEN_LOAD_REG_TN(T0, rs);
6130
            gen_op_yield();
6131
            GEN_STORE_TN_REG(rd, T0);
6132
            break;
6133
#if defined(TARGET_MIPS64)
6134
        case OPC_DEXTM ... OPC_DEXT:
6135
        case OPC_DINSM ... OPC_DINS:
6136
            check_insn(env, ctx, ISA_MIPS64R2);
6137
            check_mips_64(ctx);
6138
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6139
            break;
6140
        case OPC_DBSHFL:
6141
            check_insn(env, ctx, ISA_MIPS64R2);
6142
            check_mips_64(ctx);
6143
            op2 = MASK_DBSHFL(ctx->opcode);
6144
            switch (op2) {
6145
            case OPC_DSBH:
6146
                GEN_LOAD_REG_TN(T1, rt);
6147
                gen_op_dsbh();
6148
                break;
6149
            case OPC_DSHD:
6150
                GEN_LOAD_REG_TN(T1, rt);
6151
                gen_op_dshd();
6152
                break;
6153
            default:            /* Invalid */
6154
                MIPS_INVAL("dbshfl");
6155
                generate_exception(ctx, EXCP_RI);
6156
                break;
6157
            }
6158
            GEN_STORE_TN_REG(rd, T0);
6159
#endif
6160
        default:            /* Invalid */
6161
            MIPS_INVAL("special3");
6162
            generate_exception(ctx, EXCP_RI);
6163
            break;
6164
        }
6165
        break;
6166
    case OPC_REGIMM:
6167
        op1 = MASK_REGIMM(ctx->opcode);
6168
        switch (op1) {
6169
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6170
        case OPC_BLTZAL ... OPC_BGEZALL:
6171
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6172
            return;
6173
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6174
        case OPC_TNEI:
6175
            gen_trap(ctx, op1, rs, -1, imm);
6176
            break;
6177
        case OPC_SYNCI:
6178
            check_insn(env, ctx, ISA_MIPS32R2);
6179
            /* Treat as NOP. */
6180
            break;
6181
        default:            /* Invalid */
6182
            MIPS_INVAL("regimm");
6183
            generate_exception(ctx, EXCP_RI);
6184
            break;
6185
        }
6186
        break;
6187
    case OPC_CP0:
6188
        check_cp0_enabled(ctx);
6189
        op1 = MASK_CP0(ctx->opcode);
6190
        switch (op1) {
6191
        case OPC_MFC0:
6192
        case OPC_MTC0:
6193
        case OPC_MFTR:
6194
        case OPC_MTTR:
6195
#if defined(TARGET_MIPS64)
6196
        case OPC_DMFC0:
6197
        case OPC_DMTC0:
6198
#endif
6199
            gen_cp0(env, ctx, op1, rt, rd);
6200
            break;
6201
        case OPC_C0_FIRST ... OPC_C0_LAST:
6202
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6203
            break;
6204
        case OPC_MFMC0:
6205
            op2 = MASK_MFMC0(ctx->opcode);
6206
            switch (op2) {
6207
            case OPC_DMT:
6208
                check_insn(env, ctx, ASE_MT);
6209
                gen_op_dmt();
6210
                break;
6211
            case OPC_EMT:
6212
                check_insn(env, ctx, ASE_MT);
6213
                gen_op_emt();
6214
                break;
6215
            case OPC_DVPE:
6216
                check_insn(env, ctx, ASE_MT);
6217
                gen_op_dvpe();
6218
                break;
6219
            case OPC_EVPE:
6220
                check_insn(env, ctx, ASE_MT);
6221
                gen_op_evpe();
6222
                break;
6223
            case OPC_DI:
6224
                check_insn(env, ctx, ISA_MIPS32R2);
6225
                save_cpu_state(ctx, 1);
6226
                gen_op_di();
6227
                /* Stop translation as we may have switched the execution mode */
6228
                ctx->bstate = BS_STOP;
6229
                break;
6230
            case OPC_EI:
6231
                check_insn(env, ctx, ISA_MIPS32R2);
6232
                save_cpu_state(ctx, 1);
6233
                gen_op_ei();
6234
                /* Stop translation as we may have switched the execution mode */
6235
                ctx->bstate = BS_STOP;
6236
                break;
6237
            default:            /* Invalid */
6238
                MIPS_INVAL("mfmc0");
6239
                generate_exception(ctx, EXCP_RI);
6240
                break;
6241
            }
6242
            GEN_STORE_TN_REG(rt, T0);
6243
            break;
6244
        case OPC_RDPGPR:
6245
            check_insn(env, ctx, ISA_MIPS32R2);
6246
            GEN_LOAD_SRSREG_TN(T0, rt);
6247
            GEN_STORE_TN_REG(rd, T0);
6248
            break;
6249
        case OPC_WRPGPR:
6250
            check_insn(env, ctx, ISA_MIPS32R2);
6251
            GEN_LOAD_REG_TN(T0, rt);
6252
            GEN_STORE_TN_SRSREG(rd, T0);
6253
            break;
6254
        default:
6255
            MIPS_INVAL("cp0");
6256
            generate_exception(ctx, EXCP_RI);
6257
            break;
6258
        }
6259
        break;
6260
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6261
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6262
         break;
6263
    case OPC_J ... OPC_JAL: /* Jump */
6264
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6265
         gen_compute_branch(ctx, op, rs, rt, offset);
6266
         return;
6267
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6268
    case OPC_BEQL ... OPC_BGTZL:
6269
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6270
         return;
6271
    case OPC_LB ... OPC_LWR: /* Load and stores */
6272
    case OPC_SB ... OPC_SW:
6273
    case OPC_SWR:
6274
    case OPC_LL:
6275
    case OPC_SC:
6276
         gen_ldst(ctx, op, rt, rs, imm);
6277
         break;
6278
    case OPC_CACHE:
6279
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6280
        /* Treat as NOP. */
6281
        break;
6282
    case OPC_PREF:
6283
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6284
        /* Treat as NOP. */
6285
        break;
6286

    
6287
    /* Floating point (COP1). */
6288
    case OPC_LWC1:
6289
    case OPC_LDC1:
6290
    case OPC_SWC1:
6291
    case OPC_SDC1:
6292
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6293
            save_cpu_state(ctx, 1);
6294
            check_cp1_enabled(ctx);
6295
            gen_flt_ldst(ctx, op, rt, rs, imm);
6296
        } else {
6297
            generate_exception_err(ctx, EXCP_CpU, 1);
6298
        }
6299
        break;
6300

    
6301
    case OPC_CP1:
6302
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6303
            save_cpu_state(ctx, 1);
6304
            check_cp1_enabled(ctx);
6305
            op1 = MASK_CP1(ctx->opcode);
6306
            switch (op1) {
6307
            case OPC_MFHC1:
6308
            case OPC_MTHC1:
6309
                check_insn(env, ctx, ISA_MIPS32R2);
6310
            case OPC_MFC1:
6311
            case OPC_CFC1:
6312
            case OPC_MTC1:
6313
            case OPC_CTC1:
6314
                gen_cp1(ctx, op1, rt, rd);
6315
                break;
6316
#if defined(TARGET_MIPS64)
6317
            case OPC_DMFC1:
6318
            case OPC_DMTC1:
6319
                check_insn(env, ctx, ISA_MIPS3);
6320
                gen_cp1(ctx, op1, rt, rd);
6321
                break;
6322
#endif
6323
            case OPC_BC1ANY2:
6324
            case OPC_BC1ANY4:
6325
                check_insn(env, ctx, ASE_MIPS3D);
6326
                /* fall through */
6327
            case OPC_BC1:
6328
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6329
                                    (rt >> 2) & 0x7, imm << 2);
6330
                return;
6331
            case OPC_S_FMT:
6332
            case OPC_D_FMT:
6333
            case OPC_W_FMT:
6334
            case OPC_L_FMT:
6335
            case OPC_PS_FMT:
6336
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6337
                           (imm >> 8) & 0x7);
6338
                break;
6339
            default:
6340
                MIPS_INVAL("cp1");
6341
                generate_exception (ctx, EXCP_RI);
6342
                break;
6343
            }
6344
        } else {
6345
            generate_exception_err(ctx, EXCP_CpU, 1);
6346
        }
6347
        break;
6348

    
6349
    /* COP2.  */
6350
    case OPC_LWC2:
6351
    case OPC_LDC2:
6352
    case OPC_SWC2:
6353
    case OPC_SDC2:
6354
    case OPC_CP2:
6355
        /* COP2: Not implemented. */
6356
        generate_exception_err(ctx, EXCP_CpU, 2);
6357
        break;
6358

    
6359
    case OPC_CP3:
6360
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6361
            save_cpu_state(ctx, 1);
6362
            check_cp1_enabled(ctx);
6363
            op1 = MASK_CP3(ctx->opcode);
6364
            switch (op1) {
6365
            case OPC_LWXC1:
6366
            case OPC_LDXC1:
6367
            case OPC_LUXC1:
6368
            case OPC_SWXC1:
6369
            case OPC_SDXC1:
6370
            case OPC_SUXC1:
6371
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6372
                break;
6373
            case OPC_PREFX:
6374
                /* Treat as NOP. */
6375
                break;
6376
            case OPC_ALNV_PS:
6377
            case OPC_MADD_S:
6378
            case OPC_MADD_D:
6379
            case OPC_MADD_PS:
6380
            case OPC_MSUB_S:
6381
            case OPC_MSUB_D:
6382
            case OPC_MSUB_PS:
6383
            case OPC_NMADD_S:
6384
            case OPC_NMADD_D:
6385
            case OPC_NMADD_PS:
6386
            case OPC_NMSUB_S:
6387
            case OPC_NMSUB_D:
6388
            case OPC_NMSUB_PS:
6389
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6390
                break;
6391
            default:
6392
                MIPS_INVAL("cp3");
6393
                generate_exception (ctx, EXCP_RI);
6394
                break;
6395
            }
6396
        } else {
6397
            generate_exception_err(ctx, EXCP_CpU, 1);
6398
        }
6399
        break;
6400

    
6401
#if defined(TARGET_MIPS64)
6402
    /* MIPS64 opcodes */
6403
    case OPC_LWU:
6404
    case OPC_LDL ... OPC_LDR:
6405
    case OPC_SDL ... OPC_SDR:
6406
    case OPC_LLD:
6407
    case OPC_LD:
6408
    case OPC_SCD:
6409
    case OPC_SD:
6410
        check_insn(env, ctx, ISA_MIPS3);
6411
        check_mips_64(ctx);
6412
        gen_ldst(ctx, op, rt, rs, imm);
6413
        break;
6414
    case OPC_DADDI ... OPC_DADDIU:
6415
        check_insn(env, ctx, ISA_MIPS3);
6416
        check_mips_64(ctx);
6417
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6418
        break;
6419
#endif
6420
    case OPC_JALX:
6421
        check_insn(env, ctx, ASE_MIPS16);
6422
        /* MIPS16: Not implemented. */
6423
    case OPC_MDMX:
6424
        check_insn(env, ctx, ASE_MDMX);
6425
        /* MDMX: Not implemented. */
6426
    default:            /* Invalid */
6427
        MIPS_INVAL("major opcode");
6428
        generate_exception(ctx, EXCP_RI);
6429
        break;
6430
    }
6431
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6432
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6433
        /* Branches completion */
6434
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6435
        ctx->bstate = BS_BRANCH;
6436
        save_cpu_state(ctx, 0);
6437
        switch (hflags) {
6438
        case MIPS_HFLAG_B:
6439
            /* unconditional branch */
6440
            MIPS_DEBUG("unconditional branch");
6441
            gen_goto_tb(ctx, 0, ctx->btarget);
6442
            break;
6443
        case MIPS_HFLAG_BL:
6444
            /* blikely taken case */
6445
            MIPS_DEBUG("blikely branch taken");
6446
            gen_goto_tb(ctx, 0, ctx->btarget);
6447
            break;
6448
        case MIPS_HFLAG_BC:
6449
            /* Conditional branch */
6450
            MIPS_DEBUG("conditional branch");
6451
            {
6452
              int l1;
6453
              l1 = gen_new_label();
6454
              gen_op_jnz_T2(l1);
6455
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6456
              gen_set_label(l1);
6457
              gen_goto_tb(ctx, 0, ctx->btarget);
6458
            }
6459
            break;
6460
        case MIPS_HFLAG_BR:
6461
            /* unconditional branch to register */
6462
            MIPS_DEBUG("branch to register");
6463
            gen_op_breg();
6464
            gen_op_reset_T0();
6465
            gen_op_exit_tb();
6466
            break;
6467
        default:
6468
            MIPS_DEBUG("unknown branch");
6469
            break;
6470
        }
6471
    }
6472
}
6473

    
6474
static always_inline int
6475
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6476
                                int search_pc)
6477
{
6478
    DisasContext ctx;
6479
    target_ulong pc_start;
6480
    uint16_t *gen_opc_end;
6481
    int j, lj = -1;
6482

    
6483
    if (search_pc && loglevel)
6484
        fprintf (logfile, "search pc %d\n", search_pc);
6485

    
6486
    pc_start = tb->pc;
6487
    gen_opc_ptr = gen_opc_buf;
6488
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6489
    gen_opparam_ptr = gen_opparam_buf;
6490
    nb_gen_labels = 0;
6491
    ctx.pc = pc_start;
6492
    ctx.saved_pc = -1;
6493
    ctx.tb = tb;
6494
    ctx.bstate = BS_NONE;
6495
    /* Restore delay slot state from the tb context.  */
6496
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6497
    restore_cpu_state(env, &ctx);
6498
#if defined(CONFIG_USER_ONLY)
6499
    ctx.mem_idx = MIPS_HFLAG_UM;
6500
#else
6501
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6502
#endif
6503
#ifdef DEBUG_DISAS
6504
    if (loglevel & CPU_LOG_TB_CPU) {
6505
        fprintf(logfile, "------------------------------------------------\n");
6506
        /* FIXME: This may print out stale hflags from env... */
6507
        cpu_dump_state(env, logfile, fprintf, 0);
6508
    }
6509
#endif
6510
#ifdef MIPS_DEBUG_DISAS
6511
    if (loglevel & CPU_LOG_TB_IN_ASM)
6512
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6513
                tb, ctx.mem_idx, ctx.hflags);
6514
#endif
6515
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6516
        if (env->nb_breakpoints > 0) {
6517
            for(j = 0; j < env->nb_breakpoints; j++) {
6518
                if (env->breakpoints[j] == ctx.pc) {
6519
                    save_cpu_state(&ctx, 1);
6520
                    ctx.bstate = BS_BRANCH;
6521
                    gen_op_debug();
6522
                    /* Include the breakpoint location or the tb won't
6523
                     * be flushed when it must be.  */
6524
                    ctx.pc += 4;
6525
                    goto done_generating;
6526
                }
6527
            }
6528
        }
6529

    
6530
        if (search_pc) {
6531
            j = gen_opc_ptr - gen_opc_buf;
6532
            if (lj < j) {
6533
                lj++;
6534
                while (lj < j)
6535
                    gen_opc_instr_start[lj++] = 0;
6536
            }
6537
            gen_opc_pc[lj] = ctx.pc;
6538
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6539
            gen_opc_instr_start[lj] = 1;
6540
        }
6541
        ctx.opcode = ldl_code(ctx.pc);
6542
        decode_opc(env, &ctx);
6543
        ctx.pc += 4;
6544

    
6545
        if (env->singlestep_enabled)
6546
            break;
6547

    
6548
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6549
            break;
6550

    
6551
#if defined (MIPS_SINGLE_STEP)
6552
        break;
6553
#endif
6554
    }
6555
    if (env->singlestep_enabled) {
6556
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6557
        gen_op_debug();
6558
    } else {
6559
        switch (ctx.bstate) {
6560
        case BS_STOP:
6561
            gen_op_interrupt_restart();
6562
            gen_goto_tb(&ctx, 0, ctx.pc);
6563
            break;
6564
        case BS_NONE:
6565
            save_cpu_state(&ctx, 0);
6566
            gen_goto_tb(&ctx, 0, ctx.pc);
6567
            break;
6568
        case BS_EXCP:
6569
            gen_op_interrupt_restart();
6570
            gen_op_reset_T0();
6571
            gen_op_exit_tb();
6572
            break;
6573
        case BS_BRANCH:
6574
        default:
6575
            break;
6576
        }
6577
    }
6578
done_generating:
6579
    *gen_opc_ptr = INDEX_op_end;
6580
    if (search_pc) {
6581
        j = gen_opc_ptr - gen_opc_buf;
6582
        lj++;
6583
        while (lj <= j)
6584
            gen_opc_instr_start[lj++] = 0;
6585
    } else {
6586
        tb->size = ctx.pc - pc_start;
6587
    }
6588
#ifdef DEBUG_DISAS
6589
#if defined MIPS_DEBUG_DISAS
6590
    if (loglevel & CPU_LOG_TB_IN_ASM)
6591
        fprintf(logfile, "\n");
6592
#endif
6593
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6594
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6595
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6596
        fprintf(logfile, "\n");
6597
    }
6598
    if (loglevel & CPU_LOG_TB_OP) {
6599
        fprintf(logfile, "OP:\n");
6600
        dump_ops(gen_opc_buf, gen_opparam_buf);
6601
        fprintf(logfile, "\n");
6602
    }
6603
    if (loglevel & CPU_LOG_TB_CPU) {
6604
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6605
    }
6606
#endif
6607

    
6608
    return 0;
6609
}
6610

    
6611
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6612
{
6613
    return gen_intermediate_code_internal(env, tb, 0);
6614
}
6615

    
6616
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6617
{
6618
    return gen_intermediate_code_internal(env, tb, 1);
6619
}
6620

    
6621
void fpu_dump_state(CPUState *env, FILE *f,
6622
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6623
                    int flags)
6624
{
6625
    int i;
6626
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6627

    
6628
#define printfpr(fp)                                                        \
6629
    do {                                                                    \
6630
        if (is_fpu64)                                                       \
6631
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6632
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6633
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6634
        else {                                                              \
6635
            fpr_t tmp;                                                      \
6636
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6637
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6638
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6639
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6640
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6641
        }                                                                   \
6642
    } while(0)
6643

    
6644

    
6645
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6646
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6647
                get_float_exception_flags(&env->fpu->fp_status));
6648
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6649
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6650
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6651
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6652
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6653
        printfpr(&env->fpu->fpr[i]);
6654
    }
6655

    
6656
#undef printfpr
6657
}
6658

    
6659
void dump_fpu (CPUState *env)
6660
{
6661
    if (loglevel) {
6662
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6663
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6664
       fpu_dump_state(env, logfile, fprintf, 0);
6665
    }
6666
}
6667

    
6668
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6669
/* Debug help: The architecture requires 32bit code to maintain proper
6670
   sign-extened values on 64bit machines.  */
6671

    
6672
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6673

    
6674
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6675
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6676
                     int flags)
6677
{
6678
    int i;
6679

    
6680
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6681
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6682
    if (!SIGN_EXT_P(env->HI[env->current_tc]))
6683
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc]);
6684
    if (!SIGN_EXT_P(env->LO[env->current_tc]))
6685
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc]);
6686
    if (!SIGN_EXT_P(env->btarget))
6687
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6688

    
6689
    for (i = 0; i < 32; i++) {
6690
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6691
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6692
    }
6693

    
6694
    if (!SIGN_EXT_P(env->CP0_EPC))
6695
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6696
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6697
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6698
}
6699
#endif
6700

    
6701
void cpu_dump_state (CPUState *env, FILE *f,
6702
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6703
                     int flags)
6704
{
6705
    int i;
6706

    
6707
    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",
6708
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6709
    for (i = 0; i < 32; i++) {
6710
        if ((i & 3) == 0)
6711
            cpu_fprintf(f, "GPR%02d:", i);
6712
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6713
        if ((i & 3) == 3)
6714
            cpu_fprintf(f, "\n");
6715
    }
6716

    
6717
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6718
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6719
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6720
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6721
    if (env->hflags & MIPS_HFLAG_FPU)
6722
        fpu_dump_state(env, f, cpu_fprintf, flags);
6723
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6724
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6725
#endif
6726
}
6727

    
6728
CPUMIPSState *cpu_mips_init (void)
6729
{
6730
    CPUMIPSState *env;
6731

    
6732
    env = qemu_mallocz(sizeof(CPUMIPSState));
6733
    if (!env)
6734
        return NULL;
6735
    cpu_exec_init(env);
6736
    cpu_reset(env);
6737
    return env;
6738
}
6739

    
6740
void cpu_reset (CPUMIPSState *env)
6741
{
6742
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6743

    
6744
    tlb_flush(env, 1);
6745

    
6746
    /* Minimal init */
6747
#if !defined(CONFIG_USER_ONLY)
6748
    if (env->hflags & MIPS_HFLAG_BMASK) {
6749
        /* If the exception was raised from a delay slot,
6750
         * come back to the jump.  */
6751
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6752
    } else {
6753
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6754
    }
6755
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6756
    env->CP0_Wired = 0;
6757
    /* SMP not implemented */
6758
    env->CP0_EBase = 0x80000000;
6759
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6760
    /* vectored interrupts not implemented, timer on int 7,
6761
       no performance counters. */
6762
    env->CP0_IntCtl = 0xe0000000;
6763
    {
6764
        int i;
6765

    
6766
        for (i = 0; i < 7; i++) {
6767
            env->CP0_WatchLo[i] = 0;
6768
            env->CP0_WatchHi[i] = 0x80000000;
6769
        }
6770
        env->CP0_WatchLo[7] = 0;
6771
        env->CP0_WatchHi[7] = 0;
6772
    }
6773
    /* Count register increments in debug mode, EJTAG version 1 */
6774
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6775
#endif
6776
    env->exception_index = EXCP_NONE;
6777
#if defined(CONFIG_USER_ONLY)
6778
    env->hflags = MIPS_HFLAG_UM;
6779
    env->user_mode_only = 1;
6780
#else
6781
    env->hflags = MIPS_HFLAG_CP0;
6782
#endif
6783
}
6784

    
6785
#include "translate_init.c"