Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 278d0702

History | View | Annotate | Download (165 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
572
#ifdef TARGET_MIPS64
573
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
574
do {                                                                          \
575
    if (Imm == 0) {                                                           \
576
        glue(gen_op_reset_, Tn)();                                            \
577
    } else if ((int32_t)Imm == Imm) {                                         \
578
        glue(gen_op_set_, Tn)(Imm);                                           \
579
    } else {                                                                  \
580
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
581
    }                                                                         \
582
} while (0)
583
#else
584
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
585
do {                                                                          \
586
    if (Imm == 0) {                                                           \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_set_, Tn)(Imm);                                           \
590
    }                                                                         \
591
} while (0)
592
#endif
593

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

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

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

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

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

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

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

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

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

    
706
static inline void check_cp1_enabled(DisasContext *ctx)
707
{
708
    if (!(ctx->hflags & MIPS_HFLAG_FPU))
709
        generate_exception_err(ctx, EXCP_CpU, 1);
710
}
711

    
712
static inline void check_cp1_64bitmode(DisasContext *ctx)
713
{
714
    if (!(ctx->hflags & MIPS_HFLAG_F64))
715
        generate_exception(ctx, EXCP_RI);
716
}
717

    
718
/*
719
 * Verify if floating point register is valid; an operation is not defined
720
 * if bit 0 of any register specification is set and the FR bit in the
721
 * Status register equals zero, since the register numbers specify an
722
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
723
 * in the Status register equals one, both even and odd register numbers
724
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
725
 *
726
 * Multiple 64 bit wide registers can be checked by calling
727
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
728
 */
729
void check_cp1_registers(DisasContext *ctx, int regs)
730
{
731
    if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))
732
        generate_exception(ctx, EXCP_RI);
733
}
734

    
735
#if defined(CONFIG_USER_ONLY)
736
#define op_ldst(name)        gen_op_##name##_raw()
737
#define OP_LD_TABLE(width)
738
#define OP_ST_TABLE(width)
739
#else
740
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
741
#define OP_LD_TABLE(width)                                                    \
742
static GenOpFunc *gen_op_l##width[] = {                                       \
743
    &gen_op_l##width##_user,                                                  \
744
    &gen_op_l##width##_kernel,                                                \
745
}
746
#define OP_ST_TABLE(width)                                                    \
747
static GenOpFunc *gen_op_s##width[] = {                                       \
748
    &gen_op_s##width##_user,                                                  \
749
    &gen_op_s##width##_kernel,                                                \
750
}
751
#endif
752

    
753
#ifdef TARGET_MIPS64
754
OP_LD_TABLE(d);
755
OP_LD_TABLE(dl);
756
OP_LD_TABLE(dr);
757
OP_ST_TABLE(d);
758
OP_ST_TABLE(dl);
759
OP_ST_TABLE(dr);
760
OP_LD_TABLE(ld);
761
OP_ST_TABLE(cd);
762
OP_LD_TABLE(wu);
763
#endif
764
OP_LD_TABLE(w);
765
OP_LD_TABLE(wl);
766
OP_LD_TABLE(wr);
767
OP_ST_TABLE(w);
768
OP_ST_TABLE(wl);
769
OP_ST_TABLE(wr);
770
OP_LD_TABLE(h);
771
OP_LD_TABLE(hu);
772
OP_ST_TABLE(h);
773
OP_LD_TABLE(b);
774
OP_LD_TABLE(bu);
775
OP_ST_TABLE(b);
776
OP_LD_TABLE(l);
777
OP_ST_TABLE(c);
778
OP_LD_TABLE(wc1);
779
OP_ST_TABLE(wc1);
780
OP_LD_TABLE(dc1);
781
OP_ST_TABLE(dc1);
782
OP_LD_TABLE(uxc1);
783
OP_ST_TABLE(uxc1);
784

    
785
/* Load and store */
786
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
787
                      int base, int16_t offset)
