Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 5a1e8ffb

History | View | Annotate | Download (163.7 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 * cond ## 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
    cond ## 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, saved_fp_status;
529
    /* Routine used to access memory */
530
    int mem_idx;
531
    uint32_t hflags, saved_hflags;
532
    uint32_t CP0_Status;
533
    int bstate;
534
    target_ulong btarget;
535
} DisasContext;
536

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

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

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

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

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

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

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

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

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

    
631
static inline void save_fpu_state (DisasContext *ctx)
632
{
633
    if (ctx->fp_status != ctx->saved_fp_status) {
634
        gen_op_save_fp_status(ctx->fp_status);
635
        ctx->saved_fp_status = ctx->fp_status;
636
    }
637
}
638

    
639
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
640
{
641
#if defined MIPS_DEBUG_DISAS
642
    if (loglevel & CPU_LOG_TB_IN_ASM)
643
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
644
#endif
645
    save_cpu_state(ctx, 1);
646
    if (err == 0)
647
        gen_op_raise_exception(excp);
648
    else
649
        gen_op_raise_exception_err(excp, err);
650
    ctx->bstate = BS_EXCP;
651
}
652

    
653
static inline void generate_exception (DisasContext *ctx, int excp)
654
{
655
    generate_exception_err (ctx, excp, 0);
656
}
657

    
658
#if defined(CONFIG_USER_ONLY)
659
#define op_ldst(name)        gen_op_##name##_raw()
660
#define OP_LD_TABLE(width)
661
#define OP_ST_TABLE(width)
662
#else
663
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
664
#define OP_LD_TABLE(width)                                                    \
665
static GenOpFunc *gen_op_l##width[] = {                                       \
666
    &gen_op_l##width##_user,                                                  \
667
    &gen_op_l##width##_kernel,                                                \
668
}
669
#define OP_ST_TABLE(width)                                                    \
670
static GenOpFunc *gen_op_s##width[] = {                                       \
671
    &gen_op_s##width##_user,                                                  \
672
    &gen_op_s##width##_kernel,                                                \
673
}
674
#endif
675

    
676
#ifdef TARGET_MIPS64
677
OP_LD_TABLE(d);
678
OP_LD_TABLE(dl);
679
OP_LD_TABLE(dr);
680
OP_ST_TABLE(d);
681
OP_ST_TABLE(dl);
682
OP_ST_TABLE(dr);
683
OP_LD_TABLE(ld);
684
OP_ST_TABLE(cd);
685
#endif
686
OP_LD_TABLE(w);
687
OP_LD_TABLE(wu);
688
OP_LD_TABLE(wl);
689
OP_LD_TABLE(wr);
690
OP_ST_TABLE(w);
691
OP_ST_TABLE(wl);
692
OP_ST_TABLE(wr);
693
OP_LD_TABLE(h);
694
OP_LD_TABLE(hu);
695
OP_ST_TABLE(h);
696
OP_LD_TABLE(b);
697
OP_LD_TABLE(bu);
698
OP_ST_TABLE(b);
699
OP_LD_TABLE(l);
700
OP_ST_TABLE(c);
701
OP_LD_TABLE(wc1);
702
OP_ST_TABLE(wc1);
703
OP_LD_TABLE(dc1);
704
OP_ST_TABLE(dc1);
705
OP_LD_TABLE(wxc1);
706
OP_ST_TABLE(wxc1);
707
OP_LD_TABLE(dxc1);
708
OP_ST_TABLE(dxc1);
709
OP_LD_TABLE(uxc1);
710
OP_ST_TABLE(uxc1);
711

    
712
/* Load and store */
713
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
714
                      int base, int16_t offset)
715
{
716
    const char *opn = "ldst";
717

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

    
862
/* Load and store */
863
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
864
                      int base, int16_t offset)
865
{
866
    const char *opn = "flt_ldst";
867

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

    
909
/* Arithmetic with immediate operand */
910
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
911
                           int rs, int16_t imm)
