Statistics
| Branch: | Revision:

root / target-mips / translate.c @ e9c71dd1

History | View | Annotate | Download (189.8 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
/* Multiplication variants of the vr54xx. */
218
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
219

    
220
enum {
221
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
222
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
223
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
224
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
225
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
226
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
227
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
228
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
229
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
230
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
231
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
232
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
233
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
234
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
235
};
236

    
237
/* REGIMM (rt field) opcodes */
238
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
239

    
240
enum {
241
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
242
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
243
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
244
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
245
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
246
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
247
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
248
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
249
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
250
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
251
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
252
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
253
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
254
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
255
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
256
};
257

    
258
/* Special2 opcodes */
259
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
260

    
261
enum {
262
    /* Multiply & xxx operations */
263
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
264
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
265
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
266
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
267
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
268
    /* Misc */
269
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
270
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
271
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
272
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
273
    /* Special */
274
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
275
};
276

    
277
/* Special3 opcodes */
278
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
279

    
280
enum {
281
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
282
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
283
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
284
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
285
    OPC_INS      = 0x04 | OPC_SPECIAL3,
286
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
287
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
288
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
289
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
290
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
291
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
292
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
293
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
294
};
295

    
296
/* BSHFL opcodes */
297
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
298

    
299
enum {
300
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
301
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
302
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
303
};
304

    
305
/* DBSHFL opcodes */
306
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
307

    
308
enum {
309
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
310
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
311
};
312

    
313
/* Coprocessor 0 (rs field) */
314
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
315

    
316
enum {
317
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
318
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
319
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
320
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
321
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
322
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
323
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
324
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
325
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
326
    OPC_C0       = (0x10 << 21) | OPC_CP0,
327
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
328
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
329
};
330

    
331
/* MFMC0 opcodes */
332
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
333

    
334
enum {
335
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
336
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
337
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
338
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
339
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
340
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
341
};
342

    
343
/* Coprocessor 0 (with rs == C0) */
344
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
345

    
346
enum {
347
    OPC_TLBR     = 0x01 | OPC_C0,
348
    OPC_TLBWI    = 0x02 | OPC_C0,
349
    OPC_TLBWR    = 0x06 | OPC_C0,
350
    OPC_TLBP     = 0x08 | OPC_C0,
351
    OPC_RFE      = 0x10 | OPC_C0,
352
    OPC_ERET     = 0x18 | OPC_C0,
353
    OPC_DERET    = 0x1F | OPC_C0,
354
    OPC_WAIT     = 0x20 | OPC_C0,
355
};
356

    
357
/* Coprocessor 1 (rs field) */
358
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
359

    
360
enum {
361
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
362
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
363
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
364
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
365
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
366
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
367
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
368
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
369
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
370
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
371
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
372
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
373
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
374
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
375
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
376
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
377
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
378
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
379
};
380

    
381
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
382
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
383

    
384
enum {
385
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
386
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
387
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
388
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
389
};
390

    
391
enum {
392
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
393
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
394
};
395

    
396
enum {
397
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
398
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
399
};
400

    
401
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
402

    
403
enum {
404
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
405
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
406
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
407
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
408
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
409
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
410
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
411
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
412
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
413
};
414

    
415
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
416

    
417
enum {
418
    OPC_LWXC1   = 0x00 | OPC_CP3,
419
    OPC_LDXC1   = 0x01 | OPC_CP3,
420
    OPC_LUXC1   = 0x05 | OPC_CP3,
421
    OPC_SWXC1   = 0x08 | OPC_CP3,
422
    OPC_SDXC1   = 0x09 | OPC_CP3,
423
    OPC_SUXC1   = 0x0D | OPC_CP3,
424
    OPC_PREFX   = 0x0F | OPC_CP3,
425
    OPC_ALNV_PS = 0x1E | OPC_CP3,
426
    OPC_MADD_S  = 0x20 | OPC_CP3,
427
    OPC_MADD_D  = 0x21 | OPC_CP3,
428
    OPC_MADD_PS = 0x26 | OPC_CP3,
429
    OPC_MSUB_S  = 0x28 | OPC_CP3,
430
    OPC_MSUB_D  = 0x29 | OPC_CP3,
431
    OPC_MSUB_PS = 0x2E | OPC_CP3,
432
    OPC_NMADD_S = 0x30 | OPC_CP3,
433
    OPC_NMADD_D = 0x31 | OPC_CP3,
434
    OPC_NMADD_PS= 0x36 | OPC_CP3,
435
    OPC_NMSUB_S = 0x38 | OPC_CP3,
436
    OPC_NMSUB_D = 0x39 | OPC_CP3,
437
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
438
};
439

    
440

    
441
const unsigned char *regnames[] =
442
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
443
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
444
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
445
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
446

    
447
/* Warning: no function for r0 register (hard wired to zero) */
448
#define GEN32(func, NAME)                        \
449
static GenOpFunc *NAME ## _table [32] = {        \
450
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
451
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
452
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
453
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
454
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
455
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
456
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
457
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
458
};                                               \
459
static always_inline void func(int n)            \
460
{                                                \
461
    NAME ## _table[n]();                         \
462
}
463

    
464
/* General purpose registers moves */
465
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
466
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
467
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
468

    
469
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
470
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
471

    
472
/* Moves to/from shadow registers */
473
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
474
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
475

    
476
static const char *fregnames[] =
477
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
478
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
479
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
480
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
481

    
482
#define FGEN32(func, NAME)                       \
483
static GenOpFunc *NAME ## _table [32] = {        \
484
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
485
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
486
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
487
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
488
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
489
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
490
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
491
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
492
};                                               \
493
static always_inline void func(int n)            \
494
{                                                \
495
    NAME ## _table[n]();                         \
496
}
497

    
498
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
499
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
500

    
501
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
502
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
503

    
504
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
505
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
506

    
507
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
508
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
509

    
510
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
511
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
512

    
513
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
514
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
515

    
516
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
517
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
518

    
519
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
520
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
521

    
522
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
523
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
524

    
525
#define FOP_CONDS(type, fmt)                                            \
526
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
527
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
528
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
529
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
530
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
531
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
532
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
533
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
534
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
535
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
536
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
537
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
538
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
539
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
540
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
541
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
542
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
543
};                                                                      \
544
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
545
{                                                                       \
546
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
547
}
548

    
549
FOP_CONDS(, d)
550
FOP_CONDS(abs, d)
551
FOP_CONDS(, s)
552
FOP_CONDS(abs, s)
553
FOP_CONDS(, ps)
554
FOP_CONDS(abs, ps)
555

    
556
typedef struct DisasContext {
557
    struct TranslationBlock *tb;
558
    target_ulong pc, saved_pc;
559
    uint32_t opcode;
560
    uint32_t fp_status;
561
    /* Routine used to access memory */
562
    int mem_idx;
563
    uint32_t hflags, saved_hflags;
564
    int bstate;
565
    target_ulong btarget;
566
    void *last_T0_store;
567
    int last_T0_gpr;
568
} DisasContext;
569

    
570
enum {
571
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
572
                      * exception condition
573
                      */
574
    BS_STOP     = 1, /* We want to stop translation for any reason */
575
    BS_BRANCH   = 2, /* We reached a branch condition     */
576
    BS_EXCP     = 3, /* We reached an exception condition */
577
};
578

    
579
#ifdef MIPS_DEBUG_DISAS
580
#define MIPS_DEBUG(fmt, args...)                                              \
581
do {                                                                          \
582
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
583
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
584
                ctx->pc, ctx->opcode , ##args);                               \
585
    }                                                                         \
586
} while (0)
587
#else
588
#define MIPS_DEBUG(fmt, args...) do { } while(0)
589
#endif
590

    
591
#define MIPS_INVAL(op)                                                        \
592
do {                                                                          \
593
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
594
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
595
} while (0)
596

    
597
#define GEN_LOAD_REG_T0(Rn)                                                   \
598
do {                                                                          \
599
    if (Rn == 0) {                                                            \
600
        gen_op_reset_T0();                                                    \
601
    } else {                                                                  \
602
        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
603
            || ctx->glue(last_T0, _gpr) != Rn) {                              \
604
                gen_op_load_gpr_T0(Rn);                                       \
605
        }                                                                     \
606
    }                                                                         \
607
} while (0)
608

    
609
#define GEN_LOAD_REG_T1(Rn)                                                   \
610
do {                                                                          \
611
    if (Rn == 0) {                                                            \
612
        gen_op_reset_T1();                                                    \
613
    } else {                                                                  \
614
        gen_op_load_gpr_T1(Rn);                                               \
615
    }                                                                         \
616
} while (0)
617

    
618
#define GEN_LOAD_REG_T2(Rn)                                                   \
619
do {                                                                          \
620
    if (Rn == 0) {                                                            \
621
        gen_op_reset_T2();                                                    \
622
    } else {                                                                  \
623
        gen_op_load_gpr_T2(Rn);                                               \
624
    }                                                                         \
625
} while (0)
626

    
627
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
628
do {                                                                          \
629
    if (Rn == 0) {                                                            \
630
        glue(gen_op_reset_, Tn)();                                            \
631
    } else {                                                                  \
632
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
633
    }                                                                         \
634
} while (0)
635

    
636
#if defined(TARGET_MIPS64)
637
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
638
do {                                                                          \
639
    if (Imm == 0) {                                                           \
640
        glue(gen_op_reset_, Tn)();                                            \
641
    } else if ((int32_t)Imm == Imm) {                                         \
642
        glue(gen_op_set_, Tn)(Imm);                                           \
643
    } else {                                                                  \
644
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
645
    }                                                                         \
646
} while (0)
647
#else
648
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
649
do {                                                                          \
650
    if (Imm == 0) {                                                           \
651
        glue(gen_op_reset_, Tn)();                                            \
652
    } else {                                                                  \
653
        glue(gen_op_set_, Tn)(Imm);                                           \
654
    }                                                                         \
655
} while (0)
656
#endif
657

    
658
#define GEN_STORE_T0_REG(Rn)                                                  \
659
do {                                                                          \
660
    if (Rn != 0) {                                                            \
661
        glue(gen_op_store_T0,_gpr)(Rn);                                       \
662
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
663
        ctx->glue(last_T0,_gpr) = Rn;                                         \
664
    }                                                                         \
665
} while (0)
666

    
667
#define GEN_STORE_T1_REG(Rn)                                                  \
668
do {                                                                          \
669
    if (Rn != 0)                                                              \
670
        glue(gen_op_store_T1,_gpr)(Rn);                                       \
671
} while (0)
672

    
673
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
674
do {                                                                          \
675
    if (Rn != 0) {                                                            \
676
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
677
    }                                                                         \
678
} while (0)
679

    
680
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
681
do {                                                                          \
682
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
683
} while (0)
684

    
685
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
686
do {                                                                          \
687
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
688
} while (0)
689

    
690
static always_inline void gen_save_pc(target_ulong pc)
691
{
692
#if defined(TARGET_MIPS64)
693
    if (pc == (int32_t)pc) {
694
        gen_op_save_pc(pc);
695
    } else {
696
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
697
    }
698
#else
699
    gen_op_save_pc(pc);
700
#endif
701
}
702

    
703
static always_inline void gen_save_btarget(target_ulong btarget)
704
{
705
#if defined(TARGET_MIPS64)
706
    if (btarget == (int32_t)btarget) {
707
        gen_op_save_btarget(btarget);
708
    } else {
709
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
710
    }
711
#else
712
    gen_op_save_btarget(btarget);
713
#endif
714
}
715

    
716
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
717
{
718
#if defined MIPS_DEBUG_DISAS
719
    if (loglevel & CPU_LOG_TB_IN_ASM) {
720
            fprintf(logfile, "hflags %08x saved %08x\n",
721
                    ctx->hflags, ctx->saved_hflags);
722
    }
723
#endif
724
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
725
        gen_save_pc(ctx->pc);
726
        ctx->saved_pc = ctx->pc;
727
    }
728
    if (ctx->hflags != ctx->saved_hflags) {
729
        gen_op_save_state(ctx->hflags);
730
        ctx->saved_hflags = ctx->hflags;
731
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
732
        case MIPS_HFLAG_BR:
733
            gen_op_save_breg_target();
734
            break;
735
        case MIPS_HFLAG_BC:
736
            gen_op_save_bcond();
737
            /* fall through */
738
        case MIPS_HFLAG_BL:
739
            /* bcond was already saved by the BL insn */
740
            /* fall through */
741
        case MIPS_HFLAG_B:
742
            gen_save_btarget(ctx->btarget);
743
            break;
744
        }
745
    }
746
}
747

    
748
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
749
{
750
    ctx->saved_hflags = ctx->hflags;
751
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
752
    case MIPS_HFLAG_BR:
753
        gen_op_restore_breg_target();
754
        break;
755
    case MIPS_HFLAG_B:
756
        ctx->btarget = env->btarget;
757
        break;
758
    case MIPS_HFLAG_BC:
759
    case MIPS_HFLAG_BL:
760
        ctx->btarget = env->btarget;
761
        gen_op_restore_bcond();
762
        break;
763
    }
764
}
765

    
766
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
767
{
768
#if defined MIPS_DEBUG_DISAS
769
    if (loglevel & CPU_LOG_TB_IN_ASM)
770
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
771
#endif
772
    save_cpu_state(ctx, 1);
773
    if (err == 0)
774
        gen_op_raise_exception(excp);
775
    else
776
        gen_op_raise_exception_err(excp, err);
777
    ctx->bstate = BS_EXCP;
778
}
779

    
780
static always_inline void generate_exception (DisasContext *ctx, int excp)
781
{
782
    generate_exception_err (ctx, excp, 0);
783
}
784

    
785
static always_inline void check_cp0_enabled(DisasContext *ctx)
786
{
787
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
788
        generate_exception_err(ctx, EXCP_CpU, 1);
789
}
790

    
791
static always_inline void check_cp1_enabled(DisasContext *ctx)
792
{
793
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
794
        generate_exception_err(ctx, EXCP_CpU, 1);
795
}
796

    
797
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
798
{
799
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64)))
800
        generate_exception(ctx, EXCP_RI);
801
}
802

    
803
/*
804
 * Verify if floating point register is valid; an operation is not defined
805
 * if bit 0 of any register specification is set and the FR bit in the
806
 * Status register equals zero, since the register numbers specify an
807
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
808
 * in the Status register equals one, both even and odd register numbers
809
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
810
 *
811
 * Multiple 64 bit wide registers can be checked by calling
812
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
813
 */
814
void check_cp1_registers(DisasContext *ctx, int regs)
815
{
816
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
817
        generate_exception(ctx, EXCP_RI);
818
}
819

    
820
/* This code generates a "reserved instruction" exception if the
821
   CPU does not support the instruction set corresponding to flags. */
822
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
823
{
824
    if (unlikely(!(env->insn_flags & flags)))
825
        generate_exception(ctx, EXCP_RI);
826
}
827

    
828
/* This code generates a "reserved instruction" exception if 64-bit
829
   instructions are not enabled. */
830
static always_inline void check_mips_64(DisasContext *ctx)
831
{
832
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
833
        generate_exception(ctx, EXCP_RI);
834
}
835

    
836
#if defined(CONFIG_USER_ONLY)
837
#define op_ldst(name)        gen_op_##name##_raw()
838
#define OP_LD_TABLE(width)
839
#define OP_ST_TABLE(width)
840
#else
841
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
842
#define OP_LD_TABLE(width)                                                    \
843
static GenOpFunc *gen_op_l##width[] = {                                       \
844
    &gen_op_l##width##_kernel,                                                \
845
    &gen_op_l##width##_super,                                                 \
846
    &gen_op_l##width##_user,                                                  \
847
}
848
#define OP_ST_TABLE(width)                                                    \
849
static GenOpFunc *gen_op_s##width[] = {                                       \
850
    &gen_op_s##width##_kernel,                                                \
851
    &gen_op_s##width##_super,                                                 \
852
    &gen_op_s##width##_user,                                                  \
853
}
854
#endif
855

    
856
#if defined(TARGET_MIPS64)
857
OP_LD_TABLE(d);
858
OP_LD_TABLE(dl);
859
OP_LD_TABLE(dr);
860
OP_ST_TABLE(d);
861
OP_ST_TABLE(dl);
862
OP_ST_TABLE(dr);
863
OP_LD_TABLE(ld);
864
OP_ST_TABLE(cd);
865
OP_LD_TABLE(wu);
866
#endif
867
OP_LD_TABLE(w);
868
OP_LD_TABLE(wl);
869
OP_LD_TABLE(wr);
870
OP_ST_TABLE(w);
871
OP_ST_TABLE(wl);
872
OP_ST_TABLE(wr);
873
OP_LD_TABLE(h);
874
OP_LD_TABLE(hu);
875
OP_ST_TABLE(h);
876
OP_LD_TABLE(b);
877
OP_LD_TABLE(bu);
878
OP_ST_TABLE(b);
879
OP_LD_TABLE(l);
880
OP_ST_TABLE(c);
881
OP_LD_TABLE(wc1);
882
OP_ST_TABLE(wc1);
883
OP_LD_TABLE(dc1);
884
OP_ST_TABLE(dc1);
885
OP_LD_TABLE(uxc1);
886
OP_ST_TABLE(uxc1);
887

    
888
/* Load and store */
889
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
890
                      int base, int16_t offset)
891
{
892
    const char *opn = "ldst";
893

    
894
    if (base == 0) {
895
        GEN_LOAD_IMM_TN(T0, offset);
896
    } else if (offset == 0) {
897
        gen_op_load_gpr_T0(base);
898
    } else {
899
        gen_op_load_gpr_T0(base);
900
        gen_op_set_T1(offset);
901
        gen_op_addr_add();
902
    }
903
    /* Don't do NOP if destination is zero: we must perform the actual
904
       memory access. */
905
    switch (opc) {
906
#if defined(TARGET_MIPS64)
907
    case OPC_LWU:
908
        op_ldst(lwu);
909
        GEN_STORE_T0_REG(rt);
910
        opn = "lwu";
911
        break;
912
    case OPC_LD:
913
        op_ldst(ld);
914
        GEN_STORE_T0_REG(rt);
915
        opn = "ld";
916
        break;
917
    case OPC_LLD:
918
        op_ldst(lld);
919
        GEN_STORE_T0_REG(rt);
920
        opn = "lld";
921
        break;
922
    case OPC_SD:
923
        GEN_LOAD_REG_T1(rt);
924
        op_ldst(sd);
925
        opn = "sd";
926
        break;
927
    case OPC_SCD:
928
        save_cpu_state(ctx, 1);
929
        GEN_LOAD_REG_T1(rt);
930
        op_ldst(scd);
931
        GEN_STORE_T0_REG(rt);
932
        opn = "scd";
933
        break;
934
    case OPC_LDL:
935
        GEN_LOAD_REG_T1(rt);
936
        op_ldst(ldl);
937
        GEN_STORE_T1_REG(rt);
938
        opn = "ldl";
939
        break;
940
    case OPC_SDL:
941
        GEN_LOAD_REG_T1(rt);
942
        op_ldst(sdl);
943
        opn = "sdl";
944
        break;
945
    case OPC_LDR:
946
        GEN_LOAD_REG_T1(rt);
947
        op_ldst(ldr);
948
        GEN_STORE_T1_REG(rt);
949
        opn = "ldr";
950
        break;
951
    case OPC_SDR:
952
        GEN_LOAD_REG_T1(rt);
953
        op_ldst(sdr);
954
        opn = "sdr";
955
        break;
956
#endif
957
    case OPC_LW:
958
        op_ldst(lw);
959
        GEN_STORE_T0_REG(rt);
960
        opn = "lw";
961
        break;
962
    case OPC_SW:
963
        GEN_LOAD_REG_T1(rt);
964
        op_ldst(sw);
965
        opn = "sw";
966
        break;
967
    case OPC_LH:
968
        op_ldst(lh);
969
        GEN_STORE_T0_REG(rt);
970
        opn = "lh";
971
        break;
972
    case OPC_SH:
973
        GEN_LOAD_REG_T1(rt);
974
        op_ldst(sh);
975
        opn = "sh";
976
        break;
977
    case OPC_LHU:
978
        op_ldst(lhu);
979
        GEN_STORE_T0_REG(rt);
980
        opn = "lhu";
981
        break;
982
    case OPC_LB:
983
        op_ldst(lb);
984
        GEN_STORE_T0_REG(rt);
985
        opn = "lb";
986
        break;
987
    case OPC_SB:
988
        GEN_LOAD_REG_T1(rt);
989
        op_ldst(sb);
990
        opn = "sb";
991
        break;
992
    case OPC_LBU:
993
        op_ldst(lbu);
994
        GEN_STORE_T0_REG(rt);
995
        opn = "lbu";
996
        break;
997
    case OPC_LWL:
998
        GEN_LOAD_REG_T1(rt);
999
        op_ldst(lwl);
1000
        GEN_STORE_T1_REG(rt);
1001
        opn = "lwl";
1002
        break;
1003
    case OPC_SWL:
1004
        GEN_LOAD_REG_T1(rt);
1005
        op_ldst(swl);
1006
        opn = "swr";
1007
        break;
1008
    case OPC_LWR:
1009
        GEN_LOAD_REG_T1(rt);
1010
        op_ldst(lwr);
1011
        GEN_STORE_T1_REG(rt);
1012
        opn = "lwr";
1013
        break;
1014
    case OPC_SWR:
1015
        GEN_LOAD_REG_T1(rt);
1016
        op_ldst(swr);
1017
        opn = "swr";
1018
        break;
1019
    case OPC_LL:
1020
        op_ldst(ll);
1021
        GEN_STORE_T0_REG(rt);
1022
        opn = "ll";
1023
        break;
1024
    case OPC_SC:
1025
        save_cpu_state(ctx, 1);
1026
        GEN_LOAD_REG_T1(rt);
1027
        op_ldst(sc);
1028
        GEN_STORE_T0_REG(rt);
1029
        opn = "sc";
1030
        break;
1031
    default:
1032
        MIPS_INVAL(opn);
1033
        generate_exception(ctx, EXCP_RI);
1034
        return;
1035
    }
1036
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1037
}
1038

    
1039
/* Load and store */
1040
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1041
                      int base, int16_t offset)
1042
{
1043
    const char *opn = "flt_ldst";
1044

    
1045
    if (base == 0) {
1046
        GEN_LOAD_IMM_TN(T0, offset);
1047
    } else if (offset == 0) {
1048
        gen_op_load_gpr_T0(base);
1049
    } else {
1050
        gen_op_load_gpr_T0(base);
1051
        gen_op_set_T1(offset);
1052
        gen_op_addr_add();
1053
    }
1054
    /* Don't do NOP if destination is zero: we must perform the actual
1055
       memory access. */
1056
    switch (opc) {
1057
    case OPC_LWC1:
1058
        op_ldst(lwc1);
1059
        GEN_STORE_FTN_FREG(ft, WT0);
1060
        opn = "lwc1";
1061
        break;
1062
    case OPC_SWC1:
1063
        GEN_LOAD_FREG_FTN(WT0, ft);
1064
        op_ldst(swc1);
1065
        opn = "swc1";
1066
        break;
1067
    case OPC_LDC1:
1068
        op_ldst(ldc1);
1069
        GEN_STORE_FTN_FREG(ft, DT0);
1070
        opn = "ldc1";
1071
        break;
1072
    case OPC_SDC1:
1073
        GEN_LOAD_FREG_FTN(DT0, ft);
1074
        op_ldst(sdc1);
1075
        opn = "sdc1";
1076
        break;
1077
    default:
1078
        MIPS_INVAL(opn);
1079
        generate_exception(ctx, EXCP_RI);
1080
        return;
1081
    }
1082
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1083
}
1084

    
1085
/* Arithmetic with immediate operand */
1086
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1087
                           int rt, int rs, int16_t imm)
1088
{
1089
    target_ulong uimm;
1090
    const char *opn = "imm arith";
1091

    
1092
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1093
        /* If no destination, treat it as a NOP.
1094
           For addi, we must generate the overflow exception when needed. */
1095
        MIPS_DEBUG("NOP");
1096
        return;
1097
    }
1098
    uimm = (uint16_t)imm;
1099
    switch (opc) {
1100
    case OPC_ADDI:
1101
    case OPC_ADDIU:
1102
#if defined(TARGET_MIPS64)
1103
    case OPC_DADDI:
1104
    case OPC_DADDIU:
1105
#endif
1106
    case OPC_SLTI:
1107
    case OPC_SLTIU:
1108
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1109
        /* Fall through. */
1110
    case OPC_ANDI:
1111
    case OPC_ORI:
1112
    case OPC_XORI:
1113
        GEN_LOAD_REG_T0(rs);
1114
        GEN_LOAD_IMM_TN(T1, uimm);
1115
        break;
1116
    case OPC_LUI:
1117
        GEN_LOAD_IMM_TN(T0, imm << 16);
1118
        break;
1119
    case OPC_SLL:
1120
    case OPC_SRA:
1121
    case OPC_SRL:
1122
#if defined(TARGET_MIPS64)
1123
    case OPC_DSLL:
1124
    case OPC_DSRA:
1125
    case OPC_DSRL:
1126
    case OPC_DSLL32:
1127
    case OPC_DSRA32:
1128
    case OPC_DSRL32:
1129
#endif
1130
        uimm &= 0x1f;
1131
        GEN_LOAD_REG_T0(rs);
1132
        GEN_LOAD_IMM_TN(T1, uimm);
1133
        break;
1134
    }
