Statistics
| Branch: | Revision:

root / target-mips / translate.c @ fd88b6ab

History | View | Annotate | Download (161.8 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
717
/* Load and store */
718
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
719
                      int base, int16_t offset)
720
{
721
    const char *opn = "ldst";
722

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

    
869
/* Load and store */
870
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
871
                      int base, int16_t offset)
872
{
873
    const char *opn = "flt_ldst";
874

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

    
916
/* Arithmetic with immediate operand */
917
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
918
                           int rs, int16_t imm)
919
{
920
    target_ulong uimm;
921
    const char *opn = "imm arith";
922

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

    
1094
/* Arithmetic */
1095
static void gen_arith (DisasContext *ctx, uint32_t opc,
1096
                       int rd, int rs, int rt)
1097
{
1098
    const char *opn = "arith";
1099

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

    
1245
/* Arithmetic on HI/LO registers */
1246
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1247
{
1248
    const char *opn = "hilo";
1249

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

    
1284
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1285
                        int rs, int rt)
1286
{
1287
    const char *opn = "mul/div";
1288

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

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

    
1388
/* Traps */
1389
static void gen_trap (DisasContext *ctx, uint32_t opc,
1390
                      int rs, int rt, int16_t imm)
1391
{
1392
    int cond;
1393

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

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

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

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

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

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

    
1799
/* CP0 (MMU and control) */
1800
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1801
{
1802
    const char *rn = "invalid";
1803

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

    
2326
die:
2327
#if defined MIPS_DEBUG_DISAS
2328
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2329
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2330
                rn, reg, sel);
2331
    }
2332
#endif
2333
    generate_exception(ctx, EXCP_RI);
2334
}
2335

    
2336
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2337
{
2338
    const char *rn = "invalid";
2339

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

    
2875
die:
2876
#if defined MIPS_DEBUG_DISAS
2877
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2878
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2879
                rn, reg, sel);
2880
    }
2881
#endif
2882
    generate_exception(ctx, EXCP_RI);
2883
}
2884

    
2885
#ifdef TARGET_MIPS64
2886
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2887
{
2888
    const char *rn = "invalid";
2889

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

    
3403
die:
3404
#if defined MIPS_DEBUG_DISAS
3405
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3406
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3407
                rn, reg, sel);
3408
    }
3409
#endif
3410
    generate_exception(ctx, EXCP_RI);
3411
}
3412

    
3413
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3414
{
3415
    const char *rn = "invalid";
3416

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

    
3943
die:
3944
#if defined MIPS_DEBUG_DISAS
3945
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3946
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
3947
                rn, reg, sel);
3948
    }
3949
#endif
3950
    generate_exception(ctx, EXCP_RI);
3951
}
3952
#endif /* TARGET_MIPS64 */
3953

    
3954
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
3955
{
3956
    const char *opn = "ldst";
3957

    
3958
    switch (opc) {
3959
    case OPC_MFC0:
3960
        if (rt == 0) {
3961
            /* Treat as NOP */
3962
            return;
3963
        }
3964
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
3965
        gen_op_store_T0_gpr(rt);
3966
        opn = "mfc0";
3967
        break;
3968
    case OPC_MTC0:
3969
        GEN_LOAD_REG_TN(T0, rt);
3970
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
3971
        opn = "mtc0";
3972
        break;
3973
#ifdef TARGET_MIPS64
3974
    case OPC_DMFC0:
3975
        if (rt == 0) {
3976
            /* Treat as NOP */
3977
            return;
3978
        }
3979
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
3980
        gen_op_store_T0_gpr(rt);
3981
        opn = "dmfc0";
3982
        break;
3983
    case OPC_DMTC0:
3984
        GEN_LOAD_REG_TN(T0, rt);
3985
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
3986
        opn = "dmtc0";
3987
        break;
3988
#endif
3989
    case OPC_TLBWI:
3990
        opn = "tlbwi";
3991
        if (!env->do_tlbwi)
3992
            goto die;
3993
        gen_op_tlbwi();
3994
        break;
3995
    case OPC_TLBWR:
3996
        opn = "tlbwr";
3997
        if (!env->do_tlbwr)
3998
            goto die;
3999
        gen_op_tlbwr();
4000
        break;
4001
    case OPC_TLBP:
4002
        opn = "tlbp";
4003
        if (!env->do_tlbp)
4004
            goto die;
4005
        gen_op_tlbp();
4006
        break;
4007
    case OPC_TLBR:
4008
        opn = "tlbr";
4009
        if (!env->do_tlbr)
4010
            goto die;
4011
        gen_op_tlbr();
4012
        break;
4013
    case OPC_ERET:
4014
        opn = "eret";
4015
        gen_op_eret();
4016
        ctx->bstate = BS_EXCP;
4017
        break;
4018
    case OPC_DERET:
4019
        opn = "deret";
4020
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4021
            MIPS_INVAL(opn);
4022
            generate_exception(ctx, EXCP_RI);
4023
        } else {
4024
            gen_op_deret();
4025
            ctx->bstate = BS_EXCP;
4026
        }
4027
        break;
4028
    case OPC_WAIT:
4029
        opn = "wait";
4030
        /* If we get an exception, we want to restart at next instruction */
4031
        ctx->pc += 4;
4032
        save_cpu_state(ctx, 1);
4033
        ctx->pc -= 4;
4034
        gen_op_wait();
4035
        ctx->bstate = BS_EXCP;
4036
        break;
4037
    default:
4038
 die:
4039
        MIPS_INVAL(opn);
4040
        generate_exception(ctx, EXCP_RI);
4041
        return;
4042
    }
