Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d8a5950a

History | View | Annotate | Download (185.7 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
146
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
147
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
148
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
149
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
150
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
151
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
152
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
153
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
154
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
156
    /* Multiplication / division */
157
    OPC_MULT     = 0x18 | OPC_SPECIAL,
158
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
159
    OPC_DIV      = 0x1A | OPC_SPECIAL,
160
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
161
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
162
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
163
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
164
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
165
    /* 2 registers arithmetic / logic */
166
    OPC_ADD      = 0x20 | OPC_SPECIAL,
167
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
168
    OPC_SUB      = 0x22 | OPC_SPECIAL,
169
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
170
    OPC_AND      = 0x24 | OPC_SPECIAL,
171
    OPC_OR       = 0x25 | OPC_SPECIAL,
172
    OPC_XOR      = 0x26 | OPC_SPECIAL,
173
    OPC_NOR      = 0x27 | OPC_SPECIAL,
174
    OPC_SLT      = 0x2A | OPC_SPECIAL,
175
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
176
    OPC_DADD     = 0x2C | OPC_SPECIAL,
177
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
178
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
179
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
180
    /* Jumps */
181
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
183
    /* Traps */
184
    OPC_TGE      = 0x30 | OPC_SPECIAL,
185
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
186
    OPC_TLT      = 0x32 | OPC_SPECIAL,
187
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
188
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
189
    OPC_TNE      = 0x36 | OPC_SPECIAL,
190
    /* HI / LO registers load & stores */
191
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
192
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
193
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
194
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
195
    /* Conditional moves */
196
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
198

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

    
201
    /* Special */
202
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
203
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
205
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
206
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
207

    
208
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215
};
216

    
217
/* REGIMM (rt field) opcodes */
218
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219

    
220
enum {
221
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
222
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
223
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
224
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
225
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
226
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
227
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
228
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
229
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
230
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
231
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
232
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
233
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
234
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
235
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
236
};
237

    
238
/* Special2 opcodes */
239
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
240

    
241
enum {
242
    /* Multiply & xxx operations */
243
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
244
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
245
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
246
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
247
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
248
    /* Misc */
249
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
250
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
251
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
252
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
253
    /* Special */
254
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
255
};
256

    
257
/* Special3 opcodes */
258
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
259

    
260
enum {
261
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
262
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
263
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
264
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
265
    OPC_INS      = 0x04 | OPC_SPECIAL3,
266
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
267
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
268
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
269
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
270
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
271
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
272
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
273
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
274
};
275

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
420

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
752
static always_inline void check_cp1_3d(CPUState *env, DisasContext *ctx)
753
{
754
    if (unlikely(!(env->fpu->fcr0 & (1 << FCR0_3D))))
755
        generate_exception(ctx, EXCP_RI);
756
}
757

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

    
775
/* This code generates a "reserved instruction" exception if the
776
   CPU does not support the instruction set corresponding to flags. */
777
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
778
{
779
    if (unlikely(!(env->insn_flags & flags)))
780
        generate_exception(ctx, EXCP_RI);
781
}
782

    
783
/* This code generates a "reserved instruction" exception if the
784
   CPU is not MIPS MT capable. */
785
static always_inline void check_mips_mt(CPUState *env, DisasContext *ctx)
786
{
787
    if (unlikely(!(env->CP0_Config3 & (1 << CP0C3_MT))))
788
        generate_exception(ctx, EXCP_RI);
789
}
790

    
791
/* This code generates a "reserved instruction" exception if 64-bit
792
   instructions are not enabled. */
793
static always_inline void check_mips_64(DisasContext *ctx)
794
{
795
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
796
        generate_exception(ctx, EXCP_RI);
797
}
798

    
799
#if defined(CONFIG_USER_ONLY)
800
#define op_ldst(name)        gen_op_##name##_raw()
801
#define OP_LD_TABLE(width)
802
#define OP_ST_TABLE(width)
803
#else
804
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
805
#define OP_LD_TABLE(width)                                                    \
806
static GenOpFunc *gen_op_l##width[] = {                                       \
807
    &gen_op_l##width##_user,                                                  \
