Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 3b46e624

History | View | Annotate | Download (180.6 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL,
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 is not a MIPS R2 (or higher) CPU. */
765
static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
766
{
767
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) < (1 << CP0C0_AR))
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
#if defined(CONFIG_USER_ONLY)
780
#define op_ldst(name)        gen_op_##name##_raw()
781
#define OP_LD_TABLE(width)
782
#define OP_ST_TABLE(width)
783
#else
784
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
785
#define OP_LD_TABLE(width)                                                    \
786
static GenOpFunc *gen_op_l##width[] = {                                       \
787
    &gen_op_l##width##_user,                                                  \
788
    &gen_op_l##width##_kernel,                                                \
789
}
790
#define OP_ST_TABLE(width)                                                    \
791
static GenOpFunc *gen_op_s##width[] = {                                       \
792
    &gen_op_s##width##_user,                                                  \
793
    &gen_op_s##width##_kernel,                                                \
794
}
795
#endif
796

    
797
#ifdef TARGET_MIPS64
798
OP_LD_TABLE(d);
799
OP_LD_TABLE(dl);
800
OP_LD_TABLE(dr);
801
OP_ST_TABLE(d);
802
OP_ST_TABLE(dl);
803
OP_ST_TABLE(dr);
804
OP_LD_TABLE(ld);
805
OP_ST_TABLE(cd);
806
OP_LD_TABLE(wu);
807
#endif
808
OP_LD_TABLE(w);
809
OP_LD_TABLE(wl);
810
OP_LD_TABLE(wr);
811
OP_ST_TABLE(w);
812
OP_ST_TABLE(wl);
813
OP_ST_TABLE(wr);
814
OP_LD_TABLE(h);
815
OP_LD_TABLE(hu);
816
OP_ST_TABLE(h);
817
OP_LD_TABLE(b);
818
OP_LD_TABLE(bu);
819
OP_ST_TABLE(b);
820
OP_LD_TABLE(l);
821
OP_ST_TABLE(c);
822
OP_LD_TABLE(wc1);
823
OP_ST_TABLE(wc1);
824
OP_LD_TABLE(dc1);
825
OP_ST_TABLE(dc1);
826
OP_LD_TABLE(uxc1);
827
OP_ST_TABLE(uxc1);
828

    
829
/* Load and store */
830
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
831
                      int base, int16_t offset)
832
{
833
    const char *opn = "ldst";
834

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

    
980
/* Load and store */
981
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
982
                      int base, int16_t offset)
983
{
984
    const char *opn = "flt_ldst";
985

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

    
1026
/* Arithmetic with immediate operand */
1027
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1028
                           int rs, int16_t imm)
1029
{
1030
    target_ulong uimm;
1031
    const char *opn = "imm arith";
1032

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

    
1203
/* Arithmetic */
1204
static void gen_arith (DisasContext *ctx, uint32_t opc,
1205
                       int rd, int rs, int rt)
1206
{
1207
    const char *opn = "arith";
1208

    
1209
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1210
       && opc != OPC_DADD && opc != OPC_DSUB) {
1211
        /* If no destination, treat it as a NOP.
1212
           For add & sub, we must generate the overflow exception when needed. */
1213
        MIPS_DEBUG("NOP");
1214
        return;
1215
    }
1216
    GEN_LOAD_REG_TN(T0, rs);
1217
    GEN_LOAD_REG_TN(T1, rt);
1218
    switch (opc) {
1219
    case OPC_ADD:
1220
        save_cpu_state(ctx, 1);
1221
        gen_op_addo();
1222
        opn = "add";
1223
        break;
1224
    case OPC_ADDU:
1225
        gen_op_add();
1226
        opn = "addu";
1227
        break;
1228
    case OPC_SUB:
1229
        save_cpu_state(ctx, 1);
1230
        gen_op_subo();
1231
        opn = "sub";
1232
        break;
1233
    case OPC_SUBU:
1234
        gen_op_sub();
1235
        opn = "subu";
1236
        break;
1237
#ifdef TARGET_MIPS64
1238
    case OPC_DADD:
1239
        save_cpu_state(ctx, 1);
1240
        gen_op_daddo();
1241
        opn = "dadd";
1242
        break;
1243
    case OPC_DADDU:
1244
        gen_op_dadd();
1245
        opn = "daddu";
1246
        break;
1247
    case OPC_DSUB:
1248
        save_cpu_state(ctx, 1);
1249
        gen_op_dsubo();
1250
        opn = "dsub";
1251
        break;
1252
    case OPC_DSUBU:
1253
        gen_op_dsub();
1254
        opn = "dsubu";
1255
        break;
1256
#endif
1257
    case OPC_SLT:
1258
        gen_op_lt();
1259
        opn = "slt";
1260
        break;
1261
    case OPC_SLTU:
1262
        gen_op_ltu();
1263
        opn = "sltu";
1264
        break;
1265
    case OPC_AND:
1266
        gen_op_and();
1267
        opn = "and";
1268
        break;
1269
    case OPC_NOR:
1270
        gen_op_nor();
1271
        opn = "nor";
1272
        break;
1273
    case OPC_OR:
1274
        gen_op_or();
1275
        opn = "or";
1276
        break;
1277
    case OPC_XOR:
1278
        gen_op_xor();
1279
        opn = "xor";
1280
        break;
1281
    case OPC_MUL:
1282
        gen_op_mul();
1283
        opn = "mul";
1284
        break;
1285
    case OPC_MOVN:
1286
        gen_op_movn(rd);
1287
        opn = "movn";
1288
        goto print;
1289
    case OPC_MOVZ:
1290
        gen_op_movz(rd);
1291
        opn = "movz";
1292
        goto print;
1293
    case OPC_SLLV:
1294
        gen_op_sllv();
1295
        opn = "sllv";
1296
        break;
1297
    case OPC_SRAV:
1298
        gen_op_srav();
1299
        opn = "srav";
1300
        break;
1301
    case OPC_SRLV:
1302
        switch ((ctx->opcode >> 6) & 0x1f) {
1303
        case 0:
1304
            gen_op_srlv();
1305
            opn = "srlv";
1306
            break;
1307
        case 1:
1308
            gen_op_rotrv();
1309
            opn = "rotrv";
1310
            break;
1311
        default:
1312
            MIPS_INVAL("invalid srlv flag");
1313
            generate_exception(ctx, EXCP_RI);
1314
            break;
1315
        }
1316
        break;
1317
#ifdef TARGET_MIPS64
1318
    case OPC_DSLLV:
1319
        gen_op_dsllv();
1320
        opn = "dsllv";
1321
        break;
1322
    case OPC_DSRAV:
1323
        gen_op_dsrav();
1324
        opn = "dsrav";
1325
        break;
1326
    case OPC_DSRLV:
1327
        switch ((ctx->opcode >> 6) & 0x1f) {
1328
        case 0:
1329
            gen_op_dsrlv();
1330
            opn = "dsrlv";
1331
            break;
1332
        case 1:
1333
            gen_op_drotrv();
1334
            opn = "drotrv";
1335
            break;
1336
        default:
1337
            MIPS_INVAL("invalid dsrlv flag");
1338
            generate_exception(ctx, EXCP_RI);
1339
            break;
1340
        }
1341
        break;
1342
#endif
1343
    default:
1344
        MIPS_INVAL(opn);
1345
        generate_exception(ctx, EXCP_RI);
1346
        return;
1347
    }
1348
    GEN_STORE_TN_REG(rd, T0);
1349
 print:
1350
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1351
}
1352

    
1353
/* Arithmetic on HI/LO registers */
1354
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1355
{
1356
    const char *opn = "hilo";
1357

    
1358
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1359
        /* Treat as NOP. */
1360
        MIPS_DEBUG("NOP");
1361
        return;
1362
    }
1363
    switch (opc) {
1364
    case OPC_MFHI:
1365
        gen_op_load_HI(0);
1366
        GEN_STORE_TN_REG(reg, T0);
1367
        opn = "mfhi";
1368
        break;
1369
    case OPC_MFLO:
1370
        gen_op_load_LO(0);
1371
        GEN_STORE_TN_REG(reg, T0);
1372
        opn = "mflo";
1373
        break;
1374
    case OPC_MTHI:
1375
        GEN_LOAD_REG_TN(T0, reg);
1376
        gen_op_store_HI(0);
1377
        opn = "mthi";
1378
        break;
1379
    case OPC_MTLO:
1380
        GEN_LOAD_REG_TN(T0, reg);
1381
        gen_op_store_LO(0);
1382
        opn = "mtlo";
1383
        break;
1384
    default:
1385
        MIPS_INVAL(opn);
1386
        generate_exception(ctx, EXCP_RI);
1387
        return;
1388
    }
1389
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1390
}
1391

    
1392
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1393
                        int rs, int rt)
1394
{
1395
    const char *opn = "mul/div";
1396

    
1397
    GEN_LOAD_REG_TN(T0, rs);
1398
    GEN_LOAD_REG_TN(T1, rt);
1399
    switch (opc) {
1400
    case OPC_DIV:
1401
        gen_op_div();
1402
        opn = "div";
1403
        break;
1404
    case OPC_DIVU:
1405
        gen_op_divu();
1406
        opn = "divu";
1407
        break;
1408
    case OPC_MULT:
1409
        gen_op_mult();
1410
        opn = "mult";
1411
        break;
1412
    case OPC_MULTU:
1413
        gen_op_multu();
1414
        opn = "multu";
1415
        break;
1416
#ifdef TARGET_MIPS64
1417
    case OPC_DDIV:
1418
        gen_op_ddiv();
1419
        opn = "ddiv";
1420
        break;
1421
    case OPC_DDIVU:
1422
        gen_op_ddivu();
1423
        opn = "ddivu";
1424
        break;
1425
    case OPC_DMULT:
1426
        gen_op_dmult();
1427
        opn = "dmult";
1428
        break;
1429
    case OPC_DMULTU:
1430
        gen_op_dmultu();
1431
        opn = "dmultu";
1432
        break;
1433
#endif
1434
    case OPC_MADD:
1435
        gen_op_madd();
1436
        opn = "madd";
1437
        break;
1438
    case OPC_MADDU:
1439
        gen_op_maddu();
1440
        opn = "maddu";
1441
        break;
1442
    case OPC_MSUB:
1443
        gen_op_msub();
1444
        opn = "msub";
1445
        break;
1446
    case OPC_MSUBU:
1447
        gen_op_msubu();
1448
        opn = "msubu";
1449
        break;
1450
    default:
1451
        MIPS_INVAL(opn);
1452
        generate_exception(ctx, EXCP_RI);
1453
        return;
1454
    }
1455
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1456
}
1457

    
1458
static void gen_cl (DisasContext *ctx, uint32_t opc,
1459
                    int rd, int rs)
