Statistics
| Branch: | Revision:

root / target-mips / translate.c @ e189e748

History | View | Annotate | Download (184.2 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 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 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 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
#ifdef 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 inline void gen_save_pc(target_ulong pc)
640
{
641
#ifdef 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 inline void gen_save_btarget(target_ulong btarget)
653
{
654
#ifdef 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 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 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 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 inline void generate_exception (DisasContext *ctx, int excp)
730
{
731
    generate_exception_err (ctx, excp, 0);
732
}
733

    
734
static inline void check_cp1_enabled(DisasContext *ctx)
735
{
736
    if (!(ctx->hflags & MIPS_HFLAG_FPU))
737
        generate_exception_err(ctx, EXCP_CpU, 1);
738
}
739

    
740
static inline void check_cp1_64bitmode(DisasContext *ctx)
741
{
742
    if (!(ctx->hflags & MIPS_HFLAG_F64))
743
        generate_exception(ctx, EXCP_RI);
744
}
745

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

    
763
/* This code generates a "reserved instruction" exception if the
764
   CPU does not support the instruction set corresponding to flags. */
765
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
766
{
767
    if (unlikely(!(env->insn_flags & flags)))
768
        generate_exception(ctx, EXCP_RI);
769
}
770

    
771
/* This code generates a "reserved instruction" exception if the
772
   CPU is not MIPS MT capable. */
773
static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
774
{
775
    if (!(env->CP0_Config3 & (1 << CP0C3_MT)))
776
        generate_exception(ctx, EXCP_RI);
777
}
778

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4591
    switch (opc) {
4592
    case OPC_MFC0:
4593
        if (rt == 0) {
4594
            /* Treat as NOP. */
4595
            return;
4596
        }
4597
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4598
        gen_op_store_T0_gpr(rt);
4599
        opn = "mfc0";
4600
        break;
4601
    case OPC_MTC0:
4602
        GEN_LOAD_REG_TN(T0, rt);
4603
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4604
        opn = "mtc0";
4605
        break;
4606
#ifdef TARGET_MIPS64
4607
    case OPC_DMFC0:
4608
        check_insn(env, ctx, ISA_MIPS3);
4609
        if (rt == 0) {
4610
            /* Treat as NOP. */
4611
            return;
4612
        }
4613
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4614
        gen_op_store_T0_gpr(rt);
4615
        opn = "dmfc0";
4616
        break;
4617
    case OPC_DMTC0:
4618
        check_insn(env, ctx, ISA_MIPS3);
4619
        GEN_LOAD_REG_TN(T0, rt);
4620
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4621
        opn = "dmtc0";
4622
        break;
4623
#endif
4624
    case OPC_MFTR:
4625
        check_mips_mt(env, ctx);
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_mips_mt(env, ctx);
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
        gen_op_eret();
4670
        ctx->bstate = BS_EXCP;
4671
        break;
4672
    case OPC_DERET:
4673
        opn = "deret";
4674
        check_insn(env, ctx, ISA_MIPS32);
4675
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4676
            MIPS_INVAL(opn);
4677
            generate_exception(ctx, EXCP_RI);
4678
        } else {
4679
            gen_op_deret();
4680
            ctx->bstate = BS_EXCP;
4681
        }
4682
        break;
4683
    case OPC_WAIT:
4684
        opn = "wait";
4685
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4686
        /* If we get an exception, we want to restart at next instruction */
4687
        ctx->pc += 4;
4688
        save_cpu_state(ctx, 1);
4689
        ctx->pc -= 4;
4690
        gen_op_wait();
4691
        ctx->bstate = BS_EXCP;
4692
        break;
4693
    default:
4694
 die:
4695
        MIPS_INVAL(opn);
4696
        generate_exception(ctx, EXCP_RI);
4697
        return;
4698
    }
4699
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4700
}
4701

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

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

    
4712
    btarget = ctx->pc + 4 + offset;
4713

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

    
4764
/* Coprocessor 1 (FPU) */
4765

    
4766
#define FOP(func, fmt) (((fmt) << 21) | (func))
4767

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

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

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

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

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

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

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

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

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

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

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

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

    
5877
#ifdef TARGET_MIPS64
5878

    
5879
/* MDMX extension to MIPS64 */
5880
/* MIPS-3D 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
#ifdef 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
#ifdef 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_mips_mt(env, ctx);
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_mips_mt(env, ctx);
6127
            GEN_LOAD_REG_TN(T0, rs);
6128
            gen_op_yield();
6129
            GEN_STORE_TN_REG(rd, T0);
6130
            break;
6131
#ifdef 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
        save_cpu_state(ctx, 1);
6187
        gen_op_cp0_enabled();
6188
        op1 = MASK_CP0(ctx->opcode);
6189
        switch (op1) {
6190
        case OPC_MFC0:
6191
        case OPC_MTC0:
6192
        case OPC_MFTR:
6193
        case OPC_MTTR:
6194
#ifdef TARGET_MIPS64
6195
        case OPC_DMFC0:
6196
        case OPC_DMTC0:
6197
#endif
6198
            gen_cp0(env, ctx, op1, rt, rd);
6199
            break;
6200
        case OPC_C0_FIRST ... OPC_C0_LAST:
6201
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6202
            break;
6203
        case OPC_MFMC0:
6204
            op2 = MASK_MFMC0(ctx->opcode);
6205
            switch (op2) {
6206
            case OPC_DMT:
6207
                check_mips_mt(env, ctx);
6208
                gen_op_dmt();
6209
                break;
6210
            case OPC_EMT:
6211
                check_mips_mt(env, ctx);
6212
                gen_op_emt();
6213
                break;
6214
            case OPC_DVPE:
6215
                check_mips_mt(env, ctx);
6216
                gen_op_dvpe();
6217
                break;
6218
            case OPC_EVPE:
6219
                check_mips_mt(env, ctx);
6220
                gen_op_evpe();
6221
                break;
6222
            case OPC_DI:
6223
                check_insn(env, ctx, ISA_MIPS32R2);
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
                gen_op_ei();
6231
                /* Stop translation as we may have switched the execution mode */
6232
                ctx->bstate = BS_STOP;
6233
                break;
6234
            default:            /* Invalid */
6235
                MIPS_INVAL("mfmc0");
6236
                generate_exception(ctx, EXCP_RI);
6237
                break;
6238
            }
