Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (163.6 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4283
    btarget = ctx->pc + 4 + offset;
4284

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

    
4335
/* Coprocessor 1 (FPU) */
4336

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5294
#ifdef TARGET_MIPS64
5295

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

    
5299
#endif
5300

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5912
        if (env->singlestep_enabled)
5913
            break;
5914

    
5915
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5916
            break;
5917

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

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

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

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

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

    
6011

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

    
6022
#undef printfpr
6023
}
6024

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

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

    
6038
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6039

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

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

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

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

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

    
6084
    c0_status = env->CP0_Status;
6085

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

    
6097
CPUMIPSState *cpu_mips_init (void)
6098
{
6099
    CPUMIPSState *env;
6100

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

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

    
6113
    tlb_flush(env, 1);
6114

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

    
6146
#include "translate_init.c"