4043
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4044
}
4045

    
4046
/* CP1 Branches (before delay slot) */
4047
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4048
                                 int32_t cc, int32_t offset)
4049
{
4050
    target_ulong btarget;
4051
    const char *opn = "cp1 cond branch";
4052

    
4053
    btarget = ctx->pc + 4 + offset;
4054

    
4055
    switch (op) {
4056
    case OPC_BC1F:
4057
        gen_op_bc1f(cc);
4058
        opn = "bc1f";
4059
        goto not_likely;
4060
    case OPC_BC1FL:
4061
        gen_op_bc1f(cc);
4062
        opn = "bc1fl";
4063
        goto likely;
4064
    case OPC_BC1T:
4065
        gen_op_bc1t(cc);
4066
        opn = "bc1t";
4067
        goto not_likely;
4068
    case OPC_BC1TL:
4069
        gen_op_bc1t(cc);
4070
        opn = "bc1tl";
4071
    likely:
4072
        ctx->hflags |= MIPS_HFLAG_BL;
4073
        gen_op_set_bcond();
4074
        gen_op_save_bcond();
4075
        break;
4076
    case OPC_BC1FANY2:
4077
        gen_op_bc1any2f(cc);
4078
        opn = "bc1any2f";
4079
        goto not_likely;
4080
    case OPC_BC1TANY2:
4081
        gen_op_bc1any2t(cc);
4082
        opn = "bc1any2t";
4083
        goto not_likely;
4084
    case OPC_BC1FANY4:
4085
        gen_op_bc1any4f(cc);
4086
        opn = "bc1any4f";
4087
        goto not_likely;
4088
    case OPC_BC1TANY4:
4089
        gen_op_bc1any4t(cc);
4090
        opn = "bc1any4t";
4091
    not_likely:
4092
        ctx->hflags |= MIPS_HFLAG_BC;
4093
        gen_op_set_bcond();
4094
        break;
4095
    default:
4096
        MIPS_INVAL(opn);
4097
        generate_exception (ctx, EXCP_RI);
4098
        return;
4099
    }
4100
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4101
               ctx->hflags, btarget);
4102
    ctx->btarget = btarget;
4103
}
4104

    
4105
/* Coprocessor 1 (FPU) */
4106

    
4107
#define FOP(func, fmt) (((fmt) << 21) | (func))
4108

    
4109
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4110
{
4111
    const char *opn = "cp1 move";
4112

    
4113
    switch (opc) {
4114
    case OPC_MFC1:
4115
        GEN_LOAD_FREG_FTN(WT0, fs);
4116
        gen_op_mfc1();
4117
        GEN_STORE_TN_REG(rt, T0);
4118
        opn = "mfc1";
4119
        break;
4120
    case OPC_MTC1:
4121
        GEN_LOAD_REG_TN(T0, rt);
4122
        gen_op_mtc1();
4123
        GEN_STORE_FTN_FREG(fs, WT0);
4124
        opn = "mtc1";
4125
        break;
4126
    case OPC_CFC1:
4127
        GEN_LOAD_IMM_TN(T1, fs);
4128
        gen_op_cfc1();
4129
        GEN_STORE_TN_REG(rt, T0);
4130
        opn = "cfc1";
4131
        break;
4132
    case OPC_CTC1:
4133
        GEN_LOAD_IMM_TN(T1, fs);
4134
        GEN_LOAD_REG_TN(T0, rt);
4135
        gen_op_ctc1();
4136
        opn = "ctc1";
4137
        break;
4138
    case OPC_DMFC1:
4139
        GEN_LOAD_FREG_FTN(DT0, fs);
4140
        gen_op_dmfc1();
4141
        GEN_STORE_TN_REG(rt, T0);
4142
        opn = "dmfc1";
4143
        break;
4144
    case OPC_DMTC1:
4145
        GEN_LOAD_REG_TN(T0, rt);
4146
        gen_op_dmtc1();
4147
        GEN_STORE_FTN_FREG(fs, DT0);
4148
        opn = "dmtc1";
4149
        break;
4150
    case OPC_MFHC1:
4151
        GEN_LOAD_FREG_FTN(WTH0, fs);
4152
        gen_op_mfhc1();
4153
        GEN_STORE_TN_REG(rt, T0);
4154
        opn = "mfhc1";
4155
        break;
4156
    case OPC_MTHC1:
4157
        GEN_LOAD_REG_TN(T0, rt);
4158
        gen_op_mthc1();
4159
        GEN_STORE_FTN_FREG(fs, WTH0);
4160
        opn = "mthc1";
4161
        break;
4162
    default:
4163
        MIPS_INVAL(opn);
4164
        generate_exception (ctx, EXCP_RI);
4165
        return;
4166
    }
4167
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4168
}
4169

    
4170
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4171
{
4172
    uint32_t ccbit;
4173

    
4174
    GEN_LOAD_REG_TN(T0, rd);
4175
    GEN_LOAD_REG_TN(T1, rs);
4176
    if (cc) {
4177
        ccbit = 1 << (24 + cc);
4178
    } else
4179
        ccbit = 1 << 23;
4180
    if (!tf)
4181
        gen_op_movf(ccbit);
4182
    else
4183
        gen_op_movt(ccbit);
4184
    GEN_STORE_TN_REG(rd, T0);
4185
}
4186

    
4187
#define GEN_MOVCF(fmt)                                                \
4188
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4189
{                                                                     \
4190
    uint32_t ccbit;                                                   \
4191
                                                                      \
4192
    if (cc) {                                                         \
4193
        ccbit = 1 << (24 + cc);                                       \
4194
    } else                                                            \
4195
        ccbit = 1 << 23;                                              \
4196
    if (!tf)                                                          \
4197
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4198
    else                                                              \
4199
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4200
}
4201
GEN_MOVCF(d);
4202
GEN_MOVCF(s);
4203
GEN_MOVCF(ps);
4204
#undef GEN_MOVCF
4205

    
4206
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4207
                        int fs, int fd, int cc)