1135
    switch (opc) {
1136
    case OPC_ADDI:
1137
        save_cpu_state(ctx, 1);
1138
        gen_op_addo();
1139
        opn = "addi";
1140
        break;
1141
    case OPC_ADDIU:
1142
        gen_op_add();
1143
        opn = "addiu";
1144
        break;
1145
#if defined(TARGET_MIPS64)
1146
    case OPC_DADDI:
1147
        save_cpu_state(ctx, 1);
1148
        gen_op_daddo();
1149
        opn = "daddi";
1150
        break;
1151
    case OPC_DADDIU:
1152
        gen_op_dadd();
1153
        opn = "daddiu";
1154
        break;
1155
#endif
1156
    case OPC_SLTI:
1157
        gen_op_lt();
1158
        opn = "slti";
1159
        break;
1160
    case OPC_SLTIU:
1161
        gen_op_ltu();
1162
        opn = "sltiu";
1163
        break;
1164
    case OPC_ANDI:
1165
        gen_op_and();
1166
        opn = "andi";
1167
        break;
1168
    case OPC_ORI:
1169
        gen_op_or();
1170
        opn = "ori";
1171
        break;
1172
    case OPC_XORI:
1173
        gen_op_xor();
1174
        opn = "xori";
1175
        break;
1176
    case OPC_LUI:
1177
        opn = "lui";
1178
        break;
1179
    case OPC_SLL:
1180
        gen_op_sll();
1181
        opn = "sll";
1182
        break;
1183
    case OPC_SRA:
1184
        gen_op_sra();
1185
        opn = "sra";
1186
        break;
1187
    case OPC_SRL:
1188
        switch ((ctx->opcode >> 21) & 0x1f) {
1189
        case 0:
1190
            gen_op_srl();
1191
            opn = "srl";
1192
            break;
1193
        case 1:
1194
            /* rotr is decoded as srl on non-R2 CPUs */
1195
            if (env->insn_flags & ISA_MIPS32R2) {
1196
                gen_op_rotr();
1197
                opn = "rotr";
1198
            } else {
1199
                gen_op_srl();
1200
                opn = "srl";
1201
            }
1202
            break;
1203
        default:
1204
            MIPS_INVAL("invalid srl flag");
1205
            generate_exception(ctx, EXCP_RI);
1206
            break;
1207
        }
1208
        break;
1209
#if defined(TARGET_MIPS64)
1210
    case OPC_DSLL:
1211
        gen_op_dsll();
1212
        opn = "dsll";
1213
        break;
1214
    case OPC_DSRA:
1215
        gen_op_dsra();
1216
        opn = "dsra";
1217
        break;
1218
    case OPC_DSRL:
1219
        switch ((ctx->opcode >> 21) & 0x1f) {
1220
        case 0:
1221
            gen_op_dsrl();
1222
            opn = "dsrl";
1223
            break;
1224
        case 1:
1225
            /* drotr is decoded as dsrl on non-R2 CPUs */
1226
            if (env->insn_flags & ISA_MIPS32R2) {
1227
                gen_op_drotr();
1228
                opn = "drotr";
1229
            } else {
1230
                gen_op_dsrl();
1231
                opn = "dsrl";
1232
            }
1233
            break;
1234
        default:
1235
            MIPS_INVAL("invalid dsrl flag");
1236
            generate_exception(ctx, EXCP_RI);
1237
            break;
1238
        }
1239
        break;
1240
    case OPC_DSLL32:
1241
        gen_op_dsll32();
1242
        opn = "dsll32";
1243
        break;
1244
    case OPC_DSRA32:
1245
        gen_op_dsra32();
1246
        opn = "dsra32";
1247
        break;
1248
    case OPC_DSRL32:
1249
        switch ((ctx->opcode >> 21) & 0x1f) {
1250
        case 0:
1251
            gen_op_dsrl32();
1252
            opn = "dsrl32";
1253
            break;
1254
        case 1:
1255
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1256
            if (env->insn_flags & ISA_MIPS32R2) {
1257
                gen_op_drotr32();
1258
                opn = "drotr32";
1259
            } else {
1260
                gen_op_dsrl32();
1261
                opn = "dsrl32";
1262
            }
1263
            break;
1264
        default:
1265
            MIPS_INVAL("invalid dsrl32 flag");
1266
            generate_exception(ctx, EXCP_RI);
1267
            break;
1268
        }
1269
        break;
1270
#endif
1271
    default:
1272
        MIPS_INVAL(opn);
1273
        generate_exception(ctx, EXCP_RI);
1274
        return;
1275
    }
1276
    GEN_STORE_T0_REG(rt);
1277
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1278
}
1279

    
1280
/* Arithmetic */
1281
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1282
                       int rd, int rs, int rt)
1283
{
1284
    const char *opn = "arith";
1285

    
1286
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1287
       && opc != OPC_DADD && opc != OPC_DSUB) {
1288
        /* If no destination, treat it as a NOP.
1289
           For add & sub, we must generate the overflow exception when needed. */
1290
        MIPS_DEBUG("NOP");
1291
        return;
1292
    }
1293
    GEN_LOAD_REG_T0(rs);
1294
    /* Specialcase the conventional move operation. */
1295
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1296
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1297
        GEN_STORE_T0_REG(rd);
1298
        return;
1299
    }
1300
    GEN_LOAD_REG_T1(rt);
1301
    switch (opc) {
1302
    case OPC_ADD:
1303
        save_cpu_state(ctx, 1);
1304
        gen_op_addo();
1305
        opn = "add";
1306
        break;
1307
    case OPC_ADDU:
1308
        gen_op_add();
1309
        opn = "addu";
1310
        break;
1311
    case OPC_SUB:
1312
        save_cpu_state(ctx, 1);
1313
        gen_op_subo();
1314
        opn = "sub";
1315
        break;
1316
    case OPC_SUBU:
1317
        gen_op_sub();
1318
        opn = "subu";
1319
        break;
1320
#if defined(TARGET_MIPS64)
1321
    case OPC_DADD:
1322
        save_cpu_state(ctx, 1);
1323
        gen_op_daddo();
1324
        opn = "dadd";
1325
        break;
1326
    case OPC_DADDU:
1327
        gen_op_dadd();
1328
        opn = "daddu";
1329
        break;
1330
    case OPC_DSUB:
1331
        save_cpu_state(ctx, 1);
1332
        gen_op_dsubo();
1333
        opn = "dsub";
1334
        break;
1335
    case OPC_DSUBU:
1336
        gen_op_dsub();
1337
        opn = "dsubu";
1338
        break;
1339
#endif
1340
    case OPC_SLT:
1341
        gen_op_lt();
1342
        opn = "slt";
1343
        break;
1344
    case OPC_SLTU:
1345
        gen_op_ltu();
1346
        opn = "sltu";
1347
        break;
1348
    case OPC_AND:
1349
        gen_op_and();
1350
        opn = "and";
1351
        break;
1352
    case OPC_NOR:
1353
        gen_op_nor();
1354
        opn = "nor";
1355
        break;
1356
    case OPC_OR:
1357
        gen_op_or();
1358
        opn = "or";
1359
        break;
1360
    case OPC_XOR:
1361
        gen_op_xor();
1362
        opn = "xor";
1363
        break;
1364
    case OPC_MUL:
1365
        gen_op_mul();
1366
        opn = "mul";
1367
        break;
1368
    case OPC_MOVN:
1369
        gen_op_movn(rd);
1370
        opn = "movn";
1371
        goto print;
1372
    case OPC_MOVZ:
1373
        gen_op_movz(rd);
1374
        opn = "movz";
1375
        goto print;
1376
    case OPC_SLLV:
1377
        gen_op_sllv();
1378
        opn = "sllv";
1379
        break;
1380
    case OPC_SRAV:
1381
        gen_op_srav();
1382
        opn = "srav";
1383
        break;
1384
    case OPC_SRLV:
1385
        switch ((ctx->opcode >> 6) & 0x1f) {
1386
        case 0:
1387
            gen_op_srlv();
1388
            opn = "srlv";
1389
            break;
1390
        case 1:
1391
            /* rotrv is decoded as srlv on non-R2 CPUs */
1392
            if (env->insn_flags & ISA_MIPS32R2) {
1393
                gen_op_rotrv();
1394
                opn = "rotrv";
1395
            } else {
1396
                gen_op_srlv();
1397
                opn = "srlv";
1398
            }
1399
            break;
1400
        default:
1401
            MIPS_INVAL("invalid srlv flag");
1402
            generate_exception(ctx, EXCP_RI);
1403
            break;
1404
        }
1405
        break;
1406
#if defined(TARGET_MIPS64)
1407
    case OPC_DSLLV:
1408
        gen_op_dsllv();
1409
        opn = "dsllv";
1410
        break;
1411
    case OPC_DSRAV:
1412
        gen_op_dsrav();
1413
        opn = "dsrav";
1414
        break;
1415
    case OPC_DSRLV:
1416
        switch ((ctx->opcode >> 6) & 0x1f) {
1417
        case 0:
1418
            gen_op_dsrlv();
1419
            opn = "dsrlv";
1420
            break;
1421
        case 1:
1422
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1423
            if (env->insn_flags & ISA_MIPS32R2) {
1424
                gen_op_drotrv();
1425
                opn = "drotrv";
1426
            } else {
1427
                gen_op_dsrlv();
1428
                opn = "dsrlv";
1429
            }
1430
            break;
1431
        default:
1432
            MIPS_INVAL("invalid dsrlv flag");
1433
            generate_exception(ctx, EXCP_RI);
1434
            break;
1435
        }
1436
        break;
1437
#endif
1438
    default:
1439
        MIPS_INVAL(opn);
1440
        generate_exception(ctx, EXCP_RI);
1441
        return;
1442
    }
1443
    GEN_STORE_T0_REG(rd);
1444
 print:
1445
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1446
}
1447

    
1448
/* Arithmetic on HI/LO registers */
1449
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1450
{
1451
    const char *opn = "hilo";
1452

    
1453
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1454
        /* Treat as NOP. */
1455
        MIPS_DEBUG("NOP");
1456
        return;
1457
    }
1458
    switch (opc) {
1459
    case OPC_MFHI:
1460
        gen_op_load_HI(0);
1461
        GEN_STORE_T0_REG(reg);
1462
        opn = "mfhi";
1463
        break;
1464
    case OPC_MFLO:
1465
        gen_op_load_LO(0);
1466
        GEN_STORE_T0_REG(reg);
1467
        opn = "mflo";
1468
        break;
1469
    case OPC_MTHI:
1470
        GEN_LOAD_REG_T0(reg);
1471
        gen_op_store_HI(0);
1472
        opn = "mthi";
1473
        break;
1474
    case OPC_MTLO:
1475
        GEN_LOAD_REG_T0(reg);
1476
        gen_op_store_LO(0);
1477
        opn = "mtlo";
1478
        break;
1479
    default:
1480
        MIPS_INVAL(opn);
1481
        generate_exception(ctx, EXCP_RI);
1482
        return;
1483
    }
1484
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1485
}
1486

    
1487
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1488
                        int rs, int rt)
1489
{
1490
    const char *opn = "mul/div";
1491

    
1492
    GEN_LOAD_REG_T0(rs);
1493
    GEN_LOAD_REG_T1(rt);
1494
    switch (opc) {
1495
    case OPC_DIV:
1496
        gen_op_div();
1497
        opn = "div";
1498
        break;
1499
    case OPC_DIVU:
1500
        gen_op_divu();
1501
        opn = "divu";
1502
        break;
1503
    case OPC_MULT:
1504
        gen_op_mult();
1505
        opn = "mult";
1506
        break;
1507
    case OPC_MULTU:
1508
        gen_op_multu();
1509
        opn = "multu";
1510
        break;
1511
#if defined(TARGET_MIPS64)
1512
    case OPC_DDIV:
1513
        gen_op_ddiv();
1514
        opn = "ddiv";
1515
        break;
1516
    case OPC_DDIVU:
1517
        gen_op_ddivu();
1518
        opn = "ddivu";
1519
        break;
1520
    case OPC_DMULT:
1521
        gen_op_dmult();
1522
        opn = "dmult";
1523
        break;
1524
    case OPC_DMULTU:
1525
        gen_op_dmultu();
1526
        opn = "dmultu";
1527
        break;
1528
#endif
1529
    case OPC_MADD:
1530
        gen_op_madd();
1531
        opn = "madd";
1532
        break;
1533
    case OPC_MADDU:
1534
        gen_op_maddu();
1535
        opn = "maddu";
1536
        break;
1537
    case OPC_MSUB:
1538
        gen_op_msub();
1539
        opn = "msub";
1540
        break;
1541
    case OPC_MSUBU:
1542
        gen_op_msubu();
1543
        opn = "msubu";
1544
        break;
1545
    default:
1546
        MIPS_INVAL(opn);
1547
        generate_exception(ctx, EXCP_RI);
1548
        return;
1549
    }
1550
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1551
}
1552

    
1553
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1554
                            int rd, int rs, int rt)
1555
{
1556
    const char *opn = "mul vr54xx";
1557

    
1558
    GEN_LOAD_REG_T0(rs);
1559
    GEN_LOAD_REG_T1(rt);
1560

    
1561
    switch (opc) {
1562
    case OPC_VR54XX_MULS:
1563
        gen_op_muls();
1564
        opn = "muls";
1565
        break;
1566
    case OPC_VR54XX_MULSU:
1567
        gen_op_mulsu();
1568
        opn = "mulsu";
1569
        break;
1570
    case OPC_VR54XX_MACC:
1571
        gen_op_macc();
1572
        opn = "macc";
1573
        break;
1574
    case OPC_VR54XX_MACCU:
1575
        gen_op_maccu();
1576
        opn = "maccu";
1577
        break;
1578
    case OPC_VR54XX_MSAC:
1579
        gen_op_msac();
1580
        opn = "msac";
1581
        break;
1582
    case OPC_VR54XX_MSACU:
1583
        gen_op_msacu();
1584
        opn = "msacu";
1585
        break;
1586
    case OPC_VR54XX_MULHI:
1587
        gen_op_mulhi();
1588
        opn = "mulhi";
1589
        break;
1590
    case OPC_VR54XX_MULHIU:
1591
        gen_op_mulhiu();
1592
        opn = "mulhiu";
1593
        break;
1594
    case OPC_VR54XX_MULSHI:
1595
        gen_op_mulshi();
1596
        opn = "mulshi";
1597
        break;
1598
    case OPC_VR54XX_MULSHIU:
1599
        gen_op_mulshiu();
1600
        opn = "mulshiu";
1601
        break;
1602
    case OPC_VR54XX_MACCHI:
1603
        gen_op_macchi();
1604
        opn = "macchi";
1605
        break;
1606
    case OPC_VR54XX_MACCHIU:
1607
        gen_op_macchiu();
1608
        opn = "macchiu";
1609
        break;
1610
    case OPC_VR54XX_MSACHI:
1611
        gen_op_msachi();
1612
        opn = "msachi";
1613
        break;
1614
    case OPC_VR54XX_MSACHIU:
1615
        gen_op_msachiu();
1616
        opn = "msachiu";
1617
        break;
1618
    default:
1619
        MIPS_INVAL("mul vr54xx");
1620
        generate_exception(ctx, EXCP_RI);
1621
        return;
1622
    }
1623
    GEN_STORE_T0_REG(rd);
1624
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1625
}
1626

    
1627
static void gen_cl (DisasContext *ctx, uint32_t opc,
1628
                    int rd, int rs)
1629
{
1630
    const char *opn = "CLx";
1631
    if (rd == 0) {
1632
        /* Treat as NOP. */
1633
        MIPS_DEBUG("NOP");
1634
        return;
1635
    }
1636
    GEN_LOAD_REG_T0(rs);
1637
    switch (opc) {
1638
    case OPC_CLO:
1639
        gen_op_clo();
1640
        opn = "clo";
1641
        break;
1642
    case OPC_CLZ:
1643
        gen_op_clz();
1644
        opn = "clz";
1645
        break;
1646
#if defined(TARGET_MIPS64)
1647
    case OPC_DCLO:
1648
        gen_op_dclo();
1649
        opn = "dclo";
1650
        break;
1651
    case OPC_DCLZ:
1652
        gen_op_dclz();
1653
        opn = "dclz";
1654
        break;
1655
#endif
1656
    default:
1657
        MIPS_INVAL(opn);
1658
        generate_exception(ctx, EXCP_RI);
1659
        return;
1660
    }
1661
    gen_op_store_T0_gpr(rd);
1662
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1663
}
1664

    
1665
/* Traps */
1666
static void gen_trap (DisasContext *ctx, uint32_t opc,
1667
                      int rs, int rt, int16_t imm)
1668
{
1669
    int cond;
1670

    
1671
    cond = 0;
1672
    /* Load needed operands */
1673
    switch (opc) {
1674
    case OPC_TEQ:
1675
    case OPC_TGE:
1676
    case OPC_TGEU:
1677
    case OPC_TLT:
1678
    case OPC_TLTU:
1679
    case OPC_TNE:
1680
        /* Compare two registers */
1681
        if (rs != rt) {
1682
            GEN_LOAD_REG_T0(rs);
1683
            GEN_LOAD_REG_T1(rt);
1684
            cond = 1;
1685
        }
1686
        break;
1687
    case OPC_TEQI:
1688
    case OPC_TGEI:
1689
    case OPC_TGEIU:
1690
    case OPC_TLTI:
1691
    case OPC_TLTIU:
1692
    case OPC_TNEI:
1693
        /* Compare register to immediate */
1694
        if (rs != 0 || imm != 0) {
1695
            GEN_LOAD_REG_T0(rs);
1696
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1697
            cond = 1;
1698
        }
1699
        break;
1700
    }
1701
    if (cond == 0) {
1702
        switch (opc) {
1703
        case OPC_TEQ:   /* rs == rs */
1704
        case OPC_TEQI:  /* r0 == 0  */
1705
        case OPC_TGE:   /* rs >= rs */
1706
        case OPC_TGEI:  /* r0 >= 0  */
1707
        case OPC_TGEU:  /* rs >= rs unsigned */
1708
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1709
            /* Always trap */
1710
            gen_op_set_T0(1);
1711
            break;
1712
        case OPC_TLT:   /* rs < rs           */
1713
        case OPC_TLTI:  /* r0 < 0            */
1714
        case OPC_TLTU:  /* rs < rs unsigned  */
1715
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1716
        case OPC_TNE:   /* rs != rs          */
1717
        case OPC_TNEI:  /* r0 != 0           */
1718
            /* Never trap: treat as NOP. */
1719
            return;
1720
        default:
1721
            MIPS_INVAL("trap");
1722
            generate_exception(ctx, EXCP_RI);
1723
            return;
1724
        }
1725
    } else {
1726
        switch (opc) {
1727
        case OPC_TEQ:
1728
        case OPC_TEQI:
1729
            gen_op_eq();
1730
            break;
1731
        case OPC_TGE:
1732
        case OPC_TGEI:
1733
            gen_op_ge();
1734
            break;
1735
        case OPC_TGEU:
1736
        case OPC_TGEIU:
1737
            gen_op_geu();
1738
            break;
1739
        case OPC_TLT:
1740
        case OPC_TLTI:
1741
            gen_op_lt();
1742
            break;
1743
        case OPC_TLTU:
1744
        case OPC_TLTIU:
1745
            gen_op_ltu();
1746
            break;
1747
        case OPC_TNE:
1748
        case OPC_TNEI:
1749
            gen_op_ne();
1750
            break;
1751
        default:
1752
            MIPS_INVAL("trap");
1753
            generate_exception(ctx, EXCP_RI);
1754
            return;
1755
        }
1756
    }
1757
    save_cpu_state(ctx, 1);
1758
    gen_op_trap();
1759
    ctx->bstate = BS_STOP;
1760
}
1761

    
1762
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1763
{
1764
    TranslationBlock *tb;
1765
    tb = ctx->tb;
1766
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1767
        if (n == 0)
1768
            gen_op_goto_tb0(TBPARAM(tb));
1769
        else
1770
            gen_op_goto_tb1(TBPARAM(tb));
1771
        gen_save_pc(dest);
1772
        gen_op_set_T0((long)tb + n);
1773
    } else {
1774
        gen_save_pc(dest);
1775
        gen_op_reset_T0();
1776
    }
1777
    gen_op_exit_tb();
1778
}
1779

    
1780
/* Branches (before delay slot) */
1781
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1782
                                int rs, int rt, int32_t offset)
1783
{
1784
    target_ulong btarget = -1;
1785
    int blink = 0;
1786
    int bcond = 0;
1787

    
1788
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1789
#ifdef MIPS_DEBUG_DISAS
1790
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1791
            fprintf(logfile,
1792
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1793
                    ctx->pc);
1794
        }
1795
#endif
1796
        generate_exception(ctx, EXCP_RI);
1797
        return;
1798
    }
1799

    
1800
    /* Load needed operands */
1801
    switch (opc) {
1802
    case OPC_BEQ:
1803
    case OPC_BEQL:
1804
    case OPC_BNE:
1805
    case OPC_BNEL:
1806
        /* Compare two registers */
1807
        if (rs != rt) {
1808
            GEN_LOAD_REG_T0(rs);
1809
            GEN_LOAD_REG_T1(rt);
1810
            bcond = 1;
1811
        }
1812
        btarget = ctx->pc + 4 + offset;
1813
        break;
1814
    case OPC_BGEZ:
1815
    case OPC_BGEZAL:
1816
    case OPC_BGEZALL:
1817
    case OPC_BGEZL:
1818
    case OPC_BGTZ:
1819
    case OPC_BGTZL:
1820
    case OPC_BLEZ:
1821
    case OPC_BLEZL:
1822
    case OPC_BLTZ:
1823
    case OPC_BLTZAL:
1824
    case OPC_BLTZALL:
1825
    case OPC_BLTZL:
1826
        /* Compare to zero */
1827
        if (rs != 0) {
1828
            gen_op_load_gpr_T0(rs);
1829
            bcond = 1;
1830
        }
1831
        btarget = ctx->pc + 4 + offset;
1832
        break;
1833
    case OPC_J:
1834
    case OPC_JAL:
1835
        /* Jump to immediate */
1836
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1837
        break;
1838
    case OPC_JR:
1839
    case OPC_JALR:
1840
        /* Jump to register */
1841
        if (offset != 0 && offset != 16) {
1842
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1843
               others are reserved. */
1844
            MIPS_INVAL("jump hint");
1845
            generate_exception(ctx, EXCP_RI);
1846
            return;
1847
        }
1848
        GEN_LOAD_REG_T2(rs);
1849
        break;
1850
    default:
1851
        MIPS_INVAL("branch/jump");
1852
        generate_exception(ctx, EXCP_RI);
1853
        return;
1854
    }
1855
    if (bcond == 0) {
1856
        /* No condition to be computed */
1857
        switch (opc) {
1858
        case OPC_BEQ:     /* rx == rx        */
1859
        case OPC_BEQL:    /* rx == rx likely */
1860
        case OPC_BGEZ:    /* 0 >= 0          */
1861
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1862
        case OPC_BLEZ:    /* 0 <= 0          */
1863
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1864
            /* Always take */
1865
            ctx->hflags |= MIPS_HFLAG_B;
1866
            MIPS_DEBUG("balways");
1867
            break;
1868
        case OPC_BGEZAL:  /* 0 >= 0          */
1869
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1870
            /* Always take and link */
1871
            blink = 31;
1872
            ctx->hflags |= MIPS_HFLAG_B;
1873
            MIPS_DEBUG("balways and link");
1874
            break;
1875
        case OPC_BNE:     /* rx != rx        */
1876
        case OPC_BGTZ:    /* 0 > 0           */
1877
        case OPC_BLTZ:    /* 0 < 0           */
1878
            /* Treat as NOP. */
1879
            MIPS_DEBUG("bnever (NOP)");
1880
            return;
1881
        case OPC_BLTZAL:  /* 0 < 0           */
1882
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1883
            gen_op_store_T0_gpr(31);
1884
            MIPS_DEBUG("bnever and link");
1885
            return;
1886
        case OPC_BLTZALL: /* 0 < 0 likely */
1887
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1888
            gen_op_store_T0_gpr(31);
1889
            /* Skip the instruction in the delay slot */
1890
            MIPS_DEBUG("bnever, link and skip");
1891
            ctx->pc += 4;
1892
            return;
1893
        case OPC_BNEL:    /* rx != rx likely */
1894
        case OPC_BGTZL:   /* 0 > 0 likely */
1895
        case OPC_BLTZL:   /* 0 < 0 likely */
1896
            /* Skip the instruction in the delay slot */
1897
            MIPS_DEBUG("bnever and skip");
1898
            ctx->pc += 4;
1899
            return;
1900
        case OPC_J:
1901
            ctx->hflags |= MIPS_HFLAG_B;
1902
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1903
            break;
1904
        case OPC_JAL:
1905
            blink = 31;
1906
            ctx->hflags |= MIPS_HFLAG_B;
1907
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1908
            break;
1909
        case OPC_JR:
1910
            ctx->hflags |= MIPS_HFLAG_BR;
1911
            MIPS_DEBUG("jr %s", regnames[rs]);
1912
            break;
1913
        case OPC_JALR:
1914
            blink = rt;
1915
            ctx->hflags |= MIPS_HFLAG_BR;
1916
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1917
            break;
1918
        default:
1919
            MIPS_INVAL("branch/jump");
1920
            generate_exception(ctx, EXCP_RI);
1921
            return;
1922
        }
1923
    } else {
1924
        switch (opc) {
1925
        case OPC_BEQ:
1926
            gen_op_eq();
1927
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1928
                       regnames[rs], regnames[rt], btarget);
1929
            goto not_likely;
1930
        case OPC_BEQL:
1931
            gen_op_eq();
1932
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1933
                       regnames[rs], regnames[rt], btarget);
1934
            goto likely;
1935
        case OPC_BNE:
1936
            gen_op_ne();
1937
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1938
                       regnames[rs], regnames[rt], btarget);
1939
            goto not_likely;
1940
        case OPC_BNEL:
1941
            gen_op_ne();
1942
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1943
                       regnames[rs], regnames[rt], btarget);
1944
            goto likely;
1945
        case OPC_BGEZ:
1946
            gen_op_gez();
1947
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1948
            goto not_likely;
1949
        case OPC_BGEZL:
1950
            gen_op_gez();
1951
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1952
            goto likely;
1953
        case OPC_BGEZAL:
1954
            gen_op_gez();
1955
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1956
            blink = 31;
1957
            goto not_likely;
1958
        case OPC_BGEZALL:
1959
            gen_op_gez();
1960
            blink = 31;
1961
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1962
            goto likely;
1963
        case OPC_BGTZ:
1964
            gen_op_gtz();
1965
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1966
            goto not_likely;
1967
        case OPC_BGTZL:
1968
            gen_op_gtz();
1969
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1970
            goto likely;
1971
        case OPC_BLEZ:
1972
            gen_op_lez();
1973
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1974
            goto not_likely;
1975
        case OPC_BLEZL:
1976
            gen_op_lez();
1977
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1978
            goto likely;
1979
        case OPC_BLTZ:
1980
            gen_op_ltz();
1981
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1982
            goto not_likely;
1983
        case OPC_BLTZL:
1984
            gen_op_ltz();
1985
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1986
            goto likely;
1987
        case OPC_BLTZAL:
1988
            gen_op_ltz();
1989
            blink = 31;
1990
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1991
        not_likely:
1992
            ctx->hflags |= MIPS_HFLAG_BC;
1993
            gen_op_set_bcond();
1994
            break;
1995
        case OPC_BLTZALL:
1996
            gen_op_ltz();
1997
            blink = 31;
1998
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1999
        likely:
2000
            ctx->hflags |= MIPS_HFLAG_BL;
2001
            gen_op_set_bcond();
2002
            gen_op_save_bcond();
2003
            break;
2004
        default:
2005
            MIPS_INVAL("conditional branch/jump");
2006
            generate_exception(ctx, EXCP_RI);
2007
            return;
2008
        }
2009
    }
2010
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2011
               blink, ctx->hflags, btarget);
2012

    
2013
    ctx->btarget = btarget;
2014
    if (blink > 0) {
2015
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2016
        gen_op_store_T0_gpr(blink);
2017
    }
2018
}
2019

    
2020
/* special3 bitfield operations */
2021
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2022
                       int rs, int lsb, int msb)
