Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 34ae7b51

History | View | Annotate | Download (164.4 kB)

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

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

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

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

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

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

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

    
53
#include "gen-op.h"
54

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3574
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3575
{
3576
    const char *rn = "invalid";
3577

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

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

    
4171
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4172
{
4173
    const char *opn = "ldst";
4174

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

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

    
4272
    btarget = ctx->pc + 4 + offset;
4273

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

    
4324
/* Coprocessor 1 (FPU) */
4325

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

    
4347
#define FOP(func, fmt) (((fmt) << 21) | (func))
4348

    
4349
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4350
{
4351
    const char *opn = "cp1 move";
4352

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

    
4412
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4413
{
4414
    uint32_t ccbit;
4415

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

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

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

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

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

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

    
5163
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5164
                            int fr, int fs, int ft)
5165
{
5166
    const char *opn = "flt3_arith";
5167

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

    
5300
/* ISA extensions (ASEs) */
5301
/* MIPS16 extension to MIPS32 */
5302
/* SmartMIPS extension to MIPS32 */
5303

    
5304
#ifdef TARGET_MIPS64
5305

    
5306
/* MDMX extension to MIPS64 */
5307
/* MIPS-3D extension to MIPS64 */
5308

    
5309
#endif
5310

    
5311
static void decode_opc (CPUState *env, DisasContext *ctx)
5312
{
5313
    int32_t offset;
5314
    int rs, rt, rd, sa;
5315
    uint32_t op, op1, op2;
5316
    int16_t imm;
5317

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

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

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

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

    
5675
    /* Floating point (COP1). */
5676
    case OPC_LWC1:
5677
    case OPC_LDC1:
5678
    case OPC_SWC1:
5679
    case OPC_SDC1:
5680
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5681
            save_cpu_state(ctx, 1);
5682
            gen_op_cp1_enabled();
5683
            gen_flt_ldst(ctx, op, rt, rs, imm);
5684
        } else {
5685
            generate_exception_err(ctx, EXCP_CpU, 1);
5686
        }
5687
        break;
5688

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

    
5731
    /* COP2.  */
5732
    case OPC_LWC2:
5733
    case OPC_LDC2:
5734
    case OPC_SWC2:
5735
    case OPC_SDC2:
5736
    case OPC_CP2:
5737
        /* COP2: Not implemented. */
5738
        generate_exception_err(ctx, EXCP_CpU, 2);
5739
        break;
5740

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

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

    
5854
static inline int
5855
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5856
                                int search_pc)
5857
{
5858
    DisasContext ctx, *ctxp = &ctx;
5859
    target_ulong pc_start;
5860
    uint16_t *gen_opc_end;
5861
    int j, lj = -1;
5862

    
5863
    if (search_pc && loglevel)
5864
        fprintf (logfile, "search pc %d\n", search_pc);
5865

    
5866
    pc_start = tb->pc;
5867
    gen_opc_ptr = gen_opc_buf;
5868
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5869
    gen_opparam_ptr = gen_opparam_buf;
5870
    nb_gen_labels = 0;
5871
    ctx.pc = pc_start;
5872
    ctx.saved_pc = -1;
5873
    ctx.tb = tb;
5874
    ctx.bstate = BS_NONE;
5875
    /* Restore delay slot state from the tb context.  */
5876
    ctx.hflags = tb->flags;
5877
    ctx.saved_hflags = ctx.hflags;
5878
    switch (ctx.hflags & MIPS_HFLAG_BMASK) {
5879
    case MIPS_HFLAG_BR:
5880
        gen_op_restore_breg_target();
5881
        break;
5882
    case MIPS_HFLAG_B:
5883
        ctx.btarget = env->btarget;
5884
        break;
5885
    case MIPS_HFLAG_BC:
5886
    case MIPS_HFLAG_BL:
5887
        ctx.btarget = env->btarget;
5888
        gen_op_restore_bcond();
5889
        break;
5890
    }
5891
#if defined(CONFIG_USER_ONLY)
5892
    ctx.mem_idx = 0;
5893
#else
5894
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5895
#endif
5896
    ctx.CP0_Status = env->CP0_Status;
5897
#ifdef DEBUG_DISAS
5898
    if (loglevel & CPU_LOG_TB_CPU) {
5899
        fprintf(logfile, "------------------------------------------------\n");
5900
        /* FIXME: This may print out stale hflags from env... */
5901
        cpu_dump_state(env, logfile, fprintf, 0);
5902
    }
5903
#endif
5904
#ifdef MIPS_DEBUG_DISAS
5905
    if (loglevel & CPU_LOG_TB_IN_ASM)
5906
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5907
                tb, ctx.mem_idx, ctx.hflags);
5908
#endif
5909
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5910
        if (env->nb_breakpoints > 0) {
5911
            for(j = 0; j < env->nb_breakpoints; j++) {
5912
                if (env->breakpoints[j] == ctx.pc) {
5913
                    save_cpu_state(ctxp, 1);
5914
                    ctx.bstate = BS_BRANCH;
5915
                    gen_op_debug();
5916
                    goto done_generating;
5917
                }
5918
            }
5919
        }
5920

    
5921
        if (search_pc) {
5922
            j = gen_opc_ptr - gen_opc_buf;
5923
            if (lj < j) {
5924
                lj++;
5925
                while (lj < j)
5926
                    gen_opc_instr_start[lj++] = 0;
5927
            }
5928
            gen_opc_pc[lj] = ctx.pc;
5929
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5930
            gen_opc_instr_start[lj] = 1;
5931
        }
5932
        ctx.opcode = ldl_code(ctx.pc);
5933
        decode_opc(env, &ctx);
5934
        ctx.pc += 4;
5935

    
5936
        if (env->singlestep_enabled)
5937
            break;
5938

    
5939
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5940
            break;
5941

    
5942
#if defined (MIPS_SINGLE_STEP)
5943
        break;
5944
#endif
5945
    }
5946
    if (env->singlestep_enabled) {
5947
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5948
        gen_op_debug();
5949
    } else {
5950
        switch (ctx.bstate) {
5951
        case BS_STOP:
5952
            gen_op_interrupt_restart();
5953
            /* Fall through. */
5954
        case BS_NONE:
5955
            save_cpu_state(ctxp, 0);
5956
            gen_goto_tb(&ctx, 0, ctx.pc);
5957
            break;
5958
        case BS_EXCP:
5959
            gen_op_interrupt_restart();
5960
            gen_op_reset_T0();
5961
            gen_op_exit_tb();
5962
            break;
5963
        case BS_BRANCH:
5964
        default:
5965
            break;
5966
        }
5967
    }
5968
done_generating:
5969
    *gen_opc_ptr = INDEX_op_end;
5970
    if (search_pc) {
5971
        j = gen_opc_ptr - gen_opc_buf;
5972
        lj++;
5973
        while (lj <= j)
5974
            gen_opc_instr_start[lj++] = 0;
5975
        tb->size = 0;
5976
    } else {
5977
        tb->size = ctx.pc - pc_start;
5978
    }
5979
#ifdef DEBUG_DISAS
5980
#if defined MIPS_DEBUG_DISAS
5981
    if (loglevel & CPU_LOG_TB_IN_ASM)
5982
        fprintf(logfile, "\n");
5983
#endif
5984
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5985
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5986
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5987
        fprintf(logfile, "\n");
5988
    }
5989
    if (loglevel & CPU_LOG_TB_OP) {
5990
        fprintf(logfile, "OP:\n");
5991
        dump_ops(gen_opc_buf, gen_opparam_buf);
5992
        fprintf(logfile, "\n");
5993
    }
5994
    if (loglevel & CPU_LOG_TB_CPU) {
5995
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5996
    }
5997
#endif
5998
    
5999
    return 0;
6000
}
6001

    
6002
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6003
{
6004
    return gen_intermediate_code_internal(env, tb, 0);
6005
}
6006

    
6007
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6008
{
6009
    return gen_intermediate_code_internal(env, tb, 1);
6010
}
6011

    
6012
void fpu_dump_state(CPUState *env, FILE *f, 
6013
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6014
                    int flags)