4208
{
4209
    const char *opn = "farith";
4210
    const char *condnames[] = {
4211
            "c.f",
4212
            "c.un",
4213
            "c.eq",
4214
            "c.ueq",
4215
            "c.olt",
4216
            "c.ult",
4217
            "c.ole",
4218
            "c.ule",
4219
            "c.sf",
4220
            "c.ngle",
4221
            "c.seq",
4222
            "c.ngl",
4223
            "c.lt",
4224
            "c.nge",
4225
            "c.le",
4226
            "c.ngt",
4227
    };
4228
    const char *condnames_abs[] = {
4229
            "cabs.f",
4230
            "cabs.un",
4231
            "cabs.eq",
4232
            "cabs.ueq",
4233
            "cabs.olt",
4234
            "cabs.ult",
4235
            "cabs.ole",
4236
            "cabs.ule",
4237
            "cabs.sf",
4238
            "cabs.ngle",
4239
            "cabs.seq",
4240
            "cabs.ngl",
4241
            "cabs.lt",
4242
            "cabs.nge",
4243
            "cabs.le",
4244
            "cabs.ngt",
4245
    };
4246
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4247
    uint32_t func = ctx->opcode & 0x3f;
4248

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

    
5013
/* Coprocessor 3 (FPU) */
5014
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5015
                           int fs, int base, int index)
5016
{
5017
    const char *opn = "extended float load/store";
5018
    int store = 0;
5019

    
5020
    /* All of those work only on 64bit FPUs. */
5021
    gen_op_cp1_64bitmode();
5022
    if (base == 0) {
5023
        if (index == 0)
5024
            gen_op_reset_T0();
5025
        else
5026
            GEN_LOAD_REG_TN(T0, index);
5027
    } else if (index == 0) {
5028
        GEN_LOAD_REG_TN(T0, base);
5029
    } else {
5030
        GEN_LOAD_REG_TN(T0, base);
5031
        GEN_LOAD_REG_TN(T1, index);
5032
        gen_op_addr_add();
5033
    }
5034
    /* Don't do NOP if destination is zero: we must perform the actual
5035
     * memory access
5036
     */
5037
    switch (opc) {
5038
    case OPC_LWXC1:
5039
        op_ldst(lwc1);
5040
        GEN_STORE_FTN_FREG(fd, WT0);
5041
        opn = "lwxc1";
5042
        break;
5043
    case OPC_LDXC1:
5044
        op_ldst(ldc1);
5045
        GEN_STORE_FTN_FREG(fd, DT0);
5046
        opn = "ldxc1";
5047
        break;
5048
    case OPC_LUXC1:
5049
        op_ldst(luxc1);
5050
        GEN_STORE_FTN_FREG(fd, DT0);
5051
        opn = "luxc1";
5052
        break;
5053
    case OPC_SWXC1:
5054
        GEN_LOAD_FREG_FTN(WT0, fs);
5055
        op_ldst(swc1);
5056
        opn = "swxc1";
5057
        store = 1;
5058
        break;
5059
    case OPC_SDXC1:
5060
        GEN_LOAD_FREG_FTN(DT0, fs);
5061
        op_ldst(sdc1);
5062
        opn = "sdxc1";
5063
        store = 1;
5064
        break;
5065
    case OPC_SUXC1:
5066
        GEN_LOAD_FREG_FTN(DT0, fs);
5067
        op_ldst(suxc1);
5068
        opn = "suxc1";
5069
        store = 1;
5070
        break;
5071
    default:
5072
        MIPS_INVAL(opn);
5073
        generate_exception(ctx, EXCP_RI);
5074
        return;
5075
    }
5076
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5077
               regnames[index], regnames[base]);
5078
}
5079

    
5080
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5081
                            int fr, int fs, int ft)