788
{
789
    const char *opn = "ldst";
790

    
791
    if (base == 0) {
792
        GEN_LOAD_IMM_TN(T0, offset);
793
    } else if (offset == 0) {
794
        gen_op_load_gpr_T0(base);
795
    } else {
796
        gen_op_load_gpr_T0(base);
797
        gen_op_set_T1(offset);
798
        gen_op_addr_add();
799
    }
800
    /* Don't do NOP if destination is zero: we must perform the actual
801
     * memory access
802
     */
803
    switch (opc) {
804
#ifdef TARGET_MIPS64
805
    case OPC_LWU:
806
        op_ldst(lwu);
807
        GEN_STORE_TN_REG(rt, T0);
808
        opn = "lwu";
809
        break;
810
    case OPC_LD:
811
        op_ldst(ld);
812
        GEN_STORE_TN_REG(rt, T0);
813
        opn = "ld";
814
        break;
815
    case OPC_LLD:
816
        op_ldst(lld);
817
        GEN_STORE_TN_REG(rt, T0);
818
        opn = "lld";
819
        break;
820
    case OPC_SD:
821
        GEN_LOAD_REG_TN(T1, rt);
822
        op_ldst(sd);
823
        opn = "sd";
824
        break;
825
    case OPC_SCD:
826
        save_cpu_state(ctx, 1);
827
        GEN_LOAD_REG_TN(T1, rt);
828
        op_ldst(scd);
829
        GEN_STORE_TN_REG(rt, T0);
830
        opn = "scd";
831
        break;
832
    case OPC_LDL:
833
        GEN_LOAD_REG_TN(T1, rt);
834
        op_ldst(ldl);
835
        GEN_STORE_TN_REG(rt, T0);
836
        opn = "ldl";
837
        break;
838
    case OPC_SDL:
839
        GEN_LOAD_REG_TN(T1, rt);
840
        op_ldst(sdl);
841
        opn = "sdl";
842
        break;
843
    case OPC_LDR:
844
        GEN_LOAD_REG_TN(T1, rt);
845
        op_ldst(ldr);
846
        GEN_STORE_TN_REG(rt, T0);
847
        opn = "ldr";
848
        break;
849
    case OPC_SDR:
850
        GEN_LOAD_REG_TN(T1, rt);
851
        op_ldst(sdr);
852
        opn = "sdr";
853
        break;
854
#endif
855
    case OPC_LW:
856
        op_ldst(lw);
857
        GEN_STORE_TN_REG(rt, T0);
858
        opn = "lw";
859
        break;
860
    case OPC_SW:
861
        GEN_LOAD_REG_TN(T1, rt);
862
        op_ldst(sw);
863
        opn = "sw";
864
        break;
865
    case OPC_LH:
866
        op_ldst(lh);
867
        GEN_STORE_TN_REG(rt, T0);
868
        opn = "lh";
869
        break;
870
    case OPC_SH:
871
        GEN_LOAD_REG_TN(T1, rt);
872
        op_ldst(sh);
873
        opn = "sh";
874
        break;
875
    case OPC_LHU:
876
        op_ldst(lhu);
877
        GEN_STORE_TN_REG(rt, T0);
878
        opn = "lhu";
879
        break;
880
    case OPC_LB:
881
        op_ldst(lb);
882
        GEN_STORE_TN_REG(rt, T0);
883
        opn = "lb";
884
        break;
885
    case OPC_SB:
886
        GEN_LOAD_REG_TN(T1, rt);
887
        op_ldst(sb);
888
        opn = "sb";
889
        break;
890
    case OPC_LBU:
891
        op_ldst(lbu);
892
        GEN_STORE_TN_REG(rt, T0);
893
        opn = "lbu";
894
        break;
895
    case OPC_LWL:
896
        GEN_LOAD_REG_TN(T1, rt);
897
        op_ldst(lwl);
898
        GEN_STORE_TN_REG(rt, T0);
899
        opn = "lwl";
900
        break;
901
    case OPC_SWL:
902
        GEN_LOAD_REG_TN(T1, rt);
903
        op_ldst(swl);
904
        opn = "swr";
905
        break;
906
    case OPC_LWR:
907
        GEN_LOAD_REG_TN(T1, rt);
908
        op_ldst(lwr);
909
        GEN_STORE_TN_REG(rt, T0);
910
        opn = "lwr";
911
        break;
912
    case OPC_SWR:
913
        GEN_LOAD_REG_TN(T1, rt);
914
        op_ldst(swr);
915
        opn = "swr";
916
        break;
917
    case OPC_LL:
918
        op_ldst(ll);
919
        GEN_STORE_TN_REG(rt, T0);
920
        opn = "ll";
921
        break;
922
    case OPC_SC:
923
        save_cpu_state(ctx, 1);
924
        GEN_LOAD_REG_TN(T1, rt);
925
        op_ldst(sc);
926
        GEN_STORE_TN_REG(rt, T0);
927
        opn = "sc";
928
        break;
929
    default:
930
        MIPS_INVAL(opn);
931
        generate_exception(ctx, EXCP_RI);
932
        return;
933
    }
934
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
935
}
936

    
937
/* Load and store */
938
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
939
                      int base, int16_t offset)