1460
{
1461
    const char *opn = "CLx";
1462
    if (rd == 0) {
1463
        /* Treat as NOP. */
1464
        MIPS_DEBUG("NOP");
1465
        return;
1466
    }
1467
    GEN_LOAD_REG_TN(T0, rs);
1468
    switch (opc) {
1469
    case OPC_CLO:
1470
        gen_op_clo();
1471
        opn = "clo";
1472
        break;
1473
    case OPC_CLZ:
1474
        gen_op_clz();
1475
        opn = "clz";
1476
        break;
1477
#ifdef TARGET_MIPS64
1478
    case OPC_DCLO:
1479
        gen_op_dclo();
1480
        opn = "dclo";
1481
        break;
1482
    case OPC_DCLZ:
1483
        gen_op_dclz();
1484
        opn = "dclz";
1485
        break;
1486
#endif
1487
    default:
1488
        MIPS_INVAL(opn);
1489
        generate_exception(ctx, EXCP_RI);
1490
        return;
1491
    }
1492
    gen_op_store_T0_gpr(rd);
1493
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1494
}
1495

    
1496
/* Traps */
1497
static void gen_trap (DisasContext *ctx, uint32_t opc,
1498
                      int rs, int rt, int16_t imm)
1499
{
1500
    int cond;
1501

    
1502
    cond = 0;
1503
    /* Load needed operands */
1504
    switch (opc) {
1505
    case OPC_TEQ:
1506
    case OPC_TGE:
1507
    case OPC_TGEU:
1508
    case OPC_TLT:
1509
    case OPC_TLTU:
1510
    case OPC_TNE:
1511
        /* Compare two registers */
1512
        if (rs != rt) {
1513
            GEN_LOAD_REG_TN(T0, rs);
1514
            GEN_LOAD_REG_TN(T1, rt);
1515
            cond = 1;
1516
        }
1517
        break;
1518
    case OPC_TEQI:
1519
    case OPC_TGEI:
1520
    case OPC_TGEIU:
1521
    case OPC_TLTI:
1522
    case OPC_TLTIU:
1523
    case OPC_TNEI:
1524
        /* Compare register to immediate */
1525
        if (rs != 0 || imm != 0) {
1526
            GEN_LOAD_REG_TN(T0, rs);
1527
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1528
            cond = 1;
1529
        }
1530
        break;
1531
    }
1532
    if (cond == 0) {
1533
        switch (opc) {
1534
        case OPC_TEQ:   /* rs == rs */
1535
        case OPC_TEQI:  /* r0 == 0  */
1536
        case OPC_TGE:   /* rs >= rs */
1537
        case OPC_TGEI:  /* r0 >= 0  */
1538
        case OPC_TGEU:  /* rs >= rs unsigned */
1539
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1540
            /* Always trap */
1541
            gen_op_set_T0(1);
1542
            break;
1543
        case OPC_TLT:   /* rs < rs           */
1544
        case OPC_TLTI:  /* r0 < 0            */
1545
        case OPC_TLTU:  /* rs < rs unsigned  */
1546
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1547
        case OPC_TNE:   /* rs != rs          */
1548
        case OPC_TNEI:  /* r0 != 0           */
1549
            /* Never trap: treat as NOP. */
1550
            return;
1551
        default:
1552
            MIPS_INVAL("trap");
1553
            generate_exception(ctx, EXCP_RI);
1554
            return;
1555
        }
1556
    } else {
1557
        switch (opc) {
1558
        case OPC_TEQ:
1559
        case OPC_TEQI:
1560
            gen_op_eq();
1561
            break;
1562
        case OPC_TGE:
1563
        case OPC_TGEI:
1564
            gen_op_ge();
1565
            break;
1566
        case OPC_TGEU:
1567
        case OPC_TGEIU:
1568
            gen_op_geu();
1569
            break;
1570
        case OPC_TLT:
1571
        case OPC_TLTI:
1572
            gen_op_lt();
1573
            break;
1574
        case OPC_TLTU:
1575
        case OPC_TLTIU:
1576
            gen_op_ltu();
1577
            break;
1578
        case OPC_TNE:
1579
        case OPC_TNEI:
1580
            gen_op_ne();
1581
            break;
1582
        default:
1583
            MIPS_INVAL("trap");
1584
            generate_exception(ctx, EXCP_RI);
1585
            return;
1586
        }
1587
    }
1588
    save_cpu_state(ctx, 1);
1589
    gen_op_trap();
1590
    ctx->bstate = BS_STOP;
1591
}
1592

    
1593
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1594
{
1595
    TranslationBlock *tb;
1596
    tb = ctx->tb;
1597
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1598
        if (n == 0)
1599
            gen_op_goto_tb0(TBPARAM(tb));
1600
        else
1601
            gen_op_goto_tb1(TBPARAM(tb));
1602
        gen_save_pc(dest);
1603
        gen_op_set_T0((long)tb + n);
1604
    } else {
1605
        gen_save_pc(dest);
1606
        gen_op_reset_T0();
1607
    }
1608
    gen_op_exit_tb();
1609
}
1610

    
1611
/* Branches (before delay slot) */
1612
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1613
                                int rs, int rt, int32_t offset)
1614
{
1615
    target_ulong btarget = -1;
1616
    int blink = 0;
1617
    int bcond = 0;
1618

    
1619
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1620
#ifdef MIPS_DEBUG_DISAS
1621
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1622
            fprintf(logfile,
1623
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1624
                    ctx->pc);
1625
        }
1626
#endif
1627
        generate_exception(ctx, EXCP_RI);
1628
        return;
1629
    }
1630

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

    
1844
    ctx->btarget = btarget;
1845
    if (blink > 0) {
1846
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1847
        gen_op_store_T0_gpr(blink);
1848
    }
1849
}
1850

    
1851
/* special3 bitfield operations */
1852
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1853
                       int rs, int lsb, int msb)
1854
{
1855
    GEN_LOAD_REG_TN(T1, rs);
1856
    switch (opc) {
1857
    case OPC_EXT:
1858
        if (lsb + msb > 31)
1859
            goto fail;
1860
        gen_op_ext(lsb, msb + 1);
1861
        break;
1862
    case OPC_DEXTM:
1863
        if (lsb + msb > 63)
1864
            goto fail;
1865
        gen_op_ext(lsb, msb + 1 + 32);
1866
        break;
1867
    case OPC_DEXTU:
1868
        if (lsb + msb > 63)
1869
            goto fail;
1870
        gen_op_ext(lsb + 32, msb + 1);
1871
        break;
1872
    case OPC_DEXT:
1873
        gen_op_ext(lsb, msb + 1);
1874
        break;
1875
    case OPC_INS:
1876
        if (lsb > msb)
1877
            goto fail;
1878
        GEN_LOAD_REG_TN(T0, rt);
1879
        gen_op_ins(lsb, msb - lsb + 1);
1880
        break;
1881
    case OPC_DINSM:
1882
        if (lsb > msb)
1883
            goto fail;
1884
        GEN_LOAD_REG_TN(T0, rt);
1885
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1886
        break;
1887
    case OPC_DINSU:
1888
        if (lsb > msb)
1889
            goto fail;
1890
        GEN_LOAD_REG_TN(T0, rt);
1891
        gen_op_ins(lsb + 32, msb - lsb + 1);
1892
        break;
1893
    case OPC_DINS:
1894
        if (lsb > msb)
1895
            goto fail;
1896
        GEN_LOAD_REG_TN(T0, rt);
1897
        gen_op_ins(lsb, msb - lsb + 1);
1898
        break;
1899
    default:
1900
fail:
1901
        MIPS_INVAL("bitops");
1902
        generate_exception(ctx, EXCP_RI);
1903
        return;
1904
    }
1905
    GEN_STORE_TN_REG(rt, T0);
1906
}
1907

    
1908
/* CP0 (MMU and control) */
1909
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1910
{
1911
    const char *rn = "invalid";
1912

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

    
2460
die:
2461
#if defined MIPS_DEBUG_DISAS
2462
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2463
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2464
                rn, reg, sel);
2465
    }
2466
#endif
2467
    generate_exception(ctx, EXCP_RI);
2468
}
2469

    
2470
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2471
{
2472
    const char *rn = "invalid";
2473

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

    
3052
die:
3053
#if defined MIPS_DEBUG_DISAS
3054
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3055
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3056
                rn, reg, sel);
3057
    }
3058
#endif
3059
    generate_exception(ctx, EXCP_RI);
3060
}
3061

    
3062
#ifdef TARGET_MIPS64
3063
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3064
{
3065
    const char *rn = "invalid";
3066

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

    
3601
die:
3602
#if defined MIPS_DEBUG_DISAS
3603
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3604
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3605
                rn, reg, sel);
3606
    }
3607
#endif
3608
    generate_exception(ctx, EXCP_RI);
3609
}
3610

    
3611
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3612
{
3613
    const char *rn = "invalid";
3614

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

    
4178
die:
4179
#if defined MIPS_DEBUG_DISAS
4180
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4181
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4182
                rn, reg, sel);
4183
    }
4184
#endif
4185
    generate_exception(ctx, EXCP_RI);
4186
}
4187
#endif /* TARGET_MIPS64 */
4188

    
4189
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4190
                     int u, int sel, int h)