5082
{
5083
    const char *opn = "flt3_arith";
5084

    
5085
    /* All of those work only on 64bit FPUs. */
5086
    gen_op_cp1_64bitmode();
5087
    switch (opc) {
5088
    case OPC_ALNV_PS:
5089
        GEN_LOAD_REG_TN(T0, fr);
5090
        GEN_LOAD_FREG_FTN(DT0, fs);
5091
        GEN_LOAD_FREG_FTN(DT1, ft);
5092
        gen_op_float_alnv_ps();
5093
        GEN_STORE_FTN_FREG(fd, DT2);
5094
        opn = "alnv.ps";
5095
        break;
5096
    case OPC_MADD_S:
5097
        GEN_LOAD_FREG_FTN(WT0, fs);
5098
        GEN_LOAD_FREG_FTN(WT1, ft);
5099
        GEN_LOAD_FREG_FTN(WT2, fr);
5100
        gen_op_float_muladd_s();
5101
        GEN_STORE_FTN_FREG(fd, WT2);
5102
        opn = "madd.s";
5103
        break;
5104
    case OPC_MADD_D:
5105
        GEN_LOAD_FREG_FTN(DT0, fs);
5106
        GEN_LOAD_FREG_FTN(DT1, ft);
5107
        GEN_LOAD_FREG_FTN(DT2, fr);
5108
        gen_op_float_muladd_d();
5109
        GEN_STORE_FTN_FREG(fd, DT2);
5110
        opn = "madd.d";
5111
        break;
5112
    case OPC_MADD_PS:
5113
        GEN_LOAD_FREG_FTN(WT0, fs);
5114
        GEN_LOAD_FREG_FTN(WTH0, fs);
5115
        GEN_LOAD_FREG_FTN(WT1, ft);
5116
        GEN_LOAD_FREG_FTN(WTH1, ft);
5117
        GEN_LOAD_FREG_FTN(WT2, fr);
5118
        GEN_LOAD_FREG_FTN(WTH2, fr);
5119
        gen_op_float_muladd_ps();
5120
        GEN_STORE_FTN_FREG(fd, WT2);
5121
        GEN_STORE_FTN_FREG(fd, WTH2);
5122
        opn = "madd.ps";
5123
        break;
5124
    case OPC_MSUB_S:
5125
        GEN_LOAD_FREG_FTN(WT0, fs);
5126
        GEN_LOAD_FREG_FTN(WT1, ft);
5127
        GEN_LOAD_FREG_FTN(WT2, fr);
5128
        gen_op_float_mulsub_s();
5129
        GEN_STORE_FTN_FREG(fd, WT2);
5130
        opn = "msub.s";
5131
        break;
5132
    case OPC_MSUB_D:
5133
        GEN_LOAD_FREG_FTN(DT0, fs);
5134
        GEN_LOAD_FREG_FTN(DT1, ft);
5135
        GEN_LOAD_FREG_FTN(DT2, fr);
5136
        gen_op_float_mulsub_d();
5137
        GEN_STORE_FTN_FREG(fd, DT2);
5138
        opn = "msub.d";
5139
        break;
5140
    case OPC_MSUB_PS:
5141
        GEN_LOAD_FREG_FTN(WT0, fs);
5142
        GEN_LOAD_FREG_FTN(WTH0, fs);
5143
        GEN_LOAD_FREG_FTN(WT1, ft);
5144
        GEN_LOAD_FREG_FTN(WTH1, ft);
5145
        GEN_LOAD_FREG_FTN(WT2, fr);
5146
        GEN_LOAD_FREG_FTN(WTH2, fr);
5147
        gen_op_float_mulsub_ps();
5148
        GEN_STORE_FTN_FREG(fd, WT2);
5149
        GEN_STORE_FTN_FREG(fd, WTH2);
5150
        opn = "msub.ps";
5151
        break;
5152
    case OPC_NMADD_S:
5153
        GEN_LOAD_FREG_FTN(WT0, fs);
5154
        GEN_LOAD_FREG_FTN(WT1, ft);
5155
        GEN_LOAD_FREG_FTN(WT2, fr);
5156
        gen_op_float_nmuladd_s();
5157
        GEN_STORE_FTN_FREG(fd, WT2);
5158
        opn = "nmadd.s";
5159
        break;
5160
    case OPC_NMADD_D:
5161
        GEN_LOAD_FREG_FTN(DT0, fs);
5162
        GEN_LOAD_FREG_FTN(DT1, ft);
5163
        GEN_LOAD_FREG_FTN(DT2, fr);
5164
        gen_op_float_nmuladd_d();
5165
        GEN_STORE_FTN_FREG(fd, DT2);
5166
        opn = "nmadd.d";
5167
        break;
5168
    case OPC_NMADD_PS:
5169
        GEN_LOAD_FREG_FTN(WT0, fs);
5170
        GEN_LOAD_FREG_FTN(WTH0, fs);
5171
        GEN_LOAD_FREG_FTN(WT1, ft);
5172
        GEN_LOAD_FREG_FTN(WTH1, ft);
5173
        GEN_LOAD_FREG_FTN(WT2, fr);
5174
        GEN_LOAD_FREG_FTN(WTH2, fr);
5175
        gen_op_float_nmuladd_ps();
5176
        GEN_STORE_FTN_FREG(fd, WT2);
5177
        GEN_STORE_FTN_FREG(fd, WTH2);
5178
        opn = "nmadd.ps";
5179
        break;
5180
    case OPC_NMSUB_S:
5181
        GEN_LOAD_FREG_FTN(WT0, fs);
5182
        GEN_LOAD_FREG_FTN(WT1, ft);
5183
        GEN_LOAD_FREG_FTN(WT2, fr);
5184
        gen_op_float_nmulsub_s();
5185
        GEN_STORE_FTN_FREG(fd, WT2);
5186
        opn = "nmsub.s";
5187
        break;
5188
    case OPC_NMSUB_D:
5189
        GEN_LOAD_FREG_FTN(DT0, fs);
5190
        GEN_LOAD_FREG_FTN(DT1, ft);
5191
        GEN_LOAD_FREG_FTN(DT2, fr);
5192
        gen_op_float_nmulsub_d();
5193
        GEN_STORE_FTN_FREG(fd, DT2);
5194
        opn = "nmsub.d";
5195
        break;
5196
    case OPC_NMSUB_PS:
5197
        GEN_LOAD_FREG_FTN(WT0, fs);
5198
        GEN_LOAD_FREG_FTN(WTH0, fs);
5199
        GEN_LOAD_FREG_FTN(WT1, ft);
5200
        GEN_LOAD_FREG_FTN(WTH1, ft);
5201
        GEN_LOAD_FREG_FTN(WT2, fr);
5202
        GEN_LOAD_FREG_FTN(WTH2, fr);
5203
        gen_op_float_nmulsub_ps();
5204
        GEN_STORE_FTN_FREG(fd, WT2);
5205
        GEN_STORE_FTN_FREG(fd, WTH2);
5206
        opn = "nmsub.ps";
5207
        break;
5208
    default:
5209
        MIPS_INVAL(opn);
5210
        generate_exception (ctx, EXCP_RI);
5211
        return;
5212
    }
5213
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5214
               fregnames[fs], fregnames[ft]);