940
{
941
    const char *opn = "flt_ldst";
942

    
943
    if (base == 0) {
944
        GEN_LOAD_IMM_TN(T0, offset);
945
    } else if (offset == 0) {
946
        gen_op_load_gpr_T0(base);
947
    } else {
948
        gen_op_load_gpr_T0(base);
949
        gen_op_set_T1(offset);
950
        gen_op_addr_add();
951
    }
952
    /* Don't do NOP if destination is zero: we must perform the actual
953
     * memory access
954
     */
955
    switch (opc) {
956
    case OPC_LWC1:
957
        op_ldst(lwc1);
958
        GEN_STORE_FTN_FREG(ft, WT0);
959
        opn = "lwc1";
960
        break;
961
    case OPC_SWC1:
962
        GEN_LOAD_FREG_FTN(WT0, ft);
963
        op_ldst(swc1);
964
        opn = "swc1";
965
        break;
966
    case OPC_LDC1:
967
        op_ldst(ldc1);
968
        GEN_STORE_FTN_FREG(ft, DT0);
969
        opn = "ldc1";
970
        break;
971
    case OPC_SDC1:
972
        GEN_LOAD_FREG_FTN(DT0, ft);
973
        op_ldst(sdc1);
974
        opn = "sdc1";
975
        break;
976
    default:
977
        MIPS_INVAL(opn);
978
        generate_exception(ctx, EXCP_RI);
979
        return;
980
    }
981
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
982
}
983

    
984
/* Arithmetic with immediate operand */
985
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
986
                           int rs, int16_t imm)
987
{
988
    target_ulong uimm;
989
    const char *opn = "imm arith";
990

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

    
1162
/* Arithmetic */
1163
static void gen_arith (DisasContext *ctx, uint32_t opc,
1164
                       int rd, int rs, int rt)
1165
{
1166
    const char *opn = "arith";
1167

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

    
1313
/* Arithmetic on HI/LO registers */
1314
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1315
{
1316
    const char *opn = "hilo";
1317

    
1318
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1319
        /* Treat as a NOP */
1320
        MIPS_DEBUG("NOP");
1321
        return;
1322
    }
1323
    switch (opc) {
1324
    case OPC_MFHI:
1325
        gen_op_load_HI();
1326
        GEN_STORE_TN_REG(reg, T0);
1327
        opn = "mfhi";
1328
        break;
1329
    case OPC_MFLO:
1330
        gen_op_load_LO();
1331
        GEN_STORE_TN_REG(reg, T0);
1332
        opn = "mflo";
1333
        break;
1334
    case OPC_MTHI:
1335
        GEN_LOAD_REG_TN(T0, reg);
1336
        gen_op_store_HI();
1337
        opn = "mthi";
1338
        break;
1339
    case OPC_MTLO:
1340
        GEN_LOAD_REG_TN(T0, reg);
1341
        gen_op_store_LO();
1342
        opn = "mtlo";
1343
        break;
1344
    default:
1345
        MIPS_INVAL(opn);
1346
        generate_exception(ctx, EXCP_RI);
1347
        return;
1348
    }
1349
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1350
}
1351

    
1352
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1353
                        int rs, int rt)
1354
{
1355
    const char *opn = "mul/div";
1356

    
1357
    GEN_LOAD_REG_TN(T0, rs);
1358
    GEN_LOAD_REG_TN(T1, rt);
1359
    switch (opc) {
1360
    case OPC_DIV:
1361
        gen_op_div();
1362
        opn = "div";
1363
        break;
1364
    case OPC_DIVU:
1365
        gen_op_divu();
1366
        opn = "divu";
1367
        break;
1368
    case OPC_MULT:
1369
        gen_op_mult();
1370
        opn = "mult";
1371
        break;
1372
    case OPC_MULTU:
1373
        gen_op_multu();
1374
        opn = "multu";
1375
        break;
1376
#ifdef TARGET_MIPS64
1377
    case OPC_DDIV:
1378
        gen_op_ddiv();
1379
        opn = "ddiv";
1380
        break;
1381
    case OPC_DDIVU:
1382
        gen_op_ddivu();
1383
        opn = "ddivu";
1384
        break;
1385
    case OPC_DMULT:
1386
        gen_op_dmult();
1387
        opn = "dmult";
1388
        break;
1389
    case OPC_DMULTU:
1390
        gen_op_dmultu();
1391
        opn = "dmultu";
1392
        break;
1393
#endif
1394
    case OPC_MADD:
1395
        gen_op_madd();
1396
        opn = "madd";
1397
        break;
1398
    case OPC_MADDU:
1399
        gen_op_maddu();
1400
        opn = "maddu";
1401
        break;
1402
    case OPC_MSUB:
1403
        gen_op_msub();
1404
        opn = "msub";
1405
        break;
1406
    case OPC_MSUBU:
1407
        gen_op_msubu();
1408
        opn = "msubu";
1409
        break;
1410
    default:
1411
        MIPS_INVAL(opn);
1412
        generate_exception(ctx, EXCP_RI);
1413
        return;
1414
    }
1415
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1416
}
1417

    
1418
static void gen_cl (DisasContext *ctx, uint32_t opc,
1419
                    int rd, int rs)