4191
{
4192
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4193

    
4194
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4195
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4196
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4197
        gen_op_set_T0(-1);
4198
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4199
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4200
        gen_op_set_T0(-1);
4201
    else if (u == 0) {
4202
        switch (rt) {
4203
        case 2:
4204
            switch (sel) {
4205
            case 1:
4206
                gen_op_mftc0_tcstatus();
4207
                break;
4208
            case 2:
4209
                gen_op_mftc0_tcbind();
4210
                break;
4211
            case 3:
4212
                gen_op_mftc0_tcrestart();
4213
                break;
4214
            case 4:
4215
                gen_op_mftc0_tchalt();
4216
                break;
4217
            case 5:
4218
                gen_op_mftc0_tccontext();
4219
                break;
4220
            case 6:
4221
                gen_op_mftc0_tcschedule();
4222
                break;
4223
            case 7:
4224
                gen_op_mftc0_tcschefback();
4225
                break;
4226
            default:
4227
                gen_mfc0(env, ctx, rt, sel);
4228
                break;
4229
            }
4230
            break;
4231
        case 10:
4232
            switch (sel) {
4233
            case 0:
4234
                gen_op_mftc0_entryhi();
4235
                break;
4236
            default:
4237
                gen_mfc0(env, ctx, rt, sel);
4238
                break;
4239
            }
4240
        case 12:
4241
            switch (sel) {
4242
            case 0:
4243
                gen_op_mftc0_status();
4244
                break;
4245
            default:
4246
                gen_mfc0(env, ctx, rt, sel);
4247
                break;
4248
            }
4249
        case 23:
4250
            switch (sel) {
4251
            case 0:
4252
                gen_op_mftc0_debug();
4253
                break;
4254
            default:
4255
                gen_mfc0(env, ctx, rt, sel);
4256
                break;
4257
            }
4258
            break;
4259
        default:
4260
            gen_mfc0(env, ctx, rt, sel);
4261
        }
4262
    } else switch (sel) {
4263
    /* GPR registers. */
4264
    case 0:
4265
        gen_op_mftgpr(rt);
4266
        break;
4267
    /* Auxiliary CPU registers */
4268
    case 1:
4269
        switch (rt) {
4270
        case 0:
4271
            gen_op_mftlo(0);
4272
            break;
4273
        case 1:
4274
            gen_op_mfthi(0);
4275
            break;
4276
        case 2:
4277
            gen_op_mftacx(0);
4278
            break;
4279
        case 4:
4280
            gen_op_mftlo(1);
4281
            break;
4282
        case 5:
4283
            gen_op_mfthi(1);
4284
            break;
4285
        case 6:
4286
            gen_op_mftacx(1);
4287
            break;
4288
        case 8:
4289
            gen_op_mftlo(2);
4290
            break;
4291
        case 9:
4292
            gen_op_mfthi(2);
4293
            break;
4294
        case 10:
4295
            gen_op_mftacx(2);
4296
            break;
4297
        case 12:
4298
            gen_op_mftlo(3);
4299
            break;
4300
        case 13:
4301
            gen_op_mfthi(3);
4302
            break;
4303
        case 14:
4304
            gen_op_mftacx(3);
4305
            break;
4306
        case 16:
4307
            gen_op_mftdsp();
4308
            break;
4309
        default:
4310
            goto die;
4311
        }
4312
        break;
4313
    /* Floating point (COP1). */
4314
    case 2:
4315
        /* XXX: For now we support only a single FPU context. */
4316
        if (h == 0) {
4317
            GEN_LOAD_FREG_FTN(WT0, rt);
4318
            gen_op_mfc1();
4319
        } else {
4320
            GEN_LOAD_FREG_FTN(WTH0, rt);
4321
            gen_op_mfhc1();
4322
        }
4323
        break;
4324
    case 3:
4325
        /* XXX: For now we support only a single FPU context. */
4326
        gen_op_cfc1(rt);
4327
        break;
4328
    /* COP2: Not implemented. */
4329
    case 4:
4330
    case 5:
4331
        /* fall through */
4332
    default:
4333
        goto die;
4334
    }
4335
#if defined MIPS_DEBUG_DISAS
4336
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4337
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4338
                rt, u, sel, h);
4339
    }
4340
#endif
4341
    return;
4342

    
4343
die:
4344
#if defined MIPS_DEBUG_DISAS
4345
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4346
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4347
                rt, u, sel, h);
4348
    }
4349
#endif
4350
    generate_exception(ctx, EXCP_RI);
4351
}
4352

    
4353
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4354
                     int u, int sel, int h)
4355
{
4356
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4357

    
4358
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4359
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4360
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4361
        /* NOP */ ;
4362
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4363
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4364
        /* NOP */ ;
4365
    else if (u == 0) {
4366
        switch (rd) {
4367
        case 2:
4368
            switch (sel) {
4369
            case 1:
4370
                gen_op_mttc0_tcstatus();
4371
                break;
4372
            case 2:
4373
                gen_op_mttc0_tcbind();
4374
                break;
4375
            case 3:
4376
                gen_op_mttc0_tcrestart();
4377
                break;
4378
            case 4:
4379
                gen_op_mttc0_tchalt();
4380
                break;
4381
            case 5:
4382
                gen_op_mttc0_tccontext();
4383
                break;
4384
            case 6:
4385
                gen_op_mttc0_tcschedule();
4386
                break;
4387
            case 7:
4388
                gen_op_mttc0_tcschefback();
4389
                break;
4390
            default:
4391
                gen_mtc0(env, ctx, rd, sel);
4392
                break;
4393
            }
4394
            break;
4395
        case 10:
4396
            switch (sel) {
4397
            case 0:
4398
                gen_op_mttc0_entryhi();
4399
                break;
4400
            default:
4401
                gen_mtc0(env, ctx, rd, sel);
4402
                break;
4403
            }
4404
        case 12:
4405
            switch (sel) {
4406
            case 0:
4407
                gen_op_mttc0_status();
4408
                break;
4409
            default:
4410
                gen_mtc0(env, ctx, rd, sel);
4411
                break;
4412
            }
4413
        case 23:
4414
            switch (sel) {
4415
            case 0:
4416
                gen_op_mttc0_debug();
4417
                break;
4418
            default:
4419
                gen_mtc0(env, ctx, rd, sel);
4420
                break;
4421
            }
4422
            break;
4423
        default:
4424
            gen_mtc0(env, ctx, rd, sel);
4425
        }
4426
    } else switch (sel) {
4427
    /* GPR registers. */
4428
    case 0:
4429
        gen_op_mttgpr(rd);
4430
        break;
4431
    /* Auxiliary CPU registers */
4432
    case 1:
4433
        switch (rd) {
4434
        case 0:
4435
            gen_op_mttlo(0);
4436
            break;
4437
        case 1:
4438
            gen_op_mtthi(0);
4439
            break;
4440
        case 2:
4441
            gen_op_mttacx(0);
4442
            break;
4443
        case 4:
4444
            gen_op_mttlo(1);
4445
            break;
4446
        case 5:
4447
            gen_op_mtthi(1);
4448
            break;
4449
        case 6:
4450
            gen_op_mttacx(1);
4451
            break;
4452
        case 8:
4453
            gen_op_mttlo(2);
4454
            break;
4455
        case 9:
4456
            gen_op_mtthi(2);
4457
            break;
4458
        case 10:
4459
            gen_op_mttacx(2);
4460
            break;
4461
        case 12:
4462
            gen_op_mttlo(3);
4463
            break;
4464
        case 13:
4465
            gen_op_mtthi(3);
4466
            break;
4467
        case 14:
4468
            gen_op_mttacx(3);
4469
            break;
4470
        case 16:
4471
            gen_op_mttdsp();
4472
            break;
4473
        default:
4474
            goto die;
4475
        }
4476
        break;
4477
    /* Floating point (COP1). */
4478
    case 2:
4479
        /* XXX: For now we support only a single FPU context. */
4480
        if (h == 0) {
4481
            gen_op_mtc1();
4482
            GEN_STORE_FTN_FREG(rd, WT0);
4483
        } else {
4484
            gen_op_mthc1();
4485
            GEN_STORE_FTN_FREG(rd, WTH0);
4486
        }
4487
        break;
4488
    case 3:
4489
        /* XXX: For now we support only a single FPU context. */
4490
        gen_op_ctc1(rd);
4491
        break;
4492
    /* COP2: Not implemented. */
4493
    case 4:
4494
    case 5:
4495
        /* fall through */
4496
    default:
4497
        goto die;
4498
    }
4499
#if defined MIPS_DEBUG_DISAS
4500
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4501
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4502
                rd, u, sel, h);
4503
    }
4504
#endif
4505
    return;
4506

    
4507
die:
4508
#if defined MIPS_DEBUG_DISAS
4509
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4510
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4511
                rd, u, sel, h);
4512
    }
4513
#endif
4514
    generate_exception(ctx, EXCP_RI);