6015
{
6016
    int i;
6017
    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
6018

    
6019
#define printfpr(fp)                                                        \
6020
    do {                                                                    \
6021
        if (is_fpu64)                                                       \
6022
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6023
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6024
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6025
        else {                                                              \
6026
            fpr_t tmp;                                                      \
6027
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6028
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6029
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6030
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6031
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6032
        }                                                                   \
6033
    } while(0)
6034

    
6035

    
6036
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6037
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6038
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6039
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6040
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
6041
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6042
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6043
        printfpr(&env->fpr[i]);
6044
    }
6045

    
6046
#undef printfpr
6047
}
6048

    
6049
void dump_fpu (CPUState *env)
6050
{
6051
    if (loglevel) { 
6052
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6053
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6054
       fpu_dump_state(env, logfile, fprintf, 0);
6055
    }
6056
}
6057

    
6058
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6059
/* Debug help: The architecture requires 32bit code to maintain proper
6060
   sign-extened values on 64bit machines.  */
6061

    
6062
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6063

    
6064
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6065
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6066
                     int flags)
6067
{
6068
    int i;
6069

    
6070
    if (!SIGN_EXT_P(env->PC))
6071
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6072
    if (!SIGN_EXT_P(env->HI))
6073
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6074
    if (!SIGN_EXT_P(env->LO))
6075
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6076
    if (!SIGN_EXT_P(env->btarget))
6077
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6078

    
6079
    for (i = 0; i < 32; i++) {
6080
        if (!SIGN_EXT_P(env->gpr[i]))
6081
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6082
    }
6083

    
6084
    if (!SIGN_EXT_P(env->CP0_EPC))
6085
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6086
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6087
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6088
}
6089
#endif
6090

    
6091
void cpu_dump_state (CPUState *env, FILE *f, 
6092
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6093
                     int flags)
