Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (163.1 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
#ifdef TARGET_MIPS64
573
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
574
do {                                                                          \
575
    if (Imm == 0) {                                                           \
576
        glue(gen_op_reset_, Tn)();                                            \
577
    } else if ((int32_t)Imm == Imm) {                                         \
578
        glue(gen_op_set_, Tn)(Imm);                                           \
579
    } else {                                                                  \
580
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
581
    }                                                                         \
582
} while (0)
583
#else
584
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
585
do {                                                                          \
586
    if (Imm == 0) {                                                           \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_set_, Tn)(Imm);                                           \
590
    }                                                                         \
591
} while (0)
592
#endif
593

    
594
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
595
do {                                                                          \
596
    if (Rn != 0) {                                                            \
597
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
598
    }                                                                         \
599
} while (0)
600

    
601
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
602
do {                                                                          \
603
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
604
} while (0)
605

    
606
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
607
do {                                                                          \
608
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
609
} while (0)
610

    
611
static inline void gen_save_pc(target_ulong pc)
612
{
613
#ifdef TARGET_MIPS64
614
    if (pc == (int32_t)pc) {
615
        gen_op_save_pc(pc);
616
    } else {
617
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
618
    }
619
#else
620
    gen_op_save_pc(pc);
621
#endif
622
}
623

    
624
static inline void gen_save_btarget(target_ulong btarget)
625
{
626
#ifdef TARGET_MIPS64
627
    if (btarget == (int32_t)btarget) {
628
        gen_op_save_btarget(btarget);
629
    } else {
630
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
631
    }
632
#else
633
    gen_op_save_btarget(btarget);
634
#endif
635
}
636

    
637
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
638
{
639
#if defined MIPS_DEBUG_DISAS
640
    if (loglevel & CPU_LOG_TB_IN_ASM) {
641
            fprintf(logfile, "hflags %08x saved %08x\n",
642
                    ctx->hflags, ctx->saved_hflags);
643
    }
644
#endif
645
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
646
        gen_save_pc(ctx->pc);
647
        ctx->saved_pc = ctx->pc;
648
    }
649
    if (ctx->hflags != ctx->saved_hflags) {
650
        gen_op_save_state(ctx->hflags);
651
        ctx->saved_hflags = ctx->hflags;
652
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
653
        case MIPS_HFLAG_BR:
654
            gen_op_save_breg_target();
655
            break;
656
        case MIPS_HFLAG_BC:
657
            gen_op_save_bcond();
658
            /* fall through */
659
        case MIPS_HFLAG_BL:
660
            /* bcond was already saved by the BL insn */
661
            /* fall through */
662
        case MIPS_HFLAG_B:
663
            gen_save_btarget(ctx->btarget);
664
            break;
665
        }
666
    }
667
}
668

    
669
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
670
{
671
    ctx->saved_hflags = ctx->hflags;
672
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
673
    case MIPS_HFLAG_BR:
674
        gen_op_restore_breg_target();
675
        break;
676
    case MIPS_HFLAG_B:
677
        ctx->btarget = env->btarget;
678
        break;
679
    case MIPS_HFLAG_BC:
680
    case MIPS_HFLAG_BL:
681
        ctx->btarget = env->btarget;
682
        gen_op_restore_bcond();
683
        break;
684
    }
685
}
686

    
687
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
688
{
689
#if defined MIPS_DEBUG_DISAS
690
    if (loglevel & CPU_LOG_TB_IN_ASM)
691
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
692
#endif
693
    save_cpu_state(ctx, 1);
694
    if (err == 0)
695
        gen_op_raise_exception(excp);
696
    else
697
        gen_op_raise_exception_err(excp, err);
698
    ctx->bstate = BS_EXCP;
699
}
700

    
701
static inline void generate_exception (DisasContext *ctx, int excp)
702
{
703
    generate_exception_err (ctx, excp, 0);
704
}
705

    
706
#if defined(CONFIG_USER_ONLY)
707
#define op_ldst(name)        gen_op_##name##_raw()
708
#define OP_LD_TABLE(width)
709
#define OP_ST_TABLE(width)
710
#else
711
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
712
#define OP_LD_TABLE(width)                                                    \
713
static GenOpFunc *gen_op_l##width[] = {                                       \
714
    &gen_op_l##width##_user,                                                  \
715
    &gen_op_l##width##_kernel,                                                \
716
}
717
#define OP_ST_TABLE(width)                                                    \
718
static GenOpFunc *gen_op_s##width[] = {                                       \
719
    &gen_op_s##width##_user,                                                  \
720
    &gen_op_s##width##_kernel,                                                \
721
}
722
#endif
723

    
724
#ifdef TARGET_MIPS64
725
OP_LD_TABLE(d);
726
OP_LD_TABLE(dl);
727
OP_LD_TABLE(dr);
728
OP_ST_TABLE(d);
729
OP_ST_TABLE(dl);
730
OP_ST_TABLE(dr);
731
OP_LD_TABLE(ld);
732
OP_ST_TABLE(cd);
733
#endif
734
OP_LD_TABLE(w);
735
OP_LD_TABLE(wu);
736
OP_LD_TABLE(wl);
737
OP_LD_TABLE(wr);
738
OP_ST_TABLE(w);
739
OP_ST_TABLE(wl);
740
OP_ST_TABLE(wr);
741
OP_LD_TABLE(h);
742
OP_LD_TABLE(hu);
743
OP_ST_TABLE(h);
744
OP_LD_TABLE(b);
745
OP_LD_TABLE(bu);
746
OP_ST_TABLE(b);
747
OP_LD_TABLE(l);
748
OP_ST_TABLE(c);
749
OP_LD_TABLE(wc1);
750
OP_ST_TABLE(wc1);
751
OP_LD_TABLE(dc1);
752
OP_ST_TABLE(dc1);
753
OP_LD_TABLE(uxc1);
754
OP_ST_TABLE(uxc1);
755

    
756
/* Load and store */
757
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
758
                      int base, int16_t offset)
759
{
760
    const char *opn = "ldst";
761

    
762
    if (base == 0) {
763
        GEN_LOAD_IMM_TN(T0, offset);
764
    } else if (offset == 0) {
765
        gen_op_load_gpr_T0(base);
766
    } else {
767
        gen_op_load_gpr_T0(base);
768
        gen_op_set_T1(offset);
769
        gen_op_addr_add();
770
    }
771
    /* Don't do NOP if destination is zero: we must perform the actual
772
     * memory access
773
     */
774
    switch (opc) {
775
#ifdef TARGET_MIPS64
776
    case OPC_LD:
777
        op_ldst(ld);
778
        GEN_STORE_TN_REG(rt, T0);
779
        opn = "ld";
780
        break;
781
    case OPC_LLD:
782
        op_ldst(lld);
783
        GEN_STORE_TN_REG(rt, T0);
784
        opn = "lld";
785
        break;
786
    case OPC_SD:
787
        GEN_LOAD_REG_TN(T1, rt);
788
        op_ldst(sd);
789
        opn = "sd";
790
        break;
791
    case OPC_SCD:
792
        save_cpu_state(ctx, 1);
793
        GEN_LOAD_REG_TN(T1, rt);
794
        op_ldst(scd);
795
        GEN_STORE_TN_REG(rt, T0);
796
        opn = "scd";
797
        break;
798
    case OPC_LDL:
799
        GEN_LOAD_REG_TN(T1, rt);
800
        op_ldst(ldl);
801
        GEN_STORE_TN_REG(rt, T0);
802
        opn = "ldl";
803
        break;
804
    case OPC_SDL:
805
        GEN_LOAD_REG_TN(T1, rt);
806
        op_ldst(sdl);
807
        opn = "sdl";
808
        break;
809
    case OPC_LDR:
810
        GEN_LOAD_REG_TN(T1, rt);
811
        op_ldst(ldr);
812
        GEN_STORE_TN_REG(rt, T0);
813
        opn = "ldr";
814
        break;
815
    case OPC_SDR:
816
        GEN_LOAD_REG_TN(T1, rt);
817
        op_ldst(sdr);
818
        opn = "sdr";
819
        break;
820
#endif
821
    case OPC_LW:
822
        op_ldst(lw);
823
        GEN_STORE_TN_REG(rt, T0);
824
        opn = "lw";
825
        break;
826
    case OPC_LWU:
827
        op_ldst(lwu);
828
        GEN_STORE_TN_REG(rt, T0);
829
        opn = "lwu";
830
        break;
831
    case OPC_SW:
832
        GEN_LOAD_REG_TN(T1, rt);
833
        op_ldst(sw);
834
        opn = "sw";
835
        break;
836
    case OPC_LH:
837
        op_ldst(lh);
838
        GEN_STORE_TN_REG(rt, T0);
839
        opn = "lh";
840
        break;
841
    case OPC_SH:
842
        GEN_LOAD_REG_TN(T1, rt);
843
        op_ldst(sh);
844
        opn = "sh";
845
        break;
846
    case OPC_LHU:
847
        op_ldst(lhu);
848
        GEN_STORE_TN_REG(rt, T0);
849
        opn = "lhu";
850
        break;
851
    case OPC_LB:
852
        op_ldst(lb);
853
        GEN_STORE_TN_REG(rt, T0);
854
        opn = "lb";
855
        break;
856
    case OPC_SB:
857
        GEN_LOAD_REG_TN(T1, rt);
858
        op_ldst(sb);
859
        opn = "sb";
860
        break;
861
    case OPC_LBU:
862
        op_ldst(lbu);
863
        GEN_STORE_TN_REG(rt, T0);
864
        opn = "lbu";
865
        break;
866
    case OPC_LWL:
867
        GEN_LOAD_REG_TN(T1, rt);
868
        op_ldst(lwl);
869
        GEN_STORE_TN_REG(rt, T0);
870
        opn = "lwl";
871
        break;
872
    case OPC_SWL:
873
        GEN_LOAD_REG_TN(T1, rt);
874
        op_ldst(swl);
875
        opn = "swr";
876
        break;
877
    case OPC_LWR:
878
        GEN_LOAD_REG_TN(T1, rt);
879
        op_ldst(lwr);
880
        GEN_STORE_TN_REG(rt, T0);
881
        opn = "lwr";
882
        break;
883
    case OPC_SWR:
884
        GEN_LOAD_REG_TN(T1, rt);
885
        op_ldst(swr);
886
        opn = "swr";
887
        break;
888
    case OPC_LL:
889
        op_ldst(ll);
890
        GEN_STORE_TN_REG(rt, T0);
891
        opn = "ll";
892
        break;
893
    case OPC_SC:
894
        save_cpu_state(ctx, 1);
895
        GEN_LOAD_REG_TN(T1, rt);
896
        op_ldst(sc);
897
        GEN_STORE_TN_REG(rt, T0);
898
        opn = "sc";
899
        break;
900
    default:
901
        MIPS_INVAL(opn);
902
        generate_exception(ctx, EXCP_RI);
903
        return;
904
    }
905
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
906
}
907

    
908
/* Load and store */
909
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
910
                      int base, int16_t offset)
911
{
912
    const char *opn = "flt_ldst";
913

    
914
    if (base == 0) {
915
        GEN_LOAD_IMM_TN(T0, offset);
916
    } else if (offset == 0) {
917
        gen_op_load_gpr_T0(base);
918
    } else {
919
        gen_op_load_gpr_T0(base);
920
        gen_op_set_T1(offset);
921
        gen_op_addr_add();
922
    }
923
    /* Don't do NOP if destination is zero: we must perform the actual
924
     * memory access
925
     */
926
    switch (opc) {
927
    case OPC_LWC1:
928
        op_ldst(lwc1);
929
        GEN_STORE_FTN_FREG(ft, WT0);
930
        opn = "lwc1";
931
        break;
932
    case OPC_SWC1:
933
        GEN_LOAD_FREG_FTN(WT0, ft);
934
        op_ldst(swc1);
935
        opn = "swc1";
936
        break;
937
    case OPC_LDC1:
938
        op_ldst(ldc1);
939
        GEN_STORE_FTN_FREG(ft, DT0);
940
        opn = "ldc1";
941
        break;
942
    case OPC_SDC1:
943
        GEN_LOAD_FREG_FTN(DT0, ft);
944
        op_ldst(sdc1);
945
        opn = "sdc1";
946
        break;
947
    default:
948
        MIPS_INVAL(opn);
949
        generate_exception(ctx, EXCP_RI);
950
        return;
951
    }
952
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
953
}
954

    
955
/* Arithmetic with immediate operand */
956
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
957
                           int rs, int16_t imm)
958
{
959
    target_ulong uimm;
960
    const char *opn = "imm arith";
961

    
962
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
963
        /* if no destination, treat it as a NOP 
964
         * For addi, we must generate the overflow exception when needed.
965
         */
966
        MIPS_DEBUG("NOP");
967
        return;
968
    }
969
    uimm = (uint16_t)imm;
970
    switch (opc) {
971
    case OPC_ADDI:
972
    case OPC_ADDIU:
973
#ifdef TARGET_MIPS64
974
    case OPC_DADDI:
975
    case OPC_DADDIU:
976
#endif
977
    case OPC_SLTI:
978
    case OPC_SLTIU:
979
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
980
        /* Fall through. */
981
    case OPC_ANDI:
982
    case OPC_ORI:
983
    case OPC_XORI:
984
        GEN_LOAD_REG_TN(T0, rs);
985
        GEN_LOAD_IMM_TN(T1, uimm);
986
        break;
987
    case OPC_LUI:
988
        GEN_LOAD_IMM_TN(T0, imm << 16);
989
        break;
990
    case OPC_SLL:
991
    case OPC_SRA:
992
    case OPC_SRL:
993
#ifdef TARGET_MIPS64
994
    case OPC_DSLL:
995
    case OPC_DSRA:
996
    case OPC_DSRL:
997
    case OPC_DSLL32:
998
    case OPC_DSRA32:
999
    case OPC_DSRL32:
1000
#endif
1001
        uimm &= 0x1f;
1002
        GEN_LOAD_REG_TN(T0, rs);
1003
        GEN_LOAD_IMM_TN(T1, uimm);
1004
        break;
1005
    }
1006
    switch (opc) {
1007
    case OPC_ADDI:
1008
        save_cpu_state(ctx, 1);
1009
        gen_op_addo();
1010
        opn = "addi";
1011
        break;
1012
    case OPC_ADDIU:
1013
        gen_op_add();
1014
        opn = "addiu";
1015
        break;
1016
#ifdef TARGET_MIPS64
1017
    case OPC_DADDI:
1018
        save_cpu_state(ctx, 1);
1019
        gen_op_daddo();
1020
        opn = "daddi";
1021
        break;
1022
    case OPC_DADDIU:
1023
        gen_op_dadd();
1024
        opn = "daddiu";
1025
        break;
1026
#endif
1027
    case OPC_SLTI:
1028
        gen_op_lt();
1029
        opn = "slti";
1030
        break;
1031
    case OPC_SLTIU:
1032
        gen_op_ltu();
1033
        opn = "sltiu";
1034
        break;
1035
    case OPC_ANDI:
1036
        gen_op_and();
1037
        opn = "andi";
1038
        break;
1039
    case OPC_ORI:
1040
        gen_op_or();
1041
        opn = "ori";
1042
        break;
1043
    case OPC_XORI:
1044
        gen_op_xor();
1045
        opn = "xori";
1046
        break;
1047
    case OPC_LUI:
1048
        opn = "lui";
1049
        break;
1050
    case OPC_SLL:
1051
        gen_op_sll();
1052
        opn = "sll";
1053
        break;
1054
    case OPC_SRA:
1055
        gen_op_sra();
1056
        opn = "sra";
1057
        break;
1058
    case OPC_SRL:
1059
        switch ((ctx->opcode >> 21) & 0x1f) {
1060
        case 0:
1061
            gen_op_srl();
1062
            opn = "srl";
1063
            break;
1064
        case 1:
1065
            gen_op_rotr();
1066
            opn = "rotr";
1067
            break;
1068
        default:
1069
            MIPS_INVAL("invalid srl flag");
1070
            generate_exception(ctx, EXCP_RI);
1071
            break;
1072
        }
1073
        break;
1074
#ifdef TARGET_MIPS64
1075
    case OPC_DSLL:
1076
        gen_op_dsll();
1077
        opn = "dsll";
1078
        break;
1079
    case OPC_DSRA:
1080
        gen_op_dsra();
1081
        opn = "dsra";
1082
        break;
1083
    case OPC_DSRL:
1084
        switch ((ctx->opcode >> 21) & 0x1f) {
1085
        case 0:
1086
            gen_op_dsrl();
1087
            opn = "dsrl";
1088
            break;
1089
        case 1:
1090
            gen_op_drotr();
1091
            opn = "drotr";
1092
            break;
1093
        default:
1094
            MIPS_INVAL("invalid dsrl flag");
1095
            generate_exception(ctx, EXCP_RI);
1096
            break;
1097
        }
1098
        break;
1099
    case OPC_DSLL32:
1100
        gen_op_dsll32();
1101
        opn = "dsll32";
1102
        break;
1103
    case OPC_DSRA32:
1104
        gen_op_dsra32();
1105
        opn = "dsra32";
1106
        break;
1107
    case OPC_DSRL32:
1108
        switch ((ctx->opcode >> 21) & 0x1f) {
1109
        case 0:
1110
            gen_op_dsrl32();
1111
            opn = "dsrl32";
1112
            break;
1113
        case 1:
1114
            gen_op_drotr32();
1115
            opn = "drotr32";
1116
            break;
1117
        default:
1118
            MIPS_INVAL("invalid dsrl32 flag");
1119
            generate_exception(ctx, EXCP_RI);
1120
            break;
1121
        }
1122
        break;
1123
#endif
1124
    default:
1125
        MIPS_INVAL(opn);
1126
        generate_exception(ctx, EXCP_RI);
1127
        return;
1128
    }