2023
{
2024
    GEN_LOAD_REG_T1(rs);
2025
    switch (opc) {
2026
    case OPC_EXT:
2027
        if (lsb + msb > 31)
2028
            goto fail;
2029
        gen_op_ext(lsb, msb + 1);
2030
        break;
2031
#if defined(TARGET_MIPS64)
2032
    case OPC_DEXTM:
2033
        if (lsb + msb > 63)
2034
            goto fail;
2035
        gen_op_dext(lsb, msb + 1 + 32);
2036
        break;
2037
    case OPC_DEXTU:
2038
        if (lsb + msb > 63)
2039
            goto fail;
2040
        gen_op_dext(lsb + 32, msb + 1);
2041
        break;
2042
    case OPC_DEXT:
2043
        if (lsb + msb > 63)
2044
            goto fail;
2045
        gen_op_dext(lsb, msb + 1);
2046
        break;
2047
#endif
2048
    case OPC_INS:
2049
        if (lsb > msb)
2050
            goto fail;
2051
        GEN_LOAD_REG_T0(rt);
2052
        gen_op_ins(lsb, msb - lsb + 1);
2053
        break;
2054
#if defined(TARGET_MIPS64)
2055
    case OPC_DINSM:
2056
        if (lsb > msb)
2057
            goto fail;
2058
        GEN_LOAD_REG_T0(rt);
2059
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2060
        break;
2061
    case OPC_DINSU:
2062
        if (lsb > msb)
2063
            goto fail;
2064
        GEN_LOAD_REG_T0(rt);
2065
        gen_op_dins(lsb + 32, msb - lsb + 1);
2066
        break;
2067
    case OPC_DINS:
2068
        if (lsb > msb)
2069
            goto fail;
2070
        GEN_LOAD_REG_T0(rt);
2071
        gen_op_dins(lsb, msb - lsb + 1);
2072
        break;
2073
#endif
2074
    default:
2075
fail:
2076
        MIPS_INVAL("bitops");
2077
        generate_exception(ctx, EXCP_RI);
2078
        return;
2079
    }
2080
    GEN_STORE_T0_REG(rt);
2081
}
2082

    
2083
/* CP0 (MMU and control) */
2084
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2085
{
2086
    const char *rn = "invalid";
2087

    
2088
    if (sel != 0)
2089
        check_insn(env, ctx, ISA_MIPS32);
2090

    
2091
    switch (reg) {
2092
    case 0:
2093
        switch (sel) {
2094
        case 0:
2095
            gen_op_mfc0_index();
2096
            rn = "Index";
2097
            break;
2098
        case 1:
2099
            check_insn(env, ctx, ASE_MT);
2100
            gen_op_mfc0_mvpcontrol();
2101
            rn = "MVPControl";
2102
            break;
2103
        case 2:
2104
            check_insn(env, ctx, ASE_MT);
2105
            gen_op_mfc0_mvpconf0();
2106
            rn = "MVPConf0";
2107
            break;
2108
        case 3:
2109
            check_insn(env, ctx, ASE_MT);
2110
            gen_op_mfc0_mvpconf1();
2111
            rn = "MVPConf1";
2112
            break;
2113
        default:
2114
            goto die;
2115
        }
2116
        break;
2117
    case 1:
2118
        switch (sel) {
2119
        case 0:
2120
            gen_op_mfc0_random();
2121
            rn = "Random";
2122
            break;
2123
        case 1:
2124
            check_insn(env, ctx, ASE_MT);
2125
            gen_op_mfc0_vpecontrol();
2126
            rn = "VPEControl";
2127
            break;
2128
        case 2:
2129
            check_insn(env, ctx, ASE_MT);
2130
            gen_op_mfc0_vpeconf0();
2131
            rn = "VPEConf0";
2132
            break;
2133
        case 3:
2134
            check_insn(env, ctx, ASE_MT);
2135
            gen_op_mfc0_vpeconf1();
2136
            rn = "VPEConf1";
2137
            break;
2138
        case 4:
2139
            check_insn(env, ctx, ASE_MT);
2140
            gen_op_mfc0_yqmask();
2141
            rn = "YQMask";
2142
            break;
2143
        case 5:
2144
            check_insn(env, ctx, ASE_MT);
2145
            gen_op_mfc0_vpeschedule();
2146
            rn = "VPESchedule";
2147
            break;
2148
        case 6:
2149
            check_insn(env, ctx, ASE_MT);
2150
            gen_op_mfc0_vpeschefback();
2151
            rn = "VPEScheFBack";
2152
            break;
2153
        case 7:
2154
            check_insn(env, ctx, ASE_MT);
2155
            gen_op_mfc0_vpeopt();
2156
            rn = "VPEOpt";
2157
            break;
2158
        default:
2159
            goto die;
2160
        }
2161
        break;
2162
    case 2:
2163
        switch (sel) {
2164
        case 0:
2165
            gen_op_mfc0_entrylo0();
2166
            rn = "EntryLo0";
2167
            break;
2168
        case 1:
2169
            check_insn(env, ctx, ASE_MT);
2170
            gen_op_mfc0_tcstatus();
2171
            rn = "TCStatus";
2172
            break;
2173
        case 2:
2174
            check_insn(env, ctx, ASE_MT);
2175
            gen_op_mfc0_tcbind();
2176
            rn = "TCBind";
2177
            break;
2178
        case 3:
2179
            check_insn(env, ctx, ASE_MT);
2180
            gen_op_mfc0_tcrestart();
2181
            rn = "TCRestart";
2182
            break;
2183
        case 4:
2184
            check_insn(env, ctx, ASE_MT);
2185
            gen_op_mfc0_tchalt();
2186
            rn = "TCHalt";
2187
            break;
2188
        case 5:
2189
            check_insn(env, ctx, ASE_MT);
2190
            gen_op_mfc0_tccontext();
2191
            rn = "TCContext";
2192
            break;
2193
        case 6:
2194
            check_insn(env, ctx, ASE_MT);
2195
            gen_op_mfc0_tcschedule();
2196
            rn = "TCSchedule";
2197
            break;
2198
        case 7:
2199
            check_insn(env, ctx, ASE_MT);
2200
            gen_op_mfc0_tcschefback();
2201
            rn = "TCScheFBack";
2202
            break;
2203
        default:
2204
            goto die;
2205
        }
2206
        break;
2207
    case 3:
2208
        switch (sel) {
2209
        case 0:
2210
            gen_op_mfc0_entrylo1();
2211
            rn = "EntryLo1";
2212
            break;
2213
        default:
2214
            goto die;
2215
        }
2216
        break;
2217
    case 4:
2218
        switch (sel) {
2219
        case 0:
2220
            gen_op_mfc0_context();
2221
            rn = "Context";
2222
            break;
2223
        case 1:
2224
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2225
            rn = "ContextConfig";
2226
//            break;
2227
        default:
2228
            goto die;
2229
        }
2230
        break;
2231
    case 5:
2232
        switch (sel) {
2233
        case 0:
2234
            gen_op_mfc0_pagemask();
2235
            rn = "PageMask";
2236
            break;
2237
        case 1:
2238
            check_insn(env, ctx, ISA_MIPS32R2);
2239
            gen_op_mfc0_pagegrain();
2240
            rn = "PageGrain";
2241
            break;
2242
        default:
2243
            goto die;
2244
        }
2245
        break;
2246
    case 6:
2247
        switch (sel) {
2248
        case 0:
2249
            gen_op_mfc0_wired();
2250
            rn = "Wired";
2251
            break;
2252
        case 1:
2253
            check_insn(env, ctx, ISA_MIPS32R2);
2254
            gen_op_mfc0_srsconf0();
2255
            rn = "SRSConf0";
2256
            break;
2257
        case 2:
2258
            check_insn(env, ctx, ISA_MIPS32R2);
2259
            gen_op_mfc0_srsconf1();
2260
            rn = "SRSConf1";
2261
            break;
2262
        case 3:
2263
            check_insn(env, ctx, ISA_MIPS32R2);
2264
            gen_op_mfc0_srsconf2();
2265
            rn = "SRSConf2";
2266
            break;
2267
        case 4:
2268
            check_insn(env, ctx, ISA_MIPS32R2);
2269
            gen_op_mfc0_srsconf3();
2270
            rn = "SRSConf3";
2271
            break;
2272
        case 5:
2273
            check_insn(env, ctx, ISA_MIPS32R2);
2274
            gen_op_mfc0_srsconf4();
2275
            rn = "SRSConf4";
2276
            break;
2277
        default:
2278
            goto die;
2279
        }
2280
        break;
2281
    case 7:
2282
        switch (sel) {
2283
        case 0:
2284
            check_insn(env, ctx, ISA_MIPS32R2);
2285
            gen_op_mfc0_hwrena();
2286
            rn = "HWREna";
2287
            break;
2288
        default:
2289
            goto die;
2290
        }
2291
        break;
2292
    case 8:
2293
        switch (sel) {
2294
        case 0:
2295
            gen_op_mfc0_badvaddr();
2296
            rn = "BadVaddr";
2297
            break;
2298
        default:
2299
            goto die;
2300
       }
2301
        break;
2302
    case 9:
2303
        switch (sel) {
2304
        case 0:
2305
            gen_op_mfc0_count();
2306
            rn = "Count";
2307
            break;
2308
        /* 6,7 are implementation dependent */
2309
        default:
2310
            goto die;
2311
        }
2312
        break;
2313
    case 10:
2314
        switch (sel) {
2315
        case 0:
2316
            gen_op_mfc0_entryhi();
2317
            rn = "EntryHi";
2318
            break;
2319
        default:
2320
            goto die;
2321
        }
2322
        break;
2323
    case 11:
2324
        switch (sel) {
2325
        case 0:
2326
            gen_op_mfc0_compare();
2327
            rn = "Compare";
2328
            break;
2329
        /* 6,7 are implementation dependent */
2330
        default:
2331
            goto die;
2332
        }
2333
        break;
2334
    case 12:
2335
        switch (sel) {
2336
        case 0:
2337
            gen_op_mfc0_status();
2338
            rn = "Status";
2339
            break;
2340
        case 1:
2341
            check_insn(env, ctx, ISA_MIPS32R2);
2342
            gen_op_mfc0_intctl();
2343
            rn = "IntCtl";
2344
            break;
2345
        case 2:
2346
            check_insn(env, ctx, ISA_MIPS32R2);
2347
            gen_op_mfc0_srsctl();
2348
            rn = "SRSCtl";
2349
            break;
2350
        case 3:
2351
            check_insn(env, ctx, ISA_MIPS32R2);
2352
            gen_op_mfc0_srsmap();
2353
            rn = "SRSMap";
2354
            break;
2355
        default:
2356
            goto die;
2357
       }
2358
        break;
2359
    case 13:
2360
        switch (sel) {
2361
        case 0:
2362
            gen_op_mfc0_cause();
2363
            rn = "Cause";
2364
            break;
2365
        default:
2366
            goto die;
2367
       }
2368
        break;
2369
    case 14:
2370
        switch (sel) {
2371
        case 0:
2372
            gen_op_mfc0_epc();
2373
            rn = "EPC";
2374
            break;
2375
        default:
2376
            goto die;
2377
        }
2378
        break;
2379
    case 15:
2380
        switch (sel) {
2381
        case 0:
2382
            gen_op_mfc0_prid();
2383
            rn = "PRid";
2384
            break;
2385
        case 1:
2386
            check_insn(env, ctx, ISA_MIPS32R2);
2387
            gen_op_mfc0_ebase();
2388
            rn = "EBase";
2389
            break;
2390
        default:
2391
            goto die;
2392
       }
2393
        break;
2394
    case 16:
2395
        switch (sel) {
2396
        case 0:
2397
            gen_op_mfc0_config0();
2398
            rn = "Config";
2399
            break;
2400
        case 1:
2401
            gen_op_mfc0_config1();
2402
            rn = "Config1";
2403
            break;
2404
        case 2:
2405
            gen_op_mfc0_config2();
2406
            rn = "Config2";
2407
            break;
2408
        case 3:
2409
            gen_op_mfc0_config3();
2410
            rn = "Config3";
2411
            break;
2412
        /* 4,5 are reserved */
2413
        /* 6,7 are implementation dependent */
2414
        case 6:
2415
            gen_op_mfc0_config6();
2416
            rn = "Config6";
2417
            break;
2418
        case 7:
2419
            gen_op_mfc0_config7();
2420
            rn = "Config7";
2421
            break;
2422
        default:
2423
            goto die;
2424
        }
2425
        break;
2426
    case 17:
2427
        switch (sel) {
2428
        case 0:
2429
            gen_op_mfc0_lladdr();
2430
            rn = "LLAddr";
2431
            break;
2432
        default:
2433
            goto die;
2434
        }
2435
        break;
2436
    case 18:
2437
        switch (sel) {
2438
        case 0 ... 7:
2439
            gen_op_mfc0_watchlo(sel);
2440
            rn = "WatchLo";
2441
            break;
2442
        default:
2443
            goto die;
2444
        }
2445
        break;
2446
    case 19:
2447
        switch (sel) {
2448
        case 0 ...7:
2449
            gen_op_mfc0_watchhi(sel);
2450
            rn = "WatchHi";
2451
            break;
2452
        default:
2453
            goto die;
2454
        }
2455
        break;
2456
    case 20:
2457
        switch (sel) {
2458
        case 0:
2459
#if defined(TARGET_MIPS64)
2460
            check_insn(env, ctx, ISA_MIPS3);
2461
            gen_op_mfc0_xcontext();
2462
            rn = "XContext";
2463
            break;
2464
#endif
2465
        default:
2466
            goto die;
2467
        }
2468
        break;
2469
    case 21:
2470
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2471
        switch (sel) {
2472
        case 0:
2473
            gen_op_mfc0_framemask();
2474
            rn = "Framemask";
2475
            break;
2476
        default:
2477
            goto die;
2478
        }
2479
        break;
2480
    case 22:
2481
        /* ignored */
2482
        rn = "'Diagnostic"; /* implementation dependent */
2483
        break;
2484
    case 23:
2485
        switch (sel) {
2486
        case 0:
2487
            gen_op_mfc0_debug(); /* EJTAG support */
2488
            rn = "Debug";
2489
            break;
2490
        case 1:
2491
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2492
            rn = "TraceControl";
2493
//            break;
2494
        case 2:
2495
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2496
            rn = "TraceControl2";
2497
//            break;
2498
        case 3:
2499
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2500
            rn = "UserTraceData";
2501
//            break;
2502
        case 4:
2503
//            gen_op_mfc0_debug(); /* PDtrace support */
2504
            rn = "TraceBPC";
2505
//            break;
2506
        default:
2507
            goto die;
2508
        }
2509
        break;
2510
    case 24:
2511
        switch (sel) {
2512
        case 0:
2513
            gen_op_mfc0_depc(); /* EJTAG support */
2514
            rn = "DEPC";
2515
            break;
2516
        default:
2517
            goto die;
2518
        }
2519
        break;
2520
    case 25:
2521
        switch (sel) {
2522
        case 0:
2523
            gen_op_mfc0_performance0();
2524
            rn = "Performance0";
2525
            break;
2526
        case 1:
2527
//            gen_op_mfc0_performance1();
2528
            rn = "Performance1";
2529
//            break;
2530
        case 2:
2531
//            gen_op_mfc0_performance2();
2532
            rn = "Performance2";
2533
//            break;
2534
        case 3:
2535
//            gen_op_mfc0_performance3();
2536
            rn = "Performance3";
2537
//            break;
2538
        case 4:
2539
//            gen_op_mfc0_performance4();
2540
            rn = "Performance4";
2541
//            break;
2542
        case 5:
2543
//            gen_op_mfc0_performance5();
2544
            rn = "Performance5";
2545
//            break;
2546
        case 6:
2547
//            gen_op_mfc0_performance6();
2548
            rn = "Performance6";
2549
//            break;
2550
        case 7:
2551
//            gen_op_mfc0_performance7();
2552
            rn = "Performance7";
2553
//            break;
2554
        default:
2555
            goto die;
2556
        }
2557
        break;
2558
    case 26:
2559
       rn = "ECC";
2560
       break;
2561
    case 27:
2562
        switch (sel) {
2563
        /* ignored */
2564
        case 0 ... 3:
2565
            rn = "CacheErr";
2566
            break;
2567
        default:
2568
            goto die;
2569
        }
2570
        break;
2571
    case 28:
2572
        switch (sel) {
2573
        case 0:
2574
        case 2:
2575
        case 4:
2576
        case 6:
2577
            gen_op_mfc0_taglo();
2578
            rn = "TagLo";
2579
            break;
2580
        case 1:
2581
        case 3:
2582
        case 5:
2583
        case 7:
2584
            gen_op_mfc0_datalo();
2585
            rn = "DataLo";
2586
            break;
2587
        default:
2588
            goto die;
2589
        }
2590
        break;
2591
    case 29:
2592
        switch (sel) {
2593
        case 0:
2594
        case 2:
2595
        case 4:
2596
        case 6:
2597
            gen_op_mfc0_taghi();
2598
            rn = "TagHi";
2599
            break;
2600
        case 1:
2601
        case 3:
2602
        case 5:
2603
        case 7:
2604
            gen_op_mfc0_datahi();
2605
            rn = "DataHi";
2606
            break;
2607
        default:
2608
            goto die;
2609
        }
2610
        break;
2611
    case 30:
2612
        switch (sel) {
2613
        case 0:
2614
            gen_op_mfc0_errorepc();
2615
            rn = "ErrorEPC";
2616
            break;
2617
        default:
2618
            goto die;
2619
        }
2620
        break;
2621
    case 31:
2622
        switch (sel) {
2623
        case 0:
2624
            gen_op_mfc0_desave(); /* EJTAG support */
2625
            rn = "DESAVE";
2626
            break;
2627
        default:
2628
            goto die;
2629
        }
2630
        break;
2631
    default:
2632
       goto die;
2633
    }
2634
#if defined MIPS_DEBUG_DISAS
2635
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2636
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2637
                rn, reg, sel);
2638
    }
2639
#endif
2640
    return;
2641

    
2642
die:
2643
#if defined MIPS_DEBUG_DISAS
2644
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2645
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2646
                rn, reg, sel);
2647
    }
2648
#endif
2649
    generate_exception(ctx, EXCP_RI);
2650
}
2651

    
2652
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2653
{
2654
    const char *rn = "invalid";
2655

    
2656
    if (sel != 0)
2657
        check_insn(env, ctx, ISA_MIPS32);
2658

    
2659
    switch (reg) {
2660
    case 0:
2661
        switch (sel) {
2662
        case 0:
2663
            gen_op_mtc0_index();
2664
            rn = "Index";
2665
            break;
2666
        case 1:
2667
            check_insn(env, ctx, ASE_MT);
2668
            gen_op_mtc0_mvpcontrol();
2669
            rn = "MVPControl";
2670
            break;
2671
        case 2:
2672
            check_insn(env, ctx, ASE_MT);
2673
            /* ignored */
2674
            rn = "MVPConf0";
2675
            break;
2676
        case 3:
2677
            check_insn(env, ctx, ASE_MT);
2678
            /* ignored */
2679
            rn = "MVPConf1";
2680
            break;
2681
        default:
2682
            goto die;
2683
        }
2684
        break;
2685
    case 1:
2686
        switch (sel) {
2687
        case 0:
2688
            /* ignored */
2689
            rn = "Random";
2690
            break;
2691
        case 1:
2692
            check_insn(env, ctx, ASE_MT);
2693
            gen_op_mtc0_vpecontrol();
2694
            rn = "VPEControl";
2695
            break;
2696
        case 2:
2697
            check_insn(env, ctx, ASE_MT);
2698
            gen_op_mtc0_vpeconf0();
2699
            rn = "VPEConf0";
2700
            break;
2701
        case 3:
2702
            check_insn(env, ctx, ASE_MT);
2703
            gen_op_mtc0_vpeconf1();
2704
            rn = "VPEConf1";
2705
            break;
2706
        case 4:
2707
            check_insn(env, ctx, ASE_MT);
2708
            gen_op_mtc0_yqmask();
2709
            rn = "YQMask";
2710
            break;
2711
        case 5:
2712
            check_insn(env, ctx, ASE_MT);
2713
            gen_op_mtc0_vpeschedule();
2714
            rn = "VPESchedule";
2715
            break;
2716
        case 6:
2717
            check_insn(env, ctx, ASE_MT);
2718
            gen_op_mtc0_vpeschefback();
2719
            rn = "VPEScheFBack";
2720
            break;
2721
        case 7:
2722
            check_insn(env, ctx, ASE_MT);
2723
            gen_op_mtc0_vpeopt();
2724
            rn = "VPEOpt";
2725
            break;
2726
        default:
2727
            goto die;
2728
        }
2729
        break;
2730
    case 2:
2731
        switch (sel) {
2732
        case 0:
2733
            gen_op_mtc0_entrylo0();
2734
            rn = "EntryLo0";
2735
            break;
2736
        case 1:
2737
            check_insn(env, ctx, ASE_MT);
2738
            gen_op_mtc0_tcstatus();
2739
            rn = "TCStatus";
2740
            break;
2741
        case 2:
2742
            check_insn(env, ctx, ASE_MT);
2743
            gen_op_mtc0_tcbind();
2744
            rn = "TCBind";
2745
            break;
2746
        case 3:
2747
            check_insn(env, ctx, ASE_MT);
2748
            gen_op_mtc0_tcrestart();
2749
            rn = "TCRestart";
2750
            break;
2751
        case 4:
2752
            check_insn(env, ctx, ASE_MT);
2753
            gen_op_mtc0_tchalt();
2754
            rn = "TCHalt";
2755
            break;
2756
        case 5:
2757
            check_insn(env, ctx, ASE_MT);
2758
            gen_op_mtc0_tccontext();
2759
            rn = "TCContext";
2760
            break;
2761
        case 6:
2762
            check_insn(env, ctx, ASE_MT);
2763
            gen_op_mtc0_tcschedule();
2764
            rn = "TCSchedule";
2765
            break;
2766
        case 7:
2767
            check_insn(env, ctx, ASE_MT);
2768
            gen_op_mtc0_tcschefback();
2769
            rn = "TCScheFBack";
2770
            break;
2771
        default:
2772
            goto die;
2773
        }
2774
        break;
2775
    case 3:
2776
        switch (sel) {
2777
        case 0:
2778
            gen_op_mtc0_entrylo1();
2779
            rn = "EntryLo1";
2780
            break;
2781
        default:
2782
            goto die;
2783
        }
2784
        break;
2785
    case 4:
2786
        switch (sel) {
2787
        case 0:
2788
            gen_op_mtc0_context();
2789
            rn = "Context";
2790
            break;
2791
        case 1:
2792
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2793
            rn = "ContextConfig";
2794
//            break;
2795
        default:
2796
            goto die;
2797
        }
2798
        break;
2799
    case 5:
2800
        switch (sel) {
2801
        case 0:
2802
            gen_op_mtc0_pagemask();
2803
            rn = "PageMask";
2804
            break;
2805
        case 1:
2806
            check_insn(env, ctx, ISA_MIPS32R2);
2807
            gen_op_mtc0_pagegrain();
2808
            rn = "PageGrain";
2809
            break;
2810
        default:
2811
            goto die;
2812
        }
2813
        break;
2814
    case 6:
2815
        switch (sel) {
2816
        case 0:
2817
            gen_op_mtc0_wired();
2818
            rn = "Wired";
2819
            break;
2820
        case 1:
2821
            check_insn(env, ctx, ISA_MIPS32R2);
2822
            gen_op_mtc0_srsconf0();
2823
            rn = "SRSConf0";
2824
            break;
2825
        case 2:
2826
            check_insn(env, ctx, ISA_MIPS32R2);
2827
            gen_op_mtc0_srsconf1();
2828
            rn = "SRSConf1";
2829
            break;
2830
        case 3:
2831
            check_insn(env, ctx, ISA_MIPS32R2);
2832
            gen_op_mtc0_srsconf2();
2833
            rn = "SRSConf2";
2834
            break;
2835
        case 4:
2836
            check_insn(env, ctx, ISA_MIPS32R2);
2837
            gen_op_mtc0_srsconf3();
2838
            rn = "SRSConf3";
2839
            break;
2840
        case 5:
2841
            check_insn(env, ctx, ISA_MIPS32R2);
2842
            gen_op_mtc0_srsconf4();
2843
            rn = "SRSConf4";
2844
            break;
2845
        default:
2846
            goto die;
2847
        }
2848
        break;
2849
    case 7:
2850
        switch (sel) {
2851
        case 0:
2852
            check_insn(env, ctx, ISA_MIPS32R2);
2853
            gen_op_mtc0_hwrena();
2854
            rn = "HWREna";
2855
            break;
2856
        default:
2857
            goto die;
2858
        }
2859
        break;
2860
    case 8:
2861
        /* ignored */
2862
        rn = "BadVaddr";
2863
        break;
2864
    case 9:
2865
        switch (sel) {
2866
        case 0:
2867
            gen_op_mtc0_count();
2868
            rn = "Count";
2869
            break;
2870
        /* 6,7 are implementation dependent */
2871
        default:
2872
            goto die;
2873
        }
2874
        /* Stop translation as we may have switched the execution mode */
2875
        ctx->bstate = BS_STOP;
2876
        break;
2877
    case 10:
2878
        switch (sel) {
2879
        case 0:
2880
            gen_op_mtc0_entryhi();
2881
            rn = "EntryHi";
2882
            break;
2883
        default:
2884
            goto die;
2885
        }
2886
        break;
2887
    case 11:
2888
        switch (sel) {
2889
        case 0:
2890
            gen_op_mtc0_compare();
2891
            rn = "Compare";
2892
            break;
2893
        /* 6,7 are implementation dependent */
2894
        default:
2895
            goto die;
2896
        }
2897
        /* Stop translation as we may have switched the execution mode */
2898
        ctx->bstate = BS_STOP;
2899
        break;
2900
    case 12:
2901
        switch (sel) {
2902
        case 0:
2903
            gen_op_mtc0_status();
2904
            /* BS_STOP isn't good enough here, hflags may have changed. */
2905
            gen_save_pc(ctx->pc + 4);
2906
            ctx->bstate = BS_EXCP;
2907
            rn = "Status";
2908
            break;
2909
        case 1:
2910
            check_insn(env, ctx, ISA_MIPS32R2);
2911
            gen_op_mtc0_intctl();
2912
            /* Stop translation as we may have switched the execution mode */
2913
            ctx->bstate = BS_STOP;
2914
            rn = "IntCtl";
2915
            break;
2916
        case 2:
2917
            check_insn(env, ctx, ISA_MIPS32R2);
2918
            gen_op_mtc0_srsctl();
2919
            /* Stop translation as we may have switched the execution mode */
2920
            ctx->bstate = BS_STOP;
2921
            rn = "SRSCtl";
2922
            break;
2923
        case 3:
2924
            check_insn(env, ctx, ISA_MIPS32R2);
2925
            gen_op_mtc0_srsmap();
2926
            /* Stop translation as we may have switched the execution mode */
2927
            ctx->bstate = BS_STOP;
2928
            rn = "SRSMap";
2929
            break;
2930
        default:
2931
            goto die;
2932
        }
2933
        break;
2934
    case 13:
2935
        switch (sel) {
2936
        case 0:
2937
            gen_op_mtc0_cause();
2938
            rn = "Cause";
2939
            break;
2940
        default:
2941
            goto die;
2942
        }
2943
        /* Stop translation as we may have switched the execution mode */
2944
        ctx->bstate = BS_STOP;
2945
        break;
2946
    case 14:
2947
        switch (sel) {
2948
        case 0:
2949
            gen_op_mtc0_epc();
2950
            rn = "EPC";
2951
            break;
2952
        default:
2953
            goto die;
2954
        }
2955
        break;
2956
    case 15:
2957
        switch (sel) {
2958
        case 0:
2959
            /* ignored */
2960
            rn = "PRid";
2961
            break;
2962
        case 1:
2963
            check_insn(env, ctx, ISA_MIPS32R2);
2964
            gen_op_mtc0_ebase();
2965
            rn = "EBase";
2966
            break;
2967
        default:
2968
            goto die;
2969
        }
2970
        break;
2971
    case 16:
2972
        switch (sel) {
2973
        case 0:
2974
            gen_op_mtc0_config0();
2975
            rn = "Config";
2976
            /* Stop translation as we may have switched the execution mode */
2977
            ctx->bstate = BS_STOP;
2978
            break;
2979
        case 1:
2980
            /* ignored, read only */
2981
            rn = "Config1";
2982
            break;
2983
        case 2:
2984
            gen_op_mtc0_config2();
2985
            rn = "Config2";
2986
            /* Stop translation as we may have switched the execution mode */
2987
            ctx->bstate = BS_STOP;
2988
            break;
2989
        case 3:
2990
            /* ignored, read only */
2991
            rn = "Config3";
2992
            break;
2993
        /* 4,5 are reserved */
2994
        /* 6,7 are implementation dependent */
2995
        case 6:
2996
            /* ignored */
2997
            rn = "Config6";
2998
            break;
2999
        case 7:
3000
            /* ignored */
3001
            rn = "Config7";
3002
            break;
3003
        default:
3004
            rn = "Invalid config selector";
3005
            goto die;
3006
        }
3007
        break;
3008
    case 17:
3009
        switch (sel) {
3010
        case 0:
3011
            /* ignored */
3012
            rn = "LLAddr";
3013
            break;
3014
        default:
3015
            goto die;
3016
        }
3017
        break;
3018
    case 18:
3019
        switch (sel) {
3020
        case 0 ... 7:
3021
            gen_op_mtc0_watchlo(sel);
3022
            rn = "WatchLo";
3023
            break;
3024
        default:
3025
            goto die;
3026
        }
3027
        break;
3028
    case 19:
3029
        switch (sel) {
3030
        case 0 ... 7:
3031
            gen_op_mtc0_watchhi(sel);
3032
            rn = "WatchHi";
3033
            break;
3034
        default:
3035
            goto die;
3036
        }
3037
        break;
3038
    case 20:
3039
        switch (sel) {
3040
        case 0:
3041
#if defined(TARGET_MIPS64)
3042
            check_insn(env, ctx, ISA_MIPS3);
3043
            gen_op_mtc0_xcontext();
3044
            rn = "XContext";
3045
            break;
3046
#endif
3047
        default:
3048
            goto die;
3049
        }
3050
        break;
3051
    case 21:
3052
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3053
        switch (sel) {
3054
        case 0:
3055
            gen_op_mtc0_framemask();
3056
            rn = "Framemask";
3057
            break;
3058
        default:
3059
            goto die;
3060
        }
3061
        break;
3062
    case 22:
3063
        /* ignored */
3064
        rn = "Diagnostic"; /* implementation dependent */
3065
        break;
3066
    case 23:
3067
        switch (sel) {
3068
        case 0:
3069
            gen_op_mtc0_debug(); /* EJTAG support */
3070
            /* BS_STOP isn't good enough here, hflags may have changed. */
3071
            gen_save_pc(ctx->pc + 4);
3072
            ctx->bstate = BS_EXCP;
3073
            rn = "Debug";
3074
            break;
3075
        case 1:
3076
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3077
            rn = "TraceControl";
3078
            /* Stop translation as we may have switched the execution mode */
3079
            ctx->bstate = BS_STOP;
3080
//            break;
3081
        case 2:
3082
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3083
            rn = "TraceControl2";
3084
            /* Stop translation as we may have switched the execution mode */
3085
            ctx->bstate = BS_STOP;
3086
//            break;
3087
        case 3:
3088
            /* Stop translation as we may have switched the execution mode */
3089
            ctx->bstate = BS_STOP;
3090
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3091
            rn = "UserTraceData";
3092
            /* Stop translation as we may have switched the execution mode */
3093
            ctx->bstate = BS_STOP;
3094
//            break;
3095
        case 4:
3096
//            gen_op_mtc0_debug(); /* PDtrace support */
3097
            /* Stop translation as we may have switched the execution mode */
3098
            ctx->bstate = BS_STOP;
3099
            rn = "TraceBPC";
3100
//            break;
3101
        default:
3102
            goto die;
3103
        }
3104
        break;
3105
    case 24:
3106
        switch (sel) {
3107
        case 0:
3108
            gen_op_mtc0_depc(); /* EJTAG support */
3109
            rn = "DEPC";
3110
            break;
3111
        default:
3112
            goto die;
3113
        }
3114
        break;
3115
    case 25:
3116
        switch (sel) {
3117
        case 0:
3118
            gen_op_mtc0_performance0();
3119
            rn = "Performance0";
3120
            break;
3121
        case 1:
3122
//            gen_op_mtc0_performance1();
3123
            rn = "Performance1";
3124
//            break;
3125
        case 2:
3126
//            gen_op_mtc0_performance2();
3127
            rn = "Performance2";
3128
//            break;
3129
        case 3:
3130
//            gen_op_mtc0_performance3();
3131
            rn = "Performance3";
3132
//            break;
3133
        case 4:
3134
//            gen_op_mtc0_performance4();
3135
            rn = "Performance4";
3136
//            break;
3137
        case 5:
3138
//            gen_op_mtc0_performance5();
3139
            rn = "Performance5";
3140
//            break;
3141
        case 6:
3142
//            gen_op_mtc0_performance6();
3143
            rn = "Performance6";
3144
//            break;
3145
        case 7:
3146
//            gen_op_mtc0_performance7();
3147
            rn = "Performance7";
3148
//            break;
3149
        default:
3150
            goto die;
3151
        }
3152
       break;
3153
    case 26:
3154
        /* ignored */
3155
        rn = "ECC";
3156
        break;
3157
    case 27:
3158
        switch (sel) {
3159
        case 0 ... 3:
3160
            /* ignored */
3161
            rn = "CacheErr";
3162
            break;
3163
        default:
3164
            goto die;
3165
        }
3166
       break;
3167
    case 28:
3168
        switch (sel) {
3169
        case 0:
3170
        case 2:
3171
        case 4:
3172
        case 6:
3173
            gen_op_mtc0_taglo();
3174
            rn = "TagLo";
3175
            break;
3176
        case 1:
3177
        case 3:
3178
        case 5:
3179
        case 7:
3180
            gen_op_mtc0_datalo();
3181
            rn = "DataLo";
3182
            break;
3183
        default:
3184
            goto die;
3185
        }
3186
        break;
3187
    case 29:
3188
        switch (sel) {
3189
        case 0:
3190
        case 2:
3191
        case 4:
3192
        case 6:
3193
            gen_op_mtc0_taghi();
3194
            rn = "TagHi";
3195
            break;
3196
        case 1:
3197
        case 3:
3198
        case 5:
3199
        case 7:
3200
            gen_op_mtc0_datahi();
3201
            rn = "DataHi";
3202
            break;
3203
        default:
3204
            rn = "invalid sel";
3205
            goto die;
3206
        }
3207
       break;
3208
    case 30:
3209
        switch (sel) {
3210
        case 0:
3211
            gen_op_mtc0_errorepc();
3212
            rn = "ErrorEPC";
3213
            break;
3214
        default:
3215
            goto die;
3216
        }
3217
        break;
3218
    case 31:
3219
        switch (sel) {
3220
        case 0:
3221
            gen_op_mtc0_desave(); /* EJTAG support */
3222
            rn = "DESAVE";
3223
            break;
3224
        default:
3225
            goto die;
3226
        }
3227
        /* Stop translation as we may have switched the execution mode */
3228
        ctx->bstate = BS_STOP;
3229
        break;
3230
    default:
3231
       goto die;
3232
    }
3233
#if defined MIPS_DEBUG_DISAS
3234
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3235
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3236
                rn, reg, sel);
