Statistics
| Branch: | Revision:

root / target-mips / translate.c @ fd4a04eb

History | View | Annotate | Download (163.5 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
307
/* MFMC0 opcodes */
308
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
309

    
310
enum {
311
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313
};
314

    
315
/* Coprocessor 0 (with rs == C0) */
316
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
317

    
318
enum {
319
    OPC_TLBR     = 0x01 | OPC_C0,
320
    OPC_TLBWI    = 0x02 | OPC_C0,
321
    OPC_TLBWR    = 0x06 | OPC_C0,
322
    OPC_TLBP     = 0x08 | OPC_C0,
323
    OPC_RFE      = 0x10 | OPC_C0,
324
    OPC_ERET     = 0x18 | OPC_C0,
325
    OPC_DERET    = 0x1F | OPC_C0,
326
    OPC_WAIT     = 0x20 | OPC_C0,
327
};
328

    
329
/* Coprocessor 1 (rs field) */
330
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
331

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

    
353
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
354
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
355

    
356
enum {
357
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
358
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
359
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
360
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
361
};
362

    
363
enum {
364
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
365
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
366
};
367

    
368
enum {
369
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
370
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
371
};
372

    
373
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
374

    
375
enum {
376
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
377
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
378
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
379
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
380
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
381
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
382
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
383
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
384
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
385
};
386

    
387
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
388

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

    
412

    
413
const unsigned char *regnames[] =
414
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
415
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
416
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
417
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
418

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

    
436
/* General purpose registers moves */
437
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
438
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
439
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
440

    
441
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
443

    
444
static const char *fregnames[] =
445
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
446
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
447
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
448
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
449

    
450
#define FGEN32(func, NAME)                       \
451
static GenOpFunc *NAME ## _table [32] = {        \
452
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
453
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
454
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
455
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
456
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
457
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
458
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
459
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
460
};                                               \
461
static inline void func(int n)                   \
462
{                                                \
463
    NAME ## _table[n]();                         \
464
}
465

    
466
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
467
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
468

    
469
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
470
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
471

    
472
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
473
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
474

    
475
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
476
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
477

    
478
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
479
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
480

    
481
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
482
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
485
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
486

    
487
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
488
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
489

    
490
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
491
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492

    
493
#define FOP_CONDS(type, fmt)                                            \
494
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
495
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
496
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
497
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
498
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
499
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
500
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
501
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
502
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
503
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
504
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
505
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
506
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
507
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
508
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
509
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
510
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
511
};                                                                      \
512
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)          \
513
{                                                                       \
514
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
515
}
516

    
517
FOP_CONDS(, d)
518
FOP_CONDS(abs, d)
519
FOP_CONDS(, s)
520
FOP_CONDS(abs, s)
521
FOP_CONDS(, ps)
522
FOP_CONDS(abs, ps)
523

    
524
typedef struct DisasContext {
525
    struct TranslationBlock *tb;
526
    target_ulong pc, saved_pc;
527
    uint32_t opcode;
528
    uint32_t fp_status;
529
    /* Routine used to access memory */
530
    int mem_idx;
531
    uint32_t hflags, saved_hflags;
532
    int bstate;
533
    target_ulong btarget;
534
} DisasContext;
535

    
536
enum {
537
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
538
                      * exception condition
539
                      */
540
    BS_STOP     = 1, /* We want to stop translation for any reason */
541
    BS_BRANCH   = 2, /* We reached a branch condition     */
542
    BS_EXCP     = 3, /* We reached an exception condition */
543
};
544

    
545
#ifdef MIPS_DEBUG_DISAS
546
#define MIPS_DEBUG(fmt, args...)                                              \
547
do {                                                                          \
548
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
549
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
550
                ctx->pc, ctx->opcode , ##args);                               \
551
    }                                                                         \
552
} while (0)
553
#else
554
#define MIPS_DEBUG(fmt, args...) do { } while(0)
555
#endif
556

    
557
#define MIPS_INVAL(op)                                                        \
558
do {                                                                          \
559
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
560
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
561
} while (0)
562

    
563
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
564
do {                                                                          \
565
    if (Rn == 0) {                                                            \
566
        glue(gen_op_reset_, Tn)();                                            \
567
    } else {                                                                  \
568
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
569
    }                                                                         \
570
} while (0)
571

    
572
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
573
do {                                                                          \
574
    if (Imm == 0) {                                                           \
575
        glue(gen_op_reset_, Tn)();                                            \
576
    } else {                                                                  \
577
        glue(gen_op_set_, Tn)(Imm);                                           \
578
    }                                                                         \
579
} while (0)
580

    
581
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
582
do {                                                                          \
583
    if (Rn != 0) {                                                            \
584
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
585
    }                                                                         \
586
} while (0)
587

    
588
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
589
do {                                                                          \
590
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
591
} while (0)
592

    
593
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
594
do {                                                                          \
595
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
596
} while (0)
597

    
598
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
599
{
600
#if defined MIPS_DEBUG_DISAS
601
    if (loglevel & CPU_LOG_TB_IN_ASM) {
602
            fprintf(logfile, "hflags %08x saved %08x\n",
603
                    ctx->hflags, ctx->saved_hflags);
604
    }
605
#endif
606
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
607
        gen_op_save_pc(ctx->pc);
608
        ctx->saved_pc = ctx->pc;
609
    }
610
    if (ctx->hflags != ctx->saved_hflags) {
611
        gen_op_save_state(ctx->hflags);
612
        ctx->saved_hflags = ctx->hflags;
613
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
614
        case MIPS_HFLAG_BR:
615
            gen_op_save_breg_target();
616
            break;
617
        case MIPS_HFLAG_BC:
618
            gen_op_save_bcond();
619
            /* fall through */
620
        case MIPS_HFLAG_BL:
621
            /* bcond was already saved by the BL insn */
622
            /* fall through */
623
        case MIPS_HFLAG_B:
624
            gen_op_save_btarget(ctx->btarget);
625
            break;
626
        }
627
    }
628
}
629

    
630
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
631
{
632
    ctx->saved_hflags = ctx->hflags;
633
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
634
    case MIPS_HFLAG_BR:
635
        gen_op_restore_breg_target();
636
        break;
637
    case MIPS_HFLAG_B:
638
        ctx->btarget = env->btarget;
639
        break;
640
    case MIPS_HFLAG_BC:
641
    case MIPS_HFLAG_BL:
642
        ctx->btarget = env->btarget;
643
        gen_op_restore_bcond();
644
        break;
645
    }
646
}
647

    
648
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
649
{
650
#if defined MIPS_DEBUG_DISAS
651
    if (loglevel & CPU_LOG_TB_IN_ASM)
652
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
653
#endif
654
    save_cpu_state(ctx, 1);
655
    if (err == 0)
656
        gen_op_raise_exception(excp);
657
    else
658
        gen_op_raise_exception_err(excp, err);
659
    ctx->bstate = BS_EXCP;
660
}
661

    
662
static inline void generate_exception (DisasContext *ctx, int excp)
663
{
664
    generate_exception_err (ctx, excp, 0);
665
}
666

    
667
#if defined(CONFIG_USER_ONLY)
668
#define op_ldst(name)        gen_op_##name##_raw()
669
#define OP_LD_TABLE(width)
670
#define OP_ST_TABLE(width)
671
#else
672
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
673
#define OP_LD_TABLE(width)                                                    \
674
static GenOpFunc *gen_op_l##width[] = {                                       \
675
    &gen_op_l##width##_user,                                                  \
676
    &gen_op_l##width##_kernel,                                                \
677
}
678
#define OP_ST_TABLE(width)                                                    \
679
static GenOpFunc *gen_op_s##width[] = {                                       \
680
    &gen_op_s##width##_user,                                                  \
681
    &gen_op_s##width##_kernel,                                                \
682
}
683
#endif
684

    
685
#ifdef TARGET_MIPS64
686
OP_LD_TABLE(d);
687
OP_LD_TABLE(dl);
688
OP_LD_TABLE(dr);
689
OP_ST_TABLE(d);
690
OP_ST_TABLE(dl);
691
OP_ST_TABLE(dr);
692
OP_LD_TABLE(ld);
693
OP_ST_TABLE(cd);
694
#endif
695
OP_LD_TABLE(w);
696
OP_LD_TABLE(wu);
697
OP_LD_TABLE(wl);
698
OP_LD_TABLE(wr);
699
OP_ST_TABLE(w);
700
OP_ST_TABLE(wl);
701
OP_ST_TABLE(wr);
702
OP_LD_TABLE(h);
703
OP_LD_TABLE(hu);
704
OP_ST_TABLE(h);
705
OP_LD_TABLE(b);
706
OP_LD_TABLE(bu);
707
OP_ST_TABLE(b);
708
OP_LD_TABLE(l);
709
OP_ST_TABLE(c);
710
OP_LD_TABLE(wc1);
711
OP_ST_TABLE(wc1);
712
OP_LD_TABLE(dc1);
713
OP_ST_TABLE(dc1);
714
OP_LD_TABLE(wxc1);
715
OP_ST_TABLE(wxc1);
716
OP_LD_TABLE(dxc1);
717
OP_ST_TABLE(dxc1);
718
OP_LD_TABLE(uxc1);
719
OP_ST_TABLE(uxc1);
720

    
721
/* Load and store */
722
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
723
                      int base, int16_t offset)
724
{
725
    const char *opn = "ldst";
726

    
727
    if (base == 0) {
728
        GEN_LOAD_IMM_TN(T0, offset);
729
    } else if (offset == 0) {
730
        gen_op_load_gpr_T0(base);
731
    } else {
732
        gen_op_load_gpr_T0(base);
733
        gen_op_set_T1(offset);
734
        gen_op_addr_add();
735
    }
736
    /* Don't do NOP if destination is zero: we must perform the actual
737
     * memory access
738
     */
739
    switch (opc) {
740
#ifdef TARGET_MIPS64
741
    case OPC_LD:
742
        op_ldst(ld);
743
        GEN_STORE_TN_REG(rt, T0);
744
        opn = "ld";
745
        break;
746
    case OPC_LLD:
747
        op_ldst(lld);
748
        GEN_STORE_TN_REG(rt, T0);
749
        opn = "lld";
750
        break;
751
    case OPC_SD:
752
        GEN_LOAD_REG_TN(T1, rt);
753
        op_ldst(sd);
754
        opn = "sd";
755
        break;
756
    case OPC_SCD:
757
        save_cpu_state(ctx, 1);
758
        GEN_LOAD_REG_TN(T1, rt);
759
        op_ldst(scd);
760
        GEN_STORE_TN_REG(rt, T0);
761
        opn = "scd";
762
        break;
763
    case OPC_LDL:
764
        op_ldst(ldl);
765
        GEN_STORE_TN_REG(rt, T0);
766
        opn = "ldl";
767
        break;
768
    case OPC_SDL:
769
        GEN_LOAD_REG_TN(T1, rt);
770
        op_ldst(sdl);
771
        opn = "sdl";
772
        break;
773
    case OPC_LDR:
774
        op_ldst(ldr);
775
        GEN_STORE_TN_REG(rt, T0);
776
        opn = "ldr";
777
        break;
778
    case OPC_SDR:
779
        GEN_LOAD_REG_TN(T1, rt);
780
        op_ldst(sdr);
781
        opn = "sdr";
782
        break;
783
#endif
784
    case OPC_LW:
785
        op_ldst(lw);
786
        GEN_STORE_TN_REG(rt, T0);
787
        opn = "lw";
788
        break;
789
    case OPC_LWU:
790
        op_ldst(lwu);
791
        GEN_STORE_TN_REG(rt, T0);
792
        opn = "lwu";
793
        break;
794
    case OPC_SW:
795
        GEN_LOAD_REG_TN(T1, rt);
796
        op_ldst(sw);
797
        opn = "sw";
798
        break;
799
    case OPC_LH:
800
        op_ldst(lh);
801
        GEN_STORE_TN_REG(rt, T0);
802
        opn = "lh";
803
        break;
804
    case OPC_SH:
805
        GEN_LOAD_REG_TN(T1, rt);
806
        op_ldst(sh);
807
        opn = "sh";
808
        break;
809
    case OPC_LHU:
810
        op_ldst(lhu);
811
        GEN_STORE_TN_REG(rt, T0);
812
        opn = "lhu";
813
        break;
814
    case OPC_LB:
815
        op_ldst(lb);
816
        GEN_STORE_TN_REG(rt, T0);
817
        opn = "lb";
818
        break;
819
    case OPC_SB:
820
        GEN_LOAD_REG_TN(T1, rt);
821
        op_ldst(sb);
822
        opn = "sb";
823
        break;
824
    case OPC_LBU:
825
        op_ldst(lbu);
826
        GEN_STORE_TN_REG(rt, T0);
827
        opn = "lbu";
828
        break;
829
    case OPC_LWL:
830
        GEN_LOAD_REG_TN(T1, rt);
831
        op_ldst(lwl);
832
        GEN_STORE_TN_REG(rt, T0);
833
        opn = "lwl";
834
        break;
835
    case OPC_SWL:
836
        GEN_LOAD_REG_TN(T1, rt);
837
        op_ldst(swl);
838
        opn = "swr";
839
        break;
840
    case OPC_LWR:
841
        GEN_LOAD_REG_TN(T1, rt);
842
        op_ldst(lwr);
843
        GEN_STORE_TN_REG(rt, T0);
844
        opn = "lwr";
845
        break;
846
    case OPC_SWR:
847
        GEN_LOAD_REG_TN(T1, rt);
848
        op_ldst(swr);
849
        opn = "swr";
850
        break;
851
    case OPC_LL:
852
        op_ldst(ll);
853
        GEN_STORE_TN_REG(rt, T0);
854
        opn = "ll";
855
        break;
856
    case OPC_SC:
857
        save_cpu_state(ctx, 1);
858
        GEN_LOAD_REG_TN(T1, rt);
859
        op_ldst(sc);
860
        GEN_STORE_TN_REG(rt, T0);
861
        opn = "sc";
862
        break;
863
    default:
864
        MIPS_INVAL(opn);
865
        generate_exception(ctx, EXCP_RI);
866
        return;
867
    }
868
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
869
}
870

    
871
/* Load and store */
872
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
873
                      int base, int16_t offset)
874
{
875
    const char *opn = "flt_ldst";
876

    
877
    if (base == 0) {
878
        GEN_LOAD_IMM_TN(T0, offset);
879
    } else if (offset == 0) {
880
        gen_op_load_gpr_T0(base);
881
    } else {
882
        gen_op_load_gpr_T0(base);
883
        gen_op_set_T1(offset);
884
        gen_op_addr_add();
885
    }
886
    /* Don't do NOP if destination is zero: we must perform the actual
887
     * memory access
888
     */
889
    switch (opc) {
890
    case OPC_LWC1:
891
        op_ldst(lwc1);
892
        GEN_STORE_FTN_FREG(ft, WT0);
893
        opn = "lwc1";
894
        break;
895
    case OPC_SWC1:
896
        GEN_LOAD_FREG_FTN(WT0, ft);
897
        op_ldst(swc1);
898
        opn = "swc1";
899
        break;
900
    case OPC_LDC1:
901
        op_ldst(ldc1);
902
        GEN_STORE_FTN_FREG(ft, DT0);
903
        opn = "ldc1";
904
        break;
905
    case OPC_SDC1:
906
        GEN_LOAD_FREG_FTN(DT0, ft);
907
        op_ldst(sdc1);
908
        opn = "sdc1";
909
        break;
910
    default:
911
        MIPS_INVAL(opn);
912
        generate_exception(ctx, EXCP_RI);
913
        return;
914
    }
915
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
916
}
917

    
918
/* Arithmetic with immediate operand */
919
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
920
                           int rs, int16_t imm)
921
{
922
    uint32_t uimm;
923
    const char *opn = "imm arith";
924

    
925
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
926
        /* if no destination, treat it as a NOP 
927
         * For addi, we must generate the overflow exception when needed.
928
         */
929
        MIPS_DEBUG("NOP");
930
        return;
931
    }
932
    uimm = (uint16_t)imm;
933
    switch (opc) {
934
    case OPC_ADDI:
935
    case OPC_ADDIU:
936
#ifdef TARGET_MIPS64
937
    case OPC_DADDI:
938
    case OPC_DADDIU:
939
#endif
940
    case OPC_SLTI:
941
    case OPC_SLTIU:
942
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
943
        /* Fall through. */
944
    case OPC_ANDI:
945
    case OPC_ORI:
946
    case OPC_XORI:
947
        GEN_LOAD_REG_TN(T0, rs);
948
        GEN_LOAD_IMM_TN(T1, uimm);
949
        break;
950
    case OPC_LUI:
951
        GEN_LOAD_IMM_TN(T0, uimm << 16);
952
        break;
953
    case OPC_SLL:
954
    case OPC_SRA:
955
    case OPC_SRL:
956
#ifdef TARGET_MIPS64
957
    case OPC_DSLL:
958
    case OPC_DSRA:
959
    case OPC_DSRL:
960
    case OPC_DSLL32:
961
    case OPC_DSRA32:
962
    case OPC_DSRL32:
963
#endif
964
        uimm &= 0x1f;
965
        GEN_LOAD_REG_TN(T0, rs);
966
        GEN_LOAD_IMM_TN(T1, uimm);
967
        break;
968
    }
969
    switch (opc) {
970
    case OPC_ADDI:
971
        save_cpu_state(ctx, 1);
972
        gen_op_addo();
973
        opn = "addi";
974
        break;
975
    case OPC_ADDIU:
976
        gen_op_add();
977
        opn = "addiu";
978
        break;
979
#ifdef TARGET_MIPS64
980
    case OPC_DADDI:
981
        save_cpu_state(ctx, 1);
982
        gen_op_daddo();
983
        opn = "daddi";
984
        break;
985
    case OPC_DADDIU:
986
        gen_op_dadd();
987
        opn = "daddiu";
988
        break;
989
#endif
990
    case OPC_SLTI:
991
        gen_op_lt();
992
        opn = "slti";
993
        break;
994
    case OPC_SLTIU:
995
        gen_op_ltu();
996
        opn = "sltiu";
997
        break;
998
    case OPC_ANDI:
999
        gen_op_and();
1000
        opn = "andi";
1001
        break;
1002
    case OPC_ORI:
1003
        gen_op_or();
1004
        opn = "ori";
1005
        break;
1006
    case OPC_XORI:
1007
        gen_op_xor();
1008
        opn = "xori";
1009
        break;
1010
    case OPC_LUI:
1011
        opn = "lui";
1012
        break;
1013
    case OPC_SLL:
1014
        gen_op_sll();
1015
        opn = "sll";
1016
        break;
1017
    case OPC_SRA:
1018
        gen_op_sra();
1019
        opn = "sra";
1020
        break;
1021
    case OPC_SRL:
1022
        switch ((ctx->opcode >> 21) & 0x1f) {
1023
        case 0:
1024
            gen_op_srl();
1025
            opn = "srl";
1026
            break;
1027
        case 1:
1028
            gen_op_rotr();
1029
            opn = "rotr";
1030
            break;
1031
        default:
1032
            MIPS_INVAL("invalid srl flag");
1033
            generate_exception(ctx, EXCP_RI);
1034
            break;
1035
        }
1036
        break;
1037
#ifdef TARGET_MIPS64
1038
    case OPC_DSLL:
1039
        gen_op_dsll();
1040
        opn = "dsll";
1041
        break;
1042
    case OPC_DSRA:
1043
        gen_op_dsra();
1044
        opn = "dsra";
1045
        break;
1046
    case OPC_DSRL:
1047
        switch ((ctx->opcode >> 21) & 0x1f) {
1048
        case 0:
1049
            gen_op_dsrl();
1050
            opn = "dsrl";
1051
            break;
1052
        case 1:
1053
            gen_op_drotr();
1054
            opn = "drotr";
1055
            break;
1056
        default:
1057
            MIPS_INVAL("invalid dsrl flag");
1058
            generate_exception(ctx, EXCP_RI);
1059
            break;
1060
        }
1061
        break;
1062
    case OPC_DSLL32:
1063
        gen_op_dsll32();
1064
        opn = "dsll32";
1065
        break;
1066
    case OPC_DSRA32:
1067
        gen_op_dsra32();
1068
        opn = "dsra32";
1069
        break;
1070
    case OPC_DSRL32:
1071
        switch ((ctx->opcode >> 21) & 0x1f) {
1072
        case 0:
1073
            gen_op_dsrl32();
1074
            opn = "dsrl32";
1075
            break;
1076
        case 1:
1077
            gen_op_drotr32();
1078
            opn = "drotr32";
1079
            break;
1080
        default:
1081
            MIPS_INVAL("invalid dsrl32 flag");
1082
            generate_exception(ctx, EXCP_RI);
1083
            break;
1084
        }
1085
        break;
1086
#endif
1087
    default:
1088
        MIPS_INVAL(opn);
1089
        generate_exception(ctx, EXCP_RI);
1090
        return;
1091
    }