5215
}
5216

    
5217
/* ISA extensions (ASEs) */
5218
/* MIPS16 extension to MIPS32 */
5219
/* SmartMIPS extension to MIPS32 */
5220

    
5221
#ifdef TARGET_MIPS64
5222

    
5223
/* MDMX extension to MIPS64 */
5224
/* MIPS-3D extension to MIPS64 */
5225

    
5226
#endif
5227

    
5228
static void decode_opc (CPUState *env, DisasContext *ctx)
5229
{
5230
    int32_t offset;
5231
    int rs, rt, rd, sa;
5232
    uint32_t op, op1, op2;
5233
    int16_t imm;
5234

    
5235
    /* make sure instructions are on a word boundary */
5236
    if (ctx->pc & 0x3) {
5237
        env->CP0_BadVAddr = ctx->pc;
5238
        generate_exception(ctx, EXCP_AdEL);
5239
        return;
5240
    }
5241

    
5242
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5243
        int l1;
5244
        /* Handle blikely not taken case */
5245
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5246
        l1 = gen_new_label();
5247
        gen_op_jnz_T2(l1);
5248
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5249
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5250
        gen_set_label(l1);
5251
    }
5252
    op = MASK_OP_MAJOR(ctx->opcode);
5253
    rs = (ctx->opcode >> 21) & 0x1f;
5254
    rt = (ctx->opcode >> 16) & 0x1f;
5255
    rd = (ctx->opcode >> 11) & 0x1f;
5256
    sa = (ctx->opcode >> 6) & 0x1f;
5257
    imm = (int16_t)ctx->opcode;
5258
    switch (op) {
5259
    case OPC_SPECIAL:
5260
        op1 = MASK_SPECIAL(ctx->opcode);
5261
        switch (op1) {
5262
        case OPC_SLL:          /* Arithmetic with immediate */
5263
        case OPC_SRL ... OPC_SRA:
5264
            gen_arith_imm(ctx, op1, rd, rt, sa);
5265
            break;
5266
        case OPC_SLLV:         /* Arithmetic */
5267
        case OPC_SRLV ... OPC_SRAV:
5268
        case OPC_MOVZ ... OPC_MOVN:
5269
        case OPC_ADD ... OPC_NOR:
5270
        case OPC_SLT ... OPC_SLTU:
5271
            gen_arith(ctx, op1, rd, rs, rt);
5272
            break;
5273
        case OPC_MULT ... OPC_DIVU:
5274
            gen_muldiv(ctx, op1, rs, rt);
5275
            break;
5276
        case OPC_JR ... OPC_JALR:
5277
            gen_compute_branch(ctx, op1, rs, rd, sa);
5278
            return;
5279
        case OPC_TGE ... OPC_TEQ: /* Traps */
5280
        case OPC_TNE:
5281
            gen_trap(ctx, op1, rs, rt, -1);
5282
            break;
5283
        case OPC_MFHI:          /* Move from HI/LO */
5284
        case OPC_MFLO:
5285
            gen_HILO(ctx, op1, rd);
5286
            break;
5287
        case OPC_MTHI:
5288
        case OPC_MTLO:          /* Move to HI/LO */
5289
            gen_HILO(ctx, op1, rs);
5290
            break;
5291
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5292
#ifdef MIPS_STRICT_STANDARD
5293
            MIPS_INVAL("PMON / selsl");
5294
            generate_exception(ctx, EXCP_RI);
5295
#else
5296
            gen_op_pmon(sa);
5297
#endif
5298
            break;
5299
        case OPC_SYSCALL:
5300
            generate_exception(ctx, EXCP_SYSCALL);
5301
            break;
5302
        case OPC_BREAK:
5303
            /* XXX: Hack to work around wrong handling of self-modifying code. */
5304
            ctx->pc += 4;
5305
            save_cpu_state(ctx, 1);
5306
            ctx->pc -= 4;
5307
            generate_exception(ctx, EXCP_BREAK);
5308
            break;
5309
        case OPC_SPIM:
5310
#ifdef MIPS_STRICT_STANDARD
5311
            MIPS_INVAL("SPIM");
5312
            generate_exception(ctx, EXCP_RI);
5313
#else
5314
           /* Implemented as RI exception for now. */
5315
            MIPS_INVAL("spim (unofficial)");
5316
            generate_exception(ctx, EXCP_RI);
5317
#endif
5318
            break;
5319
        case OPC_SYNC:
5320
            /* Treat as a noop. */
5321
            break;
5322

    
5323
        case OPC_MOVCI:
5324
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5325
                save_cpu_state(ctx, 1);
5326
                gen_op_cp1_enabled();
5327
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5328
                          (ctx->opcode >> 16) & 1);
5329
            } else {
5330
                generate_exception_err(ctx, EXCP_CpU, 1);
5331
            }
5332
            break;
5333

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

    
5578
    /* Floating point (COP1). */