1129
    GEN_STORE_TN_REG(rt, T0);
1130
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1131
}
1132

    
1133
/* Arithmetic */
1134
static void gen_arith (DisasContext *ctx, uint32_t opc,
1135
                       int rd, int rs, int rt)
1136
{
1137
    const char *opn = "arith";
1138

    
1139
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1140
       && opc != OPC_DADD && opc != OPC_DSUB) {
1141
        /* if no destination, treat it as a NOP 
1142
         * For add & sub, we must generate the overflow exception when needed.
1143
         */
1144
        MIPS_DEBUG("NOP");
1145
        return;
1146
    }
1147
    GEN_LOAD_REG_TN(T0, rs);
1148
    GEN_LOAD_REG_TN(T1, rt);
1149
    switch (opc) {
1150
    case OPC_ADD:
1151
        save_cpu_state(ctx, 1);
1152
        gen_op_addo();
1153
        opn = "add";
1154
        break;
1155
    case OPC_ADDU:
1156
        gen_op_add();
1157
        opn = "addu";
1158
        break;
1159
    case OPC_SUB:
1160
        save_cpu_state(ctx, 1);
1161
        gen_op_subo();
1162
        opn = "sub";
1163
        break;
1164
    case OPC_SUBU:
1165
        gen_op_sub();
1166
        opn = "subu";
1167
        break;
1168
#ifdef TARGET_MIPS64
1169
    case OPC_DADD:
1170
        save_cpu_state(ctx, 1);
1171
        gen_op_daddo();
1172
        opn = "dadd";
1173
        break;
1174
    case OPC_DADDU:
1175
        gen_op_dadd();
1176
        opn = "daddu";
1177
        break;
1178
    case OPC_DSUB:
1179
        save_cpu_state(ctx, 1);
1180
        gen_op_dsubo();
1181
        opn = "dsub";
1182
        break;
1183
    case OPC_DSUBU:
1184
        gen_op_dsub();
1185
        opn = "dsubu";
1186
        break;
1187
#endif
1188
    case OPC_SLT:
1189
        gen_op_lt();
1190
        opn = "slt";
1191
        break;
1192
    case OPC_SLTU:
1193
        gen_op_ltu();
1194
        opn = "sltu";
1195
        break;
1196
    case OPC_AND:
1197
        gen_op_and();
1198
        opn = "and";
1199
        break;
1200
    case OPC_NOR:
1201
        gen_op_nor();
1202
        opn = "nor";
1203
        break;
1204
    case OPC_OR:
1205
        gen_op_or();
1206
        opn = "or";
1207
        break;
1208
    case OPC_XOR:
1209
        gen_op_xor();
1210
        opn = "xor";
1211
        break;
1212
    case OPC_MUL:
1213
        gen_op_mul();
1214
        opn = "mul";
1215
        break;
1216
    case OPC_MOVN:
1217
        gen_op_movn(rd);
1218
        opn = "movn";
1219
        goto print;
1220
    case OPC_MOVZ:
1221
        gen_op_movz(rd);
1222
        opn = "movz";
1223
        goto print;
1224
    case OPC_SLLV:
1225
        gen_op_sllv();
1226
        opn = "sllv";
1227
        break;
1228
    case OPC_SRAV:
1229
        gen_op_srav();
1230
        opn = "srav";
1231
        break;
1232
    case OPC_SRLV:
1233
        switch ((ctx->opcode >> 6) & 0x1f) {
1234
        case 0:
1235
            gen_op_srlv();
1236
            opn = "srlv";
1237
            break;
1238
        case 1:
1239
            gen_op_rotrv();
1240
            opn = "rotrv";
1241
            break;
1242
        default:
1243
            MIPS_INVAL("invalid srlv flag");
1244
            generate_exception(ctx, EXCP_RI);
1245
            break;
1246
        }
1247
        break;
1248
#ifdef TARGET_MIPS64
1249
    case OPC_DSLLV:
1250
        gen_op_dsllv();
1251
        opn = "dsllv";
1252
        break;
1253
    case OPC_DSRAV:
1254
        gen_op_dsrav();
1255
        opn = "dsrav";
1256
        break;
1257
    case OPC_DSRLV:
1258
        switch ((ctx->opcode >> 6) & 0x1f) {
1259
        case 0:
1260
            gen_op_dsrlv();
1261
            opn = "dsrlv";
1262
            break;
1263
        case 1:
1264
            gen_op_drotrv();
1265
            opn = "drotrv";
1266
            break;
1267
        default:
1268
            MIPS_INVAL("invalid dsrlv flag");
1269
            generate_exception(ctx, EXCP_RI);
1270
            break;
1271
        }
1272
        break;
1273
#endif
1274
    default:
1275
        MIPS_INVAL(opn);
1276
        generate_exception(ctx, EXCP_RI);
1277
        return;
1278
    }
1279
    GEN_STORE_TN_REG(rd, T0);
1280
 print:
1281
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1282
}
1283

    
1284
/* Arithmetic on HI/LO registers */
1285
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1286
{
1287
    const char *opn = "hilo";
1288

    
1289
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1290
        /* Treat as a NOP */
1291
        MIPS_DEBUG("NOP");
1292
        return;
1293
    }
1294
    switch (opc) {
1295
    case OPC_MFHI:
1296
        gen_op_load_HI();
1297
        GEN_STORE_TN_REG(reg, T0);
1298
        opn = "mfhi";
1299
        break;
1300
    case OPC_MFLO:
1301
        gen_op_load_LO();
1302
        GEN_STORE_TN_REG(reg, T0);
1303
        opn = "mflo";
1304
        break;
1305
    case OPC_MTHI:
1306
        GEN_LOAD_REG_TN(T0, reg);
1307
        gen_op_store_HI();
1308
        opn = "mthi";
1309
        break;
1310
    case OPC_MTLO:
1311
        GEN_LOAD_REG_TN(T0, reg);
1312
        gen_op_store_LO();
1313
        opn = "mtlo";
1314
        break;
1315
    default:
1316
        MIPS_INVAL(opn);
1317
        generate_exception(ctx, EXCP_RI);
1318
        return;
1319
    }
1320
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1321
}
1322

    
1323
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1324
                        int rs, int rt)
1325
{
1326
    const char *opn = "mul/div";
1327

    
1328
    GEN_LOAD_REG_TN(T0, rs);
1329
    GEN_LOAD_REG_TN(T1, rt);
1330
    switch (opc) {
1331
    case OPC_DIV:
1332
        gen_op_div();
1333
        opn = "div";
1334
        break;
1335
    case OPC_DIVU:
1336
        gen_op_divu();
1337
        opn = "divu";
1338
        break;
1339
    case OPC_MULT:
1340
        gen_op_mult();
1341
        opn = "mult";
1342
        break;
1343
    case OPC_MULTU:
1344
        gen_op_multu();
1345
        opn = "multu";
1346
        break;
1347
#ifdef TARGET_MIPS64
1348
    case OPC_DDIV:
1349
        gen_op_ddiv();
1350
        opn = "ddiv";
1351
        break;
1352
    case OPC_DDIVU:
1353
        gen_op_ddivu();
1354
        opn = "ddivu";
1355
        break;
1356
    case OPC_DMULT:
1357
        gen_op_dmult();
1358
        opn = "dmult";
1359
        break;
1360
    case OPC_DMULTU:
1361
        gen_op_dmultu();
1362
        opn = "dmultu";
1363
        break;
1364
#endif
1365
    case OPC_MADD:
1366
        gen_op_madd();
1367
        opn = "madd";
1368
        break;
1369
    case OPC_MADDU:
1370
        gen_op_maddu();
1371
        opn = "maddu";
1372
        break;
1373
    case OPC_MSUB:
1374
        gen_op_msub();
1375
        opn = "msub";
1376
        break;
1377
    case OPC_MSUBU:
1378
        gen_op_msubu();
1379
        opn = "msubu";
1380
        break;
1381
    default:
1382
        MIPS_INVAL(opn);
1383
        generate_exception(ctx, EXCP_RI);
1384
        return;
1385
    }
1386
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1387
}
1388

    
1389
static void gen_cl (DisasContext *ctx, uint32_t opc,
1390
                    int rd, int rs)
1391
{
1392
    const char *opn = "CLx";
1393
    if (rd == 0) {
1394
        /* Treat as a NOP */
1395
        MIPS_DEBUG("NOP");
1396
        return;
1397
    }
1398
    GEN_LOAD_REG_TN(T0, rs);
1399
    switch (opc) {
1400
    case OPC_CLO:
1401
        gen_op_clo();
1402
        opn = "clo";
1403
        break;
1404
    case OPC_CLZ:
1405
        gen_op_clz();
1406
        opn = "clz";
1407
        break;
1408
#ifdef TARGET_MIPS64
1409
    case OPC_DCLO:
1410
        gen_op_dclo();
1411
        opn = "dclo";
1412
        break;
1413
    case OPC_DCLZ:
1414
        gen_op_dclz();
1415
        opn = "dclz";
1416
        break;
1417
#endif
1418
    default:
1419
        MIPS_INVAL(opn);
1420
        generate_exception(ctx, EXCP_RI);
1421
        return;
1422
    }
1423
    gen_op_store_T0_gpr(rd);
1424
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1425
}
1426

    
1427
/* Traps */
1428
static void gen_trap (DisasContext *ctx, uint32_t opc,
1429
                      int rs, int rt, int16_t imm)
1430
{
1431
    int cond;
1432

    
1433
    cond = 0;
1434
    /* Load needed operands */
1435
    switch (opc) {
1436
    case OPC_TEQ:
1437
    case OPC_TGE:
1438
    case OPC_TGEU:
1439
    case OPC_TLT:
1440
    case OPC_TLTU:
1441
    case OPC_TNE:
1442
        /* Compare two registers */
1443
        if (rs != rt) {
1444
            GEN_LOAD_REG_TN(T0, rs);
1445
            GEN_LOAD_REG_TN(T1, rt);
1446
            cond = 1;
1447
        }
1448
        break;
1449
    case OPC_TEQI:
1450
    case OPC_TGEI:
1451
    case OPC_TGEIU:
1452
    case OPC_TLTI:
1453
    case OPC_TLTIU:
1454
    case OPC_TNEI:
1455
        /* Compare register to immediate */
1456
        if (rs != 0 || imm != 0) {
1457
            GEN_LOAD_REG_TN(T0, rs);
1458
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1459
            cond = 1;
1460
        }
1461
        break;
1462
    }
1463
    if (cond == 0) {
1464
        switch (opc) {
1465
        case OPC_TEQ:   /* rs == rs */
1466
        case OPC_TEQI:  /* r0 == 0  */
1467
        case OPC_TGE:   /* rs >= rs */
1468
        case OPC_TGEI:  /* r0 >= 0  */
1469
        case OPC_TGEU:  /* rs >= rs unsigned */
1470
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1471
            /* Always trap */
1472
            gen_op_set_T0(1);
1473
            break;
1474
        case OPC_TLT:   /* rs < rs           */
1475
        case OPC_TLTI:  /* r0 < 0            */
1476
        case OPC_TLTU:  /* rs < rs unsigned  */
1477
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1478
        case OPC_TNE:   /* rs != rs          */
1479
        case OPC_TNEI:  /* r0 != 0           */
1480
            /* Never trap: treat as NOP */
1481
            return;
1482
        default:
1483
            MIPS_INVAL("trap");
1484
            generate_exception(ctx, EXCP_RI);
1485
            return;
1486
        }
1487
    } else {
1488
        switch (opc) {
1489
        case OPC_TEQ:
1490
        case OPC_TEQI:
1491
            gen_op_eq();
1492
            break;
1493
        case OPC_TGE:
1494
        case OPC_TGEI:
1495
            gen_op_ge();
1496
            break;
1497
        case OPC_TGEU:
1498
        case OPC_TGEIU:
1499
            gen_op_geu();
1500
            break;
1501
        case OPC_TLT:
1502
        case OPC_TLTI:
1503
            gen_op_lt();
1504
            break;
1505
        case OPC_TLTU:
1506
        case OPC_TLTIU:
1507
            gen_op_ltu();
1508
            break;
1509
        case OPC_TNE:
1510
        case OPC_TNEI:
1511
            gen_op_ne();
1512
            break;
1513
        default:
1514
            MIPS_INVAL("trap");
1515
            generate_exception(ctx, EXCP_RI);
1516
            return;
1517
        }
1518
    }
1519
    save_cpu_state(ctx, 1);
1520
    gen_op_trap();
1521
    ctx->bstate = BS_STOP;
1522
}
1523

    
1524
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1525
{
1526
    TranslationBlock *tb;
1527
    tb = ctx->tb;
1528
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1529
        if (n == 0)
1530
            gen_op_goto_tb0(TBPARAM(tb));
1531
        else
1532
            gen_op_goto_tb1(TBPARAM(tb));
1533
        gen_save_pc(dest);
1534
        gen_op_set_T0((long)tb + n);
1535
    } else {
1536
        gen_save_pc(dest);
1537
        gen_op_reset_T0();
1538
    }
1539
    gen_op_exit_tb();
1540
}
1541

    
1542
/* Branches (before delay slot) */
1543
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1544
                                int rs, int rt, int32_t offset)
1545
{
1546
    target_ulong btarget = -1;
1547
    int blink = 0;
1548
    int bcond = 0;
1549

    
1550
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1551
#ifdef MIPS_DEBUG_DISAS
1552
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1553
            fprintf(logfile,
1554
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1555
                    ctx->pc);
1556
        }
1557
#endif
1558
        generate_exception(ctx, EXCP_RI);
1559
        return;
1560
    }
1561

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

    
1775
    ctx->btarget = btarget;
1776
    if (blink > 0) {
1777
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1778
        gen_op_store_T0_gpr(blink);
1779
    }
1780
}
1781

    
1782
/* special3 bitfield operations */
1783
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1784
                       int rs, int lsb, int msb)
1785
{
1786
    GEN_LOAD_REG_TN(T1, rs);
1787
    switch (opc) {
1788
    case OPC_EXT:
1789
        if (lsb + msb > 31)
1790
            goto fail;
1791
        gen_op_ext(lsb, msb + 1);
1792
        break;
1793
    case OPC_DEXTM:
1794
        if (lsb + msb > 63)
1795
            goto fail;
1796
        gen_op_ext(lsb, msb + 1 + 32);
1797
        break;
1798
    case OPC_DEXTU:
1799
        if (lsb + msb > 63)
1800
            goto fail;
1801
        gen_op_ext(lsb + 32, msb + 1);
1802
        break;
1803
    case OPC_DEXT:
1804
        gen_op_ext(lsb, msb + 1);
1805
        break;
1806
    case OPC_INS:
1807
        if (lsb > msb)
1808
            goto fail;
1809
        GEN_LOAD_REG_TN(T0, rt);
1810
        gen_op_ins(lsb, msb - lsb + 1);
1811
        break;
1812
    case OPC_DINSM:
1813
        if (lsb > msb)
1814
            goto fail;
1815
        GEN_LOAD_REG_TN(T0, rt);
1816
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1817
        break;
1818
    case OPC_DINSU:
1819
        if (lsb > msb)
1820
            goto fail;
1821
        GEN_LOAD_REG_TN(T0, rt);
1822
        gen_op_ins(lsb + 32, msb - lsb + 1);
1823
        break;
1824
    case OPC_DINS:
1825
        if (lsb > msb)
1826
            goto fail;
1827
        GEN_LOAD_REG_TN(T0, rt);
1828
        gen_op_ins(lsb, msb - lsb + 1);
1829
        break;
1830
    default:
1831
fail:
1832
        MIPS_INVAL("bitops");
1833
        generate_exception(ctx, EXCP_RI);
1834
        return;
1835
    }
1836
    GEN_STORE_TN_REG(rt, T0);
1837
}
1838

    
1839
/* CP0 (MMU and control) */
1840
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1841
{
1842
    const char *rn = "invalid";
1843

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

    
2366
die:
2367
#if defined MIPS_DEBUG_DISAS
2368
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2369
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2370
                rn, reg, sel);
2371
    }
2372
#endif
2373
    generate_exception(ctx, EXCP_RI);
2374
}
2375

    
2376
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2377
{
2378
    const char *rn = "invalid";
2379

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

    
2915
die:
2916
#if defined MIPS_DEBUG_DISAS
2917
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2918
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2919
                rn, reg, sel);
2920
    }
2921
#endif
2922
    generate_exception(ctx, EXCP_RI);