1092
    GEN_STORE_TN_REG(rt, T0);
1093
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1094
}
1095

    
1096
/* Arithmetic */
1097
static void gen_arith (DisasContext *ctx, uint32_t opc,
1098
                       int rd, int rs, int rt)
1099
{
1100
    const char *opn = "arith";
1101

    
1102
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1103
       && opc != OPC_DADD && opc != OPC_DSUB) {
1104
        /* if no destination, treat it as a NOP 
1105
         * For add & sub, we must generate the overflow exception when needed.
1106
         */
1107
        MIPS_DEBUG("NOP");
1108
        return;
1109
    }
1110
    GEN_LOAD_REG_TN(T0, rs);
1111
    GEN_LOAD_REG_TN(T1, rt);
1112
    switch (opc) {
1113
    case OPC_ADD:
1114
        save_cpu_state(ctx, 1);
1115
        gen_op_addo();
1116
        opn = "add";
1117
        break;
1118
    case OPC_ADDU:
1119
        gen_op_add();
1120
        opn = "addu";
1121
        break;
1122
    case OPC_SUB:
1123
        save_cpu_state(ctx, 1);
1124
        gen_op_subo();
1125
        opn = "sub";
1126
        break;
1127
    case OPC_SUBU:
1128
        gen_op_sub();
1129
        opn = "subu";
1130
        break;
1131
#ifdef TARGET_MIPS64
1132
    case OPC_DADD:
1133
        save_cpu_state(ctx, 1);
1134
        gen_op_daddo();
1135
        opn = "dadd";
1136
        break;
1137
    case OPC_DADDU:
1138
        gen_op_dadd();
1139
        opn = "daddu";
1140
        break;
1141
    case OPC_DSUB:
1142
        save_cpu_state(ctx, 1);
1143
        gen_op_dsubo();
1144
        opn = "dsub";
1145
        break;
1146
    case OPC_DSUBU:
1147
        gen_op_dsub();
1148
        opn = "dsubu";
1149
        break;
1150
#endif
1151
    case OPC_SLT:
1152
        gen_op_lt();
1153
        opn = "slt";
1154
        break;
1155
    case OPC_SLTU:
1156
        gen_op_ltu();
1157
        opn = "sltu";
1158
        break;
1159
    case OPC_AND:
1160
        gen_op_and();
1161
        opn = "and";
1162
        break;
1163
    case OPC_NOR:
1164
        gen_op_nor();
1165
        opn = "nor";
1166
        break;
1167
    case OPC_OR:
1168
        gen_op_or();
1169
        opn = "or";
1170
        break;
1171
    case OPC_XOR:
1172
        gen_op_xor();
1173
        opn = "xor";
1174
        break;
1175
    case OPC_MUL:
1176
        gen_op_mul();
1177
        opn = "mul";
1178
        break;
1179
    case OPC_MOVN:
1180
        gen_op_movn(rd);
1181
        opn = "movn";
1182
        goto print;
1183
    case OPC_MOVZ:
1184
        gen_op_movz(rd);
1185
        opn = "movz";
1186
        goto print;
1187
    case OPC_SLLV:
1188
        gen_op_sllv();
1189
        opn = "sllv";
1190
        break;
1191
    case OPC_SRAV:
1192
        gen_op_srav();
1193
        opn = "srav";
1194
        break;
1195
    case OPC_SRLV:
1196
        switch ((ctx->opcode >> 6) & 0x1f) {
1197
        case 0:
1198
            gen_op_srlv();
1199
            opn = "srlv";
1200
            break;
1201
        case 1:
1202
            gen_op_rotrv();
1203
            opn = "rotrv";
1204
            break;
1205
        default:
1206
            MIPS_INVAL("invalid srlv flag");
1207
            generate_exception(ctx, EXCP_RI);
1208
            break;
1209
        }
1210
        break;
1211
#ifdef TARGET_MIPS64
1212
    case OPC_DSLLV:
1213
        gen_op_dsllv();
1214
        opn = "dsllv";
1215
        break;
1216
    case OPC_DSRAV:
1217
        gen_op_dsrav();
1218
        opn = "dsrav";
1219
        break;
1220
    case OPC_DSRLV:
1221
        switch ((ctx->opcode >> 6) & 0x1f) {
1222
        case 0:
1223
            gen_op_dsrlv();
1224
            opn = "dsrlv";
1225
            break;
1226
        case 1:
1227
            gen_op_drotrv();
1228
            opn = "drotrv";
1229
            break;
1230
        default:
1231
            MIPS_INVAL("invalid dsrlv flag");
1232
            generate_exception(ctx, EXCP_RI);
1233
            break;
1234
        }
1235
        break;
1236
#endif
1237
    default:
1238
        MIPS_INVAL(opn);
1239
        generate_exception(ctx, EXCP_RI);
1240
        return;
1241
    }
1242
    GEN_STORE_TN_REG(rd, T0);
1243
 print:
1244
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1245
}
1246

    
1247
/* Arithmetic on HI/LO registers */
1248
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1249
{
1250
    const char *opn = "hilo";
1251

    
1252
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1253
        /* Treat as a NOP */
1254
        MIPS_DEBUG("NOP");
1255
        return;
1256
    }
1257
    switch (opc) {
1258
    case OPC_MFHI:
1259
        gen_op_load_HI();
1260
        GEN_STORE_TN_REG(reg, T0);
1261
        opn = "mfhi";
1262
        break;
1263
    case OPC_MFLO:
1264
        gen_op_load_LO();
1265
        GEN_STORE_TN_REG(reg, T0);
1266
        opn = "mflo";
1267
        break;
1268
    case OPC_MTHI:
1269
        GEN_LOAD_REG_TN(T0, reg);
1270
        gen_op_store_HI();
1271
        opn = "mthi";
1272
        break;
1273
    case OPC_MTLO:
1274
        GEN_LOAD_REG_TN(T0, reg);
1275
        gen_op_store_LO();
1276
        opn = "mtlo";
1277
        break;
1278
    default:
1279
        MIPS_INVAL(opn);
1280
        generate_exception(ctx, EXCP_RI);
1281
        return;
1282
    }
1283
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1284
}
1285

    
1286
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1287
                        int rs, int rt)
1288
{
1289
    const char *opn = "mul/div";
1290

    
1291
    GEN_LOAD_REG_TN(T0, rs);
1292
    GEN_LOAD_REG_TN(T1, rt);
1293
    switch (opc) {
1294
    case OPC_DIV:
1295
        gen_op_div();
1296
        opn = "div";
1297
        break;
1298
    case OPC_DIVU:
1299
        gen_op_divu();
1300
        opn = "divu";
1301
        break;
1302
    case OPC_MULT:
1303
        gen_op_mult();
1304
        opn = "mult";
1305
        break;
1306
    case OPC_MULTU:
1307
        gen_op_multu();
1308
        opn = "multu";
1309
        break;
1310
#ifdef TARGET_MIPS64
1311
    case OPC_DDIV:
1312
        gen_op_ddiv();
1313
        opn = "ddiv";
1314
        break;
1315
    case OPC_DDIVU:
1316
        gen_op_ddivu();
1317
        opn = "ddivu";
1318
        break;
1319
    case OPC_DMULT:
1320
        gen_op_dmult();
1321
        opn = "dmult";
1322
        break;
1323
    case OPC_DMULTU:
1324
        gen_op_dmultu();
1325
        opn = "dmultu";
1326
        break;
1327
#endif
1328
    case OPC_MADD:
1329
        gen_op_madd();
1330
        opn = "madd";
1331
        break;
1332
    case OPC_MADDU:
1333
        gen_op_maddu();
1334
        opn = "maddu";
1335
        break;
1336
    case OPC_MSUB:
1337
        gen_op_msub();
1338
        opn = "msub";
1339
        break;
1340
    case OPC_MSUBU:
1341
        gen_op_msubu();
1342
        opn = "msubu";
1343
        break;
1344
    default:
1345
        MIPS_INVAL(opn);
1346
        generate_exception(ctx, EXCP_RI);
1347
        return;
1348
    }
1349
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1350
}
1351

    
1352
static void gen_cl (DisasContext *ctx, uint32_t opc,
1353
                    int rd, int rs)
1354
{
1355
    const char *opn = "CLx";
1356
    if (rd == 0) {
1357
        /* Treat as a NOP */
1358
        MIPS_DEBUG("NOP");
1359
        return;
1360
    }
1361
    GEN_LOAD_REG_TN(T0, rs);
1362
    switch (opc) {
1363
    case OPC_CLO:
1364
        gen_op_clo();
1365
        opn = "clo";
1366
        break;
1367
    case OPC_CLZ:
1368
        gen_op_clz();
1369
        opn = "clz";
1370
        break;
1371
#ifdef TARGET_MIPS64
1372
    case OPC_DCLO:
1373
        gen_op_dclo();
1374
        opn = "dclo";
1375
        break;
1376
    case OPC_DCLZ:
1377
        gen_op_dclz();
1378
        opn = "dclz";
1379
        break;
1380
#endif
1381
    default:
1382
        MIPS_INVAL(opn);
1383
        generate_exception(ctx, EXCP_RI);
1384
        return;
1385
    }
1386
    gen_op_store_T0_gpr(rd);
1387
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1388
}
1389

    
1390
/* Traps */
1391
static void gen_trap (DisasContext *ctx, uint32_t opc,
1392
                      int rs, int rt, int16_t imm)
1393
{
1394
    int cond;
1395

    
1396
    cond = 0;
1397
    /* Load needed operands */
1398
    switch (opc) {
1399
    case OPC_TEQ:
1400
    case OPC_TGE:
1401
    case OPC_TGEU:
1402
    case OPC_TLT:
1403
    case OPC_TLTU:
1404
    case OPC_TNE:
1405
        /* Compare two registers */
1406
        if (rs != rt) {
1407
            GEN_LOAD_REG_TN(T0, rs);
1408
            GEN_LOAD_REG_TN(T1, rt);
1409
            cond = 1;
1410
        }
1411
        break;
1412
    case OPC_TEQI:
1413
    case OPC_TGEI:
1414
    case OPC_TGEIU:
1415
    case OPC_TLTI:
1416
    case OPC_TLTIU:
1417
    case OPC_TNEI:
1418
        /* Compare register to immediate */
1419
        if (rs != 0 || imm != 0) {
1420
            GEN_LOAD_REG_TN(T0, rs);
1421
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1422
            cond = 1;
1423
        }
1424
        break;
1425
    }
1426
    if (cond == 0) {
1427
        switch (opc) {
1428
        case OPC_TEQ:   /* rs == rs */
1429
        case OPC_TEQI:  /* r0 == 0  */
1430
        case OPC_TGE:   /* rs >= rs */
1431
        case OPC_TGEI:  /* r0 >= 0  */
1432
        case OPC_TGEU:  /* rs >= rs unsigned */
1433
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1434
            /* Always trap */
1435
            gen_op_set_T0(1);
1436
            break;
1437
        case OPC_TLT:   /* rs < rs           */
1438
        case OPC_TLTI:  /* r0 < 0            */
1439
        case OPC_TLTU:  /* rs < rs unsigned  */
1440
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1441
        case OPC_TNE:   /* rs != rs          */
1442
        case OPC_TNEI:  /* r0 != 0           */
1443
            /* Never trap: treat as NOP */
1444
            return;
1445
        default:
1446
            MIPS_INVAL("trap");
1447
            generate_exception(ctx, EXCP_RI);
1448
            return;
1449
        }
1450
    } else {
1451
        switch (opc) {
1452
        case OPC_TEQ:
1453
        case OPC_TEQI:
1454
            gen_op_eq();
1455
            break;
1456
        case OPC_TGE:
1457
        case OPC_TGEI:
1458
            gen_op_ge();
1459
            break;
1460
        case OPC_TGEU:
1461
        case OPC_TGEIU:
1462
            gen_op_geu();
1463
            break;
1464
        case OPC_TLT:
1465
        case OPC_TLTI:
1466
            gen_op_lt();
1467
            break;
1468
        case OPC_TLTU:
1469
        case OPC_TLTIU:
1470
            gen_op_ltu();
1471
            break;
1472
        case OPC_TNE:
1473
        case OPC_TNEI:
1474
            gen_op_ne();
1475
            break;
1476
        default:
1477
            MIPS_INVAL("trap");
1478
            generate_exception(ctx, EXCP_RI);
1479
            return;
1480
        }
1481
    }
1482
    save_cpu_state(ctx, 1);
1483
    gen_op_trap();
1484
    ctx->bstate = BS_STOP;
1485
}
1486

    
1487
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1488
{
1489
    TranslationBlock *tb;
1490
    tb = ctx->tb;
1491
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1492
        if (n == 0)
1493
            gen_op_goto_tb0(TBPARAM(tb));
1494
        else
1495
            gen_op_goto_tb1(TBPARAM(tb));
1496
        gen_op_save_pc(dest);
1497
        gen_op_set_T0((long)tb + n);
1498
    } else {
1499
        gen_op_save_pc(dest);
1500
        gen_op_reset_T0();
1501
    }
1502
    gen_op_exit_tb();
1503
}
1504

    
1505
/* Branches (before delay slot) */
1506
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1507
                                int rs, int rt, int32_t offset)
1508
{
1509
    target_ulong btarget = -1;
1510
    int blink = 0;
1511
    int bcond = 0;
1512

    
1513
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1514
#ifdef MIPS_DEBUG_DISAS
1515
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1516
            fprintf(logfile,
1517
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1518
                    ctx->pc);
1519
        }
1520
#endif
1521
        generate_exception(ctx, EXCP_RI);
1522
        return;
1523
    }
1524

    
1525
    /* Load needed operands */
1526
    switch (opc) {
1527
    case OPC_BEQ:
1528
    case OPC_BEQL:
1529
    case OPC_BNE:
1530
    case OPC_BNEL:
1531
        /* Compare two registers */
1532
        if (rs != rt) {
1533
            GEN_LOAD_REG_TN(T0, rs);
1534
            GEN_LOAD_REG_TN(T1, rt);
1535
            bcond = 1;
1536
        }
1537
        btarget = ctx->pc + 4 + offset;
1538
        break;
1539
    case OPC_BGEZ:
1540
    case OPC_BGEZAL:
1541
    case OPC_BGEZALL:
1542
    case OPC_BGEZL:
1543
    case OPC_BGTZ:
1544
    case OPC_BGTZL:
1545
    case OPC_BLEZ:
1546
    case OPC_BLEZL:
1547
    case OPC_BLTZ:
1548
    case OPC_BLTZAL:
1549
    case OPC_BLTZALL:
1550
    case OPC_BLTZL:
1551
        /* Compare to zero */
1552
        if (rs != 0) {
1553
            gen_op_load_gpr_T0(rs);
1554
            bcond = 1;
1555
        }
1556
        btarget = ctx->pc + 4 + offset;
1557
        break;
1558
    case OPC_J:
1559
    case OPC_JAL:
1560
        /* Jump to immediate */
1561
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1562
        break;
1563
    case OPC_JR:
1564
    case OPC_JALR:
1565
        /* Jump to register */
1566
        if (offset != 0 && offset != 16) {
1567
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1568
               others are reserved. */
1569
            MIPS_INVAL("jump hint");
1570
            generate_exception(ctx, EXCP_RI);
1571
            return;
1572
        }
1573
        GEN_LOAD_REG_TN(T2, rs);
1574
        break;
1575
    default:
1576
        MIPS_INVAL("branch/jump");
1577
        generate_exception(ctx, EXCP_RI);
1578
        return;
1579
    }
1580
    if (bcond == 0) {
1581
        /* No condition to be computed */
1582
        switch (opc) {
1583
        case OPC_BEQ:     /* rx == rx        */
1584
        case OPC_BEQL:    /* rx == rx likely */
1585
        case OPC_BGEZ:    /* 0 >= 0          */
1586
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1587
        case OPC_BLEZ:    /* 0 <= 0          */
1588
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1589
            /* Always take */
1590
            ctx->hflags |= MIPS_HFLAG_B;
1591
            MIPS_DEBUG("balways");
1592
            break;
1593
        case OPC_BGEZAL:  /* 0 >= 0          */
1594
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1595
            /* Always take and link */
1596
            blink = 31;
1597
            ctx->hflags |= MIPS_HFLAG_B;
1598
            MIPS_DEBUG("balways and link");
1599
            break;
1600
        case OPC_BNE:     /* rx != rx        */
1601
        case OPC_BGTZ:    /* 0 > 0           */
1602
        case OPC_BLTZ:    /* 0 < 0           */
1603
            /* Treated as NOP */
1604
            MIPS_DEBUG("bnever (NOP)");
1605
            return;
1606
        case OPC_BLTZAL:  /* 0 < 0           */
1607
            gen_op_set_T0(ctx->pc + 8);
1608
            gen_op_store_T0_gpr(31);
1609
            MIPS_DEBUG("bnever and link");
1610
            return;
1611
        case OPC_BLTZALL: /* 0 < 0 likely */
1612
            gen_op_set_T0(ctx->pc + 8);
1613
            gen_op_store_T0_gpr(31);
1614
            /* Skip the instruction in the delay slot */
1615
            MIPS_DEBUG("bnever, link and skip");
1616
            ctx->pc += 4;
1617
            return;
1618
        case OPC_BNEL:    /* rx != rx likely */
1619
        case OPC_BGTZL:   /* 0 > 0 likely */
1620
        case OPC_BLTZL:   /* 0 < 0 likely */
1621
            /* Skip the instruction in the delay slot */
1622
            MIPS_DEBUG("bnever and skip");
1623
            ctx->pc += 4;
1624
            return;
1625
        case OPC_J:
1626
            ctx->hflags |= MIPS_HFLAG_B;
1627
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1628
            break;
1629
        case OPC_JAL:
1630
            blink = 31;
1631
            ctx->hflags |= MIPS_HFLAG_B;
1632
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1633
            break;
1634
        case OPC_JR:
1635
            ctx->hflags |= MIPS_HFLAG_BR;
1636
            MIPS_DEBUG("jr %s", regnames[rs]);
1637
            break;
1638
        case OPC_JALR:
1639
            blink = rt;
1640
            ctx->hflags |= MIPS_HFLAG_BR;
1641
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1642
            break;
1643
        default:
1644
            MIPS_INVAL("branch/jump");
1645
            generate_exception(ctx, EXCP_RI);
1646
            return;
1647
        }
1648
    } else {
1649
        switch (opc) {
1650
        case OPC_BEQ:
1651
            gen_op_eq();
1652
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1653
                       regnames[rs], regnames[rt], btarget);
1654
            goto not_likely;
1655
        case OPC_BEQL:
1656
            gen_op_eq();
1657
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1658
                       regnames[rs], regnames[rt], btarget);