4515
}
4516

    
4517
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4518
{
4519
    const char *opn = "ldst";
4520

    
4521
    switch (opc) {
4522
    case OPC_MFC0:
4523
        if (rt == 0) {
4524
            /* Treat as NOP. */
4525
            return;
4526
        }
4527
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4528
        gen_op_store_T0_gpr(rt);
4529
        opn = "mfc0";
4530
        break;
4531
    case OPC_MTC0:
4532
        GEN_LOAD_REG_TN(T0, rt);
4533
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4534
        opn = "mtc0";
4535
        break;
4536
#ifdef TARGET_MIPS64
4537
    case OPC_DMFC0:
4538
        if (!(ctx->hflags & MIPS_HFLAG_64))
4539
            generate_exception(ctx, EXCP_RI);
4540
        if (rt == 0) {
4541
            /* Treat as NOP. */
4542
            return;
4543
        }
4544
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4545
        gen_op_store_T0_gpr(rt);
4546
        opn = "dmfc0";
4547
        break;
4548
    case OPC_DMTC0:
4549
        if (!(ctx->hflags & MIPS_HFLAG_64))
4550
            generate_exception(ctx, EXCP_RI);
4551
        GEN_LOAD_REG_TN(T0, rt);
4552
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4553
        opn = "dmtc0";
4554
        break;
4555
#endif
4556
    case OPC_MFTR:
4557
        check_mips_mt(env, ctx);
4558
        if (rd == 0) {
4559
            /* Treat as NOP. */
4560
            return;
4561
        }
4562
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4563
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4564
        gen_op_store_T0_gpr(rd);
4565
        opn = "mftr";
4566
        break;
4567
    case OPC_MTTR:
4568
        check_mips_mt(env, ctx);
4569
        GEN_LOAD_REG_TN(T0, rt);
4570
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4571
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4572
        opn = "mttr";
4573
        break;
4574
    case OPC_TLBWI:
4575
        opn = "tlbwi";
4576
        if (!env->tlb->do_tlbwi)
4577
            goto die;
4578
        gen_op_tlbwi();
4579
        break;
4580
    case OPC_TLBWR:
4581
        opn = "tlbwr";
4582
        if (!env->tlb->do_tlbwr)
4583
            goto die;
4584
        gen_op_tlbwr();
4585
        break;
4586
    case OPC_TLBP:
4587
        opn = "tlbp";
4588
        if (!env->tlb->do_tlbp)
4589
            goto die;
4590
        gen_op_tlbp();
4591
        break;
4592
    case OPC_TLBR:
4593
        opn = "tlbr";
4594
        if (!env->tlb->do_tlbr)
4595
            goto die;
4596
        gen_op_tlbr();
4597
        break;
4598
    case OPC_ERET:
4599
        opn = "eret";
4600
        gen_op_eret();
4601
        ctx->bstate = BS_EXCP;
4602
        break;
4603
    case OPC_DERET:
4604
        opn = "deret";
4605
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4606
            MIPS_INVAL(opn);
4607
            generate_exception(ctx, EXCP_RI);
4608
        } else {
4609
            gen_op_deret();
4610
            ctx->bstate = BS_EXCP;
4611
        }
4612
        break;
4613
    case OPC_WAIT:
4614
        opn = "wait";
4615
        /* If we get an exception, we want to restart at next instruction */
4616
        ctx->pc += 4;
4617
        save_cpu_state(ctx, 1);
4618
        ctx->pc -= 4;
4619
        gen_op_wait();
4620
        ctx->bstate = BS_EXCP;
4621
        break;
4622
    default:
4623
 die:
4624
        MIPS_INVAL(opn);
4625
        generate_exception(ctx, EXCP_RI);
4626
        return;
4627
    }
4628
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4629
}
4630

    
4631
/* CP1 Branches (before delay slot) */
4632
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4633
                                 int32_t cc, int32_t offset)
4634
{
4635
    target_ulong btarget;
4636
    const char *opn = "cp1 cond branch";
4637

    
4638
    btarget = ctx->pc + 4 + offset;
4639

    
4640
    switch (op) {
4641
    case OPC_BC1F:
4642
        gen_op_bc1f(cc);
4643
        opn = "bc1f";
4644
        goto not_likely;
4645
    case OPC_BC1FL:
4646
        gen_op_bc1f(cc);
4647
        opn = "bc1fl";
4648
        goto likely;
4649
    case OPC_BC1T:
4650
        gen_op_bc1t(cc);
4651
        opn = "bc1t";
4652
        goto not_likely;
4653
    case OPC_BC1TL:
4654
        gen_op_bc1t(cc);
4655
        opn = "bc1tl";
4656
    likely:
4657
        ctx->hflags |= MIPS_HFLAG_BL;
4658
        gen_op_set_bcond();
4659
        gen_op_save_bcond();
4660
        break;
4661
    case OPC_BC1FANY2:
4662
        gen_op_bc1any2f(cc);
4663
        opn = "bc1any2f";
4664
        goto not_likely;
4665
    case OPC_BC1TANY2:
4666
        gen_op_bc1any2t(cc);
4667
        opn = "bc1any2t";
4668
        goto not_likely;
4669
    case OPC_BC1FANY4:
4670
        gen_op_bc1any4f(cc);
4671
        opn = "bc1any4f";
4672
        goto not_likely;
4673
    case OPC_BC1TANY4:
4674
        gen_op_bc1any4t(cc);
4675
        opn = "bc1any4t";
4676
    not_likely:
4677
        ctx->hflags |= MIPS_HFLAG_BC;
4678
        gen_op_set_bcond();
4679
        break;
4680
    default:
4681
        MIPS_INVAL(opn);
4682
        generate_exception (ctx, EXCP_RI);
4683
        return;
4684
    }
4685
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4686
               ctx->hflags, btarget);
4687
    ctx->btarget = btarget;
4688
}
4689

    
4690
/* Coprocessor 1 (FPU) */
4691

    
4692
#define FOP(func, fmt) (((fmt) << 21) | (func))
4693

    
4694
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4695
{
4696
    const char *opn = "cp1 move";
4697

    
4698
    switch (opc) {
4699
    case OPC_MFC1:
4700
        GEN_LOAD_FREG_FTN(WT0, fs);
4701
        gen_op_mfc1();
4702
        GEN_STORE_TN_REG(rt, T0);
4703
        opn = "mfc1";
4704
        break;
4705
    case OPC_MTC1:
4706
        GEN_LOAD_REG_TN(T0, rt);
4707
        gen_op_mtc1();
4708
        GEN_STORE_FTN_FREG(fs, WT0);
4709
        opn = "mtc1";
4710
        break;
4711
    case OPC_CFC1:
4712
        gen_op_cfc1(fs);
4713
        GEN_STORE_TN_REG(rt, T0);
4714
        opn = "cfc1";
4715
        break;
4716
    case OPC_CTC1:
4717
        GEN_LOAD_REG_TN(T0, rt);
4718
        gen_op_ctc1(fs);
4719
        opn = "ctc1";
4720
        break;
4721
    case OPC_DMFC1:
4722
        GEN_LOAD_FREG_FTN(DT0, fs);
4723
        gen_op_dmfc1();
4724
        GEN_STORE_TN_REG(rt, T0);
4725
        opn = "dmfc1";
4726
        break;
4727
    case OPC_DMTC1:
4728
        GEN_LOAD_REG_TN(T0, rt);
4729
        gen_op_dmtc1();
4730
        GEN_STORE_FTN_FREG(fs, DT0);
4731
        opn = "dmtc1";
4732
        break;
4733
    case OPC_MFHC1:
4734
        GEN_LOAD_FREG_FTN(WTH0, fs);
4735
        gen_op_mfhc1();
4736
        GEN_STORE_TN_REG(rt, T0);
4737
        opn = "mfhc1";
4738
        break;
4739
    case OPC_MTHC1:
4740
        GEN_LOAD_REG_TN(T0, rt);
4741
        gen_op_mthc1();
4742
        GEN_STORE_FTN_FREG(fs, WTH0);
4743
        opn = "mthc1";
4744
        break;
4745
    default:
4746
        MIPS_INVAL(opn);
4747
        generate_exception (ctx, EXCP_RI);
4748
        return;
4749
    }
4750
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4751
}
4752

    
4753
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4754
{
4755
    uint32_t ccbit;
4756

    
4757
    GEN_LOAD_REG_TN(T0, rd);
4758
    GEN_LOAD_REG_TN(T1, rs);
4759
    if (cc) {
4760
        ccbit = 1 << (24 + cc);
4761
    } else
4762
        ccbit = 1 << 23;
4763
    if (!tf)
4764
        gen_op_movf(ccbit);
4765
    else
4766
        gen_op_movt(ccbit);
4767
    GEN_STORE_TN_REG(rd, T0);
4768
}
4769

    
4770
#define GEN_MOVCF(fmt)                                                \
4771
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4772
{                                                                     \
4773
    uint32_t ccbit;                                                   \
4774
                                                                      \
4775
    if (cc) {                                                         \
4776
        ccbit = 1 << (24 + cc);                                       \
4777
    } else                                                            \
4778
        ccbit = 1 << 23;                                              \
4779
    if (!tf)                                                          \
4780
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4781
    else                                                              \
4782
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4783
}
4784
GEN_MOVCF(d);
4785
GEN_MOVCF(s);
4786
GEN_MOVCF(ps);
4787
#undef GEN_MOVCF
4788

    
4789
static void gen_farith (DisasContext *ctx, uint32_t op1,
4790
                        int ft, int fs, int fd, int cc)
4791
{
4792
    const char *opn = "farith";
4793
    const char *condnames[] = {
4794
            "c.f",
4795
            "c.un",
4796
            "c.eq",
4797
            "c.ueq",
4798
            "c.olt",
4799
            "c.ult",
4800
            "c.ole",
4801
            "c.ule",
4802
            "c.sf",
4803
            "c.ngle",
4804
            "c.seq",
4805
            "c.ngl",
4806
            "c.lt",
4807
            "c.nge",
4808
            "c.le",
4809
            "c.ngt",
4810
    };
4811
    const char *condnames_abs[] = {
4812
            "cabs.f",
4813
            "cabs.un",
4814
            "cabs.eq",
4815
            "cabs.ueq",
4816
            "cabs.olt",
4817
            "cabs.ult",
4818
            "cabs.ole",
4819
            "cabs.ule",
4820
            "cabs.sf",
4821
            "cabs.ngle",
4822
            "cabs.seq",
4823
            "cabs.ngl",
4824
            "cabs.lt",
4825
            "cabs.nge",
4826
            "cabs.le",
4827
            "cabs.ngt",
4828
    };
4829
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4830
    uint32_t func = ctx->opcode & 0x3f;
4831

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

    
5596
/* Coprocessor 3 (FPU) */
5597
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5598
                           int fd, int fs, int base, int index)