3237
    }
3238
#endif
3239
    return;
3240

    
3241
die:
3242
#if defined MIPS_DEBUG_DISAS
3243
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3244
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3245
                rn, reg, sel);
3246
    }
3247
#endif
3248
    generate_exception(ctx, EXCP_RI);
3249
}
3250

    
3251
#if defined(TARGET_MIPS64)
3252
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3253
{
3254
    const char *rn = "invalid";
3255

    
3256
    if (sel != 0)
3257
        check_insn(env, ctx, ISA_MIPS64);
3258

    
3259
    switch (reg) {
3260
    case 0:
3261
        switch (sel) {
3262
        case 0:
3263
            gen_op_mfc0_index();
3264
            rn = "Index";
3265
            break;
3266
        case 1:
3267
            check_insn(env, ctx, ASE_MT);
3268
            gen_op_mfc0_mvpcontrol();
3269
            rn = "MVPControl";
3270
            break;
3271
        case 2:
3272
            check_insn(env, ctx, ASE_MT);
3273
            gen_op_mfc0_mvpconf0();
3274
            rn = "MVPConf0";
3275
            break;
3276
        case 3:
3277
            check_insn(env, ctx, ASE_MT);
3278
            gen_op_mfc0_mvpconf1();
3279
            rn = "MVPConf1";
3280
            break;
3281
        default:
3282
            goto die;
3283
        }
3284
        break;
3285
    case 1:
3286
        switch (sel) {
3287
        case 0:
3288
            gen_op_mfc0_random();
3289
            rn = "Random";
3290
            break;
3291
        case 1:
3292
            check_insn(env, ctx, ASE_MT);
3293
            gen_op_mfc0_vpecontrol();
3294
            rn = "VPEControl";
3295
            break;
3296
        case 2:
3297
            check_insn(env, ctx, ASE_MT);
3298
            gen_op_mfc0_vpeconf0();
3299
            rn = "VPEConf0";
3300
            break;
3301
        case 3:
3302
            check_insn(env, ctx, ASE_MT);
3303
            gen_op_mfc0_vpeconf1();
3304
            rn = "VPEConf1";
3305
            break;
3306
        case 4:
3307
            check_insn(env, ctx, ASE_MT);
3308
            gen_op_dmfc0_yqmask();
3309
            rn = "YQMask";
3310
            break;
3311
        case 5:
3312
            check_insn(env, ctx, ASE_MT);
3313
            gen_op_dmfc0_vpeschedule();
3314
            rn = "VPESchedule";
3315
            break;
3316
        case 6:
3317
            check_insn(env, ctx, ASE_MT);
3318
            gen_op_dmfc0_vpeschefback();
3319
            rn = "VPEScheFBack";
3320
            break;
3321
        case 7:
3322
            check_insn(env, ctx, ASE_MT);
3323
            gen_op_mfc0_vpeopt();
3324
            rn = "VPEOpt";
3325
            break;
3326
        default:
3327
            goto die;
3328
        }
3329
        break;
3330
    case 2:
3331
        switch (sel) {
3332
        case 0:
3333
            gen_op_dmfc0_entrylo0();
3334
            rn = "EntryLo0";
3335
            break;
3336
        case 1:
3337
            check_insn(env, ctx, ASE_MT);
3338
            gen_op_mfc0_tcstatus();
3339
            rn = "TCStatus";
3340
            break;
3341
        case 2:
3342
            check_insn(env, ctx, ASE_MT);
3343
            gen_op_mfc0_tcbind();
3344
            rn = "TCBind";
3345
            break;
3346
        case 3:
3347
            check_insn(env, ctx, ASE_MT);
3348
            gen_op_dmfc0_tcrestart();
3349
            rn = "TCRestart";
3350
            break;
3351
        case 4:
3352
            check_insn(env, ctx, ASE_MT);
3353
            gen_op_dmfc0_tchalt();
3354
            rn = "TCHalt";
3355
            break;
3356
        case 5:
3357
            check_insn(env, ctx, ASE_MT);
3358
            gen_op_dmfc0_tccontext();
3359
            rn = "TCContext";
3360
            break;
3361
        case 6:
3362
            check_insn(env, ctx, ASE_MT);
3363
            gen_op_dmfc0_tcschedule();
3364
            rn = "TCSchedule";
3365
            break;
3366
        case 7:
3367
            check_insn(env, ctx, ASE_MT);
3368
            gen_op_dmfc0_tcschefback();
3369
            rn = "TCScheFBack";
3370
            break;
3371
        default:
3372
            goto die;
3373
        }
3374
        break;
3375
    case 3:
3376
        switch (sel) {
3377
        case 0:
3378
            gen_op_dmfc0_entrylo1();
3379
            rn = "EntryLo1";
3380
            break;
3381
        default:
3382
            goto die;
3383
        }
3384
        break;
3385
    case 4:
3386
        switch (sel) {
3387
        case 0:
3388
            gen_op_dmfc0_context();
3389
            rn = "Context";
3390
            break;
3391
        case 1:
3392
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3393
            rn = "ContextConfig";
3394
//            break;
3395
        default:
3396
            goto die;
3397
        }
3398
        break;
3399
    case 5:
3400
        switch (sel) {
3401
        case 0:
3402
            gen_op_mfc0_pagemask();
3403
            rn = "PageMask";
3404
            break;
3405
        case 1:
3406
            check_insn(env, ctx, ISA_MIPS32R2);
3407
            gen_op_mfc0_pagegrain();
3408
            rn = "PageGrain";
3409
            break;
3410
        default:
3411
            goto die;
3412
        }
3413
        break;
3414
    case 6:
3415
        switch (sel) {
3416
        case 0:
3417
            gen_op_mfc0_wired();
3418
            rn = "Wired";
3419
            break;
3420
        case 1:
3421
            check_insn(env, ctx, ISA_MIPS32R2);
3422
            gen_op_mfc0_srsconf0();
3423
            rn = "SRSConf0";
3424
            break;
3425
        case 2:
3426
            check_insn(env, ctx, ISA_MIPS32R2);
3427
            gen_op_mfc0_srsconf1();
3428
            rn = "SRSConf1";
3429
            break;
3430
        case 3:
3431
            check_insn(env, ctx, ISA_MIPS32R2);
3432
            gen_op_mfc0_srsconf2();
3433
            rn = "SRSConf2";
3434
            break;
3435
        case 4:
3436
            check_insn(env, ctx, ISA_MIPS32R2);
3437
            gen_op_mfc0_srsconf3();
3438
            rn = "SRSConf3";
3439
            break;
3440
        case 5:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_op_mfc0_srsconf4();
3443
            rn = "SRSConf4";
3444
            break;
3445
        default:
3446
            goto die;
3447
        }
3448
        break;
3449
    case 7:
3450
        switch (sel) {
3451
        case 0:
3452
            check_insn(env, ctx, ISA_MIPS32R2);
3453
            gen_op_mfc0_hwrena();
3454
            rn = "HWREna";
3455
            break;
3456
        default:
3457
            goto die;
3458
        }
3459
        break;
3460
    case 8:
3461
        switch (sel) {
3462
        case 0:
3463
            gen_op_dmfc0_badvaddr();
3464
            rn = "BadVaddr";
3465
            break;
3466
        default:
3467
            goto die;
3468
        }
3469
        break;
3470
    case 9:
3471
        switch (sel) {
3472
        case 0:
3473
            gen_op_mfc0_count();
3474
            rn = "Count";
3475
            break;
3476
        /* 6,7 are implementation dependent */
3477
        default:
3478
            goto die;
3479
        }
3480
        break;
3481
    case 10:
3482
        switch (sel) {
3483
        case 0:
3484
            gen_op_dmfc0_entryhi();
3485
            rn = "EntryHi";
3486
            break;
3487
        default:
3488
            goto die;
3489
        }
3490
        break;
3491
    case 11:
3492
        switch (sel) {
3493
        case 0:
3494
            gen_op_mfc0_compare();
3495
            rn = "Compare";
3496
            break;
3497
        /* 6,7 are implementation dependent */
3498
        default:
3499
            goto die;
3500
        }
3501
        break;
3502
    case 12:
3503
        switch (sel) {
3504
        case 0:
3505
            gen_op_mfc0_status();
3506
            rn = "Status";
3507
            break;
3508
        case 1:
3509
            check_insn(env, ctx, ISA_MIPS32R2);
3510
            gen_op_mfc0_intctl();
3511
            rn = "IntCtl";
3512
            break;
3513
        case 2:
3514
            check_insn(env, ctx, ISA_MIPS32R2);
3515
            gen_op_mfc0_srsctl();
3516
            rn = "SRSCtl";
3517
            break;
3518
        case 3:
3519
            check_insn(env, ctx, ISA_MIPS32R2);
3520
            gen_op_mfc0_srsmap();
3521
            rn = "SRSMap";
3522
            break;
3523
        default:
3524
            goto die;
3525
        }
3526
        break;
3527
    case 13:
3528
        switch (sel) {
3529
        case 0:
3530
            gen_op_mfc0_cause();
3531
            rn = "Cause";
3532
            break;
3533
        default:
3534
            goto die;
3535
        }
3536
        break;
3537
    case 14:
3538
        switch (sel) {
3539
        case 0:
3540
            gen_op_dmfc0_epc();
3541
            rn = "EPC";
3542
            break;
3543
        default:
3544
            goto die;
3545
        }
3546
        break;
3547
    case 15:
3548
        switch (sel) {
3549
        case 0:
3550
            gen_op_mfc0_prid();
3551
            rn = "PRid";
3552
            break;
3553
        case 1:
3554
            check_insn(env, ctx, ISA_MIPS32R2);
3555
            gen_op_mfc0_ebase();
3556
            rn = "EBase";
3557
            break;
3558
        default:
3559
            goto die;
3560
        }
3561
        break;
3562
    case 16:
3563
        switch (sel) {
3564
        case 0:
3565
            gen_op_mfc0_config0();
3566
            rn = "Config";
3567
            break;
3568
        case 1:
3569
            gen_op_mfc0_config1();
3570
            rn = "Config1";
3571
            break;
3572
        case 2:
3573
            gen_op_mfc0_config2();
3574
            rn = "Config2";
3575
            break;
3576
        case 3:
3577
            gen_op_mfc0_config3();
3578
            rn = "Config3";
3579
            break;
3580
       /* 6,7 are implementation dependent */
3581
        default:
3582
            goto die;
3583
        }
3584
        break;
3585
    case 17:
3586
        switch (sel) {
3587
        case 0:
3588
            gen_op_dmfc0_lladdr();
3589
            rn = "LLAddr";
3590
            break;
3591
        default:
3592
            goto die;
3593
        }
3594
        break;
3595
    case 18:
3596
        switch (sel) {
3597
        case 0 ... 7:
3598
            gen_op_dmfc0_watchlo(sel);
3599
            rn = "WatchLo";
3600
            break;
3601
        default:
3602
            goto die;
3603
        }
3604
        break;
3605
    case 19:
3606
        switch (sel) {
3607
        case 0 ... 7:
3608
            gen_op_mfc0_watchhi(sel);
3609
            rn = "WatchHi";
3610
            break;
3611
        default:
3612
            goto die;
3613
        }
3614
        break;
3615
    case 20:
3616
        switch (sel) {
3617
        case 0:
3618
            check_insn(env, ctx, ISA_MIPS3);
3619
            gen_op_dmfc0_xcontext();
3620
            rn = "XContext";
3621
            break;
3622
        default:
3623
            goto die;
3624
        }
3625
        break;
3626
    case 21:
3627
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3628
        switch (sel) {
3629
        case 0:
3630
            gen_op_mfc0_framemask();
3631
            rn = "Framemask";
3632
            break;
3633
        default:
3634
            goto die;
3635
        }
3636
        break;
3637
    case 22:
3638
        /* ignored */
3639
        rn = "'Diagnostic"; /* implementation dependent */
3640
        break;
3641
    case 23:
3642
        switch (sel) {
3643
        case 0:
3644
            gen_op_mfc0_debug(); /* EJTAG support */
3645
            rn = "Debug";
3646
            break;
3647
        case 1:
3648
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3649
            rn = "TraceControl";
3650
//            break;
3651
        case 2:
3652
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3653
            rn = "TraceControl2";
3654
//            break;
3655
        case 3:
3656
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3657
            rn = "UserTraceData";
3658
//            break;
3659
        case 4:
3660
//            gen_op_dmfc0_debug(); /* PDtrace support */
3661
            rn = "TraceBPC";
3662
//            break;
3663
        default:
3664
            goto die;
3665
        }
3666
        break;
3667
    case 24:
3668
        switch (sel) {
3669
        case 0:
3670
            gen_op_dmfc0_depc(); /* EJTAG support */
3671
            rn = "DEPC";
3672
            break;
3673
        default:
3674
            goto die;
3675
        }
3676
        break;
3677
    case 25:
3678
        switch (sel) {
3679
        case 0:
3680
            gen_op_mfc0_performance0();
3681
            rn = "Performance0";
3682
            break;
3683
        case 1:
3684
//            gen_op_dmfc0_performance1();
3685
            rn = "Performance1";
3686
//            break;
3687
        case 2:
3688
//            gen_op_dmfc0_performance2();
3689
            rn = "Performance2";
3690
//            break;
3691
        case 3:
3692
//            gen_op_dmfc0_performance3();
3693
            rn = "Performance3";
3694
//            break;
3695
        case 4:
3696
//            gen_op_dmfc0_performance4();
3697
            rn = "Performance4";
3698
//            break;
3699
        case 5:
3700
//            gen_op_dmfc0_performance5();
3701
            rn = "Performance5";
3702
//            break;
3703
        case 6:
3704
//            gen_op_dmfc0_performance6();
3705
            rn = "Performance6";
3706
//            break;
3707
        case 7:
3708
//            gen_op_dmfc0_performance7();
3709
            rn = "Performance7";
3710
//            break;
3711
        default:
3712
            goto die;
3713
        }
3714
        break;
3715
    case 26:
3716
       rn = "ECC";
3717
       break;
3718
    case 27:
3719
        switch (sel) {
3720
        /* ignored */
3721
        case 0 ... 3:
3722
            rn = "CacheErr";
3723
            break;
3724
        default:
3725
            goto die;
3726
        }
3727
        break;
3728
    case 28:
3729
        switch (sel) {
3730
        case 0:
3731
        case 2:
3732
        case 4:
3733
        case 6:
3734
            gen_op_mfc0_taglo();
3735
            rn = "TagLo";
3736
            break;
3737
        case 1:
3738
        case 3:
3739
        case 5:
3740
        case 7:
3741
            gen_op_mfc0_datalo();
3742
            rn = "DataLo";
3743
            break;
3744
        default:
3745
            goto die;
3746
        }
3747
        break;
3748
    case 29:
3749
        switch (sel) {
3750
        case 0:
3751
        case 2:
3752
        case 4:
3753
        case 6:
3754
            gen_op_mfc0_taghi();
3755
            rn = "TagHi";
3756
            break;
3757
        case 1:
3758
        case 3:
3759
        case 5:
3760
        case 7:
3761
            gen_op_mfc0_datahi();
3762
            rn = "DataHi";
3763
            break;
3764
        default:
3765
            goto die;
3766
        }
3767
        break;
3768
    case 30:
3769
        switch (sel) {
3770
        case 0:
3771
            gen_op_dmfc0_errorepc();
3772
            rn = "ErrorEPC";
3773
            break;
3774
        default:
3775
            goto die;
3776
        }
3777
        break;
3778
    case 31:
3779
        switch (sel) {
3780
        case 0:
3781
            gen_op_mfc0_desave(); /* EJTAG support */
3782
            rn = "DESAVE";
3783
            break;
3784
        default:
3785
            goto die;
3786
        }
3787
        break;
3788
    default:
3789
        goto die;
3790
    }
3791
#if defined MIPS_DEBUG_DISAS
3792
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3793
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3794
                rn, reg, sel);
3795
    }
3796
#endif
3797
    return;
3798

    
3799
die:
3800
#if defined MIPS_DEBUG_DISAS
3801
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3802
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3803
                rn, reg, sel);
3804
    }
3805
#endif
3806
    generate_exception(ctx, EXCP_RI);