1659
            goto likely;
1660
        case OPC_BNE:
1661
            gen_op_ne();
1662
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1663
                       regnames[rs], regnames[rt], btarget);
1664
            goto not_likely;
1665
        case OPC_BNEL:
1666
            gen_op_ne();
1667
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1668
                       regnames[rs], regnames[rt], btarget);
1669
            goto likely;
1670
        case OPC_BGEZ:
1671
            gen_op_gez();
1672
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1673
            goto not_likely;
1674
        case OPC_BGEZL:
1675
            gen_op_gez();
1676
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1677
            goto likely;
1678
        case OPC_BGEZAL:
1679
            gen_op_gez();
1680
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1681
            blink = 31;
1682
            goto not_likely;
1683
        case OPC_BGEZALL:
1684
            gen_op_gez();
1685
            blink = 31;
1686
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1687
            goto likely;
1688
        case OPC_BGTZ:
1689
            gen_op_gtz();
1690
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1691
            goto not_likely;
1692
        case OPC_BGTZL:
1693
            gen_op_gtz();
1694
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1695
            goto likely;
1696
        case OPC_BLEZ:
1697
            gen_op_lez();
1698
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1699
            goto not_likely;
1700
        case OPC_BLEZL:
1701
            gen_op_lez();
1702
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1703
            goto likely;
1704
        case OPC_BLTZ:
1705
            gen_op_ltz();
1706
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1707
            goto not_likely;
1708
        case OPC_BLTZL:
1709
            gen_op_ltz();
1710
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1711
            goto likely;
1712
        case OPC_BLTZAL:
1713
            gen_op_ltz();
1714
            blink = 31;
1715
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1716
        not_likely:
1717
            ctx->hflags |= MIPS_HFLAG_BC;
1718
            gen_op_set_bcond();
1719
            break;
1720
        case OPC_BLTZALL:
1721
            gen_op_ltz();
1722
            blink = 31;
1723
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1724
        likely:
1725
            ctx->hflags |= MIPS_HFLAG_BL;
1726
            gen_op_set_bcond();
1727
            gen_op_save_bcond();
1728
            break;
1729
        default:
1730
            MIPS_INVAL("conditional branch/jump");
1731
            generate_exception(ctx, EXCP_RI);
1732
            return;
1733
        }
1734
    }
1735
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1736
               blink, ctx->hflags, btarget);
1737
    ctx->btarget = btarget;
1738
    if (blink > 0) {
1739
        gen_op_set_T0(ctx->pc + 8);
1740
        gen_op_store_T0_gpr(blink);
1741
    }
1742
}
1743

    
1744
/* special3 bitfield operations */
1745
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1746
                       int rs, int lsb, int msb)
1747
{
1748
    GEN_LOAD_REG_TN(T1, rs);
1749
    switch (opc) {
1750
    case OPC_EXT:
1751
        if (lsb + msb > 31)
1752
            goto fail;
1753
        gen_op_ext(lsb, msb + 1);
1754
        break;
1755
    case OPC_DEXTM:
1756
        if (lsb + msb > 63)
1757
            goto fail;
1758
        gen_op_ext(lsb, msb + 1 + 32);
1759
        break;
1760
    case OPC_DEXTU:
1761
        if (lsb + msb > 63)
1762
            goto fail;
1763
        gen_op_ext(lsb + 32, msb + 1);
1764
        break;
1765
    case OPC_DEXT:
1766
        gen_op_ext(lsb, msb + 1);
1767
        break;
1768
    case OPC_INS:
1769
        if (lsb > msb)
1770
            goto fail;
1771
        GEN_LOAD_REG_TN(T0, rt);
1772
        gen_op_ins(lsb, msb - lsb + 1);
1773
        break;
1774
    case OPC_DINSM:
1775
        if (lsb > msb)
1776
            goto fail;
1777
        GEN_LOAD_REG_TN(T0, rt);
1778
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1779
        break;
1780
    case OPC_DINSU:
1781
        if (lsb > msb)
1782
            goto fail;
1783
        GEN_LOAD_REG_TN(T0, rt);
1784
        gen_op_ins(lsb + 32, msb - lsb + 1);
1785
        break;
1786
    case OPC_DINS:
1787
        if (lsb > msb)
1788
            goto fail;
1789
        GEN_LOAD_REG_TN(T0, rt);
1790
        gen_op_ins(lsb, msb - lsb + 1);
1791
        break;
1792
    default:
1793
fail:
1794
        MIPS_INVAL("bitops");
1795
        generate_exception(ctx, EXCP_RI);
1796
        return;
1797
    }
1798
    GEN_STORE_TN_REG(rt, T0);
1799
}
1800

    
1801
/* CP0 (MMU and control) */
1802
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1803
{
1804
    const char *rn = "invalid";
1805

    
1806
    switch (reg) {
1807
    case 0:
1808
        switch (sel) {
1809
        case 0:
1810
            gen_op_mfc0_index();
1811
            rn = "Index";
1812
            break;
1813
        case 1:
1814
//            gen_op_mfc0_mvpcontrol(); /* MT ASE */
1815
            rn = "MVPControl";
1816
//            break;
1817
        case 2:
1818
//            gen_op_mfc0_mvpconf0(); /* MT ASE */
1819
            rn = "MVPConf0";
1820
//            break;
1821
        case 3:
1822
//            gen_op_mfc0_mvpconf1(); /* MT ASE */
1823
            rn = "MVPConf1";
1824
//            break;
1825
        default:
1826
            goto die;
1827
        }
1828
        break;
1829
    case 1:
1830
        switch (sel) {
1831
        case 0:
1832
            gen_op_mfc0_random();
1833
            rn = "Random";
1834
            break;
1835
        case 1:
1836
//            gen_op_mfc0_vpecontrol(); /* MT ASE */
1837
            rn = "VPEControl";
1838
//            break;
1839
        case 2:
1840
//            gen_op_mfc0_vpeconf0(); /* MT ASE */
1841
            rn = "VPEConf0";
1842
//            break;
1843
        case 3:
1844
//            gen_op_mfc0_vpeconf1(); /* MT ASE */
1845
            rn = "VPEConf1";
1846
//            break;
1847
        case 4:
1848
//            gen_op_mfc0_YQMask(); /* MT ASE */
1849
            rn = "YQMask";
1850
//            break;
1851
        case 5:
1852
//            gen_op_mfc0_vpeschedule(); /* MT ASE */
1853
            rn = "VPESchedule";
1854
//            break;
1855
        case 6:
1856
//            gen_op_mfc0_vpeschefback(); /* MT ASE */
1857
            rn = "VPEScheFBack";
1858
//            break;
1859
        case 7:
1860
//            gen_op_mfc0_vpeopt(); /* MT ASE */
1861
            rn = "VPEOpt";
1862
//            break;
1863
        default:
1864
            goto die;
1865
        }
1866
        break;
1867
    case 2:
1868
        switch (sel) {
1869
        case 0:
1870
            gen_op_mfc0_entrylo0();
1871
            rn = "EntryLo0";
1872
            break;
1873
        case 1:
1874
//            gen_op_mfc0_tcstatus(); /* MT ASE */
1875
            rn = "TCStatus";
1876
//            break;
1877
        case 2:
1878
//            gen_op_mfc0_tcbind(); /* MT ASE */
1879
            rn = "TCBind";
1880
//            break;
1881
        case 3:
1882
//            gen_op_mfc0_tcrestart(); /* MT ASE */
1883
            rn = "TCRestart";
1884
//            break;
1885
        case 4:
1886
//            gen_op_mfc0_tchalt(); /* MT ASE */
1887
            rn = "TCHalt";
1888
//            break;
1889
        case 5:
1890
//            gen_op_mfc0_tccontext(); /* MT ASE */
1891
            rn = "TCContext";
1892
//            break;
1893
        case 6:
1894
//            gen_op_mfc0_tcschedule(); /* MT ASE */
1895
            rn = "TCSchedule";
1896
//            break;
1897
        case 7:
1898
//            gen_op_mfc0_tcschefback(); /* MT ASE */
1899
            rn = "TCScheFBack";
1900
//            break;
1901
        default:
1902
            goto die;
1903
        }
1904
        break;
1905
    case 3:
1906
        switch (sel) {
1907
        case 0:
1908
            gen_op_mfc0_entrylo1();
1909
            rn = "EntryLo1";
1910
            break;
1911
        default:
1912
            goto die;
1913
        }
1914
        break;
1915
    case 4:
1916
        switch (sel) {
1917
        case 0:
1918
            gen_op_mfc0_context();
1919
            rn = "Context";
1920
            break;
1921
        case 1:
1922
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1923
            rn = "ContextConfig";
1924
//            break;
1925
        default:
1926
            goto die;
1927
        }
1928
        break;
1929
    case 5:
1930
        switch (sel) {
1931
        case 0:
1932
            gen_op_mfc0_pagemask();
1933
            rn = "PageMask";
1934
            break;
1935
        case 1:
1936
            gen_op_mfc0_pagegrain();
1937
            rn = "PageGrain";
1938
            break;
1939
        default:
1940
            goto die;
1941
        }
1942
        break;
1943
    case 6:
1944
        switch (sel) {
1945
        case 0:
1946
            gen_op_mfc0_wired();
1947
            rn = "Wired";
1948
            break;
1949
        case 1:
1950
//            gen_op_mfc0_srsconf0(); /* shadow registers */
1951
            rn = "SRSConf0";
1952
//            break;
1953
        case 2:
1954
//            gen_op_mfc0_srsconf1(); /* shadow registers */
1955
            rn = "SRSConf1";
1956
//            break;
1957
        case 3:
1958
//            gen_op_mfc0_srsconf2(); /* shadow registers */
1959
            rn = "SRSConf2";
1960
//            break;
1961
        case 4:
1962
//            gen_op_mfc0_srsconf3(); /* shadow registers */
1963
            rn = "SRSConf3";
1964
//            break;
1965
        case 5:
1966
//            gen_op_mfc0_srsconf4(); /* shadow registers */
1967
            rn = "SRSConf4";
1968
//            break;
1969
        default:
1970
            goto die;
1971
        }
1972
        break;
1973
    case 7:
1974
        switch (sel) {
1975
        case 0:
1976
            gen_op_mfc0_hwrena();
1977
            rn = "HWREna";
1978
            break;
1979
        default:
1980
            goto die;
1981
        }
1982
        break;
1983
    case 8:
1984
        switch (sel) {
1985
        case 0:
1986
            gen_op_mfc0_badvaddr();
1987
            rn = "BadVaddr";
1988
            break;
1989
        default:
1990
            goto die;
1991
       }
1992
        break;
1993
    case 9:
1994
        switch (sel) {
1995
        case 0:
1996
            gen_op_mfc0_count();
1997
            rn = "Count";
1998
            break;
1999
        /* 6,7 are implementation dependent */
2000
        default:
2001
            goto die;
2002
        }
2003
        break;
2004
    case 10:
2005
        switch (sel) {
2006
        case 0:
2007
            gen_op_mfc0_entryhi();
2008
            rn = "EntryHi";
2009
            break;
2010
        default:
2011
            goto die;
2012
        }
2013
        break;
2014
    case 11:
2015
        switch (sel) {
2016
        case 0:
2017
            gen_op_mfc0_compare();
2018
            rn = "Compare";
2019
            break;
2020
        /* 6,7 are implementation dependent */
2021
        default:
2022
            goto die;
2023
        }
2024
        break;
2025
    case 12:
2026
        switch (sel) {
2027
        case 0:
2028
            gen_op_mfc0_status();
2029
            rn = "Status";
2030
            break;
2031
        case 1:
2032
            gen_op_mfc0_intctl();
2033
            rn = "IntCtl";
2034
            break;
2035
        case 2:
2036
            gen_op_mfc0_srsctl();
2037
            rn = "SRSCtl";
2038
            break;
2039
        case 3:
2040
//            gen_op_mfc0_srsmap(); /* shadow registers */
2041
            rn = "SRSMap";
2042
//            break;
2043
        default:
2044
            goto die;
2045
       }
2046
        break;
2047
    case 13:
2048
        switch (sel) {
2049
        case 0:
2050
            gen_op_mfc0_cause();
2051
            rn = "Cause";
2052
            break;
2053
        default:
2054
            goto die;
2055
       }
2056
        break;
2057
    case 14:
2058
        switch (sel) {
2059
        case 0:
2060
            gen_op_mfc0_epc();
2061
            rn = "EPC";
2062
            break;
2063
        default:
2064
            goto die;
2065
        }
2066
        break;
2067
    case 15:
2068
        switch (sel) {
2069
        case 0:
2070
            gen_op_mfc0_prid();
2071
            rn = "PRid";
2072
            break;
2073
        case 1:
2074
            gen_op_mfc0_ebase();
2075
            rn = "EBase";
2076
            break;
2077
        default:
2078
            goto die;
2079
       }
2080
        break;
2081
    case 16:
2082
        switch (sel) {
2083
        case 0:
2084
            gen_op_mfc0_config0();
2085
            rn = "Config";
2086
            break;
2087
        case 1:
2088
            gen_op_mfc0_config1();
2089
            rn = "Config1";
2090
            break;
2091
        case 2:
2092
            gen_op_mfc0_config2();
2093
            rn = "Config2";
2094
            break;
2095
        case 3:
2096
            gen_op_mfc0_config3();
2097
            rn = "Config3";
2098
            break;
2099
        /* 4,5 are reserved */
2100
        /* 6,7 are implementation dependent */
2101
        case 6:
2102
            gen_op_mfc0_config6();
2103
            rn = "Config6";
2104
            break;
2105
        case 7:
2106
            gen_op_mfc0_config7();
2107
            rn = "Config7";
2108
            break;
2109
        default:
2110
            goto die;
2111
        }
2112
        break;
2113
    case 17:
2114
        switch (sel) {
2115
        case 0:
2116
            gen_op_mfc0_lladdr();
2117
            rn = "LLAddr";
2118
            break;
2119
        default:
2120
            goto die;
2121
        }
2122
        break;
2123
    case 18:
2124
        switch (sel) {
2125
        case 0:
2126
            gen_op_mfc0_watchlo0();
2127
            rn = "WatchLo";
2128
            break;
2129
        case 1:
2130
//            gen_op_mfc0_watchlo1();
2131
            rn = "WatchLo1";
2132
//            break;
2133
        case 2:
2134
//            gen_op_mfc0_watchlo2();
2135
            rn = "WatchLo2";
2136
//            break;
2137
        case 3:
2138
//            gen_op_mfc0_watchlo3();
2139
            rn = "WatchLo3";
2140
//            break;
2141
        case 4:
2142
//            gen_op_mfc0_watchlo4();
2143
            rn = "WatchLo4";
2144
//            break;
2145
        case 5:
2146
//            gen_op_mfc0_watchlo5();
2147
            rn = "WatchLo5";
2148
//            break;
2149
        case 6:
2150
//            gen_op_mfc0_watchlo6();
2151
            rn = "WatchLo6";
2152
//            break;
2153
        case 7:
2154
//            gen_op_mfc0_watchlo7();
2155
            rn = "WatchLo7";
2156
//            break;
2157
        default:
2158
            goto die;
2159
        }
2160
        break;
2161
    case 19:
2162
        switch (sel) {
2163
        case 0:
2164
            gen_op_mfc0_watchhi0();
2165
            rn = "WatchHi";
2166
            break;
2167
        case 1:
2168
//            gen_op_mfc0_watchhi1();
2169
            rn = "WatchHi1";
2170
//            break;
2171
        case 2:
2172
//            gen_op_mfc0_watchhi2();
2173
            rn = "WatchHi2";
2174
//            break;
2175
        case 3:
2176
//            gen_op_mfc0_watchhi3();
2177
            rn = "WatchHi3";
2178
//            break;
2179
        case 4:
2180
//            gen_op_mfc0_watchhi4();
2181
            rn = "WatchHi4";
2182
//            break;
2183
        case 5:
2184
//            gen_op_mfc0_watchhi5();
2185
            rn = "WatchHi5";
2186
//            break;
2187
        case 6:
2188
//            gen_op_mfc0_watchhi6();
2189
            rn = "WatchHi6";
2190
//            break;
2191
        case 7:
2192
//            gen_op_mfc0_watchhi7();
2193
            rn = "WatchHi7";
2194
//            break;
2195
        default:
2196
            goto die;
2197
        }
2198
        break;
2199
    case 20:
2200
        switch (sel) {
2201
        case 0:
2202
#ifdef TARGET_MIPS64
2203
            gen_op_mfc0_xcontext();
2204
            rn = "XContext";
2205
            break;
2206
#endif
2207
        default:
2208
            goto die;
2209
        }
2210
        break;
2211
    case 21:
2212
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2213
        switch (sel) {
2214
        case 0:
2215
            gen_op_mfc0_framemask();
2216
            rn = "Framemask";
2217
            break;
2218
        default:
2219
            goto die;
2220
        }
2221
        break;
2222
    case 22:
2223
        /* ignored */
2224
        rn = "'Diagnostic"; /* implementation dependent */
2225
        break;
2226
    case 23:
2227
        switch (sel) {
2228
        case 0:
2229
            gen_op_mfc0_debug(); /* EJTAG support */
2230
            rn = "Debug";
2231
            break;
2232
        case 1:
2233
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2234
            rn = "TraceControl";
2235
//            break;
2236
        case 2:
2237
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2238
            rn = "TraceControl2";
2239
//            break;
2240
        case 3:
2241
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2242
            rn = "UserTraceData";
2243
//            break;
2244
        case 4:
2245
//            gen_op_mfc0_debug(); /* PDtrace support */
2246
            rn = "TraceBPC";
2247
//            break;
2248
        default:
2249
            goto die;
2250
        }
2251
        break;
2252
    case 24:
2253
        switch (sel) {
2254
        case 0:
2255
            gen_op_mfc0_depc(); /* EJTAG support */
2256
            rn = "DEPC";
2257
            break;
2258
        default:
2259
            goto die;
2260
        }
2261
        break;
2262
    case 25:
2263
        switch (sel) {
2264
        case 0:
2265
            gen_op_mfc0_performance0();
2266
            rn = "Performance0";
2267
            break;
2268
        case 1:
2269
//            gen_op_mfc0_performance1();
2270
            rn = "Performance1";
2271
//            break;
2272
        case 2:
2273
//            gen_op_mfc0_performance2();
2274
            rn = "Performance2";
2275
//            break;
2276
        case 3:
2277
//            gen_op_mfc0_performance3();
2278
            rn = "Performance3";
2279
//            break;
2280
        case 4:
2281
//            gen_op_mfc0_performance4();
2282
            rn = "Performance4";
2283
//            break;
2284
        case 5:
2285
//            gen_op_mfc0_performance5();
2286
            rn = "Performance5";
2287
//            break;
2288
        case 6:
2289
//            gen_op_mfc0_performance6();
2290
            rn = "Performance6";
2291
//            break;
2292
        case 7:
2293
//            gen_op_mfc0_performance7();
2294
            rn = "Performance7";
2295
//            break;
2296
        default:
2297
            goto die;
2298
        }
2299
        break;
2300
    case 26:
2301
       rn = "ECC";
2302
       break;
2303
    case 27:
2304
        switch (sel) {
2305
        /* ignored */
2306
        case 0 ... 3:
2307
            rn = "CacheErr";
2308
            break;
2309
        default:
2310
            goto die;
2311
        }
2312
        break;
2313
    case 28:
2314
        switch (sel) {
2315
        case 0:
2316
        case 2:
2317
        case 4:
2318
        case 6:
2319
            gen_op_mfc0_taglo();
2320
            rn = "TagLo";
2321
            break;
2322
        case 1:
2323
        case 3:
2324
        case 5:
2325
        case 7:
2326
            gen_op_mfc0_datalo();
2327
            rn = "DataLo";
2328
            break;
2329
        default:
2330
            goto die;
2331
        }
2332
        break;
2333
    case 29:
2334
        switch (sel) {
2335
        case 0:
2336
        case 2:
2337
        case 4:
2338
        case 6:
2339
            gen_op_mfc0_taghi();
2340
            rn = "TagHi";
2341
            break;
2342
        case 1:
2343
        case 3:
2344
        case 5:
2345
        case 7:
2346
            gen_op_mfc0_datahi();
2347
            rn = "DataHi";
2348
            break;
2349
        default:
2350
            goto die;
2351
        }
2352
        break;
2353
    case 30:
2354
        switch (sel) {
2355
        case 0:
2356
            gen_op_mfc0_errorepc();
2357
            rn = "ErrorEPC";
2358
            break;
2359
        default:
2360
            goto die;
2361
        }
2362
        break;
2363
    case 31:
2364
        switch (sel) {
2365
        case 0:
2366
            gen_op_mfc0_desave(); /* EJTAG support */
2367
            rn = "DESAVE";
2368
            break;
2369
        default:
2370
            goto die;
2371
        }
2372
        break;
2373
    default:
2374
       goto die;
2375
    }
2376
#if defined MIPS_DEBUG_DISAS
2377
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2378
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2379
                rn, reg, sel);