5599
{
5600
    const char *opn = "extended float load/store";
5601
    int store = 0;
5602

    
5603
    /* All of those work only on 64bit FPUs. */
5604
    check_cp1_64bitmode(ctx);
5605
    if (base == 0) {
5606
        if (index == 0)
5607
            gen_op_reset_T0();
5608
        else
5609
            GEN_LOAD_REG_TN(T0, index);
5610
    } else if (index == 0) {
5611
        GEN_LOAD_REG_TN(T0, base);
5612
    } else {
5613
        GEN_LOAD_REG_TN(T0, base);
5614
        GEN_LOAD_REG_TN(T1, index);
5615
        gen_op_addr_add();
5616
    }
5617
    /* Don't do NOP if destination is zero: we must perform the actual
5618
       memory access. */
5619
    switch (opc) {
5620
    case OPC_LWXC1:
5621
        op_ldst(lwc1);
5622
        GEN_STORE_FTN_FREG(fd, WT0);
5623
        opn = "lwxc1";
5624
        break;
5625
    case OPC_LDXC1:
5626
        op_ldst(ldc1);
5627
        GEN_STORE_FTN_FREG(fd, DT0);
5628
        opn = "ldxc1";
5629
        break;
5630
    case OPC_LUXC1:
5631
        op_ldst(luxc1);
5632
        GEN_STORE_FTN_FREG(fd, DT0);
5633
        opn = "luxc1";
5634
        break;
5635
    case OPC_SWXC1:
5636
        GEN_LOAD_FREG_FTN(WT0, fs);
5637
        op_ldst(swc1);
5638
        opn = "swxc1";
5639
        store = 1;
5640
        break;
5641
    case OPC_SDXC1:
5642
        GEN_LOAD_FREG_FTN(DT0, fs);
5643
        op_ldst(sdc1);
5644
        opn = "sdxc1";
5645
        store = 1;
5646
        break;
5647
    case OPC_SUXC1:
5648
        GEN_LOAD_FREG_FTN(DT0, fs);
5649
        op_ldst(suxc1);
5650
        opn = "suxc1";
5651
        store = 1;
5652
        break;
5653
    default:
5654
        MIPS_INVAL(opn);
5655
        generate_exception(ctx, EXCP_RI);
5656
        return;
5657
    }
5658
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5659
               regnames[index], regnames[base]);
5660
}
5661

    
5662
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5663
                            int fd, int fr, int fs, int ft)
5664
{
5665
    const char *opn = "flt3_arith";
5666

    
5667
    /* All of those work only on 64bit FPUs. */
5668
    check_cp1_64bitmode(ctx);
5669
    switch (opc) {
5670
    case OPC_ALNV_PS:
5671
        GEN_LOAD_REG_TN(T0, fr);
5672
        GEN_LOAD_FREG_FTN(DT0, fs);
5673
        GEN_LOAD_FREG_FTN(DT1, ft);
5674
        gen_op_float_alnv_ps();
5675
        GEN_STORE_FTN_FREG(fd, DT2);
5676
        opn = "alnv.ps";
5677
        break;
5678
    case OPC_MADD_S:
5679
        GEN_LOAD_FREG_FTN(WT0, fs);
5680
        GEN_LOAD_FREG_FTN(WT1, ft);
5681
        GEN_LOAD_FREG_FTN(WT2, fr);
5682
        gen_op_float_muladd_s();
5683
        GEN_STORE_FTN_FREG(fd, WT2);
5684
        opn = "madd.s";
5685
        break;
5686
    case OPC_MADD_D:
5687
        GEN_LOAD_FREG_FTN(DT0, fs);
5688
        GEN_LOAD_FREG_FTN(DT1, ft);
5689
        GEN_LOAD_FREG_FTN(DT2, fr);
5690
        gen_op_float_muladd_d();
5691
        GEN_STORE_FTN_FREG(fd, DT2);
5692
        opn = "madd.d";
5693
        break;
5694
    case OPC_MADD_PS:
5695
        GEN_LOAD_FREG_FTN(WT0, fs);
5696
        GEN_LOAD_FREG_FTN(WTH0, fs);
5697
        GEN_LOAD_FREG_FTN(WT1, ft);
5698
        GEN_LOAD_FREG_FTN(WTH1, ft);
5699
        GEN_LOAD_FREG_FTN(WT2, fr);
5700
        GEN_LOAD_FREG_FTN(WTH2, fr);
5701
        gen_op_float_muladd_ps();
5702
        GEN_STORE_FTN_FREG(fd, WT2);
5703
        GEN_STORE_FTN_FREG(fd, WTH2);
5704
        opn = "madd.ps";
5705
        break;
5706
    case OPC_MSUB_S:
5707
        GEN_LOAD_FREG_FTN(WT0, fs);
5708
        GEN_LOAD_FREG_FTN(WT1, ft);
5709
        GEN_LOAD_FREG_FTN(WT2, fr);
5710
        gen_op_float_mulsub_s();
5711
        GEN_STORE_FTN_FREG(fd, WT2);
5712
        opn = "msub.s";
5713
        break;
5714
    case OPC_MSUB_D:
5715
        GEN_LOAD_FREG_FTN(DT0, fs);
5716
        GEN_LOAD_FREG_FTN(DT1, ft);
5717
        GEN_LOAD_FREG_FTN(DT2, fr);
5718
        gen_op_float_mulsub_d();
5719
        GEN_STORE_FTN_FREG(fd, DT2);
5720
        opn = "msub.d";
5721
        break;
5722
    case OPC_MSUB_PS:
5723
        GEN_LOAD_FREG_FTN(WT0, fs);
5724
        GEN_LOAD_FREG_FTN(WTH0, fs);
5725
        GEN_LOAD_FREG_FTN(WT1, ft);
5726
        GEN_LOAD_FREG_FTN(WTH1, ft);
5727
        GEN_LOAD_FREG_FTN(WT2, fr);
5728
        GEN_LOAD_FREG_FTN(WTH2, fr);
5729
        gen_op_float_mulsub_ps();
5730
        GEN_STORE_FTN_FREG(fd, WT2);
5731
        GEN_STORE_FTN_FREG(fd, WTH2);
5732
        opn = "msub.ps";
5733
        break;
5734
    case OPC_NMADD_S:
5735
        GEN_LOAD_FREG_FTN(WT0, fs);
5736
        GEN_LOAD_FREG_FTN(WT1, ft);
5737
        GEN_LOAD_FREG_FTN(WT2, fr);
5738
        gen_op_float_nmuladd_s();
5739
        GEN_STORE_FTN_FREG(fd, WT2);
5740
        opn = "nmadd.s";
5741
        break;
5742
    case OPC_NMADD_D:
5743
        GEN_LOAD_FREG_FTN(DT0, fs);
5744
        GEN_LOAD_FREG_FTN(DT1, ft);
5745
        GEN_LOAD_FREG_FTN(DT2, fr);
5746
        gen_op_float_nmuladd_d();
5747
        GEN_STORE_FTN_FREG(fd, DT2);
5748
        opn = "nmadd.d";
5749
        break;
5750
    case OPC_NMADD_PS:
5751
        GEN_LOAD_FREG_FTN(WT0, fs);
5752
        GEN_LOAD_FREG_FTN(WTH0, fs);
5753
        GEN_LOAD_FREG_FTN(WT1, ft);
5754
        GEN_LOAD_FREG_FTN(WTH1, ft);
5755
        GEN_LOAD_FREG_FTN(WT2, fr);
5756
        GEN_LOAD_FREG_FTN(WTH2, fr);
5757
        gen_op_float_nmuladd_ps();
5758
        GEN_STORE_FTN_FREG(fd, WT2);
5759
        GEN_STORE_FTN_FREG(fd, WTH2);
5760
        opn = "nmadd.ps";
5761
        break;
5762
    case OPC_NMSUB_S:
5763
        GEN_LOAD_FREG_FTN(WT0, fs);
5764
        GEN_LOAD_FREG_FTN(WT1, ft);
5765
        GEN_LOAD_FREG_FTN(WT2, fr);
5766
        gen_op_float_nmulsub_s();
5767
        GEN_STORE_FTN_FREG(fd, WT2);
5768
        opn = "nmsub.s";
5769
        break;
5770
    case OPC_NMSUB_D:
5771
        GEN_LOAD_FREG_FTN(DT0, fs);
5772
        GEN_LOAD_FREG_FTN(DT1, ft);
5773
        GEN_LOAD_FREG_FTN(DT2, fr);
5774
        gen_op_float_nmulsub_d();
5775
        GEN_STORE_FTN_FREG(fd, DT2);
5776
        opn = "nmsub.d";
5777
        break;
5778
    case OPC_NMSUB_PS:
5779
        GEN_LOAD_FREG_FTN(WT0, fs);
5780
        GEN_LOAD_FREG_FTN(WTH0, fs);
5781
        GEN_LOAD_FREG_FTN(WT1, ft);
5782
        GEN_LOAD_FREG_FTN(WTH1, ft);
5783
        GEN_LOAD_FREG_FTN(WT2, fr);
5784
        GEN_LOAD_FREG_FTN(WTH2, fr);
5785
        gen_op_float_nmulsub_ps();
5786
        GEN_STORE_FTN_FREG(fd, WT2);
5787
        GEN_STORE_FTN_FREG(fd, WTH2);
5788
        opn = "nmsub.ps";
5789
        break;
5790
    default:
5791
        MIPS_INVAL(opn);
5792
        generate_exception (ctx, EXCP_RI);
5793
        return;
5794
    }
5795
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5796
               fregnames[fs], fregnames[ft]);
5797
}
5798

    
5799
/* ISA extensions (ASEs) */
5800
/* MIPS16 extension to MIPS32 */
5801
/* SmartMIPS extension to MIPS32 */
5802

    
5803
#ifdef TARGET_MIPS64
5804

    
5805
/* MDMX extension to MIPS64 */
5806
/* MIPS-3D extension to MIPS64 */
5807

    
5808
#endif
5809

    
5810
static void decode_opc (CPUState *env, DisasContext *ctx)
5811
{
5812
    int32_t offset;
5813
    int rs, rt, rd, sa;
5814
    uint32_t op, op1, op2;
5815
    int16_t imm;
5816

    
5817
    /* make sure instructions are on a word boundary */
5818
    if (ctx->pc & 0x3) {
5819
        env->CP0_BadVAddr = ctx->pc;
5820
        generate_exception(ctx, EXCP_AdEL);
5821
        return;
5822
    }
5823

    
5824
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5825
        int l1;
5826
        /* Handle blikely not taken case */
5827
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5828
        l1 = gen_new_label();
5829
        gen_op_jnz_T2(l1);
5830
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5831
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5832
        gen_set_label(l1);
5833
    }
5834
    op = MASK_OP_MAJOR(ctx->opcode);
5835
    rs = (ctx->opcode >> 21) & 0x1f;
5836
    rt = (ctx->opcode >> 16) & 0x1f;
5837
    rd = (ctx->opcode >> 11) & 0x1f;
5838
    sa = (ctx->opcode >> 6) & 0x1f;
5839
    imm = (int16_t)ctx->opcode;