912
{
913
    uint32_t uimm;
914
    const char *opn = "imm arith";
915

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

    
1087
/* Arithmetic */
1088
static void gen_arith (DisasContext *ctx, uint32_t opc,
1089
                       int rd, int rs, int rt)
1090
{
1091
    const char *opn = "arith";
1092

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

    
1238
/* Arithmetic on HI/LO registers */
1239
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1240
{
1241
    const char *opn = "hilo";
1242

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

    
1277
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1278
                        int rs, int rt)
1279
{
1280
    const char *opn = "mul/div";
1281

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

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

    
1381
/* Traps */
1382
static void gen_trap (DisasContext *ctx, uint32_t opc,
1383
                      int rs, int rt, int16_t imm)
1384
{
1385
    int cond;
1386

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

    
1478
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1479
{
1480
    TranslationBlock *tb;
1481
    tb = ctx->tb;
1482
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1483
        if (n == 0)
1484
            gen_op_goto_tb0(TBPARAM(tb));
1485
        else
1486
            gen_op_goto_tb1(TBPARAM(tb));
1487
        gen_op_save_pc(dest);
1488
        gen_op_set_T0((long)tb + n);
1489
    } else {
1490
        gen_op_save_pc(dest);
1491
        gen_op_reset_T0();
1492
    }
1493
    gen_op_exit_tb();
1494
}
1495

    
1496
/* Branches (before delay slot) */
1497
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1498
                                int rs, int rt, int32_t offset)
1499
{
1500
    target_ulong btarget = -1;
1501
    int blink = 0;
1502
    int bcond = 0;
1503

    
1504
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1505
#ifdef MIPS_DEBUG_DISAS
1506
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1507
            fprintf(logfile,
1508
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1509
                    ctx->pc);
1510
        }
1511
#endif
1512
        generate_exception(ctx, EXCP_RI);
1513
        return;
1514
    }
1515

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

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

    
1792
/* CP0 (MMU and control) */
1793
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1794
{
1795
    const char *rn = "invalid";
1796

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

    
2374
die:
2375
#if defined MIPS_DEBUG_DISAS
2376
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2377
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2378
                rn, reg, sel);
2379
    }
2380
#endif
2381
    generate_exception(ctx, EXCP_RI);
2382
}
2383

    
2384
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2385
{
2386
    const char *rn = "invalid";
2387

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

    
2978
die:
2979
#if defined MIPS_DEBUG_DISAS
2980
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2981
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2982
                rn, reg, sel);
2983
    }
2984
#endif
2985
    generate_exception(ctx, EXCP_RI);
2986
}
2987

    
2988
#ifdef TARGET_MIPS64
2989
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2990
{
2991
    const char *rn = "invalid";
2992

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

    
3561
die:
3562
#if defined MIPS_DEBUG_DISAS
3563
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3564
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3565
                rn, reg, sel);
3566
    }
3567
#endif
3568
    generate_exception(ctx, EXCP_RI);
3569
}
3570

    
3571
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3572
{
3573
    const char *rn = "invalid";
3574

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

    
4156
die:
4157
#if defined MIPS_DEBUG_DISAS
4158
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4159
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4160
                rn, reg, sel);
4161
    }
4162
#endif
4163
    generate_exception(ctx, EXCP_RI);
4164
}
4165
#endif /* TARGET_MIPS64 */
4166

    
4167
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4168
{
4169
    const char *opn = "ldst";
4170

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

    
4254
/* CP1 Branches (before delay slot) */
4255
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4256
                                 int32_t cc, int32_t offset)
4257
{
4258
    target_ulong btarget;
4259
    const char *opn = "cp1 cond branch";
4260

    
4261
    btarget = ctx->pc + 4 + offset;
4262

    
4263
    switch (op) {
4264
    case OPC_BC1F:
4265
        gen_op_bc1f(cc);
4266
        opn = "bc1f";
4267
        goto not_likely;
4268
    case OPC_BC1FL:
4269
        gen_op_bc1f(cc);
4270
        opn = "bc1fl";
4271
        goto likely;
4272
    case OPC_BC1T:
4273
        gen_op_bc1t(cc);
4274
        opn = "bc1t";
4275
        goto not_likely;
4276
    case OPC_BC1TL:
4277
        gen_op_bc1t(cc);
4278
        opn = "bc1tl";
4279
    likely:
4280
        ctx->hflags |= MIPS_HFLAG_BL;
4281
        gen_op_set_bcond();
4282
        gen_op_save_bcond();
4283
        break;
4284
    case OPC_BC1FANY2:
4285
        gen_op_bc1fany2(cc);
4286
        opn = "bc1fany2";
4287
        goto not_likely;
4288
    case OPC_BC1TANY2:
4289
        gen_op_bc1tany2(cc);
4290
        opn = "bc1tany2";
4291
        goto not_likely;
4292
    case OPC_BC1FANY4:
4293
        gen_op_bc1fany4(cc);
4294
        opn = "bc1fany4";
4295
        goto not_likely;
4296
    case OPC_BC1TANY4:
4297
        gen_op_bc1tany4(cc);
4298
        opn = "bc1tany4";
4299
    not_likely:
4300
        ctx->hflags |= MIPS_HFLAG_BC;
4301
        gen_op_set_bcond();
4302
        break;
4303
    default:
4304
        MIPS_INVAL(opn);
4305
        generate_exception (ctx, EXCP_RI);
4306
        return;
4307
    }
4308
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4309
               ctx->hflags, btarget);