5579
    case OPC_LWC1:
5580
    case OPC_LDC1:
5581
    case OPC_SWC1:
5582
    case OPC_SDC1:
5583
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5584
            save_cpu_state(ctx, 1);
5585
            gen_op_cp1_enabled();
5586
            gen_flt_ldst(ctx, op, rt, rs, imm);
5587
        } else {
5588
            generate_exception_err(ctx, EXCP_CpU, 1);
5589
        }
5590
        break;
5591

    
5592
    case OPC_CP1:
5593
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5594
            save_cpu_state(ctx, 1);
5595
            gen_op_cp1_enabled();
5596
            op1 = MASK_CP1(ctx->opcode);
5597
            switch (op1) {
5598
            case OPC_MFC1:
5599
            case OPC_CFC1:
5600
            case OPC_MTC1:
5601
            case OPC_CTC1:
5602
#ifdef TARGET_MIPS64
5603
            case OPC_DMFC1:
5604
            case OPC_DMTC1:
5605
#endif
5606
            case OPC_MFHC1:
5607
            case OPC_MTHC1:
5608
                gen_cp1(ctx, op1, rt, rd);
5609
                break;
5610
            case OPC_BC1:
5611
            case OPC_BC1ANY2:
5612
            case OPC_BC1ANY4:
5613
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5614
                                    (rt >> 2) & 0x7, imm << 2);
5615
                return;
5616
            case OPC_S_FMT:
5617
            case OPC_D_FMT:
5618
            case OPC_W_FMT:
5619
            case OPC_L_FMT:
5620
            case OPC_PS_FMT:
5621
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5622
                           (imm >> 8) & 0x7);
5623
                break;
5624
            default:
5625
                MIPS_INVAL("cp1");
5626
                generate_exception (ctx, EXCP_RI);
5627
                break;
5628
            }
5629
        } else {
5630
            generate_exception_err(ctx, EXCP_CpU, 1);
5631
        }
5632
        break;
5633

    
5634
    /* COP2.  */
5635
    case OPC_LWC2:
5636
    case OPC_LDC2:
5637
    case OPC_SWC2:
5638
    case OPC_SDC2:
5639
    case OPC_CP2:
5640
        /* COP2: Not implemented. */
5641
        generate_exception_err(ctx, EXCP_CpU, 2);
5642
        break;
5643

    
5644
    case OPC_CP3:
5645
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5646
            save_cpu_state(ctx, 1);
5647
            gen_op_cp1_enabled();
5648
            op1 = MASK_CP3(ctx->opcode);
5649
            switch (op1) {
5650
            case OPC_LWXC1:
5651
            case OPC_LDXC1:
5652
            case OPC_LUXC1:
5653
            case OPC_SWXC1:
5654
            case OPC_SDXC1:
5655
            case OPC_SUXC1:
5656
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5657
                break;
5658
            case OPC_PREFX:
5659
                /* treat as noop */
5660
                break;
5661
            case OPC_ALNV_PS:
5662
            case OPC_MADD_S:
5663
            case OPC_MADD_D:
5664
            case OPC_MADD_PS:
5665
            case OPC_MSUB_S:
5666
            case OPC_MSUB_D:
5667
            case OPC_MSUB_PS:
5668
            case OPC_NMADD_S:
5669
            case OPC_NMADD_D:
5670
            case OPC_NMADD_PS:
5671
            case OPC_NMSUB_S:
5672
            case OPC_NMSUB_D:
5673
            case OPC_NMSUB_PS:
5674
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5675
                break;
5676
            default:
5677
                MIPS_INVAL("cp3");
5678
                generate_exception (ctx, EXCP_RI);
5679
                break;
5680
            }
5681
        } else {
5682
            generate_exception_err(ctx, EXCP_CpU, 1);
5683
        }
5684
        break;
5685

    
5686
#ifdef TARGET_MIPS64
5687
    /* MIPS64 opcodes */
5688
    case OPC_LWU:
5689
    case OPC_LDL ... OPC_LDR:
5690
    case OPC_SDL ... OPC_SDR:
5691
    case OPC_LLD:
5692
    case OPC_LD:
5693
    case OPC_SCD:
5694
    case OPC_SD:
5695
        gen_ldst(ctx, op, rt, rs, imm);
5696
        break;
5697
    case OPC_DADDI ... OPC_DADDIU:
5698
        gen_arith_imm(ctx, op, rt, rs, imm);
5699
        break;
5700
#endif
5701
#ifdef MIPS_HAS_MIPS16
5702
    case OPC_JALX:
5703
        /* MIPS16: Not implemented. */
5704
#endif
5705
#ifdef MIPS_HAS_MDMX
5706
    case OPC_MDMX:
5707
        /* MDMX: Not implemented. */
5708
#endif
5709
    default:            /* Invalid */
5710
        MIPS_INVAL("major opcode");
5711
        generate_exception(ctx, EXCP_RI);
5712
        break;
5713
    }
5714
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5715
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5716
        /* Branches completion */
5717
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5718
        ctx->bstate = BS_BRANCH;
5719
        save_cpu_state(ctx, 0);