1420
{
1421
    const char *opn = "CLx";
1422
    if (rd == 0) {
1423
        /* Treat as a NOP */
1424
        MIPS_DEBUG("NOP");
1425
        return;
1426
    }
1427
    GEN_LOAD_REG_TN(T0, rs);
1428
    switch (opc) {
1429
    case OPC_CLO:
1430
        gen_op_clo();
1431
        opn = "clo";
1432
        break;
1433
    case OPC_CLZ:
1434
        gen_op_clz();
1435
        opn = "clz";
1436
        break;
1437
#ifdef TARGET_MIPS64
1438
    case OPC_DCLO:
1439
        gen_op_dclo();
1440
        opn = "dclo";
1441
        break;
1442
    case OPC_DCLZ:
1443
        gen_op_dclz();
1444
        opn = "dclz";
1445
        break;
1446
#endif
1447
    default:
1448
        MIPS_INVAL(opn);
1449
        generate_exception(ctx, EXCP_RI);
1450
        return;
1451
    }
1452
    gen_op_store_T0_gpr(rd);
1453
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1454
}
1455

    
1456
/* Traps */
1457
static void gen_trap (DisasContext *ctx, uint32_t opc,
1458
                      int rs, int rt, int16_t imm)
1459
{
1460
    int cond;
1461

    
1462
    cond = 0;
1463
    /* Load needed operands */
1464
    switch (opc) {
1465
    case OPC_TEQ:
1466
    case OPC_TGE:
1467
    case OPC_TGEU:
1468
    case OPC_TLT:
1469
    case OPC_TLTU:
1470
    case OPC_TNE:
1471
        /* Compare two registers */
1472
        if (rs != rt) {
1473
            GEN_LOAD_REG_TN(T0, rs);
1474
            GEN_LOAD_REG_TN(T1, rt);
1475
            cond = 1;
1476
        }
1477
        break;
1478
    case OPC_TEQI:
1479
    case OPC_TGEI:
1480
    case OPC_TGEIU:
1481
    case OPC_TLTI:
1482
    case OPC_TLTIU:
1483
    case OPC_TNEI:
1484
        /* Compare register to immediate */
1485
        if (rs != 0 || imm != 0) {
1486
            GEN_LOAD_REG_TN(T0, rs);
1487
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1488
            cond = 1;
1489
        }
1490
        break;
1491
    }
1492
    if (cond == 0) {
1493
        switch (opc) {
1494
        case OPC_TEQ:   /* rs == rs */
1495
        case OPC_TEQI:  /* r0 == 0  */
1496
        case OPC_TGE:   /* rs >= rs */
1497
        case OPC_TGEI:  /* r0 >= 0  */
1498
        case OPC_TGEU:  /* rs >= rs unsigned */
1499
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1500
            /* Always trap */
1501
            gen_op_set_T0(1);
1502
            break;
1503
        case OPC_TLT:   /* rs < rs           */
1504
        case OPC_TLTI:  /* r0 < 0            */
1505
        case OPC_TLTU:  /* rs < rs unsigned  */
1506
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1507
        case OPC_TNE:   /* rs != rs          */
1508
        case OPC_TNEI:  /* r0 != 0           */
1509
            /* Never trap: treat as NOP */
1510
            return;
1511
        default:
1512
            MIPS_INVAL("trap");
1513
            generate_exception(ctx, EXCP_RI);
1514
            return;
1515
        }
1516
    } else {
1517
        switch (opc) {
1518
        case OPC_TEQ:
1519
        case OPC_TEQI:
1520
            gen_op_eq();
1521
            break;
1522
        case OPC_TGE:
1523
        case OPC_TGEI:
1524
            gen_op_ge();
1525
            break;
1526
        case OPC_TGEU:
1527
        case OPC_TGEIU:
1528
            gen_op_geu();
1529
            break;
1530
        case OPC_TLT:
1531
        case OPC_TLTI:
1532
            gen_op_lt();
1533
            break;
1534
        case OPC_TLTU:
1535
        case OPC_TLTIU:
1536
            gen_op_ltu();
1537
            break;
1538
        case OPC_TNE:
1539
        case OPC_TNEI:
1540
            gen_op_ne();
1541
            break;
1542
        default:
1543
            MIPS_INVAL("trap");
1544
            generate_exception(ctx, EXCP_RI);
1545
            return;
1546
        }
1547
    }
1548
    save_cpu_state(ctx, 1);
1549
    gen_op_trap();
1550
    ctx->bstate = BS_STOP;
1551
}
1552

    
1553
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1554
{
1555
    TranslationBlock *tb;
1556
    tb = ctx->tb;
1557
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1558
        if (n == 0)
1559
            gen_op_goto_tb0(TBPARAM(tb));
1560
        else
1561
            gen_op_goto_tb1(TBPARAM(tb));
1562
        gen_save_pc(dest);
1563
        gen_op_set_T0((long)tb + n);
1564
    } else {
1565
        gen_save_pc(dest);
1566
        gen_op_reset_T0();
1567
    }
1568
    gen_op_exit_tb();
1569
}
1570

    
1571
/* Branches (before delay slot) */
1572
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1573
                                int rs, int rt, int32_t offset)