4310
    ctx->btarget = btarget;
4311
}
4312

    
4313
/* Coprocessor 1 (FPU) */
4314

    
4315
/* verify if floating point register is valid; an operation is not defined
4316
 * if bit 0 of any register specification is set and the FR bit in the
4317
 * Status register equals zero, since the register numbers specify an
4318
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4319
 * in the Status register equals one, both even and odd register numbers
4320
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
4321
 * 
4322
 * Multiple 64 bit wide registers can be checked by calling
4323
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4324
 * 
4325
 * FIXME: This is broken for R2, it needs to be checked at runtime, not
4326
 * at translation time.
4327
 */
4328
#define CHECK_FR(ctx, freg) do {                                      \
4329
        if (!((ctx)->CP0_Status & (1 << CP0St_FR)) && ((freg) & 1)) { \
4330
            MIPS_INVAL("FPU mode");                                   \
4331
            generate_exception (ctx, EXCP_RI);                        \
4332
            return;                                                   \
4333
        }                                                             \
4334
    } while(0)
4335

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5293
#ifdef TARGET_MIPS64
5294

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

    
5298
#endif
5299

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

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

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

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

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

    
5646
    /* Floating point (COP1). */
5647
    case OPC_LWC1:
5648
    case OPC_LDC1:
5649
    case OPC_SWC1:
5650
    case OPC_SDC1:
5651
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5652
            save_cpu_state(ctx, 1);
5653
            gen_op_cp1_enabled();
5654
            gen_flt_ldst(ctx, op, rt, rs, imm);
5655
        } else {
5656
            generate_exception_err(ctx, EXCP_CpU, 1);
5657
        }
5658
        break;
5659

    
5660
    case OPC_CP1:
5661
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5662
            save_cpu_state(ctx, 1);
5663
            gen_op_cp1_enabled();
5664
            op1 = MASK_CP1(ctx->opcode);
5665
            switch (op1) {
5666
            case OPC_MFC1:
5667
            case OPC_CFC1:
5668
            case OPC_MTC1:
5669
            case OPC_CTC1:
5670
#ifdef TARGET_MIPS64
5671
            case OPC_DMFC1:
5672
            case OPC_DMTC1:
5673
#endif
5674
            case OPC_MFHC1:
5675
            case OPC_MTHC1:
5676
                gen_cp1(ctx, op1, rt, rd);
5677
                break;
5678
            case OPC_BC1:
5679
            case OPC_BC1ANY2:
5680
            case OPC_BC1ANY4:
5681
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5682
                                    (rt >> 2) & 0x7, imm << 2);
5683
                return;
5684
            case OPC_S_FMT:
5685
            case OPC_D_FMT:
5686
            case OPC_W_FMT:
5687
            case OPC_L_FMT:
5688
            case OPC_PS_FMT:
5689
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5690
                           (imm >> 8) & 0x7);
5691
                break;
5692
            default:
5693
                MIPS_INVAL("cp1");
5694
                generate_exception (ctx, EXCP_RI);
5695
                break;
5696
            }
5697
        } else {
5698
            generate_exception_err(ctx, EXCP_CpU, 1);
5699
        }
5700
        break;
5701

    
5702
    /* COP2.  */
5703
    case OPC_LWC2:
5704
    case OPC_LDC2:
5705
    case OPC_SWC2:
5706
    case OPC_SDC2:
5707
    case OPC_CP2:
5708
        /* COP2: Not implemented. */
5709
        generate_exception_err(ctx, EXCP_CpU, 2);
5710
        break;
5711

    
5712
    case OPC_CP3:
5713
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5714
            save_cpu_state(ctx, 1);
5715
            gen_op_cp1_enabled();
5716
            op1 = MASK_CP3(ctx->opcode);
5717
            switch (op1) {
5718
            case OPC_LWXC1:
5719
            case OPC_LDXC1:
5720
            case OPC_LUXC1:
5721
            case OPC_SWXC1:
5722
            case OPC_SDXC1:
5723
            case OPC_SUXC1:
5724
                gen_flt3_ldst(ctx, op1, sa, rs, rt);
5725
                break;
5726
            case OPC_PREFX:
5727
                /* treat as noop */
5728
                break;
5729
            case OPC_ALNV_PS:
5730
            case OPC_MADD_S:
5731
            case OPC_MADD_D:
5732
            case OPC_MADD_PS:
5733
            case OPC_MSUB_S:
5734
            case OPC_MSUB_D:
5735
            case OPC_MSUB_PS:
5736
            case OPC_NMADD_S:
5737
            case OPC_NMADD_D:
5738
            case OPC_NMADD_PS:
5739
            case OPC_NMSUB_S:
5740
            case OPC_NMSUB_D:
5741
            case OPC_NMSUB_PS:
5742
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5743
                break;
5744
            default:
5745
                MIPS_INVAL("cp3");
5746
                generate_exception (ctx, EXCP_RI);
5747
                break;
5748
            }
