Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 9f77c1cd

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1949
    if (sel != 0)
1950
        check_insn(env, ctx, ISA_MIPS32);
1951

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

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

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

    
2517
    if (sel != 0)
2518
        check_insn(env, ctx, ISA_MIPS32);
2519

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

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

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

    
3117
    if (sel != 0)
3118
        check_insn(env, ctx, ISA_MIPS64);
3119

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

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

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

    
3674
    if (sel != 0)
3675
        check_insn(env, ctx, ISA_MIPS64);
3676

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

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

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

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

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

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

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

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

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

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

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

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

    
4714
    btarget = ctx->pc + 4 + offset;
4715

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

    
4766
/* Coprocessor 1 (FPU) */
4767

    
4768
#define FOP(func, fmt) (((fmt) << 21) | (func))
4769

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

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

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

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

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

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

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

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

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

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

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

    
5874
/* ISA extensions (ASEs) */
5875
/* MIPS16 extension to MIPS32 */
5876
/* SmartMIPS extension to MIPS32 */
5877

    
5878
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
5879

    
5880
/* MDMX extension to MIPS64 */
5881

    
5882
#endif
5883

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6543
        if (env->singlestep_enabled)
6544
            break;
6545

    
6546
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6547
            break;
6548

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

    
6606
    return 0;
6607
}
6608

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

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

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

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

    
6642

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

    
6654
#undef printfpr
6655
}
6656

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

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

    
6670
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6671

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

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

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

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

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

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

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

    
6726
CPUMIPSState *cpu_mips_init (void)
6727
{
6728
    CPUMIPSState *env;
6729

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

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

    
6742
    tlb_flush(env, 1);
6743

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

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

    
6783
#include "translate_init.c"