5720
        switch (hflags) {
5721
        case MIPS_HFLAG_B:
5722
            /* unconditional branch */
5723
            MIPS_DEBUG("unconditional branch");
5724
            gen_goto_tb(ctx, 0, ctx->btarget);
5725
            break;
5726
        case MIPS_HFLAG_BL:
5727
            /* blikely taken case */
5728
            MIPS_DEBUG("blikely branch taken");
5729
            gen_goto_tb(ctx, 0, ctx->btarget);
5730
            break;
5731
        case MIPS_HFLAG_BC:
5732
            /* Conditional branch */
5733
            MIPS_DEBUG("conditional branch");
5734
            {
5735
              int l1;
5736
              l1 = gen_new_label();
5737
              gen_op_jnz_T2(l1);
5738
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5739
              gen_set_label(l1);
5740
              gen_goto_tb(ctx, 0, ctx->btarget);
5741
            }
5742
            break;
5743
        case MIPS_HFLAG_BR:
5744
            /* unconditional branch to register */
5745
            MIPS_DEBUG("branch to register");
5746
            gen_op_breg();
5747
            gen_op_reset_T0();
5748
            gen_op_exit_tb();
5749
            break;
5750
        default:
5751
            MIPS_DEBUG("unknown branch");
5752
            break;
5753
        }
5754
    }
5755
}
5756

    
5757
static inline int
5758
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5759
                                int search_pc)
5760
{
5761
    DisasContext ctx, *ctxp = &ctx;
5762
    target_ulong pc_start;
5763
    uint16_t *gen_opc_end;
5764
    int j, lj = -1;
5765

    
5766
    if (search_pc && loglevel)
5767
        fprintf (logfile, "search pc %d\n", search_pc);
5768

    
5769
    pc_start = tb->pc;
5770
    gen_opc_ptr = gen_opc_buf;
5771
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5772
    gen_opparam_ptr = gen_opparam_buf;
5773
    nb_gen_labels = 0;
5774
    ctx.pc = pc_start;
5775
    ctx.saved_pc = -1;
5776
    ctx.tb = tb;
5777
    ctx.bstate = BS_NONE;
5778
    /* Restore delay slot state from the tb context.  */
5779
    ctx.hflags = tb->flags;
5780
    restore_cpu_state(env, &ctx);
5781
#if defined(CONFIG_USER_ONLY)
5782
    ctx.mem_idx = 0;
5783
#else
5784
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5785
#endif
5786
#ifdef DEBUG_DISAS
5787
    if (loglevel & CPU_LOG_TB_CPU) {
5788
        fprintf(logfile, "------------------------------------------------\n");
5789
        /* FIXME: This may print out stale hflags from env... */
5790
        cpu_dump_state(env, logfile, fprintf, 0);
5791
    }
5792
#endif
5793
#ifdef MIPS_DEBUG_DISAS
5794
    if (loglevel & CPU_LOG_TB_IN_ASM)
5795
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5796
                tb, ctx.mem_idx, ctx.hflags);
5797
#endif
5798
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5799
        if (env->nb_breakpoints > 0) {
5800
            for(j = 0; j < env->nb_breakpoints; j++) {
5801
                if (env->breakpoints[j] == ctx.pc) {
5802
                    save_cpu_state(ctxp, 1);
5803
                    ctx.bstate = BS_BRANCH;
5804
                    gen_op_debug();
5805
                    goto done_generating;
5806
                }
5807
            }
5808
        }
5809

    
5810
        if (search_pc) {
5811
            j = gen_opc_ptr - gen_opc_buf;
5812
            if (lj < j) {
5813
                lj++;
5814
                while (lj < j)
5815
                    gen_opc_instr_start[lj++] = 0;
5816
            }
5817
            gen_opc_pc[lj] = ctx.pc;
5818
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5819
            gen_opc_instr_start[lj] = 1;
5820
        }
5821
        ctx.opcode = ldl_code(ctx.pc);
5822
        decode_opc(env, &ctx);
5823
        ctx.pc += 4;
5824

    
5825
        if (env->singlestep_enabled)
5826
            break;
5827

    
5828
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5829
            break;
5830

    
5831
#if defined (MIPS_SINGLE_STEP)
5832
        break;
5833
#endif
5834
    }
5835
    if (env->singlestep_enabled) {
5836
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5837
        gen_op_debug();
5838
    } else {
5839
        switch (ctx.bstate) {
5840
        case BS_STOP:
5841
            gen_op_interrupt_restart();
5842
            gen_goto_tb(&ctx, 0, ctx.pc);
5843
            break;
5844
        case BS_NONE:
5845
            save_cpu_state(ctxp, 0);
5846
            gen_goto_tb(&ctx, 0, ctx.pc);
5847
            break;
5848
        case BS_EXCP:
5849
            gen_op_interrupt_restart();
5850
            gen_op_reset_T0();
5851
            gen_op_exit_tb();
5852
            break;
5853
        case BS_BRANCH:
5854
        default:
5855
            break;
5856
        }
5857
    }
5858
done_generating:
5859
    *gen_opc_ptr = INDEX_op_end;
5860
    if (search_pc) {
5861
        j = gen_opc_ptr - gen_opc_buf;
5862
        lj++;
5863
        while (lj <= j)
5864
            gen_opc_instr_start[lj++] = 0;
5865
        tb->size = 0;
5866
    } else {
5867
        tb->size = ctx.pc - pc_start;
5868
    }
5869
#ifdef DEBUG_DISAS
5870
#if defined MIPS_DEBUG_DISAS
5871
    if (loglevel & CPU_LOG_TB_IN_ASM)
5872
        fprintf(logfile, "\n");
5873
#endif
5874
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5875
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5876
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5877
        fprintf(logfile, "\n");
5878
    }