3807
}
3808

    
3809
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3810
{
3811
    const char *rn = "invalid";
3812

    
3813
    if (sel != 0)
3814
        check_insn(env, ctx, ISA_MIPS64);
3815

    
3816
    switch (reg) {
3817
    case 0:
3818
        switch (sel) {
3819
        case 0:
3820
            gen_op_mtc0_index();
3821
            rn = "Index";
3822
            break;
3823
        case 1:
3824
            check_insn(env, ctx, ASE_MT);
3825
            gen_op_mtc0_mvpcontrol();
3826
            rn = "MVPControl";
3827
            break;
3828
        case 2:
3829
            check_insn(env, ctx, ASE_MT);
3830
            /* ignored */
3831
            rn = "MVPConf0";
3832
            break;
3833
        case 3:
3834
            check_insn(env, ctx, ASE_MT);
3835
            /* ignored */
3836
            rn = "MVPConf1";
3837
            break;
3838
        default:
3839
            goto die;
3840
        }
3841
        break;
3842
    case 1:
3843
        switch (sel) {
3844
        case 0:
3845
            /* ignored */
3846
            rn = "Random";
3847
            break;
3848
        case 1:
3849
            check_insn(env, ctx, ASE_MT);
3850
            gen_op_mtc0_vpecontrol();
3851
            rn = "VPEControl";
3852
            break;
3853
        case 2:
3854
            check_insn(env, ctx, ASE_MT);
3855
            gen_op_mtc0_vpeconf0();
3856
            rn = "VPEConf0";
3857
            break;
3858
        case 3:
3859
            check_insn(env, ctx, ASE_MT);
3860
            gen_op_mtc0_vpeconf1();
3861
            rn = "VPEConf1";
3862
            break;
3863
        case 4:
3864
            check_insn(env, ctx, ASE_MT);
3865
            gen_op_mtc0_yqmask();
3866
            rn = "YQMask";
3867
            break;
3868
        case 5:
3869
            check_insn(env, ctx, ASE_MT);
3870
            gen_op_mtc0_vpeschedule();
3871
            rn = "VPESchedule";
3872
            break;
3873
        case 6:
3874
            check_insn(env, ctx, ASE_MT);
3875
            gen_op_mtc0_vpeschefback();
3876
            rn = "VPEScheFBack";
3877
            break;
3878
        case 7:
3879
            check_insn(env, ctx, ASE_MT);
3880
            gen_op_mtc0_vpeopt();
3881
            rn = "VPEOpt";
3882
            break;
3883
        default:
3884
            goto die;
3885
        }
3886
        break;
3887
    case 2:
3888
        switch (sel) {
3889
        case 0:
3890
            gen_op_mtc0_entrylo0();
3891
            rn = "EntryLo0";
3892
            break;
3893
        case 1:
3894
            check_insn(env, ctx, ASE_MT);
3895
            gen_op_mtc0_tcstatus();
3896
            rn = "TCStatus";
3897
            break;
3898
        case 2:
3899
            check_insn(env, ctx, ASE_MT);
3900
            gen_op_mtc0_tcbind();
3901
            rn = "TCBind";
3902
            break;
3903
        case 3:
3904
            check_insn(env, ctx, ASE_MT);
3905
            gen_op_mtc0_tcrestart();
3906
            rn = "TCRestart";
3907
            break;
3908
        case 4:
3909
            check_insn(env, ctx, ASE_MT);
3910
            gen_op_mtc0_tchalt();
3911
            rn = "TCHalt";
3912
            break;
3913
        case 5:
3914
            check_insn(env, ctx, ASE_MT);
3915
            gen_op_mtc0_tccontext();
3916
            rn = "TCContext";
3917
            break;
3918
        case 6:
3919
            check_insn(env, ctx, ASE_MT);
3920
            gen_op_mtc0_tcschedule();
3921
            rn = "TCSchedule";
3922
            break;
3923
        case 7:
3924
            check_insn(env, ctx, ASE_MT);
3925
            gen_op_mtc0_tcschefback();
3926
            rn = "TCScheFBack";
3927
            break;
3928
        default:
3929
            goto die;
3930
        }
3931
        break;
3932
    case 3:
3933
        switch (sel) {
3934
        case 0:
3935
            gen_op_mtc0_entrylo1();
3936
            rn = "EntryLo1";
3937
            break;
3938
        default:
3939
            goto die;
3940
        }
3941
        break;
3942
    case 4:
3943
        switch (sel) {
3944
        case 0:
3945
            gen_op_mtc0_context();
3946
            rn = "Context";
3947
            break;
3948
        case 1:
3949
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3950
            rn = "ContextConfig";
3951
//           break;
3952
        default:
3953
            goto die;
3954
        }
3955
        break;
3956
    case 5:
3957
        switch (sel) {
3958
        case 0:
3959
            gen_op_mtc0_pagemask();
3960
            rn = "PageMask";
3961
            break;
3962
        case 1:
3963
            check_insn(env, ctx, ISA_MIPS32R2);
3964
            gen_op_mtc0_pagegrain();
3965
            rn = "PageGrain";
3966
            break;
3967
        default:
3968
            goto die;
3969
        }
3970
        break;
3971
    case 6:
3972
        switch (sel) {
3973
        case 0:
3974
            gen_op_mtc0_wired();
3975
            rn = "Wired";
3976
            break;
3977
        case 1:
3978
            check_insn(env, ctx, ISA_MIPS32R2);
3979
            gen_op_mtc0_srsconf0();
3980
            rn = "SRSConf0";
3981
            break;
3982
        case 2:
3983
            check_insn(env, ctx, ISA_MIPS32R2);
3984
            gen_op_mtc0_srsconf1();
3985
            rn = "SRSConf1";
3986
            break;
3987
        case 3:
3988
            check_insn(env, ctx, ISA_MIPS32R2);
3989
            gen_op_mtc0_srsconf2();
3990
            rn = "SRSConf2";
3991
            break;
3992
        case 4:
3993
            check_insn(env, ctx, ISA_MIPS32R2);
3994
            gen_op_mtc0_srsconf3();
3995
            rn = "SRSConf3";
3996
            break;
3997
        case 5:
3998
            check_insn(env, ctx, ISA_MIPS32R2);
3999
            gen_op_mtc0_srsconf4();
4000
            rn = "SRSConf4";
4001
            break;
4002
        default:
4003
            goto die;
4004
        }
4005
        break;
4006
    case 7:
4007
        switch (sel) {
4008
        case 0:
4009
            check_insn(env, ctx, ISA_MIPS32R2);
4010
            gen_op_mtc0_hwrena();
4011
            rn = "HWREna";
4012
            break;
4013
        default:
4014
            goto die;
4015
        }
4016
        break;
4017
    case 8:
4018
        /* ignored */
4019
        rn = "BadVaddr";
4020
        break;
4021
    case 9:
4022
        switch (sel) {
4023
        case 0:
4024
            gen_op_mtc0_count();
4025
            rn = "Count";
4026
            break;
4027
        /* 6,7 are implementation dependent */
4028
        default:
4029
            goto die;
4030
        }
4031
        /* Stop translation as we may have switched the execution mode */
4032
        ctx->bstate = BS_STOP;
4033
        break;
4034
    case 10:
4035
        switch (sel) {
4036
        case 0:
4037
            gen_op_mtc0_entryhi();
4038
            rn = "EntryHi";
4039
            break;
4040
        default:
4041
            goto die;
4042
        }
4043
        break;
4044
    case 11:
4045
        switch (sel) {
4046
        case 0:
4047
            gen_op_mtc0_compare();
4048
            rn = "Compare";
4049
            break;
4050
        /* 6,7 are implementation dependent */
4051
        default:
4052
            goto die;
4053
        }
4054
        /* Stop translation as we may have switched the execution mode */
4055
        ctx->bstate = BS_STOP;
4056
        break;
4057
    case 12:
4058
        switch (sel) {
4059
        case 0:
4060
            gen_op_mtc0_status();
4061
            /* BS_STOP isn't good enough here, hflags may have changed. */
4062
            gen_save_pc(ctx->pc + 4);
4063
            ctx->bstate = BS_EXCP;
4064
            rn = "Status";
4065
            break;
4066
        case 1:
4067
            check_insn(env, ctx, ISA_MIPS32R2);
4068
            gen_op_mtc0_intctl();
4069
            /* Stop translation as we may have switched the execution mode */
4070
            ctx->bstate = BS_STOP;
4071
            rn = "IntCtl";
4072
            break;
4073
        case 2:
4074
            check_insn(env, ctx, ISA_MIPS32R2);
4075
            gen_op_mtc0_srsctl();
4076
            /* Stop translation as we may have switched the execution mode */
4077
            ctx->bstate = BS_STOP;
4078
            rn = "SRSCtl";
4079
            break;
4080
        case 3:
4081
            check_insn(env, ctx, ISA_MIPS32R2);
4082
            gen_op_mtc0_srsmap();
4083
            /* Stop translation as we may have switched the execution mode */
4084
            ctx->bstate = BS_STOP;
4085
            rn = "SRSMap";
4086
            break;
4087
        default:
4088
            goto die;
4089
        }
4090
        break;
4091
    case 13:
4092
        switch (sel) {
4093
        case 0:
4094
            gen_op_mtc0_cause();
4095
            rn = "Cause";
4096
            break;
4097
        default:
4098
            goto die;
4099
        }
4100
        /* Stop translation as we may have switched the execution mode */
4101
        ctx->bstate = BS_STOP;
4102
        break;
4103
    case 14:
4104
        switch (sel) {
4105
        case 0:
4106
            gen_op_mtc0_epc();
4107
            rn = "EPC";
4108
            break;
4109
        default:
4110
            goto die;
4111
        }
4112
        break;
4113
    case 15:
4114
        switch (sel) {
4115
        case 0:
4116
            /* ignored */
4117
            rn = "PRid";
4118
            break;
4119
        case 1:
4120
            check_insn(env, ctx, ISA_MIPS32R2);
4121
            gen_op_mtc0_ebase();
4122
            rn = "EBase";
4123
            break;
4124
        default:
4125
            goto die;
4126
        }
4127
        break;
4128
    case 16:
4129
        switch (sel) {
4130
        case 0:
4131
            gen_op_mtc0_config0();
4132
            rn = "Config";
4133
            /* Stop translation as we may have switched the execution mode */
4134
            ctx->bstate = BS_STOP;
4135
            break;
4136
        case 1:
4137
            /* ignored */
4138
            rn = "Config1";
4139
            break;
4140
        case 2:
4141
            gen_op_mtc0_config2();
4142
            rn = "Config2";
4143
            /* Stop translation as we may have switched the execution mode */
4144
            ctx->bstate = BS_STOP;
4145
            break;
4146
        case 3:
4147
            /* ignored */
4148
            rn = "Config3";
4149
            break;
4150
        /* 6,7 are implementation dependent */
4151
        default:
4152
            rn = "Invalid config selector";
4153
            goto die;
4154
        }
4155
        break;
4156
    case 17:
4157
        switch (sel) {
4158
        case 0:
4159
            /* ignored */
4160
            rn = "LLAddr";
4161
            break;
4162
        default:
4163
            goto die;
4164
        }
4165
        break;
4166
    case 18:
4167
        switch (sel) {
4168
        case 0 ... 7:
4169
            gen_op_mtc0_watchlo(sel);
4170
            rn = "WatchLo";
4171
            break;
4172
        default:
4173
            goto die;
4174
        }
4175
        break;
4176
    case 19:
4177
        switch (sel) {
4178
        case 0 ... 7:
4179
            gen_op_mtc0_watchhi(sel);
4180
            rn = "WatchHi";
4181
            break;
4182
        default:
4183
            goto die;
4184
        }
4185
        break;
4186
    case 20:
4187
        switch (sel) {
4188
        case 0:
4189
            check_insn(env, ctx, ISA_MIPS3);
4190
            gen_op_mtc0_xcontext();
4191
            rn = "XContext";
4192
            break;
4193
        default:
4194
            goto die;
4195
        }
4196
        break;
4197
    case 21:
4198
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4199
        switch (sel) {
4200
        case 0:
4201
            gen_op_mtc0_framemask();
4202
            rn = "Framemask";
4203
            break;
4204
        default:
4205
            goto die;
4206
        }
4207
        break;
4208
    case 22:
4209
        /* ignored */
4210
        rn = "Diagnostic"; /* implementation dependent */
4211
        break;
4212
    case 23:
4213
        switch (sel) {
4214
        case 0:
4215
            gen_op_mtc0_debug(); /* EJTAG support */
4216
            /* BS_STOP isn't good enough here, hflags may have changed. */
4217
            gen_save_pc(ctx->pc + 4);
4218
            ctx->bstate = BS_EXCP;
4219
            rn = "Debug";
4220
            break;
4221
        case 1:
4222
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4223
            /* Stop translation as we may have switched the execution mode */
4224
            ctx->bstate = BS_STOP;
4225
            rn = "TraceControl";
4226
//            break;
4227
        case 2:
4228
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4229
            /* Stop translation as we may have switched the execution mode */
4230
            ctx->bstate = BS_STOP;
4231
            rn = "TraceControl2";
4232
//            break;
4233
        case 3:
4234
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4235
            /* Stop translation as we may have switched the execution mode */
4236
            ctx->bstate = BS_STOP;
4237
            rn = "UserTraceData";
4238
//            break;
4239
        case 4:
4240
//            gen_op_mtc0_debug(); /* PDtrace support */
4241
            /* Stop translation as we may have switched the execution mode */
4242
            ctx->bstate = BS_STOP;
4243
            rn = "TraceBPC";
4244
//            break;
4245
        default:
4246
            goto die;
4247
        }
4248
        break;
4249
    case 24:
4250
        switch (sel) {
4251
        case 0:
4252
            gen_op_mtc0_depc(); /* EJTAG support */
4253
            rn = "DEPC";
4254
            break;
4255
        default:
4256
            goto die;
4257
        }
4258
        break;
4259
    case 25:
4260
        switch (sel) {
4261
        case 0:
4262
            gen_op_mtc0_performance0();
4263
            rn = "Performance0";
4264
            break;
4265
        case 1:
4266
//            gen_op_mtc0_performance1();
4267
            rn = "Performance1";
4268
//            break;
4269
        case 2:
4270
//            gen_op_mtc0_performance2();
4271
            rn = "Performance2";
4272
//            break;
4273
        case 3:
4274
//            gen_op_mtc0_performance3();
4275
            rn = "Performance3";
4276
//            break;
4277
        case 4:
4278
//            gen_op_mtc0_performance4();
4279
            rn = "Performance4";
4280
//            break;
4281
        case 5:
4282
//            gen_op_mtc0_performance5();
4283
            rn = "Performance5";
4284
//            break;
4285
        case 6:
4286
//            gen_op_mtc0_performance6();
4287
            rn = "Performance6";
4288
//            break;
4289
        case 7:
4290
//            gen_op_mtc0_performance7();
4291
            rn = "Performance7";
4292
//            break;
4293
        default:
4294
            goto die;
4295
        }
4296
        break;
4297
    case 26:
4298
        /* ignored */
4299
        rn = "ECC";
4300
        break;
4301
    case 27:
4302
        switch (sel) {
4303
        case 0 ... 3:
4304
            /* ignored */
4305
            rn = "CacheErr";
4306
            break;
4307
        default:
4308
            goto die;
4309
        }
4310
        break;
4311
    case 28:
4312
        switch (sel) {
4313
        case 0:
4314
        case 2:
4315
        case 4:
4316
        case 6:
4317
            gen_op_mtc0_taglo();
4318
            rn = "TagLo";
4319
            break;
4320
        case 1:
4321
        case 3:
4322
        case 5:
4323
        case 7:
4324
            gen_op_mtc0_datalo();
4325
            rn = "DataLo";
4326
            break;
4327
        default:
4328
            goto die;
4329
        }
4330
        break;
4331
    case 29:
4332
        switch (sel) {
4333
        case 0:
4334
        case 2:
4335
        case 4:
4336
        case 6:
4337
            gen_op_mtc0_taghi();
4338
            rn = "TagHi";
4339
            break;
4340
        case 1:
4341
        case 3:
4342
        case 5:
4343
        case 7:
4344
            gen_op_mtc0_datahi();
4345
            rn = "DataHi";
4346
            break;
4347
        default:
4348
            rn = "invalid sel";
4349
            goto die;
4350
        }
4351
        break;
4352
    case 30:
4353
        switch (sel) {
4354
        case 0:
4355
            gen_op_mtc0_errorepc();
4356
            rn = "ErrorEPC";
4357
            break;
4358
        default:
4359
            goto die;
4360
        }
4361
        break;
4362
    case 31:
4363
        switch (sel) {
4364
        case 0:
4365
            gen_op_mtc0_desave(); /* EJTAG support */
4366
            rn = "DESAVE";
4367
            break;
4368
        default:
4369
            goto die;
4370
        }
4371
        /* Stop translation as we may have switched the execution mode */
4372
        ctx->bstate = BS_STOP;
4373
        break;
4374
    default:
4375
        goto die;
4376
    }
4377
#if defined MIPS_DEBUG_DISAS
4378
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4379
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4380
                rn, reg, sel);
4381
    }
4382
#endif
4383
    return;
4384

    
4385
die:
4386
#if defined MIPS_DEBUG_DISAS
4387
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4388
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4389
                rn, reg, sel);
4390
    }
4391
#endif
4392
    generate_exception(ctx, EXCP_RI);
4393
}
4394
#endif /* TARGET_MIPS64 */
4395

    
4396
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4397
                     int u, int sel, int h)
4398
{
4399
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4400

    
4401
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4402
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4403
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4404
        gen_op_set_T0(-1);
4405
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4406
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4407
        gen_op_set_T0(-1);
4408
    else if (u == 0) {
4409
        switch (rt) {
4410
        case 2:
4411
            switch (sel) {
4412
            case 1:
4413
                gen_op_mftc0_tcstatus();
4414
                break;
4415
            case 2:
4416
                gen_op_mftc0_tcbind();
4417
                break;
4418
            case 3:
4419
                gen_op_mftc0_tcrestart();
4420
                break;
4421
            case 4:
4422
                gen_op_mftc0_tchalt();
4423
                break;
4424
            case 5:
4425
                gen_op_mftc0_tccontext();
4426
                break;
4427
            case 6:
4428
                gen_op_mftc0_tcschedule();
4429
                break;
4430
            case 7:
4431
                gen_op_mftc0_tcschefback();
4432
                break;
4433
            default:
4434
                gen_mfc0(env, ctx, rt, sel);
4435
                break;
4436
            }
4437
            break;
4438
        case 10:
4439
            switch (sel) {
4440
            case 0:
4441
                gen_op_mftc0_entryhi();
4442
                break;
4443
            default:
4444
                gen_mfc0(env, ctx, rt, sel);
4445
                break;
4446
            }
4447
        case 12:
4448
            switch (sel) {
4449
            case 0:
4450
                gen_op_mftc0_status();
4451
                break;
4452
            default:
4453
                gen_mfc0(env, ctx, rt, sel);
4454
                break;
4455
            }
4456
        case 23:
4457
            switch (sel) {
4458
            case 0:
4459
                gen_op_mftc0_debug();
4460
                break;
4461
            default:
4462
                gen_mfc0(env, ctx, rt, sel);
4463
                break;
4464
            }
4465
            break;
4466
        default:
4467
            gen_mfc0(env, ctx, rt, sel);
4468
        }
4469
    } else switch (sel) {
4470
    /* GPR registers. */
4471
    case 0:
4472
        gen_op_mftgpr(rt);
4473
        break;
4474
    /* Auxiliary CPU registers */
4475
    case 1:
4476
        switch (rt) {
4477
        case 0:
4478
            gen_op_mftlo(0);
4479
            break;
4480
        case 1:
4481
            gen_op_mfthi(0);
4482
            break;
4483
        case 2:
4484
            gen_op_mftacx(0);
4485
            break;
4486
        case 4:
4487
            gen_op_mftlo(1);
4488
            break;
4489
        case 5:
4490
            gen_op_mfthi(1);
4491
            break;
4492
        case 6:
4493
            gen_op_mftacx(1);
4494
            break;
4495
        case 8:
4496
            gen_op_mftlo(2);
4497
            break;
4498
        case 9:
4499
            gen_op_mfthi(2);
4500
            break;
4501
        case 10:
4502
            gen_op_mftacx(2);
4503
            break;
4504
        case 12:
4505
            gen_op_mftlo(3);
4506
            break;
4507
        case 13:
4508
            gen_op_mfthi(3);
4509
            break;
4510
        case 14:
4511
            gen_op_mftacx(3);
4512
            break;
4513
        case 16:
4514
            gen_op_mftdsp();
4515
            break;
4516
        default:
4517
            goto die;
4518
        }
4519
        break;
4520
    /* Floating point (COP1). */
4521
    case 2:
4522
        /* XXX: For now we support only a single FPU context. */
4523
        if (h == 0) {
4524
            GEN_LOAD_FREG_FTN(WT0, rt);
4525
            gen_op_mfc1();
4526
        } else {
4527
            GEN_LOAD_FREG_FTN(WTH0, rt);
4528
            gen_op_mfhc1();
4529
        }
4530
        break;
4531
    case 3:
4532
        /* XXX: For now we support only a single FPU context. */
4533
        gen_op_cfc1(rt);
4534
        break;
4535
    /* COP2: Not implemented. */
4536
    case 4:
4537
    case 5:
4538
        /* fall through */
4539
    default:
4540
        goto die;
4541
    }
4542
#if defined MIPS_DEBUG_DISAS
4543
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4544
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4545
                rt, u, sel, h);
4546
    }
4547
#endif
4548
    return;
4549

    
4550
die:
4551
#if defined MIPS_DEBUG_DISAS
4552
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4553
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4554
                rt, u, sel, h);
4555
    }
4556
#endif
4557
    generate_exception(ctx, EXCP_RI);
4558
}
4559

    
4560
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4561
                     int u, int sel, int h)
4562
{
4563
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4564

    
4565
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4566
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4567
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4568
        /* NOP */ ;
4569
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4570
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4571
        /* NOP */ ;
4572
    else if (u == 0) {
4573
        switch (rd) {
4574
        case 2:
4575
            switch (sel) {
4576
            case 1:
4577
                gen_op_mttc0_tcstatus();
4578
                break;
4579
            case 2:
4580
                gen_op_mttc0_tcbind();
4581
                break;
4582
            case 3:
4583
                gen_op_mttc0_tcrestart();
4584
                break;
4585
            case 4:
4586
                gen_op_mttc0_tchalt();
4587
                break;
4588
            case 5:
4589
                gen_op_mttc0_tccontext();
4590
                break;
4591
            case 6:
4592
                gen_op_mttc0_tcschedule();
4593
                break;
4594
            case 7:
4595
                gen_op_mttc0_tcschefback();
4596
                break;
4597
            default:
4598
                gen_mtc0(env, ctx, rd, sel);
4599
                break;
4600
            }
4601
            break;
4602
        case 10:
4603
            switch (sel) {
4604
            case 0:
4605
                gen_op_mttc0_entryhi();
4606
                break;
4607
            default:
4608
                gen_mtc0(env, ctx, rd, sel);
4609
                break;
4610
            }
4611
        case 12:
4612
            switch (sel) {
4613
            case 0:
4614
                gen_op_mttc0_status();
4615
                break;
4616
            default:
4617
                gen_mtc0(env, ctx, rd, sel);
4618
                break;
4619
            }
4620
        case 23:
4621
            switch (sel) {
4622
            case 0:
4623
                gen_op_mttc0_debug();
4624
                break;
4625
            default:
4626
                gen_mtc0(env, ctx, rd, sel);
4627
                break;
4628
            }
4629
            break;
4630
        default:
4631
            gen_mtc0(env, ctx, rd, sel);
4632
        }
4633
    } else switch (sel) {
4634
    /* GPR registers. */
4635
    case 0:
4636
        gen_op_mttgpr(rd);
4637
        break;
4638
    /* Auxiliary CPU registers */
4639
    case 1:
4640
        switch (rd) {
4641
        case 0:
4642
            gen_op_mttlo(0);
4643
            break;
4644
        case 1:
4645
            gen_op_mtthi(0);
4646
            break;
4647
        case 2:
4648
            gen_op_mttacx(0);
4649
            break;
4650
        case 4:
4651
            gen_op_mttlo(1);
4652
            break;
4653
        case 5:
4654
            gen_op_mtthi(1);
4655
            break;
4656
        case 6:
4657
            gen_op_mttacx(1);
4658
            break;
4659
        case 8:
4660
            gen_op_mttlo(2);
4661
            break;
4662
        case 9:
4663
            gen_op_mtthi(2);
4664
            break;
4665
        case 10:
4666
            gen_op_mttacx(2);
4667
            break;
4668
        case 12:
4669
            gen_op_mttlo(3);
4670
            break;
4671
        case 13:
4672
            gen_op_mtthi(3);
4673
            break;
4674
        case 14:
4675
            gen_op_mttacx(3);
4676
            break;
4677
        case 16:
4678
            gen_op_mttdsp();
4679
            break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    /* Floating point (COP1). */
4685
    case 2:
4686
        /* XXX: For now we support only a single FPU context. */
4687
        if (h == 0) {
4688
            gen_op_mtc1();
4689
            GEN_STORE_FTN_FREG(rd, WT0);
4690
        } else {
4691
            gen_op_mthc1();
4692
            GEN_STORE_FTN_FREG(rd, WTH0);
4693
        }
4694
        break;
4695
    case 3:
4696
        /* XXX: For now we support only a single FPU context. */
4697
        gen_op_ctc1(rd);
4698
        break;
4699
    /* COP2: Not implemented. */
4700
    case 4:
4701
    case 5:
4702
        /* fall through */
4703
    default:
4704
        goto die;
4705
    }
4706
#if defined MIPS_DEBUG_DISAS
4707
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4708
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4709
                rd, u, sel, h);
4710
    }
4711
#endif
4712
    return;
4713

    
4714
die:
4715
#if defined MIPS_DEBUG_DISAS
4716
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4717
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4718
                rd, u, sel, h);
4719
    }
4720
#endif
4721
    generate_exception(ctx, EXCP_RI);
4722
}
4723

    
4724
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4725
{
4726
    const char *opn = "ldst";
4727

    
4728
    switch (opc) {
4729
    case OPC_MFC0:
4730
        if (rt == 0) {
4731
            /* Treat as NOP. */
4732
            return;
4733
        }
4734
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4735
        gen_op_store_T0_gpr(rt);
4736
        opn = "mfc0";
4737
        break;
4738
    case OPC_MTC0:
4739
        GEN_LOAD_REG_T0(rt);
4740
        save_cpu_state(ctx, 1);
4741
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4742
        opn = "mtc0";
4743
        break;
4744
#if defined(TARGET_MIPS64)
4745
    case OPC_DMFC0:
4746
        check_insn(env, ctx, ISA_MIPS3);
4747
        if (rt == 0) {
4748
            /* Treat as NOP. */
4749
            return;
4750
        }
4751
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4752
        gen_op_store_T0_gpr(rt);
4753
        opn = "dmfc0";
4754
        break;
4755
    case OPC_DMTC0:
4756
        check_insn(env, ctx, ISA_MIPS3);
4757
        GEN_LOAD_REG_T0(rt);
4758
        save_cpu_state(ctx, 1);
4759
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4760
        opn = "dmtc0";
4761
        break;
4762
#endif
4763
    case OPC_MFTR:
4764
        check_insn(env, ctx, ASE_MT);
4765
        if (rd == 0) {
4766
            /* Treat as NOP. */
4767
            return;
4768
        }
4769
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4770
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4771
        gen_op_store_T0_gpr(rd);
4772
        opn = "mftr";
4773
        break;
4774
    case OPC_MTTR:
4775
        check_insn(env, ctx, ASE_MT);
4776
        GEN_LOAD_REG_T0(rt);
4777
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4778
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4779
        opn = "mttr";
4780
        break;
4781
    case OPC_TLBWI:
4782
        opn = "tlbwi";
4783
        if (!env->tlb->do_tlbwi)
4784
            goto die;
4785
        gen_op_tlbwi();
4786
        break;
4787
    case OPC_TLBWR:
4788
        opn = "tlbwr";
4789
        if (!env->tlb->do_tlbwr)
4790
            goto die;
4791
        gen_op_tlbwr();
4792
        break;
4793
    case OPC_TLBP:
4794
        opn = "tlbp";
4795
        if (!env->tlb->do_tlbp)
4796
            goto die;
4797
        gen_op_tlbp();
4798
        break;
4799
    case OPC_TLBR:
4800
        opn = "tlbr";
4801
        if (!env->tlb->do_tlbr)
4802
            goto die;
4803
        gen_op_tlbr();
4804
        break;
4805
    case OPC_ERET:
4806
        opn = "eret";
4807
        check_insn(env, ctx, ISA_MIPS2);
4808
        save_cpu_state(ctx, 1);
4809
        gen_op_eret();
4810
        ctx->bstate = BS_EXCP;
4811
        break;
4812
    case OPC_DERET:
4813
        opn = "deret";
4814
        check_insn(env, ctx, ISA_MIPS32);
4815
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4816
            MIPS_INVAL(opn);
4817
            generate_exception(ctx, EXCP_RI);
4818
        } else {
4819
            save_cpu_state(ctx, 1);
4820
            gen_op_deret();
4821
            ctx->bstate = BS_EXCP;
4822
        }
4823
        break;
4824
    case OPC_WAIT:
4825
        opn = "wait";
4826
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4827
        /* If we get an exception, we want to restart at next instruction */
4828
        ctx->pc += 4;
4829
        save_cpu_state(ctx, 1);
4830
        ctx->pc -= 4;
4831
        gen_op_wait();
4832
        ctx->bstate = BS_EXCP;
4833
        break;
4834
    default:
4835
 die:
4836
        MIPS_INVAL(opn);
4837
        generate_exception(ctx, EXCP_RI);
4838
        return;
4839
    }
4840
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4841
}
4842

    
4843
/* CP1 Branches (before delay slot) */
4844
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4845
                                 int32_t cc, int32_t offset)
4846
{
4847
    target_ulong btarget;
4848
    const char *opn = "cp1 cond branch";
4849

    
4850
    if (cc != 0)
4851
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4852

    
4853
    btarget = ctx->pc + 4 + offset;
4854

    
4855
    switch (op) {
4856
    case OPC_BC1F:
4857
        gen_op_bc1f(cc);
4858
        opn = "bc1f";
4859
        goto not_likely;
4860
    case OPC_BC1FL:
4861
        gen_op_bc1f(cc);
4862
        opn = "bc1fl";
4863
        goto likely;
4864
    case OPC_BC1T:
4865
        gen_op_bc1t(cc);
4866
        opn = "bc1t";
4867
        goto not_likely;
4868
    case OPC_BC1TL:
4869
        gen_op_bc1t(cc);
4870
        opn = "bc1tl";
4871
    likely:
4872
        ctx->hflags |= MIPS_HFLAG_BL;
4873
        gen_op_set_bcond();
4874
        gen_op_save_bcond();
4875
        break;
4876
    case OPC_BC1FANY2:
4877
        gen_op_bc1any2f(cc);
4878
        opn = "bc1any2f";
4879
        goto not_likely;
4880
    case OPC_BC1TANY2:
4881
        gen_op_bc1any2t(cc);
4882
        opn = "bc1any2t";
4883
        goto not_likely;
4884
    case OPC_BC1FANY4:
4885
        gen_op_bc1any4f(cc);
4886
        opn = "bc1any4f";
4887
        goto not_likely;
4888
    case OPC_BC1TANY4:
4889
        gen_op_bc1any4t(cc);
4890
        opn = "bc1any4t";
4891
    not_likely:
4892
        ctx->hflags |= MIPS_HFLAG_BC;
4893
        gen_op_set_bcond();
4894
        break;
4895
    default:
4896
        MIPS_INVAL(opn);
4897
        generate_exception (ctx, EXCP_RI);
4898
        return;
4899
    }
4900
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4901
               ctx->hflags, btarget);
4902
    ctx->btarget = btarget;