2380
    }
2381
#endif
2382
    return;
2383

    
2384
die:
2385
#if defined MIPS_DEBUG_DISAS
2386
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2387
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2388
                rn, reg, sel);
2389
    }
2390
#endif
2391
    generate_exception(ctx, EXCP_RI);
2392
}
2393

    
2394
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2395
{
2396
    const char *rn = "invalid";
2397

    
2398
    switch (reg) {
2399
    case 0:
2400
        switch (sel) {
2401
        case 0:
2402
           gen_op_mtc0_index();
2403
            rn = "Index";
2404
            break;
2405
        case 1:
2406
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
2407
            rn = "MVPControl";
2408
//            break;
2409
        case 2:
2410
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
2411
            rn = "MVPConf0";
2412
//            break;
2413
        case 3:
2414
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
2415
            rn = "MVPConf1";
2416
//            break;
2417
        default:
2418
            goto die;
2419
        }
2420
        break;
2421
    case 1:
2422
        switch (sel) {
2423
        case 0:
2424
            /* ignored */
2425
            rn = "Random";
2426
            break;
2427
        case 1:
2428
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
2429
            rn = "VPEControl";
2430
//            break;
2431
        case 2:
2432
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
2433
            rn = "VPEConf0";
2434
//            break;
2435
        case 3:
2436
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
2437
            rn = "VPEConf1";
2438
//            break;
2439
        case 4:
2440
//            gen_op_mtc0_YQMask(); /* MT ASE */
2441
            rn = "YQMask";
2442
//            break;
2443
        case 5:
2444
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
2445
            rn = "VPESchedule";
2446
//            break;
2447
        case 6:
2448
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
2449
            rn = "VPEScheFBack";
2450
//            break;
2451
        case 7:
2452
//            gen_op_mtc0_vpeopt(); /* MT ASE */
2453
            rn = "VPEOpt";
2454
//            break;
2455
        default:
2456
            goto die;
2457
        }
2458
        break;
2459
    case 2:
2460
        switch (sel) {
2461
        case 0:
2462
            gen_op_mtc0_entrylo0();
2463
            rn = "EntryLo0";
2464
            break;
2465
        case 1:
2466
//            gen_op_mtc0_tcstatus(); /* MT ASE */
2467
            rn = "TCStatus";
2468
//            break;
2469
        case 2:
2470
//            gen_op_mtc0_tcbind(); /* MT ASE */
2471
            rn = "TCBind";
2472
//            break;
2473
        case 3:
2474
//            gen_op_mtc0_tcrestart(); /* MT ASE */
2475
            rn = "TCRestart";
2476
//            break;
2477
        case 4:
2478
//            gen_op_mtc0_tchalt(); /* MT ASE */
2479
            rn = "TCHalt";
2480
//            break;
2481
        case 5:
2482
//            gen_op_mtc0_tccontext(); /* MT ASE */
2483
            rn = "TCContext";
2484
//            break;
2485
        case 6:
2486
//            gen_op_mtc0_tcschedule(); /* MT ASE */
2487
            rn = "TCSchedule";
2488
//            break;
2489
        case 7:
2490
//            gen_op_mtc0_tcschefback(); /* MT ASE */
2491
            rn = "TCScheFBack";
2492
//            break;
2493
        default:
2494
            goto die;
2495
        }
2496
        break;
2497
    case 3:
2498
        switch (sel) {
2499
        case 0:
2500
            gen_op_mtc0_entrylo1();
2501
            rn = "EntryLo1";
2502
            break;
2503
        default:
2504
            goto die;
2505
        }
2506
        break;
2507
    case 4:
2508
        switch (sel) {
2509
        case 0:
2510
            gen_op_mtc0_context();
2511
            rn = "Context";
2512
            break;
2513
        case 1:
2514
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2515
            rn = "ContextConfig";
2516
//            break;
2517
        default:
2518
            goto die;
2519
        }
2520
        break;
2521
    case 5:
2522
        switch (sel) {
2523
        case 0:
2524
            gen_op_mtc0_pagemask();
2525
            rn = "PageMask";
2526
            break;
2527
        case 1:
2528
            gen_op_mtc0_pagegrain();
2529
            rn = "PageGrain";
2530
            break;
2531
        default:
2532
            goto die;
2533
        }
2534
        break;
2535
    case 6:
2536
        switch (sel) {
2537
        case 0:
2538
            gen_op_mtc0_wired();
2539
            rn = "Wired";
2540
            break;
2541
        case 1:
2542
//            gen_op_mtc0_srsconf0(); /* shadow registers */
2543
            rn = "SRSConf0";
2544
//            break;
2545
        case 2:
2546
//            gen_op_mtc0_srsconf1(); /* shadow registers */
2547
            rn = "SRSConf1";
2548
//            break;
2549
        case 3:
2550
//            gen_op_mtc0_srsconf2(); /* shadow registers */
2551
            rn = "SRSConf2";
2552
//            break;
2553
        case 4:
2554
//            gen_op_mtc0_srsconf3(); /* shadow registers */
2555
            rn = "SRSConf3";
2556
//            break;
2557
        case 5:
2558
//            gen_op_mtc0_srsconf4(); /* shadow registers */
2559
            rn = "SRSConf4";
2560
//            break;
2561
        default:
2562
            goto die;
2563
        }
2564
        break;
2565
    case 7:
2566
        switch (sel) {
2567
        case 0:
2568
            gen_op_mtc0_hwrena();
2569
            rn = "HWREna";
2570
            break;
2571
        default:
2572
            goto die;
2573
        }
2574
        break;
2575
    case 8:
2576
        /* ignored */
2577
        rn = "BadVaddr";
2578
        break;
2579
    case 9:
2580
        switch (sel) {
2581
        case 0:
2582
            gen_op_mtc0_count();
2583
            rn = "Count";
2584
            break;
2585
        /* 6,7 are implementation dependent */
2586
        default:
2587
            goto die;
2588
        }
2589
        /* Stop translation as we may have switched the execution mode */
2590
        ctx->bstate = BS_STOP;
2591
        break;
2592
    case 10:
2593
        switch (sel) {
2594
        case 0:
2595
            gen_op_mtc0_entryhi();
2596
            rn = "EntryHi";
2597
            break;
2598
        default:
2599
            goto die;
2600
        }
2601
        break;
2602
    case 11:
2603
        switch (sel) {
2604
        case 0:
2605
            gen_op_mtc0_compare();
2606
            rn = "Compare";
2607
            break;
2608
        /* 6,7 are implementation dependent */
2609
        default:
2610
            goto die;
2611
        }
2612
        /* Stop translation as we may have switched the execution mode */
2613
        ctx->bstate = BS_STOP;
2614
        break;
2615
    case 12:
2616
        switch (sel) {
2617
        case 0:
2618
            gen_op_mtc0_status();
2619
            rn = "Status";
2620
            break;
2621
        case 1:
2622
            gen_op_mtc0_intctl();
2623
            rn = "IntCtl";
2624
            break;
2625
        case 2:
2626
            gen_op_mtc0_srsctl();
2627
            rn = "SRSCtl";
2628
            break;
2629
        case 3:
2630
//            gen_op_mtc0_srsmap(); /* shadow registers */
2631
            rn = "SRSMap";
2632
//            break;
2633
        default:
2634
            goto die;
2635
        }
2636
        /* Stop translation as we may have switched the execution mode */
2637
        ctx->bstate = BS_STOP;
2638
        break;
2639
    case 13:
2640
        switch (sel) {
2641
        case 0:
2642
            gen_op_mtc0_cause();
2643
            rn = "Cause";
2644
            break;
2645
        default:
2646
            goto die;
2647
        }
2648
        /* Stop translation as we may have switched the execution mode */
2649
        ctx->bstate = BS_STOP;
2650
        break;
2651
    case 14:
2652
        switch (sel) {
2653
        case 0:
2654
            gen_op_mtc0_epc();
2655
            rn = "EPC";
2656
            break;
2657
        default:
2658
            goto die;
2659
        }
2660
        break;
2661
    case 15:
2662
        switch (sel) {
2663
        case 0:
2664
            /* ignored */
2665
            rn = "PRid";
2666
            break;
2667
        case 1:
2668
            gen_op_mtc0_ebase();
2669
            rn = "EBase";
2670
            break;
2671
        default:
2672
            goto die;
2673
        }
2674
        break;
2675
    case 16:
2676
        switch (sel) {
2677
        case 0:
2678
            gen_op_mtc0_config0();
2679
            rn = "Config";
2680
            /* Stop translation as we may have switched the execution mode */
2681
            ctx->bstate = BS_STOP;
2682
            break;
2683
        case 1:
2684
            /* ignored, read only */
2685
            rn = "Config1";
2686
            break;
2687
        case 2:
2688
            gen_op_mtc0_config2();
2689
            rn = "Config2";
2690
            /* Stop translation as we may have switched the execution mode */
2691
            ctx->bstate = BS_STOP;
2692
            break;
2693
        case 3:
2694
            /* ignored, read only */
2695
            rn = "Config3";
2696
            break;
2697
        /* 4,5 are reserved */
2698
        /* 6,7 are implementation dependent */
2699
        case 6:
2700
            /* ignored */
2701
            rn = "Config6";
2702
            break;
2703
        case 7:
2704
            /* ignored */
2705
            rn = "Config7";
2706
            break;
2707
        default:
2708
            rn = "Invalid config selector";
2709
            goto die;
2710
        }
2711
        break;
2712
    case 17:
2713
        switch (sel) {
2714
        case 0:
2715
            /* ignored */
2716
            rn = "LLAddr";
2717
            break;
2718
        default:
2719
            goto die;
2720
        }
2721
        break;
2722
    case 18:
2723
        switch (sel) {
2724
        case 0:
2725
            gen_op_mtc0_watchlo0();
2726
            rn = "WatchLo";
2727
            break;
2728
        case 1:
2729
//            gen_op_mtc0_watchlo1();
2730
            rn = "WatchLo1";
2731
//            break;
2732
        case 2:
2733
//            gen_op_mtc0_watchlo2();
2734
            rn = "WatchLo2";
2735
//            break;
2736
        case 3:
2737
//            gen_op_mtc0_watchlo3();
2738
            rn = "WatchLo3";
2739
//            break;
2740
        case 4:
2741
//            gen_op_mtc0_watchlo4();
2742
            rn = "WatchLo4";
2743
//            break;
2744
        case 5:
2745
//            gen_op_mtc0_watchlo5();
2746
            rn = "WatchLo5";
2747
//            break;
2748
        case 6:
2749
//            gen_op_mtc0_watchlo6();
2750
            rn = "WatchLo6";
2751
//            break;
2752
        case 7:
2753
//            gen_op_mtc0_watchlo7();
2754
            rn = "WatchLo7";
2755
//            break;
2756
        default:
2757
            goto die;
2758
        }
2759
        break;
2760
    case 19:
2761
        switch (sel) {
2762
        case 0:
2763
            gen_op_mtc0_watchhi0();
2764
            rn = "WatchHi";
2765
            break;
2766
        case 1:
2767
//            gen_op_mtc0_watchhi1();
2768
            rn = "WatchHi1";
2769
//            break;
2770
        case 2:
2771
//            gen_op_mtc0_watchhi2();
2772
            rn = "WatchHi2";
2773
//            break;
2774
        case 3:
2775
//            gen_op_mtc0_watchhi3();
2776
            rn = "WatchHi3";
2777
//            break;
2778
        case 4:
2779
//            gen_op_mtc0_watchhi4();
2780
            rn = "WatchHi4";
2781
//            break;
2782
        case 5:
2783
//            gen_op_mtc0_watchhi5();
2784
            rn = "WatchHi5";
2785
//            break;
2786
        case 6:
2787
//            gen_op_mtc0_watchhi6();
2788
            rn = "WatchHi6";
2789
//            break;
2790
        case 7:
2791
//            gen_op_mtc0_watchhi7();
2792
            rn = "WatchHi7";
2793
//            break;
2794
        default:
2795
            goto die;
2796
        }
2797
        break;
2798
    case 20:
2799
        switch (sel) {
2800
        case 0:
2801
#ifdef TARGET_MIPS64
2802
            gen_op_mtc0_xcontext();
2803
            rn = "XContext";
2804
            break;
2805
#endif
2806
        default:
2807
            goto die;
2808
        }
2809
        break;
2810
    case 21:
2811
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2812
        switch (sel) {
2813
        case 0:
2814
            gen_op_mtc0_framemask();
2815
            rn = "Framemask";
2816
            break;
2817
        default:
2818
            goto die;
2819
        }
2820
        break;
2821
    case 22:
2822
        /* ignored */
2823
        rn = "Diagnostic"; /* implementation dependent */
2824
        break;
2825
    case 23:
2826
        switch (sel) {
2827
        case 0:
2828
            gen_op_mtc0_debug(); /* EJTAG support */
2829
            rn = "Debug";
2830
            break;
2831
        case 1:
2832
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2833
            rn = "TraceControl";
2834
//            break;
2835
        case 2:
2836
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2837
            rn = "TraceControl2";
2838
//            break;
2839
        case 3:
2840
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2841
            rn = "UserTraceData";
2842
//            break;
2843
        case 4:
2844
//            gen_op_mtc0_debug(); /* PDtrace support */
2845
            rn = "TraceBPC";
2846
//            break;
2847
        default:
2848
            goto die;
2849
        }
2850
        /* Stop translation as we may have switched the execution mode */
2851
        ctx->bstate = BS_STOP;
2852
        break;
2853
    case 24:
2854
        switch (sel) {
2855
        case 0:
2856
            gen_op_mtc0_depc(); /* EJTAG support */
2857
            rn = "DEPC";
2858
            break;
2859
        default:
2860
            goto die;
2861
        }
2862
        break;
2863
    case 25:
2864
        switch (sel) {
2865
        case 0:
2866
            gen_op_mtc0_performance0();
2867
            rn = "Performance0";
2868
            break;
2869
        case 1:
2870
//            gen_op_mtc0_performance1();
2871
            rn = "Performance1";
2872
//            break;
2873
        case 2:
2874
//            gen_op_mtc0_performance2();
2875
            rn = "Performance2";
2876
//            break;
2877
        case 3:
2878
//            gen_op_mtc0_performance3();
2879
            rn = "Performance3";
2880
//            break;
2881
        case 4:
2882
//            gen_op_mtc0_performance4();
2883
            rn = "Performance4";
2884
//            break;
2885
        case 5:
2886
//            gen_op_mtc0_performance5();
2887
            rn = "Performance5";
2888
//            break;
2889
        case 6:
2890
//            gen_op_mtc0_performance6();
2891
            rn = "Performance6";
2892
//            break;
2893
        case 7:
2894
//            gen_op_mtc0_performance7();
2895
            rn = "Performance7";
2896
//            break;
2897
        default:
2898
            goto die;
2899
        }
2900
       break;
2901
    case 26:
2902
        /* ignored */
2903
        rn = "ECC";
2904
        break;
2905
    case 27:
2906
        switch (sel) {
2907
        case 0 ... 3:
2908
            /* ignored */
2909
            rn = "CacheErr";
2910
            break;
2911
        default:
2912
            goto die;
2913
        }
2914
       break;
2915
    case 28:
2916
        switch (sel) {
2917
        case 0:
2918
        case 2:
2919
        case 4:
2920
        case 6:
2921
            gen_op_mtc0_taglo();
2922
            rn = "TagLo";
2923
            break;
2924
        case 1:
2925
        case 3:
2926
        case 5:
2927
        case 7:
2928
            gen_op_mtc0_datalo();
2929
            rn = "DataLo";
2930
            break;
2931
        default:
2932
            goto die;
2933
        }
2934
        break;
2935
    case 29:
2936
        switch (sel) {
2937
        case 0:
2938
        case 2:
2939
        case 4:
2940
        case 6:
2941
            gen_op_mtc0_taghi();
2942
            rn = "TagHi";
2943
            break;
2944
        case 1:
2945
        case 3:
2946
        case 5:
2947
        case 7:
2948
            gen_op_mtc0_datahi();
2949
            rn = "DataHi";
2950
            break;
2951
        default:
2952
            rn = "invalid sel";
2953
            goto die;
2954
        }
2955
       break;
2956
    case 30:
2957
        switch (sel) {
2958
        case 0:
2959
            gen_op_mtc0_errorepc();
2960
            rn = "ErrorEPC";
2961
            break;
2962
        default:
2963
            goto die;
2964
        }
2965
        break;
2966
    case 31:
2967
        switch (sel) {
2968
        case 0:
2969
            gen_op_mtc0_desave(); /* EJTAG support */
2970
            rn = "DESAVE";
2971
            break;
2972
        default:
2973
            goto die;
2974
        }
2975
        /* Stop translation as we may have switched the execution mode */
2976
        ctx->bstate = BS_STOP;
2977
        break;
2978
    default:
2979
       goto die;
2980
    }
2981
#if defined MIPS_DEBUG_DISAS
2982
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2983
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2984
                rn, reg, sel);
2985
    }
2986
#endif
2987
    return;
2988

    
2989
die:
2990
#if defined MIPS_DEBUG_DISAS
2991
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2992
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2993
                rn, reg, sel);
2994
    }
2995
#endif
2996
    generate_exception(ctx, EXCP_RI);
2997
}
2998

    
2999
#ifdef TARGET_MIPS64
3000
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
3001
{
3002
    const char *rn = "invalid";
3003

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

    
3573
die:
3574
#if defined MIPS_DEBUG_DISAS
3575
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3576
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3577
                rn, reg, sel);
3578
    }
3579
#endif
3580
    generate_exception(ctx, EXCP_RI);
3581
}
3582

    
3583
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3584
{
3585
    const char *rn = "invalid";
3586

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

    
4169
die:
4170
#if defined MIPS_DEBUG_DISAS
4171
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4172
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4173
                rn, reg, sel);
4174
    }
4175
#endif
4176
    generate_exception(ctx, EXCP_RI);