5840
    switch (op) {
5841
    case OPC_SPECIAL:
5842
        op1 = MASK_SPECIAL(ctx->opcode);
5843
        switch (op1) {
5844
        case OPC_SLL:          /* Arithmetic with immediate */
5845
        case OPC_SRL ... OPC_SRA:
5846
            gen_arith_imm(ctx, op1, rd, rt, sa);
5847
            break;
5848
        case OPC_SLLV:         /* Arithmetic */
5849
        case OPC_SRLV ... OPC_SRAV:
5850
        case OPC_MOVZ ... OPC_MOVN:
5851
        case OPC_ADD ... OPC_NOR:
5852
        case OPC_SLT ... OPC_SLTU:
5853
            gen_arith(ctx, op1, rd, rs, rt);
5854
            break;
5855
        case OPC_MULT ... OPC_DIVU:
5856
            gen_muldiv(ctx, op1, rs, rt);
5857
            break;
5858
        case OPC_JR ... OPC_JALR:
5859
            gen_compute_branch(ctx, op1, rs, rd, sa);
5860
            return;
5861
        case OPC_TGE ... OPC_TEQ: /* Traps */
5862
        case OPC_TNE:
5863
            gen_trap(ctx, op1, rs, rt, -1);
5864
            break;
5865
        case OPC_MFHI:          /* Move from HI/LO */
5866
        case OPC_MFLO:
5867
            gen_HILO(ctx, op1, rd);
5868
            break;
5869
        case OPC_MTHI:
5870
        case OPC_MTLO:          /* Move to HI/LO */
5871
            gen_HILO(ctx, op1, rs);
5872
            break;
5873
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5874
#ifdef MIPS_STRICT_STANDARD
5875
            MIPS_INVAL("PMON / selsl");
5876
            generate_exception(ctx, EXCP_RI);
5877
#else
5878
            gen_op_pmon(sa);
5879
#endif
5880
            break;
5881
        case OPC_SYSCALL:
5882
            generate_exception(ctx, EXCP_SYSCALL);
5883
            break;
5884
        case OPC_BREAK:
5885
            generate_exception(ctx, EXCP_BREAK);
5886
            break;
5887
        case OPC_SPIM:
5888
#ifdef MIPS_STRICT_STANDARD
5889
            MIPS_INVAL("SPIM");
5890
            generate_exception(ctx, EXCP_RI);
5891
#else
5892
           /* Implemented as RI exception for now. */
5893
            MIPS_INVAL("spim (unofficial)");
5894
            generate_exception(ctx, EXCP_RI);
5895
#endif
5896
            break;
5897
        case OPC_SYNC:
5898
            /* Treat as NOP. */
5899
            break;
5900

    
5901
        case OPC_MOVCI:
5902
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5903
                save_cpu_state(ctx, 1);
5904
                check_cp1_enabled(ctx);
5905
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5906
                          (ctx->opcode >> 16) & 1);
5907
            } else {
5908
                generate_exception_err(ctx, EXCP_CpU, 1);
5909
            }
5910
            break;
5911

    
5912
#ifdef TARGET_MIPS64
5913
       /* MIPS64 specific opcodes */
5914
        case OPC_DSLL:
5915
        case OPC_DSRL ... OPC_DSRA:
5916
        case OPC_DSLL32:
5917
        case OPC_DSRL32 ... OPC_DSRA32:
5918
            if (!(ctx->hflags & MIPS_HFLAG_64))
5919
                generate_exception(ctx, EXCP_RI);
5920
            gen_arith_imm(ctx, op1, rd, rt, sa);
5921
            break;
5922
        case OPC_DSLLV:
5923
        case OPC_DSRLV ... OPC_DSRAV:
5924
        case OPC_DADD ... OPC_DSUBU:
5925
            if (!(ctx->hflags & MIPS_HFLAG_64))
5926
                generate_exception(ctx, EXCP_RI);
5927
            gen_arith(ctx, op1, rd, rs, rt);
5928
            break;
5929
        case OPC_DMULT ... OPC_DDIVU:
5930
            if (!(ctx->hflags & MIPS_HFLAG_64))
5931
                generate_exception(ctx, EXCP_RI);
5932
            gen_muldiv(ctx, op1, rs, rt);
5933
            break;
5934
#endif
5935
        default:            /* Invalid */
5936
            MIPS_INVAL("special");
5937
            generate_exception(ctx, EXCP_RI);
5938
            break;
5939
        }
5940
        break;
5941
    case OPC_SPECIAL2:
5942
        op1 = MASK_SPECIAL2(ctx->opcode);
5943
        switch (op1) {
5944
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5945
        case OPC_MSUB ... OPC_MSUBU:
5946
            gen_muldiv(ctx, op1, rs, rt);
5947
            break;
5948
        case OPC_MUL:
5949
            gen_arith(ctx, op1, rd, rs, rt);
5950
            break;
5951
        case OPC_CLZ ... OPC_CLO:
5952
            gen_cl(ctx, op1, rd, rs);
5953
            break;
5954
        case OPC_SDBBP:
5955
            /* XXX: not clear which exception should be raised
5956
             *      when in debug mode...
5957
             */
5958
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5959
                generate_exception(ctx, EXCP_DBp);
5960
            } else {
5961
                generate_exception(ctx, EXCP_DBp);
5962
            }
5963
            /* Treat as NOP. */
5964
            break;
5965
#ifdef TARGET_MIPS64
5966
        case OPC_DCLZ ... OPC_DCLO:
5967
            if (!(ctx->hflags & MIPS_HFLAG_64))
5968
                generate_exception(ctx, EXCP_RI);
5969
            gen_cl(ctx, op1, rd, rs);
5970
            break;
5971
#endif
5972
        default:            /* Invalid */
5973
            MIPS_INVAL("special2");
5974
            generate_exception(ctx, EXCP_RI);
5975
            break;
5976
        }
5977
        break;
5978
    case OPC_SPECIAL3:
5979
         check_mips_r2(env, ctx);
5980
         op1 = MASK_SPECIAL3(ctx->opcode);
5981
         switch (op1) {
5982
         case OPC_EXT:
5983
         case OPC_INS:
5984
             gen_bitops(ctx, op1, rt, rs, sa, rd);
5985
             break;
5986
         case OPC_BSHFL:
5987
             op2 = MASK_BSHFL(ctx->opcode);
5988
             switch (op2) {
5989
             case OPC_WSBH:
5990
                 GEN_LOAD_REG_TN(T1, rt);
5991
                 gen_op_wsbh();
5992
                 break;
5993
             case OPC_SEB:
5994
                 GEN_LOAD_REG_TN(T1, rt);
5995
                 gen_op_seb();
5996
                 break;
5997
             case OPC_SEH:
5998
                 GEN_LOAD_REG_TN(T1, rt);
5999
                 gen_op_seh();
6000
                 break;
6001
             default:            /* Invalid */
6002
                 MIPS_INVAL("bshfl");
6003
                 generate_exception(ctx, EXCP_RI);
6004
                 break;
6005
            }
6006
            GEN_STORE_TN_REG(rd, T0);
6007
            break;
6008
        case OPC_RDHWR:
6009
            switch (rd) {
6010
            case 0:
6011
                save_cpu_state(ctx, 1);
6012
                gen_op_rdhwr_cpunum();
6013
                break;
6014
            case 1:
6015
                save_cpu_state(ctx, 1);
6016
                gen_op_rdhwr_synci_step();
6017
                break;
6018
            case 2:
6019
                save_cpu_state(ctx, 1);
6020
                gen_op_rdhwr_cc();
6021
                break;
6022
            case 3:
6023
                save_cpu_state(ctx, 1);
6024
                gen_op_rdhwr_ccres();
6025
                break;
6026
            case 29:
6027
#if defined (CONFIG_USER_ONLY)
6028
                gen_op_tls_value();
6029
                break;
6030
#endif
6031
            default:            /* Invalid */
6032
                MIPS_INVAL("rdhwr");
6033
                generate_exception(ctx, EXCP_RI);
6034
                break;
6035
            }
6036
            GEN_STORE_TN_REG(rt, T0);
6037
            break;
6038
        case OPC_FORK:
6039
            check_mips_mt(env, ctx);
6040
            GEN_LOAD_REG_TN(T0, rt);
6041
            GEN_LOAD_REG_TN(T1, rs);
6042
            gen_op_fork();
6043
            break;
6044
        case OPC_YIELD:
6045
            check_mips_mt(env, ctx);
6046
            GEN_LOAD_REG_TN(T0, rs);
6047
            gen_op_yield();
6048
            GEN_STORE_TN_REG(rd, T0);
6049
            break;
6050
#ifdef TARGET_MIPS64
6051
        case OPC_DEXTM ... OPC_DEXT:
6052
        case OPC_DINSM ... OPC_DINS:
6053
            if (!(ctx->hflags & MIPS_HFLAG_64))
6054
                generate_exception(ctx, EXCP_RI);
6055
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6056
            break;
6057
        case OPC_DBSHFL:
6058
            if (!(ctx->hflags & MIPS_HFLAG_64))
6059
                generate_exception(ctx, EXCP_RI);
6060
            op2 = MASK_DBSHFL(ctx->opcode);
6061
            switch (op2) {
6062
            case OPC_DSBH:
6063
                GEN_LOAD_REG_TN(T1, rt);
6064
                gen_op_dsbh();
6065
                break;
6066
            case OPC_DSHD:
6067
                GEN_LOAD_REG_TN(T1, rt);
6068
                gen_op_dshd();
6069
                break;
6070
            default:            /* Invalid */
6071
                MIPS_INVAL("dbshfl");
6072
                generate_exception(ctx, EXCP_RI);
6073
                break;
6074
            }
6075
            GEN_STORE_TN_REG(rd, T0);
6076
#endif
6077
        default:            /* Invalid */
6078
            MIPS_INVAL("special3");
6079
            generate_exception(ctx, EXCP_RI);
6080
            break;
6081
        }
6082
        break;
6083
    case OPC_REGIMM:
6084
        op1 = MASK_REGIMM(ctx->opcode);