2923
}
2924

    
2925
#ifdef TARGET_MIPS64
2926
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2927
{
2928
    const char *rn = "invalid";
2929

    
2930
    switch (reg) {
2931
    case 0:
2932
        switch (sel) {
2933
        case 0:
2934
            gen_op_mfc0_index();
2935
            rn = "Index";
2936
            break;
2937
        case 1:
2938
//            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2939
            rn = "MVPControl";
2940
//            break;
2941
        case 2:
2942
//            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2943
            rn = "MVPConf0";
2944
//            break;
2945
        case 3:
2946
//            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2947
            rn = "MVPConf1";
2948
//            break;
2949
        default:
2950
            goto die;
2951
        }
2952
        break;
2953
    case 1:
2954
        switch (sel) {
2955
        case 0:
2956
            gen_op_mfc0_random();
2957
            rn = "Random";
2958
            break;
2959
        case 1:
2960
//            gen_op_dmfc0_vpecontrol(); /* MT ASE */
2961
            rn = "VPEControl";
2962
//            break;
2963
        case 2:
2964
//            gen_op_dmfc0_vpeconf0(); /* MT ASE */
2965
            rn = "VPEConf0";
2966
//            break;
2967
        case 3:
2968
//            gen_op_dmfc0_vpeconf1(); /* MT ASE */
2969
            rn = "VPEConf1";
2970
//            break;
2971
        case 4:
2972
//            gen_op_dmfc0_YQMask(); /* MT ASE */
2973
            rn = "YQMask";
2974
//            break;
2975
        case 5:
2976
//            gen_op_dmfc0_vpeschedule(); /* MT ASE */
2977
            rn = "VPESchedule";
2978
//            break;
2979
        case 6:
2980
//            gen_op_dmfc0_vpeschefback(); /* MT ASE */
2981
            rn = "VPEScheFBack";
2982
//            break;
2983
        case 7:
2984
//            gen_op_dmfc0_vpeopt(); /* MT ASE */
2985
            rn = "VPEOpt";
2986
//            break;
2987
        default:
2988
            goto die;
2989
        }
2990
        break;
2991
    case 2:
2992
        switch (sel) {
2993
        case 0:
2994
            gen_op_dmfc0_entrylo0();
2995
            rn = "EntryLo0";
2996
            break;
2997
        case 1:
2998
//            gen_op_dmfc0_tcstatus(); /* MT ASE */
2999
            rn = "TCStatus";
3000
//            break;
3001
        case 2:
3002
//            gen_op_dmfc0_tcbind(); /* MT ASE */
3003
            rn = "TCBind";
3004
//            break;
3005
        case 3:
3006
//            gen_op_dmfc0_tcrestart(); /* MT ASE */
3007
            rn = "TCRestart";
3008
//            break;
3009
        case 4:
3010
//            gen_op_dmfc0_tchalt(); /* MT ASE */
3011
            rn = "TCHalt";
3012
//            break;
3013
        case 5:
3014
//            gen_op_dmfc0_tccontext(); /* MT ASE */
3015
            rn = "TCContext";
3016
//            break;
3017
        case 6:
3018
//            gen_op_dmfc0_tcschedule(); /* MT ASE */
3019
            rn = "TCSchedule";
3020
//            break;
3021
        case 7:
3022
//            gen_op_dmfc0_tcschefback(); /* MT ASE */
3023
            rn = "TCScheFBack";
3024
//            break;
3025
        default:
3026
            goto die;
3027
        }
3028
        break;
3029
    case 3:
3030
        switch (sel) {
3031
        case 0:
3032
            gen_op_dmfc0_entrylo1();
3033
            rn = "EntryLo1";
3034
            break;
3035
        default:
3036
            goto die;
3037
        }
3038
        break;
3039
    case 4:
3040
        switch (sel) {
3041
        case 0:
3042
            gen_op_dmfc0_context();
3043
            rn = "Context";
3044
            break;
3045
        case 1:
3046
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3047
            rn = "ContextConfig";
3048
//            break;
3049
        default:
3050
            goto die;
3051
        }
3052
        break;
3053
    case 5:
3054
        switch (sel) {
3055
        case 0:
3056
            gen_op_mfc0_pagemask();
3057
            rn = "PageMask";
3058
            break;
3059
        case 1:
3060
            gen_op_mfc0_pagegrain();
3061
            rn = "PageGrain";
3062
            break;
3063
        default:
3064
            goto die;
3065
        }
3066
        break;
3067
    case 6:
3068
        switch (sel) {
3069
        case 0:
3070
            gen_op_mfc0_wired();
3071
            rn = "Wired";
3072
            break;
3073
        case 1:
3074
//            gen_op_dmfc0_srsconf0(); /* shadow registers */
3075
            rn = "SRSConf0";
3076
//            break;
3077
        case 2:
3078
//            gen_op_dmfc0_srsconf1(); /* shadow registers */
3079
            rn = "SRSConf1";
3080
//            break;
3081
        case 3:
3082
//            gen_op_dmfc0_srsconf2(); /* shadow registers */
3083
            rn = "SRSConf2";
3084
//            break;
3085
        case 4:
3086
//            gen_op_dmfc0_srsconf3(); /* shadow registers */
3087
            rn = "SRSConf3";
3088
//            break;
3089
        case 5:
3090
//            gen_op_dmfc0_srsconf4(); /* shadow registers */
3091
            rn = "SRSConf4";
3092
//            break;
3093
        default:
3094
            goto die;
3095
        }
3096
        break;
3097
    case 7:
3098
        switch (sel) {
3099
        case 0:
3100
            gen_op_mfc0_hwrena();
3101
            rn = "HWREna";
3102
            break;
3103
        default:
3104
            goto die;
3105
        }
3106
        break;
3107
    case 8:
3108
        switch (sel) {
3109
        case 0:
3110
            gen_op_dmfc0_badvaddr();
3111
            rn = "BadVaddr";
3112
            break;
3113
        default:
3114
            goto die;
3115
        }
3116
        break;
3117
    case 9:
3118
        switch (sel) {
3119
        case 0:
3120
            gen_op_mfc0_count();
3121
            rn = "Count";
3122
            break;
3123
        /* 6,7 are implementation dependent */
3124
        default:
3125
            goto die;
3126
        }
3127
        break;
3128
    case 10:
3129
        switch (sel) {
3130
        case 0:
3131
            gen_op_dmfc0_entryhi();
3132
            rn = "EntryHi";
3133
            break;
3134
        default:
3135
            goto die;
3136
        }
3137
        break;
3138
    case 11:
3139
        switch (sel) {
3140
        case 0:
3141
            gen_op_mfc0_compare();
3142
            rn = "Compare";
3143
            break;
3144
        /* 6,7 are implementation dependent */
3145
        default:
3146
            goto die;
3147
        }
3148
        break;
3149
    case 12:
3150
        switch (sel) {
3151
        case 0:
3152
            gen_op_mfc0_status();
3153
            rn = "Status";
3154
            break;
3155
        case 1:
3156
            gen_op_mfc0_intctl();
3157
            rn = "IntCtl";
3158
            break;
3159
        case 2:
3160
            gen_op_mfc0_srsctl();
3161
            rn = "SRSCtl";
3162
            break;
3163
        case 3:
3164
            gen_op_mfc0_srsmap(); /* shadow registers */
3165
            rn = "SRSMap";
3166
            break;
3167
        default:
3168
            goto die;
3169
        }
3170
        break;
3171
    case 13:
3172
        switch (sel) {
3173
        case 0:
3174
            gen_op_mfc0_cause();
3175
            rn = "Cause";
3176
            break;
3177
        default:
3178
            goto die;
3179
        }
3180
        break;
3181
    case 14:
3182
        switch (sel) {
3183
        case 0:
3184
            gen_op_dmfc0_epc();
3185
            rn = "EPC";
3186
            break;
3187
        default:
3188
            goto die;
3189
        }
3190
        break;
3191
    case 15:
3192
        switch (sel) {
3193
        case 0:
3194
            gen_op_mfc0_prid();
3195
            rn = "PRid";
3196
            break;
3197
        case 1:
3198
            gen_op_mfc0_ebase();
3199
            rn = "EBase";
3200
            break;
3201
        default:
3202
            goto die;
3203
        }
3204
        break;
3205
    case 16:
3206
        switch (sel) {
3207
        case 0:
3208
            gen_op_mfc0_config0();
3209
            rn = "Config";
3210
            break;
3211
        case 1:
3212
            gen_op_mfc0_config1();
3213
            rn = "Config1";
3214
            break;
3215
        case 2:
3216
            gen_op_mfc0_config2();
3217
            rn = "Config2";
3218
            break;
3219
        case 3:
3220
            gen_op_mfc0_config3();
3221
            rn = "Config3";
3222
            break;
3223
       /* 6,7 are implementation dependent */
3224
        default:
3225
            goto die;
3226
        }
3227
        break;
3228
    case 17:
3229
        switch (sel) {
3230
        case 0:
3231
            gen_op_dmfc0_lladdr();
3232
            rn = "LLAddr";
3233
            break;
3234
        default:
3235
            goto die;
3236
        }
3237
        break;
3238
    case 18:
3239
        switch (sel) {
3240
        case 0 ... 7:
3241
            gen_op_dmfc0_watchlo(sel);
3242
            rn = "WatchLo";
3243
            break;
3244
        default:
3245
            goto die;
3246
        }
3247
        break;
3248
    case 19:
3249
        switch (sel) {
3250
        case 0 ... 7:
3251
            gen_op_mfc0_watchhi(sel);
3252
            rn = "WatchHi";
3253
            break;
3254
        default:
3255
            goto die;
3256
        }
3257
        break;
3258
    case 20:
3259
        switch (sel) {
3260
        case 0:
3261
#ifdef TARGET_MIPS64
3262
            gen_op_dmfc0_xcontext();
3263
            rn = "XContext";
3264
            break;
3265
#endif
3266
        default:
3267
            goto die;
3268
        }
3269
        break;
3270
    case 21:
3271
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3272
        switch (sel) {
3273
        case 0:
3274
            gen_op_mfc0_framemask();
3275
            rn = "Framemask";
3276
            break;
3277
        default:
3278
            goto die;
3279
        }
3280
        break;
3281
    case 22:
3282
        /* ignored */
3283
        rn = "'Diagnostic"; /* implementation dependent */
3284
        break;
3285
    case 23:
3286
        switch (sel) {
3287
        case 0:
3288
            gen_op_mfc0_debug(); /* EJTAG support */
3289
            rn = "Debug";
3290
            break;
3291
        case 1:
3292
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3293
            rn = "TraceControl";
3294
//            break;
3295
        case 2:
3296
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3297
            rn = "TraceControl2";
3298
//            break;
3299
        case 3:
3300
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3301
            rn = "UserTraceData";
3302
//            break;
3303
        case 4:
3304
//            gen_op_dmfc0_debug(); /* PDtrace support */
3305
            rn = "TraceBPC";
3306
//            break;
3307
        default:
3308
            goto die;
3309
        }
3310
        break;
3311
    case 24:
3312
        switch (sel) {
3313
        case 0:
3314
            gen_op_dmfc0_depc(); /* EJTAG support */
3315
            rn = "DEPC";
3316
            break;
3317
        default:
3318
            goto die;
3319
        }
3320
        break;
3321
    case 25:
3322
        switch (sel) {
3323
        case 0:
3324
            gen_op_mfc0_performance0();
3325
            rn = "Performance0";
3326
            break;
3327
        case 1:
3328
//            gen_op_dmfc0_performance1();
3329
            rn = "Performance1";
3330
//            break;
3331
        case 2:
3332
//            gen_op_dmfc0_performance2();
3333
            rn = "Performance2";
3334
//            break;
3335
        case 3:
3336
//            gen_op_dmfc0_performance3();
3337
            rn = "Performance3";
3338
//            break;
3339
        case 4:
3340
//            gen_op_dmfc0_performance4();
3341
            rn = "Performance4";
3342
//            break;
3343
        case 5:
3344
//            gen_op_dmfc0_performance5();
3345
            rn = "Performance5";
3346
//            break;
3347
        case 6:
3348
//            gen_op_dmfc0_performance6();
3349
            rn = "Performance6";
3350
//            break;
3351
        case 7:
3352
//            gen_op_dmfc0_performance7();
3353
            rn = "Performance7";
3354
//            break;
3355
        default:
3356
            goto die;
3357
        }
3358
        break;
3359
    case 26:
3360
       rn = "ECC";
3361
       break;
3362
    case 27:
3363
        switch (sel) {
3364
        /* ignored */
3365
        case 0 ... 3:
3366
            rn = "CacheErr";
3367
            break;
3368
        default:
3369
            goto die;
3370
        }
3371
        break;
3372
    case 28:
3373
        switch (sel) {
3374
        case 0:
3375
        case 2:
3376
        case 4:
3377
        case 6:
3378
            gen_op_mfc0_taglo();
3379
            rn = "TagLo";
3380
            break;
3381
        case 1:
3382
        case 3:
3383
        case 5:
3384
        case 7:
3385
            gen_op_mfc0_datalo();
3386
            rn = "DataLo";
3387
            break;
3388
        default:
3389
            goto die;
3390
        }
3391
        break;
3392
    case 29:
3393
        switch (sel) {
3394
        case 0:
3395
        case 2:
3396
        case 4:
3397
        case 6:
3398
            gen_op_mfc0_taghi();
3399
            rn = "TagHi";
3400
            break;
3401
        case 1:
3402
        case 3:
3403
        case 5:
3404
        case 7:
3405
            gen_op_mfc0_datahi();
3406
            rn = "DataHi";
3407
            break;
3408
        default:
3409
            goto die;
3410
        }
3411
        break;
3412
    case 30:
3413
        switch (sel) {
3414
        case 0:
3415
            gen_op_dmfc0_errorepc();
3416
            rn = "ErrorEPC";
3417
            break;
3418
        default:
3419
            goto die;
3420
        }
3421
        break;
3422
    case 31:
3423
        switch (sel) {
3424
        case 0:
3425
            gen_op_mfc0_desave(); /* EJTAG support */
3426
            rn = "DESAVE";
3427
            break;
3428
        default:
3429
            goto die;
3430
        }
3431
        break;
3432
    default:
3433
        goto die;
3434
    }
3435
#if defined MIPS_DEBUG_DISAS
3436
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3437
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3438
                rn, reg, sel);
3439
    }
3440
#endif
3441
    return;
3442

    
3443
die:
3444
#if defined MIPS_DEBUG_DISAS
3445
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3446
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3447
                rn, reg, sel);
3448
    }
3449
#endif
3450
    generate_exception(ctx, EXCP_RI);