808
    &gen_op_l##width##_kernel,                                                \
809
}
810
#define OP_ST_TABLE(width)                                                    \
811
static GenOpFunc *gen_op_s##width[] = {                                       \
812
    &gen_op_s##width##_user,                                                  \
813
    &gen_op_s##width##_kernel,                                                \
814
}
815
#endif
816

    
817
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
818
OP_LD_TABLE(d);
819
OP_LD_TABLE(dl);
820
OP_LD_TABLE(dr);
821
OP_ST_TABLE(d);
822
OP_ST_TABLE(dl);
823
OP_ST_TABLE(dr);
824
OP_LD_TABLE(ld);
825
OP_ST_TABLE(cd);
826
OP_LD_TABLE(wu);
827
#endif
828
OP_LD_TABLE(w);
829
OP_LD_TABLE(wl);
830
OP_LD_TABLE(wr);
831
OP_ST_TABLE(w);
832
OP_ST_TABLE(wl);
833
OP_ST_TABLE(wr);
834
OP_LD_TABLE(h);
835
OP_LD_TABLE(hu);
836
OP_ST_TABLE(h);
837
OP_LD_TABLE(b);
838
OP_LD_TABLE(bu);
839
OP_ST_TABLE(b);
840
OP_LD_TABLE(l);
841
OP_ST_TABLE(c);
842
OP_LD_TABLE(wc1);
843
OP_ST_TABLE(wc1);
844
OP_LD_TABLE(dc1);
845
OP_ST_TABLE(dc1);
846
OP_LD_TABLE(uxc1);
847
OP_ST_TABLE(uxc1);
848

    
849
/* Load and store */
850
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
851
                      int base, int16_t offset)
852
{
853
    const char *opn = "ldst";
854

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

    
1000
/* Load and store */
1001
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1002
                      int base, int16_t offset)
1003
{
1004
    const char *opn = "flt_ldst";
1005

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

    
1046
/* Arithmetic with immediate operand */
1047
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1048
                           int rt, int rs, int16_t imm)
1049
{
1050
    target_ulong uimm;
1051
    const char *opn = "imm arith";
1052

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

    
1241
/* Arithmetic */
1242
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1243
                       int rd, int rs, int rt)
1244
{
1245
    const char *opn = "arith";
1246

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

    
1403
/* Arithmetic on HI/LO registers */
1404
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1405
{
1406
    const char *opn = "hilo";
1407

    
1408
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1409
        /* Treat as NOP. */
1410
        MIPS_DEBUG("NOP");
1411
        return;
1412
    }
1413
    switch (opc) {
1414
    case OPC_MFHI:
1415
        gen_op_load_HI(0);
1416
        GEN_STORE_TN_REG(reg, T0);
1417
        opn = "mfhi";
1418
        break;
1419
    case OPC_MFLO:
1420
        gen_op_load_LO(0);
1421
        GEN_STORE_TN_REG(reg, T0);
1422
        opn = "mflo";
1423
        break;
1424
    case OPC_MTHI:
1425
        GEN_LOAD_REG_TN(T0, reg);
1426
        gen_op_store_HI(0);
1427
        opn = "mthi";
1428
        break;
1429
    case OPC_MTLO:
1430
        GEN_LOAD_REG_TN(T0, reg);
1431
        gen_op_store_LO(0);
1432
        opn = "mtlo";
1433
        break;
1434
    default:
1435
        MIPS_INVAL(opn);
1436
        generate_exception(ctx, EXCP_RI);
1437
        return;
1438
    }
1439
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1440
}
1441

    
1442
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1443
                        int rs, int rt)