1574
{
1575
    target_ulong btarget = -1;
1576
    int blink = 0;
1577
    int bcond = 0;
1578

    
1579
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1580
#ifdef MIPS_DEBUG_DISAS
1581
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1582
            fprintf(logfile,
1583
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1584
                    ctx->pc);
1585
        }
1586
#endif
1587
        generate_exception(ctx, EXCP_RI);
1588
        return;
1589
    }
1590

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

    
1804
    ctx->btarget = btarget;
1805
    if (blink > 0) {
1806
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1807
        gen_op_store_T0_gpr(blink);
1808
    }
1809
}
1810

    
1811
/* special3 bitfield operations */
1812
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1813
                       int rs, int lsb, int msb)
1814
{
1815
    GEN_LOAD_REG_TN(T1, rs);
1816
    switch (opc) {
1817
    case OPC_EXT:
1818
        if (lsb + msb > 31)
1819
            goto fail;
1820
        gen_op_ext(lsb, msb + 1);
1821
        break;
1822
    case OPC_DEXTM:
1823
        if (lsb + msb > 63)
1824
            goto fail;
1825
        gen_op_ext(lsb, msb + 1 + 32);
1826
        break;
1827
    case OPC_DEXTU:
1828
        if (lsb + msb > 63)
1829
            goto fail;
1830
        gen_op_ext(lsb + 32, msb + 1);
1831
        break;
1832
    case OPC_DEXT:
1833
        gen_op_ext(lsb, msb + 1);
1834
        break;
1835
    case OPC_INS:
1836
        if (lsb > msb)
1837
            goto fail;
1838
        GEN_LOAD_REG_TN(T0, rt);
1839
        gen_op_ins(lsb, msb - lsb + 1);
1840
        break;
1841
    case OPC_DINSM:
1842
        if (lsb > msb)
1843
            goto fail;
1844
        GEN_LOAD_REG_TN(T0, rt);
1845
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1846
        break;
1847
    case OPC_DINSU:
1848
        if (lsb > msb)
1849
            goto fail;
1850
        GEN_LOAD_REG_TN(T0, rt);
1851
        gen_op_ins(lsb + 32, msb - lsb + 1);
1852
        break;
1853
    case OPC_DINS:
1854
        if (lsb > msb)
1855
            goto fail;
1856
        GEN_LOAD_REG_TN(T0, rt);
1857
        gen_op_ins(lsb, msb - lsb + 1);
1858
        break;
1859
    default:
1860
fail:
1861
        MIPS_INVAL("bitops");
1862
        generate_exception(ctx, EXCP_RI);
1863
        return;
1864
    }
1865
    GEN_STORE_TN_REG(rt, T0);
1866
}
1867

    
1868
/* CP0 (MMU and control) */
1869
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1870
{
1871
    const char *rn = "invalid";
1872

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

    
2395
die:
2396
#if defined MIPS_DEBUG_DISAS
2397
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2398
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2399
                rn, reg, sel);
2400
    }
2401
#endif
2402
    generate_exception(ctx, EXCP_RI);
2403
}
2404

    
2405
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2406
{
2407
    const char *rn = "invalid";
2408

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

    
2944
die:
2945
#if defined MIPS_DEBUG_DISAS
2946
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2947
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2948
                rn, reg, sel);
2949
    }
2950
#endif
2951
    generate_exception(ctx, EXCP_RI);
2952
}
2953

    
2954
#ifdef TARGET_MIPS64
2955
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2956
{
2957
    const char *rn = "invalid";
2958

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

    
3472
die:
3473
#if defined MIPS_DEBUG_DISAS
3474
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3475
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3476
                rn, reg, sel);
3477
    }
3478
#endif
3479
    generate_exception(ctx, EXCP_RI);
3480
}
3481

    
3482
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3483
{
3484
    const char *rn = "invalid";
3485

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

    
4012
die:
4013
#if defined MIPS_DEBUG_DISAS
4014
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4015
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4016
                rn, reg, sel);
4017
    }
4018
#endif
4019
    generate_exception(ctx, EXCP_RI);