3451
}
3452

    
3453
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3454
{
3455
    const char *rn = "invalid";
3456

    
3457
    switch (reg) {
3458
    case 0:
3459
        switch (sel) {
3460
        case 0:
3461
            gen_op_mtc0_index();
3462
            rn = "Index";
3463
            break;
3464
        case 1:
3465
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
3466
            rn = "MVPControl";
3467
//            break;
3468
        case 2:
3469
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
3470
            rn = "MVPConf0";
3471
//            break;
3472
        case 3:
3473
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
3474
            rn = "MVPConf1";
3475
//            break;
3476
        default:
3477
            goto die;
3478
        }
3479
        break;
3480
    case 1:
3481
        switch (sel) {
3482
        case 0:
3483
            /* ignored */
3484
            rn = "Random";
3485
            break;
3486
        case 1:
3487
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
3488
            rn = "VPEControl";
3489
//            break;
3490
        case 2:
3491
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
3492
            rn = "VPEConf0";
3493
//            break;
3494
        case 3:
3495
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
3496
            rn = "VPEConf1";
3497
//            break;
3498
        case 4:
3499
//            gen_op_mtc0_YQMask(); /* MT ASE */
3500
            rn = "YQMask";
3501
//            break;
3502
        case 5:
3503
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
3504
            rn = "VPESchedule";
3505
//            break;
3506
        case 6:
3507
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
3508
            rn = "VPEScheFBack";
3509
//            break;
3510
        case 7:
3511
//            gen_op_mtc0_vpeopt(); /* MT ASE */
3512
            rn = "VPEOpt";
3513
//            break;
3514
        default:
3515
            goto die;
3516
        }
3517
        break;
3518
    case 2:
3519
        switch (sel) {
3520
        case 0:
3521
            gen_op_mtc0_entrylo0();
3522
            rn = "EntryLo0";
3523
            break;
3524
        case 1:
3525
//            gen_op_mtc0_tcstatus(); /* MT ASE */
3526
            rn = "TCStatus";
3527
//            break;
3528
        case 2:
3529
//            gen_op_mtc0_tcbind(); /* MT ASE */
3530
            rn = "TCBind";
3531
//            break;
3532
        case 3:
3533
//            gen_op_mtc0_tcrestart(); /* MT ASE */
3534
            rn = "TCRestart";
3535
//            break;
3536
        case 4:
3537
//            gen_op_mtc0_tchalt(); /* MT ASE */
3538
            rn = "TCHalt";
3539
//            break;
3540
        case 5:
3541
//            gen_op_mtc0_tccontext(); /* MT ASE */
3542
            rn = "TCContext";
3543
//            break;
3544
        case 6:
3545
//            gen_op_mtc0_tcschedule(); /* MT ASE */
3546
            rn = "TCSchedule";
3547
//            break;
3548
        case 7:
3549
//            gen_op_mtc0_tcschefback(); /* MT ASE */
3550
            rn = "TCScheFBack";
3551
//            break;
3552
        default:
3553
            goto die;
3554
        }
3555
        break;
3556
    case 3:
3557
        switch (sel) {
3558
        case 0:
3559
            gen_op_mtc0_entrylo1();
3560
            rn = "EntryLo1";
3561
            break;
3562
        default:
3563
            goto die;
3564
        }
3565
        break;
3566
    case 4:
3567
        switch (sel) {
3568
        case 0:
3569
            gen_op_mtc0_context();
3570
            rn = "Context";
3571
            break;
3572
        case 1:
3573
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3574
            rn = "ContextConfig";
3575
//           break;
3576
        default:
3577
            goto die;
3578
        }
3579
        break;
3580
    case 5:
3581
        switch (sel) {
3582
        case 0:
3583
            gen_op_mtc0_pagemask();
3584
            rn = "PageMask";
3585
            break;
3586
        case 1:
3587
            gen_op_mtc0_pagegrain();
3588
            rn = "PageGrain";
3589
            break;
3590
        default:
3591
            goto die;
3592
        }
3593
        break;
3594
    case 6:
3595
        switch (sel) {
3596
        case 0:
3597
            gen_op_mtc0_wired();
3598
            rn = "Wired";
3599
            break;
3600
        case 1:
3601
//            gen_op_mtc0_srsconf0(); /* shadow registers */
3602
            rn = "SRSConf0";
3603
//            break;
3604
        case 2:
3605
//            gen_op_mtc0_srsconf1(); /* shadow registers */
3606
            rn = "SRSConf1";
3607
//            break;
3608
        case 3:
3609
//            gen_op_mtc0_srsconf2(); /* shadow registers */
3610
            rn = "SRSConf2";
3611
//            break;
3612
        case 4:
3613
//            gen_op_mtc0_srsconf3(); /* shadow registers */
3614
            rn = "SRSConf3";
3615
//            break;
3616
        case 5:
3617
//            gen_op_mtc0_srsconf4(); /* shadow registers */
3618
            rn = "SRSConf4";
3619
//            break;
3620
        default:
3621
            goto die;
3622
        }
3623
        break;
3624
    case 7:
3625
        switch (sel) {
3626
        case 0:
3627
            gen_op_mtc0_hwrena();
3628
            rn = "HWREna";
3629
            break;
3630
        default:
3631
            goto die;
3632
        }
3633
        break;
3634
    case 8:
3635
        /* ignored */
3636
        rn = "BadVaddr";
3637
        break;
3638
    case 9:
3639
        switch (sel) {
3640
        case 0:
3641
            gen_op_mtc0_count();
3642
            rn = "Count";
3643
            break;
3644
        /* 6,7 are implementation dependent */
3645
        default:
3646
            goto die;
3647
        }
3648
        /* Stop translation as we may have switched the execution mode */
3649
        ctx->bstate = BS_STOP;
3650
        break;
3651
    case 10:
3652
        switch (sel) {
3653
        case 0:
3654
            gen_op_mtc0_entryhi();
3655
            rn = "EntryHi";
3656
            break;
3657
        default:
3658
            goto die;
3659
        }
3660
        break;
3661
    case 11:
3662
        switch (sel) {
3663
        case 0:
3664
            gen_op_mtc0_compare();
3665
            rn = "Compare";
3666
            break;
3667
        /* 6,7 are implementation dependent */
3668
        default:
3669
            goto die;
3670
        }
3671
        /* Stop translation as we may have switched the execution mode */
3672
        ctx->bstate = BS_STOP;
3673
        break;
3674
    case 12:
3675
        switch (sel) {
3676
        case 0:
3677
            gen_op_mtc0_status();
3678
            rn = "Status";
3679
            break;
3680
        case 1:
3681
            gen_op_mtc0_intctl();
3682
            rn = "IntCtl";
3683
            break;
3684
        case 2:
3685
            gen_op_mtc0_srsctl();
3686
            rn = "SRSCtl";
3687
            break;
3688
        case 3:
3689
            gen_op_mtc0_srsmap();
3690
            rn = "SRSMap";
3691
            break;
3692
        default:
3693
            goto die;
3694
        }
3695
        /* Stop translation as we may have switched the execution mode */
3696
        ctx->bstate = BS_STOP;
3697
        break;
3698
    case 13:
3699
        switch (sel) {
3700
        case 0:
3701
            gen_op_mtc0_cause();
3702
            rn = "Cause";
3703
            break;
3704
        default:
3705
            goto die;
3706
        }
3707
        /* Stop translation as we may have switched the execution mode */
3708
        ctx->bstate = BS_STOP;
3709
        break;
3710
    case 14:
3711
        switch (sel) {
3712
        case 0:
3713
            gen_op_mtc0_epc();
3714
            rn = "EPC";
3715
            break;
3716
        default:
3717
            goto die;
3718
        }
3719
        break;
3720
    case 15:
3721
        switch (sel) {
3722
        case 0:
3723
            /* ignored */
3724
            rn = "PRid";
3725
            break;
3726
        case 1:
3727
            gen_op_mtc0_ebase();
3728
            rn = "EBase";
3729
            break;
3730
        default:
3731
            goto die;
3732
        }
3733
        break;
3734
    case 16:
3735
        switch (sel) {
3736
        case 0:
3737
            gen_op_mtc0_config0();
3738
            rn = "Config";
3739
            /* Stop translation as we may have switched the execution mode */
3740
            ctx->bstate = BS_STOP;
3741
            break;
3742
        case 1:
3743
            /* ignored */
3744
            rn = "Config1";
3745
            break;
3746
        case 2:
3747
            gen_op_mtc0_config2();
3748
            rn = "Config2";
3749
            /* Stop translation as we may have switched the execution mode */
3750
            ctx->bstate = BS_STOP;
3751
            break;
3752
        case 3:
3753
            /* ignored */
3754
            rn = "Config3";
3755
            break;
3756
        /* 6,7 are implementation dependent */
3757
        default:
3758
            rn = "Invalid config selector";
3759
            goto die;
3760
        }
3761
        break;
3762
    case 17:
3763
        switch (sel) {
3764
        case 0:
3765
            /* ignored */
3766
            rn = "LLAddr";
3767
            break;
3768
        default:
3769
            goto die;
3770
        }
3771
        break;
3772
    case 18:
3773
        switch (sel) {
3774
        case 0 ... 7:
3775
            gen_op_mtc0_watchlo(sel);
3776
            rn = "WatchLo";
3777
            break;
3778
        default:
3779
            goto die;
3780
        }
3781
        break;
3782
    case 19:
3783
        switch (sel) {
3784
        case 0 ... 7:
3785
            gen_op_mtc0_watchhi(sel);
3786
            rn = "WatchHi";
3787
            break;
3788
        default:
3789
            goto die;
3790
        }
3791
        break;
3792
    case 20:
3793
        switch (sel) {
3794
        case 0:
3795
#ifdef TARGET_MIPS64
3796
            gen_op_mtc0_xcontext();
3797
            rn = "XContext";
3798
            break;
3799
#endif
3800
        default:
3801
            goto die;
3802
        }
3803
        break;
3804
    case 21:
3805
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3806
        switch (sel) {
3807
        case 0:
3808
            gen_op_mtc0_framemask();
3809
            rn = "Framemask";
3810
            break;
3811
        default:
3812
            goto die;
3813
        }
3814
        break;
3815
    case 22:
3816
        /* ignored */
3817
        rn = "Diagnostic"; /* implementation dependent */
3818
        break;
3819
    case 23:
3820
        switch (sel) {
3821
        case 0:
3822
            gen_op_mtc0_debug(); /* EJTAG support */
3823
            rn = "Debug";
3824
            break;
3825
        case 1:
3826
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3827
            rn = "TraceControl";
3828
//            break;
3829
        case 2:
3830
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3831
            rn = "TraceControl2";
3832
//            break;
3833
        case 3:
3834
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3835
            rn = "UserTraceData";
3836
//            break;
3837
        case 4:
3838
//            gen_op_mtc0_debug(); /* PDtrace support */
3839
            rn = "TraceBPC";
3840
//            break;
3841
        default:
3842
            goto die;
3843
        }
3844
        /* Stop translation as we may have switched the execution mode */
3845
        ctx->bstate = BS_STOP;
3846
        break;
3847
    case 24:
3848
        switch (sel) {
3849
        case 0:
3850
            gen_op_mtc0_depc(); /* EJTAG support */
3851
            rn = "DEPC";
3852
            break;
3853
        default:
3854
            goto die;
3855
        }
3856
        break;
3857
    case 25:
3858
        switch (sel) {
3859
        case 0:
3860
            gen_op_mtc0_performance0();
3861
            rn = "Performance0";
3862
            break;
3863
        case 1:
3864
//            gen_op_mtc0_performance1();
3865
            rn = "Performance1";
3866
//            break;
3867
        case 2:
3868
//            gen_op_mtc0_performance2();
3869
            rn = "Performance2";
3870
//            break;
3871
        case 3:
3872
//            gen_op_mtc0_performance3();
3873
            rn = "Performance3";
3874
//            break;
3875
        case 4:
3876
//            gen_op_mtc0_performance4();
3877
            rn = "Performance4";
3878
//            break;
3879
        case 5:
3880
//            gen_op_mtc0_performance5();
3881
            rn = "Performance5";
3882
//            break;
3883
        case 6:
3884
//            gen_op_mtc0_performance6();
3885
            rn = "Performance6";
3886
//            break;
3887
        case 7:
3888
//            gen_op_mtc0_performance7();
3889
            rn = "Performance7";
3890
//            break;
3891
        default:
3892
            goto die;
3893
        }
3894
        break;
3895
    case 26:
3896
        /* ignored */
3897
        rn = "ECC";
3898
        break;
3899
    case 27:
3900
        switch (sel) {
3901
        case 0 ... 3:
3902
            /* ignored */
3903
            rn = "CacheErr";
3904
            break;
3905
        default:
3906
            goto die;
3907
        }
3908
        break;
3909
    case 28:
3910
        switch (sel) {
3911
        case 0:
3912
        case 2:
3913
        case 4:
3914
        case 6:
3915
            gen_op_mtc0_taglo();
3916
            rn = "TagLo";
3917
            break;
3918
        case 1:
3919
        case 3:
3920
        case 5:
3921
        case 7:
3922
            gen_op_mtc0_datalo();
3923
            rn = "DataLo";
3924
            break;
3925
        default:
3926
            goto die;
3927
        }
3928
        break;
3929
    case 29:
3930
        switch (sel) {
3931
        case 0:
3932
        case 2:
3933
        case 4:
3934
        case 6:
3935
            gen_op_mtc0_taghi();
3936
            rn = "TagHi";
3937
            break;
3938
        case 1:
3939
        case 3:
3940
        case 5:
3941
        case 7:
3942
            gen_op_mtc0_datahi();
3943
            rn = "DataHi";
3944
            break;
3945
        default:
3946
            rn = "invalid sel";
3947
            goto die;
3948
        }
3949
        break;
3950
    case 30:
3951
        switch (sel) {
3952
        case 0:
3953
            gen_op_mtc0_errorepc();
3954
            rn = "ErrorEPC";
3955
            break;
3956
        default:
3957
            goto die;
3958
        }
3959
        break;
3960
    case 31:
3961
        switch (sel) {
3962
        case 0:
3963
            gen_op_mtc0_desave(); /* EJTAG support */
3964
            rn = "DESAVE";
3965
            break;
3966
        default:
3967
            goto die;
3968
        }
3969
        /* Stop translation as we may have switched the execution mode */
3970
        ctx->bstate = BS_STOP;
3971
        break;
3972
    default:
3973
        goto die;
3974
    }
3975
#if defined MIPS_DEBUG_DISAS
3976
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3977
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
3978
                rn, reg, sel);
3979
    }
3980
#endif
3981
    return;
3982

    
3983
die:
3984
#if defined MIPS_DEBUG_DISAS
3985
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3986
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
3987
                rn, reg, sel);
3988
    }
3989
#endif
3990
    generate_exception(ctx, EXCP_RI);
3991
}
3992
#endif /* TARGET_MIPS64 */
3993

    
3994
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
3995
{
3996
    const char *opn = "ldst";
3997

    
3998
    switch (opc) {
3999
    case OPC_MFC0:
4000
        if (rt == 0) {
4001
            /* Treat as NOP */
4002
            return;
4003
        }
4004
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4005
        gen_op_store_T0_gpr(rt);
4006
        opn = "mfc0";
4007
        break;
4008
    case OPC_MTC0:
4009
        GEN_LOAD_REG_TN(T0, rt);
4010
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4011
        opn = "mtc0";
4012
        break;
4013
#ifdef TARGET_MIPS64
4014
    case OPC_DMFC0:
4015
        if (rt == 0) {
4016
            /* Treat as NOP */
4017
            return;
4018
        }
4019
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4020
        gen_op_store_T0_gpr(rt);
4021
        opn = "dmfc0";
4022
        break;
4023
    case OPC_DMTC0:
4024
        GEN_LOAD_REG_TN(T0, rt);
4025
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4026
        opn = "dmtc0";
4027
        break;
4028
#endif
4029
    case OPC_TLBWI:
4030
        opn = "tlbwi";
4031
        if (!env->do_tlbwi)
4032
            goto die;
4033
        gen_op_tlbwi();
4034
        break;
4035
    case OPC_TLBWR:
4036
        opn = "tlbwr";
4037
        if (!env->do_tlbwr)
4038
            goto die;
4039
        gen_op_tlbwr();
4040
        break;
4041
    case OPC_TLBP:
4042
        opn = "tlbp";
4043
        if (!env->do_tlbp)
4044
            goto die;
4045
        gen_op_tlbp();
4046
        break;
4047
    case OPC_TLBR:
4048
        opn = "tlbr";
4049
        if (!env->do_tlbr)
4050
            goto die;
4051
        gen_op_tlbr();
4052
        break;
4053
    case OPC_ERET:
4054
        opn = "eret";
4055
        gen_op_eret();
4056
        ctx->bstate = BS_EXCP;
4057
        break;
4058
    case OPC_DERET:
4059
        opn = "deret";
4060
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4061
            MIPS_INVAL(opn);
4062
            generate_exception(ctx, EXCP_RI);
4063
        } else {
4064
            gen_op_deret();
4065
            ctx->bstate = BS_EXCP;
4066
        }
4067
        break;
4068
    case OPC_WAIT:
4069
        opn = "wait";
4070
        /* If we get an exception, we want to restart at next instruction */
4071
        ctx->pc += 4;
4072
        save_cpu_state(ctx, 1);
4073
        ctx->pc -= 4;
4074
        gen_op_wait();
4075
        ctx->bstate = BS_EXCP;
4076
        break;
4077
    default:
4078
 die:
4079
        MIPS_INVAL(opn);
4080
        generate_exception(ctx, EXCP_RI);
4081
        return;
4082
    }
4083
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4084
}
4085

    
4086
/* CP1 Branches (before delay slot) */
4087
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4088
                                 int32_t cc, int32_t offset)
4089
{
4090
    target_ulong btarget;
4091
    const char *opn = "cp1 cond branch";
4092

    
4093
    btarget = ctx->pc + 4 + offset;
4094

    
4095
    switch (op) {
4096
    case OPC_BC1F:
4097
        gen_op_bc1f(cc);
4098
        opn = "bc1f";
4099
        goto not_likely;
4100
    case OPC_BC1FL:
4101
        gen_op_bc1f(cc);
4102
        opn = "bc1fl";
4103
        goto likely;
4104
    case OPC_BC1T:
4105
        gen_op_bc1t(cc);
4106
        opn = "bc1t";
4107
        goto not_likely;
4108
    case OPC_BC1TL:
4109
        gen_op_bc1t(cc);
4110
        opn = "bc1tl";
4111
    likely:
4112
        ctx->hflags |= MIPS_HFLAG_BL;
4113
        gen_op_set_bcond();
4114
        gen_op_save_bcond();
4115
        break;
4116
    case OPC_BC1FANY2:
4117
        gen_op_bc1any2f(cc);
4118
        opn = "bc1any2f";
4119
        goto not_likely;
4120
    case OPC_BC1TANY2:
4121
        gen_op_bc1any2t(cc);
4122
        opn = "bc1any2t";
4123
        goto not_likely;
4124
    case OPC_BC1FANY4:
4125
        gen_op_bc1any4f(cc);
4126
        opn = "bc1any4f";
4127
        goto not_likely;
4128
    case OPC_BC1TANY4:
4129
        gen_op_bc1any4t(cc);
4130
        opn = "bc1any4t";
4131
    not_likely:
4132
        ctx->hflags |= MIPS_HFLAG_BC;
4133
        gen_op_set_bcond();
4134
        break;
4135
    default:
4136
        MIPS_INVAL(opn);
4137
        generate_exception (ctx, EXCP_RI);
4138
        return;
4139
    }
4140
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4141
               ctx->hflags, btarget);
4142
    ctx->btarget = btarget;