5749
        } else {
5750
            generate_exception_err(ctx, EXCP_CpU, 1);
5751
        }
5752
        break;
5753

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

    
5825
static inline int
5826
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5827
                                int search_pc)
5828
{
5829
    DisasContext ctx, *ctxp = &ctx;
5830
    target_ulong pc_start;
5831
    uint16_t *gen_opc_end;
5832
    int j, lj = -1;
5833

    
5834
    if (search_pc && loglevel)
5835
        fprintf (logfile, "search pc %d\n", search_pc);
5836

    
5837
    pc_start = tb->pc;
5838
    gen_opc_ptr = gen_opc_buf;
5839
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5840
    gen_opparam_ptr = gen_opparam_buf;
5841
    nb_gen_labels = 0;
5842
    ctx.pc = pc_start;
5843
    ctx.saved_pc = -1;
5844
    ctx.tb = tb;
5845
    ctx.bstate = BS_NONE;
5846
    /* Restore delay slot state from the tb context.  */
5847
    ctx.hflags = tb->flags;
5848
    ctx.saved_hflags = ctx.hflags;
5849
    switch (ctx.hflags & MIPS_HFLAG_BMASK) {
5850
    case MIPS_HFLAG_BR:
5851
        gen_op_restore_breg_target();
5852
        break;
5853
    case MIPS_HFLAG_B:
5854
        ctx.btarget = env->btarget;
5855
        break;
5856
    case MIPS_HFLAG_BC:
5857
    case MIPS_HFLAG_BL:
5858
        ctx.btarget = env->btarget;
5859
        gen_op_restore_bcond();
5860
        break;
5861
    }
5862
#if defined(CONFIG_USER_ONLY)
5863
    ctx.mem_idx = 0;
5864
#else
5865
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5866
#endif
5867
    ctx.CP0_Status = env->CP0_Status;
5868
#ifdef DEBUG_DISAS
5869
    if (loglevel & CPU_LOG_TB_CPU) {
5870
        fprintf(logfile, "------------------------------------------------\n");
5871
        /* FIXME: This may print out stale hflags from env... */
5872
        cpu_dump_state(env, logfile, fprintf, 0);
5873
    }
5874
#endif
5875
#ifdef MIPS_DEBUG_DISAS
5876
    if (loglevel & CPU_LOG_TB_IN_ASM)
5877
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5878
                tb, ctx.mem_idx, ctx.hflags);
5879
#endif
5880
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5881
        if (env->nb_breakpoints > 0) {
5882
            for(j = 0; j < env->nb_breakpoints; j++) {
5883
                if (env->breakpoints[j] == ctx.pc) {
5884
                    save_cpu_state(ctxp, 1);
5885
                    ctx.bstate = BS_BRANCH;
5886
                    gen_op_debug();
5887
                    goto done_generating;
5888
                }
5889
            }
5890
        }
5891

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

    
5907
        if (env->singlestep_enabled)
5908
            break;
5909

    
5910
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5911
            break;
5912

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

    
5973
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5974
{
5975
    return gen_intermediate_code_internal(env, tb, 0);
5976
}
5977

    
5978
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5979
{
5980
    return gen_intermediate_code_internal(env, tb, 1);
5981
}
5982

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

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

    
6006

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

    
6017
#undef printfpr
6018
}
6019

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

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

    
6033
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6034

    
6035
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6036
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6037
                     int flags)
6038
{
6039
    int i;
6040

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

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

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

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

    
6079
    c0_status = env->CP0_Status;
6080

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

    
6092
CPUMIPSState *cpu_mips_init (void)
6093
{
6094
    CPUMIPSState *env;
6095

    
6096
    env = qemu_mallocz(sizeof(CPUMIPSState));
6097
    if (!env)
6098
        return NULL;
6099
    cpu_exec_init(env);
6100
    cpu_reset(env);
6101
    return env;
6102
}
6103

    
6104
void cpu_reset (CPUMIPSState *env)
6105
{
6106
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6107

    
6108
    tlb_flush(env, 1);
6109

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

    
6141
#include "translate_init.c"