Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 29929e34

History | View | Annotate | Download (163.9 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4261
/* CP1 Branches (before delay slot) */
4262
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4263
                                 int32_t cc, int32_t offset)
4264
{
4265
    target_ulong btarget;
4266
    const char *opn = "cp1 cond branch";
4267

    
4268
    btarget = ctx->pc + 4 + offset;
4269

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

    
4320
/* Coprocessor 1 (FPU) */
4321

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

    
4343
#define FOP(func, fmt) (((fmt) << 21) | (func))
4344

    
4345
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4346
{
4347
    const char *opn = "cp1 move";
4348

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

    
4408
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4409
{
4410
    uint32_t ccbit;
4411

    
4412
    GEN_LOAD_REG_TN(T0, rd);
4413
    GEN_LOAD_REG_TN(T1, rs);
4414
    if (cc)
4415
        ccbit = 1 << (24 + cc);
4416
    else
4417
        ccbit = 1 << 23;
4418
    if (!tf)
4419
        gen_op_movf(ccbit);
4420
    else
4421
        gen_op_movt(ccbit);
4422
    GEN_STORE_TN_REG(rd, T0);
4423
}
4424

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

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

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

    
5109
/* Coprocessor 3 (FPU) */
5110
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5111
                           int base, int index)
5112
{
5113
    const char *opn = "extended float load/store";
5114

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

    
5159
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5160
                            int fr, int fs, int ft)
5161
{
5162
    const char *opn = "flt3_arith";
5163

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

    
5296
/* ISA extensions (ASEs) */
5297
/* MIPS16 extension to MIPS32 */
5298
/* SmartMIPS extension to MIPS32 */
5299

    
5300
#ifdef TARGET_MIPS64
5301

    
5302
/* MDMX extension to MIPS64 */
5303
/* MIPS-3D extension to MIPS64 */
5304

    
5305
#endif
5306

    
5307
static void decode_opc (CPUState *env, DisasContext *ctx)
5308
{
5309
    int32_t offset;
5310
    int rs, rt, rd, sa;
5311
    uint32_t op, op1, op2;
5312
    int16_t imm;
5313

    
5314
    /* make sure instructions are on a word boundary */
5315
    if (ctx->pc & 0x3) {
5316
        env->CP0_BadVAddr = ctx->pc;
5317
        generate_exception(ctx, EXCP_AdEL);
5318
        return;
5319
    }
5320

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

    
5398
        case OPC_MOVCI:
5399
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5400
                save_cpu_state(ctx, 1);
5401
                gen_op_cp1_enabled();
5402
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5403
                          (ctx->opcode >> 16) & 1);
5404
            } else {
5405
                generate_exception_err(ctx, EXCP_CpU, 1);
5406
            }
5407
            break;
5408

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

    
5653
    /* Floating point (COP1). */
5654
    case OPC_LWC1:
5655
    case OPC_LDC1:
5656
    case OPC_SWC1:
5657
    case OPC_SDC1:
5658
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5659
            save_cpu_state(ctx, 1);
5660
            gen_op_cp1_enabled();
5661
            gen_flt_ldst(ctx, op, rt, rs, imm);
5662
        } else {
5663
            generate_exception_err(ctx, EXCP_CpU, 1);
5664
        }
5665
        break;
5666

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

    
5709
    /* COP2.  */
5710
    case OPC_LWC2:
5711
    case OPC_LDC2:
5712
    case OPC_SWC2:
5713
    case OPC_SDC2:
5714
    case OPC_CP2:
5715
        /* COP2: Not implemented. */
5716
        generate_exception_err(ctx, EXCP_CpU, 2);
5717
        break;
5718

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

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

    
5832
static inline int
5833
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5834
                                int search_pc)
5835
{
5836
    DisasContext ctx, *ctxp = &ctx;
5837
    target_ulong pc_start;
5838
    uint16_t *gen_opc_end;
5839
    int j, lj = -1;
5840

    
5841
    if (search_pc && loglevel)
5842
        fprintf (logfile, "search pc %d\n", search_pc);
5843

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

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

    
5914
        if (env->singlestep_enabled)
5915
            break;
5916

    
5917
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5918
            break;
5919

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

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

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

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

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

    
6013

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

    
6024
#undef printfpr
6025
}
6026

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

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

    
6040
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6041

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

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

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

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

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

    
6086
    c0_status = env->CP0_Status;
6087

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

    
6099
CPUMIPSState *cpu_mips_init (void)
6100
{
6101
    CPUMIPSState *env;
6102

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

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

    
6115
    tlb_flush(env, 1);
6116

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

    
6148
#include "translate_init.c"