4143
}
4144

    
4145
/* Coprocessor 1 (FPU) */
4146

    
4147
#define FOP(func, fmt) (((fmt) << 21) | (func))
4148

    
4149
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4150
{
4151
    const char *opn = "cp1 move";
4152

    
4153
    switch (opc) {
4154
    case OPC_MFC1:
4155
        GEN_LOAD_FREG_FTN(WT0, fs);
4156
        gen_op_mfc1();
4157
        GEN_STORE_TN_REG(rt, T0);
4158
        opn = "mfc1";
4159
        break;
4160
    case OPC_MTC1:
4161
        GEN_LOAD_REG_TN(T0, rt);
4162
        gen_op_mtc1();
4163
        GEN_STORE_FTN_FREG(fs, WT0);
4164
        opn = "mtc1";
4165
        break;
4166
    case OPC_CFC1:
4167
        GEN_LOAD_IMM_TN(T1, fs);
4168
        gen_op_cfc1();
4169
        GEN_STORE_TN_REG(rt, T0);
4170
        opn = "cfc1";
4171
        break;
4172
    case OPC_CTC1:
4173
        GEN_LOAD_IMM_TN(T1, fs);
4174
        GEN_LOAD_REG_TN(T0, rt);
4175
        gen_op_ctc1();
4176
        opn = "ctc1";
4177
        break;
4178
    case OPC_DMFC1:
4179
        GEN_LOAD_FREG_FTN(DT0, fs);
4180
        gen_op_dmfc1();
4181
        GEN_STORE_TN_REG(rt, T0);
4182
        opn = "dmfc1";
4183
        break;
4184
    case OPC_DMTC1:
4185
        GEN_LOAD_REG_TN(T0, rt);
4186
        gen_op_dmtc1();
4187
        GEN_STORE_FTN_FREG(fs, DT0);
4188
        opn = "dmtc1";
4189
        break;
4190
    case OPC_MFHC1:
4191
        GEN_LOAD_FREG_FTN(WTH0, fs);
4192
        gen_op_mfhc1();
4193
        GEN_STORE_TN_REG(rt, T0);
4194
        opn = "mfhc1";
4195
        break;
4196
    case OPC_MTHC1:
4197
        GEN_LOAD_REG_TN(T0, rt);
4198
        gen_op_mthc1();
4199
        GEN_STORE_FTN_FREG(fs, WTH0);
4200
        opn = "mthc1";
4201
        break;
4202
    default:
4203
        MIPS_INVAL(opn);
4204
        generate_exception (ctx, EXCP_RI);
4205
        return;
4206
    }
4207
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4208
}
4209

    
4210
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4211
{
4212
    uint32_t ccbit;
4213

    
4214
    GEN_LOAD_REG_TN(T0, rd);
4215
    GEN_LOAD_REG_TN(T1, rs);
4216
    if (cc) {
4217
        ccbit = 1 << (24 + cc);
4218
    } else
4219
        ccbit = 1 << 23;
4220
    if (!tf)
4221
        gen_op_movf(ccbit);
4222
    else
4223
        gen_op_movt(ccbit);
4224
    GEN_STORE_TN_REG(rd, T0);
4225
}
4226

    
4227
#define GEN_MOVCF(fmt)                                                \
4228
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4229
{                                                                     \
4230
    uint32_t ccbit;                                                   \
4231
                                                                      \
4232
    if (cc) {                                                         \
4233
        ccbit = 1 << (24 + cc);                                       \
4234
    } else                                                            \
4235
        ccbit = 1 << 23;                                              \
4236
    if (!tf)                                                          \
4237
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4238
    else                                                              \
4239
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4240
}
4241
GEN_MOVCF(d);
4242
GEN_MOVCF(s);
4243
GEN_MOVCF(ps);
4244
#undef GEN_MOVCF
4245

    
4246
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4247
                        int fs, int fd, int cc)