4020
}
4021
#endif /* TARGET_MIPS64 */
4022

    
4023
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4024
{
4025
    const char *opn = "ldst";
4026

    
4027
    switch (opc) {
4028
    case OPC_MFC0:
4029
        if (rt == 0) {
4030
            /* Treat as NOP */
4031
            return;
4032
        }
4033
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4034
        gen_op_store_T0_gpr(rt);
4035
        opn = "mfc0";
4036
        break;
4037
    case OPC_MTC0:
4038
        GEN_LOAD_REG_TN(T0, rt);
4039
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4040
        opn = "mtc0";
4041
        break;
4042
#ifdef TARGET_MIPS64
4043
    case OPC_DMFC0:
4044
        if (rt == 0) {
4045
            /* Treat as NOP */
4046
            return;
4047
        }
4048
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4049
        gen_op_store_T0_gpr(rt);
4050
        opn = "dmfc0";
4051
        break;
4052
    case OPC_DMTC0:
4053
        GEN_LOAD_REG_TN(T0, rt);
4054
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4055
        opn = "dmtc0";
4056
        break;
4057
#endif
4058
    case OPC_TLBWI:
4059
        opn = "tlbwi";
4060
        if (!env->do_tlbwi)
4061
            goto die;
4062
        gen_op_tlbwi();
4063
        break;
4064
    case OPC_TLBWR:
4065
        opn = "tlbwr";
4066
        if (!env->do_tlbwr)
4067
            goto die;
4068
        gen_op_tlbwr();
4069
        break;
4070
    case OPC_TLBP:
4071
        opn = "tlbp";
4072
        if (!env->do_tlbp)
4073
            goto die;
4074
        gen_op_tlbp();
4075
        break;
4076
    case OPC_TLBR:
4077
        opn = "tlbr";
4078
        if (!env->do_tlbr)
4079
            goto die;
4080
        gen_op_tlbr();
4081
        break;
4082
    case OPC_ERET:
4083
        opn = "eret";
4084
        gen_op_eret();
4085
        ctx->bstate = BS_EXCP;
4086
        break;
4087
    case OPC_DERET:
4088
        opn = "deret";
4089
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4090
            MIPS_INVAL(opn);
4091
            generate_exception(ctx, EXCP_RI);
4092
        } else {
4093
            gen_op_deret();
4094
            ctx->bstate = BS_EXCP;
4095
        }
4096
        break;
4097
    case OPC_WAIT:
4098
        opn = "wait";
4099
        /* If we get an exception, we want to restart at next instruction */
4100
        ctx->pc += 4;
4101
        save_cpu_state(ctx, 1);
4102
        ctx->pc -= 4;
4103
        gen_op_wait();
4104
        ctx->bstate = BS_EXCP;
4105
        break;
4106
    default:
4107
 die:
4108
        MIPS_INVAL(opn);
4109
        generate_exception(ctx, EXCP_RI);
4110
        return;
4111
    }
4112
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4113
}
4114

    
4115
/* CP1 Branches (before delay slot) */
4116
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4117
                                 int32_t cc, int32_t offset)
4118
{
4119
    target_ulong btarget;
4120
    const char *opn = "cp1 cond branch";
4121

    
4122
    btarget = ctx->pc + 4 + offset;
4123

    
4124
    switch (op) {
4125
    case OPC_BC1F:
4126
        gen_op_bc1f(cc);
4127
        opn = "bc1f";
4128
        goto not_likely;
4129
    case OPC_BC1FL:
4130
        gen_op_bc1f(cc);
4131
        opn = "bc1fl";
4132
        goto likely;
4133
    case OPC_BC1T:
4134
        gen_op_bc1t(cc);
4135
        opn = "bc1t";
4136
        goto not_likely;
4137
    case OPC_BC1TL:
4138
        gen_op_bc1t(cc);
4139
        opn = "bc1tl";
4140
    likely:
4141
        ctx->hflags |= MIPS_HFLAG_BL;
4142
        gen_op_set_bcond();
4143
        gen_op_save_bcond();
4144
        break;
4145
    case OPC_BC1FANY2:
4146
        gen_op_bc1any2f(cc);
4147
        opn = "bc1any2f";
4148
        goto not_likely;
4149
    case OPC_BC1TANY2:
4150
        gen_op_bc1any2t(cc);
4151
        opn = "bc1any2t";
4152
        goto not_likely;
4153
    case OPC_BC1FANY4:
4154
        gen_op_bc1any4f(cc);
4155
        opn = "bc1any4f";
4156
        goto not_likely;
4157
    case OPC_BC1TANY4:
4158
        gen_op_bc1any4t(cc);
4159
        opn = "bc1any4t";
4160
    not_likely:
4161
        ctx->hflags |= MIPS_HFLAG_BC;
4162
        gen_op_set_bcond();
4163
        break;
4164
    default:
4165
        MIPS_INVAL(opn);
4166
        generate_exception (ctx, EXCP_RI);
4167
        return;
4168
    }
4169
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4170
               ctx->hflags, btarget);
4171
    ctx->btarget = btarget;