4177
}
4178
#endif /* TARGET_MIPS64 */
4179

    
4180
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4181
{
4182
    const char *opn = "ldst";
4183

    
4184
    switch (opc) {
4185
    case OPC_MFC0:
4186
        if (rt == 0) {
4187
            /* Treat as NOP */
4188
            return;
4189
        }
4190
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4191
        gen_op_store_T0_gpr(rt);
4192
        opn = "mfc0";
4193
        break;
4194
    case OPC_MTC0:
4195
        GEN_LOAD_REG_TN(T0, rt);
4196
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4197
        opn = "mtc0";
4198
        break;
4199
#ifdef TARGET_MIPS64
4200
    case OPC_DMFC0:
4201
        if (rt == 0) {
4202
            /* Treat as NOP */
4203
            return;
4204
        }
4205
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4206
        gen_op_store_T0_gpr(rt);
4207
        opn = "dmfc0";
4208
        break;
4209
    case OPC_DMTC0:
4210
        GEN_LOAD_REG_TN(T0, rt);
4211
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4212
        opn = "dmtc0";
4213
        break;
4214
#endif
4215
    case OPC_TLBWI:
4216
        opn = "tlbwi";
4217
        if (!env->do_tlbwi)
4218
            goto die;
4219
        gen_op_tlbwi();
4220
        break;
4221
    case OPC_TLBWR:
4222
        opn = "tlbwr";
4223
        if (!env->do_tlbwr)
4224
            goto die;
4225
        gen_op_tlbwr();
4226
        break;
4227
    case OPC_TLBP:
4228
        opn = "tlbp";
4229
        if (!env->do_tlbp)
4230
            goto die;
4231
        gen_op_tlbp();
4232
        break;
4233
    case OPC_TLBR:
4234
        opn = "tlbr";
4235
        if (!env->do_tlbr)
4236
            goto die;
4237
        gen_op_tlbr();
4238
        break;
4239
    case OPC_ERET:
4240
        opn = "eret";
4241
        save_cpu_state(ctx, 0);
4242
        gen_op_eret();
4243
        ctx->bstate = BS_EXCP;
4244
        break;
4245
    case OPC_DERET:
4246
        opn = "deret";
4247
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4248
            MIPS_INVAL(opn);
4249
            generate_exception(ctx, EXCP_RI);
4250
        } else {
4251
            save_cpu_state(ctx, 0);
4252
            gen_op_deret();
4253
            ctx->bstate = BS_EXCP;
4254
        }
4255
        break;
4256
    case OPC_WAIT:
4257
        opn = "wait";
4258
        /* If we get an exception, we want to restart at next instruction */
4259
        ctx->pc += 4;
4260
        save_cpu_state(ctx, 1);
4261
        ctx->pc -= 4;
4262
        gen_op_wait();
4263
        ctx->bstate = BS_EXCP;
4264
        break;
4265
    default:
4266
 die:
4267
        MIPS_INVAL(opn);
4268
        generate_exception(ctx, EXCP_RI);
4269
        return;
4270
    }
4271
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4272
}
4273

    
4274
/* CP1 Branches (before delay slot) */
4275
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4276
                                 int32_t cc, int32_t offset)
4277
{
4278
    target_ulong btarget;
4279
    const char *opn = "cp1 cond branch";
4280

    
4281
    btarget = ctx->pc + 4 + offset;
4282

    
4283
    switch (op) {
4284
    case OPC_BC1F:
4285
        gen_op_bc1f(cc);
4286
        opn = "bc1f";
4287
        goto not_likely;
4288
    case OPC_BC1FL:
4289
        gen_op_bc1f(cc);
4290
        opn = "bc1fl";
4291
        goto likely;
4292
    case OPC_BC1T:
4293
        gen_op_bc1t(cc);
4294
        opn = "bc1t";
4295
        goto not_likely;
4296
    case OPC_BC1TL:
4297
        gen_op_bc1t(cc);
4298
        opn = "bc1tl";
4299
    likely:
4300
        ctx->hflags |= MIPS_HFLAG_BL;
4301
        gen_op_set_bcond();
4302
        gen_op_save_bcond();
4303
        break;
4304
    case OPC_BC1FANY2:
4305
        gen_op_bc1any2f(cc);
4306
        opn = "bc1any2f";
4307
        goto not_likely;
4308
    case OPC_BC1TANY2:
4309
        gen_op_bc1any2t(cc);
4310
        opn = "bc1any2t";
4311
        goto not_likely;
4312
    case OPC_BC1FANY4:
4313
        gen_op_bc1any4f(cc);
4314
        opn = "bc1any4f";
4315
        goto not_likely;
4316
    case OPC_BC1TANY4:
4317
        gen_op_bc1any4t(cc);
4318
        opn = "bc1any4t";
4319
    not_likely:
4320
        ctx->hflags |= MIPS_HFLAG_BC;
4321
        gen_op_set_bcond();
4322
        break;
4323
    default:
4324
        MIPS_INVAL(opn);
4325
        generate_exception (ctx, EXCP_RI);
4326
        return;
4327
    }
4328
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4329
               ctx->hflags, btarget);
4330
    ctx->btarget = btarget;
4331
}
4332

    
4333
/* Coprocessor 1 (FPU) */
4334

    
4335
#define FOP(func, fmt) (((fmt) << 21) | (func))
4336

    
4337
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4338
{
4339
    const char *opn = "cp1 move";
4340

    
4341
    switch (opc) {
4342
    case OPC_MFC1:
4343
        GEN_LOAD_FREG_FTN(WT0, fs);
4344
        gen_op_mfc1();
4345
        GEN_STORE_TN_REG(rt, T0);
4346
        opn = "mfc1";
4347
        break;
4348
    case OPC_MTC1:
4349
        GEN_LOAD_REG_TN(T0, rt);
4350
        gen_op_mtc1();
4351
        GEN_STORE_FTN_FREG(fs, WT0);
4352
        opn = "mtc1";
4353
        break;
4354
    case OPC_CFC1:
4355
        GEN_LOAD_IMM_TN(T1, fs);
4356
        gen_op_cfc1();
4357
        GEN_STORE_TN_REG(rt, T0);
4358
        opn = "cfc1";
4359
        break;
4360
    case OPC_CTC1:
4361
        GEN_LOAD_IMM_TN(T1, fs);
4362
        GEN_LOAD_REG_TN(T0, rt);
4363
        gen_op_ctc1();
4364
        opn = "ctc1";
4365
        break;
4366
    case OPC_DMFC1:
4367
        GEN_LOAD_FREG_FTN(DT0, fs);
4368
        gen_op_dmfc1();
4369
        GEN_STORE_TN_REG(rt, T0);
4370
        opn = "dmfc1";
4371
        break;
4372
    case OPC_DMTC1:
4373
        GEN_LOAD_REG_TN(T0, rt);
4374
        gen_op_dmtc1();
4375
        GEN_STORE_FTN_FREG(fs, DT0);
4376
        opn = "dmtc1";
4377
        break;
4378
    case OPC_MFHC1:
4379
        gen_op_cp1_registers(fs);
4380
        GEN_LOAD_FREG_FTN(WTH0, fs);
4381
        gen_op_mfhc1();
4382
        GEN_STORE_TN_REG(rt, T0);
4383
        opn = "mfhc1";
4384
        break;
4385
    case OPC_MTHC1:
4386
        gen_op_cp1_registers(fs);
4387
        GEN_LOAD_REG_TN(T0, rt);
4388
        gen_op_mthc1();
4389
        GEN_STORE_FTN_FREG(fs, WTH0);
4390
        opn = "mthc1";
4391
        break;
4392
    default:
4393
        MIPS_INVAL(opn);
4394
        generate_exception (ctx, EXCP_RI);
4395
        return;
4396
    }
4397
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4398
}
4399

    
4400
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4401
{
4402
    uint32_t ccbit;
4403

    
4404
    GEN_LOAD_REG_TN(T0, rd);
4405
    GEN_LOAD_REG_TN(T1, rs);
4406
    if (cc)
4407
        ccbit = 1 << (24 + cc);
4408
    else
4409
        ccbit = 1 << 23;
4410
    if (!tf)
4411
        gen_op_movf(ccbit);
4412
    else
4413
        gen_op_movt(ccbit);
4414
    GEN_STORE_TN_REG(rd, T0);
4415
}
4416

    
4417
#define GEN_MOVCF(fmt)                                                \
4418
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4419
{                                                                     \
4420
    uint32_t ccbit;                                                   \
4421
                                                                      \
4422
    if (cc)                                                           \
4423
        ccbit = 1 << (24 + cc);                                       \
4424
    else                                                              \
4425
        ccbit = 1 << 23;                                              \
4426
    if (!tf)                                                          \
4427
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4428
    else                                                              \
4429
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4430
}
4431
GEN_MOVCF(d);
4432
GEN_MOVCF(s);
4433
GEN_MOVCF(ps);
4434
#undef GEN_MOVCF
4435

    
4436
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4437
                        int fs, int fd, int cc)