6085
        switch (op1) {
6086
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6087
        case OPC_BLTZAL ... OPC_BGEZALL:
6088
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6089
            return;
6090
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6091
        case OPC_TNEI:
6092
            gen_trap(ctx, op1, rs, -1, imm);
6093
            break;
6094
        case OPC_SYNCI:
6095
            check_mips_r2(env, ctx);
6096
            /* Treat as NOP. */
6097
            break;
6098
        default:            /* Invalid */
6099
            MIPS_INVAL("regimm");
6100
            generate_exception(ctx, EXCP_RI);
6101
            break;
6102
        }
6103
        break;
6104
    case OPC_CP0:
6105
        save_cpu_state(ctx, 1);
6106
        gen_op_cp0_enabled();
6107
        op1 = MASK_CP0(ctx->opcode);
6108
        switch (op1) {
6109
        case OPC_MFC0:
6110
        case OPC_MTC0:
6111
        case OPC_MFTR:
6112
        case OPC_MTTR:
6113
#ifdef TARGET_MIPS64
6114
        case OPC_DMFC0:
6115
        case OPC_DMTC0:
6116
#endif
6117
            gen_cp0(env, ctx, op1, rt, rd);
6118
            break;
6119
        case OPC_C0_FIRST ... OPC_C0_LAST:
6120
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6121
            break;
6122
        case OPC_MFMC0:
6123
            check_mips_r2(env, ctx);
6124
            op2 = MASK_MFMC0(ctx->opcode);
6125
            switch (op2) {
6126
            case OPC_DMT:
6127
                check_mips_mt(env, ctx);
6128
                gen_op_dmt();
6129
                break;
6130
            case OPC_EMT:
6131
                check_mips_mt(env, ctx);
6132
                gen_op_emt();
6133
                break;
6134
            case OPC_DVPE:
6135
                check_mips_mt(env, ctx);
6136
                gen_op_dvpe();
6137
                break;
6138
            case OPC_EVPE:
6139
                check_mips_mt(env, ctx);
6140
                gen_op_evpe();
6141
                break;
6142
            case OPC_DI:
6143
                gen_op_di();
6144
                /* Stop translation as we may have switched the execution mode */
6145
                ctx->bstate = BS_STOP;
6146
                break;
6147
            case OPC_EI:
6148
                gen_op_ei();
6149
                /* Stop translation as we may have switched the execution mode */
6150
                ctx->bstate = BS_STOP;
6151
                break;
6152
            default:            /* Invalid */
6153
                MIPS_INVAL("mfmc0");
6154
                generate_exception(ctx, EXCP_RI);
6155
                break;
6156
            }
6157
            GEN_STORE_TN_REG(rt, T0);
6158
            break;
6159
        case OPC_RDPGPR:
6160
            check_mips_r2(env, ctx);
6161
            GEN_LOAD_SRSREG_TN(T0, rt);
6162
            GEN_STORE_TN_REG(rd, T0);
6163
            break;
6164
        case OPC_WRPGPR:
6165
            check_mips_r2(env, ctx);
6166
            GEN_LOAD_REG_TN(T0, rt);
6167
            GEN_STORE_TN_SRSREG(rd, T0);
6168
            break;
6169
        default:
6170
            MIPS_INVAL("cp0");
6171
            generate_exception(ctx, EXCP_RI);
6172
            break;
6173
        }
6174
        break;
6175
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6176
         gen_arith_imm(ctx, op, rt, rs, imm);
6177
         break;
6178
    case OPC_J ... OPC_JAL: /* Jump */
6179
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6180
         gen_compute_branch(ctx, op, rs, rt, offset);
6181
         return;
6182
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6183
    case OPC_BEQL ... OPC_BGTZL:
6184
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6185
         return;
6186
    case OPC_LB ... OPC_LWR: /* Load and stores */
6187
    case OPC_SB ... OPC_SW:
6188
    case OPC_SWR:
6189
    case OPC_LL:
6190
    case OPC_SC:
6191
         gen_ldst(ctx, op, rt, rs, imm);
6192
         break;
6193
    case OPC_CACHE:
6194
        /* Treat as NOP. */
6195
        break;
6196
    case OPC_PREF:
6197
        /* Treat as NOP. */
6198
        break;
6199

    
6200
    /* Floating point (COP1). */
6201
    case OPC_LWC1:
6202
    case OPC_LDC1:
6203
    case OPC_SWC1:
6204
    case OPC_SDC1:
6205
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6206
            save_cpu_state(ctx, 1);
6207
            check_cp1_enabled(ctx);
6208
            gen_flt_ldst(ctx, op, rt, rs, imm);
6209
        } else {
6210
            generate_exception_err(ctx, EXCP_CpU, 1);
6211
        }
6212
        break;
6213

    
6214
    case OPC_CP1:
6215
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6216
            save_cpu_state(ctx, 1);
6217
            check_cp1_enabled(ctx);
6218
            op1 = MASK_CP1(ctx->opcode);
6219
            switch (op1) {
6220
            case OPC_MFHC1:
6221
            case OPC_MTHC1:
6222
                check_mips_r2(env, ctx);
6223
            case OPC_MFC1:
6224
            case OPC_CFC1:
6225
            case OPC_MTC1:
6226
            case OPC_CTC1:
6227
#ifdef TARGET_MIPS64
6228
            case OPC_DMFC1:
6229
            case OPC_DMTC1:
6230
#endif
6231
                gen_cp1(ctx, op1, rt, rd);
6232
                break;
6233
            case OPC_BC1:
6234
            case OPC_BC1ANY2:
6235
            case OPC_BC1ANY4:
6236
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
6237
                                    (rt >> 2) & 0x7, imm << 2);
6238
                return;
6239
            case OPC_S_FMT:
6240
            case OPC_D_FMT:
6241
            case OPC_W_FMT:
6242
            case OPC_L_FMT:
6243
            case OPC_PS_FMT:
6244
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6245
                           (imm >> 8) & 0x7);
6246
                break;
6247
            default:
6248
                MIPS_INVAL("cp1");
6249
                generate_exception (ctx, EXCP_RI);
6250
                break;
6251
            }
6252
        } else {
6253
            generate_exception_err(ctx, EXCP_CpU, 1);
6254
        }
6255
        break;
6256

    
6257
    /* COP2.  */
6258
    case OPC_LWC2:
6259
    case OPC_LDC2:
6260
    case OPC_SWC2:
6261
    case OPC_SDC2:
6262
    case OPC_CP2:
6263
        /* COP2: Not implemented. */
6264
        generate_exception_err(ctx, EXCP_CpU, 2);
6265
        break;
6266

    
6267
    case OPC_CP3:
6268
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6269
            save_cpu_state(ctx, 1);
6270
            check_cp1_enabled(ctx);
6271
            op1 = MASK_CP3(ctx->opcode);
6272
            switch (op1) {
6273
            case OPC_LWXC1:
6274
            case OPC_LDXC1:
6275
            case OPC_LUXC1:
6276
            case OPC_SWXC1:
6277
            case OPC_SDXC1:
6278
            case OPC_SUXC1:
6279
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6280
                break;
6281
            case OPC_PREFX:
6282
                /* Treat as NOP. */
6283
                break;
6284
            case OPC_ALNV_PS:
6285
            case OPC_MADD_S:
6286
            case OPC_MADD_D:
6287
            case OPC_MADD_PS:
6288
            case OPC_MSUB_S:
6289
            case OPC_MSUB_D:
6290
            case OPC_MSUB_PS:
6291
            case OPC_NMADD_S:
6292
            case OPC_NMADD_D:
6293
            case OPC_NMADD_PS:
6294
            case OPC_NMSUB_S:
6295
            case OPC_NMSUB_D:
6296
            case OPC_NMSUB_PS:
6297
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6298
                break;
6299
            default:
6300
                MIPS_INVAL("cp3");
6301
                generate_exception (ctx, EXCP_RI);
6302
                break;
6303
            }
6304
        } else {
6305
            generate_exception_err(ctx, EXCP_CpU, 1);
6306
        }
6307
        break;
6308

    
6309
#ifdef TARGET_MIPS64
6310
    /* MIPS64 opcodes */
6311
    case OPC_LWU:
6312
    case OPC_LDL ... OPC_LDR:
6313
    case OPC_SDL ... OPC_SDR:
6314
    case OPC_LLD:
6315
    case OPC_LD:
6316
    case OPC_SCD:
6317
    case OPC_SD:
6318
        if (!(ctx->hflags & MIPS_HFLAG_64))
6319
            generate_exception(ctx, EXCP_RI);
6320
        gen_ldst(ctx, op, rt, rs, imm);
6321
        break;
6322
    case OPC_DADDI ... OPC_DADDIU:
6323
        if (!(ctx->hflags & MIPS_HFLAG_64))
6324
            generate_exception(ctx, EXCP_RI);
6325
        gen_arith_imm(ctx, op, rt, rs, imm);
6326
        break;
6327
#endif
6328
#ifdef MIPS_HAS_MIPS16
6329
    case OPC_JALX:
6330
        /* MIPS16: Not implemented. */
6331
#endif
6332
#ifdef MIPS_HAS_MDMX
6333
    case OPC_MDMX:
6334
        /* MDMX: Not implemented. */
6335
#endif
6336
    default:            /* Invalid */
6337
        MIPS_INVAL("major opcode");
6338
        generate_exception(ctx, EXCP_RI);
6339
        break;
6340
    }
6341
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6342
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6343
        /* Branches completion */
6344
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
6345
        ctx->bstate = BS_BRANCH;
6346
        save_cpu_state(ctx, 0);
6347
        switch (hflags) {
6348
        case MIPS_HFLAG_B:
6349
            /* unconditional branch */
6350
            MIPS_DEBUG("unconditional branch");
6351
            gen_goto_tb(ctx, 0, ctx->btarget);
6352
            break;
6353
        case MIPS_HFLAG_BL:
6354
            /* blikely taken case */
6355
            MIPS_DEBUG("blikely branch taken");
6356
            gen_goto_tb(ctx, 0, ctx->btarget);
6357
            break;
6358
        case MIPS_HFLAG_BC:
6359
            /* Conditional branch */
6360
            MIPS_DEBUG("conditional branch");
6361
            {
6362
              int l1;
6363
              l1 = gen_new_label();
6364
              gen_op_jnz_T2(l1);
6365
              gen_goto_tb(ctx, 1, ctx->pc + 4);
6366
              gen_set_label(l1);
6367
              gen_goto_tb(ctx, 0, ctx->btarget);
6368
            }
6369
            break;
6370
        case MIPS_HFLAG_BR:
6371
            /* unconditional branch to register */
6372
            MIPS_DEBUG("branch to register");
6373
            gen_op_breg();
6374
            gen_op_reset_T0();
6375
            gen_op_exit_tb();
6376
            break;
6377
        default:
6378
            MIPS_DEBUG("unknown branch");
6379
            break;
6380
        }