4172
}
4173

    
4174
/* Coprocessor 1 (FPU) */
4175

    
4176
#define FOP(func, fmt) (((fmt) << 21) | (func))
4177

    
4178
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4179
{
4180
    const char *opn = "cp1 move";
4181

    
4182
    switch (opc) {
4183
    case OPC_MFC1:
4184
        GEN_LOAD_FREG_FTN(WT0, fs);
4185
        gen_op_mfc1();
4186
        GEN_STORE_TN_REG(rt, T0);
4187
        opn = "mfc1";
4188
        break;
4189
    case OPC_MTC1:
4190
        GEN_LOAD_REG_TN(T0, rt);
4191
        gen_op_mtc1();
4192
        GEN_STORE_FTN_FREG(fs, WT0);
4193
        opn = "mtc1";
4194
        break;
4195
    case OPC_CFC1:
4196
        GEN_LOAD_IMM_TN(T1, fs);
4197
        gen_op_cfc1();
4198
        GEN_STORE_TN_REG(rt, T0);
4199
        opn = "cfc1";
4200
        break;
4201
    case OPC_CTC1:
4202
        GEN_LOAD_IMM_TN(T1, fs);
4203
        GEN_LOAD_REG_TN(T0, rt);
4204
        gen_op_ctc1();
4205
        opn = "ctc1";
4206
        break;
4207
    case OPC_DMFC1:
4208
        GEN_LOAD_FREG_FTN(DT0, fs);
4209
        gen_op_dmfc1();
4210
        GEN_STORE_TN_REG(rt, T0);
4211
        opn = "dmfc1";
4212
        break;
4213
    case OPC_DMTC1:
4214
        GEN_LOAD_REG_TN(T0, rt);
4215
        gen_op_dmtc1();
4216
        GEN_STORE_FTN_FREG(fs, DT0);
4217
        opn = "dmtc1";
4218
        break;
4219
    case OPC_MFHC1:
4220
        GEN_LOAD_FREG_FTN(WTH0, fs);
4221
        gen_op_mfhc1();
4222
        GEN_STORE_TN_REG(rt, T0);
4223
        opn = "mfhc1";
4224
        break;
4225
    case OPC_MTHC1:
4226
        GEN_LOAD_REG_TN(T0, rt);
4227
        gen_op_mthc1();
4228
        GEN_STORE_FTN_FREG(fs, WTH0);
4229
        opn = "mthc1";
4230
        break;
4231
    default:
4232
        MIPS_INVAL(opn);
4233
        generate_exception (ctx, EXCP_RI);
4234
        return;
4235
    }
4236
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4237
}
4238

    
4239
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4240
{
4241
    uint32_t ccbit;
4242

    
4243
    GEN_LOAD_REG_TN(T0, rd);
4244
    GEN_LOAD_REG_TN(T1, rs);
4245
    if (cc) {
4246
        ccbit = 1 << (24 + cc);
4247
    } else
4248
        ccbit = 1 << 23;
4249
    if (!tf)
4250
        gen_op_movf(ccbit);
4251
    else
4252
        gen_op_movt(ccbit);
4253
    GEN_STORE_TN_REG(rd, T0);
4254
}
4255

    
4256
#define GEN_MOVCF(fmt)                                                \
4257
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4258
{                                                                     \
4259
    uint32_t ccbit;                                                   \
4260
                                                                      \
4261
    if (cc) {                                                         \
4262
        ccbit = 1 << (24 + cc);                                       \
4263
    } else                                                            \
4264
        ccbit = 1 << 23;                                              \
4265
    if (!tf)                                                          \
4266
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4267
    else                                                              \
4268
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4269
}
4270
GEN_MOVCF(d);
4271
GEN_MOVCF(s);
4272
GEN_MOVCF(ps);
4273
#undef GEN_MOVCF
4274

    
4275
static void gen_farith (DisasContext *ctx, uint32_t op1,
4276
                        int ft, int fs, int fd, int cc)
4277
{
4278
    const char *opn = "farith";
4279
    const char *condnames[] = {
4280
            "c.f",
4281
            "c.un",
4282
            "c.eq",
4283
            "c.ueq",
4284
            "c.olt",
4285
            "c.ult",
4286
            "c.ole",
4287
            "c.ule",
4288
            "c.sf",
4289
            "c.ngle",
4290
            "c.seq",
4291
            "c.ngl",
4292
            "c.lt",
4293
            "c.nge",
4294
            "c.le",
4295
            "c.ngt",
4296
    };
4297
    const char *condnames_abs[] = {
4298
            "cabs.f",
4299
            "cabs.un",
4300
            "cabs.eq",
4301
            "cabs.ueq",
4302
            "cabs.olt",
4303
            "cabs.ult",
4304
            "cabs.ole",
4305
            "cabs.ule",
4306
            "cabs.sf",
4307
            "cabs.ngle",
4308
            "cabs.seq",
4309
            "cabs.ngl",
4310
            "cabs.lt",
4311
            "cabs.nge",
4312
            "cabs.le",
4313
            "cabs.ngt",
4314
    };
4315
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4316
    uint32_t func = ctx->opcode & 0x3f;
4317

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

    
5082
/* Coprocessor 3 (FPU) */
5083
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5084
                           int fd, int fs, int base, int index)