4248
{
4249
    const char *opn = "farith";
4250
    const char *condnames[] = {
4251
            "c.f",
4252
            "c.un",
4253
            "c.eq",
4254
            "c.ueq",
4255
            "c.olt",
4256
            "c.ult",
4257
            "c.ole",
4258
            "c.ule",
4259
            "c.sf",
4260
            "c.ngle",
4261
            "c.seq",
4262
            "c.ngl",
4263
            "c.lt",
4264
            "c.nge",
4265
            "c.le",
4266
            "c.ngt",
4267
    };
4268
    const char *condnames_abs[] = {
4269
            "cabs.f",
4270
            "cabs.un",
4271
            "cabs.eq",
4272
            "cabs.ueq",
4273
            "cabs.olt",
4274
            "cabs.ult",
4275
            "cabs.ole",
4276
            "cabs.ule",
4277
            "cabs.sf",
4278
            "cabs.ngle",
4279
            "cabs.seq",
4280
            "cabs.ngl",
4281
            "cabs.lt",
4282
            "cabs.nge",
4283
            "cabs.le",
4284
            "cabs.ngt",
4285
    };
4286
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4287
    uint32_t func = ctx->opcode & 0x3f;
4288

    
4289
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4290
    case FOP(0, 16):
4291
        GEN_LOAD_FREG_FTN(WT0, fs);
4292
        GEN_LOAD_FREG_FTN(WT1, ft);
4293
        gen_op_float_add_s();
4294
        GEN_STORE_FTN_FREG(fd, WT2);
4295
        opn = "add.s";
4296
        optype = BINOP;
4297
        break;
4298
    case FOP(1, 16):
4299
        GEN_LOAD_FREG_FTN(WT0, fs);
4300
        GEN_LOAD_FREG_FTN(WT1, ft);
4301
        gen_op_float_sub_s();
4302
        GEN_STORE_FTN_FREG(fd, WT2);
4303
        opn = "sub.s";
4304
        optype = BINOP;
4305
        break;
4306
    case FOP(2, 16):
4307
        GEN_LOAD_FREG_FTN(WT0, fs);
4308
        GEN_LOAD_FREG_FTN(WT1, ft);
4309
        gen_op_float_mul_s();
4310
        GEN_STORE_FTN_FREG(fd, WT2);
4311
        opn = "mul.s";
4312
        optype = BINOP;
4313
        break;
4314
    case FOP(3, 16):
4315
        GEN_LOAD_FREG_FTN(WT0, fs);
4316
        GEN_LOAD_FREG_FTN(WT1, ft);
4317
        gen_op_float_div_s();
4318
        GEN_STORE_FTN_FREG(fd, WT2);
4319
        opn = "div.s";
4320
        optype = BINOP;
4321
        break;
4322
    case FOP(4, 16):
4323
        GEN_LOAD_FREG_FTN(WT0, fs);
4324
        gen_op_float_sqrt_s();
4325
        GEN_STORE_FTN_FREG(fd, WT2);
4326
        opn = "sqrt.s";
4327
        break;
4328
    case FOP(5, 16):
4329
        GEN_LOAD_FREG_FTN(WT0, fs);
4330
        gen_op_float_abs_s();
4331
        GEN_STORE_FTN_FREG(fd, WT2);
4332
        opn = "abs.s";
4333
        break;
4334
    case FOP(6, 16):
4335
        GEN_LOAD_FREG_FTN(WT0, fs);
4336
        gen_op_float_mov_s();
4337
        GEN_STORE_FTN_FREG(fd, WT2);
4338
        opn = "mov.s";
4339
        break;
4340
    case FOP(7, 16):
4341
        GEN_LOAD_FREG_FTN(WT0, fs);
4342
        gen_op_float_chs_s();
4343
        GEN_STORE_FTN_FREG(fd, WT2);
4344
        opn = "neg.s";
4345
        break;
4346
    case FOP(8, 16):
4347
        gen_op_cp1_64bitmode();
4348
        GEN_LOAD_FREG_FTN(WT0, fs);
4349
        gen_op_float_roundl_s();
4350
        GEN_STORE_FTN_FREG(fd, DT2);
4351
        opn = "round.l.s";
4352
        break;
4353
    case FOP(9, 16):
4354
        gen_op_cp1_64bitmode();
4355
        GEN_LOAD_FREG_FTN(WT0, fs);
4356
        gen_op_float_truncl_s();
4357
        GEN_STORE_FTN_FREG(fd, DT2);
4358
        opn = "trunc.l.s";
4359
        break;
4360
    case FOP(10, 16):
4361
        gen_op_cp1_64bitmode();
4362
        GEN_LOAD_FREG_FTN(WT0, fs);
4363
        gen_op_float_ceill_s();
4364
        GEN_STORE_FTN_FREG(fd, DT2);
4365
        opn = "ceil.l.s";
4366
        break;
4367
    case FOP(11, 16):
4368
        gen_op_cp1_64bitmode();
4369
        GEN_LOAD_FREG_FTN(WT0, fs);
4370
        gen_op_float_floorl_s();
4371
        GEN_STORE_FTN_FREG(fd, DT2);
4372
        opn = "floor.l.s";
4373
        break;
4374
    case FOP(12, 16):
4375
        GEN_LOAD_FREG_FTN(WT0, fs);
4376
        gen_op_float_roundw_s();
4377
        GEN_STORE_FTN_FREG(fd, WT2);
4378
        opn = "round.w.s";
4379
        break;
4380
    case FOP(13, 16):
4381
        GEN_LOAD_FREG_FTN(WT0, fs);
4382
        gen_op_float_truncw_s();
4383
        GEN_STORE_FTN_FREG(fd, WT2);
4384
        opn = "trunc.w.s";
4385
        break;
4386
    case FOP(14, 16):
4387
        GEN_LOAD_FREG_FTN(WT0, fs);
4388
        gen_op_float_ceilw_s();
4389
        GEN_STORE_FTN_FREG(fd, WT2);
4390
        opn = "ceil.w.s";
4391
        break;
4392
    case FOP(15, 16):
4393
        GEN_LOAD_FREG_FTN(WT0, fs);
4394
        gen_op_float_floorw_s();
4395
        GEN_STORE_FTN_FREG(fd, WT2);
4396
        opn = "floor.w.s";
4397
        break;
4398
    case FOP(17, 16):
4399
        GEN_LOAD_REG_TN(T0, ft);
4400
        GEN_LOAD_FREG_FTN(WT0, fs);
4401
        GEN_LOAD_FREG_FTN(WT2, fd);
4402
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4403
        GEN_STORE_FTN_FREG(fd, WT2);
4404
        opn = "movcf.s";
4405
        break;
4406
    case FOP(18, 16):
4407
        GEN_LOAD_REG_TN(T0, ft);
4408
        GEN_LOAD_FREG_FTN(WT0, fs);
4409
        GEN_LOAD_FREG_FTN(WT2, fd);
4410
        gen_op_float_movz_s();
4411
        GEN_STORE_FTN_FREG(fd, WT2);
4412
        opn = "movz.s";
4413
        break;
4414
    case FOP(19, 16):
4415
        GEN_LOAD_REG_TN(T0, ft);
4416
        GEN_LOAD_FREG_FTN(WT0, fs);
4417
        GEN_LOAD_FREG_FTN(WT2, fd);
4418
        gen_op_float_movn_s();
4419
        GEN_STORE_FTN_FREG(fd, WT2);
4420
        opn = "movn.s";
4421
        break;
4422
    case FOP(21, 16):
4423
        GEN_LOAD_FREG_FTN(WT0, fs);
4424
        gen_op_float_recip_s();
4425
        GEN_STORE_FTN_FREG(fd, WT2);
4426
        opn = "recip.s";
4427
        break;
4428
    case FOP(22, 16):
4429
        GEN_LOAD_FREG_FTN(WT0, fs);
4430
        gen_op_float_rsqrt_s();
4431
        GEN_STORE_FTN_FREG(fd, WT2);
4432
        opn = "rsqrt.s";
4433
        break;
4434
    case FOP(28, 16):
4435
        gen_op_cp1_64bitmode();
4436
        GEN_LOAD_FREG_FTN(WT0, fs);
4437
        GEN_LOAD_FREG_FTN(WT2, fd);
4438
        gen_op_float_recip2_s();
4439
        GEN_STORE_FTN_FREG(fd, WT2);
4440
        opn = "recip2.s";
4441
        break;
4442
    case FOP(29, 16):
4443
        gen_op_cp1_64bitmode();
4444
        GEN_LOAD_FREG_FTN(WT0, fs);
4445
        gen_op_float_recip1_s();
4446
        GEN_STORE_FTN_FREG(fd, WT2);
4447
        opn = "recip1.s";
4448
        break;
4449
    case FOP(30, 16):
4450
        gen_op_cp1_64bitmode();
4451
        GEN_LOAD_FREG_FTN(WT0, fs);
4452
        gen_op_float_rsqrt1_s();
4453
        GEN_STORE_FTN_FREG(fd, WT2);
4454
        opn = "rsqrt1.s";
4455
        break;
4456
    case FOP(31, 16):
4457
        gen_op_cp1_64bitmode();
4458
        GEN_LOAD_FREG_FTN(WT0, fs);
4459
        GEN_LOAD_FREG_FTN(WT2, fd);
4460
        gen_op_float_rsqrt2_s();
4461
        GEN_STORE_FTN_FREG(fd, WT2);
4462
        opn = "rsqrt2.s";
4463
        break;
4464
    case FOP(33, 16):
4465
        gen_op_cp1_registers(fd);
4466
        GEN_LOAD_FREG_FTN(WT0, fs);
4467
        gen_op_float_cvtd_s();
4468
        GEN_STORE_FTN_FREG(fd, DT2);
4469
        opn = "cvt.d.s";
4470
        break;
4471
    case FOP(36, 16):
4472
        GEN_LOAD_FREG_FTN(WT0, fs);
4473
        gen_op_float_cvtw_s();
4474
        GEN_STORE_FTN_FREG(fd, WT2);
4475
        opn = "cvt.w.s";
4476
        break;
4477
    case FOP(37, 16):
4478
        gen_op_cp1_64bitmode();
4479
        GEN_LOAD_FREG_FTN(WT0, fs);
4480
        gen_op_float_cvtl_s();
4481
        GEN_STORE_FTN_FREG(fd, DT2);
4482
        opn = "cvt.l.s";
4483
        break;
4484
    case FOP(38, 16):
4485
        gen_op_cp1_64bitmode();
4486
        GEN_LOAD_FREG_FTN(WT1, fs);
4487
        GEN_LOAD_FREG_FTN(WT0, ft);
4488
        gen_op_float_cvtps_s();
4489
        GEN_STORE_FTN_FREG(fd, DT2);
4490
        opn = "cvt.ps.s";
4491
        break;
4492
    case FOP(48, 16):
4493
    case FOP(49, 16):
4494
    case FOP(50, 16):
4495
    case FOP(51, 16):
4496
    case FOP(52, 16):
4497
    case FOP(53, 16):
4498
    case FOP(54, 16):
4499
    case FOP(55, 16):
4500
    case FOP(56, 16):
4501
    case FOP(57, 16):
4502
    case FOP(58, 16):
4503
    case FOP(59, 16):
4504
    case FOP(60, 16):
4505
    case FOP(61, 16):
4506
    case FOP(62, 16):
4507
    case FOP(63, 16):
4508
        GEN_LOAD_FREG_FTN(WT0, fs);
4509
        GEN_LOAD_FREG_FTN(WT1, ft);
4510
        if (ctx->opcode & (1 << 6)) {
4511
            gen_op_cp1_64bitmode();
4512
            gen_cmpabs_s(func-48, cc);
4513
            opn = condnames_abs[func-48];
4514
        } else {
4515
            gen_cmp_s(func-48, cc);
4516
            opn = condnames[func-48];
4517
        }
4518
        break;
4519
    case FOP(0, 17):
4520
        gen_op_cp1_registers(fs | ft | fd);
4521
        GEN_LOAD_FREG_FTN(DT0, fs);
4522
        GEN_LOAD_FREG_FTN(DT1, ft);
4523
        gen_op_float_add_d();
4524
        GEN_STORE_FTN_FREG(fd, DT2);
4525
        opn = "add.d";
4526
        optype = BINOP;
4527
        break;
4528
    case FOP(1, 17):
4529
        gen_op_cp1_registers(fs | ft | fd);
4530
        GEN_LOAD_FREG_FTN(DT0, fs);
4531
        GEN_LOAD_FREG_FTN(DT1, ft);
4532
        gen_op_float_sub_d();
4533
        GEN_STORE_FTN_FREG(fd, DT2);
4534
        opn = "sub.d";
4535
        optype = BINOP;
4536
        break;
4537
    case FOP(2, 17):
4538
        gen_op_cp1_registers(fs | ft | fd);
4539
        GEN_LOAD_FREG_FTN(DT0, fs);
4540
        GEN_LOAD_FREG_FTN(DT1, ft);
4541
        gen_op_float_mul_d();
4542
        GEN_STORE_FTN_FREG(fd, DT2);
4543
        opn = "mul.d";
4544
        optype = BINOP;
4545
        break;
4546
    case FOP(3, 17):
4547
        gen_op_cp1_registers(fs | ft | fd);
4548
        GEN_LOAD_FREG_FTN(DT0, fs);
4549
        GEN_LOAD_FREG_FTN(DT1, ft);
4550
        gen_op_float_div_d();
4551
        GEN_STORE_FTN_FREG(fd, DT2);
4552
        opn = "div.d";
4553
        optype = BINOP;
4554
        break;
4555
    case FOP(4, 17):
4556
        gen_op_cp1_registers(fs | fd);
4557
        GEN_LOAD_FREG_FTN(DT0, fs);
4558
        gen_op_float_sqrt_d();
4559
        GEN_STORE_FTN_FREG(fd, DT2);
4560
        opn = "sqrt.d";
4561
        break;
4562
    case FOP(5, 17):
4563
        gen_op_cp1_registers(fs | fd);
4564
        GEN_LOAD_FREG_FTN(DT0, fs);
4565
        gen_op_float_abs_d();
4566
        GEN_STORE_FTN_FREG(fd, DT2);
4567
        opn = "abs.d";
4568
        break;
4569
    case FOP(6, 17):
4570
        gen_op_cp1_registers(fs | fd);
4571
        GEN_LOAD_FREG_FTN(DT0, fs);
4572
        gen_op_float_mov_d();
4573
        GEN_STORE_FTN_FREG(fd, DT2);
4574
        opn = "mov.d";
4575
        break;
4576
    case FOP(7, 17):
4577
        gen_op_cp1_registers(fs | fd);
4578
        GEN_LOAD_FREG_FTN(DT0, fs);
4579
        gen_op_float_chs_d();
4580
        GEN_STORE_FTN_FREG(fd, DT2);
4581
        opn = "neg.d";
4582
        break;
4583
    case FOP(8, 17):
4584
        gen_op_cp1_64bitmode();
4585
        GEN_LOAD_FREG_FTN(DT0, fs);
4586
        gen_op_float_roundl_d();
4587
        GEN_STORE_FTN_FREG(fd, DT2);
4588
        opn = "round.l.d";
4589
        break;
4590
    case FOP(9, 17):
4591
        gen_op_cp1_64bitmode();
4592
        GEN_LOAD_FREG_FTN(DT0, fs);
4593
        gen_op_float_truncl_d();
4594
        GEN_STORE_FTN_FREG(fd, DT2);
4595
        opn = "trunc.l.d";
4596
        break;
4597
    case FOP(10, 17):
4598
        gen_op_cp1_64bitmode();
4599
        GEN_LOAD_FREG_FTN(DT0, fs);
4600
        gen_op_float_ceill_d();
4601
        GEN_STORE_FTN_FREG(fd, DT2);
4602
        opn = "ceil.l.d";
4603
        break;
4604
    case FOP(11, 17):
4605
        gen_op_cp1_64bitmode();
4606
        GEN_LOAD_FREG_FTN(DT0, fs);
4607
        gen_op_float_floorl_d();
4608
        GEN_STORE_FTN_FREG(fd, DT2);
4609
        opn = "floor.l.d";
4610
        break;
4611
    case FOP(12, 17):
4612
        gen_op_cp1_registers(fs);
4613
        GEN_LOAD_FREG_FTN(DT0, fs);
4614
        gen_op_float_roundw_d();
4615
        GEN_STORE_FTN_FREG(fd, WT2);
4616
        opn = "round.w.d";
4617
        break;
4618
    case FOP(13, 17):
4619
        gen_op_cp1_registers(fs);
4620
        GEN_LOAD_FREG_FTN(DT0, fs);
4621
        gen_op_float_truncw_d();
4622
        GEN_STORE_FTN_FREG(fd, WT2);
4623
        opn = "trunc.w.d";
4624
        break;
4625
    case FOP(14, 17):
4626
        gen_op_cp1_registers(fs);
4627
        GEN_LOAD_FREG_FTN(DT0, fs);
4628
        gen_op_float_ceilw_d();
4629
        GEN_STORE_FTN_FREG(fd, WT2);
4630
        opn = "ceil.w.d";
4631
        break;
4632
    case FOP(15, 17):
4633
        gen_op_cp1_registers(fs);
4634
        GEN_LOAD_FREG_FTN(DT0, fs);
4635
        gen_op_float_floorw_d();
4636
        GEN_STORE_FTN_FREG(fd, WT2);
4637
        opn = "floor.w.d";
4638
        break;
4639
    case FOP(17, 17):
4640
        GEN_LOAD_REG_TN(T0, ft);
4641
        GEN_LOAD_FREG_FTN(DT0, fs);
4642
        GEN_LOAD_FREG_FTN(DT2, fd);
4643
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4644
        GEN_STORE_FTN_FREG(fd, DT2);
4645
        opn = "movcf.d";
4646
        break;
4647
    case FOP(18, 17):
4648
        GEN_LOAD_REG_TN(T0, ft);
4649
        GEN_LOAD_FREG_FTN(DT0, fs);
4650
        GEN_LOAD_FREG_FTN(DT2, fd);
4651
        gen_op_float_movz_d();
4652
        GEN_STORE_FTN_FREG(fd, DT2);
4653
        opn = "movz.d";
4654
        break;
4655
    case FOP(19, 17):
4656
        GEN_LOAD_REG_TN(T0, ft);
4657
        GEN_LOAD_FREG_FTN(DT0, fs);
4658
        GEN_LOAD_FREG_FTN(DT2, fd);
4659
        gen_op_float_movn_d();
4660
        GEN_STORE_FTN_FREG(fd, DT2);
4661
        opn = "movn.d";
4662
        break;
4663
    case FOP(21, 17):
4664
        gen_op_cp1_registers(fs | fd);
4665
        GEN_LOAD_FREG_FTN(DT0, fs);
4666
        gen_op_float_recip_d();
4667
        GEN_STORE_FTN_FREG(fd, DT2);
4668
        opn = "recip.d";
4669
        break;
4670
    case FOP(22, 17):
4671
        gen_op_cp1_registers(fs | fd);
4672
        GEN_LOAD_FREG_FTN(DT0, fs);
4673
        gen_op_float_rsqrt_d();
4674
        GEN_STORE_FTN_FREG(fd, DT2);
4675
        opn = "rsqrt.d";
4676
        break;
4677
    case FOP(28, 17):
4678
        gen_op_cp1_64bitmode();
4679
        GEN_LOAD_FREG_FTN(DT0, fs);
4680
        GEN_LOAD_FREG_FTN(DT2, ft);
4681
        gen_op_float_recip2_d();
4682
        GEN_STORE_FTN_FREG(fd, DT2);
4683
        opn = "recip2.d";
4684
        break;
4685
    case FOP(29, 17):
4686
        gen_op_cp1_64bitmode();
4687
        GEN_LOAD_FREG_FTN(DT0, fs);
4688
        gen_op_float_recip1_d();
4689
        GEN_STORE_FTN_FREG(fd, DT2);
4690
        opn = "recip1.d";
4691
        break;
4692
    case FOP(30, 17):
4693
        gen_op_cp1_64bitmode();
4694
        GEN_LOAD_FREG_FTN(DT0, fs);
4695
        gen_op_float_rsqrt1_d();
4696
        GEN_STORE_FTN_FREG(fd, DT2);
4697
        opn = "rsqrt1.d";
4698
        break;
4699
    case FOP(31, 17):
4700
        gen_op_cp1_64bitmode();
4701
        GEN_LOAD_FREG_FTN(DT0, fs);
4702
        GEN_LOAD_FREG_FTN(DT2, ft);
4703
        gen_op_float_rsqrt2_d();
4704
        GEN_STORE_FTN_FREG(fd, DT2);
4705
        opn = "rsqrt2.d";
4706
        break;
4707
    case FOP(48, 17):
4708
    case FOP(49, 17):
4709
    case FOP(50, 17):
4710
    case FOP(51, 17):
4711
    case FOP(52, 17):
4712
    case FOP(53, 17):
4713
    case FOP(54, 17):
4714
    case FOP(55, 17):
4715
    case FOP(56, 17):
4716
    case FOP(57, 17):
4717
    case FOP(58, 17):
4718
    case FOP(59, 17):
4719
    case FOP(60, 17):
4720
    case FOP(61, 17):
4721
    case FOP(62, 17):
4722
    case FOP(63, 17):
4723
        GEN_LOAD_FREG_FTN(DT0, fs);
4724
        GEN_LOAD_FREG_FTN(DT1, ft);
4725
        if (ctx->opcode & (1 << 6)) {
4726
            gen_op_cp1_64bitmode();
4727
            gen_cmpabs_d(func-48, cc);
4728
            opn = condnames_abs[func-48];
4729
        } else {
4730
            gen_op_cp1_registers(fs | ft);
4731
            gen_cmp_d(func-48, cc);
4732
            opn = condnames[func-48];
4733
        }
4734
        break;
4735
    case FOP(32, 17):
4736
        gen_op_cp1_registers(fs);
4737
        GEN_LOAD_FREG_FTN(DT0, fs);
4738
        gen_op_float_cvts_d();
4739
        GEN_STORE_FTN_FREG(fd, WT2);
4740
        opn = "cvt.s.d";
4741
        break;
4742
    case FOP(36, 17):
4743
        gen_op_cp1_registers(fs);
4744
        GEN_LOAD_FREG_FTN(DT0, fs);
4745
        gen_op_float_cvtw_d();
4746
        GEN_STORE_FTN_FREG(fd, WT2);
4747
        opn = "cvt.w.d";
4748
        break;
4749
    case FOP(37, 17):
4750
        gen_op_cp1_64bitmode();
4751
        GEN_LOAD_FREG_FTN(DT0, fs);
4752
        gen_op_float_cvtl_d();
4753
        GEN_STORE_FTN_FREG(fd, DT2);
4754
        opn = "cvt.l.d";
4755
        break;
4756
    case FOP(32, 20):
4757
        GEN_LOAD_FREG_FTN(WT0, fs);
4758
        gen_op_float_cvts_w();
4759
        GEN_STORE_FTN_FREG(fd, WT2);
4760
        opn = "cvt.s.w";
4761
        break;
4762
    case FOP(33, 20):
4763
        gen_op_cp1_registers(fd);
4764
        GEN_LOAD_FREG_FTN(WT0, fs);
4765
        gen_op_float_cvtd_w();
4766
        GEN_STORE_FTN_FREG(fd, DT2);
4767
        opn = "cvt.d.w";
4768
        break;
4769
    case FOP(32, 21):
4770
        gen_op_cp1_64bitmode();
4771
        GEN_LOAD_FREG_FTN(DT0, fs);
4772
        gen_op_float_cvts_l();
4773
        GEN_STORE_FTN_FREG(fd, WT2);
4774
        opn = "cvt.s.l";
4775
        break;
4776
    case FOP(33, 21):
4777
        gen_op_cp1_64bitmode();
4778
        GEN_LOAD_FREG_FTN(DT0, fs);
4779
        gen_op_float_cvtd_l();
4780
        GEN_STORE_FTN_FREG(fd, DT2);
4781
        opn = "cvt.d.l";
4782
        break;
4783
    case FOP(38, 20):
4784
    case FOP(38, 21):
4785
        gen_op_cp1_64bitmode();
4786
        GEN_LOAD_FREG_FTN(WT0, fs);
4787
        GEN_LOAD_FREG_FTN(WTH0, fs);
4788
        gen_op_float_cvtps_pw();
4789
        GEN_STORE_FTN_FREG(fd, WT2);
4790
        GEN_STORE_FTN_FREG(fd, WTH2);
4791
        opn = "cvt.ps.pw";
4792
        break;
4793
    case FOP(0, 22):
4794
        gen_op_cp1_64bitmode();
4795
        GEN_LOAD_FREG_FTN(WT0, fs);
4796
        GEN_LOAD_FREG_FTN(WTH0, fs);
4797
        GEN_LOAD_FREG_FTN(WT1, ft);
4798
        GEN_LOAD_FREG_FTN(WTH1, ft);
4799
        gen_op_float_add_ps();
4800
        GEN_STORE_FTN_FREG(fd, WT2);
4801
        GEN_STORE_FTN_FREG(fd, WTH2);
4802
        opn = "add.ps";
4803
        break;
4804
    case FOP(1, 22):
4805
        gen_op_cp1_64bitmode();
4806
        GEN_LOAD_FREG_FTN(WT0, fs);
4807
        GEN_LOAD_FREG_FTN(WTH0, fs);
4808
        GEN_LOAD_FREG_FTN(WT1, ft);
4809
        GEN_LOAD_FREG_FTN(WTH1, ft);
4810
        gen_op_float_sub_ps();
4811
        GEN_STORE_FTN_FREG(fd, WT2);
4812
        GEN_STORE_FTN_FREG(fd, WTH2);
4813
        opn = "sub.ps";
4814
        break;
4815
    case FOP(2, 22):
4816
        gen_op_cp1_64bitmode();
4817
        GEN_LOAD_FREG_FTN(WT0, fs);
4818
        GEN_LOAD_FREG_FTN(WTH0, fs);
4819
        GEN_LOAD_FREG_FTN(WT1, ft);
4820
        GEN_LOAD_FREG_FTN(WTH1, ft);
4821
        gen_op_float_mul_ps();
4822
        GEN_STORE_FTN_FREG(fd, WT2);
4823
        GEN_STORE_FTN_FREG(fd, WTH2);
4824
        opn = "mul.ps";
4825
        break;
4826
    case FOP(5, 22):
4827
        gen_op_cp1_64bitmode();
4828
        GEN_LOAD_FREG_FTN(WT0, fs);
4829
        GEN_LOAD_FREG_FTN(WTH0, fs);
4830
        gen_op_float_abs_ps();
4831
        GEN_STORE_FTN_FREG(fd, WT2);
4832
        GEN_STORE_FTN_FREG(fd, WTH2);
4833
        opn = "abs.ps";
4834
        break;
4835
    case FOP(6, 22):
4836
        gen_op_cp1_64bitmode();
4837
        GEN_LOAD_FREG_FTN(WT0, fs);
4838
        GEN_LOAD_FREG_FTN(WTH0, fs);
4839
        gen_op_float_mov_ps();
4840
        GEN_STORE_FTN_FREG(fd, WT2);
4841
        GEN_STORE_FTN_FREG(fd, WTH2);
4842
        opn = "mov.ps";
4843
        break;
4844
    case FOP(7, 22):
4845
        gen_op_cp1_64bitmode();
4846
        GEN_LOAD_FREG_FTN(WT0, fs);
4847
        GEN_LOAD_FREG_FTN(WTH0, fs);
4848
        gen_op_float_chs_ps();
4849
        GEN_STORE_FTN_FREG(fd, WT2);
4850
        GEN_STORE_FTN_FREG(fd, WTH2);
4851
        opn = "neg.ps";
4852
        break;
4853
    case FOP(17, 22):
4854
        gen_op_cp1_64bitmode();
4855
        GEN_LOAD_REG_TN(T0, ft);
4856
        GEN_LOAD_FREG_FTN(WT0, fs);
4857
        GEN_LOAD_FREG_FTN(WTH0, fs);
4858
        GEN_LOAD_FREG_FTN(WT2, fd);
4859
        GEN_LOAD_FREG_FTN(WTH2, fd);
4860
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
4861
        GEN_STORE_FTN_FREG(fd, WT2);
4862
        GEN_STORE_FTN_FREG(fd, WTH2);
4863
        opn = "movcf.ps";
4864
        break;
4865
    case FOP(18, 22):
4866
        gen_op_cp1_64bitmode();
4867
        GEN_LOAD_REG_TN(T0, ft);
4868
        GEN_LOAD_FREG_FTN(WT0, fs);
4869
        GEN_LOAD_FREG_FTN(WTH0, fs);
4870
        GEN_LOAD_FREG_FTN(WT2, fd);
4871
        GEN_LOAD_FREG_FTN(WTH2, fd);
4872
        gen_op_float_movz_ps();
4873
        GEN_STORE_FTN_FREG(fd, WT2);
4874
        GEN_STORE_FTN_FREG(fd, WTH2);
4875
        opn = "movz.ps";
4876
        break;
4877
    case FOP(19, 22):
4878
        gen_op_cp1_64bitmode();
4879
        GEN_LOAD_REG_TN(T0, ft);
4880
        GEN_LOAD_FREG_FTN(WT0, fs);
4881
        GEN_LOAD_FREG_FTN(WTH0, fs);
4882
        GEN_LOAD_FREG_FTN(WT2, fd);
4883
        GEN_LOAD_FREG_FTN(WTH2, fd);
4884
        gen_op_float_movn_ps();
4885
        GEN_STORE_FTN_FREG(fd, WT2);
4886
        GEN_STORE_FTN_FREG(fd, WTH2);
4887
        opn = "movn.ps";
4888
        break;
4889
    case FOP(24, 22):
4890
        gen_op_cp1_64bitmode();
4891
        GEN_LOAD_FREG_FTN(WT0, ft);
4892
        GEN_LOAD_FREG_FTN(WTH0, ft);
4893
        GEN_LOAD_FREG_FTN(WT1, fs);
4894
        GEN_LOAD_FREG_FTN(WTH1, fs);
4895
        gen_op_float_addr_ps();
4896
        GEN_STORE_FTN_FREG(fd, WT2);
4897
        GEN_STORE_FTN_FREG(fd, WTH2);
4898
        opn = "addr.ps";
4899
        break;
4900
    case FOP(26, 22):
4901
        gen_op_cp1_64bitmode();
4902
        GEN_LOAD_FREG_FTN(WT0, ft);
4903
        GEN_LOAD_FREG_FTN(WTH0, ft);
4904
        GEN_LOAD_FREG_FTN(WT1, fs);
4905
        GEN_LOAD_FREG_FTN(WTH1, fs);
4906
        gen_op_float_mulr_ps();
4907
        GEN_STORE_FTN_FREG(fd, WT2);
4908
        GEN_STORE_FTN_FREG(fd, WTH2);
4909
        opn = "mulr.ps";
4910
        break;
4911
    case FOP(28, 22):
4912
        gen_op_cp1_64bitmode();
4913
        GEN_LOAD_FREG_FTN(WT0, fs);
4914
        GEN_LOAD_FREG_FTN(WTH0, fs);
4915
        GEN_LOAD_FREG_FTN(WT2, fd);
4916
        GEN_LOAD_FREG_FTN(WTH2, fd);
4917
        gen_op_float_recip2_ps();
4918
        GEN_STORE_FTN_FREG(fd, WT2);
4919
        GEN_STORE_FTN_FREG(fd, WTH2);
4920
        opn = "recip2.ps";
4921
        break;
4922
    case FOP(29, 22):
4923
        gen_op_cp1_64bitmode();
4924
        GEN_LOAD_FREG_FTN(WT0, fs);
4925
        GEN_LOAD_FREG_FTN(WTH0, fs);
4926
        gen_op_float_recip1_ps();
4927
        GEN_STORE_FTN_FREG(fd, WT2);
4928
        GEN_STORE_FTN_FREG(fd, WTH2);
4929
        opn = "recip1.ps";
4930
        break;
4931
    case FOP(30, 22):
4932
        gen_op_cp1_64bitmode();
4933
        GEN_LOAD_FREG_FTN(WT0, fs);
4934
        GEN_LOAD_FREG_FTN(WTH0, fs);
4935
        gen_op_float_rsqrt1_ps();
4936
        GEN_STORE_FTN_FREG(fd, WT2);
4937
        GEN_STORE_FTN_FREG(fd, WTH2);
4938
        opn = "rsqrt1.ps";
4939
        break;
4940
    case FOP(31, 22):
4941
        gen_op_cp1_64bitmode();
4942
        GEN_LOAD_FREG_FTN(WT0, fs);
4943
        GEN_LOAD_FREG_FTN(WTH0, fs);
4944
        GEN_LOAD_FREG_FTN(WT2, fd);
4945
        GEN_LOAD_FREG_FTN(WTH2, fd);
4946
        gen_op_float_rsqrt2_ps();
4947
        GEN_STORE_FTN_FREG(fd, WT2);
4948
        GEN_STORE_FTN_FREG(fd, WTH2);
4949
        opn = "rsqrt2.ps";
4950
        break;
4951
    case FOP(32, 22):
4952
        gen_op_cp1_64bitmode();
4953
        GEN_LOAD_FREG_FTN(WTH0, fs);
4954
        gen_op_float_cvts_pu();
4955
        GEN_STORE_FTN_FREG(fd, WT2);
4956
        opn = "cvt.s.pu";
4957
        break;
4958
    case FOP(36, 22):
4959
        gen_op_cp1_64bitmode();
4960
        GEN_LOAD_FREG_FTN(WT0, fs);
4961
        GEN_LOAD_FREG_FTN(WTH0, fs);
4962
        gen_op_float_cvtpw_ps();
4963
        GEN_STORE_FTN_FREG(fd, WT2);
4964
        GEN_STORE_FTN_FREG(fd, WTH2);
4965
        opn = "cvt.pw.ps";
4966
        break;
4967
    case FOP(40, 22):
4968
        gen_op_cp1_64bitmode();
4969
        GEN_LOAD_FREG_FTN(WT0, fs);
4970
        gen_op_float_cvts_pl();
4971
        GEN_STORE_FTN_FREG(fd, WT2);
4972
        opn = "cvt.s.pl";
4973
        break;
4974
    case FOP(44, 22):
4975
        gen_op_cp1_64bitmode();
4976
        GEN_LOAD_FREG_FTN(WT0, fs);
4977
        GEN_LOAD_FREG_FTN(WT1, ft);
4978
        gen_op_float_pll_ps();
4979
        GEN_STORE_FTN_FREG(fd, DT2);
4980
        opn = "pll.ps";
4981
        break;
4982
    case FOP(45, 22):
4983
        gen_op_cp1_64bitmode();
4984
        GEN_LOAD_FREG_FTN(WT0, fs);
4985
        GEN_LOAD_FREG_FTN(WTH1, ft);
4986
        gen_op_float_plu_ps();
4987
        GEN_STORE_FTN_FREG(fd, DT2);
4988
        opn = "plu.ps";
4989
        break;
4990
    case FOP(46, 22):
4991
        gen_op_cp1_64bitmode();
4992
        GEN_LOAD_FREG_FTN(WTH0, fs);
4993
        GEN_LOAD_FREG_FTN(WT1, ft);
4994
        gen_op_float_pul_ps();
4995
        GEN_STORE_FTN_FREG(fd, DT2);
4996
        opn = "pul.ps";
4997
        break;
4998
    case FOP(47, 22):
4999
        gen_op_cp1_64bitmode();
5000
        GEN_LOAD_FREG_FTN(WTH0, fs);
5001
        GEN_LOAD_FREG_FTN(WTH1, ft);
5002
        gen_op_float_puu_ps();
5003
        GEN_STORE_FTN_FREG(fd, DT2);
5004
        opn = "puu.ps";
5005
        break;
5006
    case FOP(48, 22):
5007
    case FOP(49, 22):
5008
    case FOP(50, 22):
5009
    case FOP(51, 22):
5010
    case FOP(52, 22):
5011
    case FOP(53, 22):
5012
    case FOP(54, 22):
5013
    case FOP(55, 22):
5014
    case FOP(56, 22):
5015
    case FOP(57, 22):
5016
    case FOP(58, 22):
5017
    case FOP(59, 22):
5018
    case FOP(60, 22):
5019
    case FOP(61, 22):
5020
    case FOP(62, 22):
5021
    case FOP(63, 22):
5022
        gen_op_cp1_64bitmode();
5023
        GEN_LOAD_FREG_FTN(WT0, fs);
5024
        GEN_LOAD_FREG_FTN(WTH0, fs);
5025
        GEN_LOAD_FREG_FTN(WT1, ft);
5026
        GEN_LOAD_FREG_FTN(WTH1, ft);
5027
        if (ctx->opcode & (1 << 6)) {
5028
            gen_cmpabs_ps(func-48, cc);
5029
            opn = condnames_abs[func-48];
5030
        } else {
5031
            gen_cmp_ps(func-48, cc);
5032
            opn = condnames[func-48];
5033
        }
5034
        break;
5035
    default:
5036
        MIPS_INVAL(opn);
5037
        generate_exception (ctx, EXCP_RI);
5038
        return;
5039
    }