4903
}
4904

    
4905
/* Coprocessor 1 (FPU) */
4906

    
4907
#define FOP(func, fmt) (((fmt) << 21) | (func))
4908

    
4909
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4910
{
4911
    const char *opn = "cp1 move";
4912

    
4913
    switch (opc) {
4914
    case OPC_MFC1:
4915
        GEN_LOAD_FREG_FTN(WT0, fs);
4916
        gen_op_mfc1();
4917
        GEN_STORE_T0_REG(rt);
4918
        opn = "mfc1";
4919
        break;
4920
    case OPC_MTC1:
4921
        GEN_LOAD_REG_T0(rt);
4922
        gen_op_mtc1();
4923
        GEN_STORE_FTN_FREG(fs, WT0);
4924
        opn = "mtc1";
4925
        break;
4926
    case OPC_CFC1:
4927
        gen_op_cfc1(fs);
4928
        GEN_STORE_T0_REG(rt);
4929
        opn = "cfc1";
4930
        break;
4931
    case OPC_CTC1:
4932
        GEN_LOAD_REG_T0(rt);
4933
        gen_op_ctc1(fs);
4934
        opn = "ctc1";
4935
        break;
4936
    case OPC_DMFC1:
4937
        GEN_LOAD_FREG_FTN(DT0, fs);
4938
        gen_op_dmfc1();
4939
        GEN_STORE_T0_REG(rt);
4940
        opn = "dmfc1";
4941
        break;
4942
    case OPC_DMTC1:
4943
        GEN_LOAD_REG_T0(rt);
4944
        gen_op_dmtc1();
4945
        GEN_STORE_FTN_FREG(fs, DT0);
4946
        opn = "dmtc1";
4947
        break;
4948
    case OPC_MFHC1:
4949
        GEN_LOAD_FREG_FTN(WTH0, fs);
4950
        gen_op_mfhc1();
4951
        GEN_STORE_T0_REG(rt);
4952
        opn = "mfhc1";
4953
        break;
4954
    case OPC_MTHC1:
4955
        GEN_LOAD_REG_T0(rt);
4956
        gen_op_mthc1();
4957
        GEN_STORE_FTN_FREG(fs, WTH0);
4958
        opn = "mthc1";
4959
        break;
4960
    default:
4961
        MIPS_INVAL(opn);
4962
        generate_exception (ctx, EXCP_RI);
4963
        return;
4964
    }
4965
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4966
}
4967

    
4968
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4969
{
4970
    uint32_t ccbit;
4971

    
4972
    GEN_LOAD_REG_T0(rd);
4973
    GEN_LOAD_REG_T1(rs);
4974
    if (cc) {
4975
        ccbit = 1 << (24 + cc);
4976
    } else
4977
        ccbit = 1 << 23;
4978
    if (!tf)
4979
        gen_op_movf(ccbit);
4980
    else
4981
        gen_op_movt(ccbit);
4982
    GEN_STORE_T0_REG(rd);
4983
}
4984

    
4985
#define GEN_MOVCF(fmt)                                                \
4986
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4987
{                                                                     \
4988
    uint32_t ccbit;                                                   \
4989
                                                                      \
4990
    if (cc) {                                                         \
4991
        ccbit = 1 << (24 + cc);                                       \
4992
    } else                                                            \
4993
        ccbit = 1 << 23;                                              \
4994
    if (!tf)                                                          \
4995
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4996
    else                                                              \
4997
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4998
}
4999
GEN_MOVCF(d);
5000
GEN_MOVCF(s);
5001
GEN_MOVCF(ps);
5002
#undef GEN_MOVCF
5003

    
5004
static void gen_farith (DisasContext *ctx, uint32_t op1,
5005
                        int ft, int fs, int fd, int cc)
5006
{
5007
    const char *opn = "farith";
5008
    const char *condnames[] = {
5009
            "c.f",
5010
            "c.un",
5011
            "c.eq",
5012
            "c.ueq",
5013
            "c.olt",
5014
            "c.ult",
5015
            "c.ole",
5016
            "c.ule",
5017
            "c.sf",
5018
            "c.ngle",
5019
            "c.seq",
5020
            "c.ngl",
5021
            "c.lt",
5022
            "c.nge",
5023
            "c.le",
5024
            "c.ngt",
5025
    };
5026
    const char *condnames_abs[] = {
5027
            "cabs.f",
5028
            "cabs.un",
5029
            "cabs.eq",
5030
            "cabs.ueq",
5031
            "cabs.olt",
5032
            "cabs.ult",
5033
            "cabs.ole",
5034
            "cabs.ule",
5035
            "cabs.sf",
5036
            "cabs.ngle",
5037
            "cabs.seq",
5038
            "cabs.ngl",
5039
            "cabs.lt",
5040
            "cabs.nge",
5041
            "cabs.le",
5042
            "cabs.ngt",
5043
    };
5044
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5045
    uint32_t func = ctx->opcode & 0x3f;
5046

    
5047
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5048
    case FOP(0, 16):
5049
        GEN_LOAD_FREG_FTN(WT0, fs);
5050
        GEN_LOAD_FREG_FTN(WT1, ft);
5051
        gen_op_float_add_s();
5052
        GEN_STORE_FTN_FREG(fd, WT2);
5053
        opn = "add.s";
5054
        optype = BINOP;
5055
        break;
5056
    case FOP(1, 16):
5057
        GEN_LOAD_FREG_FTN(WT0, fs);
5058
        GEN_LOAD_FREG_FTN(WT1, ft);
5059
        gen_op_float_sub_s();
5060
        GEN_STORE_FTN_FREG(fd, WT2);
5061
        opn = "sub.s";
5062
        optype = BINOP;
5063
        break;
5064
    case FOP(2, 16):
5065
        GEN_LOAD_FREG_FTN(WT0, fs);
5066
        GEN_LOAD_FREG_FTN(WT1, ft);
5067
        gen_op_float_mul_s();
5068
        GEN_STORE_FTN_FREG(fd, WT2);
5069
        opn = "mul.s";
5070
        optype = BINOP;
5071
        break;
5072
    case FOP(3, 16):
5073
        GEN_LOAD_FREG_FTN(WT0, fs);
5074
        GEN_LOAD_FREG_FTN(WT1, ft);
5075
        gen_op_float_div_s();
5076
        GEN_STORE_FTN_FREG(fd, WT2);
5077
        opn = "div.s";
5078
        optype = BINOP;
5079
        break;
5080
    case FOP(4, 16):
5081
        GEN_LOAD_FREG_FTN(WT0, fs);
5082
        gen_op_float_sqrt_s();
5083
        GEN_STORE_FTN_FREG(fd, WT2);
5084
        opn = "sqrt.s";
5085
        break;
5086
    case FOP(5, 16):
5087
        GEN_LOAD_FREG_FTN(WT0, fs);
5088
        gen_op_float_abs_s();
5089
        GEN_STORE_FTN_FREG(fd, WT2);
5090
        opn = "abs.s";
5091
        break;
5092
    case FOP(6, 16):
5093
        GEN_LOAD_FREG_FTN(WT0, fs);
5094
        gen_op_float_mov_s();
5095
        GEN_STORE_FTN_FREG(fd, WT2);
5096
        opn = "mov.s";
5097
        break;
5098
    case FOP(7, 16):
5099
        GEN_LOAD_FREG_FTN(WT0, fs);
5100
        gen_op_float_chs_s();
5101
        GEN_STORE_FTN_FREG(fd, WT2);
5102
        opn = "neg.s";
5103
        break;
5104
    case FOP(8, 16):
5105
        check_cp1_64bitmode(ctx);
5106
        GEN_LOAD_FREG_FTN(WT0, fs);
5107
        gen_op_float_roundl_s();
5108
        GEN_STORE_FTN_FREG(fd, DT2);
5109
        opn = "round.l.s";
5110
        break;
5111
    case FOP(9, 16):
5112
        check_cp1_64bitmode(ctx);
5113
        GEN_LOAD_FREG_FTN(WT0, fs);
5114
        gen_op_float_truncl_s();
5115
        GEN_STORE_FTN_FREG(fd, DT2);
5116
        opn = "trunc.l.s";
5117
        break;
5118
    case FOP(10, 16):
5119
        check_cp1_64bitmode(ctx);
5120
        GEN_LOAD_FREG_FTN(WT0, fs);
5121
        gen_op_float_ceill_s();
5122
        GEN_STORE_FTN_FREG(fd, DT2);
5123
        opn = "ceil.l.s";
5124
        break;
5125
    case FOP(11, 16):
5126
        check_cp1_64bitmode(ctx);
5127
        GEN_LOAD_FREG_FTN(WT0, fs);
5128
        gen_op_float_floorl_s();
5129
        GEN_STORE_FTN_FREG(fd, DT2);
5130
        opn = "floor.l.s";
5131
        break;
5132
    case FOP(12, 16):
5133
        GEN_LOAD_FREG_FTN(WT0, fs);
5134
        gen_op_float_roundw_s();
5135
        GEN_STORE_FTN_FREG(fd, WT2);
5136
        opn = "round.w.s";
5137
        break;
5138
    case FOP(13, 16):
5139
        GEN_LOAD_FREG_FTN(WT0, fs);
5140
        gen_op_float_truncw_s();
5141
        GEN_STORE_FTN_FREG(fd, WT2);
5142
        opn = "trunc.w.s";
5143
        break;
5144
    case FOP(14, 16):
5145
        GEN_LOAD_FREG_FTN(WT0, fs);
5146
        gen_op_float_ceilw_s();
5147
        GEN_STORE_FTN_FREG(fd, WT2);
5148
        opn = "ceil.w.s";
5149
        break;
5150
    case FOP(15, 16):
5151
        GEN_LOAD_FREG_FTN(WT0, fs);
5152
        gen_op_float_floorw_s();
5153
        GEN_STORE_FTN_FREG(fd, WT2);
5154
        opn = "floor.w.s";
5155
        break;
5156
    case FOP(17, 16):
5157
        GEN_LOAD_REG_T0(ft);
5158
        GEN_LOAD_FREG_FTN(WT0, fs);
5159
        GEN_LOAD_FREG_FTN(WT2, fd);
5160
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5161
        GEN_STORE_FTN_FREG(fd, WT2);
5162
        opn = "movcf.s";
5163
        break;
5164
    case FOP(18, 16):
5165
        GEN_LOAD_REG_T0(ft);
5166
        GEN_LOAD_FREG_FTN(WT0, fs);
5167
        GEN_LOAD_FREG_FTN(WT2, fd);
5168
        gen_op_float_movz_s();
5169
        GEN_STORE_FTN_FREG(fd, WT2);
5170
        opn = "movz.s";
5171
        break;
5172
    case FOP(19, 16):
5173
        GEN_LOAD_REG_T0(ft);
5174
        GEN_LOAD_FREG_FTN(WT0, fs);
5175
        GEN_LOAD_FREG_FTN(WT2, fd);
5176
        gen_op_float_movn_s();
5177
        GEN_STORE_FTN_FREG(fd, WT2);
5178
        opn = "movn.s";
5179
        break;
5180
    case FOP(21, 16):
5181
        GEN_LOAD_FREG_FTN(WT0, fs);
5182
        gen_op_float_recip_s();
5183
        GEN_STORE_FTN_FREG(fd, WT2);
5184
        opn = "recip.s";
5185
        break;
5186
    case FOP(22, 16):
5187
        GEN_LOAD_FREG_FTN(WT0, fs);
5188
        gen_op_float_rsqrt_s();
5189
        GEN_STORE_FTN_FREG(fd, WT2);
5190
        opn = "rsqrt.s";
5191
        break;
5192
    case FOP(28, 16):
5193
        check_cp1_64bitmode(ctx);
5194
        GEN_LOAD_FREG_FTN(WT0, fs);
5195
        GEN_LOAD_FREG_FTN(WT2, fd);
5196
        gen_op_float_recip2_s();
5197
        GEN_STORE_FTN_FREG(fd, WT2);
5198
        opn = "recip2.s";
5199
        break;
5200
    case FOP(29, 16):
5201
        check_cp1_64bitmode(ctx);
5202
        GEN_LOAD_FREG_FTN(WT0, fs);
5203
        gen_op_float_recip1_s();
5204
        GEN_STORE_FTN_FREG(fd, WT2);
5205
        opn = "recip1.s";
5206
        break;
5207
    case FOP(30, 16):
5208
        check_cp1_64bitmode(ctx);
5209
        GEN_LOAD_FREG_FTN(WT0, fs);
5210
        gen_op_float_rsqrt1_s();
5211
        GEN_STORE_FTN_FREG(fd, WT2);
5212
        opn = "rsqrt1.s";
5213
        break;
5214
    case FOP(31, 16):
5215
        check_cp1_64bitmode(ctx);
5216
        GEN_LOAD_FREG_FTN(WT0, fs);
5217
        GEN_LOAD_FREG_FTN(WT2, ft);
5218
        gen_op_float_rsqrt2_s();
5219
        GEN_STORE_FTN_FREG(fd, WT2);
5220
        opn = "rsqrt2.s";
5221
        break;
5222
    case FOP(33, 16):
5223
        check_cp1_registers(ctx, fd);
5224
        GEN_LOAD_FREG_FTN(WT0, fs);
5225
        gen_op_float_cvtd_s();
5226
        GEN_STORE_FTN_FREG(fd, DT2);
5227
        opn = "cvt.d.s";
5228
        break;
5229
    case FOP(36, 16):
5230
        GEN_LOAD_FREG_FTN(WT0, fs);
5231
        gen_op_float_cvtw_s();
5232
        GEN_STORE_FTN_FREG(fd, WT2);
5233
        opn = "cvt.w.s";
5234
        break;
5235
    case FOP(37, 16):
5236
        check_cp1_64bitmode(ctx);
5237
        GEN_LOAD_FREG_FTN(WT0, fs);
5238
        gen_op_float_cvtl_s();
5239
        GEN_STORE_FTN_FREG(fd, DT2);
5240
        opn = "cvt.l.s";
5241
        break;
5242
    case FOP(38, 16):
5243
        check_cp1_64bitmode(ctx);
5244
        GEN_LOAD_FREG_FTN(WT1, fs);
5245
        GEN_LOAD_FREG_FTN(WT0, ft);
5246
        gen_op_float_cvtps_s();
5247
        GEN_STORE_FTN_FREG(fd, DT2);
5248
        opn = "cvt.ps.s";
5249
        break;
5250
    case FOP(48, 16):
5251
    case FOP(49, 16):
5252
    case FOP(50, 16):
5253
    case FOP(51, 16):
5254
    case FOP(52, 16):
5255
    case FOP(53, 16):
5256
    case FOP(54, 16):
5257
    case FOP(55, 16):
5258
    case FOP(56, 16):
5259
    case FOP(57, 16):
5260
    case FOP(58, 16):
5261
    case FOP(59, 16):
5262
    case FOP(60, 16):
5263
    case FOP(61, 16):
5264
    case FOP(62, 16):
5265
    case FOP(63, 16):
5266
        GEN_LOAD_FREG_FTN(WT0, fs);
5267
        GEN_LOAD_FREG_FTN(WT1, ft);
5268
        if (ctx->opcode & (1 << 6)) {
5269
            check_cp1_64bitmode(ctx);
5270
            gen_cmpabs_s(func-48, cc);
5271
            opn = condnames_abs[func-48];
5272
        } else {
5273
            gen_cmp_s(func-48, cc);
5274
            opn = condnames[func-48];
5275
        }
5276
        break;
5277
    case FOP(0, 17):
5278
        check_cp1_registers(ctx, fs | ft | fd);
5279
        GEN_LOAD_FREG_FTN(DT0, fs);
5280
        GEN_LOAD_FREG_FTN(DT1, ft);
5281
        gen_op_float_add_d();
5282
        GEN_STORE_FTN_FREG(fd, DT2);
5283
        opn = "add.d";
5284
        optype = BINOP;
5285
        break;
5286
    case FOP(1, 17):
5287
        check_cp1_registers(ctx, fs | ft | fd);
5288
        GEN_LOAD_FREG_FTN(DT0, fs);
5289
        GEN_LOAD_FREG_FTN(DT1, ft);
5290
        gen_op_float_sub_d();
5291
        GEN_STORE_FTN_FREG(fd, DT2);
5292
        opn = "sub.d";
5293
        optype = BINOP;
5294
        break;
5295
    case FOP(2, 17):
5296
        check_cp1_registers(ctx, fs | ft | fd);
5297
        GEN_LOAD_FREG_FTN(DT0, fs);
5298
        GEN_LOAD_FREG_FTN(DT1, ft);
5299
        gen_op_float_mul_d();
5300
        GEN_STORE_FTN_FREG(fd, DT2);
5301
        opn = "mul.d";
5302
        optype = BINOP;
5303
        break;
5304
    case FOP(3, 17):
5305
        check_cp1_registers(ctx, fs | ft | fd);
5306
        GEN_LOAD_FREG_FTN(DT0, fs);
5307
        GEN_LOAD_FREG_FTN(DT1, ft);
5308
        gen_op_float_div_d();
5309
        GEN_STORE_FTN_FREG(fd, DT2);
5310
        opn = "div.d";
5311
        optype = BINOP;
5312
        break;
5313
    case FOP(4, 17):
5314
        check_cp1_registers(ctx, fs | fd);
5315
        GEN_LOAD_FREG_FTN(DT0, fs);
5316
        gen_op_float_sqrt_d();
5317
        GEN_STORE_FTN_FREG(fd, DT2);
5318
        opn = "sqrt.d";
5319
        break;
5320
    case FOP(5, 17):
5321
        check_cp1_registers(ctx, fs | fd);
5322
        GEN_LOAD_FREG_FTN(DT0, fs);
5323
        gen_op_float_abs_d();
5324
        GEN_STORE_FTN_FREG(fd, DT2);
5325
        opn = "abs.d";
5326
        break;
5327
    case FOP(6, 17):
5328
        check_cp1_registers(ctx, fs | fd);
5329
        GEN_LOAD_FREG_FTN(DT0, fs);
5330
        gen_op_float_mov_d();
5331
        GEN_STORE_FTN_FREG(fd, DT2);
5332
        opn = "mov.d";
5333
        break;
5334
    case FOP(7, 17):
5335
        check_cp1_registers(ctx, fs | fd);
5336
        GEN_LOAD_FREG_FTN(DT0, fs);
5337
        gen_op_float_chs_d();
5338
        GEN_STORE_FTN_FREG(fd, DT2);
5339
        opn = "neg.d";
5340
        break;
5341
    case FOP(8, 17):
5342
        check_cp1_64bitmode(ctx);
5343
        GEN_LOAD_FREG_FTN(DT0, fs);
5344
        gen_op_float_roundl_d();
5345
        GEN_STORE_FTN_FREG(fd, DT2);
5346
        opn = "round.l.d";
5347
        break;
5348
    case FOP(9, 17):
5349
        check_cp1_64bitmode(ctx);
5350
        GEN_LOAD_FREG_FTN(DT0, fs);
5351
        gen_op_float_truncl_d();
5352
        GEN_STORE_FTN_FREG(fd, DT2);
5353
        opn = "trunc.l.d";
5354
        break;
5355
    case FOP(10, 17):
5356
        check_cp1_64bitmode(ctx);
5357
        GEN_LOAD_FREG_FTN(DT0, fs);
5358
        gen_op_float_ceill_d();
5359
        GEN_STORE_FTN_FREG(fd, DT2);
5360
        opn = "ceil.l.d";
5361
        break;
5362
    case FOP(11, 17):
5363
        check_cp1_64bitmode(ctx);
5364
        GEN_LOAD_FREG_FTN(DT0, fs);
5365
        gen_op_float_floorl_d();
5366
        GEN_STORE_FTN_FREG(fd, DT2);
5367
        opn = "floor.l.d";
5368
        break;
5369
    case FOP(12, 17):
5370
        check_cp1_registers(ctx, fs);
5371
        GEN_LOAD_FREG_FTN(DT0, fs);
5372
        gen_op_float_roundw_d();
5373
        GEN_STORE_FTN_FREG(fd, WT2);
5374
        opn = "round.w.d";
5375
        break;
5376
    case FOP(13, 17):
5377
        check_cp1_registers(ctx, fs);
5378
        GEN_LOAD_FREG_FTN(DT0, fs);
5379
        gen_op_float_truncw_d();
5380
        GEN_STORE_FTN_FREG(fd, WT2);
5381
        opn = "trunc.w.d";
5382
        break;
5383
    case FOP(14, 17):
5384
        check_cp1_registers(ctx, fs);
5385
        GEN_LOAD_FREG_FTN(DT0, fs);
5386
        gen_op_float_ceilw_d();
5387
        GEN_STORE_FTN_FREG(fd, WT2);
5388
        opn = "ceil.w.d";
5389
        break;
5390
    case FOP(15, 17):
5391
        check_cp1_registers(ctx, fs);
5392
        GEN_LOAD_FREG_FTN(DT0, fs);
5393
        gen_op_float_floorw_d();
5394
        GEN_STORE_FTN_FREG(fd, WT2);
5395
        opn = "floor.w.d";
5396
        break;
5397
    case FOP(17, 17):
5398
        GEN_LOAD_REG_T0(ft);
5399
        GEN_LOAD_FREG_FTN(DT0, fs);
5400
        GEN_LOAD_FREG_FTN(DT2, fd);
5401
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5402
        GEN_STORE_FTN_FREG(fd, DT2);
5403
        opn = "movcf.d";
5404
        break;
5405
    case FOP(18, 17):
5406
        GEN_LOAD_REG_T0(ft);
5407
        GEN_LOAD_FREG_FTN(DT0, fs);
5408
        GEN_LOAD_FREG_FTN(DT2, fd);
5409
        gen_op_float_movz_d();
5410
        GEN_STORE_FTN_FREG(fd, DT2);
5411
        opn = "movz.d";
5412
        break;
5413
    case FOP(19, 17):
5414
        GEN_LOAD_REG_T0(ft);
5415
        GEN_LOAD_FREG_FTN(DT0, fs);
5416
        GEN_LOAD_FREG_FTN(DT2, fd);
5417
        gen_op_float_movn_d();
5418
        GEN_STORE_FTN_FREG(fd, DT2);
5419
        opn = "movn.d";
5420
        break;
5421
    case FOP(21, 17):
5422
        check_cp1_registers(ctx, fs | fd);
5423
        GEN_LOAD_FREG_FTN(DT0, fs);
5424
        gen_op_float_recip_d();
5425
        GEN_STORE_FTN_FREG(fd, DT2);
5426
        opn = "recip.d";
5427
        break;
5428
    case FOP(22, 17):
5429
        check_cp1_registers(ctx, fs | fd);
5430
        GEN_LOAD_FREG_FTN(DT0, fs);
5431
        gen_op_float_rsqrt_d();
5432
        GEN_STORE_FTN_FREG(fd, DT2);
5433
        opn = "rsqrt.d";
5434
        break;
5435
    case FOP(28, 17):
5436
        check_cp1_64bitmode(ctx);
5437
        GEN_LOAD_FREG_FTN(DT0, fs);
5438
        GEN_LOAD_FREG_FTN(DT2, ft);
5439
        gen_op_float_recip2_d();
5440
        GEN_STORE_FTN_FREG(fd, DT2);
5441
        opn = "recip2.d";
5442
        break;
5443
    case FOP(29, 17):
5444
        check_cp1_64bitmode(ctx);
5445
        GEN_LOAD_FREG_FTN(DT0, fs);
5446
        gen_op_float_recip1_d();
5447
        GEN_STORE_FTN_FREG(fd, DT2);
5448
        opn = "recip1.d";
5449
        break;
5450
    case FOP(30, 17):
5451
        check_cp1_64bitmode(ctx);
5452
        GEN_LOAD_FREG_FTN(DT0, fs);
5453
        gen_op_float_rsqrt1_d();
5454
        GEN_STORE_FTN_FREG(fd, DT2);
5455
        opn = "rsqrt1.d";
5456
        break;
5457
    case FOP(31, 17):
5458
        check_cp1_64bitmode(ctx);
5459
        GEN_LOAD_FREG_FTN(DT0, fs);
5460
        GEN_LOAD_FREG_FTN(DT2, ft);
5461
        gen_op_float_rsqrt2_d();
5462
        GEN_STORE_FTN_FREG(fd, DT2);
5463
        opn = "rsqrt2.d";
5464
        break;
5465
    case FOP(48, 17):
5466
    case FOP(49, 17):
5467
    case FOP(50, 17):
5468
    case FOP(51, 17):
5469
    case FOP(52, 17):
5470
    case FOP(53, 17):
5471
    case FOP(54, 17):
5472
    case FOP(55, 17):
5473
    case FOP(56, 17):
5474
    case FOP(57, 17):
5475
    case FOP(58, 17):
5476
    case FOP(59, 17):
5477
    case FOP(60, 17):
5478
    case FOP(61, 17):
5479
    case FOP(62, 17):
5480
    case FOP(63, 17):
5481
        GEN_LOAD_FREG_FTN(DT0, fs);
5482
        GEN_LOAD_FREG_FTN(DT1, ft);
5483
        if (ctx->opcode & (1 << 6)) {
5484
            check_cp1_64bitmode(ctx);
5485
            gen_cmpabs_d(func-48, cc);
5486
            opn = condnames_abs[func-48];
5487
        } else {
5488
            check_cp1_registers(ctx, fs | ft);
5489
            gen_cmp_d(func-48, cc);
5490
            opn = condnames[func-48];
5491
        }
5492
        break;
5493
    case FOP(32, 17):
5494
        check_cp1_registers(ctx, fs);
5495
        GEN_LOAD_FREG_FTN(DT0, fs);
5496
        gen_op_float_cvts_d();
5497
        GEN_STORE_FTN_FREG(fd, WT2);
5498
        opn = "cvt.s.d";
5499
        break;
5500
    case FOP(36, 17):
5501
        check_cp1_registers(ctx, fs);
5502
        GEN_LOAD_FREG_FTN(DT0, fs);
5503
        gen_op_float_cvtw_d();
5504
        GEN_STORE_FTN_FREG(fd, WT2);
5505
        opn = "cvt.w.d";
5506
        break;
5507
    case FOP(37, 17):
5508
        check_cp1_64bitmode(ctx);
5509
        GEN_LOAD_FREG_FTN(DT0, fs);
5510
        gen_op_float_cvtl_d();
5511
        GEN_STORE_FTN_FREG(fd, DT2);
5512
        opn = "cvt.l.d";
5513
        break;
5514
    case FOP(32, 20):
5515
        GEN_LOAD_FREG_FTN(WT0, fs);
5516
        gen_op_float_cvts_w();
5517
        GEN_STORE_FTN_FREG(fd, WT2);
5518
        opn = "cvt.s.w";
5519
        break;
5520
    case FOP(33, 20):
5521
        check_cp1_registers(ctx, fd);
5522
        GEN_LOAD_FREG_FTN(WT0, fs);
5523
        gen_op_float_cvtd_w();
5524
        GEN_STORE_FTN_FREG(fd, DT2);
5525
        opn = "cvt.d.w";
5526
        break;
5527
    case FOP(32, 21):
5528
        check_cp1_64bitmode(ctx);
5529
        GEN_LOAD_FREG_FTN(DT0, fs);
5530
        gen_op_float_cvts_l();
5531
        GEN_STORE_FTN_FREG(fd, WT2);
5532
        opn = "cvt.s.l";
5533
        break;
5534
    case FOP(33, 21):
5535
        check_cp1_64bitmode(ctx);
5536
        GEN_LOAD_FREG_FTN(DT0, fs);
5537
        gen_op_float_cvtd_l();
5538
        GEN_STORE_FTN_FREG(fd, DT2);
5539
        opn = "cvt.d.l";
5540
        break;
5541
    case FOP(38, 20):
5542
        check_cp1_64bitmode(ctx);
5543
        GEN_LOAD_FREG_FTN(WT0, fs);
5544
        GEN_LOAD_FREG_FTN(WTH0, fs);
5545
        gen_op_float_cvtps_pw();
5546
        GEN_STORE_FTN_FREG(fd, WT2);
5547
        GEN_STORE_FTN_FREG(fd, WTH2);
5548
        opn = "cvt.ps.pw";
5549
        break;
5550
    case FOP(0, 22):
5551
        check_cp1_64bitmode(ctx);
5552
        GEN_LOAD_FREG_FTN(WT0, fs);
5553
        GEN_LOAD_FREG_FTN(WTH0, fs);
5554
        GEN_LOAD_FREG_FTN(WT1, ft);
5555
        GEN_LOAD_FREG_FTN(WTH1, ft);
5556
        gen_op_float_add_ps();
5557
        GEN_STORE_FTN_FREG(fd, WT2);
5558
        GEN_STORE_FTN_FREG(fd, WTH2);
5559
        opn = "add.ps";
5560
        break;
5561
    case FOP(1, 22):
5562
        check_cp1_64bitmode(ctx);
5563
        GEN_LOAD_FREG_FTN(WT0, fs);
5564
        GEN_LOAD_FREG_FTN(WTH0, fs);
5565
        GEN_LOAD_FREG_FTN(WT1, ft);
5566
        GEN_LOAD_FREG_FTN(WTH1, ft);
5567
        gen_op_float_sub_ps();
5568
        GEN_STORE_FTN_FREG(fd, WT2);
5569
        GEN_STORE_FTN_FREG(fd, WTH2);
5570
        opn = "sub.ps";
5571
        break;
5572
    case FOP(2, 22):
5573
        check_cp1_64bitmode(ctx);
5574
        GEN_LOAD_FREG_FTN(WT0, fs);
5575
        GEN_LOAD_FREG_FTN(WTH0, fs);
5576
        GEN_LOAD_FREG_FTN(WT1, ft);
5577
        GEN_LOAD_FREG_FTN(WTH1, ft);
5578
        gen_op_float_mul_ps();
5579
        GEN_STORE_FTN_FREG(fd, WT2);
5580
        GEN_STORE_FTN_FREG(fd, WTH2);
5581
        opn = "mul.ps";
5582
        break;
5583
    case FOP(5, 22):
5584
        check_cp1_64bitmode(ctx);
5585
        GEN_LOAD_FREG_FTN(WT0, fs);
5586
        GEN_LOAD_FREG_FTN(WTH0, fs);
5587
        gen_op_float_abs_ps();
5588
        GEN_STORE_FTN_FREG(fd, WT2);
5589
        GEN_STORE_FTN_FREG(fd, WTH2);
5590
        opn = "abs.ps";
5591
        break;
5592
    case FOP(6, 22):
5593
        check_cp1_64bitmode(ctx);
5594
        GEN_LOAD_FREG_FTN(WT0, fs);
5595
        GEN_LOAD_FREG_FTN(WTH0, fs);
5596
        gen_op_float_mov_ps();
5597
        GEN_STORE_FTN_FREG(fd, WT2);
5598
        GEN_STORE_FTN_FREG(fd, WTH2);
5599
        opn = "mov.ps";
5600
        break;
5601
    case FOP(7, 22):
5602
        check_cp1_64bitmode(ctx);
5603
        GEN_LOAD_FREG_FTN(WT0, fs);
5604
        GEN_LOAD_FREG_FTN(WTH0, fs);
5605
        gen_op_float_chs_ps();
5606
        GEN_STORE_FTN_FREG(fd, WT2);
5607
        GEN_STORE_FTN_FREG(fd, WTH2);
5608
        opn = "neg.ps";
5609
        break;
5610
    case FOP(17, 22):
5611
        check_cp1_64bitmode(ctx);
5612
        GEN_LOAD_REG_T0(ft);
5613
        GEN_LOAD_FREG_FTN(WT0, fs);
5614
        GEN_LOAD_FREG_FTN(WTH0, fs);
5615
        GEN_LOAD_FREG_FTN(WT2, fd);
5616
        GEN_LOAD_FREG_FTN(WTH2, fd);
5617
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5618
        GEN_STORE_FTN_FREG(fd, WT2);
5619
        GEN_STORE_FTN_FREG(fd, WTH2);
5620
        opn = "movcf.ps";
5621
        break;
5622
    case FOP(18, 22):
5623
        check_cp1_64bitmode(ctx);
5624
        GEN_LOAD_REG_T0(ft);
5625
        GEN_LOAD_FREG_FTN(WT0, fs);
5626
        GEN_LOAD_FREG_FTN(WTH0, fs);
5627
        GEN_LOAD_FREG_FTN(WT2, fd);
5628
        GEN_LOAD_FREG_FTN(WTH2, fd);
5629
        gen_op_float_movz_ps();
5630
        GEN_STORE_FTN_FREG(fd, WT2);
5631
        GEN_STORE_FTN_FREG(fd, WTH2);
5632
        opn = "movz.ps";
5633
        break;
5634
    case FOP(19, 22):
5635
        check_cp1_64bitmode(ctx);
5636
        GEN_LOAD_REG_T0(ft);
5637
        GEN_LOAD_FREG_FTN(WT0, fs);
5638
        GEN_LOAD_FREG_FTN(WTH0, fs);
5639
        GEN_LOAD_FREG_FTN(WT2, fd);
5640
        GEN_LOAD_FREG_FTN(WTH2, fd);
5641
        gen_op_float_movn_ps();
5642
        GEN_STORE_FTN_FREG(fd, WT2);
5643
        GEN_STORE_FTN_FREG(fd, WTH2);
5644
        opn = "movn.ps";
5645
        break;
5646
    case FOP(24, 22):
5647
        check_cp1_64bitmode(ctx);
5648
        GEN_LOAD_FREG_FTN(WT0, ft);
5649
        GEN_LOAD_FREG_FTN(WTH0, ft);
5650
        GEN_LOAD_FREG_FTN(WT1, fs);
5651
        GEN_LOAD_FREG_FTN(WTH1, fs);
5652
        gen_op_float_addr_ps();
5653
        GEN_STORE_FTN_FREG(fd, WT2);
5654
        GEN_STORE_FTN_FREG(fd, WTH2);
5655
        opn = "addr.ps";
5656
        break;
5657
    case FOP(26, 22):
5658
        check_cp1_64bitmode(ctx);
5659
        GEN_LOAD_FREG_FTN(WT0, ft);
5660
        GEN_LOAD_FREG_FTN(WTH0, ft);
5661
        GEN_LOAD_FREG_FTN(WT1, fs);
5662
        GEN_LOAD_FREG_FTN(WTH1, fs);
5663
        gen_op_float_mulr_ps();
5664
        GEN_STORE_FTN_FREG(fd, WT2);
5665
        GEN_STORE_FTN_FREG(fd, WTH2);
5666
        opn = "mulr.ps";
5667
        break;
5668
    case FOP(28, 22):
5669
        check_cp1_64bitmode(ctx);
5670
        GEN_LOAD_FREG_FTN(WT0, fs);
5671
        GEN_LOAD_FREG_FTN(WTH0, fs);
5672
        GEN_LOAD_FREG_FTN(WT2, fd);
5673
        GEN_LOAD_FREG_FTN(WTH2, fd);
5674
        gen_op_float_recip2_ps();
5675
        GEN_STORE_FTN_FREG(fd, WT2);
5676
        GEN_STORE_FTN_FREG(fd, WTH2);
5677
        opn = "recip2.ps";
5678
        break;
5679
    case FOP(29, 22):
5680
        check_cp1_64bitmode(ctx);
5681
        GEN_LOAD_FREG_FTN(WT0, fs);
5682
        GEN_LOAD_FREG_FTN(WTH0, fs);
5683
        gen_op_float_recip1_ps();
5684
        GEN_STORE_FTN_FREG(fd, WT2);
5685
        GEN_STORE_FTN_FREG(fd, WTH2);
5686
        opn = "recip1.ps";
5687
        break;
5688
    case FOP(30, 22):
5689
        check_cp1_64bitmode(ctx);
5690
        GEN_LOAD_FREG_FTN(WT0, fs);
5691
        GEN_LOAD_FREG_FTN(WTH0, fs);
5692
        gen_op_float_rsqrt1_ps();
5693
        GEN_STORE_FTN_FREG(fd, WT2);
5694
        GEN_STORE_FTN_FREG(fd, WTH2);
5695
        opn = "rsqrt1.ps";
5696
        break;
5697
    case FOP(31, 22):
5698
        check_cp1_64bitmode(ctx);
5699
        GEN_LOAD_FREG_FTN(WT0, fs);
5700
        GEN_LOAD_FREG_FTN(WTH0, fs);
5701
        GEN_LOAD_FREG_FTN(WT2, ft);
5702
        GEN_LOAD_FREG_FTN(WTH2, ft);
5703
        gen_op_float_rsqrt2_ps();
5704
        GEN_STORE_FTN_FREG(fd, WT2);
5705
        GEN_STORE_FTN_FREG(fd, WTH2);
5706
        opn = "rsqrt2.ps";
5707
        break;
5708
    case FOP(32, 22):
5709
        check_cp1_64bitmode(ctx);
5710
        GEN_LOAD_FREG_FTN(WTH0, fs);
5711
        gen_op_float_cvts_pu();
5712
        GEN_STORE_FTN_FREG(fd, WT2);
5713
        opn = "cvt.s.pu";
5714
        break;
5715
    case FOP(36, 22):
5716
        check_cp1_64bitmode(ctx);
5717
        GEN_LOAD_FREG_FTN(WT0, fs);
5718
        GEN_LOAD_FREG_FTN(WTH0, fs);
5719
        gen_op_float_cvtpw_ps();
5720
        GEN_STORE_FTN_FREG(fd, WT2);
5721
        GEN_STORE_FTN_FREG(fd, WTH2);
5722
        opn = "cvt.pw.ps";
5723
        break;
5724
    case FOP(40, 22):
5725
        check_cp1_64bitmode(ctx);
5726
        GEN_LOAD_FREG_FTN(WT0, fs);
5727
        gen_op_float_cvts_pl();
5728
        GEN_STORE_FTN_FREG(fd, WT2);
5729
        opn = "cvt.s.pl";
5730
        break;
5731
    case FOP(44, 22):
5732
        check_cp1_64bitmode(ctx);
5733
        GEN_LOAD_FREG_FTN(WT0, fs);
5734
        GEN_LOAD_FREG_FTN(WT1, ft);
5735
        gen_op_float_pll_ps();
5736
        GEN_STORE_FTN_FREG(fd, DT2);
5737
        opn = "pll.ps";
5738
        break;
5739
    case FOP(45, 22):
5740
        check_cp1_64bitmode(ctx);
5741
        GEN_LOAD_FREG_FTN(WT0, fs);
5742
        GEN_LOAD_FREG_FTN(WTH1, ft);
5743
        gen_op_float_plu_ps();
5744
        GEN_STORE_FTN_FREG(fd, DT2);
5745
        opn = "plu.ps";
5746
        break;
5747
    case FOP(46, 22):
5748
        check_cp1_64bitmode(ctx);
5749
        GEN_LOAD_FREG_FTN(WTH0, fs);
5750
        GEN_LOAD_FREG_FTN(WT1, ft);
5751
        gen_op_float_pul_ps();
5752
        GEN_STORE_FTN_FREG(fd, DT2);
5753
        opn = "pul.ps";
5754
        break;
5755
    case FOP(47, 22):
5756
        check_cp1_64bitmode(ctx);
5757
        GEN_LOAD_FREG_FTN(WTH0, fs);
5758
        GEN_LOAD_FREG_FTN(WTH1, ft);
5759
        gen_op_float_puu_ps();
5760
        GEN_STORE_FTN_FREG(fd, DT2);
5761
        opn = "puu.ps";
5762
        break;
5763
    case FOP(48, 22):
5764
    case FOP(49, 22):
5765
    case FOP(50, 22):
5766
    case FOP(51, 22):
5767
    case FOP(52, 22):
5768
    case FOP(53, 22):
5769
    case FOP(54, 22):
5770
    case FOP(55, 22):
5771
    case FOP(56, 22):
5772
    case FOP(57, 22):
5773
    case FOP(58, 22):
5774
    case FOP(59, 22):
5775
    case FOP(60, 22):
5776
    case FOP(61, 22):
5777
    case FOP(62, 22):
5778
    case FOP(63, 22):
5779
        check_cp1_64bitmode(ctx);
5780
        GEN_LOAD_FREG_FTN(WT0, fs);
5781
        GEN_LOAD_FREG_FTN(WTH0, fs);
5782
        GEN_LOAD_FREG_FTN(WT1, ft);
5783
        GEN_LOAD_FREG_FTN(WTH1, ft);
5784
        if (ctx->opcode & (1 << 6)) {
5785
            gen_cmpabs_ps(func-48, cc);
5786
            opn = condnames_abs[func-48];
5787
        } else {
5788
            gen_cmp_ps(func-48, cc);
5789
            opn = condnames[func-48];
5790
        }
5791
        break;
5792
    default:
5793
        MIPS_INVAL(opn);
5794
        generate_exception (ctx, EXCP_RI);
5795
        return;
5796
    }