1444
{
1445
    const char *opn = "mul/div";
1446

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

    
1508
static void gen_cl (DisasContext *ctx, uint32_t opc,
1509
                    int rd, int rs)
1510
{
1511
    const char *opn = "CLx";
1512
    if (rd == 0) {
1513
        /* Treat as NOP. */
1514
        MIPS_DEBUG("NOP");
1515
        return;
1516
    }
1517
    GEN_LOAD_REG_TN(T0, rs);
1518
    switch (opc) {
1519
    case OPC_CLO:
1520
        gen_op_clo();
1521
        opn = "clo";
1522
        break;
1523
    case OPC_CLZ:
1524
        gen_op_clz();
1525
        opn = "clz";
1526
        break;
1527
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1528
    case OPC_DCLO:
1529
        gen_op_dclo();
1530
        opn = "dclo";
1531
        break;
1532
    case OPC_DCLZ:
1533
        gen_op_dclz();
1534
        opn = "dclz";
1535
        break;
1536
#endif
1537
    default:
1538
        MIPS_INVAL(opn);
1539
        generate_exception(ctx, EXCP_RI);
1540
        return;
1541
    }
1542
    gen_op_store_T0_gpr(rd);
1543
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1544
}
1545

    
1546
/* Traps */
1547
static void gen_trap (DisasContext *ctx, uint32_t opc,
1548
                      int rs, int rt, int16_t imm)
1549
{
1550
    int cond;
1551

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

    
1643
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1644
{
1645
    TranslationBlock *tb;
1646
    tb = ctx->tb;
1647
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1648
        if (n == 0)
1649
            gen_op_goto_tb0(TBPARAM(tb));
1650
        else
1651
            gen_op_goto_tb1(TBPARAM(tb));
1652
        gen_save_pc(dest);
1653
        gen_op_set_T0((long)tb + n);
1654
    } else {
1655
        gen_save_pc(dest);
1656
        gen_op_reset_T0();
1657
    }
1658
    gen_op_exit_tb();
1659
}
1660

    
1661
/* Branches (before delay slot) */
1662
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1663
                                int rs, int rt, int32_t offset)
1664
{
1665
    target_ulong btarget = -1;
1666
    int blink = 0;
1667
    int bcond = 0;
1668

    
1669
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1670
#ifdef MIPS_DEBUG_DISAS
1671
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1672
            fprintf(logfile,
1673
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1674
                    ctx->pc);
1675
        }
1676
#endif
1677
        generate_exception(ctx, EXCP_RI);
1678
        return;
1679
    }
1680

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

    
1894
    ctx->btarget = btarget;
1895
    if (blink > 0) {
1896
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1897
        gen_op_store_T0_gpr(blink);
1898
    }
1899
}
1900

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

    
1958
/* CP0 (MMU and control) */
1959
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1960
{
1961
    const char *rn = "invalid";
1962

    
1963
    if (sel != 0)
1964
        check_insn(env, ctx, ISA_MIPS32);
1965

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

    
2517
die:
2518
#if defined MIPS_DEBUG_DISAS
2519
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2520
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2521
                rn, reg, sel);
2522
    }
2523
#endif
2524
    generate_exception(ctx, EXCP_RI);
2525
}
2526

    
2527
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2528
{
2529
    const char *rn = "invalid";
2530

    
2531
    if (sel != 0)
2532
        check_insn(env, ctx, ISA_MIPS32);
2533

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

    
3116
die:
3117
#if defined MIPS_DEBUG_DISAS
3118
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3119
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3120
                rn, reg, sel);
3121
    }
3122
#endif
3123
    generate_exception(ctx, EXCP_RI);
3124
}
3125

    
3126
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
3127
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3128
{
3129
    const char *rn = "invalid";
3130

    
3131
    if (sel != 0)
3132
        check_insn(env, ctx, ISA_MIPS64);
3133

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

    
3674
die:
3675
#if defined MIPS_DEBUG_DISAS
3676
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3677
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3678
                rn, reg, sel);
3679
    }
3680
#endif
3681
    generate_exception(ctx, EXCP_RI);