6094
{
6095
    uint32_t c0_status;
6096
    int i;
6097
    
6098
    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",
6099
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6100
    for (i = 0; i < 32; i++) {
6101
        if ((i & 3) == 0)
6102
            cpu_fprintf(f, "GPR%02d:", i);
6103
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6104
        if ((i & 3) == 3)
6105
            cpu_fprintf(f, "\n");
6106
    }
6107

    
6108
    c0_status = env->CP0_Status;
6109

    
6110
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6111
                c0_status, env->CP0_Cause, env->CP0_EPC);
6112
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6113
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6114
    if (c0_status & (1 << CP0St_CU1))
6115
        fpu_dump_state(env, f, cpu_fprintf, flags);
6116
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6117
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6118
#endif
6119
}
6120

    
6121
CPUMIPSState *cpu_mips_init (void)
6122
{
6123
    CPUMIPSState *env;
6124

    
6125
    env = qemu_mallocz(sizeof(CPUMIPSState));
6126
    if (!env)
6127
        return NULL;
6128
    cpu_exec_init(env);
6129
    cpu_reset(env);
6130
    return env;
6131
}
6132

    
6133
void cpu_reset (CPUMIPSState *env)
6134
{
6135
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6136

    
6137
    tlb_flush(env, 1);
6138

    
6139
    /* Minimal init */
6140
#if !defined(CONFIG_USER_ONLY)
6141
    if (env->hflags & MIPS_HFLAG_BMASK) {
6142
        /* If the exception was raised from a delay slot,
6143
         * come back to the jump.  */
6144
        env->CP0_ErrorEPC = env->PC - 4;
6145
        env->hflags &= ~MIPS_HFLAG_BMASK;
6146
    } else {
6147
        env->CP0_ErrorEPC = env->PC;
6148
    }
6149
    env->hflags = 0;
6150
    env->PC = (int32_t)0xBFC00000;
6151
    env->CP0_Wired = 0;
6152
    /* SMP not implemented */
6153
    env->CP0_EBase = 0x80000000;
6154
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6155
    /* vectored interrupts not implemented, timer on int 7,
6156
       no performance counters. */
6157
    env->CP0_IntCtl = 0xe0000000;
6158
    env->CP0_WatchLo = 0;
6159
    env->CP0_WatchHi = 0;
6160
    /* Count register increments in debug mode, EJTAG version 1 */
6161
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6162
#endif
6163
    env->exception_index = EXCP_NONE;
6164
#if defined(CONFIG_USER_ONLY)
6165
    env->hflags |= MIPS_HFLAG_UM;
6166
    env->user_mode_only = 1;
6167
#endif
6168
}
6169

    
6170
#include "translate_init.c"