5040
    switch (optype) {
5041
    case BINOP:
5042
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5043
        break;
5044
    case CMPOP:
5045
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5046
        break;
5047
    default:
5048
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5049
        break;
5050
    }
5051
}
5052

    
5053
/* Coprocessor 3 (FPU) */
5054
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5055
                           int fs, int base, int index)
5056
{
5057
    const char *opn = "extended float load/store";
5058
    int store = 0;
5059

    
5060
    /* All of those work only on 64bit FPUs. */
5061
    gen_op_cp1_64bitmode();
5062
    if (base == 0) {
5063
        if (index == 0)
5064
            gen_op_reset_T0();
5065
        else
5066
            GEN_LOAD_REG_TN(T0, index);
5067
    } else if (index == 0) {
5068
        GEN_LOAD_REG_TN(T0, base);
5069
    } else {
5070
        GEN_LOAD_REG_TN(T0, base);
5071
        GEN_LOAD_REG_TN(T1, index);
5072
        gen_op_addr_add();
5073
    }
5074
    /* Don't do NOP if destination is zero: we must perform the actual
5075
     * memory access
5076
     */
5077
    switch (opc) {
5078
    case OPC_LWXC1:
5079
        op_ldst(lwc1);
5080
        GEN_STORE_FTN_FREG(fd, WT0);
5081
        opn = "lwxc1";
5082
        break;
5083
    case OPC_LDXC1:
5084
        op_ldst(ldc1);
5085
        GEN_STORE_FTN_FREG(fd, DT0);
5086
        opn = "ldxc1";
5087
        break;
5088
    case OPC_LUXC1:
5089
        op_ldst(luxc1);
5090
        GEN_STORE_FTN_FREG(fd, DT0);
5091
        opn = "luxc1";
5092
        break;
5093
    case OPC_SWXC1:
5094
        GEN_LOAD_FREG_FTN(WT0, fs);
5095
        op_ldst(swc1);
5096
        opn = "swxc1";
5097
        store = 1;
5098
        break;
5099
    case OPC_SDXC1:
5100
        GEN_LOAD_FREG_FTN(DT0, fs);
5101
        op_ldst(sdc1);
5102
        opn = "sdxc1";
5103
        store = 1;
5104
        break;
5105
    case OPC_SUXC1:
5106
        GEN_LOAD_FREG_FTN(DT0, fs);
5107
        op_ldst(suxc1);
5108
        opn = "suxc1";
5109
        store = 1;
5110
        break;
5111
    default:
5112
        MIPS_INVAL(opn);
5113
        generate_exception(ctx, EXCP_RI);
5114
        return;
5115
    }
5116
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5117
               regnames[index], regnames[base]);
5118
}
5119

    
5120
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5121
                            int fr, int fs, int ft)
5122
{
5123
    const char *opn = "flt3_arith";
5124

    
5125
    /* All of those work only on 64bit FPUs. */
5126
    gen_op_cp1_64bitmode();
5127
    switch (opc) {
5128
    case OPC_ALNV_PS:
5129
        GEN_LOAD_REG_TN(T0, fr);
5130
        GEN_LOAD_FREG_FTN(DT0, fs);
5131
        GEN_LOAD_FREG_FTN(DT1, ft);
5132
        gen_op_float_alnv_ps();
5133
        GEN_STORE_FTN_FREG(fd, DT2);
5134
        opn = "alnv.ps";
5135
        break;
5136
    case OPC_MADD_S:
5137
        GEN_LOAD_FREG_FTN(WT0, fs);
5138
        GEN_LOAD_FREG_FTN(WT1, ft);
5139
        GEN_LOAD_FREG_FTN(WT2, fr);
5140
        gen_op_float_muladd_s();
5141
        GEN_STORE_FTN_FREG(fd, WT2);
5142
        opn = "madd.s";
5143
        break;
5144
    case OPC_MADD_D:
5145
        GEN_LOAD_FREG_FTN(DT0, fs);
5146
        GEN_LOAD_FREG_FTN(DT1, ft);
5147
        GEN_LOAD_FREG_FTN(DT2, fr);
5148
        gen_op_float_muladd_d();
5149
        GEN_STORE_FTN_FREG(fd, DT2);
5150
        opn = "madd.d";
5151
        break;
5152
    case OPC_MADD_PS:
5153
        GEN_LOAD_FREG_FTN(WT0, fs);
5154
        GEN_LOAD_FREG_FTN(WTH0, fs);
5155
        GEN_LOAD_FREG_FTN(WT1, ft);
5156
        GEN_LOAD_FREG_FTN(WTH1, ft);
5157
        GEN_LOAD_FREG_FTN(WT2, fr);
5158
        GEN_LOAD_FREG_FTN(WTH2, fr);
5159
        gen_op_float_muladd_ps();
5160
        GEN_STORE_FTN_FREG(fd, WT2);
5161
        GEN_STORE_FTN_FREG(fd, WTH2);
5162
        opn = "madd.ps";
5163
        break;
5164
    case OPC_MSUB_S:
5165
        GEN_LOAD_FREG_FTN(WT0, fs);
5166
        GEN_LOAD_FREG_FTN(WT1, ft);
5167
        GEN_LOAD_FREG_FTN(WT2, fr);
5168
        gen_op_float_mulsub_s();
5169
        GEN_STORE_FTN_FREG(fd, WT2);
5170
        opn = "msub.s";
5171
        break;
5172
    case OPC_MSUB_D:
5173
        GEN_LOAD_FREG_FTN(DT0, fs);
5174
        GEN_LOAD_FREG_FTN(DT1, ft);
5175
        GEN_LOAD_FREG_FTN(DT2, fr);
5176
        gen_op_float_mulsub_d();
5177
        GEN_STORE_FTN_FREG(fd, DT2);
5178
        opn = "msub.d";
5179
        break;
5180
    case OPC_MSUB_PS:
5181
        GEN_LOAD_FREG_FTN(WT0, fs);
5182
        GEN_LOAD_FREG_FTN(WTH0, fs);
5183
        GEN_LOAD_FREG_FTN(WT1, ft);
5184
        GEN_LOAD_FREG_FTN(WTH1, ft);
5185
        GEN_LOAD_FREG_FTN(WT2, fr);
5186
        GEN_LOAD_FREG_FTN(WTH2, fr);
5187
        gen_op_float_mulsub_ps();
5188
        GEN_STORE_FTN_FREG(fd, WT2);
5189
        GEN_STORE_FTN_FREG(fd, WTH2);
5190
        opn = "msub.ps";
5191
        break;
5192
    case OPC_NMADD_S:
5193
        GEN_LOAD_FREG_FTN(WT0, fs);
5194
        GEN_LOAD_FREG_FTN(WT1, ft);
5195
        GEN_LOAD_FREG_FTN(WT2, fr);
5196
        gen_op_float_nmuladd_s();
5197
        GEN_STORE_FTN_FREG(fd, WT2);
5198
        opn = "nmadd.s";
5199
        break;
5200
    case OPC_NMADD_D:
5201
        GEN_LOAD_FREG_FTN(DT0, fs);
5202
        GEN_LOAD_FREG_FTN(DT1, ft);
5203
        GEN_LOAD_FREG_FTN(DT2, fr);
5204
        gen_op_float_nmuladd_d();
5205
        GEN_STORE_FTN_FREG(fd, DT2);
5206
        opn = "nmadd.d";
5207
        break;
5208
    case OPC_NMADD_PS:
5209
        GEN_LOAD_FREG_FTN(WT0, fs);
5210
        GEN_LOAD_FREG_FTN(WTH0, fs);
5211
        GEN_LOAD_FREG_FTN(WT1, ft);
5212
        GEN_LOAD_FREG_FTN(WTH1, ft);
5213
        GEN_LOAD_FREG_FTN(WT2, fr);
5214
        GEN_LOAD_FREG_FTN(WTH2, fr);
5215
        gen_op_float_nmuladd_ps();
5216
        GEN_STORE_FTN_FREG(fd, WT2);
5217
        GEN_STORE_FTN_FREG(fd, WTH2);
5218
        opn = "nmadd.ps";
5219
        break;
5220
    case OPC_NMSUB_S:
5221
        GEN_LOAD_FREG_FTN(WT0, fs);
5222
        GEN_LOAD_FREG_FTN(WT1, ft);
5223
        GEN_LOAD_FREG_FTN(WT2, fr);
5224
        gen_op_float_nmulsub_s();
5225
        GEN_STORE_FTN_FREG(fd, WT2);
5226
        opn = "nmsub.s";
5227
        break;
5228
    case OPC_NMSUB_D:
5229
        GEN_LOAD_FREG_FTN(DT0, fs);
5230
        GEN_LOAD_FREG_FTN(DT1, ft);
5231
        GEN_LOAD_FREG_FTN(DT2, fr);
5232
        gen_op_float_nmulsub_d();
5233
        GEN_STORE_FTN_FREG(fd, DT2);
5234
        opn = "nmsub.d";
5235
        break;
5236
    case OPC_NMSUB_PS:
5237
        GEN_LOAD_FREG_FTN(WT0, fs);
5238
        GEN_LOAD_FREG_FTN(WTH0, fs);
5239
        GEN_LOAD_FREG_FTN(WT1, ft);
5240
        GEN_LOAD_FREG_FTN(WTH1, ft);
5241
        GEN_LOAD_FREG_FTN(WT2, fr);
5242
        GEN_LOAD_FREG_FTN(WTH2, fr);
5243
        gen_op_float_nmulsub_ps();
5244
        GEN_STORE_FTN_FREG(fd, WT2);
5245
        GEN_STORE_FTN_FREG(fd, WTH2);
5246
        opn = "nmsub.ps";
5247
        break;
5248
    default:
5249
        MIPS_INVAL(opn);
5250
        generate_exception (ctx, EXCP_RI);
5251
        return;
5252
    }
5253
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5254
               fregnames[fs], fregnames[ft]);
5255
}
5256

    
5257
/* ISA extensions (ASEs) */
5258
/* MIPS16 extension to MIPS32 */
5259
/* SmartMIPS extension to MIPS32 */
5260

    
5261
#ifdef TARGET_MIPS64
5262

    
5263
/* MDMX extension to MIPS64 */
5264
/* MIPS-3D extension to MIPS64 */
5265

    
5266
#endif
5267

    
5268
static void decode_opc (CPUState *env, DisasContext *ctx)
5269
{
5270
    int32_t offset;
5271
    int rs, rt, rd, sa;
5272
    uint32_t op, op1, op2;
5273
    int16_t imm;
5274

    
5275
    /* make sure instructions are on a word boundary */
5276
    if (ctx->pc & 0x3) {
5277
        env->CP0_BadVAddr = ctx->pc;
5278
        generate_exception(ctx, EXCP_AdEL);
5279
        return;
5280
    }
5281

    
5282
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5283
        int l1;
5284
        /* Handle blikely not taken case */
5285
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5286
        l1 = gen_new_label();
5287
        gen_op_jnz_T2(l1);
5288
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5289
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5290
        gen_set_label(l1);
5291
    }
5292
    op = MASK_OP_MAJOR(ctx->opcode);
5293
    rs = (ctx->opcode >> 21) & 0x1f;
5294
    rt = (ctx->opcode >> 16) & 0x1f;
5295
    rd = (ctx->opcode >> 11) & 0x1f;
5296
    sa = (ctx->opcode >> 6) & 0x1f;
5297
    imm = (int16_t)ctx->opcode;
5298
    switch (op) {
5299
    case OPC_SPECIAL:
5300
        op1 = MASK_SPECIAL(ctx->opcode);
5301
        switch (op1) {
5302
        case OPC_SLL:          /* Arithmetic with immediate */
5303
        case OPC_SRL ... OPC_SRA:
5304
            gen_arith_imm(ctx, op1, rd, rt, sa);
5305
            break;
5306
        case OPC_SLLV:         /* Arithmetic */
5307
        case OPC_SRLV ... OPC_SRAV:
5308
        case OPC_MOVZ ... OPC_MOVN:
5309
        case OPC_ADD ... OPC_NOR:
5310
        case OPC_SLT ... OPC_SLTU:
5311
            gen_arith(ctx, op1, rd, rs, rt);
5312
            break;
5313
        case OPC_MULT ... OPC_DIVU:
5314
            gen_muldiv(ctx, op1, rs, rt);
5315
            break;
5316
        case OPC_JR ... OPC_JALR:
5317
            gen_compute_branch(ctx, op1, rs, rd, sa);
5318
            return;
5319
        case OPC_TGE ... OPC_TEQ: /* Traps */
5320
        case OPC_TNE:
5321
            gen_trap(ctx, op1, rs, rt, -1);
5322
            break;
5323
        case OPC_MFHI:          /* Move from HI/LO */
5324
        case OPC_MFLO:
5325
            gen_HILO(ctx, op1, rd);
5326
            break;
5327
        case OPC_MTHI:
5328
        case OPC_MTLO:          /* Move to HI/LO */
5329
            gen_HILO(ctx, op1, rs);
5330
            break;
5331
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5332
#ifdef MIPS_STRICT_STANDARD
5333
            MIPS_INVAL("PMON / selsl");
5334
            generate_exception(ctx, EXCP_RI);
5335
#else
5336
            gen_op_pmon(sa);
5337
#endif
5338
            break;
5339
        case OPC_SYSCALL:
5340
            generate_exception(ctx, EXCP_SYSCALL);
5341
            break;
5342
        case OPC_BREAK:
5343
            /* XXX: Hack to work around wrong handling of self-modifying code. */
5344
            ctx->pc += 4;
5345
            save_cpu_state(ctx, 1);
5346
            ctx->pc -= 4;
5347
            generate_exception(ctx, EXCP_BREAK);
5348
            break;
5349
        case OPC_SPIM:
5350
#ifdef MIPS_STRICT_STANDARD
5351
            MIPS_INVAL("SPIM");
5352
            generate_exception(ctx, EXCP_RI);
5353
#else
5354
           /* Implemented as RI exception for now. */
5355
            MIPS_INVAL("spim (unofficial)");
5356
            generate_exception(ctx, EXCP_RI);
5357
#endif
5358
            break;
5359
        case OPC_SYNC:
5360
            /* Treat as a noop. */
5361
            break;
5362

    
5363
        case OPC_MOVCI:
5364
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5365
                save_cpu_state(ctx, 1);
5366
                gen_op_cp1_enabled();
5367
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5368
                          (ctx->opcode >> 16) & 1);
5369
            } else {
5370
                generate_exception_err(ctx, EXCP_CpU, 1);
5371
            }