5085
{
5086
    const char *opn = "extended float load/store";
5087
    int store = 0;
5088

    
5089
    /* All of those work only on 64bit FPUs. */
5090
    check_cp1_64bitmode(ctx);
5091
    if (base == 0) {
5092
        if (index == 0)
5093
            gen_op_reset_T0();
5094
        else
5095
            GEN_LOAD_REG_TN(T0, index);
5096
    } else if (index == 0) {
5097
        GEN_LOAD_REG_TN(T0, base);
5098
    } else {
5099
        GEN_LOAD_REG_TN(T0, base);
5100
        GEN_LOAD_REG_TN(T1, index);
5101
        gen_op_addr_add();
5102
    }
5103
    /* Don't do NOP if destination is zero: we must perform the actual
5104
     * memory access
5105
     */
5106
    switch (opc) {
5107
    case OPC_LWXC1:
5108
        op_ldst(lwc1);
5109
        GEN_STORE_FTN_FREG(fd, WT0);
5110
        opn = "lwxc1";
5111
        break;
5112
    case OPC_LDXC1:
5113
        op_ldst(ldc1);
5114
        GEN_STORE_FTN_FREG(fd, DT0);
5115
        opn = "ldxc1";
5116
        break;
5117
    case OPC_LUXC1:
5118
        op_ldst(luxc1);
5119
        GEN_STORE_FTN_FREG(fd, DT0);
5120
        opn = "luxc1";
5121
        break;
5122
    case OPC_SWXC1:
5123
        GEN_LOAD_FREG_FTN(WT0, fs);
5124
        op_ldst(swc1);
5125
        opn = "swxc1";
5126
        store = 1;
5127
        break;
5128
    case OPC_SDXC1:
5129
        GEN_LOAD_FREG_FTN(DT0, fs);
5130
        op_ldst(sdc1);
5131
        opn = "sdxc1";
5132
        store = 1;
5133
        break;
5134
    case OPC_SUXC1:
5135
        GEN_LOAD_FREG_FTN(DT0, fs);
5136
        op_ldst(suxc1);
5137
        opn = "suxc1";
5138
        store = 1;
5139
        break;
5140
    default:
5141
        MIPS_INVAL(opn);
5142
        generate_exception(ctx, EXCP_RI);
5143
        return;
5144
    }
5145
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5146
               regnames[index], regnames[base]);
5147
}
5148

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

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

    
5286
/* ISA extensions (ASEs) */
5287
/* MIPS16 extension to MIPS32 */
5288
/* SmartMIPS extension to MIPS32 */
5289

    
5290
#ifdef TARGET_MIPS64
5291

    
5292
/* MDMX extension to MIPS64 */
5293
/* MIPS-3D extension to MIPS64 */
5294

    
5295
#endif
5296

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

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

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

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

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

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

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

    
5715
    /* COP2.  */
5716
    case OPC_LWC2:
5717
    case OPC_LDC2:
5718
    case OPC_SWC2:
5719
    case OPC_SDC2:
5720
    case OPC_CP2:
5721
        /* COP2: Not implemented. */
5722
        generate_exception_err(ctx, EXCP_CpU, 2);
5723
        break;
5724

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6010

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

    
6021
#undef printfpr
6022
}
6023

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

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

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

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

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

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

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

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

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

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

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

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

    
6109
    tlb_flush(env, 1);
6110

    
6111
    /* Minimal init */
6112
#if !defined(CONFIG_USER_ONLY)
6113
    if (env->hflags & MIPS_HFLAG_BMASK) {
6114
        /* If the exception was raised from a delay slot,
6115
         * come back to the jump.  */
6116
        env->CP0_ErrorEPC = env->PC - 4;
6117
    } else {
6118
        env->CP0_ErrorEPC = env->PC;
6119
    }
6120
#ifdef TARGET_MIPS64
6121
    env->hflags = MIPS_HFLAG_64;
6122
#else
6123
    env->hflags = 0;
6124
#endif
6125
    env->PC = (int32_t)0xBFC00000;
6126
    env->CP0_Wired = 0;
6127
    /* SMP not implemented */
6128
    env->CP0_EBase = 0x80000000;
6129
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6130
    /* vectored interrupts not implemented, timer on int 7,
6131
       no performance counters. */
6132
    env->CP0_IntCtl = 0xe0000000;
6133
    {
6134
        int i;
6135

    
6136
        for (i = 0; i < 7; i++) {
6137
            env->CP0_WatchLo[i] = 0;
6138
            env->CP0_WatchHi[i] = 0x80000000;
6139
        }
6140
        env->CP0_WatchLo[7] = 0;
6141
        env->CP0_WatchHi[7] = 0;
6142
    }
6143
    /* Count register increments in debug mode, EJTAG version 1 */
6144
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6145
#endif
6146
    env->exception_index = EXCP_NONE;
6147
#if defined(CONFIG_USER_ONLY)
6148
    env->hflags |= MIPS_HFLAG_UM;
6149
    env->user_mode_only = 1;
6150
#endif
6151
}
6152

    
6153
#include "translate_init.c"