5797
    switch (optype) {
5798
    case BINOP:
5799
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5800
        break;
5801
    case CMPOP:
5802
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5803
        break;
5804
    default:
5805
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5806
        break;
5807
    }
5808
}
5809

    
5810
/* Coprocessor 3 (FPU) */
5811
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5812
                           int fd, int fs, int base, int index)
5813
{
5814
    const char *opn = "extended float load/store";
5815
    int store = 0;
5816

    
5817
    /* All of those work only on 64bit FPUs. */
5818
    check_cp1_64bitmode(ctx);
5819
    if (base == 0) {
5820
        if (index == 0)
5821
            gen_op_reset_T0();
5822
        else
5823
            GEN_LOAD_REG_T0(index);
5824
    } else if (index == 0) {
5825
        GEN_LOAD_REG_T0(base);
5826
    } else {
5827
        GEN_LOAD_REG_T0(base);
5828
        GEN_LOAD_REG_T1(index);
5829
        gen_op_addr_add();
5830
    }
5831
    /* Don't do NOP if destination is zero: we must perform the actual
5832
       memory access. */
5833
    switch (opc) {
5834
    case OPC_LWXC1:
5835
        op_ldst(lwc1);
5836
        GEN_STORE_FTN_FREG(fd, WT0);
5837
        opn = "lwxc1";
5838
        break;
5839
    case OPC_LDXC1:
5840
        op_ldst(ldc1);
5841
        GEN_STORE_FTN_FREG(fd, DT0);
5842
        opn = "ldxc1";
5843
        break;
5844
    case OPC_LUXC1:
5845
        op_ldst(luxc1);
5846
        GEN_STORE_FTN_FREG(fd, DT0);
5847
        opn = "luxc1";
5848
        break;
5849
    case OPC_SWXC1:
5850
        GEN_LOAD_FREG_FTN(WT0, fs);
5851
        op_ldst(swc1);
5852
        opn = "swxc1";
5853
        store = 1;
5854
        break;
5855
    case OPC_SDXC1:
5856
        GEN_LOAD_FREG_FTN(DT0, fs);
5857
        op_ldst(sdc1);
5858
        opn = "sdxc1";
5859
        store = 1;
5860
        break;
5861
    case OPC_SUXC1:
5862
        GEN_LOAD_FREG_FTN(DT0, fs);
5863
        op_ldst(suxc1);
5864
        opn = "suxc1";
5865
        store = 1;
5866
        break;
5867
    default:
5868
        MIPS_INVAL(opn);
5869
        generate_exception(ctx, EXCP_RI);
5870
        return;
5871
    }
5872
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5873
               regnames[index], regnames[base]);
5874
}
5875

    
5876
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5877
                            int fd, int fr, int fs, int ft)
5878
{
5879
    const char *opn = "flt3_arith";
5880

    
5881
    /* All of those work only on 64bit FPUs. */
5882
    check_cp1_64bitmode(ctx);
5883
    switch (opc) {
5884
    case OPC_ALNV_PS:
5885
        GEN_LOAD_REG_T0(fr);
5886
        GEN_LOAD_FREG_FTN(DT0, fs);
5887
        GEN_LOAD_FREG_FTN(DT1, ft);
5888
        gen_op_float_alnv_ps();
5889
        GEN_STORE_FTN_FREG(fd, DT2);
5890
        opn = "alnv.ps";
5891
        break;
5892
    case OPC_MADD_S:
5893
        GEN_LOAD_FREG_FTN(WT0, fs);
5894
        GEN_LOAD_FREG_FTN(WT1, ft);
5895
        GEN_LOAD_FREG_FTN(WT2, fr);
5896
        gen_op_float_muladd_s();
5897
        GEN_STORE_FTN_FREG(fd, WT2);
5898
        opn = "madd.s";
5899
        break;
5900
    case OPC_MADD_D:
5901
        GEN_LOAD_FREG_FTN(DT0, fs);
5902
        GEN_LOAD_FREG_FTN(DT1, ft);
5903
        GEN_LOAD_FREG_FTN(DT2, fr);
5904
        gen_op_float_muladd_d();
5905
        GEN_STORE_FTN_FREG(fd, DT2);
5906
        opn = "madd.d";
5907
        break;
5908
    case OPC_MADD_PS:
5909
        GEN_LOAD_FREG_FTN(WT0, fs);
5910
        GEN_LOAD_FREG_FTN(WTH0, fs);
5911
        GEN_LOAD_FREG_FTN(WT1, ft);
5912
        GEN_LOAD_FREG_FTN(WTH1, ft);
5913
        GEN_LOAD_FREG_FTN(WT2, fr);
5914
        GEN_LOAD_FREG_FTN(WTH2, fr);
5915
        gen_op_float_muladd_ps();
5916
        GEN_STORE_FTN_FREG(fd, WT2);
5917
        GEN_STORE_FTN_FREG(fd, WTH2);
5918
        opn = "madd.ps";
5919
        break;
5920
    case OPC_MSUB_S:
5921
        GEN_LOAD_FREG_FTN(WT0, fs);
5922
        GEN_LOAD_FREG_FTN(WT1, ft);
5923
        GEN_LOAD_FREG_FTN(WT2, fr);
5924
        gen_op_float_mulsub_s();
5925
        GEN_STORE_FTN_FREG(fd, WT2);
5926
        opn = "msub.s";
5927
        break;
5928
    case OPC_MSUB_D:
5929
        GEN_LOAD_FREG_FTN(DT0, fs);
5930
        GEN_LOAD_FREG_FTN(DT1, ft);
5931
        GEN_LOAD_FREG_FTN(DT2, fr);
5932
        gen_op_float_mulsub_d();
5933
        GEN_STORE_FTN_FREG(fd, DT2);
5934
        opn = "msub.d";
5935
        break;
5936
    case OPC_MSUB_PS:
5937
        GEN_LOAD_FREG_FTN(WT0, fs);
5938
        GEN_LOAD_FREG_FTN(WTH0, fs);
5939
        GEN_LOAD_FREG_FTN(WT1, ft);
5940
        GEN_LOAD_FREG_FTN(WTH1, ft);
5941
        GEN_LOAD_FREG_FTN(WT2, fr);
5942
        GEN_LOAD_FREG_FTN(WTH2, fr);
5943
        gen_op_float_mulsub_ps();
5944
        GEN_STORE_FTN_FREG(fd, WT2);
5945
        GEN_STORE_FTN_FREG(fd, WTH2);
5946
        opn = "msub.ps";
5947
        break;
5948
    case OPC_NMADD_S:
5949
        GEN_LOAD_FREG_FTN(WT0, fs);
5950
        GEN_LOAD_FREG_FTN(WT1, ft);
5951
        GEN_LOAD_FREG_FTN(WT2, fr);
5952
        gen_op_float_nmuladd_s();
5953
        GEN_STORE_FTN_FREG(fd, WT2);
5954
        opn = "nmadd.s";
5955
        break;
5956
    case OPC_NMADD_D:
5957
        GEN_LOAD_FREG_FTN(DT0, fs);
5958
        GEN_LOAD_FREG_FTN(DT1, ft);
5959
        GEN_LOAD_FREG_FTN(DT2, fr);
5960
        gen_op_float_nmuladd_d();
5961
        GEN_STORE_FTN_FREG(fd, DT2);
5962
        opn = "nmadd.d";
5963
        break;
5964
    case OPC_NMADD_PS:
5965
        GEN_LOAD_FREG_FTN(WT0, fs);
5966
        GEN_LOAD_FREG_FTN(WTH0, fs);
5967
        GEN_LOAD_FREG_FTN(WT1, ft);
5968
        GEN_LOAD_FREG_FTN(WTH1, ft);
5969
        GEN_LOAD_FREG_FTN(WT2, fr);
5970
        GEN_LOAD_FREG_FTN(WTH2, fr);
5971
        gen_op_float_nmuladd_ps();
5972
        GEN_STORE_FTN_FREG(fd, WT2);
5973
        GEN_STORE_FTN_FREG(fd, WTH2);
5974
        opn = "nmadd.ps";
5975
        break;
5976
    case OPC_NMSUB_S:
5977
        GEN_LOAD_FREG_FTN(WT0, fs);
5978
        GEN_LOAD_FREG_FTN(WT1, ft);
5979
        GEN_LOAD_FREG_FTN(WT2, fr);
5980
        gen_op_float_nmulsub_s();
5981
        GEN_STORE_FTN_FREG(fd, WT2);
5982
        opn = "nmsub.s";
5983
        break;
5984
    case OPC_NMSUB_D:
5985
        GEN_LOAD_FREG_FTN(DT0, fs);
5986
        GEN_LOAD_FREG_FTN(DT1, ft);
5987
        GEN_LOAD_FREG_FTN(DT2, fr);
5988
        gen_op_float_nmulsub_d();
5989
        GEN_STORE_FTN_FREG(fd, DT2);
5990
        opn = "nmsub.d";
5991
        break;
5992
    case OPC_NMSUB_PS:
5993
        GEN_LOAD_FREG_FTN(WT0, fs);
5994
        GEN_LOAD_FREG_FTN(WTH0, fs);
5995
        GEN_LOAD_FREG_FTN(WT1, ft);
5996
        GEN_LOAD_FREG_FTN(WTH1, ft);
5997
        GEN_LOAD_FREG_FTN(WT2, fr);
5998
        GEN_LOAD_FREG_FTN(WTH2, fr);
5999
        gen_op_float_nmulsub_ps();
6000
        GEN_STORE_FTN_FREG(fd, WT2);
6001
        GEN_STORE_FTN_FREG(fd, WTH2);
6002
        opn = "nmsub.ps";
6003
        break;
6004
    default:
6005
        MIPS_INVAL(opn);
6006
        generate_exception (ctx, EXCP_RI);
6007
        return;
6008
    }
6009
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6010
               fregnames[fs], fregnames[ft]);
6011
}
6012

    
6013
/* ISA extensions (ASEs) */
6014
/* MIPS16 extension to MIPS32 */
6015
/* SmartMIPS extension to MIPS32 */
6016

    
6017
#if defined(TARGET_MIPS64)
6018

    
6019
/* MDMX extension to MIPS64 */
6020

    
6021
#endif
6022

    
6023
static void decode_opc (CPUState *env, DisasContext *ctx)
6024
{
6025
    int32_t offset;
6026
    int rs, rt, rd, sa;
6027
    uint32_t op, op1, op2;
6028
    int16_t imm;
6029

    
6030
    /* make sure instructions are on a word boundary */
6031
    if (ctx->pc & 0x3) {
6032
        env->CP0_BadVAddr = ctx->pc;
6033
        generate_exception(ctx, EXCP_AdEL);
6034
        return;
6035
    }
6036

    
6037
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6038
        int l1;
6039
        /* Handle blikely not taken case */
6040
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6041
        l1 = gen_new_label();
6042
        gen_op_jnz_T2(l1);
6043
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6044
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6045
        gen_set_label(l1);
6046
    }
6047
    op = MASK_OP_MAJOR(ctx->opcode);
6048
    rs = (ctx->opcode >> 21) & 0x1f;
6049
    rt = (ctx->opcode >> 16) & 0x1f;
6050
    rd = (ctx->opcode >> 11) & 0x1f;
6051
    sa = (ctx->opcode >> 6) & 0x1f;
6052
    imm = (int16_t)ctx->opcode;
6053
    switch (op) {
6054
    case OPC_SPECIAL:
6055
        op1 = MASK_SPECIAL(ctx->opcode);
6056
        switch (op1) {
6057
        case OPC_SLL:          /* Arithmetic with immediate */
6058
        case OPC_SRL ... OPC_SRA:
6059
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6060
            break;
6061
        case OPC_MOVZ ... OPC_MOVN:
6062
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6063
        case OPC_SLLV:         /* Arithmetic */
6064
        case OPC_SRLV ... OPC_SRAV:
6065
        case OPC_ADD ... OPC_NOR:
6066
        case OPC_SLT ... OPC_SLTU:
6067
            gen_arith(env, ctx, op1, rd, rs, rt);
6068
            break;
6069
        case OPC_MULT ... OPC_DIVU:
6070
            if (sa) {
6071
                check_insn(env, ctx, INSN_VR54XX);
6072
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6073
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6074
            } else
6075
                gen_muldiv(ctx, op1, rs, rt);
6076
            break;
6077
        case OPC_JR ... OPC_JALR:
6078
            gen_compute_branch(ctx, op1, rs, rd, sa);
6079
            return;
6080
        case OPC_TGE ... OPC_TEQ: /* Traps */
6081
        case OPC_TNE:
6082
            gen_trap(ctx, op1, rs, rt, -1);
6083
            break;
6084
        case OPC_MFHI:          /* Move from HI/LO */
6085
        case OPC_MFLO:
6086
            gen_HILO(ctx, op1, rd);
6087
            break;
6088
        case OPC_MTHI:
6089
        case OPC_MTLO:          /* Move to HI/LO */
6090
            gen_HILO(ctx, op1, rs);
6091
            break;
6092
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6093
#ifdef MIPS_STRICT_STANDARD
6094
            MIPS_INVAL("PMON / selsl");
6095
            generate_exception(ctx, EXCP_RI);
6096
#else
6097
            gen_op_pmon(sa);
6098
#endif
6099
            break;
6100
        case OPC_SYSCALL:
6101
            generate_exception(ctx, EXCP_SYSCALL);
6102
            break;
6103
        case OPC_BREAK:
6104
            generate_exception(ctx, EXCP_BREAK);
6105
            break;
6106
        case OPC_SPIM:
6107
#ifdef MIPS_STRICT_STANDARD
6108
            MIPS_INVAL("SPIM");
6109
            generate_exception(ctx, EXCP_RI);
6110
#else
6111
           /* Implemented as RI exception for now. */
6112
            MIPS_INVAL("spim (unofficial)");
6113
            generate_exception(ctx, EXCP_RI);
6114
#endif
6115
            break;
6116
        case OPC_SYNC:
6117
            /* Treat as NOP. */
6118
            break;
6119

    
6120
        case OPC_MOVCI:
6121
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6122
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6123
                save_cpu_state(ctx, 1);
6124
                check_cp1_enabled(ctx);
6125
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6126
                          (ctx->opcode >> 16) & 1);
6127
            } else {
6128
                generate_exception_err(ctx, EXCP_CpU, 1);
6129
            }
6130
            break;
6131

    
6132
#if defined(TARGET_MIPS64)
6133
       /* MIPS64 specific opcodes */
6134
        case OPC_DSLL:
6135
        case OPC_DSRL ... OPC_DSRA:
6136
        case OPC_DSLL32:
6137
        case OPC_DSRL32 ... OPC_DSRA32:
6138
            check_insn(env, ctx, ISA_MIPS3);