5372
            break;
5373

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

    
5618
    /* Floating point (COP1). */
5619
    case OPC_LWC1:
5620
    case OPC_LDC1:
5621
    case OPC_SWC1:
5622
    case OPC_SDC1:
5623
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5624
            save_cpu_state(ctx, 1);
5625
            gen_op_cp1_enabled();
5626
            gen_flt_ldst(ctx, op, rt, rs, imm);
5627
        } else {
5628
            generate_exception_err(ctx, EXCP_CpU, 1);
5629
        }
5630
        break;
5631

    
5632
    case OPC_CP1:
5633
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5634
            save_cpu_state(ctx, 1);
5635
            gen_op_cp1_enabled();
5636
            op1 = MASK_CP1(ctx->opcode);
5637
            switch (op1) {
5638
            case OPC_MFC1:
5639
            case OPC_CFC1:
5640
            case OPC_MTC1:
5641
            case OPC_CTC1:
5642
#ifdef TARGET_MIPS64
5643
            case OPC_DMFC1:
5644
            case OPC_DMTC1:
5645
#endif
5646
            case OPC_MFHC1:
5647
            case OPC_MTHC1:
5648
                gen_cp1(ctx, op1, rt, rd);
5649
                break;
5650
            case OPC_BC1:
5651
            case OPC_BC1ANY2:
5652
            case OPC_BC1ANY4:
5653
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5654
                                    (rt >> 2) & 0x7, imm << 2);
5655
                return;
5656
            case OPC_S_FMT:
5657
            case OPC_D_FMT:
5658
            case OPC_W_FMT:
5659
            case OPC_L_FMT:
5660
            case OPC_PS_FMT:
5661
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5662
                           (imm >> 8) & 0x7);
5663
                break;
5664
            default:
5665
                MIPS_INVAL("cp1");
5666
                generate_exception (ctx, EXCP_RI);
5667
                break;
5668
            }
5669
        } else {
5670
            generate_exception_err(ctx, EXCP_CpU, 1);
5671
        }
5672
        break;
5673

    
5674
    /* COP2.  */
5675
    case OPC_LWC2:
5676
    case OPC_LDC2:
5677
    case OPC_SWC2:
5678
    case OPC_SDC2:
5679
    case OPC_CP2:
5680
        /* COP2: Not implemented. */
5681
        generate_exception_err(ctx, EXCP_CpU, 2);
5682
        break;
5683

    
5684
    case OPC_CP3:
5685
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5686
            save_cpu_state(ctx, 1);
5687
            gen_op_cp1_enabled();
5688
            op1 = MASK_CP3(ctx->opcode);
5689
            switch (op1) {
5690
            case OPC_LWXC1:
5691
            case OPC_LDXC1:
5692
            case OPC_LUXC1:
5693
            case OPC_SWXC1:
5694
            case OPC_SDXC1:
5695
            case OPC_SUXC1:
5696
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5697
                break;
5698
            case OPC_PREFX:
5699
                /* treat as noop */
5700
                break;
5701
            case OPC_ALNV_PS:
5702
            case OPC_MADD_S:
5703
            case OPC_MADD_D:
5704
            case OPC_MADD_PS:
5705
            case OPC_MSUB_S:
5706
            case OPC_MSUB_D:
5707
            case OPC_MSUB_PS:
5708
            case OPC_NMADD_S:
5709
            case OPC_NMADD_D:
5710
            case OPC_NMADD_PS:
5711
            case OPC_NMSUB_S:
5712
            case OPC_NMSUB_D:
5713
            case OPC_NMSUB_PS:
5714
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5715
                break;
5716
            default:
5717
                MIPS_INVAL("cp3");
5718
                generate_exception (ctx, EXCP_RI);
5719
                break;
5720
            }
5721
        } else {
5722
            generate_exception_err(ctx, EXCP_CpU, 1);
5723
        }
5724
        break;
5725

    
5726
#ifdef TARGET_MIPS64
5727
    /* MIPS64 opcodes */
5728
    case OPC_LWU:
5729
    case OPC_LDL ... OPC_LDR:
5730
    case OPC_SDL ... OPC_SDR:
5731
    case OPC_LLD:
5732
    case OPC_LD:
5733
    case OPC_SCD:
5734
    case OPC_SD:
5735
        gen_ldst(ctx, op, rt, rs, imm);
5736
        break;
5737
    case OPC_DADDI ... OPC_DADDIU:
5738
        gen_arith_imm(ctx, op, rt, rs, imm);
5739
        break;
5740
#endif
5741
#ifdef MIPS_HAS_MIPS16
5742
    case OPC_JALX:
5743
        /* MIPS16: Not implemented. */
5744
#endif
5745
#ifdef MIPS_HAS_MDMX
5746
    case OPC_MDMX:
5747
        /* MDMX: Not implemented. */
5748
#endif
5749
    default:            /* Invalid */
5750
        MIPS_INVAL("major opcode");
5751
        generate_exception(ctx, EXCP_RI);
5752
        break;
5753
    }
5754
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5755
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5756
        /* Branches completion */
5757
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5758
        ctx->bstate = BS_BRANCH;
5759
        save_cpu_state(ctx, 0);
5760
        switch (hflags) {
5761
        case MIPS_HFLAG_B:
5762
            /* unconditional branch */
5763
            MIPS_DEBUG("unconditional branch");
5764
            gen_goto_tb(ctx, 0, ctx->btarget);
5765
            break;
5766
        case MIPS_HFLAG_BL:
5767
            /* blikely taken case */
5768
            MIPS_DEBUG("blikely branch taken");
5769
            gen_goto_tb(ctx, 0, ctx->btarget);
5770
            break;
5771
        case MIPS_HFLAG_BC:
5772
            /* Conditional branch */
5773
            MIPS_DEBUG("conditional branch");
5774
            {
5775
              int l1;
5776
              l1 = gen_new_label();
5777
              gen_op_jnz_T2(l1);
5778
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5779
              gen_set_label(l1);
5780
              gen_goto_tb(ctx, 0, ctx->btarget);
5781
            }
5782
            break;
5783
        case MIPS_HFLAG_BR:
5784
            /* unconditional branch to register */
5785
            MIPS_DEBUG("branch to register");
5786
            gen_op_breg();
5787
            gen_op_reset_T0();
5788
            gen_op_exit_tb();
5789
            break;
5790
        default:
5791
            MIPS_DEBUG("unknown branch");
5792
            break;
5793
        }
5794
    }
5795
}
5796

    
5797
static inline int
5798
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5799
                                int search_pc)
5800
{
5801
    DisasContext ctx, *ctxp = &ctx;
5802
    target_ulong pc_start;
5803
    uint16_t *gen_opc_end;
5804
    int j, lj = -1;
5805

    
5806
    if (search_pc && loglevel)
5807
        fprintf (logfile, "search pc %d\n", search_pc);
5808

    
5809
    pc_start = tb->pc;
5810
    gen_opc_ptr = gen_opc_buf;
5811
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5812
    gen_opparam_ptr = gen_opparam_buf;
5813
    nb_gen_labels = 0;
5814
    ctx.pc = pc_start;
5815
    ctx.saved_pc = -1;
5816
    ctx.tb = tb;
5817
    ctx.bstate = BS_NONE;
5818
    /* Restore delay slot state from the tb context.  */
5819
    ctx.hflags = tb->flags;
5820
    restore_cpu_state(env, &ctx);
5821
#if defined(CONFIG_USER_ONLY)
5822
    ctx.mem_idx = 0;
5823
#else
5824
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5825
#endif
5826
#ifdef DEBUG_DISAS
5827
    if (loglevel & CPU_LOG_TB_CPU) {
5828
        fprintf(logfile, "------------------------------------------------\n");
5829
        /* FIXME: This may print out stale hflags from env... */
5830
        cpu_dump_state(env, logfile, fprintf, 0);
5831
    }
5832
#endif
5833
#ifdef MIPS_DEBUG_DISAS
5834
    if (loglevel & CPU_LOG_TB_IN_ASM)
5835
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5836
                tb, ctx.mem_idx, ctx.hflags);
5837
#endif
5838
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5839
        if (env->nb_breakpoints > 0) {
5840
            for(j = 0; j < env->nb_breakpoints; j++) {
5841
                if (env->breakpoints[j] == ctx.pc) {
5842
                    save_cpu_state(ctxp, 1);
5843
                    ctx.bstate = BS_BRANCH;
5844
                    gen_op_debug();
5845
                    goto done_generating;
5846
                }
5847
            }
5848
        }
5849

    
5850
        if (search_pc) {
5851
            j = gen_opc_ptr - gen_opc_buf;
5852
            if (lj < j) {
5853
                lj++;
5854
                while (lj < j)
5855
                    gen_opc_instr_start[lj++] = 0;
5856
            }
5857
            gen_opc_pc[lj] = ctx.pc;
5858
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5859
            gen_opc_instr_start[lj] = 1;
5860
        }
5861
        ctx.opcode = ldl_code(ctx.pc);
5862
        decode_opc(env, &ctx);
5863
        ctx.pc += 4;
5864

    
5865
        if (env->singlestep_enabled)
5866
            break;
5867

    
5868
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5869
            break;
5870

    
5871
#if defined (MIPS_SINGLE_STEP)
5872
        break;
5873
#endif
5874
    }
5875
    if (env->singlestep_enabled) {
5876
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5877
        gen_op_debug();
5878
    } else {
5879
        switch (ctx.bstate) {
5880
        case BS_STOP:
5881
            gen_op_interrupt_restart();
5882
            gen_goto_tb(&ctx, 0, ctx.pc);
5883
            break;
5884
        case BS_NONE:
5885
            save_cpu_state(ctxp, 0);
5886
            gen_goto_tb(&ctx, 0, ctx.pc);
5887
            break;
5888
        case BS_EXCP:
5889
            gen_op_interrupt_restart();
5890
            gen_op_reset_T0();
5891
            gen_op_exit_tb();
5892
            break;
5893
        case BS_BRANCH:
5894
        default:
5895
            break;
5896
        }
5897
    }
5898
done_generating:
5899
    *gen_opc_ptr = INDEX_op_end;
5900
    if (search_pc) {
5901
        j = gen_opc_ptr - gen_opc_buf;
5902
        lj++;
5903
        while (lj <= j)
5904
            gen_opc_instr_start[lj++] = 0;
5905
        tb->size = 0;
5906
    } else {
5907
        tb->size = ctx.pc - pc_start;
5908
    }
5909
#ifdef DEBUG_DISAS
5910
#if defined MIPS_DEBUG_DISAS
5911
    if (loglevel & CPU_LOG_TB_IN_ASM)
5912
        fprintf(logfile, "\n");
5913
#endif
5914
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5915
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5916
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5917
        fprintf(logfile, "\n");
5918
    }
5919
    if (loglevel & CPU_LOG_TB_OP) {
5920
        fprintf(logfile, "OP:\n");
5921
        dump_ops(gen_opc_buf, gen_opparam_buf);
5922
        fprintf(logfile, "\n");
5923
    }
5924
    if (loglevel & CPU_LOG_TB_CPU) {
5925
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5926
    }
5927
#endif
5928
    
5929
    return 0;
5930
}
5931

    
5932
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5933
{
5934
    return gen_intermediate_code_internal(env, tb, 0);
5935
}
5936

    
5937
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5938
{
5939
    return gen_intermediate_code_internal(env, tb, 1);
5940
}
5941

    
5942
void fpu_dump_state(CPUState *env, FILE *f, 
5943
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5944
                    int flags)
5945
{
5946
    int i;
5947
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5948

    
5949
#define printfpr(fp)                                                        \
5950
    do {                                                                    \
5951
        if (is_fpu64)                                                       \
5952
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5953
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5954
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5955
        else {                                                              \
5956
            fpr_t tmp;                                                      \
5957
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
5958
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
5959
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
5960
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
5961
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
5962
        }                                                                   \
5963
    } while(0)
5964

    
5965

    
5966
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
5967
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
5968
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5969
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5970
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5971
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
5972
        fpu_fprintf(f, "%3s: ", fregnames[i]);
5973
        printfpr(&env->fpr[i]);
5974
    }
5975

    
5976
#undef printfpr
5977
}
5978

    
5979
void dump_fpu (CPUState *env)
5980
{
5981
    if (loglevel) { 
5982
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5983
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5984
       fpu_dump_state(env, logfile, fprintf, 0);
5985
    }
5986
}
5987

    
5988
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5989
/* Debug help: The architecture requires 32bit code to maintain proper
5990
   sign-extened values on 64bit machines.  */
5991

    
5992
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5993

    
5994
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5995
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5996
                     int flags)
5997
{
5998
    int i;
5999

    
6000
    if (!SIGN_EXT_P(env->PC))
6001
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6002
    if (!SIGN_EXT_P(env->HI))
6003
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6004
    if (!SIGN_EXT_P(env->LO))
6005
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6006
    if (!SIGN_EXT_P(env->btarget))
6007
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6008

    
6009
    for (i = 0; i < 32; i++) {
6010
        if (!SIGN_EXT_P(env->gpr[i]))
6011
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6012
    }
6013

    
6014
    if (!SIGN_EXT_P(env->CP0_EPC))
6015
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6016
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6017
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6018
}
6019
#endif
6020

    
6021
void cpu_dump_state (CPUState *env, FILE *f, 
6022
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6023
                     int flags)
6024
{
6025
    uint32_t c0_status;
6026
    int i;
6027
    
6028
    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",
6029
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6030
    for (i = 0; i < 32; i++) {
6031
        if ((i & 3) == 0)
6032
            cpu_fprintf(f, "GPR%02d:", i);
6033
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6034
        if ((i & 3) == 3)
6035
            cpu_fprintf(f, "\n");
6036
    }
6037

    
6038
    c0_status = env->CP0_Status;
6039

    
6040
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6041
                c0_status, env->CP0_Cause, env->CP0_EPC);
6042
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6043
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6044
    if (c0_status & (1 << CP0St_CU1))
6045
        fpu_dump_state(env, f, cpu_fprintf, flags);
6046
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6047
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6048
#endif
6049
}
6050

    
6051
CPUMIPSState *cpu_mips_init (void)
6052
{
6053
    CPUMIPSState *env;
6054

    
6055
    env = qemu_mallocz(sizeof(CPUMIPSState));
6056
    if (!env)
6057
        return NULL;
6058
    cpu_exec_init(env);
6059
    cpu_reset(env);
6060
    return env;
6061
}
6062

    
6063
void cpu_reset (CPUMIPSState *env)
6064
{
6065
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6066

    
6067
    tlb_flush(env, 1);
6068

    
6069
    /* Minimal init */
6070
#if !defined(CONFIG_USER_ONLY)
6071
    if (env->hflags & MIPS_HFLAG_BMASK) {
6072
        /* If the exception was raised from a delay slot,
6073
         * come back to the jump.  */
6074
        env->CP0_ErrorEPC = env->PC - 4;
6075
        env->hflags &= ~MIPS_HFLAG_BMASK;
6076
    } else {
6077
        env->CP0_ErrorEPC = env->PC;
6078
    }
6079
    env->hflags = 0;
6080
    env->PC = (int32_t)0xBFC00000;
6081
    env->CP0_Wired = 0;
6082
    /* SMP not implemented */
6083
    env->CP0_EBase = 0x80000000;
6084
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6085
    /* vectored interrupts not implemented, timer on int 7,
6086
       no performance counters. */
6087
    env->CP0_IntCtl = 0xe0000000;
6088
    {
6089
        int i;
6090

    
6091
        for (i = 0; i < 7; i++) {
6092
            env->CP0_WatchLo[i] = 0;
6093
            env->CP0_WatchHi[i] = 0x80000000;
6094
        }
6095
        env->CP0_WatchLo[7] = 0;
6096
        env->CP0_WatchHi[7] = 0;
6097
    }
6098
    /* Count register increments in debug mode, EJTAG version 1 */
6099
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6100
#endif
6101
    env->exception_index = EXCP_NONE;
6102
#if defined(CONFIG_USER_ONLY)
6103
    env->hflags |= MIPS_HFLAG_UM;
6104
    env->user_mode_only = 1;
6105
#endif
6106
}
6107

    
6108
#include "translate_init.c"