6381
    }
6382
}
6383

    
6384
static inline int
6385
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6386
                                int search_pc)
6387
{
6388
    DisasContext ctx;
6389
    target_ulong pc_start;
6390
    uint16_t *gen_opc_end;
6391
    int j, lj = -1;
6392

    
6393
    if (search_pc && loglevel)
6394
        fprintf (logfile, "search pc %d\n", search_pc);
6395

    
6396
    pc_start = tb->pc;
6397
    gen_opc_ptr = gen_opc_buf;
6398
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6399
    gen_opparam_ptr = gen_opparam_buf;
6400
    nb_gen_labels = 0;
6401
    ctx.pc = pc_start;
6402
    ctx.saved_pc = -1;
6403
    ctx.tb = tb;
6404
    ctx.bstate = BS_NONE;
6405
    /* Restore delay slot state from the tb context.  */
6406
    ctx.hflags = tb->flags;
6407
    restore_cpu_state(env, &ctx);
6408
#if defined(CONFIG_USER_ONLY)
6409
    ctx.mem_idx = 0;
6410
#else
6411
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
6412
#endif
6413
#ifdef DEBUG_DISAS
6414
    if (loglevel & CPU_LOG_TB_CPU) {
6415
        fprintf(logfile, "------------------------------------------------\n");
6416
        /* FIXME: This may print out stale hflags from env... */
6417
        cpu_dump_state(env, logfile, fprintf, 0);
6418
    }
6419
#endif
6420
#ifdef MIPS_DEBUG_DISAS
6421
    if (loglevel & CPU_LOG_TB_IN_ASM)
6422
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
6423
                tb, ctx.mem_idx, ctx.hflags);
6424
#endif
6425
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6426
        if (env->nb_breakpoints > 0) {
6427
            for(j = 0; j < env->nb_breakpoints; j++) {
6428
                if (env->breakpoints[j] == ctx.pc) {
6429
                    save_cpu_state(&ctx, 1);
6430
                    ctx.bstate = BS_BRANCH;
6431
                    gen_op_debug();
6432
                    /* Include the breakpoint location or the tb won't
6433
                     * be flushed when it must be.  */
6434
                    ctx.pc += 4;
6435
                    goto done_generating;
6436
                }
6437
            }
6438
        }
6439

    
6440
        if (search_pc) {
6441
            j = gen_opc_ptr - gen_opc_buf;
6442
            if (lj < j) {
6443
                lj++;
6444
                while (lj < j)
6445
                    gen_opc_instr_start[lj++] = 0;
6446
            }
6447
            gen_opc_pc[lj] = ctx.pc;
6448
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6449
            gen_opc_instr_start[lj] = 1;
6450
        }
6451
        ctx.opcode = ldl_code(ctx.pc);
6452
        decode_opc(env, &ctx);
6453
        ctx.pc += 4;
6454

    
6455
        if (env->singlestep_enabled)
6456
            break;
6457

    
6458
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6459
            break;
6460

    
6461
#if defined (MIPS_SINGLE_STEP)
6462
        break;
6463
#endif
6464
    }
6465
    if (env->singlestep_enabled) {
6466
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6467
        gen_op_debug();
6468
    } else {
6469
        switch (ctx.bstate) {
6470
        case BS_STOP:
6471
            gen_op_interrupt_restart();
6472
            gen_goto_tb(&ctx, 0, ctx.pc);
6473
            break;
6474
        case BS_NONE:
6475
            save_cpu_state(&ctx, 0);
6476
            gen_goto_tb(&ctx, 0, ctx.pc);
6477
            break;
6478
        case BS_EXCP:
6479
            gen_op_interrupt_restart();
6480
            gen_op_reset_T0();
6481
            gen_op_exit_tb();
6482
            break;
6483
        case BS_BRANCH:
6484
        default:
6485
            break;
6486
        }
6487
    }
6488
done_generating:
6489
    *gen_opc_ptr = INDEX_op_end;
6490
    if (search_pc) {
6491
        j = gen_opc_ptr - gen_opc_buf;
6492
        lj++;
6493
        while (lj <= j)
6494
            gen_opc_instr_start[lj++] = 0;
6495
    } else {
6496
        tb->size = ctx.pc - pc_start;
6497
    }
6498
#ifdef DEBUG_DISAS
6499
#if defined MIPS_DEBUG_DISAS
6500
    if (loglevel & CPU_LOG_TB_IN_ASM)
6501
        fprintf(logfile, "\n");
6502
#endif
6503
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6504
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6505
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6506
        fprintf(logfile, "\n");
6507
    }
6508
    if (loglevel & CPU_LOG_TB_OP) {
6509
        fprintf(logfile, "OP:\n");
6510
        dump_ops(gen_opc_buf, gen_opparam_buf);
6511
        fprintf(logfile, "\n");
6512
    }
6513
    if (loglevel & CPU_LOG_TB_CPU) {
6514
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6515
    }
6516
#endif
6517

    
6518
    return 0;
6519
}
6520

    
6521
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6522
{
6523
    return gen_intermediate_code_internal(env, tb, 0);
6524
}
6525

    
6526
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6527
{
6528
    return gen_intermediate_code_internal(env, tb, 1);
6529
}
6530

    
6531
void fpu_dump_state(CPUState *env, FILE *f,
6532
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6533
                    int flags)
6534
{
6535
    int i;
6536
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6537

    
6538
#define printfpr(fp)                                                        \
6539
    do {                                                                    \
6540
        if (is_fpu64)                                                       \
6541
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6542
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6543
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6544
        else {                                                              \
6545
            fpr_t tmp;                                                      \
6546
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6547
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6548
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6549
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6550
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6551
        }                                                                   \
6552
    } while(0)
6553

    
6554

    
6555
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6556
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6557
                get_float_exception_flags(&env->fpu->fp_status));
6558
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6559
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6560
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6561
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6562
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6563
        printfpr(&env->fpu->fpr[i]);
6564
    }
6565

    
6566
#undef printfpr
6567
}
6568

    
6569
void dump_fpu (CPUState *env)
6570
{
6571
    if (loglevel) {
6572
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6573
               env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
6574
       fpu_dump_state(env, logfile, fprintf, 0);
6575
    }
6576
}
6577

    
6578
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6579
/* Debug help: The architecture requires 32bit code to maintain proper
6580
   sign-extened values on 64bit machines.  */
6581

    
6582
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6583

    
6584
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6585
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6586
                     int flags)
6587
{
6588
    int i;
6589

    
6590
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
6591
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6592
    if (!SIGN_EXT_P(env->HI[env->current_tc]))
6593
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc]);
6594
    if (!SIGN_EXT_P(env->LO[env->current_tc]))
6595
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc]);
6596
    if (!SIGN_EXT_P(env->btarget))
6597
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6598

    
6599
    for (i = 0; i < 32; i++) {
6600
        if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
6601
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
6602
    }
6603

    
6604
    if (!SIGN_EXT_P(env->CP0_EPC))
6605
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6606
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6607
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6608
}
6609
#endif
6610

    
6611
void cpu_dump_state (CPUState *env, FILE *f,
6612
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6613
                     int flags)
6614
{
6615
    int i;
6616

    
6617
    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",
6618
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6619
    for (i = 0; i < 32; i++) {
6620
        if ((i & 3) == 0)
6621
            cpu_fprintf(f, "GPR%02d:", i);
6622
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
6623
        if ((i & 3) == 3)
6624
            cpu_fprintf(f, "\n");
6625
    }
6626

    
6627
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6628
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6629
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6630
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6631
    if (env->hflags & MIPS_HFLAG_FPU)
6632
        fpu_dump_state(env, f, cpu_fprintf, flags);
6633
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6634
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6635
#endif
6636
}
6637

    
6638
CPUMIPSState *cpu_mips_init (void)
6639
{
6640
    CPUMIPSState *env;
6641

    
6642
    env = qemu_mallocz(sizeof(CPUMIPSState));
6643
    if (!env)
6644
        return NULL;
6645
    cpu_exec_init(env);
6646
    cpu_reset(env);
6647
    return env;
6648
}
6649

    
6650
void cpu_reset (CPUMIPSState *env)
6651
{
6652
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6653

    
6654
    tlb_flush(env, 1);
6655

    
6656
    /* Minimal init */
6657
#if !defined(CONFIG_USER_ONLY)
6658
    if (env->hflags & MIPS_HFLAG_BMASK) {
6659
        /* If the exception was raised from a delay slot,
6660
         * come back to the jump.  */
6661
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6662
    } else {
6663
        env->CP0_ErrorEPC = env->PC[env->current_tc];
6664
    }
6665
    env->hflags = 0;
6666
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
6667
    env->CP0_Wired = 0;
6668
    /* SMP not implemented */
6669
    env->CP0_EBase = 0x80000000;
6670
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6671
    /* vectored interrupts not implemented, timer on int 7,
6672
       no performance counters. */
6673
    env->CP0_IntCtl = 0xe0000000;
6674
    {
6675
        int i;
6676

    
6677
        for (i = 0; i < 7; i++) {
6678
            env->CP0_WatchLo[i] = 0;
6679
            env->CP0_WatchHi[i] = 0x80000000;
6680
        }
6681
        env->CP0_WatchLo[7] = 0;
6682
        env->CP0_WatchHi[7] = 0;
6683
    }
6684
    /* Count register increments in debug mode, EJTAG version 1 */
6685
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6686
#endif
6687
    env->exception_index = EXCP_NONE;
6688
#if defined(CONFIG_USER_ONLY)
6689
    env->hflags |= MIPS_HFLAG_UM;
6690
    env->user_mode_only = 1;
6691
#endif
6692
}
6693

    
6694
#include "translate_init.c"