5879
    if (loglevel & CPU_LOG_TB_OP) {
5880
        fprintf(logfile, "OP:\n");
5881
        dump_ops(gen_opc_buf, gen_opparam_buf);
5882
        fprintf(logfile, "\n");
5883
    }
5884
    if (loglevel & CPU_LOG_TB_CPU) {
5885
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5886
    }
5887
#endif
5888
    
5889
    return 0;
5890
}
5891

    
5892
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5893
{
5894
    return gen_intermediate_code_internal(env, tb, 0);
5895
}
5896

    
5897
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5898
{
5899
    return gen_intermediate_code_internal(env, tb, 1);
5900
}
5901

    
5902
void fpu_dump_state(CPUState *env, FILE *f, 
5903
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5904
                    int flags)
5905
{
5906
    int i;
5907
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5908

    
5909
#define printfpr(fp)                                                        \
5910
    do {                                                                    \
5911
        if (is_fpu64)                                                       \
5912
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5913
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5914
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5915
        else {                                                              \
5916
            fpr_t tmp;                                                      \
5917
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
5918
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
5919
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
5920
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
5921
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
5922
        }                                                                   \
5923
    } while(0)
5924

    
5925

    
5926
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
5927
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
5928
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5929
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5930
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5931
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
5932
        fpu_fprintf(f, "%3s: ", fregnames[i]);
5933
        printfpr(&env->fpr[i]);
5934
    }
5935

    
5936
#undef printfpr
5937
}
5938

    
5939
void dump_fpu (CPUState *env)
5940
{
5941
    if (loglevel) { 
5942
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5943
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5944
       fpu_dump_state(env, logfile, fprintf, 0);
5945
    }
5946
}
5947

    
5948
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5949
/* Debug help: The architecture requires 32bit code to maintain proper
5950
   sign-extened values on 64bit machines.  */
5951

    
5952
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5953

    
5954
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5955
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5956
                     int flags)
5957
{
5958
    int i;
5959

    
5960
    if (!SIGN_EXT_P(env->PC))
5961
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5962
    if (!SIGN_EXT_P(env->HI))
5963
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5964
    if (!SIGN_EXT_P(env->LO))
5965
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5966
    if (!SIGN_EXT_P(env->btarget))
5967
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5968

    
5969
    for (i = 0; i < 32; i++) {
5970
        if (!SIGN_EXT_P(env->gpr[i]))
5971
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5972
    }
5973

    
5974
    if (!SIGN_EXT_P(env->CP0_EPC))
5975
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5976
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5977
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5978
}
5979
#endif
5980

    
5981
void cpu_dump_state (CPUState *env, FILE *f, 
5982
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5983
                     int flags)
5984
{
5985
    uint32_t c0_status;
5986
    int i;
5987
    
5988
    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",
5989
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5990
    for (i = 0; i < 32; i++) {
5991
        if ((i & 3) == 0)
5992
            cpu_fprintf(f, "GPR%02d:", i);
5993
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5994
        if ((i & 3) == 3)
5995
            cpu_fprintf(f, "\n");
5996
    }
5997

    
5998
    c0_status = env->CP0_Status;
5999

    
6000
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6001
                c0_status, env->CP0_Cause, env->CP0_EPC);
6002
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6003
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6004
    if (c0_status & (1 << CP0St_CU1))
6005
        fpu_dump_state(env, f, cpu_fprintf, flags);
6006
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6007
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6008
#endif
6009
}
6010

    
6011
CPUMIPSState *cpu_mips_init (void)
6012
{
6013
    CPUMIPSState *env;
6014

    
6015
    env = qemu_mallocz(sizeof(CPUMIPSState));
6016
    if (!env)
6017
        return NULL;
6018
    cpu_exec_init(env);
6019
    cpu_reset(env);
6020
    return env;
6021
}
6022

    
6023
void cpu_reset (CPUMIPSState *env)
6024
{
6025
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6026

    
6027
    tlb_flush(env, 1);
6028

    
6029
    /* Minimal init */
6030
#if !defined(CONFIG_USER_ONLY)
6031
    if (env->hflags & MIPS_HFLAG_BMASK) {
6032
        /* If the exception was raised from a delay slot,
6033
         * come back to the jump.  */
6034
        env->CP0_ErrorEPC = env->PC - 4;
6035
        env->hflags &= ~MIPS_HFLAG_BMASK;
6036
    } else {
6037
        env->CP0_ErrorEPC = env->PC;
6038
    }
6039
    env->hflags = 0;
6040
    env->PC = (int32_t)0xBFC00000;
6041
    env->CP0_Wired = 0;
6042
    /* SMP not implemented */
6043
    env->CP0_EBase = 0x80000000;
6044
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6045
    /* vectored interrupts not implemented, timer on int 7,
6046
       no performance counters. */
6047
    env->CP0_IntCtl = 0xe0000000;
6048
    {
6049
        int i;
6050

    
6051
        for (i = 0; i < 7; i++) {
6052
            env->CP0_WatchLo[i] = 0;
6053
            env->CP0_WatchHi[i] = 0x80000000;
6054
        }
6055
        env->CP0_WatchLo[7] = 0;
6056
        env->CP0_WatchHi[7] = 0;
6057
    }
6058
    /* Count register increments in debug mode, EJTAG version 1 */
6059
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6060
#endif
6061
    env->exception_index = EXCP_NONE;
6062
#if defined(CONFIG_USER_ONLY)
6063
    env->hflags |= MIPS_HFLAG_UM;
6064
    env->user_mode_only = 1;
6065
#endif
6066
}
6067

    
6068
#include "translate_init.c"