3682
}
3683

    
3684
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3685
{
3686
    const char *rn = "invalid";
3687

    
3688
    if (sel != 0)
3689
        check_insn(env, ctx, ISA_MIPS64);
3690

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

    
4260
die:
4261
#if defined MIPS_DEBUG_DISAS
4262
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4263
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4264
                rn, reg, sel);
4265
    }
4266
#endif
4267
    generate_exception(ctx, EXCP_RI);
4268
}
4269
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
4270

    
4271
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4272
                     int u, int sel, int h)
4273
{
4274
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4275

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

    
4425
die:
4426
#if defined MIPS_DEBUG_DISAS
4427
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4428
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4429
                rt, u, sel, h);
4430
    }
4431
#endif
4432
    generate_exception(ctx, EXCP_RI);
4433
}
4434

    
4435
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4436
                     int u, int sel, int h)
4437
{
4438
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4439

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

    
4589
die:
4590
#if defined MIPS_DEBUG_DISAS
4591
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4592
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4593
                rd, u, sel, h);
4594
    }
4595
#endif
4596
    generate_exception(ctx, EXCP_RI);
4597
}
4598

    
4599
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4600
{
4601
    const char *opn = "ldst";
4602

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

    
4718
/* CP1 Branches (before delay slot) */
4719
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4720
                                 int32_t cc, int32_t offset)