4438
{
4439
    const char *opn = "farith";
4440
    const char *condnames[] = {
4441
            "c.f",
4442
            "c.un",
4443
            "c.eq",
4444
            "c.ueq",
4445
            "c.olt",
4446
            "c.ult",
4447
            "c.ole",
4448
            "c.ule",
4449
            "c.sf",
4450
            "c.ngle",
4451
            "c.seq",
4452
            "c.ngl",
4453
            "c.lt",
4454
            "c.nge",
4455
            "c.le",
4456
            "c.ngt",
4457
    };
4458
    const char *condnames_abs[] = {
4459
            "cabs.f",
4460
            "cabs.un",
4461
            "cabs.eq",
4462
            "cabs.ueq",
4463
            "cabs.olt",
4464
            "cabs.ult",
4465
            "cabs.ole",
4466
            "cabs.ule",
4467
            "cabs.sf",
4468
            "cabs.ngle",
4469
            "cabs.seq",
4470
            "cabs.ngl",
4471
            "cabs.lt",
4472
            "cabs.nge",
4473
            "cabs.le",
4474
            "cabs.ngt",
4475
    };
4476
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4477
    uint32_t func = ctx->opcode & 0x3f;
4478

    
4479
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4480
    case FOP(0, 16):
4481
        GEN_LOAD_FREG_FTN(WT0, fs);
4482
        GEN_LOAD_FREG_FTN(WT1, ft);
4483
        gen_op_float_add_s();
4484
        GEN_STORE_FTN_FREG(fd, WT2);
4485
        opn = "add.s";
4486
        optype = BINOP;
4487
        break;
4488
    case FOP(1, 16):
4489
        GEN_LOAD_FREG_FTN(WT0, fs);
4490
        GEN_LOAD_FREG_FTN(WT1, ft);
4491
        gen_op_float_sub_s();
4492
        GEN_STORE_FTN_FREG(fd, WT2);
4493
        opn = "sub.s";
4494
        optype = BINOP;
4495
        break;
4496
    case FOP(2, 16):
4497
        GEN_LOAD_FREG_FTN(WT0, fs);
4498
        GEN_LOAD_FREG_FTN(WT1, ft);
4499
        gen_op_float_mul_s();
4500
        GEN_STORE_FTN_FREG(fd, WT2);
4501
        opn = "mul.s";
4502
        optype = BINOP;
4503
        break;
4504
    case FOP(3, 16):
4505
        GEN_LOAD_FREG_FTN(WT0, fs);
4506
        GEN_LOAD_FREG_FTN(WT1, ft);
4507
        gen_op_float_div_s();
4508
        GEN_STORE_FTN_FREG(fd, WT2);
4509
        opn = "div.s";
4510
        optype = BINOP;
4511
        break;
4512
    case FOP(4, 16):
4513
        GEN_LOAD_FREG_FTN(WT0, fs);
4514
        gen_op_float_sqrt_s();
4515
        GEN_STORE_FTN_FREG(fd, WT2);
4516
        opn = "sqrt.s";
4517
        break;
4518
    case FOP(5, 16):
4519
        GEN_LOAD_FREG_FTN(WT0, fs);
4520
        gen_op_float_abs_s();
4521
        GEN_STORE_FTN_FREG(fd, WT2);
4522
        opn = "abs.s";
4523
        break;
4524
    case FOP(6, 16):
4525
        GEN_LOAD_FREG_FTN(WT0, fs);
4526
        gen_op_float_mov_s();
4527
        GEN_STORE_FTN_FREG(fd, WT2);
4528
        opn = "mov.s";
4529
        break;
4530
    case FOP(7, 16):
4531
        GEN_LOAD_FREG_FTN(WT0, fs);
4532
        gen_op_float_chs_s();
4533
        GEN_STORE_FTN_FREG(fd, WT2);
4534
        opn = "neg.s";
4535
        break;
4536
    case FOP(8, 16):
4537
        gen_op_cp1_registers(fs);
4538
        GEN_LOAD_FREG_FTN(WT0, fs);
4539
        gen_op_float_roundl_s();
4540
        GEN_STORE_FTN_FREG(fd, DT2);
4541
        opn = "round.l.s";
4542
        break;
4543
    case FOP(9, 16):
4544
        gen_op_cp1_registers(fs);
4545
        GEN_LOAD_FREG_FTN(WT0, fs);
4546
        gen_op_float_truncl_s();
4547
        GEN_STORE_FTN_FREG(fd, DT2);
4548
        opn = "trunc.l.s";
4549
        break;
4550
    case FOP(10, 16):
4551
        gen_op_cp1_registers(fs);
4552
        GEN_LOAD_FREG_FTN(WT0, fs);
4553
        gen_op_float_ceill_s();
4554
        GEN_STORE_FTN_FREG(fd, DT2);
4555
        opn = "ceil.l.s";
4556
        break;
4557
    case FOP(11, 16):
4558
        gen_op_cp1_registers(fs);
4559
        GEN_LOAD_FREG_FTN(WT0, fs);
4560
        gen_op_float_floorl_s();
4561
        GEN_STORE_FTN_FREG(fd, DT2);
4562
        opn = "floor.l.s";
4563
        break;
4564
    case FOP(12, 16):
4565
        GEN_LOAD_FREG_FTN(WT0, fs);
4566
        gen_op_float_roundw_s();
4567
        GEN_STORE_FTN_FREG(fd, WT2);
4568
        opn = "round.w.s";
4569
        break;
4570
    case FOP(13, 16):
4571
        GEN_LOAD_FREG_FTN(WT0, fs);
4572
        gen_op_float_truncw_s();
4573
        GEN_STORE_FTN_FREG(fd, WT2);
4574
        opn = "trunc.w.s";
4575
        break;
4576
    case FOP(14, 16):
4577
        GEN_LOAD_FREG_FTN(WT0, fs);
4578
        gen_op_float_ceilw_s();
4579
        GEN_STORE_FTN_FREG(fd, WT2);
4580
        opn = "ceil.w.s";
4581
        break;
4582
    case FOP(15, 16):
4583
        GEN_LOAD_FREG_FTN(WT0, fs);
4584
        gen_op_float_floorw_s();
4585
        GEN_STORE_FTN_FREG(fd, WT2);
4586
        opn = "floor.w.s";
4587
        break;
4588
    case FOP(17, 16):
4589
        GEN_LOAD_REG_TN(T0, ft);
4590
        GEN_LOAD_FREG_FTN(WT0, fs);
4591
        GEN_LOAD_FREG_FTN(WT2, fd);
4592
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4593
        GEN_STORE_FTN_FREG(fd, WT2);
4594
        opn = "movcf.s";
4595
        break;
4596
    case FOP(18, 16):
4597
        GEN_LOAD_REG_TN(T0, ft);
4598
        GEN_LOAD_FREG_FTN(WT0, fs);
4599
        GEN_LOAD_FREG_FTN(WT2, fd);
4600
        gen_op_float_movz_s();
4601
        GEN_STORE_FTN_FREG(fd, WT2);
4602
        opn = "movz.s";
4603
        break;
4604
    case FOP(19, 16):
4605
        GEN_LOAD_REG_TN(T0, ft);
4606
        GEN_LOAD_FREG_FTN(WT0, fs);
4607
        GEN_LOAD_FREG_FTN(WT2, fd);
4608
        gen_op_float_movn_s();
4609
        GEN_STORE_FTN_FREG(fd, WT2);
4610
        opn = "movn.s";
4611
        break;
4612
    case FOP(33, 16):
4613
        gen_op_cp1_registers(fd);
4614
        GEN_LOAD_FREG_FTN(WT0, fs);
4615
        gen_op_float_cvtd_s();
4616
        GEN_STORE_FTN_FREG(fd, DT2);
4617
        opn = "cvt.d.s";
4618
        break;
4619
    case FOP(36, 16):
4620
        GEN_LOAD_FREG_FTN(WT0, fs);
4621
        gen_op_float_cvtw_s();
4622
        GEN_STORE_FTN_FREG(fd, WT2);
4623
        opn = "cvt.w.s";
4624
        break;
4625
    case FOP(37, 16):
4626
        gen_op_cp1_registers(fs | fd);
4627
        GEN_LOAD_FREG_FTN(WT0, fs);
4628
        gen_op_float_cvtl_s();
4629
        GEN_STORE_FTN_FREG(fd, DT2);
4630
        opn = "cvt.l.s";
4631
        break;
4632
    case FOP(38, 16):
4633
        gen_op_cp1_registers(fs | ft | fd);
4634
        GEN_LOAD_FREG_FTN(WT1, fs);
4635
        GEN_LOAD_FREG_FTN(WT0, ft);
4636
        gen_op_float_cvtps_s();
4637
        GEN_STORE_FTN_FREG(fd, DT2);
4638
        opn = "cvt.ps.s";
4639
        break;
4640
    case FOP(48, 16):
4641
    case FOP(49, 16):
4642
    case FOP(50, 16):
4643
    case FOP(51, 16):
4644
    case FOP(52, 16):
4645
    case FOP(53, 16):
4646
    case FOP(54, 16):
4647
    case FOP(55, 16):
4648
    case FOP(56, 16):
4649
    case FOP(57, 16):
4650
    case FOP(58, 16):
4651
    case FOP(59, 16):
4652
    case FOP(60, 16):
4653
    case FOP(61, 16):
4654
    case FOP(62, 16):
4655
    case FOP(63, 16):
4656
        GEN_LOAD_FREG_FTN(WT0, fs);
4657
        GEN_LOAD_FREG_FTN(WT1, ft);
4658
        if (ctx->opcode & (1 << 6)) {
4659
            gen_cmpabs_s(func-48, cc);
4660
            opn = condnames_abs[func-48];
4661
        } else {
4662
            gen_cmp_s(func-48, cc);
4663
            opn = condnames[func-48];
4664
        }
4665
        break;
4666
    case FOP(0, 17):
4667
        gen_op_cp1_registers(fs | ft | fd);
4668
        GEN_LOAD_FREG_FTN(DT0, fs);
4669
        GEN_LOAD_FREG_FTN(DT1, ft);
4670
        gen_op_float_add_d();
4671
        GEN_STORE_FTN_FREG(fd, DT2);
4672
        opn = "add.d";
4673
        optype = BINOP;
4674
        break;
4675
    case FOP(1, 17):
4676
        gen_op_cp1_registers(fs | ft | fd);
4677
        GEN_LOAD_FREG_FTN(DT0, fs);
4678
        GEN_LOAD_FREG_FTN(DT1, ft);
4679
        gen_op_float_sub_d();
4680
        GEN_STORE_FTN_FREG(fd, DT2);
4681
        opn = "sub.d";
4682
        optype = BINOP;
4683
        break;
4684
    case FOP(2, 17):
4685
        gen_op_cp1_registers(fs | ft | fd);
4686
        GEN_LOAD_FREG_FTN(DT0, fs);
4687
        GEN_LOAD_FREG_FTN(DT1, ft);
4688
        gen_op_float_mul_d();
4689
        GEN_STORE_FTN_FREG(fd, DT2);
4690
        opn = "mul.d";
4691
        optype = BINOP;
4692
        break;
4693
    case FOP(3, 17):
4694
        gen_op_cp1_registers(fs | ft | fd);
4695
        GEN_LOAD_FREG_FTN(DT0, fs);
4696
        GEN_LOAD_FREG_FTN(DT1, ft);
4697
        gen_op_float_div_d();
4698
        GEN_STORE_FTN_FREG(fd, DT2);
4699
        opn = "div.d";
4700
        optype = BINOP;
4701
        break;
4702
    case FOP(4, 17):
4703
        gen_op_cp1_registers(fs | fd);
4704
        GEN_LOAD_FREG_FTN(DT0, fs);
4705
        gen_op_float_sqrt_d();
4706
        GEN_STORE_FTN_FREG(fd, DT2);
4707
        opn = "sqrt.d";
4708
        break;
4709
    case FOP(5, 17):
4710
        gen_op_cp1_registers(fs | fd);
4711
        GEN_LOAD_FREG_FTN(DT0, fs);
4712
        gen_op_float_abs_d();
4713
        GEN_STORE_FTN_FREG(fd, DT2);
4714
        opn = "abs.d";
4715
        break;
4716
    case FOP(6, 17):
4717
        gen_op_cp1_registers(fs | fd);
4718
        GEN_LOAD_FREG_FTN(DT0, fs);
4719
        gen_op_float_mov_d();
4720
        GEN_STORE_FTN_FREG(fd, DT2);
4721
        opn = "mov.d";
4722
        break;
4723
    case FOP(7, 17):
4724
        gen_op_cp1_registers(fs | fd);
4725
        GEN_LOAD_FREG_FTN(DT0, fs);
4726
        gen_op_float_chs_d();
4727
        GEN_STORE_FTN_FREG(fd, DT2);
4728
        opn = "neg.d";
4729
        break;
4730
    case FOP(8, 17):
4731
        gen_op_cp1_registers(fs);
4732
        GEN_LOAD_FREG_FTN(DT0, fs);
4733
        gen_op_float_roundl_d();
4734
        GEN_STORE_FTN_FREG(fd, DT2);
4735
        opn = "round.l.d";
4736
        break;
4737
    case FOP(9, 17):
4738
        gen_op_cp1_registers(fs);
4739
        GEN_LOAD_FREG_FTN(DT0, fs);
4740
        gen_op_float_truncl_d();
4741
        GEN_STORE_FTN_FREG(fd, DT2);
4742
        opn = "trunc.l.d";
4743
        break;
4744
    case FOP(10, 17):
4745
        gen_op_cp1_registers(fs);
4746
        GEN_LOAD_FREG_FTN(DT0, fs);
4747
        gen_op_float_ceill_d();
4748
        GEN_STORE_FTN_FREG(fd, DT2);
4749
        opn = "ceil.l.d";
4750
        break;
4751
    case FOP(11, 17):
4752
        gen_op_cp1_registers(fs);
4753
        GEN_LOAD_FREG_FTN(DT0, fs);
4754
        gen_op_float_floorl_d();
4755
        GEN_STORE_FTN_FREG(fd, DT2);
4756
        opn = "floor.l.d";
4757
        break;
4758
    case FOP(12, 17):
4759
        gen_op_cp1_registers(fs);
4760
        GEN_LOAD_FREG_FTN(DT0, fs);
4761
        gen_op_float_roundw_d();
4762
        GEN_STORE_FTN_FREG(fd, WT2);
4763
        opn = "round.w.d";
4764
        break;
4765
    case FOP(13, 17):
4766
        gen_op_cp1_registers(fs);
4767
        GEN_LOAD_FREG_FTN(DT0, fs);
4768
        gen_op_float_truncw_d();
4769
        GEN_STORE_FTN_FREG(fd, WT2);
4770
        opn = "trunc.w.d";
4771
        break;
4772
    case FOP(14, 17):
4773
        gen_op_cp1_registers(fs);
4774
        GEN_LOAD_FREG_FTN(DT0, fs);
4775
        gen_op_float_ceilw_d();
4776
        GEN_STORE_FTN_FREG(fd, WT2);
4777
        opn = "ceil.w.d";
4778
        break;
4779
    case FOP(15, 17):
4780
        gen_op_cp1_registers(fs);
4781
        GEN_LOAD_FREG_FTN(DT0, fs);
4782
        gen_op_float_floorw_d();
4783
        GEN_STORE_FTN_FREG(fd, WT2);
4784
        opn = "floor.w.d";
4785
        break;
4786
    case FOP(17, 17):
4787
        GEN_LOAD_REG_TN(T0, ft);
4788
        GEN_LOAD_FREG_FTN(DT0, fs);
4789
        GEN_LOAD_FREG_FTN(DT2, fd);
4790
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4791
        GEN_STORE_FTN_FREG(fd, DT2);
4792
        opn = "movcf.d";
4793
        break;
4794
    case FOP(18, 17):
4795
        GEN_LOAD_REG_TN(T0, ft);
4796
        GEN_LOAD_FREG_FTN(DT0, fs);
4797
        GEN_LOAD_FREG_FTN(DT2, fd);
4798
        gen_op_float_movz_d();
4799
        GEN_STORE_FTN_FREG(fd, DT2);
4800
        opn = "movz.d";
4801
        break;
4802
    case FOP(19, 17):
4803
        GEN_LOAD_REG_TN(T0, ft);
4804
        GEN_LOAD_FREG_FTN(DT0, fs);
4805
        GEN_LOAD_FREG_FTN(DT2, fd);
4806
        gen_op_float_movn_d();
4807
        GEN_STORE_FTN_FREG(fd, DT2);
4808
        opn = "movn.d";
4809
        break;
4810
    case FOP(48, 17):
4811
    case FOP(49, 17):
4812
    case FOP(50, 17):
4813
    case FOP(51, 17):
4814
    case FOP(52, 17):
4815
    case FOP(53, 17):
4816
    case FOP(54, 17):
4817
    case FOP(55, 17):
4818
    case FOP(56, 17):
4819
    case FOP(57, 17):
4820
    case FOP(58, 17):
4821
    case FOP(59, 17):
4822
    case FOP(60, 17):
4823
    case FOP(61, 17):
4824
    case FOP(62, 17):
4825
    case FOP(63, 17):
4826
        gen_op_cp1_registers(fs | ft);
4827
        GEN_LOAD_FREG_FTN(DT0, fs);
4828
        GEN_LOAD_FREG_FTN(DT1, ft);
4829
        if (ctx->opcode & (1 << 6)) {
4830
            gen_cmpabs_d(func-48, cc);
4831
            opn = condnames_abs[func-48];
4832
        } else {
4833
            gen_cmp_d(func-48, cc);
4834
            opn = condnames[func-48];
4835
        }
4836
        break;
4837
    case FOP(32, 17):
4838
        gen_op_cp1_registers(fs);
4839
        GEN_LOAD_FREG_FTN(DT0, fs);
4840
        gen_op_float_cvts_d();
4841
        GEN_STORE_FTN_FREG(fd, WT2);
4842
        opn = "cvt.s.d";
4843
        break;
4844
    case FOP(36, 17):
4845
        gen_op_cp1_registers(fs);
4846
        GEN_LOAD_FREG_FTN(DT0, fs);
4847
        gen_op_float_cvtw_d();
4848
        GEN_STORE_FTN_FREG(fd, WT2);
4849
        opn = "cvt.w.d";
4850
        break;
4851
    case FOP(37, 17):
4852
        gen_op_cp1_registers(fs | fd);
4853
        GEN_LOAD_FREG_FTN(DT0, fs);
4854
        gen_op_float_cvtl_d();
4855
        GEN_STORE_FTN_FREG(fd, DT2);
4856
        opn = "cvt.l.d";
4857
        break;
4858
    case FOP(32, 20):
4859
        GEN_LOAD_FREG_FTN(WT0, fs);
4860
        gen_op_float_cvts_w();
4861
        GEN_STORE_FTN_FREG(fd, WT2);
4862
        opn = "cvt.s.w";
4863
        break;
4864
    case FOP(33, 20):
4865
        gen_op_cp1_registers(fd);
4866
        GEN_LOAD_FREG_FTN(WT0, fs);
4867
        gen_op_float_cvtd_w();
4868
        GEN_STORE_FTN_FREG(fd, DT2);
4869
        opn = "cvt.d.w";
4870
        break;
4871
    case FOP(32, 21):
4872
        gen_op_cp1_registers(fs);
4873
        GEN_LOAD_FREG_FTN(DT0, fs);
4874
        gen_op_float_cvts_l();
4875
        GEN_STORE_FTN_FREG(fd, WT2);
4876
        opn = "cvt.s.l";
4877
        break;
4878
    case FOP(33, 21):
4879
        gen_op_cp1_registers(fs | fd);
4880
        GEN_LOAD_FREG_FTN(DT0, fs);
4881
        gen_op_float_cvtd_l();
4882
        GEN_STORE_FTN_FREG(fd, DT2);
4883
        opn = "cvt.d.l";
4884
        break;
4885
    case FOP(38, 20):
4886
    case FOP(38, 21):
4887
        gen_op_cp1_registers(fs | fd);
4888
        GEN_LOAD_FREG_FTN(WT0, fs);
4889
        GEN_LOAD_FREG_FTN(WTH0, fs);
4890
        gen_op_float_cvtps_pw();
4891
        GEN_STORE_FTN_FREG(fd, WT2);
4892
        GEN_STORE_FTN_FREG(fd, WTH2);
4893
        opn = "cvt.ps.pw";
4894
        break;
4895
    case FOP(0, 22):
4896
        gen_op_cp1_registers(fs | ft | fd);
4897
        GEN_LOAD_FREG_FTN(WT0, fs);
4898
        GEN_LOAD_FREG_FTN(WTH0, fs);
4899
        GEN_LOAD_FREG_FTN(WT1, ft);
4900
        GEN_LOAD_FREG_FTN(WTH1, ft);
4901
        gen_op_float_add_ps();
4902
        GEN_STORE_FTN_FREG(fd, WT2);
4903
        GEN_STORE_FTN_FREG(fd, WTH2);
4904
        opn = "add.ps";
4905
        break;
4906
    case FOP(1, 22):
4907
        gen_op_cp1_registers(fs | ft | fd);
4908
        GEN_LOAD_FREG_FTN(WT0, fs);
4909
        GEN_LOAD_FREG_FTN(WTH0, fs);
4910
        GEN_LOAD_FREG_FTN(WT1, ft);
4911
        GEN_LOAD_FREG_FTN(WTH1, ft);
4912
        gen_op_float_sub_ps();
4913
        GEN_STORE_FTN_FREG(fd, WT2);
4914
        GEN_STORE_FTN_FREG(fd, WTH2);
4915
        opn = "sub.ps";
4916
        break;
4917
    case FOP(2, 22):
4918
        gen_op_cp1_registers(fs | ft | fd);
4919
        GEN_LOAD_FREG_FTN(WT0, fs);
4920
        GEN_LOAD_FREG_FTN(WTH0, fs);
4921
        GEN_LOAD_FREG_FTN(WT1, ft);
4922
        GEN_LOAD_FREG_FTN(WTH1, ft);
4923
        gen_op_float_mul_ps();
4924
        GEN_STORE_FTN_FREG(fd, WT2);
4925
        GEN_STORE_FTN_FREG(fd, WTH2);
4926
        opn = "mul.ps";
4927
        break;
4928
    case FOP(5, 22):
4929
        gen_op_cp1_registers(fs | fd);
4930
        GEN_LOAD_FREG_FTN(WT0, fs);
4931
        GEN_LOAD_FREG_FTN(WTH0, fs);
4932
        gen_op_float_abs_ps();
4933
        GEN_STORE_FTN_FREG(fd, WT2);
4934
        GEN_STORE_FTN_FREG(fd, WTH2);
4935
        opn = "abs.ps";
4936
        break;
4937
    case FOP(6, 22):
4938
        gen_op_cp1_registers(fs | fd);
4939
        GEN_LOAD_FREG_FTN(WT0, fs);
4940
        GEN_LOAD_FREG_FTN(WTH0, fs);
4941
        gen_op_float_mov_ps();
4942
        GEN_STORE_FTN_FREG(fd, WT2);
4943
        GEN_STORE_FTN_FREG(fd, WTH2);
4944
        opn = "mov.ps";
4945
        break;
4946
    case FOP(7, 22):
4947
        gen_op_cp1_registers(fs | fd);
4948
        GEN_LOAD_FREG_FTN(WT0, fs);
4949
        GEN_LOAD_FREG_FTN(WTH0, fs);
4950
        gen_op_float_chs_ps();
4951
        GEN_STORE_FTN_FREG(fd, WT2);
4952
        GEN_STORE_FTN_FREG(fd, WTH2);
4953
        opn = "neg.ps";
4954
        break;
4955
    case FOP(17, 22):
4956
        GEN_LOAD_REG_TN(T0, ft);
4957
        GEN_LOAD_FREG_FTN(WT0, fs);
4958
        GEN_LOAD_FREG_FTN(WTH0, fs);
4959
        GEN_LOAD_FREG_FTN(WT2, fd);
4960
        GEN_LOAD_FREG_FTN(WTH2, fd);
4961
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
4962
        GEN_STORE_FTN_FREG(fd, WT2);
4963
        GEN_STORE_FTN_FREG(fd, WTH2);
4964
        opn = "movcf.ps";
4965
        break;
4966
    case FOP(18, 22):
4967
        GEN_LOAD_REG_TN(T0, ft);
4968
        GEN_LOAD_FREG_FTN(WT0, fs);
4969
        GEN_LOAD_FREG_FTN(WTH0, fs);
4970
        GEN_LOAD_FREG_FTN(WT2, fd);
4971
        GEN_LOAD_FREG_FTN(WTH2, fd);
4972
        gen_op_float_movz_ps();
4973
        GEN_STORE_FTN_FREG(fd, WT2);
4974
        GEN_STORE_FTN_FREG(fd, WTH2);
4975
        opn = "movz.ps";
4976
        break;
4977
    case FOP(19, 22):
4978
        GEN_LOAD_REG_TN(T0, ft);
4979
        GEN_LOAD_FREG_FTN(WT0, fs);
4980
        GEN_LOAD_FREG_FTN(WTH0, fs);
4981
        GEN_LOAD_FREG_FTN(WT2, fd);
4982
        GEN_LOAD_FREG_FTN(WTH2, fd);
4983
        gen_op_float_movn_ps();
4984
        GEN_STORE_FTN_FREG(fd, WT2);
4985
        GEN_STORE_FTN_FREG(fd, WTH2);
4986
        opn = "movn.ps";
4987
        break;
4988
    case FOP(24, 22):
4989
        gen_op_cp1_registers(fs | fd | ft);
4990
        GEN_LOAD_FREG_FTN(WT0, fs);
4991
        GEN_LOAD_FREG_FTN(WTH0, fs);
4992
        GEN_LOAD_FREG_FTN(WT1, ft);
4993
        GEN_LOAD_FREG_FTN(WTH1, ft);
4994
        gen_op_float_addr_ps();
4995
        GEN_STORE_FTN_FREG(fd, WT2);
4996
        GEN_STORE_FTN_FREG(fd, WTH2);
4997
        opn = "addr.ps";
4998
        break;
4999
    case FOP(32, 22):
5000
        gen_op_cp1_registers(fs);
5001
        GEN_LOAD_FREG_FTN(WTH0, fs);
5002
        gen_op_float_cvts_pu();
5003
        GEN_STORE_FTN_FREG(fd, WT2);
5004
        opn = "cvt.s.pu";
5005
        break;
5006
    case FOP(36, 22):
5007
        gen_op_cp1_registers(fs | fd);
5008
        GEN_LOAD_FREG_FTN(WT0, fs);
5009
        GEN_LOAD_FREG_FTN(WTH0, fs);
5010
        gen_op_float_cvtpw_ps();
5011
        GEN_STORE_FTN_FREG(fd, WT2);
5012
        GEN_STORE_FTN_FREG(fd, WTH2);
5013
        opn = "cvt.pw.ps";
5014
        break;
5015
    case FOP(40, 22):
5016
        gen_op_cp1_registers(fs);
5017
        GEN_LOAD_FREG_FTN(WT0, fs);
5018
        gen_op_float_cvts_pl();
5019
        GEN_STORE_FTN_FREG(fd, WT2);
5020
        opn = "cvt.s.pl";
5021
        break;
5022
    case FOP(44, 22):
5023
        gen_op_cp1_registers(fs | ft | fd);
5024
        GEN_LOAD_FREG_FTN(WT0, fs);
5025
        GEN_LOAD_FREG_FTN(WT1, ft);
5026
        gen_op_float_pll_ps();
5027
        GEN_STORE_FTN_FREG(fd, DT2);
5028
        opn = "pll.ps";
5029
        break;
5030
    case FOP(45, 22):
5031
        gen_op_cp1_registers(fs | ft | fd);
5032
        GEN_LOAD_FREG_FTN(WT0, fs);
5033
        GEN_LOAD_FREG_FTN(WTH1, ft);
5034
        gen_op_float_plu_ps();
5035
        GEN_STORE_FTN_FREG(fd, DT2);
5036
        opn = "plu.ps";
5037
        break;
5038
    case FOP(46, 22):
5039
        gen_op_cp1_registers(fs | ft | fd);
5040
        GEN_LOAD_FREG_FTN(WTH0, fs);
5041
        GEN_LOAD_FREG_FTN(WT1, ft);
5042
        gen_op_float_pul_ps();
5043
        GEN_STORE_FTN_FREG(fd, DT2);
5044
        opn = "pul.ps";
5045
        break;
5046
    case FOP(47, 22):
5047
        gen_op_cp1_registers(fs | ft | fd);
5048
        GEN_LOAD_FREG_FTN(WTH0, fs);
5049
        GEN_LOAD_FREG_FTN(WTH1, ft);
5050
        gen_op_float_puu_ps();
5051
        GEN_STORE_FTN_FREG(fd, DT2);
5052
        opn = "puu.ps";
5053
        break;
5054
    case FOP(48, 22):
5055
    case FOP(49, 22):
5056
    case FOP(50, 22):
5057
    case FOP(51, 22):
5058
    case FOP(52, 22):
5059
    case FOP(53, 22):
5060
    case FOP(54, 22):
5061
    case FOP(55, 22):
5062
    case FOP(56, 22):
5063
    case FOP(57, 22):
5064
    case FOP(58, 22):
5065
    case FOP(59, 22):
5066
    case FOP(60, 22):
5067
    case FOP(61, 22):
5068
    case FOP(62, 22):
5069
    case FOP(63, 22):
5070
        gen_op_cp1_registers(fs | ft);
5071
        GEN_LOAD_FREG_FTN(WT0, fs);
5072
        GEN_LOAD_FREG_FTN(WTH0, fs);
5073
        GEN_LOAD_FREG_FTN(WT1, ft);
5074
        GEN_LOAD_FREG_FTN(WTH1, ft);
5075
        if (ctx->opcode & (1 << 6)) {
5076
            gen_cmpabs_ps(func-48, cc);
5077
            opn = condnames_abs[func-48];
5078
        } else {
5079
            gen_cmp_ps(func-48, cc);
5080
            opn = condnames[func-48];
5081
        }
5082
        break;
5083
    default:
5084
        MIPS_INVAL(opn);
5085
        generate_exception (ctx, EXCP_RI);
5086
        return;
5087
    }