6239
            GEN_STORE_TN_REG(rt, T0);
6240
            break;
6241
        case OPC_RDPGPR:
6242
            check_insn(env, ctx, ISA_MIPS32R2);
6243
            GEN_LOAD_SRSREG_TN(T0, rt);
6244
            GEN_STORE_TN_REG(rd, T0);
6245
            break;
6246
        case OPC_WRPGPR:
6247
            check_insn(env, ctx, ISA_MIPS32R2);
6248
            GEN_LOAD_REG_TN(T0, rt);
6249
            GEN_STORE_TN_SRSREG(rd, T0);
6250
            break;
6251
        default:
6252
            MIPS_INVAL("cp0");
6253
            generate_exception(ctx, EXCP_RI);
6254
            break;
6255
        }
6256
        break;
6257
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6258
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6259
         break;
6260
    case OPC_J ... OPC_JAL: /* Jump */
6261
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6262
         gen_compute_branch(ctx, op, rs, rt, offset);
6263
         return;
6264
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6265
    case OPC_BEQL ... OPC_BGTZL:
6266
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6267
         return;
6268
    case OPC_LB ... OPC_LWR: /* Load and stores */
6269
    case OPC_SB ... OPC_SW:
6270
    case OPC_SWR:
6271
    case OPC_LL:
6272
    case OPC_SC:
6273
         gen_ldst(ctx, op, rt, rs, imm);
6274
         break;
6275
    case OPC_CACHE:
6276
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6277
        /* Treat as NOP. */
6278
        break;
6279
    case OPC_PREF:
6280
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6281
        /* Treat as NOP. */
6282
        break;
6283

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

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

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

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

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

    
6469
static inline int
6470
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6471
                                int search_pc)
6472
{
6473
    DisasContext ctx;
6474
    target_ulong pc_start;
6475
    uint16_t *gen_opc_end;
6476
    int j, lj = -1;
6477

    
6478
    if (search_pc && loglevel)
6479
        fprintf (logfile, "search pc %d\n", search_pc);
6480

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

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

    
6540
        if (env->singlestep_enabled)
6541
            break;
6542

    
6543
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6544
            break;
6545

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

    
6603
    return 0;
6604
}
6605

    
6606
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6607
{
6608
    return gen_intermediate_code_internal(env, tb, 0);
6609
}
6610

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

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

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

    
6639

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

    
6651
#undef printfpr
6652
}
6653

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

    
6663
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6664
/* Debug help: The architecture requires 32bit code to maintain proper
6665
   sign-extened values on 64bit machines.  */
6666

    
6667
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6668

    
6669
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6670
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6671
                     int flags)
6672
{
6673
    int i;
6674

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

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

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

    
6696
void cpu_dump_state (CPUState *env, FILE *f,
6697
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6698
                     int flags)
6699
{
6700
    int i;
6701

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

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

    
6723
CPUMIPSState *cpu_mips_init (void)
6724
{
6725
    CPUMIPSState *env;
6726

    
6727
    env = qemu_mallocz(sizeof(CPUMIPSState));
6728
    if (!env)
6729
        return NULL;
6730
    cpu_exec_init(env);
6731
    cpu_reset(env);
6732
    return env;
6733
}
6734

    
6735
void cpu_reset (CPUMIPSState *env)
6736
{
6737
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6738

    
6739
    tlb_flush(env, 1);
6740

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

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

    
6779
#include "translate_init.c"