4721
{
4722
    target_ulong btarget;
4723
    const char *opn = "cp1 cond branch";
4724

    
4725
    if (cc != 0)
4726
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4727

    
4728
    btarget = ctx->pc + 4 + offset;
4729

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

    
4780
/* Coprocessor 1 (FPU) */
4781

    
4782
#define FOP(func, fmt) (((fmt) << 21) | (func))
4783

    
4784
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4785
{
4786
    const char *opn = "cp1 move";
4787

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

    
4843
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4844
{
4845
    uint32_t ccbit;
4846

    
4847
    GEN_LOAD_REG_TN(T0, rd);
4848
    GEN_LOAD_REG_TN(T1, rs);
4849
    if (cc) {
4850
        ccbit = 1 << (24 + cc);
4851
    } else
4852
        ccbit = 1 << 23;
4853
    if (!tf)
4854
        gen_op_movf(ccbit);
4855
    else
4856
        gen_op_movt(ccbit);
4857
    GEN_STORE_TN_REG(rd, T0);
4858
}
4859

    
4860
#define GEN_MOVCF(fmt)                                                \
4861
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4862
{                                                                     \
4863
    uint32_t ccbit;                                                   \
4864
                                                                      \
4865
    if (cc) {                                                         \
4866
        ccbit = 1 << (24 + cc);                                       \
4867
    } else                                                            \
4868
        ccbit = 1 << 23;                                              \
4869
    if (!tf)                                                          \
4870
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4871
    else                                                              \
4872
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4873
}
4874
GEN_MOVCF(d);
4875
GEN_MOVCF(s);
4876
GEN_MOVCF(ps);
4877
#undef GEN_MOVCF
4878

    
4879
static void gen_farith (DisasContext *ctx, uint32_t op1,
4880
                        int ft, int fs, int fd, int cc)
4881
{
4882
    const char *opn = "farith";
4883
    const char *condnames[] = {
4884
            "c.f",
4885
            "c.un",
4886
            "c.eq",
4887
            "c.ueq",
4888
            "c.olt",
4889
            "c.ult",
4890
            "c.ole",
4891
            "c.ule",
4892
            "c.sf",
4893
            "c.ngle",
4894
            "c.seq",
4895
            "c.ngl",
4896
            "c.lt",
4897
            "c.nge",
4898
            "c.le",
4899
            "c.ngt",
4900
    };
4901
    const char *condnames_abs[] = {
4902
            "cabs.f",
4903
            "cabs.un",
4904
            "cabs.eq",
4905
            "cabs.ueq",
4906
            "cabs.olt",
4907
            "cabs.ult",
4908
            "cabs.ole",
4909
            "cabs.ule",
4910
            "cabs.sf",
4911
            "cabs.ngle",
4912
            "cabs.seq",
4913
            "cabs.ngl",
4914
            "cabs.lt",
4915
            "cabs.nge",
4916
            "cabs.le",
4917
            "cabs.ngt",
4918
    };
4919
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4920
    uint32_t func = ctx->opcode & 0x3f;
4921

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

    
5686
/* Coprocessor 3 (FPU) */
5687
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5688
                           int fd, int fs, int base, int index)
5689
{
5690
    const char *opn = "extended float load/store";
5691
    int store = 0;
5692

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

    
5752
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5753
                            int fd, int fr, int fs, int ft)
5754
{
5755
    const char *opn = "flt3_arith";
5756

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

    
5889
/* ISA extensions (ASEs) */
5890
/* MIPS16 extension to MIPS32 */
5891
/* SmartMIPS extension to MIPS32 */
5892

    
5893
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
5894

    
5895
/* MDMX extension to MIPS64 */
5896
/* MIPS-3D extension to MIPS64 */
5897

    
5898
#endif
5899

    
5900
static void decode_opc (CPUState *env, DisasContext *ctx)
5901
{
5902
    int32_t offset;
5903
    int rs, rt, rd, sa;
5904
    uint32_t op, op1, op2;
5905
    int16_t imm;
5906

    
5907
    /* make sure instructions are on a word boundary */
5908
    if (ctx->pc & 0x3) {
5909
        env->CP0_BadVAddr = ctx->pc;
5910
        generate_exception(ctx, EXCP_AdEL);
5911
        return;
5912
    }
5913

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

    
5992
        case OPC_MOVCI:
5993
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5994
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5995
                save_cpu_state(ctx, 1);
5996
                check_cp1_enabled(ctx);
5997
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5998
                          (ctx->opcode >> 16) & 1);
5999
            } else {
6000
                generate_exception_err(ctx, EXCP_CpU, 1);
6001
            }
6002
            break;
6003

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

    
6301
    /* Floating point (COP1). */
6302
    case OPC_LWC1:
6303
    case OPC_LDC1:
6304
    case OPC_SWC1:
6305
    case OPC_SDC1:
6306
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6307
            save_cpu_state(ctx, 1);
6308
            check_cp1_enabled(ctx);
6309
            gen_flt_ldst(ctx, op, rt, rs, imm);
6310
        } else {
6311
            generate_exception_err(ctx, EXCP_CpU, 1);
6312
        }
6313
        break;
6314

    
6315
    case OPC_CP1:
6316
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6317
            save_cpu_state(ctx, 1);
6318
            check_cp1_enabled(ctx);
6319
            op1 = MASK_CP1(ctx->opcode);
6320
            switch (op1) {
6321
            case OPC_MFHC1:
6322
            case OPC_MTHC1:
6323
                check_insn(env, ctx, ISA_MIPS32R2);
6324
            case OPC_MFC1:
6325
            case OPC_CFC1:
6326
            case OPC_MTC1:
6327
            case OPC_CTC1:
6328
                gen_cp1(ctx, op1, rt, rd);
6329
                break;
6330
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
6331
            case OPC_DMFC1:
6332
            case OPC_DMTC1:
6333
                check_insn(env, ctx, ISA_MIPS3);
6334
                gen_cp1(ctx, op1, rt, rd);
6335
                break;
6336
#endif
6337
            case OPC_BC1ANY2:
6338
            case OPC_BC1ANY4:
6339
                check_cp1_3d(env, ctx);
6340
                /* fall through */
6341
            case OPC_BC1:
6342
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6343
                                    (rt >> 2) & 0x7, imm << 2);
6344
                return;
6345
            case OPC_S_FMT:
6346
            case OPC_D_FMT:
6347
            case OPC_W_FMT:
6348
            case OPC_L_FMT:
6349
            case OPC_PS_FMT:
6350
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6351
                           (imm >> 8) & 0x7);
6352
                break;
6353
            default:
6354
                MIPS_INVAL("cp1");
6355
                generate_exception (ctx, EXCP_RI);