5088
    switch (optype) {
5089
    case BINOP:
5090
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5091
        break;
5092
    case CMPOP:
5093
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5094
        break;
5095
    default:
5096
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5097
        break;
5098
    }
5099
}
5100

    
5101
/* Coprocessor 3 (FPU) */
5102
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5103
                           int base, int index)
5104
{
5105
    const char *opn = "extended float load/store";
5106

    
5107
    GEN_LOAD_REG_TN(T0, base);
5108
    GEN_LOAD_REG_TN(T1, index);
5109
    /* Don't do NOP if destination is zero: we must perform the actual
5110
     * memory access
5111
     */
5112
    switch (opc) {
5113
    case OPC_LWXC1:
5114
        op_ldst(lwxc1);
5115
        GEN_STORE_FTN_FREG(fd, WT0);
5116
        opn = "lwxc1";
5117
        break;
5118
    case OPC_LDXC1:
5119
        op_ldst(ldxc1);
5120
        GEN_STORE_FTN_FREG(fd, DT0);
5121
        opn = "ldxc1";
5122
        break;
5123
    case OPC_LUXC1:
5124
        op_ldst(luxc1);
5125
        GEN_STORE_FTN_FREG(fd, DT0);
5126
        opn = "luxc1";
5127
        break;
5128
    case OPC_SWXC1:
5129
        GEN_LOAD_FREG_FTN(WT0, fd);
5130
        op_ldst(swxc1);
5131
        opn = "swxc1";
5132
        break;
5133
    case OPC_SDXC1:
5134
        GEN_LOAD_FREG_FTN(DT0, fd);
5135
        op_ldst(sdxc1);
5136
        opn = "sdxc1";
5137
        break;
5138
    case OPC_SUXC1:
5139
        GEN_LOAD_FREG_FTN(DT0, fd);
5140
        op_ldst(suxc1);
5141
        opn = "suxc1";
5142
        break;
5143
    default:
5144
        MIPS_INVAL(opn);
5145
        generate_exception(ctx, EXCP_RI);
5146
        return;
5147
    }
5148
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
5149
}
5150

    
5151
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5152
                            int fr, int fs, int ft)
5153
{
5154
    const char *opn = "flt3_arith";
5155

    
5156
    /* All of those work only on 64bit FPUs. */
5157
    gen_op_cp1_registers(fd | fr | fs | ft);
5158
    switch (opc) {
5159
    case OPC_ALNV_PS:
5160
        GEN_LOAD_REG_TN(T0, fr);
5161
        GEN_LOAD_FREG_FTN(DT0, fs);
5162
        GEN_LOAD_FREG_FTN(DT1, ft);
5163
        gen_op_float_alnv_ps();
5164
        GEN_STORE_FTN_FREG(fd, DT2);
5165
        opn = "alnv.ps";
5166
        break;
5167
    case OPC_MADD_S:
5168
        GEN_LOAD_FREG_FTN(WT0, fs);
5169
        GEN_LOAD_FREG_FTN(WT1, ft);
5170
        GEN_LOAD_FREG_FTN(WT2, fr);
5171
        gen_op_float_muladd_s();
5172
        GEN_STORE_FTN_FREG(fd, WT2);
5173
        opn = "madd.s";
5174
        break;
5175
    case OPC_MADD_D:
5176
        GEN_LOAD_FREG_FTN(DT0, fs);
5177
        GEN_LOAD_FREG_FTN(DT1, ft);
5178
        GEN_LOAD_FREG_FTN(DT2, fr);
5179
        gen_op_float_muladd_d();
5180
        GEN_STORE_FTN_FREG(fd, DT2);
5181
        opn = "madd.d";
5182
        break;
5183
    case OPC_MADD_PS:
5184
        GEN_LOAD_FREG_FTN(WT0, fs);
5185
        GEN_LOAD_FREG_FTN(WTH0, fs);
5186
        GEN_LOAD_FREG_FTN(WT1, ft);
5187
        GEN_LOAD_FREG_FTN(WTH1, ft);
5188
        GEN_LOAD_FREG_FTN(WT2, fr);
5189
        GEN_LOAD_FREG_FTN(WTH2, fr);
5190
        gen_op_float_muladd_ps();
5191
        GEN_STORE_FTN_FREG(fd, WT2);
5192
        GEN_STORE_FTN_FREG(fd, WTH2);
5193
        opn = "madd.ps";
5194
        break;
5195
    case OPC_MSUB_S:
5196
        GEN_LOAD_FREG_FTN(WT0, fs);
5197
        GEN_LOAD_FREG_FTN(WT1, ft);
5198
        GEN_LOAD_FREG_FTN(WT2, fr);
5199
        gen_op_float_mulsub_s();
5200
        GEN_STORE_FTN_FREG(fd, WT2);
5201
        opn = "msub.s";
5202
        break;
5203
    case OPC_MSUB_D:
5204
        GEN_LOAD_FREG_FTN(DT0, fs);
5205
        GEN_LOAD_FREG_FTN(DT1, ft);
5206
        GEN_LOAD_FREG_FTN(DT2, fr);
5207
        gen_op_float_mulsub_d();
5208
        GEN_STORE_FTN_FREG(fd, DT2);
5209
        opn = "msub.d";
5210
        break;
5211
    case OPC_MSUB_PS:
5212
        GEN_LOAD_FREG_FTN(WT0, fs);
5213
        GEN_LOAD_FREG_FTN(WTH0, fs);
5214
        GEN_LOAD_FREG_FTN(WT1, ft);
5215
        GEN_LOAD_FREG_FTN(WTH1, ft);
5216
        GEN_LOAD_FREG_FTN(WT2, fr);
5217
        GEN_LOAD_FREG_FTN(WTH2, fr);
5218
        gen_op_float_mulsub_ps();
5219
        GEN_STORE_FTN_FREG(fd, WT2);
5220
        GEN_STORE_FTN_FREG(fd, WTH2);
5221
        opn = "msub.ps";
5222
        break;
5223
    case OPC_NMADD_S:
5224
        GEN_LOAD_FREG_FTN(WT0, fs);
5225
        GEN_LOAD_FREG_FTN(WT1, ft);
5226
        GEN_LOAD_FREG_FTN(WT2, fr);
5227
        gen_op_float_nmuladd_s();
5228
        GEN_STORE_FTN_FREG(fd, WT2);
5229
        opn = "nmadd.s";
5230
        break;
5231
    case OPC_NMADD_D:
5232
        GEN_LOAD_FREG_FTN(DT0, fs);
5233
        GEN_LOAD_FREG_FTN(DT1, ft);
5234
        GEN_LOAD_FREG_FTN(DT2, fr);
5235
        gen_op_float_nmuladd_d();
5236
        GEN_STORE_FTN_FREG(fd, DT2);
5237
        opn = "nmadd.d";
5238
        break;
5239
    case OPC_NMADD_PS:
5240
        GEN_LOAD_FREG_FTN(WT0, fs);
5241
        GEN_LOAD_FREG_FTN(WTH0, fs);
5242
        GEN_LOAD_FREG_FTN(WT1, ft);
5243
        GEN_LOAD_FREG_FTN(WTH1, ft);
5244
        GEN_LOAD_FREG_FTN(WT2, fr);
5245
        GEN_LOAD_FREG_FTN(WTH2, fr);
5246
        gen_op_float_nmuladd_ps();
5247
        GEN_STORE_FTN_FREG(fd, WT2);
5248
        GEN_STORE_FTN_FREG(fd, WTH2);
5249
        opn = "nmadd.ps";
5250
        break;
5251
    case OPC_NMSUB_S:
5252
        GEN_LOAD_FREG_FTN(WT0, fs);
5253
        GEN_LOAD_FREG_FTN(WT1, ft);
5254
        GEN_LOAD_FREG_FTN(WT2, fr);
5255
        gen_op_float_nmulsub_s();
5256
        GEN_STORE_FTN_FREG(fd, WT2);
5257
        opn = "nmsub.s";
5258
        break;
5259
    case OPC_NMSUB_D:
5260
        GEN_LOAD_FREG_FTN(DT0, fs);
5261
        GEN_LOAD_FREG_FTN(DT1, ft);
5262
        GEN_LOAD_FREG_FTN(DT2, fr);
5263
        gen_op_float_nmulsub_d();
5264
        GEN_STORE_FTN_FREG(fd, DT2);
5265
        opn = "nmsub.d";
5266
        break;
5267
    case OPC_NMSUB_PS:
5268
        GEN_LOAD_FREG_FTN(WT0, fs);
5269
        GEN_LOAD_FREG_FTN(WTH0, fs);
5270
        GEN_LOAD_FREG_FTN(WT1, ft);
5271
        GEN_LOAD_FREG_FTN(WTH1, ft);
5272
        GEN_LOAD_FREG_FTN(WT2, fr);
5273
        GEN_LOAD_FREG_FTN(WTH2, fr);
5274
        gen_op_float_nmulsub_ps();
5275
        GEN_STORE_FTN_FREG(fd, WT2);
5276
        GEN_STORE_FTN_FREG(fd, WTH2);
5277
        opn = "nmsub.ps";
5278
        break;
5279
    default:
5280
        MIPS_INVAL(opn);
5281
        generate_exception (ctx, EXCP_RI);
5282
        return;
5283
    }
5284
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5285
               fregnames[fs], fregnames[ft]);
5286
}
5287

    
5288
/* ISA extensions (ASEs) */
5289
/* MIPS16 extension to MIPS32 */
5290
/* SmartMIPS extension to MIPS32 */
5291

    
5292
#ifdef TARGET_MIPS64
5293

    
5294
/* MDMX extension to MIPS64 */
5295
/* MIPS-3D extension to MIPS64 */
5296

    
5297
#endif
5298

    
5299
static void decode_opc (CPUState *env, DisasContext *ctx)
5300
{
5301
    int32_t offset;
5302
    int rs, rt, rd, sa;
5303
    uint32_t op, op1, op2;
5304
    int16_t imm;
5305

    
5306
    /* make sure instructions are on a word boundary */
5307
    if (ctx->pc & 0x3) {
5308
        env->CP0_BadVAddr = ctx->pc;
5309
        generate_exception(ctx, EXCP_AdEL);
5310
        return;
5311
    }
5312

    
5313
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5314
        int l1;
5315
        /* Handle blikely not taken case */
5316
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5317
        l1 = gen_new_label();
5318
        gen_op_jnz_T2(l1);
5319
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5320
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5321
        gen_set_label(l1);
5322
    }
5323
    op = MASK_OP_MAJOR(ctx->opcode);
5324
    rs = (ctx->opcode >> 21) & 0x1f;
5325
    rt = (ctx->opcode >> 16) & 0x1f;
5326
    rd = (ctx->opcode >> 11) & 0x1f;
5327
    sa = (ctx->opcode >> 6) & 0x1f;
5328
    imm = (int16_t)ctx->opcode;
5329
    switch (op) {
5330
    case OPC_SPECIAL:
5331
        op1 = MASK_SPECIAL(ctx->opcode);
5332
        switch (op1) {
5333
        case OPC_SLL:          /* Arithmetic with immediate */
5334
        case OPC_SRL ... OPC_SRA:
5335
            gen_arith_imm(ctx, op1, rd, rt, sa);
5336
            break;
5337
        case OPC_SLLV:         /* Arithmetic */
5338
        case OPC_SRLV ... OPC_SRAV:
5339
        case OPC_MOVZ ... OPC_MOVN:
5340
        case OPC_ADD ... OPC_NOR:
5341
        case OPC_SLT ... OPC_SLTU:
5342
            gen_arith(ctx, op1, rd, rs, rt);
5343
            break;
5344
        case OPC_MULT ... OPC_DIVU:
5345
            gen_muldiv(ctx, op1, rs, rt);
5346
            break;
5347
        case OPC_JR ... OPC_JALR:
5348
            gen_compute_branch(ctx, op1, rs, rd, sa);
5349
            return;
5350
        case OPC_TGE ... OPC_TEQ: /* Traps */
5351
        case OPC_TNE:
5352
            gen_trap(ctx, op1, rs, rt, -1);
5353
            break;
5354
        case OPC_MFHI:          /* Move from HI/LO */
5355
        case OPC_MFLO:
5356
            gen_HILO(ctx, op1, rd);
5357
            break;
5358
        case OPC_MTHI:
5359
        case OPC_MTLO:          /* Move to HI/LO */
5360
            gen_HILO(ctx, op1, rs);
5361
            break;
5362
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5363
#ifdef MIPS_STRICT_STANDARD
5364
            MIPS_INVAL("PMON / selsl");
5365
            generate_exception(ctx, EXCP_RI);
5366
#else
5367
            gen_op_pmon(sa);
5368
#endif
5369
            break;
5370
        case OPC_SYSCALL:
5371
            generate_exception(ctx, EXCP_SYSCALL);
5372
            break;
5373
        case OPC_BREAK:
5374
            generate_exception(ctx, EXCP_BREAK);
5375
            break;
5376
        case OPC_SPIM:
5377
#ifdef MIPS_STRICT_STANDARD
5378
            MIPS_INVAL("SPIM");
5379
            generate_exception(ctx, EXCP_RI);
5380
#else
5381
           /* Implemented as RI exception for now. */
5382
            MIPS_INVAL("spim (unofficial)");
5383
            generate_exception(ctx, EXCP_RI);
5384
#endif
5385
            break;
5386
        case OPC_SYNC:
5387
            /* Treat as a noop. */
5388
            break;
5389

    
5390
        case OPC_MOVCI:
5391
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5392
                save_cpu_state(ctx, 1);
5393
                gen_op_cp1_enabled();
5394
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5395
                          (ctx->opcode >> 16) & 1);
5396
            } else {
5397
                generate_exception_err(ctx, EXCP_CpU, 1);
5398
            }
5399
            break;
5400

    
5401
#ifdef TARGET_MIPS64
5402
       /* MIPS64 specific opcodes */
5403
        case OPC_DSLL:
5404
        case OPC_DSRL ... OPC_DSRA:
5405
        case OPC_DSLL32:
5406
        case OPC_DSRL32 ... OPC_DSRA32:
5407
            gen_arith_imm(ctx, op1, rd, rt, sa);
5408
            break;
5409
        case OPC_DSLLV:
5410
        case OPC_DSRLV ... OPC_DSRAV:
5411
        case OPC_DADD ... OPC_DSUBU:
5412
            gen_arith(ctx, op1, rd, rs, rt);
5413
            break;
5414
        case OPC_DMULT ... OPC_DDIVU:
5415
            gen_muldiv(ctx, op1, rs, rt);
5416
            break;
5417
#endif
5418
        default:            /* Invalid */
5419
            MIPS_INVAL("special");
5420
            generate_exception(ctx, EXCP_RI);
5421
            break;
5422
        }
5423
        break;
5424
    case OPC_SPECIAL2:
5425
        op1 = MASK_SPECIAL2(ctx->opcode);
5426
        switch (op1) {
5427
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5428
        case OPC_MSUB ... OPC_MSUBU:
5429
            gen_muldiv(ctx, op1, rs, rt);
5430
            break;
5431
        case OPC_MUL:
5432
            gen_arith(ctx, op1, rd, rs, rt);
5433
            break;
5434
        case OPC_CLZ ... OPC_CLO:
5435
            gen_cl(ctx, op1, rd, rs);
5436
            break;
5437
        case OPC_SDBBP:
5438
            /* XXX: not clear which exception should be raised
5439
             *      when in debug mode...
5440
             */
5441
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5442
                generate_exception(ctx, EXCP_DBp);
5443
            } else {
5444
                generate_exception(ctx, EXCP_DBp);
5445
            }
5446
            /* Treat as a noop */
5447
            break;
5448
#ifdef TARGET_MIPS64
5449
        case OPC_DCLZ ... OPC_DCLO:
5450
            gen_cl(ctx, op1, rd, rs);
5451
            break;
5452
#endif
5453
        default:            /* Invalid */
5454
            MIPS_INVAL("special2");
5455
            generate_exception(ctx, EXCP_RI);
5456
            break;
5457
        }
5458
        break;
5459
    case OPC_SPECIAL3:
5460
         op1 = MASK_SPECIAL3(ctx->opcode);
5461
         switch (op1) {
5462
         case OPC_EXT:
5463
         case OPC_INS:
5464
             gen_bitops(ctx, op1, rt, rs, sa, rd);
5465
             break;
5466
         case OPC_BSHFL:
5467
             op2 = MASK_BSHFL(ctx->opcode);
5468
             switch (op2) {
5469
             case OPC_WSBH:
5470
                 GEN_LOAD_REG_TN(T1, rt);
5471
                 gen_op_wsbh();
5472
                 break;
5473
             case OPC_SEB:
5474
                 GEN_LOAD_REG_TN(T1, rt);
5475
                 gen_op_seb();
5476
                 break;
5477
             case OPC_SEH:
5478
                 GEN_LOAD_REG_TN(T1, rt);
5479
                 gen_op_seh();
5480
                 break;
5481
             default:            /* Invalid */
5482
                 MIPS_INVAL("bshfl");
5483
                 generate_exception(ctx, EXCP_RI);
5484
                 break;
5485
            }
5486
            GEN_STORE_TN_REG(rd, T0);
5487
            break;
5488
        case OPC_RDHWR:
5489
            switch (rd) {
5490
            case 0:
5491
                save_cpu_state(ctx, 1);
5492
                gen_op_rdhwr_cpunum();
5493
                break;
5494
            case 1:
5495
                save_cpu_state(ctx, 1);
5496
                gen_op_rdhwr_synci_step();
5497
                break;
5498
            case 2:
5499
                save_cpu_state(ctx, 1);
5500
                gen_op_rdhwr_cc();
5501
                break;
5502
            case 3:
5503
                save_cpu_state(ctx, 1);
5504
                gen_op_rdhwr_ccres();
5505
                break;
5506
            case 29:
5507
#if defined (CONFIG_USER_ONLY)
5508
                gen_op_tls_value ();
5509
                break;
5510
#endif
5511
            default:            /* Invalid */
5512
                MIPS_INVAL("rdhwr");
5513
                generate_exception(ctx, EXCP_RI);
5514
                break;
5515
            }
5516
            GEN_STORE_TN_REG(rt, T0);
5517
            break;
5518
#ifdef TARGET_MIPS64
5519
        case OPC_DEXTM ... OPC_DEXT:
5520
        case OPC_DINSM ... OPC_DINS:
5521
            gen_bitops(ctx, op1, rt, rs, sa, rd);
5522
            break;
5523
        case OPC_DBSHFL:
5524
            op2 = MASK_DBSHFL(ctx->opcode);
5525
            switch (op2) {
5526
            case OPC_DSBH:
5527
                GEN_LOAD_REG_TN(T1, rt);
5528
                gen_op_dsbh();
5529
                break;
5530
            case OPC_DSHD:
5531
                GEN_LOAD_REG_TN(T1, rt);
5532
                gen_op_dshd();
5533
                break;
5534
            default:            /* Invalid */
5535
                MIPS_INVAL("dbshfl");
5536
                generate_exception(ctx, EXCP_RI);
5537
                break;
5538
            }
5539
            GEN_STORE_TN_REG(rd, T0);
5540
#endif
5541
        default:            /* Invalid */
5542
            MIPS_INVAL("special3");
5543
            generate_exception(ctx, EXCP_RI);
5544
            break;
5545
        }
5546
        break;
5547
    case OPC_REGIMM:
5548
        op1 = MASK_REGIMM(ctx->opcode);
