Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 7d307e9e

History | View | Annotate | Download (185.6 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
420

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4766
/* Coprocessor 1 (FPU) */
4767

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5881
/* MDMX extension to MIPS64 */
5882

    
5883
#endif
5884

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6607
    return 0;
6608
}
6609

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

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

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

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

    
6643

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

    
6655
#undef printfpr
6656
}
6657

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6743
    tlb_flush(env, 1);
6744

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

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

    
6784
#include "translate_init.c"