6356
                break;
6357
            }
6358
        } else {
6359
            generate_exception_err(ctx, EXCP_CpU, 1);
6360
        }
6361
        break;
6362

    
6363
    /* COP2.  */
6364
    case OPC_LWC2:
6365
    case OPC_LDC2:
6366
    case OPC_SWC2:
6367
    case OPC_SDC2:
6368
    case OPC_CP2:
6369
        /* COP2: Not implemented. */
6370
        generate_exception_err(ctx, EXCP_CpU, 2);
6371
        break;
6372

    
6373
    case OPC_CP3:
6374
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6375
            save_cpu_state(ctx, 1);
6376
            check_cp1_enabled(ctx);
6377
            op1 = MASK_CP3(ctx->opcode);
6378
            switch (op1) {
6379
            case OPC_LWXC1:
6380
            case OPC_LDXC1:
6381
            case OPC_LUXC1:
6382
            case OPC_SWXC1:
6383
            case OPC_SDXC1:
6384
            case OPC_SUXC1:
6385
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6386
                break;
6387
            case OPC_PREFX:
6388
                /* Treat as NOP. */
6389
                break;
6390
            case OPC_ALNV_PS:
6391
            case OPC_MADD_S:
6392
            case OPC_MADD_D:
6393
            case OPC_MADD_PS:
6394
            case OPC_MSUB_S:
6395
            case OPC_MSUB_D:
6396
            case OPC_MSUB_PS:
6397
            case OPC_NMADD_S:
6398
            case OPC_NMADD_D:
6399
            case OPC_NMADD_PS:
6400
            case OPC_NMSUB_S:
6401
            case OPC_NMSUB_D:
6402
            case OPC_NMSUB_PS:
6403
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6404
                break;
6405
            default:
6406
                MIPS_INVAL("cp3");
6407
                generate_exception (ctx, EXCP_RI);
6408
                break;
6409
            }
6410
        } else {
6411
            generate_exception_err(ctx, EXCP_CpU, 1);
6412
        }
6413
        break;
6414

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

    
6488
static always_inline int
6489
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6490
                                int search_pc)
6491
{
6492
    DisasContext ctx;
6493
    target_ulong pc_start;
6494
    uint16_t *gen_opc_end;
6495
    int j, lj = -1;
6496

    
6497
    if (search_pc && loglevel)
6498
        fprintf (logfile, "search pc %d\n", search_pc);
6499

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

    
6544
        if (search_pc) {
6545
            j = gen_opc_ptr - gen_opc_buf;
6546
            if (lj < j) {
6547
                lj++;
6548
                while (lj < j)
6549
                    gen_opc_instr_start[lj++] = 0;
6550
            }
6551
            gen_opc_pc[lj] = ctx.pc;
6552
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6553
            gen_opc_instr_start[lj] = 1;
6554
        }
6555
        ctx.opcode = ldl_code(ctx.pc);
6556
        decode_opc(env, &ctx);
6557
        ctx.pc += 4;
6558

    
6559
        if (env->singlestep_enabled)
6560
            break;
6561

    
6562
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6563
            break;
6564

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

    
6622
    return 0;
6623
}
6624

    
6625
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6626
{
6627
    return gen_intermediate_code_internal(env, tb, 0);
6628
}
6629

    
6630
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6631
{
6632
    return gen_intermediate_code_internal(env, tb, 1);
6633
}
6634

    
6635
void fpu_dump_state(CPUState *env, FILE *f,
6636
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6637
                    int flags)
6638
{
6639
    int i;
6640
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6641

    
6642
#define printfpr(fp)                                                        \
6643
    do {                                                                    \
6644
        if (is_fpu64)                                                       \
6645
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6646
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6647
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6648
        else {                                                              \
6649
            fpr_t tmp;                                                      \
6650
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6651
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6652
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6653
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6654
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6655
        }                                                                   \
6656
    } while(0)
6657

    
6658

    
6659
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6660
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6661
                get_float_exception_flags(&env->fpu->fp_status));