5549
        switch (op1) {
5550
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5551
        case OPC_BLTZAL ... OPC_BGEZALL:
5552
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
5553
            return;
5554
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5555
        case OPC_TNEI:
5556
            gen_trap(ctx, op1, rs, -1, imm);
5557
            break;
5558
        case OPC_SYNCI:
5559
            /* treat as noop */
5560
            break;
5561
        default:            /* Invalid */
5562
            MIPS_INVAL("regimm");
5563
            generate_exception(ctx, EXCP_RI);
5564
            break;
5565
        }
5566
        break;
5567
    case OPC_CP0:
5568
        save_cpu_state(ctx, 1);
5569
        gen_op_cp0_enabled();
5570
        op1 = MASK_CP0(ctx->opcode);
5571
        switch (op1) {
5572
        case OPC_MFC0:
5573
        case OPC_MTC0:
5574
#ifdef TARGET_MIPS64
5575
        case OPC_DMFC0:
5576
        case OPC_DMTC0:
5577
#endif
5578
            gen_cp0(env, ctx, op1, rt, rd);
5579
            break;
5580
        case OPC_C0_FIRST ... OPC_C0_LAST:
5581
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
5582
            break;
5583
        case OPC_MFMC0:
5584
            op2 = MASK_MFMC0(ctx->opcode);
5585
            switch (op2) {
5586
            case OPC_DI:
5587
                gen_op_di();
5588
                /* Stop translation as we may have switched the execution mode */
5589
                ctx->bstate = BS_STOP;
5590
                break;
5591
            case OPC_EI:
5592
                gen_op_ei();
5593
                /* Stop translation as we may have switched the execution mode */
5594
                ctx->bstate = BS_STOP;
5595
                break;
5596
            default:            /* Invalid */
5597
                MIPS_INVAL("mfmc0");
5598
                generate_exception(ctx, EXCP_RI);
5599
                break;
5600
            }
5601
            GEN_STORE_TN_REG(rt, T0);
5602
            break;
5603
        case OPC_RDPGPR:
5604
        case OPC_WRPGPR:
5605
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5606
                /* Shadow registers not implemented. */
5607
                GEN_LOAD_REG_TN(T0, rt);
5608
                GEN_STORE_TN_REG(rd, T0);
5609
            } else {
5610
                MIPS_INVAL("shadow register move");
5611
                generate_exception(ctx, EXCP_RI);
5612
            }
5613
            break;
5614
        default:
5615
            MIPS_INVAL("cp0");
5616
            generate_exception(ctx, EXCP_RI);
5617
            break;
5618
        }
5619
        break;
5620
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5621
         gen_arith_imm(ctx, op, rt, rs, imm);
5622
         break;
5623
    case OPC_J ... OPC_JAL: /* Jump */
5624
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5625
         gen_compute_branch(ctx, op, rs, rt, offset);
5626
         return;
5627
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
5628
    case OPC_BEQL ... OPC_BGTZL:
5629
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
5630
         return;
5631
    case OPC_LB ... OPC_LWR: /* Load and stores */
5632
    case OPC_SB ... OPC_SW:
5633
    case OPC_SWR:
5634
    case OPC_LL:
5635
    case OPC_SC:
5636
         gen_ldst(ctx, op, rt, rs, imm);
5637
         break;
5638
    case OPC_CACHE:
5639
        /* FIXME: This works around self-modifying code, but only
5640
           if the guest OS handles it properly, and if there's no
5641
           such code executed in uncached space. */
5642
        if (!(rt & 0x3))
5643
            switch ((rt >> 2) & 0x7) {
5644
            case 4:
5645
                GEN_LOAD_REG_TN(T0, rs);
5646
                GEN_LOAD_IMM_TN(T1, imm);
5647
                gen_op_flush_icache_range();
5648
                break;
5649
            case 2:
5650
            case 1:
5651
            case 0:
5652
                /* Can be very inefficient. */
5653
                gen_op_flush_icache_all();
5654
                break;
5655
            default:
5656
                break;
5657
            }
5658
        break;
5659
    case OPC_PREF:
5660
        /* Treat as a noop */
5661
        break;
5662

    
5663
    /* Floating point (COP1). */
5664
    case OPC_LWC1:
5665
    case OPC_LDC1:
5666
    case OPC_SWC1:
5667
    case OPC_SDC1:
5668
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5669
            save_cpu_state(ctx, 1);
5670
            gen_op_cp1_enabled();
5671
            gen_flt_ldst(ctx, op, rt, rs, imm);
5672
        } else {
5673
            generate_exception_err(ctx, EXCP_CpU, 1);
5674
        }
5675
        break;
5676

    
5677
    case OPC_CP1:
5678
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5679
            save_cpu_state(ctx, 1);
5680
            gen_op_cp1_enabled();
5681
            op1 = MASK_CP1(ctx->opcode);
5682
            switch (op1) {
5683
            case OPC_MFC1:
5684
            case OPC_CFC1:
5685
            case OPC_MTC1:
5686
            case OPC_CTC1:
5687
#ifdef TARGET_MIPS64
5688
            case OPC_DMFC1:
5689
            case OPC_DMTC1:
5690
#endif
5691
            case OPC_MFHC1:
5692
            case OPC_MTHC1:
5693
                gen_cp1(ctx, op1, rt, rd);
5694
                break;
5695
            case OPC_BC1:
5696
            case OPC_BC1ANY2:
5697
            case OPC_BC1ANY4:
5698
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5699
                                    (rt >> 2) & 0x7, imm << 2);
5700
                return;
5701
            case OPC_S_FMT:
5702
            case OPC_D_FMT:
5703
            case OPC_W_FMT:
5704
            case OPC_L_FMT:
5705
            case OPC_PS_FMT:
5706
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5707
                           (imm >> 8) & 0x7);
5708
                break;
5709
            default:
5710
                MIPS_INVAL("cp1");
5711
                generate_exception (ctx, EXCP_RI);
5712
                break;
5713
            }
5714
        } else {
5715
            generate_exception_err(ctx, EXCP_CpU, 1);
5716
        }
5717
        break;
5718

    
5719
    /* COP2.  */
5720
    case OPC_LWC2:
5721
    case OPC_LDC2:
5722
    case OPC_SWC2:
5723
    case OPC_SDC2:
5724
    case OPC_CP2:
5725
        /* COP2: Not implemented. */
5726
        generate_exception_err(ctx, EXCP_CpU, 2);
5727
        break;
5728

    
5729
    case OPC_CP3:
5730
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5731
            save_cpu_state(ctx, 1);
5732
            gen_op_cp1_enabled();
5733
            op1 = MASK_CP3(ctx->opcode);
5734
            switch (op1) {
5735
            case OPC_LWXC1:
5736
            case OPC_LDXC1:
5737
            case OPC_LUXC1:
5738
            case OPC_SWXC1:
5739
            case OPC_SDXC1:
5740
            case OPC_SUXC1:
5741
                gen_flt3_ldst(ctx, op1, sa, rs, rt);
5742
                break;
5743
            case OPC_PREFX:
5744
                /* treat as noop */
5745
                break;
5746
            case OPC_ALNV_PS:
5747
            case OPC_MADD_S:
5748
            case OPC_MADD_D:
5749
            case OPC_MADD_PS:
5750
            case OPC_MSUB_S:
5751
            case OPC_MSUB_D:
5752
            case OPC_MSUB_PS:
5753
            case OPC_NMADD_S:
5754
            case OPC_NMADD_D:
5755
            case OPC_NMADD_PS:
5756
            case OPC_NMSUB_S:
5757
            case OPC_NMSUB_D:
5758
            case OPC_NMSUB_PS:
5759
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5760
                break;
5761
            default:
5762
                MIPS_INVAL("cp3");
5763
                generate_exception (ctx, EXCP_RI);
5764
                break;
5765
            }
5766
        } else {
5767
            generate_exception_err(ctx, EXCP_CpU, 1);
5768
        }
5769
        break;
5770

    
5771
#ifdef TARGET_MIPS64
5772
    /* MIPS64 opcodes */
5773
    case OPC_LWU:
5774
    case OPC_LDL ... OPC_LDR:
5775
    case OPC_SDL ... OPC_SDR:
5776
    case OPC_LLD:
5777
    case OPC_LD:
5778
    case OPC_SCD:
5779
    case OPC_SD:
5780
        gen_ldst(ctx, op, rt, rs, imm);
5781
        break;
5782
    case OPC_DADDI ... OPC_DADDIU:
5783
        gen_arith_imm(ctx, op, rt, rs, imm);
5784
        break;
5785
#endif
5786
#ifdef MIPS_HAS_MIPS16
5787
    case OPC_JALX:
5788
        /* MIPS16: Not implemented. */
5789
#endif
5790
#ifdef MIPS_HAS_MDMX
5791
    case OPC_MDMX:
5792
        /* MDMX: Not implemented. */
5793
#endif
5794
    default:            /* Invalid */
5795
        MIPS_INVAL("major opcode");
5796
        generate_exception(ctx, EXCP_RI);
5797
        break;
5798
    }
5799
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5800
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5801
        /* Branches completion */
5802
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5803
        ctx->bstate = BS_BRANCH;
5804
        save_cpu_state(ctx, 0);
5805
        switch (hflags) {
5806
        case MIPS_HFLAG_B:
5807
            /* unconditional branch */
5808
            MIPS_DEBUG("unconditional branch");
5809
            gen_goto_tb(ctx, 0, ctx->btarget);
5810
            break;
5811
        case MIPS_HFLAG_BL:
5812
            /* blikely taken case */
5813
            MIPS_DEBUG("blikely branch taken");
5814
            gen_goto_tb(ctx, 0, ctx->btarget);
5815
            break;
5816
        case MIPS_HFLAG_BC:
5817
            /* Conditional branch */
5818
            MIPS_DEBUG("conditional branch");
5819
            {
5820
              int l1;
5821
              l1 = gen_new_label();
5822
              gen_op_jnz_T2(l1);
5823
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5824
              gen_set_label(l1);
5825
              gen_goto_tb(ctx, 0, ctx->btarget);
5826
            }
5827
            break;
5828
        case MIPS_HFLAG_BR:
5829
            /* unconditional branch to register */
5830
            MIPS_DEBUG("branch to register");
5831
            gen_op_breg();
5832
            gen_op_reset_T0();
5833
            gen_op_exit_tb();
5834
            break;
5835
        default:
5836
            MIPS_DEBUG("unknown branch");
5837
            break;
5838
        }
5839
    }
5840
}
5841

    
5842
static inline int
5843
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5844
                                int search_pc)
5845
{
5846
    DisasContext ctx, *ctxp = &ctx;
5847
    target_ulong pc_start;
5848
    uint16_t *gen_opc_end;
5849
    int j, lj = -1;
5850

    
5851
    if (search_pc && loglevel)
5852
        fprintf (logfile, "search pc %d\n", search_pc);
5853

    
5854
    pc_start = tb->pc;
5855
    gen_opc_ptr = gen_opc_buf;
5856
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5857
    gen_opparam_ptr = gen_opparam_buf;
5858
    nb_gen_labels = 0;
5859
    ctx.pc = pc_start;
5860
    ctx.saved_pc = -1;
5861
    ctx.tb = tb;
5862
    ctx.bstate = BS_NONE;
5863
    /* Restore delay slot state from the tb context.  */
5864
    ctx.hflags = tb->flags;
5865
    restore_cpu_state(env, &ctx);
5866
#if defined(CONFIG_USER_ONLY)
5867
    ctx.mem_idx = 0;
5868
#else
5869
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5870
#endif
5871
#ifdef DEBUG_DISAS
5872
    if (loglevel & CPU_LOG_TB_CPU) {
5873
        fprintf(logfile, "------------------------------------------------\n");
5874
        /* FIXME: This may print out stale hflags from env... */
5875
        cpu_dump_state(env, logfile, fprintf, 0);
5876
    }
5877
#endif
5878
#ifdef MIPS_DEBUG_DISAS
5879
    if (loglevel & CPU_LOG_TB_IN_ASM)
5880
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5881
                tb, ctx.mem_idx, ctx.hflags);
5882
#endif
5883
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5884
        if (env->nb_breakpoints > 0) {
5885
            for(j = 0; j < env->nb_breakpoints; j++) {
5886
                if (env->breakpoints[j] == ctx.pc) {
5887
                    save_cpu_state(ctxp, 1);
5888
                    ctx.bstate = BS_BRANCH;
5889
                    gen_op_debug();
5890
                    goto done_generating;
5891
                }
5892
            }
5893
        }
5894

    
5895
        if (search_pc) {
5896
            j = gen_opc_ptr - gen_opc_buf;
5897
            if (lj < j) {
5898
                lj++;
5899
                while (lj < j)
5900
                    gen_opc_instr_start[lj++] = 0;
5901
            }
5902
            gen_opc_pc[lj] = ctx.pc;
5903
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5904
            gen_opc_instr_start[lj] = 1;
5905
        }
5906
        ctx.opcode = ldl_code(ctx.pc);
5907
        decode_opc(env, &ctx);
5908
        ctx.pc += 4;
5909

    
5910
        if (env->singlestep_enabled)
5911
            break;
5912

    
5913
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5914
            break;
5915

    
5916
#if defined (MIPS_SINGLE_STEP)
5917
        break;
5918
#endif
5919
    }
5920
    if (env->singlestep_enabled) {
5921
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5922
        gen_op_debug();
5923
    } else {
5924
        switch (ctx.bstate) {
5925
        case BS_STOP:
5926
            gen_op_interrupt_restart();
5927
            /* Fall through. */
5928
        case BS_NONE:
5929
            save_cpu_state(ctxp, 0);
5930
            gen_goto_tb(&ctx, 0, ctx.pc);
5931
            break;
5932
        case BS_EXCP:
5933
            gen_op_interrupt_restart();
5934
            gen_op_reset_T0();
5935
            gen_op_exit_tb();
5936
            break;
5937
        case BS_BRANCH:
5938
        default:
5939
            break;
5940
        }
5941
    }
5942
done_generating:
5943
    *gen_opc_ptr = INDEX_op_end;
5944
    if (search_pc) {
5945
        j = gen_opc_ptr - gen_opc_buf;
5946
        lj++;
5947
        while (lj <= j)
5948
            gen_opc_instr_start[lj++] = 0;
5949
        tb->size = 0;
5950
    } else {
5951
        tb->size = ctx.pc - pc_start;
5952
    }
5953
#ifdef DEBUG_DISAS
5954
#if defined MIPS_DEBUG_DISAS
5955
    if (loglevel & CPU_LOG_TB_IN_ASM)
5956
        fprintf(logfile, "\n");
5957
#endif
5958
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5959
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5960
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5961
        fprintf(logfile, "\n");
5962
    }
5963
    if (loglevel & CPU_LOG_TB_OP) {
5964
        fprintf(logfile, "OP:\n");
5965
        dump_ops(gen_opc_buf, gen_opparam_buf);
5966
        fprintf(logfile, "\n");
5967
    }
5968
    if (loglevel & CPU_LOG_TB_CPU) {
5969
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5970
    }
5971
#endif
5972
    
5973
    return 0;
5974
}
5975

    
5976
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5977
{
5978
    return gen_intermediate_code_internal(env, tb, 0);
5979
}
5980

    
5981
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5982
{
5983
    return gen_intermediate_code_internal(env, tb, 1);
5984
}
5985

    
5986
void fpu_dump_state(CPUState *env, FILE *f, 
5987
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5988
                    int flags)
5989
{
5990
    int i;
5991
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5992

    
5993
#define printfpr(fp)                                                        \
5994
    do {                                                                    \
5995
        if (is_fpu64)                                                       \
5996
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5997
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5998
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5999
        else {                                                              \
6000
            fpr_t tmp;                                                      \
6001
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6002
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6003
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6004
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6005
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6006
        }                                                                   \
6007
    } while(0)
6008

    
6009

    
6010
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6011
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6012
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6013
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6014
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
6015
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6016
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6017
        printfpr(&env->fpr[i]);
6018
    }
6019

    
6020
#undef printfpr
6021
}
6022

    
6023
void dump_fpu (CPUState *env)
6024
{
6025
    if (loglevel) { 
6026
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6027
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6028
       fpu_dump_state(env, logfile, fprintf, 0);
6029
    }
6030
}
6031

    
6032
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6033
/* Debug help: The architecture requires 32bit code to maintain proper
6034
   sign-extened values on 64bit machines.  */
6035

    
6036
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6037

    
6038
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6039
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6040
                     int flags)
6041
{
6042
    int i;
6043

    
6044
    if (!SIGN_EXT_P(env->PC))
6045
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6046
    if (!SIGN_EXT_P(env->HI))
6047
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6048
    if (!SIGN_EXT_P(env->LO))
6049
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6050
    if (!SIGN_EXT_P(env->btarget))
6051
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6052

    
6053
    for (i = 0; i < 32; i++) {
6054
        if (!SIGN_EXT_P(env->gpr[i]))
6055
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6056
    }
6057

    
6058
    if (!SIGN_EXT_P(env->CP0_EPC))
6059
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6060
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6061
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6062
}
6063
#endif
6064

    
6065
void cpu_dump_state (CPUState *env, FILE *f, 
6066
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6067
                     int flags)
6068
{
6069
    uint32_t c0_status;
6070
    int i;
6071
    
6072
    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",
6073
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6074
    for (i = 0; i < 32; i++) {
6075
        if ((i & 3) == 0)
6076
            cpu_fprintf(f, "GPR%02d:", i);
6077
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6078
        if ((i & 3) == 3)
6079
            cpu_fprintf(f, "\n");
6080
    }
6081

    
6082
    c0_status = env->CP0_Status;
6083

    
6084
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6085
                c0_status, env->CP0_Cause, env->CP0_EPC);
6086
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6087
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6088
    if (c0_status & (1 << CP0St_CU1))
6089
        fpu_dump_state(env, f, cpu_fprintf, flags);
6090
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6091
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6092
#endif
6093
}
6094

    
6095
CPUMIPSState *cpu_mips_init (void)
6096
{
6097
    CPUMIPSState *env;
6098

    
6099
    env = qemu_mallocz(sizeof(CPUMIPSState));
6100
    if (!env)
6101
        return NULL;
6102
    cpu_exec_init(env);
6103
    cpu_reset(env);
6104
    return env;
6105
}
6106

    
6107
void cpu_reset (CPUMIPSState *env)
6108
{
6109
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6110

    
6111
    tlb_flush(env, 1);
6112

    
6113
    /* Minimal init */
6114
#if !defined(CONFIG_USER_ONLY)
6115
    if (env->hflags & MIPS_HFLAG_BMASK) {
6116
        /* If the exception was raised from a delay slot,
6117
         * come back to the jump.  */
6118
        env->CP0_ErrorEPC = env->PC - 4;
6119
        env->hflags &= ~MIPS_HFLAG_BMASK;
6120
    } else {
6121
        env->CP0_ErrorEPC = env->PC;
6122
    }
6123
    env->hflags = 0;
6124
    env->PC = (int32_t)0xBFC00000;
6125
    env->CP0_Wired = 0;
6126
    /* SMP not implemented */
6127
    env->CP0_EBase = 0x80000000;
6128
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6129
    /* vectored interrupts not implemented, timer on int 7,
6130
       no performance counters. */
6131
    env->CP0_IntCtl = 0xe0000000;
6132
    env->CP0_WatchLo = 0;
6133
    env->CP0_WatchHi = 0;
6134
    /* Count register increments in debug mode, EJTAG version 1 */
6135
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6136
#endif
6137
    env->exception_index = EXCP_NONE;
6138
#if defined(CONFIG_USER_ONLY)
6139
    env->hflags |= MIPS_HFLAG_UM;
6140
    env->user_mode_only = 1;
6141
#endif
6142
}
6143

    
6144
#include "translate_init.c"