6139
            check_mips_64(ctx);
6140
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6141
            break;
6142
        case OPC_DSLLV:
6143
        case OPC_DSRLV ... OPC_DSRAV:
6144
        case OPC_DADD ... OPC_DSUBU:
6145
            check_insn(env, ctx, ISA_MIPS3);
6146
            check_mips_64(ctx);
6147
            gen_arith(env, ctx, op1, rd, rs, rt);
6148
            break;
6149
        case OPC_DMULT ... OPC_DDIVU:
6150
            check_insn(env, ctx, ISA_MIPS3);
6151
            check_mips_64(ctx);
6152
            gen_muldiv(ctx, op1, rs, rt);
6153
            break;
6154
#endif
6155
        default:            /* Invalid */
6156
            MIPS_INVAL("special");
6157
            generate_exception(ctx, EXCP_RI);
6158
            break;
6159
        }
6160
        break;
6161
    case OPC_SPECIAL2:
6162
        op1 = MASK_SPECIAL2(ctx->opcode);
6163
        switch (op1) {
6164
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6165
        case OPC_MSUB ... OPC_MSUBU:
6166
            check_insn(env, ctx, ISA_MIPS32);
6167
            gen_muldiv(ctx, op1, rs, rt);
6168
            break;
6169
        case OPC_MUL:
6170
            gen_arith(env, ctx, op1, rd, rs, rt);
6171
            break;
6172
        case OPC_CLZ ... OPC_CLO:
6173
            check_insn(env, ctx, ISA_MIPS32);
6174
            gen_cl(ctx, op1, rd, rs);
6175
            break;
6176
        case OPC_SDBBP:
6177
            /* XXX: not clear which exception should be raised
6178
             *      when in debug mode...
6179
             */
6180
            check_insn(env, ctx, ISA_MIPS32);
6181
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6182
                generate_exception(ctx, EXCP_DBp);
6183
            } else {
6184
                generate_exception(ctx, EXCP_DBp);
6185
            }
6186
            /* Treat as NOP. */
6187
            break;
6188
#if defined(TARGET_MIPS64)
6189
        case OPC_DCLZ ... OPC_DCLO:
6190
            check_insn(env, ctx, ISA_MIPS64);
6191
            check_mips_64(ctx);
6192
            gen_cl(ctx, op1, rd, rs);
6193
            break;
6194
#endif
6195
        default:            /* Invalid */
6196
            MIPS_INVAL("special2");
6197
            generate_exception(ctx, EXCP_RI);
6198
            break;
6199
        }
6200
        break;
6201
    case OPC_SPECIAL3:
6202
         op1 = MASK_SPECIAL3(ctx->opcode);
6203
         switch (op1) {
6204
         case OPC_EXT:
6205
         case OPC_INS:
6206
             check_insn(env, ctx, ISA_MIPS32R2);
6207
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6208
             break;
6209
         case OPC_BSHFL:
6210
             check_insn(env, ctx, ISA_MIPS32R2);
6211
             op2 = MASK_BSHFL(ctx->opcode);
6212
             switch (op2) {
6213
             case OPC_WSBH:
6214
                 GEN_LOAD_REG_T1(rt);
6215
                 gen_op_wsbh();
6216
                 break;
6217
             case OPC_SEB:
6218
                 GEN_LOAD_REG_T1(rt);
6219
                 gen_op_seb();
6220
                 break;
6221
             case OPC_SEH:
6222
                 GEN_LOAD_REG_T1(rt);
6223
                 gen_op_seh();
6224
                 break;
6225
             default:            /* Invalid */
6226
                 MIPS_INVAL("bshfl");
6227
                 generate_exception(ctx, EXCP_RI);
6228
                 break;
6229
            }
6230
            GEN_STORE_T0_REG(rd);
6231
            break;
6232
        case OPC_RDHWR:
6233
            check_insn(env, ctx, ISA_MIPS32R2);
6234
            switch (rd) {
6235
            case 0:
6236
                save_cpu_state(ctx, 1);
6237
                gen_op_rdhwr_cpunum();
6238
                break;
6239
            case 1:
6240
                save_cpu_state(ctx, 1);
6241
                gen_op_rdhwr_synci_step();
6242
                break;
6243
            case 2:
6244
                save_cpu_state(ctx, 1);
6245
                gen_op_rdhwr_cc();
6246
                break;
6247
            case 3:
6248
                save_cpu_state(ctx, 1);
6249
                gen_op_rdhwr_ccres();
6250
                break;
6251
            case 29:
6252
#if defined (CONFIG_USER_ONLY)
6253
                gen_op_tls_value();
6254
                break;
6255
#endif
6256
            default:            /* Invalid */
6257
                MIPS_INVAL("rdhwr");
6258
                generate_exception(ctx, EXCP_RI);
6259
                break;
6260
            }
6261
            GEN_STORE_T0_REG(rt);
6262
            break;
6263
        case OPC_FORK:
6264
            check_insn(env, ctx, ASE_MT);
6265
            GEN_LOAD_REG_T0(rt);
6266
            GEN_LOAD_REG_T1(rs);
6267
            gen_op_fork();
6268
            break;
6269
        case OPC_YIELD:
6270
            check_insn(env, ctx, ASE_MT);
6271
            GEN_LOAD_REG_T0(rs);
6272
            gen_op_yield();
6273
            GEN_STORE_T0_REG(rd);
6274
            break;
6275
#if defined(TARGET_MIPS64)
6276
        case OPC_DEXTM ... OPC_DEXT:
6277
        case OPC_DINSM ... OPC_DINS:
6278
            check_insn(env, ctx, ISA_MIPS64R2);
6279
            check_mips_64(ctx);
6280
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6281
            break;
6282
        case OPC_DBSHFL:
6283
            check_insn(env, ctx, ISA_MIPS64R2);
6284
            check_mips_64(ctx);
6285
            op2 = MASK_DBSHFL(ctx->opcode);
6286
            switch (op2) {
6287
            case OPC_DSBH:
6288
                GEN_LOAD_REG_T1(rt);
6289
                gen_op_dsbh();
6290
                break;
6291
            case OPC_DSHD:
6292
                GEN_LOAD_REG_T1(rt);
6293
                gen_op_dshd();
6294
                break;
6295
            default:            /* Invalid */
6296
                MIPS_INVAL("dbshfl");
6297
                generate_exception(ctx, EXCP_RI);
6298
                break;
6299
            }
6300
            GEN_STORE_T0_REG(rd);
6301
            break;
6302
#endif
6303
        default:            /* Invalid */
6304
            MIPS_INVAL("special3");
6305
            generate_exception(ctx, EXCP_RI);
6306
            break;
6307
        }
6308
        break;
6309
    case OPC_REGIMM:
6310
        op1 = MASK_REGIMM(ctx->opcode);
6311
        switch (op1) {
6312
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6313
        case OPC_BLTZAL ... OPC_BGEZALL:
6314
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6315
            return;
6316
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6317
        case OPC_TNEI:
6318
            gen_trap(ctx, op1, rs, -1, imm);
6319
            break;
6320
        case OPC_SYNCI:
6321
            check_insn(env, ctx, ISA_MIPS32R2);
6322
            /* Treat as NOP. */
6323
            break;
6324
        default:            /* Invalid */
6325
            MIPS_INVAL("regimm");
6326
            generate_exception(ctx, EXCP_RI);
6327
            break;
6328
        }
6329
        break;
6330
    case OPC_CP0:
6331
        check_cp0_enabled(ctx);
6332
        op1 = MASK_CP0(ctx->opcode);
6333
        switch (op1) {
6334
        case OPC_MFC0:
6335
        case OPC_MTC0:
6336
        case OPC_MFTR:
6337
        case OPC_MTTR:
6338
#if defined(TARGET_MIPS64)
6339
        case OPC_DMFC0:
6340
        case OPC_DMTC0:
6341
#endif
6342
            gen_cp0(env, ctx, op1, rt, rd);
6343
            break;
6344
        case OPC_C0_FIRST ... OPC_C0_LAST:
6345
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6346
            break;
6347
        case OPC_MFMC0:
6348
            op2 = MASK_MFMC0(ctx->opcode);
6349
            switch (op2) {
6350
            case OPC_DMT:
6351
                check_insn(env, ctx, ASE_MT);
6352
                gen_op_dmt();
6353
                break;
6354
            case OPC_EMT:
6355
                check_insn(env, ctx, ASE_MT);
6356
                gen_op_emt();
6357
                break;
6358
            case OPC_DVPE:
6359
                check_insn(env, ctx, ASE_MT);
6360
                gen_op_dvpe();
6361
                break;
6362
            case OPC_EVPE:
6363
                check_insn(env, ctx, ASE_MT);
6364
                gen_op_evpe();
6365
                break;
6366
            case OPC_DI:
6367
                check_insn(env, ctx, ISA_MIPS32R2);
6368
                save_cpu_state(ctx, 1);
6369
                gen_op_di();
6370
                /* Stop translation as we may have switched the execution mode */
6371
                ctx->bstate = BS_STOP;
6372
                break;
6373
            case OPC_EI:
6374
                check_insn(env, ctx, ISA_MIPS32R2);
6375
                save_cpu_state(ctx, 1);
6376
                gen_op_ei();
6377
                /* Stop translation as we may have switched the execution mode */
6378
                ctx->bstate = BS_STOP;
6379
                break;
6380
            default:            /* Invalid */
6381
                MIPS_INVAL("mfmc0");
6382
                generate_exception(ctx, EXCP_RI);
6383
                break;
6384
            }
6385
            GEN_STORE_T0_REG(rt);
6386
            break;
6387
        case OPC_RDPGPR:
6388
            check_insn(env, ctx, ISA_MIPS32R2);
6389
            GEN_LOAD_SRSREG_TN(T0, rt);
6390
            GEN_STORE_T0_REG(rd);
6391
            break;
6392
        case OPC_WRPGPR:
6393
            check_insn(env, ctx, ISA_MIPS32R2);
6394
            GEN_LOAD_REG_T0(rt);
6395
            GEN_STORE_TN_SRSREG(rd, T0);
6396
            break;
6397
        default:
6398
            MIPS_INVAL("cp0");
6399
            generate_exception(ctx, EXCP_RI);
6400
            break;
6401
        }
6402
        break;
6403
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6404
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6405
         break;
6406
    case OPC_J ... OPC_JAL: /* Jump */
6407
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6408
         gen_compute_branch(ctx, op, rs, rt, offset);
6409
         return;
6410
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6411
    case OPC_BEQL ... OPC_BGTZL:
6412
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6413
         return;
6414
    case OPC_LB ... OPC_LWR: /* Load and stores */
6415
    case OPC_SB ... OPC_SW:
6416
    case OPC_SWR:
6417
    case OPC_LL:
6418
    case OPC_SC:
6419
         gen_ldst(ctx, op, rt, rs, imm);
6420
         break;
6421
    case OPC_CACHE:
6422
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6423
        /* Treat as NOP. */
6424
        break;
6425
    case OPC_PREF:
6426
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6427
        /* Treat as NOP. */
6428
        break;
6429

    
6430
    /* Floating point (COP1). */
6431
    case OPC_LWC1:
6432
    case OPC_LDC1:
6433
    case OPC_SWC1:
6434
    case OPC_SDC1:
6435
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6436
            save_cpu_state(ctx, 1);
6437
            check_cp1_enabled(ctx);
6438
            gen_flt_ldst(ctx, op, rt, rs, imm);
6439
        } else {
6440
            generate_exception_err(ctx, EXCP_CpU, 1);
6441
        }
6442
        break;
6443

    
6444
    case OPC_CP1:
6445
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6446
            save_cpu_state(ctx, 1);
6447
            check_cp1_enabled(ctx);
6448
            op1 = MASK_CP1(ctx->opcode);
6449
            switch (op1) {
6450
            case OPC_MFHC1:
6451
            case OPC_MTHC1:
6452
                check_insn(env, ctx, ISA_MIPS32R2);
6453
            case OPC_MFC1:
6454
            case OPC_CFC1:
6455
            case OPC_MTC1:
6456
            case OPC_CTC1:
6457
                gen_cp1(ctx, op1, rt, rd);
6458
                break;
6459
#if defined(TARGET_MIPS64)
6460
            case OPC_DMFC1:
6461
            case OPC_DMTC1:
6462
                check_insn(env, ctx, ISA_MIPS3);
6463
                gen_cp1(ctx, op1, rt, rd);
6464
                break;
6465
#endif
6466
            case OPC_BC1ANY2:
6467
            case OPC_BC1ANY4:
6468
                check_insn(env, ctx, ASE_MIPS3D);
6469
                /* fall through */
6470
            case OPC_BC1:
6471
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6472
                                    (rt >> 2) & 0x7, imm << 2);
6473
                return;
6474
            case OPC_S_FMT:
6475
            case OPC_D_FMT:
6476
            case OPC_W_FMT:
6477
            case OPC_L_FMT:
6478
            case OPC_PS_FMT:
6479
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6480
                           (imm >> 8) & 0x7);
6481
                break;
6482
            default:
6483
                MIPS_INVAL("cp1");
6484
                generate_exception (ctx, EXCP_RI);
6485
                break;
6486
            }
6487
        } else {
6488
            generate_exception_err(ctx, EXCP_CpU, 1);
6489
        }
6490
        break;
6491

    
6492
    /* COP2.  */
6493
    case OPC_LWC2:
6494
    case OPC_LDC2:
6495
    case OPC_SWC2:
6496
    case OPC_SDC2:
6497
    case OPC_CP2:
6498
        /* COP2: Not implemented. */
6499
        generate_exception_err(ctx, EXCP_CpU, 2);
6500
        break;
6501

    
6502
    case OPC_CP3:
6503
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6504
            save_cpu_state(ctx, 1);
6505
            check_cp1_enabled(ctx);
6506
            op1 = MASK_CP3(ctx->opcode);
6507
            switch (op1) {
6508
            case OPC_LWXC1:
6509
            case OPC_LDXC1:
6510
            case OPC_LUXC1:
6511
            case OPC_SWXC1:
6512
            case OPC_SDXC1:
6513
            case OPC_SUXC1:
6514
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6515
                break;
6516
            case OPC_PREFX:
6517
                /* Treat as NOP. */
6518
                break;
6519
            case OPC_ALNV_PS:
6520
            case OPC_MADD_S:
6521
            case OPC_MADD_D:
6522
            case OPC_MADD_PS:
6523
            case OPC_MSUB_S:
6524
            case OPC_MSUB_D:
6525
            case OPC_MSUB_PS:
6526
            case OPC_NMADD_S:
6527
            case OPC_NMADD_D:
6528
            case OPC_NMADD_PS:
6529
            case OPC_NMSUB_S:
6530
            case OPC_NMSUB_D:
6531
            case OPC_NMSUB_PS:
6532
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6533
                break;
6534
            default:
6535
                MIPS_INVAL("cp3");
6536
                generate_exception (ctx, EXCP_RI);
6537
                break;
6538
            }
6539
        } else {
6540
            generate_exception_err(ctx, EXCP_CpU, 1);
6541
        }
6542
        break;
6543

    
6544
#if defined(TARGET_MIPS64)
6545
    /* MIPS64 opcodes */
6546
    case OPC_LWU:
6547
    case OPC_LDL ... OPC_LDR:
6548
    case OPC_SDL ... OPC_SDR:
6549
    case OPC_LLD:
6550
    case OPC_LD:
6551
    case OPC_SCD:
6552
    case OPC_SD:
6553
        check_insn(env, ctx, ISA_MIPS3);
6554
        check_mips_64(ctx);
6555
        gen_ldst(ctx, op, rt, rs, imm);
6556
        break;
6557
    case OPC_DADDI ... OPC_DADDIU:
6558
        check_insn(env, ctx, ISA_MIPS3);
6559
        check_mips_64(ctx);
6560
        gen_arith_imm(env, ctx, op, rt, rs, imm);
6561
        break;
6562
#endif
6563
    case OPC_JALX:
6564
        check_insn(env, ctx, ASE_MIPS16);
6565
        /* MIPS16: Not implemented. */
6566
    case OPC_MDMX:
6567
        check_insn(env, ctx, ASE_MDMX);
6568
        /* MDMX: Not implemented. */
6569
    default:            /* Invalid */
6570
        MIPS_INVAL("major opcode");
6571
        generate_exception(ctx, EXCP_RI);
6572
        break;
6573
    }
6574
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6575
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6576
        /* Branches completion */
6577
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6578
        ctx->bstate = BS_BRANCH;
6579
        save_cpu_state(ctx, 0);
6580
        switch (hflags) {
6581
        case MIPS_HFLAG_B:
6582
            /* unconditional branch */
6583
            MIPS_DEBUG("unconditional branch");
6584
            gen_goto_tb(ctx, 0, ctx->btarget);
6585
            break;
6586
        case MIPS_HFLAG_BL:
6587
            /* blikely taken case */
6588
            MIPS_DEBUG("blikely branch taken");
6589
            gen_goto_tb(ctx, 0, ctx->btarget);
6590
            break;
6591
        case MIPS_HFLAG_BC:
6592
            /* Conditional branch */
6593
            MIPS_DEBUG("conditional branch");
6594
            {
6595
              int l1;
6596
              l1 = gen_new_label();
6597
              gen_op_jnz_T2(l1);
6598
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6599
              gen_set_label(l1);
6600
              gen_goto_tb(ctx, 0, ctx->btarget);
6601
            }
6602
            break;
6603
        case MIPS_HFLAG_BR:
6604
            /* unconditional branch to register */
6605
            MIPS_DEBUG("branch to register");
6606
            gen_op_breg();
6607
            gen_op_reset_T0();
6608
            gen_op_exit_tb();
6609
            break;
6610
        default:
6611
            MIPS_DEBUG("unknown branch");
6612
            break;
6613
        }
6614
    }
6615
}
6616

    
6617
static always_inline int
6618
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6619
                                int search_pc)
6620
{
6621
    DisasContext ctx;
6622
    target_ulong pc_start;
6623
    uint16_t *gen_opc_end;
6624
    int j, lj = -1;
6625

    
6626
    if (search_pc && loglevel)
6627
        fprintf (logfile, "search pc %d\n", search_pc);
6628

    
6629
    pc_start = tb->pc;
6630
    gen_opc_ptr = gen_opc_buf;
6631
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6632
    gen_opparam_ptr = gen_opparam_buf;
6633
    nb_gen_labels = 0;
6634
    ctx.pc = pc_start;
6635
    ctx.saved_pc = -1;
6636
    ctx.tb = tb;
6637
    ctx.bstate = BS_NONE;
6638
    /* Restore delay slot state from the tb context.  */
6639
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6640
    restore_cpu_state(env, &ctx);
6641
#if defined(CONFIG_USER_ONLY)
6642
    ctx.mem_idx = MIPS_HFLAG_UM;
6643
#else
6644
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6645
#endif
6646
#ifdef DEBUG_DISAS
6647
    if (loglevel & CPU_LOG_TB_CPU) {
6648
        fprintf(logfile, "------------------------------------------------\n");
6649
        /* FIXME: This may print out stale hflags from env... */
6650
        cpu_dump_state(env, logfile, fprintf, 0);
6651
    }
6652
#endif
6653
#ifdef MIPS_DEBUG_DISAS
6654
    if (loglevel & CPU_LOG_TB_IN_ASM)
6655
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6656
                tb, ctx.mem_idx, ctx.hflags);
6657
#endif
6658
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6659
        if (env->nb_breakpoints > 0) {
6660
            for(j = 0; j < env->nb_breakpoints; j++) {
6661
                if (env->breakpoints[j] == ctx.pc) {
6662
                    save_cpu_state(&ctx, 1);
6663
                    ctx.bstate = BS_BRANCH;
6664
                    gen_op_debug();
6665
                    /* Include the breakpoint location or the tb won't
6666
                     * be flushed when it must be.  */
6667
                    ctx.pc += 4;
6668
                    goto done_generating;
6669
                }
6670
            }
6671
        }
6672

    
6673
        if (search_pc) {
6674
            j = gen_opc_ptr - gen_opc_buf;
6675
            if (lj < j) {
6676
                lj++;
6677
                while (lj < j)
6678
                    gen_opc_instr_start[lj++] = 0;
6679
            }
6680
            gen_opc_pc[lj] = ctx.pc;
6681
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6682
            gen_opc_instr_start[lj] = 1;
6683
        }
6684
        ctx.opcode = ldl_code(ctx.pc);
6685
        decode_opc(env, &ctx);
6686
        ctx.pc += 4;
6687

    
6688
        if (env->singlestep_enabled)
6689
            break;
6690

    
6691
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6692
            break;
6693

    
6694
#if defined (MIPS_SINGLE_STEP)
6695
        break;
6696
#endif
6697
    }
6698
    if (env->singlestep_enabled) {
6699
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6700
        gen_op_debug();
6701
    } else {
6702
        switch (ctx.bstate) {
6703
        case BS_STOP:
6704
            gen_op_interrupt_restart();
6705
            gen_goto_tb(&ctx, 0, ctx.pc);
6706
            break;
6707
        case BS_NONE:
6708
            save_cpu_state(&ctx, 0);
6709
            gen_goto_tb(&ctx, 0, ctx.pc);
6710
            break;
6711
        case BS_EXCP:
6712
            gen_op_interrupt_restart();
6713
            gen_op_reset_T0();
6714
            gen_op_exit_tb();
6715
            break;
6716
        case BS_BRANCH:
6717
        default:
6718
            break;
6719
        }
6720
    }
6721
done_generating:
6722
    ctx.last_T0_store = NULL;
6723
    *gen_opc_ptr = INDEX_op_end;
6724
    if (search_pc) {
6725
        j = gen_opc_ptr - gen_opc_buf;
6726
        lj++;
6727
        while (lj <= j)
6728
            gen_opc_instr_start[lj++] = 0;
6729
    } else {
6730
        tb->size = ctx.pc - pc_start;
6731
    }
6732
#ifdef DEBUG_DISAS
6733
#if defined MIPS_DEBUG_DISAS
6734
    if (loglevel & CPU_LOG_TB_IN_ASM)
6735
        fprintf(logfile, "\n");
6736
#endif
6737
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6738
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6739
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6740
        fprintf(logfile, "\n");
6741
    }
6742
    if (loglevel & CPU_LOG_TB_OP) {
6743
        fprintf(logfile, "OP:\n");
6744
        dump_ops(gen_opc_buf, gen_opparam_buf);
6745
        fprintf(logfile, "\n");
6746
    }
6747
    if (loglevel & CPU_LOG_TB_CPU) {
6748
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6749
    }
6750
#endif
6751

    
6752
    return 0;
6753
}
6754

    
6755
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6756
{
6757
    return gen_intermediate_code_internal(env, tb, 0);
6758
}
6759

    
6760
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6761
{
6762
    return gen_intermediate_code_internal(env, tb, 1);
6763
}
6764

    
6765
void fpu_dump_state(CPUState *env, FILE *f,
6766
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6767
                    int flags)
6768
{
6769
    int i;
6770
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6771

    
6772
#define printfpr(fp)                                                        \
6773
    do {                                                                    \
6774
        if (is_fpu64)                                                       \
6775
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6776
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6777
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6778
        else {                                                              \
6779
            fpr_t tmp;                                                      \
6780
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6781
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6782
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6783
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6784
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6785
        }                                                                   \
6786
    } while(0)
6787

    
6788

    
6789
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6790
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6791
                get_float_exception_flags(&env->fpu->fp_status));
6792
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6793
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6794
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6795
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6796
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6797
        printfpr(&env->fpu->fpr[i]);
6798
    }
6799

    
6800
#undef printfpr
6801
}
6802

    
6803
void dump_fpu (CPUState *env)
6804
{
6805
    if (loglevel) {
6806
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6807
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6808
       fpu_dump_state(env, logfile, fprintf, 0);
6809
    }
6810
}
6811

    
6812
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6813
/* Debug help: The architecture requires 32bit code to maintain proper
6814
   sign-extened values on 64bit machines.  */
6815

    
6816
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6817

    
6818
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6819
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6820
                     int flags)
6821
{
6822
    int i;
6823

    
6824
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6825
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6826
    if (!SIGN_EXT_P(env->HI[0][env->current_tc]))
6827
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[0][env->current_tc]);
6828
    if (!SIGN_EXT_P(env->LO[0][env->current_tc]))
6829
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[0][env->current_tc]);
6830
    if (!SIGN_EXT_P(env->btarget))
6831
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6832

    
6833
    for (i = 0; i < 32; i++) {
6834
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6835
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6836
    }
6837

    
6838
    if (!SIGN_EXT_P(env->CP0_EPC))
6839
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6840
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6841
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6842
}
6843
#endif
6844

    
6845
void cpu_dump_state (CPUState *env, FILE *f,
6846
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6847
                     int flags)
6848
{
6849
    int i;
6850

    
6851
    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",
6852
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6853
    for (i = 0; i < 32; i++) {
6854
        if ((i & 3) == 0)
6855
            cpu_fprintf(f, "GPR%02d:", i);
6856
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6857
        if ((i & 3) == 3)
6858
            cpu_fprintf(f, "\n");
6859
    }
6860

    
6861
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6862
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6863
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6864
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6865
    if (env->hflags & MIPS_HFLAG_FPU)
6866
        fpu_dump_state(env, f, cpu_fprintf, flags);
6867
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6868
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6869
#endif
6870
}
6871

    
6872
#include "translate_init.c"
6873

    
6874
CPUMIPSState *cpu_mips_init (const char *cpu_model)
6875
{
6876
    CPUMIPSState *env;
6877
    const mips_def_t *def;
6878

    
6879
    def = cpu_mips_find_by_name(cpu_model);
6880
    if (!def)
6881
        return NULL;
6882
    env = qemu_mallocz(sizeof(CPUMIPSState));
6883
    if (!env)
6884
        return NULL;
6885
    env->cpu_model = def;
6886

    
6887
    cpu_exec_init(env);
6888
    env->cpu_model_str = cpu_model;
6889
    cpu_reset(env);
6890
    return env;
6891
}
6892

    
6893
void cpu_reset (CPUMIPSState *env)
6894
{
6895
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6896

    
6897
    tlb_flush(env, 1);
6898

    
6899
    /* Minimal init */
6900
#if !defined(CONFIG_USER_ONLY)
6901
    if (env->hflags & MIPS_HFLAG_BMASK) {
6902
        /* If the exception was raised from a delay slot,
6903
         * come back to the jump.  */
6904
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6905
    } else {
6906
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6907
    }
6908
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6909
    env->CP0_Wired = 0;
6910
    /* SMP not implemented */
6911
    env->CP0_EBase = 0x80000000;
6912
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6913
    /* vectored interrupts not implemented, timer on int 7,
6914
       no performance counters. */
6915
    env->CP0_IntCtl = 0xe0000000;
6916
    {
6917
        int i;
6918

    
6919
        for (i = 0; i < 7; i++) {
6920
            env->CP0_WatchLo[i] = 0;
6921
            env->CP0_WatchHi[i] = 0x80000000;
6922
        }
6923
        env->CP0_WatchLo[7] = 0;
6924
        env->CP0_WatchHi[7] = 0;
6925
    }
6926
    /* Count register increments in debug mode, EJTAG version 1 */
6927
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6928
#endif
6929
    env->exception_index = EXCP_NONE;
6930
#if defined(CONFIG_USER_ONLY)
6931
    env->hflags = MIPS_HFLAG_UM;
6932
    env->user_mode_only = 1;
6933
#else
6934
    env->hflags = MIPS_HFLAG_CP0;
6935
#endif
6936
    cpu_mips_register(env, env->cpu_model);
6937
}