6662
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6663
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6664
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6665
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6666
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6667
        printfpr(&env->fpu->fpr[i]);
6668
    }
6669

    
6670
#undef printfpr
6671
}
6672

    
6673
void dump_fpu (CPUState *env)
6674
{
6675
    if (loglevel) {
6676
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6677
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6678
       fpu_dump_state(env, logfile, fprintf, 0);
6679
    }
6680
}
6681

    
6682
#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6683
/* Debug help: The architecture requires 32bit code to maintain proper
6684
   sign-extened values on 64bit machines.  */
6685

    
6686
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6687

    
6688
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6689
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6690
                     int flags)
6691
{
6692
    int i;
6693

    
6694
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6695
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6696
    if (!SIGN_EXT_P(env->HI[env->current_tc]))
6697
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc]);
6698
    if (!SIGN_EXT_P(env->LO[env->current_tc]))
6699
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc]);
6700
    if (!SIGN_EXT_P(env->btarget))
6701
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6702

    
6703
    for (i = 0; i < 32; i++) {
6704
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6705
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6706
    }
6707

    
6708
    if (!SIGN_EXT_P(env->CP0_EPC))
6709
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6710
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6711
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6712
}
6713
#endif
6714

    
6715
void cpu_dump_state (CPUState *env, FILE *f,
6716
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6717
                     int flags)
6718
{
6719
    int i;
6720

    
6721
    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",
6722
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6723
    for (i = 0; i < 32; i++) {
6724
        if ((i & 3) == 0)
6725
            cpu_fprintf(f, "GPR%02d:", i);
6726
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6727
        if ((i & 3) == 3)
6728
            cpu_fprintf(f, "\n");
6729
    }
6730

    
6731
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6732
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6733
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6734
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6735
    if (env->hflags & MIPS_HFLAG_FPU)
6736
        fpu_dump_state(env, f, cpu_fprintf, flags);
6737
#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6738
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6739
#endif
6740
}
6741

    
6742
CPUMIPSState *cpu_mips_init (void)
6743
{
6744
    CPUMIPSState *env;
6745

    
6746
    env = qemu_mallocz(sizeof(CPUMIPSState));
6747
    if (!env)
6748
        return NULL;
6749
    cpu_exec_init(env);
6750
    cpu_reset(env);
6751
    return env;
6752
}
6753

    
6754
void cpu_reset (CPUMIPSState *env)
6755
{
6756
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6757

    
6758
    tlb_flush(env, 1);
6759

    
6760
    /* Minimal init */
6761
#if !defined(CONFIG_USER_ONLY)
6762
    if (env->hflags & MIPS_HFLAG_BMASK) {
6763
        /* If the exception was raised from a delay slot,
6764
         * come back to the jump.  */
6765
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6766
    } else {
6767
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6768
    }
6769
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6770
    env->CP0_Wired = 0;
6771
    /* SMP not implemented */
6772
    env->CP0_EBase = 0x80000000;
6773
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6774
    /* vectored interrupts not implemented, timer on int 7,
6775
       no performance counters. */
6776
    env->CP0_IntCtl = 0xe0000000;
6777
    {
6778
        int i;
6779

    
6780
        for (i = 0; i < 7; i++) {
6781
            env->CP0_WatchLo[i] = 0;
6782
            env->CP0_WatchHi[i] = 0x80000000;
6783
        }
6784
        env->CP0_WatchLo[7] = 0;
6785
        env->CP0_WatchHi[7] = 0;
6786
    }
6787
    /* Count register increments in debug mode, EJTAG version 1 */
6788
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6789
#endif
6790
    env->exception_index = EXCP_NONE;
6791
#if defined(CONFIG_USER_ONLY)
6792
    env->hflags = MIPS_HFLAG_UM;
6793
    env->user_mode_only = 1;
6794
#else
6795
    env->hflags = MIPS_HFLAG_CP0;
6796
#endif
6797
}
6798

    
6799
#include "translate_init.c"