Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 90cb786c

History | View | Annotate | Download (219.7 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
#include "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

    
36
//#define MIPS_DEBUG_DISAS
37
//#define MIPS_DEBUG_SIGN_EXTENSIONS
38
//#define MIPS_SINGLE_STEP
39

    
40
/* MIPS major opcodes */
41
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
42

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

    
118
/* MIPS special opcodes */
119
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
120

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

    
186
    /* Special */
187
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
188
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
189
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
190
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
191
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
192

    
193
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
194
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
195
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
196
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
197
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
198
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
199
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
200
};
201

    
202
/* Multiplication variants of the vr54xx. */
203
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
204

    
205
enum {
206
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
207
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
208
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
209
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
210
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
211
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
212
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
213
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
214
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
215
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
216
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
217
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
218
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
219
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
220
};
221

    
222
/* REGIMM (rt field) opcodes */
223
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
224

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

    
243
/* Special2 opcodes */
244
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
245

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

    
262
/* Special3 opcodes */
263
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
264

    
265
enum {
266
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
267
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
268
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
269
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
270
    OPC_INS      = 0x04 | OPC_SPECIAL3,
271
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
272
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
273
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
274
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
275
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
276
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
277
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
278
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
279
};
280

    
281
/* BSHFL opcodes */
282
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
283

    
284
enum {
285
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
286
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
287
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
288
};
289

    
290
/* DBSHFL opcodes */
291
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
292

    
293
enum {
294
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
295
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
296
};
297

    
298
/* Coprocessor 0 (rs field) */
299
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
300

    
301
enum {
302
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
303
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
304
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
305
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
306
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
307
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
308
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
309
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
310
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
311
    OPC_C0       = (0x10 << 21) | OPC_CP0,
312
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
313
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
314
};
315

    
316
/* MFMC0 opcodes */
317
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
318

    
319
enum {
320
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
321
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
322
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
323
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
324
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
325
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
326
};
327

    
328
/* Coprocessor 0 (with rs == C0) */
329
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
330

    
331
enum {
332
    OPC_TLBR     = 0x01 | OPC_C0,
333
    OPC_TLBWI    = 0x02 | OPC_C0,
334
    OPC_TLBWR    = 0x06 | OPC_C0,
335
    OPC_TLBP     = 0x08 | OPC_C0,
336
    OPC_RFE      = 0x10 | OPC_C0,
337
    OPC_ERET     = 0x18 | OPC_C0,
338
    OPC_DERET    = 0x1F | OPC_C0,
339
    OPC_WAIT     = 0x20 | OPC_C0,
340
};
341

    
342
/* Coprocessor 1 (rs field) */
343
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
344

    
345
enum {
346
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
347
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
348
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
349
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
350
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
351
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
352
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
353
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
354
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
355
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
356
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
357
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
358
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
359
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
360
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
361
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
362
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
363
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
364
};
365

    
366
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
367
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
368

    
369
enum {
370
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
371
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
372
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
373
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
374
};
375

    
376
enum {
377
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
378
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
379
};
380

    
381
enum {
382
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
383
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
384
};
385

    
386
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

    
388
enum {
389
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
390
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
391
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
392
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
393
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
394
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
395
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
396
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
397
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
398
};
399

    
400
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
401

    
402
enum {
403
    OPC_LWXC1   = 0x00 | OPC_CP3,
404
    OPC_LDXC1   = 0x01 | OPC_CP3,
405
    OPC_LUXC1   = 0x05 | OPC_CP3,
406
    OPC_SWXC1   = 0x08 | OPC_CP3,
407
    OPC_SDXC1   = 0x09 | OPC_CP3,
408
    OPC_SUXC1   = 0x0D | OPC_CP3,
409
    OPC_PREFX   = 0x0F | OPC_CP3,
410
    OPC_ALNV_PS = 0x1E | OPC_CP3,
411
    OPC_MADD_S  = 0x20 | OPC_CP3,
412
    OPC_MADD_D  = 0x21 | OPC_CP3,
413
    OPC_MADD_PS = 0x26 | OPC_CP3,
414
    OPC_MSUB_S  = 0x28 | OPC_CP3,
415
    OPC_MSUB_D  = 0x29 | OPC_CP3,
416
    OPC_MSUB_PS = 0x2E | OPC_CP3,
417
    OPC_NMADD_S = 0x30 | OPC_CP3,
418
    OPC_NMADD_D = 0x31 | OPC_CP3,
419
    OPC_NMADD_PS= 0x36 | OPC_CP3,
420
    OPC_NMSUB_S = 0x38 | OPC_CP3,
421
    OPC_NMSUB_D = 0x39 | OPC_CP3,
422
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
423
};
424

    
425
/* global register indices */
426
static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2];
427

    
428
/* The code generator doesn't like lots of temporaries, so maintain our own
429
   cache for reuse within a function.  */
430
#define MAX_TEMPS 4
431
static int num_temps;
432
static TCGv temps[MAX_TEMPS];
433

    
434
/* Allocate a temporary variable.  */
435
static TCGv new_tmp(void)
436
{
437
    TCGv tmp;
438
    if (num_temps == MAX_TEMPS)
439
        abort();
440

    
441
    if (GET_TCGV(temps[num_temps]))
442
      return temps[num_temps++];
443

    
444
    tmp = tcg_temp_new(TCG_TYPE_I32);
445
    temps[num_temps++] = tmp;
446
    return tmp;
447
}
448

    
449
/* Release a temporary variable.  */
450
static void dead_tmp(TCGv tmp)
451
{
452
    int i;
453
    num_temps--;
454
    i = num_temps;
455
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
456
        return;
457

    
458
    /* Shuffle this temp to the last slot.  */
459
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
460
        i--;
461
    while (i < num_temps) {
462
        temps[i] = temps[i + 1];
463
        i++;
464
    }
465
    temps[i] = tmp;
466
}
467

    
468
typedef struct DisasContext {
469
    struct TranslationBlock *tb;
470
    target_ulong pc, saved_pc;
471
    uint32_t opcode;
472
    uint32_t fp_status;
473
    /* Routine used to access memory */
474
    int mem_idx;
475
    uint32_t hflags, saved_hflags;
476
    int bstate;
477
    target_ulong btarget;
478
} DisasContext;
479

    
480
enum {
481
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
482
                      * exception condition
483
                      */
484
    BS_STOP     = 1, /* We want to stop translation for any reason */
485
    BS_BRANCH   = 2, /* We reached a branch condition     */
486
    BS_EXCP     = 3, /* We reached an exception condition */
487
};
488

    
489
static const char *regnames[] =
490
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
491
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
492
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
493
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
494

    
495
static const char *fregnames[] =
496
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
497
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
498
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
499
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
500

    
501
#ifdef MIPS_DEBUG_DISAS
502
#define MIPS_DEBUG(fmt, args...)                                              \
503
do {                                                                          \
504
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
505
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
506
                ctx->pc, ctx->opcode , ##args);                               \
507
    }                                                                         \
508
} while (0)
509
#else
510
#define MIPS_DEBUG(fmt, args...) do { } while(0)
511
#endif
512

    
513
#define MIPS_INVAL(op)                                                        \
514
do {                                                                          \
515
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
516
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
517
} while (0)
518

    
519
/* General purpose registers moves. */
520
static inline void gen_load_gpr (TCGv t, int reg)
521
{
522
    if (reg == 0)
523
        tcg_gen_movi_tl(t, 0);
524
    else
525
        tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
526
}
527

    
528
static inline void gen_store_gpr (TCGv t, int reg)
529
{
530
    if (reg != 0)
531
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
532
}
533

    
534
/* Moves to/from HI and LO registers.  */
535
static inline void gen_load_LO (TCGv t, int reg)
536
{
537
    tcg_gen_ld_tl(t, current_tc_hi,
538
                  offsetof(CPUState, LO)
539
                  - offsetof(CPUState, HI)
540
                  + sizeof(target_ulong) * reg);
541
}
542

    
543
static inline void gen_store_LO (TCGv t, int reg)
544
{
545
    tcg_gen_st_tl(t, current_tc_hi,
546
                  offsetof(CPUState, LO)
547
                  - offsetof(CPUState, HI)
548
                  + sizeof(target_ulong) * reg);
549
}
550

    
551
static inline void gen_load_HI (TCGv t, int reg)
552
{
553
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
554
}
555

    
556
static inline void gen_store_HI (TCGv t, int reg)
557
{
558
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
559
}
560

    
561
/* Moves to/from shadow registers. */
562
static inline void gen_load_srsgpr (TCGv t, int reg)
563
{
564
    if (reg == 0)
565
        tcg_gen_movi_tl(t, 0);
566
    else {
567
        TCGv r_tmp = new_tmp();
568

    
569
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
570
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
571
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
572
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
573
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
574

    
575
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
576
        dead_tmp(r_tmp);
577
    }
578
}
579

    
580
static inline void gen_store_srsgpr (TCGv t, int reg)
581
{
582
    if (reg != 0) {
583
        TCGv r_tmp = new_tmp();
584

    
585
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
586
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
587
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
588
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
589
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
590

    
591
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
592
        dead_tmp(r_tmp);
593
    }
594
}
595

    
596
/* Floating point register moves. */
597
#define FGEN32(func, NAME)                       \
598
static GenOpFunc *NAME ## _table [32] = {        \
599
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
600
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
601
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
602
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
603
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
604
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
605
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
606
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
607
};                                               \
608
static always_inline void func(int n)            \
609
{                                                \
610
    NAME ## _table[n]();                         \
611
}
612

    
613
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
614
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
615

    
616
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
617
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
618

    
619
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
620
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
621

    
622
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
623
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
624

    
625
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
626
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
627

    
628
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
629
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
630

    
631
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
632
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
633

    
634
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
635
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
636

    
637
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
638
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
639

    
640
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
641
do {                                                                          \
642
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
643
} while (0)
644

    
645
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
646
do {                                                                          \
647
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
648
} while (0)
649

    
650
#define FOP_CONDS(type, fmt)                                            \
651
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
652
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
653
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
654
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
655
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
656
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
657
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
658
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
659
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
660
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
661
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
662
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
663
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
664
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
665
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
666
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
667
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
668
};                                                                      \
669
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
670
{                                                                       \
671
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
672
}
673

    
674
FOP_CONDS(, d)
675
FOP_CONDS(abs, d)
676
FOP_CONDS(, s)
677
FOP_CONDS(abs, s)
678
FOP_CONDS(, ps)
679
FOP_CONDS(abs, ps)
680

    
681
/* Tests */
682
#define OP_COND(name, cond)                                   \
683
void glue(gen_op_, name) (void)                               \
684
{                                                             \
685
    int l1 = gen_new_label();                                 \
686
    int l2 = gen_new_label();                                 \
687
                                                              \
688
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
689
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
690
    tcg_gen_br(l2);                                           \
691
    gen_set_label(l1);                                        \
692
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
693
    gen_set_label(l2);                                        \
694
}
695
OP_COND(eq, TCG_COND_EQ);
696
OP_COND(ne, TCG_COND_NE);
697
OP_COND(ge, TCG_COND_GE);
698
OP_COND(geu, TCG_COND_GEU);
699
OP_COND(lt, TCG_COND_LT);
700
OP_COND(ltu, TCG_COND_LTU);
701
#undef OP_COND
702

    
703
#define OP_CONDI(name, cond)                                  \
704
void glue(gen_op_, name) (target_ulong val)                   \
705
{                                                             \
706
    int l1 = gen_new_label();                                 \
707
    int l2 = gen_new_label();                                 \
708
                                                              \
709
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
710
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
711
    tcg_gen_br(l2);                                           \
712
    gen_set_label(l1);                                        \
713
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
714
    gen_set_label(l2);                                        \
715
}
716
OP_CONDI(lti, TCG_COND_LT);
717
OP_CONDI(ltiu, TCG_COND_LTU);
718
#undef OP_CONDI
719

    
720
#define OP_CONDZ(name, cond)                                  \
721
void glue(gen_op_, name) (void)                               \
722
{                                                             \
723
    int l1 = gen_new_label();                                 \
724
    int l2 = gen_new_label();                                 \
725
                                                              \
726
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
727
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
728
    tcg_gen_br(l2);                                           \
729
    gen_set_label(l1);                                        \
730
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
731
    gen_set_label(l2);                                        \
732
}
733
OP_CONDZ(gez, TCG_COND_GE);
734
OP_CONDZ(gtz, TCG_COND_GT);
735
OP_CONDZ(lez, TCG_COND_LE);
736
OP_CONDZ(ltz, TCG_COND_LT);
737
#undef OP_CONDZ
738

    
739
static inline void gen_save_pc(target_ulong pc)
740
{
741
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
742
    TCGv r_tc_off = new_tmp();
743
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
744
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
745

    
746
    tcg_gen_movi_tl(r_tmp, pc);
747
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
748
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
749
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
750
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
751
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
752
    dead_tmp(r_tc_off);
753
}
754

    
755
static inline void gen_breg_pc(void)
756
{
757
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
758
    TCGv r_tc_off = new_tmp();
759
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
760
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
761

    
762
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
763
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
764
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
765
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
766
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
767
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
768
    dead_tmp(r_tc_off);
769
}
770

    
771
static inline void gen_save_btarget(target_ulong btarget)
772
{
773
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
774

    
775
    tcg_gen_movi_tl(r_tmp, btarget);
776
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
777
}
778

    
779
static always_inline void gen_save_breg_target(int reg)
780
{
781
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
782

    
783
    gen_load_gpr(r_tmp, reg);
784
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
785
}
786

    
787
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
788
{
789
#if defined MIPS_DEBUG_DISAS
790
    if (loglevel & CPU_LOG_TB_IN_ASM) {
791
            fprintf(logfile, "hflags %08x saved %08x\n",
792
                    ctx->hflags, ctx->saved_hflags);
793
    }
794
#endif
795
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
796
        gen_save_pc(ctx->pc);
797
        ctx->saved_pc = ctx->pc;
798
    }
799
    if (ctx->hflags != ctx->saved_hflags) {
800
        gen_op_save_state(ctx->hflags);
801
        ctx->saved_hflags = ctx->hflags;
802
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
803
        case MIPS_HFLAG_BR:
804
            break;
805
        case MIPS_HFLAG_BC:
806
        case MIPS_HFLAG_BL:
807
        case MIPS_HFLAG_B:
808
            gen_save_btarget(ctx->btarget);
809
            break;
810
        }
811
    }
812
}
813

    
814
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
815
{
816
    ctx->saved_hflags = ctx->hflags;
817
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
818
    case MIPS_HFLAG_BR:
819
        break;
820
    case MIPS_HFLAG_BC:
821
    case MIPS_HFLAG_BL:
822
    case MIPS_HFLAG_B:
823
        ctx->btarget = env->btarget;
824
        break;
825
    }
826
}
827

    
828
static always_inline void
829
generate_exception_err (DisasContext *ctx, int excp, int err)
830
{
831
    save_cpu_state(ctx, 1);
832
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
833
    tcg_gen_helper_0_0(do_interrupt_restart);
834
    tcg_gen_exit_tb(0);
835
}
836

    
837
static always_inline void
838
generate_exception (DisasContext *ctx, int excp)
839
{
840
    save_cpu_state(ctx, 1);
841
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
842
    tcg_gen_helper_0_0(do_interrupt_restart);
843
    tcg_gen_exit_tb(0);
844
}
845

    
846
/* Addresses computation */
847
static inline void gen_op_addr_add (void)
848
{
849
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
850

    
851
#if defined(TARGET_MIPS64)
852
    /* For compatibility with 32-bit code, data reference in user mode
853
       with Status_UX = 0 should be casted to 32-bit and sign extended.
854
       See the MIPS64 PRA manual, section 4.10. */
855
    {
856
        TCGv r_tmp = new_tmp();
857
        int l1 = gen_new_label();
858

    
859
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
860
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
861
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
862
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
863
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
864
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
865
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
866
        gen_set_label(l1);
867
        dead_tmp(r_tmp);
868
    }
869
#endif
870
}
871

    
872
static always_inline void check_cp0_enabled(DisasContext *ctx)
873
{
874
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
875
        generate_exception_err(ctx, EXCP_CpU, 1);
876
}
877

    
878
static always_inline void check_cp1_enabled(DisasContext *ctx)
879
{
880
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
881
        generate_exception_err(ctx, EXCP_CpU, 1);
882
}
883

    
884
/* Verify that the processor is running with COP1X instructions enabled.
885
   This is associated with the nabla symbol in the MIPS32 and MIPS64
886
   opcode tables.  */
887

    
888
static always_inline void check_cop1x(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

    
894
/* Verify that the processor is running with 64-bit floating-point
895
   operations enabled.  */
896

    
897
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
898
{
899
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
900
        generate_exception(ctx, EXCP_RI);
901
}
902

    
903
/*
904
 * Verify if floating point register is valid; an operation is not defined
905
 * if bit 0 of any register specification is set and the FR bit in the
906
 * Status register equals zero, since the register numbers specify an
907
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
908
 * in the Status register equals one, both even and odd register numbers
909
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
910
 *
911
 * Multiple 64 bit wide registers can be checked by calling
912
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
913
 */
914
void check_cp1_registers(DisasContext *ctx, int regs)
915
{
916
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
917
        generate_exception(ctx, EXCP_RI);
918
}
919

    
920
/* This code generates a "reserved instruction" exception if the
921
   CPU does not support the instruction set corresponding to flags. */
922
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
923
{
924
    if (unlikely(!(env->insn_flags & flags)))
925
        generate_exception(ctx, EXCP_RI);
926
}
927

    
928
/* This code generates a "reserved instruction" exception if 64-bit
929
   instructions are not enabled. */
930
static always_inline void check_mips_64(DisasContext *ctx)
931
{
932
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
933
        generate_exception(ctx, EXCP_RI);
934
}
935

    
936
/* load/store instructions. */
937
#if defined(CONFIG_USER_ONLY)
938
#define op_ldst(name)        gen_op_##name##_raw()
939
#define OP_LD_TABLE(width)
940
#define OP_ST_TABLE(width)
941
#else
942
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
943
#define OP_LD_TABLE(width)                                                    \
944
static GenOpFunc *gen_op_l##width[] = {                                       \
945
    &gen_op_l##width##_kernel,                                                \
946
    &gen_op_l##width##_super,                                                 \
947
    &gen_op_l##width##_user,                                                  \
948
}
949
#define OP_ST_TABLE(width)                                                    \
950
static GenOpFunc *gen_op_s##width[] = {                                       \
951
    &gen_op_s##width##_kernel,                                                \
952
    &gen_op_s##width##_super,                                                 \
953
    &gen_op_s##width##_user,                                                  \
954
}
955
#endif
956

    
957
#if defined(TARGET_MIPS64)
958
OP_LD_TABLE(dl);
959
OP_LD_TABLE(dr);
960
OP_ST_TABLE(dl);
961
OP_ST_TABLE(dr);
962
#endif
963
OP_LD_TABLE(wl);
964
OP_LD_TABLE(wr);
965
OP_ST_TABLE(wl);
966
OP_ST_TABLE(wr);
967
OP_LD_TABLE(wc1);
968
OP_ST_TABLE(wc1);
969
OP_LD_TABLE(dc1);
970
OP_ST_TABLE(dc1);
971
OP_LD_TABLE(uxc1);
972
OP_ST_TABLE(uxc1);
973

    
974
#define OP_LD(insn,fname)                                        \
975
void inline op_ldst_##insn(DisasContext *ctx)                    \
976
{                                                                \
977
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
978
}
979
OP_LD(lb,ld8s);
980
OP_LD(lbu,ld8u);
981
OP_LD(lh,ld16s);
982
OP_LD(lhu,ld16u);
983
OP_LD(lw,ld32s);
984
#if defined(TARGET_MIPS64)
985
OP_LD(lwu,ld32u);
986
OP_LD(ld,ld64);
987
#endif
988
#undef OP_LD
989

    
990
#define OP_ST(insn,fname)                                        \
991
void inline op_ldst_##insn(DisasContext *ctx)                    \
992
{                                                                \
993
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
994
}
995
OP_ST(sb,st8);
996
OP_ST(sh,st16);
997
OP_ST(sw,st32);
998
#if defined(TARGET_MIPS64)
999
OP_ST(sd,st64);
1000
#endif
1001
#undef OP_ST
1002

    
1003
#define OP_LD_ATOMIC(insn,fname)                                        \
1004
void inline op_ldst_##insn(DisasContext *ctx)                           \
1005
{                                                                       \
1006
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
1007
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1008
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1009
}
1010
OP_LD_ATOMIC(ll,ld32s);
1011
#if defined(TARGET_MIPS64)
1012
OP_LD_ATOMIC(lld,ld64);
1013
#endif
1014
#undef OP_LD_ATOMIC
1015

    
1016
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1017
void inline op_ldst_##insn(DisasContext *ctx)                           \
1018
{                                                                       \
1019
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
1020
    int l1 = gen_new_label();                                           \
1021
    int l2 = gen_new_label();                                           \
1022
    int l3 = gen_new_label();                                           \
1023
                                                                        \
1024
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1025
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1026
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1027
    generate_exception(ctx, EXCP_AdES);                                 \
1028
    gen_set_label(l1);                                                  \
1029
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1030
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1031
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1032
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1033
    tcg_gen_br(l3);                                                     \
1034
    gen_set_label(l2);                                                  \
1035
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1036
    gen_set_label(l3);                                                  \
1037
}
1038
OP_ST_ATOMIC(sc,st32,0x3);
1039
#if defined(TARGET_MIPS64)
1040
OP_ST_ATOMIC(scd,st64,0x7);
1041
#endif
1042
#undef OP_ST_ATOMIC
1043

    
1044
void inline op_ldst_lwc1(DisasContext *ctx)
1045
{
1046
    op_ldst(lwc1);
1047
}
1048

    
1049
void inline op_ldst_ldc1(DisasContext *ctx)
1050
{
1051
    op_ldst(ldc1);
1052
}
1053

    
1054
void inline op_ldst_swc1(DisasContext *ctx)
1055
{
1056
    op_ldst(swc1);
1057
}
1058

    
1059
void inline op_ldst_sdc1(DisasContext *ctx)
1060
{
1061
    op_ldst(sdc1);
1062
}
1063

    
1064
/* Load and store */
1065
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1066
                      int base, int16_t offset)
1067
{
1068
    const char *opn = "ldst";
1069

    
1070
    if (base == 0) {
1071
        tcg_gen_movi_tl(cpu_T[0], offset);
1072
    } else if (offset == 0) {
1073
        gen_load_gpr(cpu_T[0], base);
1074
    } else {
1075
        gen_load_gpr(cpu_T[0], base);
1076
        tcg_gen_movi_tl(cpu_T[1], offset);
1077
        gen_op_addr_add();
1078
    }
1079
    /* Don't do NOP if destination is zero: we must perform the actual
1080
       memory access. */
1081
    switch (opc) {
1082
#if defined(TARGET_MIPS64)
1083
    case OPC_LWU:
1084
        op_ldst_lwu(ctx);
1085
        gen_store_gpr(cpu_T[0], rt);
1086
        opn = "lwu";
1087
        break;
1088
    case OPC_LD:
1089
        op_ldst_ld(ctx);
1090
        gen_store_gpr(cpu_T[0], rt);
1091
        opn = "ld";
1092
        break;
1093
    case OPC_LLD:
1094
        op_ldst_lld(ctx);
1095
        gen_store_gpr(cpu_T[0], rt);
1096
        opn = "lld";
1097
        break;
1098
    case OPC_SD:
1099
        gen_load_gpr(cpu_T[1], rt);
1100
        op_ldst_sd(ctx);
1101
        opn = "sd";
1102
        break;
1103
    case OPC_SCD:
1104
        save_cpu_state(ctx, 1);
1105
        gen_load_gpr(cpu_T[1], rt);
1106
        op_ldst_scd(ctx);
1107
        gen_store_gpr(cpu_T[0], rt);
1108
        opn = "scd";
1109
        break;
1110
    case OPC_LDL:
1111
        gen_load_gpr(cpu_T[1], rt);
1112
        op_ldst(ldl);
1113
        gen_store_gpr(cpu_T[1], rt);
1114
        opn = "ldl";
1115
        break;
1116
    case OPC_SDL:
1117
        gen_load_gpr(cpu_T[1], rt);
1118
        op_ldst(sdl);
1119
        opn = "sdl";
1120
        break;
1121
    case OPC_LDR:
1122
        gen_load_gpr(cpu_T[1], rt);
1123
        op_ldst(ldr);
1124
        gen_store_gpr(cpu_T[1], rt);
1125
        opn = "ldr";
1126
        break;
1127
    case OPC_SDR:
1128
        gen_load_gpr(cpu_T[1], rt);
1129
        op_ldst(sdr);
1130
        opn = "sdr";
1131
        break;
1132
#endif
1133
    case OPC_LW:
1134
        op_ldst_lw(ctx);
1135
        gen_store_gpr(cpu_T[0], rt);
1136
        opn = "lw";
1137
        break;
1138
    case OPC_SW:
1139
        gen_load_gpr(cpu_T[1], rt);
1140
        op_ldst_sw(ctx);
1141
        opn = "sw";
1142
        break;
1143
    case OPC_LH:
1144
        op_ldst_lh(ctx);
1145
        gen_store_gpr(cpu_T[0], rt);
1146
        opn = "lh";
1147
        break;
1148
    case OPC_SH:
1149
        gen_load_gpr(cpu_T[1], rt);
1150
        op_ldst_sh(ctx);
1151
        opn = "sh";
1152
        break;
1153
    case OPC_LHU:
1154
        op_ldst_lhu(ctx);
1155
        gen_store_gpr(cpu_T[0], rt);
1156
        opn = "lhu";
1157
        break;
1158
    case OPC_LB:
1159
        op_ldst_lb(ctx);
1160
        gen_store_gpr(cpu_T[0], rt);
1161
        opn = "lb";
1162
        break;
1163
    case OPC_SB:
1164
        gen_load_gpr(cpu_T[1], rt);
1165
        op_ldst_sb(ctx);
1166
        opn = "sb";
1167
        break;
1168
    case OPC_LBU:
1169
        op_ldst_lbu(ctx);
1170
        gen_store_gpr(cpu_T[0], rt);
1171
        opn = "lbu";
1172
        break;
1173
    case OPC_LWL:
1174
        gen_load_gpr(cpu_T[1], rt);
1175
        op_ldst(lwl);
1176
        gen_store_gpr(cpu_T[1], rt);
1177
        opn = "lwl";
1178
        break;
1179
    case OPC_SWL:
1180
        gen_load_gpr(cpu_T[1], rt);
1181
        op_ldst(swl);
1182
        opn = "swr";
1183
        break;
1184
    case OPC_LWR:
1185
        gen_load_gpr(cpu_T[1], rt);
1186
        op_ldst(lwr);
1187
        gen_store_gpr(cpu_T[1], rt);
1188
        opn = "lwr";
1189
        break;
1190
    case OPC_SWR:
1191
        gen_load_gpr(cpu_T[1], rt);
1192
        op_ldst(swr);
1193
        opn = "swr";
1194
        break;
1195
    case OPC_LL:
1196
        op_ldst_ll(ctx);
1197
        gen_store_gpr(cpu_T[0], rt);
1198
        opn = "ll";
1199
        break;
1200
    case OPC_SC:
1201
        save_cpu_state(ctx, 1);
1202
        gen_load_gpr(cpu_T[1], rt);
1203
        op_ldst_sc(ctx);
1204
        gen_store_gpr(cpu_T[0], rt);
1205
        opn = "sc";
1206
        break;
1207
    default:
1208
        MIPS_INVAL(opn);
1209
        generate_exception(ctx, EXCP_RI);
1210
        return;
1211
    }
1212
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1213
}
1214

    
1215
/* Load and store */
1216
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1217
                      int base, int16_t offset)
1218
{
1219
    const char *opn = "flt_ldst";
1220

    
1221
    if (base == 0) {
1222
        tcg_gen_movi_tl(cpu_T[0], offset);
1223
    } else if (offset == 0) {
1224
        gen_load_gpr(cpu_T[0], base);
1225
    } else {
1226
        gen_load_gpr(cpu_T[0], base);
1227
        tcg_gen_movi_tl(cpu_T[1], offset);
1228
        gen_op_addr_add();
1229
    }
1230
    /* Don't do NOP if destination is zero: we must perform the actual
1231
       memory access. */
1232
    switch (opc) {
1233
    case OPC_LWC1:
1234
        op_ldst_lwc1(ctx);
1235
        GEN_STORE_FTN_FREG(ft, WT0);
1236
        opn = "lwc1";
1237
        break;
1238
    case OPC_SWC1:
1239
        GEN_LOAD_FREG_FTN(WT0, ft);
1240
        op_ldst_swc1(ctx);
1241
        opn = "swc1";
1242
        break;
1243
    case OPC_LDC1:
1244
        op_ldst_ldc1(ctx);
1245
        GEN_STORE_FTN_FREG(ft, DT0);
1246
        opn = "ldc1";
1247
        break;
1248
    case OPC_SDC1:
1249
        GEN_LOAD_FREG_FTN(DT0, ft);
1250
        op_ldst_sdc1(ctx);
1251
        opn = "sdc1";
1252
        break;
1253
    default:
1254
        MIPS_INVAL(opn);
1255
        generate_exception(ctx, EXCP_RI);
1256
        return;
1257
    }
1258
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1259
}
1260

    
1261
/* Arithmetic with immediate operand */
1262
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1263
                           int rt, int rs, int16_t imm)
1264
{
1265
    target_ulong uimm;
1266
    const char *opn = "imm arith";
1267

    
1268
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1269
        /* If no destination, treat it as a NOP.
1270
           For addi, we must generate the overflow exception when needed. */
1271
        MIPS_DEBUG("NOP");
1272
        return;
1273
    }
1274
    uimm = (uint16_t)imm;
1275
    switch (opc) {
1276
    case OPC_ADDI:
1277
    case OPC_ADDIU:
1278
#if defined(TARGET_MIPS64)
1279
    case OPC_DADDI:
1280
    case OPC_DADDIU:
1281
#endif
1282
    case OPC_SLTI:
1283
    case OPC_SLTIU:
1284
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1285
        tcg_gen_movi_tl(cpu_T[1], uimm);
1286
        /* Fall through. */
1287
    case OPC_ANDI:
1288
    case OPC_ORI:
1289
    case OPC_XORI:
1290
        gen_load_gpr(cpu_T[0], rs);
1291
        break;
1292
    case OPC_LUI:
1293
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1294
        break;
1295
    case OPC_SLL:
1296
    case OPC_SRA:
1297
    case OPC_SRL:
1298
#if defined(TARGET_MIPS64)
1299
    case OPC_DSLL:
1300
    case OPC_DSRA:
1301
    case OPC_DSRL:
1302
    case OPC_DSLL32:
1303
    case OPC_DSRA32:
1304
    case OPC_DSRL32:
1305
#endif
1306
        uimm &= 0x1f;
1307
        gen_load_gpr(cpu_T[0], rs);
1308
        break;
1309
    }
1310
    switch (opc) {
1311
    case OPC_ADDI:
1312
        {
1313
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1314
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1315
            int l1 = gen_new_label();
1316

    
1317
            save_cpu_state(ctx, 1);
1318
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1319
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1320

    
1321
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1322
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1323
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1324
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1325
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1326
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1327
            /* operands of same sign, result different sign */
1328
            generate_exception(ctx, EXCP_OVERFLOW);
1329
            gen_set_label(l1);
1330

    
1331
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1332
        }
1333
        opn = "addi";
1334
        break;
1335
    case OPC_ADDIU:
1336
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1337
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1338
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1339
        opn = "addiu";
1340
        break;
1341
#if defined(TARGET_MIPS64)
1342
    case OPC_DADDI:
1343
        {
1344
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1345
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1346
            int l1 = gen_new_label();
1347

    
1348
            save_cpu_state(ctx, 1);
1349
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1350
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1351

    
1352
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1353
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1354
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1355
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1356
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1357
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1358
            /* operands of same sign, result different sign */
1359
            generate_exception(ctx, EXCP_OVERFLOW);
1360
            gen_set_label(l1);
1361
        }
1362
        opn = "daddi";
1363
        break;
1364
    case OPC_DADDIU:
1365
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1366
        opn = "daddiu";
1367
        break;
1368
#endif
1369
    case OPC_SLTI:
1370
        gen_op_lti(uimm);
1371
        opn = "slti";
1372
        break;
1373
    case OPC_SLTIU:
1374
        gen_op_ltiu(uimm);
1375
        opn = "sltiu";
1376
        break;
1377
    case OPC_ANDI:
1378
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1379
        opn = "andi";
1380
        break;
1381
    case OPC_ORI:
1382
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1383
        opn = "ori";
1384
        break;
1385
    case OPC_XORI:
1386
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1387
        opn = "xori";
1388
        break;
1389
    case OPC_LUI:
1390
        opn = "lui";
1391
        break;
1392
    case OPC_SLL:
1393
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1394
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1395
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1396
        opn = "sll";
1397
        break;
1398
    case OPC_SRA:
1399
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1400
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1401
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1402
        opn = "sra";
1403
        break;
1404
    case OPC_SRL:
1405
        switch ((ctx->opcode >> 21) & 0x1f) {
1406
        case 0:
1407
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1408
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1409
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1410
            opn = "srl";
1411
            break;
1412
        case 1:
1413
            /* rotr is decoded as srl on non-R2 CPUs */
1414
            if (env->insn_flags & ISA_MIPS32R2) {
1415
                if (uimm != 0) {
1416
                    TCGv r_tmp1 = new_tmp();
1417
                    TCGv r_tmp2 = new_tmp();
1418

    
1419
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1420
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1421
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1422
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1423
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1424
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1425
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1426
                    dead_tmp(r_tmp1);
1427
                    dead_tmp(r_tmp2);
1428
                }
1429
                opn = "rotr";
1430
            } else {
1431
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1432
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1433
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1434
                opn = "srl";
1435
            }
1436
            break;
1437
        default:
1438
            MIPS_INVAL("invalid srl flag");
1439
            generate_exception(ctx, EXCP_RI);
1440
            break;
1441
        }
1442
        break;
1443
#if defined(TARGET_MIPS64)
1444
    case OPC_DSLL:
1445
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1446
        opn = "dsll";
1447
        break;
1448
    case OPC_DSRA:
1449
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1450
        opn = "dsra";
1451
        break;
1452
    case OPC_DSRL:
1453
        switch ((ctx->opcode >> 21) & 0x1f) {
1454
        case 0:
1455
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1456
            opn = "dsrl";
1457
            break;
1458
        case 1:
1459
            /* drotr is decoded as dsrl on non-R2 CPUs */
1460
            if (env->insn_flags & ISA_MIPS32R2) {
1461
                if (uimm != 0) {
1462
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1463

    
1464
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1465
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1466
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1467
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1468
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1469
                }
1470
                opn = "drotr";
1471
            } else {
1472
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1473
                opn = "dsrl";
1474
            }
1475
            break;
1476
        default:
1477
            MIPS_INVAL("invalid dsrl flag");
1478
            generate_exception(ctx, EXCP_RI);
1479
            break;
1480
        }
1481
        break;
1482
    case OPC_DSLL32:
1483
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1484
        opn = "dsll32";
1485
        break;
1486
    case OPC_DSRA32:
1487
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1488
        opn = "dsra32";
1489
        break;
1490
    case OPC_DSRL32:
1491
        switch ((ctx->opcode >> 21) & 0x1f) {
1492
        case 0:
1493
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1494
            opn = "dsrl32";
1495
            break;
1496
        case 1:
1497
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1498
            if (env->insn_flags & ISA_MIPS32R2) {
1499
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1500
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1501

    
1502
                tcg_gen_movi_tl(r_tmp1, 0x40);
1503
                tcg_gen_movi_tl(r_tmp2, 32);
1504
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1505
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1506
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1507
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1508
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1509
                opn = "drotr32";
1510
            } else {
1511
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1512
                opn = "dsrl32";
1513
            }
1514
            break;
1515
        default:
1516
            MIPS_INVAL("invalid dsrl32 flag");
1517
            generate_exception(ctx, EXCP_RI);
1518
            break;
1519
        }
1520
        break;
1521
#endif
1522
    default:
1523
        MIPS_INVAL(opn);
1524
        generate_exception(ctx, EXCP_RI);
1525
        return;
1526
    }
1527
    gen_store_gpr(cpu_T[0], rt);
1528
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1529
}
1530

    
1531
/* Arithmetic */
1532
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1533
                       int rd, int rs, int rt)
1534
{
1535
    const char *opn = "arith";
1536

    
1537
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1538
       && opc != OPC_DADD && opc != OPC_DSUB) {
1539
        /* If no destination, treat it as a NOP.
1540
           For add & sub, we must generate the overflow exception when needed. */
1541
        MIPS_DEBUG("NOP");
1542
        return;
1543
    }
1544
    gen_load_gpr(cpu_T[0], rs);
1545
    /* Specialcase the conventional move operation. */
1546
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1547
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1548
        gen_store_gpr(cpu_T[0], rd);
1549
        return;
1550
    }
1551
    gen_load_gpr(cpu_T[1], rt);
1552
    switch (opc) {
1553
    case OPC_ADD:
1554
        {
1555
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1556
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1557
            int l1 = gen_new_label();
1558

    
1559
            save_cpu_state(ctx, 1);
1560
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1561
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1562
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1563

    
1564
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1565
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1566
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1567
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1568
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1569
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1570
            /* operands of same sign, result different sign */
1571
            generate_exception(ctx, EXCP_OVERFLOW);
1572
            gen_set_label(l1);
1573

    
1574
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1575
        }
1576
        opn = "add";
1577
        break;
1578
    case OPC_ADDU:
1579
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1580
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1581
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1582
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1583
        opn = "addu";
1584
        break;
1585
    case OPC_SUB:
1586
        {
1587
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1588
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1589
            int l1 = gen_new_label();
1590

    
1591
            save_cpu_state(ctx, 1);
1592
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1593
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1594
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1595

    
1596
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1597
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1598
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1599
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1600
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1601
            /* operands of different sign, first operand and result different sign */
1602
            generate_exception(ctx, EXCP_OVERFLOW);
1603
            gen_set_label(l1);
1604

    
1605
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1606
        }
1607
        opn = "sub";
1608
        break;
1609
    case OPC_SUBU:
1610
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1611
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1612
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1613
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1614
        opn = "subu";
1615
        break;
1616
#if defined(TARGET_MIPS64)
1617
    case OPC_DADD:
1618
        {
1619
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1620
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1621
            int l1 = gen_new_label();
1622

    
1623
            save_cpu_state(ctx, 1);
1624
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1625
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1626

    
1627
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1628
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1629
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1630
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1631
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1632
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1633
            /* operands of same sign, result different sign */
1634
            generate_exception(ctx, EXCP_OVERFLOW);
1635
            gen_set_label(l1);
1636
        }
1637
        opn = "dadd";
1638
        break;
1639
    case OPC_DADDU:
1640
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1641
        opn = "daddu";
1642
        break;
1643
    case OPC_DSUB:
1644
        {
1645
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1646
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1647
            int l1 = gen_new_label();
1648

    
1649
            save_cpu_state(ctx, 1);
1650
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1651
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1652

    
1653
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1654
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1655
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1656
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1657
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1658
            /* operands of different sign, first operand and result different sign */
1659
            generate_exception(ctx, EXCP_OVERFLOW);
1660
            gen_set_label(l1);
1661
        }
1662
        opn = "dsub";
1663
        break;
1664
    case OPC_DSUBU:
1665
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1666
        opn = "dsubu";
1667
        break;
1668
#endif
1669
    case OPC_SLT:
1670
        gen_op_lt();
1671
        opn = "slt";
1672
        break;
1673
    case OPC_SLTU:
1674
        gen_op_ltu();
1675
        opn = "sltu";
1676
        break;
1677
    case OPC_AND:
1678
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1679
        opn = "and";
1680
        break;
1681
    case OPC_NOR:
1682
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1683
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1684
        opn = "nor";
1685
        break;
1686
    case OPC_OR:
1687
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1688
        opn = "or";
1689
        break;
1690
    case OPC_XOR:
1691
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1692
        opn = "xor";
1693
        break;
1694
    case OPC_MUL:
1695
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1696
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1697
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1698
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1699
        opn = "mul";
1700
        break;
1701
    case OPC_MOVN:
1702
        {
1703
            int l1 = gen_new_label();
1704

    
1705
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1706
            gen_store_gpr(cpu_T[0], rd);
1707
            gen_set_label(l1);
1708
        }
1709
        opn = "movn";
1710
        goto print;
1711
    case OPC_MOVZ:
1712
        {
1713
            int l1 = gen_new_label();
1714

    
1715
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1716
            gen_store_gpr(cpu_T[0], rd);
1717
            gen_set_label(l1);
1718
        }
1719
        opn = "movz";
1720
        goto print;
1721
    case OPC_SLLV:
1722
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1723
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1724
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1725
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1726
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1727
        opn = "sllv";
1728
        break;
1729
    case OPC_SRAV:
1730
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1731
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1732
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1733
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1734
        opn = "srav";
1735
        break;
1736
    case OPC_SRLV:
1737
        switch ((ctx->opcode >> 6) & 0x1f) {
1738
        case 0:
1739
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1740
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1741
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1742
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1743
            opn = "srlv";
1744
            break;
1745
        case 1:
1746
            /* rotrv is decoded as srlv on non-R2 CPUs */
1747
            if (env->insn_flags & ISA_MIPS32R2) {
1748
                int l1 = gen_new_label();
1749
                int l2 = gen_new_label();
1750

    
1751
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1752
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1753
                {
1754
                    TCGv r_tmp1 = new_tmp();
1755
                    TCGv r_tmp2 = new_tmp();
1756
                    TCGv r_tmp3 = new_tmp();
1757

    
1758
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1759
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1760
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1761
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1762
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1763
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1764
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1765
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1766
                    dead_tmp(r_tmp1);
1767
                    dead_tmp(r_tmp2);
1768
                    dead_tmp(r_tmp3);
1769
                    tcg_gen_br(l2);
1770
                }
1771
                gen_set_label(l1);
1772
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1773
                gen_set_label(l2);
1774
                opn = "rotrv";
1775
            } else {
1776
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1777
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1778
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1779
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1780
                opn = "srlv";
1781
            }
1782
            break;
1783
        default:
1784
            MIPS_INVAL("invalid srlv flag");
1785
            generate_exception(ctx, EXCP_RI);
1786
            break;
1787
        }
1788
        break;
1789
#if defined(TARGET_MIPS64)
1790
    case OPC_DSLLV:
1791
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1792
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1793
        opn = "dsllv";
1794
        break;
1795
    case OPC_DSRAV:
1796
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1797
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1798
        opn = "dsrav";
1799
        break;
1800
    case OPC_DSRLV:
1801
        switch ((ctx->opcode >> 6) & 0x1f) {
1802
        case 0:
1803
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1804
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1805
            opn = "dsrlv";
1806
            break;
1807
        case 1:
1808
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1809
            if (env->insn_flags & ISA_MIPS32R2) {
1810
                int l1 = gen_new_label();
1811
                int l2 = gen_new_label();
1812

    
1813
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1814
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1815
                {
1816
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1817

    
1818
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1819
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1820
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1821
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1822
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1823
                    tcg_gen_br(l2);
1824
                }
1825
                gen_set_label(l1);
1826
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1827
                gen_set_label(l2);
1828
                opn = "drotrv";
1829
            } else {
1830
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1831
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1832
                opn = "dsrlv";
1833
            }
1834
            break;
1835
        default:
1836
            MIPS_INVAL("invalid dsrlv flag");
1837
            generate_exception(ctx, EXCP_RI);
1838
            break;
1839
        }
1840
        break;
1841
#endif
1842
    default:
1843
        MIPS_INVAL(opn);
1844
        generate_exception(ctx, EXCP_RI);
1845
        return;
1846
    }
1847
    gen_store_gpr(cpu_T[0], rd);
1848
 print:
1849
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1850
}
1851

    
1852
/* Arithmetic on HI/LO registers */
1853
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1854
{
1855
    const char *opn = "hilo";
1856

    
1857
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1858
        /* Treat as NOP. */
1859
        MIPS_DEBUG("NOP");
1860
        return;
1861
    }
1862
    switch (opc) {
1863
    case OPC_MFHI:
1864
        gen_load_HI(cpu_T[0], 0);
1865
        gen_store_gpr(cpu_T[0], reg);
1866
        opn = "mfhi";
1867
        break;
1868
    case OPC_MFLO:
1869
        gen_load_LO(cpu_T[0], 0);
1870
        gen_store_gpr(cpu_T[0], reg);
1871
        opn = "mflo";
1872
        break;
1873
    case OPC_MTHI:
1874
        gen_load_gpr(cpu_T[0], reg);
1875
        gen_store_HI(cpu_T[0], 0);
1876
        opn = "mthi";
1877
        break;
1878
    case OPC_MTLO:
1879
        gen_load_gpr(cpu_T[0], reg);
1880
        gen_store_LO(cpu_T[0], 0);
1881
        opn = "mtlo";
1882
        break;
1883
    default:
1884
        MIPS_INVAL(opn);
1885
        generate_exception(ctx, EXCP_RI);
1886
        return;
1887
    }
1888
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1889
}
1890

    
1891
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1892
                        int rs, int rt)
1893
{
1894
    const char *opn = "mul/div";
1895

    
1896
    gen_load_gpr(cpu_T[0], rs);
1897
    gen_load_gpr(cpu_T[1], rt);
1898
    switch (opc) {
1899
    case OPC_DIV:
1900
        {
1901
            int l1 = gen_new_label();
1902

    
1903
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1904
            {
1905
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1906
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1907

    
1908
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1909
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1910
                tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1911
                tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1912
                tcg_gen_ext32s_tl(r_tmp1, r_tmp1);
1913
                tcg_gen_ext32s_tl(r_tmp2, r_tmp2);
1914
                gen_store_LO(r_tmp1, 0);
1915
                gen_store_HI(r_tmp2, 0);
1916
            }
1917
            gen_set_label(l1);
1918
        }
1919
        opn = "div";
1920
        break;
1921
    case OPC_DIVU:
1922
        {
1923
            int l1 = gen_new_label();
1924

    
1925
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1926
            {
1927
                TCGv r_tmp1 = new_tmp();
1928
                TCGv r_tmp2 = new_tmp();
1929
                TCGv r_tmp3 = new_tmp();
1930

    
1931
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1932
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1933
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1934
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1935
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1936
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1937
                gen_store_LO(cpu_T[0], 0);
1938
                gen_store_HI(cpu_T[1], 0);
1939
                dead_tmp(r_tmp1);
1940
                dead_tmp(r_tmp2);
1941
                dead_tmp(r_tmp3);
1942
            }
1943
            gen_set_label(l1);
1944
        }
1945
        opn = "divu";
1946
        break;
1947
    case OPC_MULT:
1948
        gen_op_mult();
1949
        opn = "mult";
1950
        break;
1951
    case OPC_MULTU:
1952
        gen_op_multu();
1953
        opn = "multu";
1954
        break;
1955
#if defined(TARGET_MIPS64)
1956
    case OPC_DDIV:
1957
        {
1958
            int l1 = gen_new_label();
1959

    
1960
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1961
            {
1962
                int l2 = gen_new_label();
1963

    
1964
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1965
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1966
                {
1967
                    tcg_gen_movi_tl(cpu_T[1], 0);
1968
                    gen_store_LO(cpu_T[0], 0);
1969
                    gen_store_HI(cpu_T[1], 0);
1970
                    tcg_gen_br(l1);
1971
                }
1972
                gen_set_label(l2);
1973
                {
1974
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1975
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1976

    
1977
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1978
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1979
                    gen_store_LO(r_tmp1, 0);
1980
                    gen_store_HI(r_tmp2, 0);
1981
                }
1982
            }
1983
            gen_set_label(l1);
1984
        }
1985
        opn = "ddiv";
1986
        break;
1987
    case OPC_DDIVU:
1988
        {
1989
            int l1 = gen_new_label();
1990

    
1991
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1992
            {
1993
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1994
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1995

    
1996
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1997
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1998
                gen_store_LO(r_tmp1, 0);
1999
                gen_store_HI(r_tmp2, 0);
2000
            }
2001
            gen_set_label(l1);
2002
        }
2003
        opn = "ddivu";
2004
        break;
2005
    case OPC_DMULT:
2006
        gen_op_dmult();
2007
        opn = "dmult";
2008
        break;
2009
    case OPC_DMULTU:
2010
        gen_op_dmultu();
2011
        opn = "dmultu";
2012
        break;
2013
#endif
2014
    case OPC_MADD:
2015
        gen_op_madd();
2016
        opn = "madd";
2017
        break;
2018
    case OPC_MADDU:
2019
        gen_op_maddu();
2020
        opn = "maddu";
2021
        break;
2022
    case OPC_MSUB:
2023
        gen_op_msub();
2024
        opn = "msub";
2025
        break;
2026
    case OPC_MSUBU:
2027
        gen_op_msubu();
2028
        opn = "msubu";
2029
        break;
2030
    default:
2031
        MIPS_INVAL(opn);
2032
        generate_exception(ctx, EXCP_RI);
2033
        return;
2034
    }
2035
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2036
}
2037

    
2038
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2039
                            int rd, int rs, int rt)
2040
{
2041
    const char *opn = "mul vr54xx";
2042

    
2043
    gen_load_gpr(cpu_T[0], rs);
2044
    gen_load_gpr(cpu_T[1], rt);
2045

    
2046
    switch (opc) {
2047
    case OPC_VR54XX_MULS:
2048
        gen_op_muls();
2049
        opn = "muls";
2050
        break;
2051
    case OPC_VR54XX_MULSU:
2052
        gen_op_mulsu();
2053
        opn = "mulsu";
2054
        break;
2055
    case OPC_VR54XX_MACC:
2056
        gen_op_macc();
2057
        opn = "macc";
2058
        break;
2059
    case OPC_VR54XX_MACCU:
2060
        gen_op_maccu();
2061
        opn = "maccu";
2062
        break;
2063
    case OPC_VR54XX_MSAC:
2064
        gen_op_msac();
2065
        opn = "msac";
2066
        break;
2067
    case OPC_VR54XX_MSACU:
2068
        gen_op_msacu();
2069
        opn = "msacu";
2070
        break;
2071
    case OPC_VR54XX_MULHI:
2072
        gen_op_mulhi();
2073
        opn = "mulhi";
2074
        break;
2075
    case OPC_VR54XX_MULHIU:
2076
        gen_op_mulhiu();
2077
        opn = "mulhiu";
2078
        break;
2079
    case OPC_VR54XX_MULSHI:
2080
        gen_op_mulshi();
2081
        opn = "mulshi";
2082
        break;
2083
    case OPC_VR54XX_MULSHIU:
2084
        gen_op_mulshiu();
2085
        opn = "mulshiu";
2086
        break;
2087
    case OPC_VR54XX_MACCHI:
2088
        gen_op_macchi();
2089
        opn = "macchi";
2090
        break;
2091
    case OPC_VR54XX_MACCHIU:
2092
        gen_op_macchiu();
2093
        opn = "macchiu";
2094
        break;
2095
    case OPC_VR54XX_MSACHI:
2096
        gen_op_msachi();
2097
        opn = "msachi";
2098
        break;
2099
    case OPC_VR54XX_MSACHIU:
2100
        gen_op_msachiu();
2101
        opn = "msachiu";
2102
        break;
2103
    default:
2104
        MIPS_INVAL("mul vr54xx");
2105
        generate_exception(ctx, EXCP_RI);
2106
        return;
2107
    }
2108
    gen_store_gpr(cpu_T[0], rd);
2109
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2110
}
2111

    
2112
static void gen_cl (DisasContext *ctx, uint32_t opc,
2113
                    int rd, int rs)
2114
{
2115
    const char *opn = "CLx";
2116
    if (rd == 0) {
2117
        /* Treat as NOP. */
2118
        MIPS_DEBUG("NOP");
2119
        return;
2120
    }
2121
    gen_load_gpr(cpu_T[0], rs);
2122
    switch (opc) {
2123
    case OPC_CLO:
2124
        tcg_gen_helper_0_0(do_clo);
2125
        opn = "clo";
2126
        break;
2127
    case OPC_CLZ:
2128
        tcg_gen_helper_0_0(do_clz);
2129
        opn = "clz";
2130
        break;
2131
#if defined(TARGET_MIPS64)
2132
    case OPC_DCLO:
2133
        tcg_gen_helper_0_0(do_dclo);
2134
        opn = "dclo";
2135
        break;
2136
    case OPC_DCLZ:
2137
        tcg_gen_helper_0_0(do_dclz);
2138
        opn = "dclz";
2139
        break;
2140
#endif
2141
    default:
2142
        MIPS_INVAL(opn);
2143
        generate_exception(ctx, EXCP_RI);
2144
        return;
2145
    }
2146
    gen_store_gpr(cpu_T[0], rd);
2147
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2148
}
2149

    
2150
/* Traps */
2151
static void gen_trap (DisasContext *ctx, uint32_t opc,
2152
                      int rs, int rt, int16_t imm)
2153
{
2154
    int cond;
2155

    
2156
    cond = 0;
2157
    /* Load needed operands */
2158
    switch (opc) {
2159
    case OPC_TEQ:
2160
    case OPC_TGE:
2161
    case OPC_TGEU:
2162
    case OPC_TLT:
2163
    case OPC_TLTU:
2164
    case OPC_TNE:
2165
        /* Compare two registers */
2166
        if (rs != rt) {
2167
            gen_load_gpr(cpu_T[0], rs);
2168
            gen_load_gpr(cpu_T[1], rt);
2169
            cond = 1;
2170
        }
2171
        break;
2172
    case OPC_TEQI:
2173
    case OPC_TGEI:
2174
    case OPC_TGEIU:
2175
    case OPC_TLTI:
2176
    case OPC_TLTIU:
2177
    case OPC_TNEI:
2178
        /* Compare register to immediate */
2179
        if (rs != 0 || imm != 0) {
2180
            gen_load_gpr(cpu_T[0], rs);
2181
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2182
            cond = 1;
2183
        }
2184
        break;
2185
    }
2186
    if (cond == 0) {
2187
        switch (opc) {
2188
        case OPC_TEQ:   /* rs == rs */
2189
        case OPC_TEQI:  /* r0 == 0  */
2190
        case OPC_TGE:   /* rs >= rs */
2191
        case OPC_TGEI:  /* r0 >= 0  */
2192
        case OPC_TGEU:  /* rs >= rs unsigned */
2193
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2194
            /* Always trap */
2195
            tcg_gen_movi_tl(cpu_T[0], 1);
2196
            break;
2197
        case OPC_TLT:   /* rs < rs           */
2198
        case OPC_TLTI:  /* r0 < 0            */
2199
        case OPC_TLTU:  /* rs < rs unsigned  */
2200
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2201
        case OPC_TNE:   /* rs != rs          */
2202
        case OPC_TNEI:  /* r0 != 0           */
2203
            /* Never trap: treat as NOP. */
2204
            return;
2205
        default:
2206
            MIPS_INVAL("trap");
2207
            generate_exception(ctx, EXCP_RI);
2208
            return;
2209
        }
2210
    } else {
2211
        switch (opc) {
2212
        case OPC_TEQ:
2213
        case OPC_TEQI:
2214
            gen_op_eq();
2215
            break;
2216
        case OPC_TGE:
2217
        case OPC_TGEI:
2218
            gen_op_ge();
2219
            break;
2220
        case OPC_TGEU:
2221
        case OPC_TGEIU:
2222
            gen_op_geu();
2223
            break;
2224
        case OPC_TLT:
2225
        case OPC_TLTI:
2226
            gen_op_lt();
2227
            break;
2228
        case OPC_TLTU:
2229
        case OPC_TLTIU:
2230
            gen_op_ltu();
2231
            break;
2232
        case OPC_TNE:
2233
        case OPC_TNEI:
2234
            gen_op_ne();
2235
            break;
2236
        default:
2237
            MIPS_INVAL("trap");
2238
            generate_exception(ctx, EXCP_RI);
2239
            return;
2240
        }
2241
    }
2242
    save_cpu_state(ctx, 1);
2243
    gen_op_trap();
2244
    ctx->bstate = BS_STOP;
2245
}
2246

    
2247
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2248
{
2249
    TranslationBlock *tb;
2250
    tb = ctx->tb;
2251
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2252
        tcg_gen_goto_tb(n);
2253
        gen_save_pc(dest);
2254
        tcg_gen_exit_tb((long)tb + n);
2255
    } else {
2256
        gen_save_pc(dest);
2257
        tcg_gen_exit_tb(0);
2258
    }
2259
}
2260

    
2261
/* Branches (before delay slot) */
2262
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2263
                                int rs, int rt, int32_t offset)
2264
{
2265
    target_ulong btarget = -1;
2266
    int blink = 0;
2267
    int bcond = 0;
2268

    
2269
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2270
#ifdef MIPS_DEBUG_DISAS
2271
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2272
            fprintf(logfile,
2273
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2274
                    ctx->pc);
2275
        }
2276
#endif
2277
        generate_exception(ctx, EXCP_RI);
2278
        return;
2279
    }
2280

    
2281
    /* Load needed operands */
2282
    switch (opc) {
2283
    case OPC_BEQ:
2284
    case OPC_BEQL:
2285
    case OPC_BNE:
2286
    case OPC_BNEL:
2287
        /* Compare two registers */
2288
        if (rs != rt) {
2289
            gen_load_gpr(cpu_T[0], rs);
2290
            gen_load_gpr(cpu_T[1], rt);
2291
            bcond = 1;
2292
        }
2293
        btarget = ctx->pc + 4 + offset;
2294
        break;
2295
    case OPC_BGEZ:
2296
    case OPC_BGEZAL:
2297
    case OPC_BGEZALL:
2298
    case OPC_BGEZL:
2299
    case OPC_BGTZ:
2300
    case OPC_BGTZL:
2301
    case OPC_BLEZ:
2302
    case OPC_BLEZL:
2303
    case OPC_BLTZ:
2304
    case OPC_BLTZAL:
2305
    case OPC_BLTZALL:
2306
    case OPC_BLTZL:
2307
        /* Compare to zero */
2308
        if (rs != 0) {
2309
            gen_load_gpr(cpu_T[0], rs);
2310
            bcond = 1;
2311
        }
2312
        btarget = ctx->pc + 4 + offset;
2313
        break;
2314
    case OPC_J:
2315
    case OPC_JAL:
2316
        /* Jump to immediate */
2317
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2318
        break;
2319
    case OPC_JR:
2320
    case OPC_JALR:
2321
        /* Jump to register */
2322
        if (offset != 0 && offset != 16) {
2323
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2324
               others are reserved. */
2325
            MIPS_INVAL("jump hint");
2326
            generate_exception(ctx, EXCP_RI);
2327
            return;
2328
        }
2329
        gen_save_breg_target(rs);
2330
        break;
2331
    default:
2332
        MIPS_INVAL("branch/jump");
2333
        generate_exception(ctx, EXCP_RI);
2334
        return;
2335
    }
2336
    if (bcond == 0) {
2337
        /* No condition to be computed */
2338
        switch (opc) {
2339
        case OPC_BEQ:     /* rx == rx        */
2340
        case OPC_BEQL:    /* rx == rx likely */
2341
        case OPC_BGEZ:    /* 0 >= 0          */
2342
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2343
        case OPC_BLEZ:    /* 0 <= 0          */
2344
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2345
            /* Always take */
2346
            ctx->hflags |= MIPS_HFLAG_B;
2347
            MIPS_DEBUG("balways");
2348
            break;
2349
        case OPC_BGEZAL:  /* 0 >= 0          */
2350
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2351
            /* Always take and link */
2352
            blink = 31;
2353
            ctx->hflags |= MIPS_HFLAG_B;
2354
            MIPS_DEBUG("balways and link");
2355
            break;
2356
        case OPC_BNE:     /* rx != rx        */
2357
        case OPC_BGTZ:    /* 0 > 0           */
2358
        case OPC_BLTZ:    /* 0 < 0           */
2359
            /* Treat as NOP. */
2360
            MIPS_DEBUG("bnever (NOP)");
2361
            return;
2362
        case OPC_BLTZAL:  /* 0 < 0           */
2363
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2364
            gen_store_gpr(cpu_T[0], 31);
2365
            MIPS_DEBUG("bnever and link");
2366
            return;
2367
        case OPC_BLTZALL: /* 0 < 0 likely */
2368
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2369
            gen_store_gpr(cpu_T[0], 31);
2370
            /* Skip the instruction in the delay slot */
2371
            MIPS_DEBUG("bnever, link and skip");
2372
            ctx->pc += 4;
2373
            return;
2374
        case OPC_BNEL:    /* rx != rx likely */
2375
        case OPC_BGTZL:   /* 0 > 0 likely */
2376
        case OPC_BLTZL:   /* 0 < 0 likely */
2377
            /* Skip the instruction in the delay slot */
2378
            MIPS_DEBUG("bnever and skip");
2379
            ctx->pc += 4;
2380
            return;
2381
        case OPC_J:
2382
            ctx->hflags |= MIPS_HFLAG_B;
2383
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2384
            break;
2385
        case OPC_JAL:
2386
            blink = 31;
2387
            ctx->hflags |= MIPS_HFLAG_B;
2388
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2389
            break;
2390
        case OPC_JR:
2391
            ctx->hflags |= MIPS_HFLAG_BR;
2392
            MIPS_DEBUG("jr %s", regnames[rs]);
2393
            break;
2394
        case OPC_JALR:
2395
            blink = rt;
2396
            ctx->hflags |= MIPS_HFLAG_BR;
2397
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2398
            break;
2399
        default:
2400
            MIPS_INVAL("branch/jump");
2401
            generate_exception(ctx, EXCP_RI);
2402
            return;
2403
        }
2404
    } else {
2405
        switch (opc) {
2406
        case OPC_BEQ:
2407
            gen_op_eq();
2408
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2409
                       regnames[rs], regnames[rt], btarget);
2410
            goto not_likely;
2411
        case OPC_BEQL:
2412
            gen_op_eq();
2413
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2414
                       regnames[rs], regnames[rt], btarget);
2415
            goto likely;
2416
        case OPC_BNE:
2417
            gen_op_ne();
2418
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2419
                       regnames[rs], regnames[rt], btarget);
2420
            goto not_likely;
2421
        case OPC_BNEL:
2422
            gen_op_ne();
2423
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2424
                       regnames[rs], regnames[rt], btarget);
2425
            goto likely;
2426
        case OPC_BGEZ:
2427
            gen_op_gez();
2428
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2429
            goto not_likely;
2430
        case OPC_BGEZL:
2431
            gen_op_gez();
2432
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2433
            goto likely;
2434
        case OPC_BGEZAL:
2435
            gen_op_gez();
2436
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2437
            blink = 31;
2438
            goto not_likely;
2439
        case OPC_BGEZALL:
2440
            gen_op_gez();
2441
            blink = 31;
2442
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2443
            goto likely;
2444
        case OPC_BGTZ:
2445
            gen_op_gtz();
2446
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2447
            goto not_likely;
2448
        case OPC_BGTZL:
2449
            gen_op_gtz();
2450
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2451
            goto likely;
2452
        case OPC_BLEZ:
2453
            gen_op_lez();
2454
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2455
            goto not_likely;
2456
        case OPC_BLEZL:
2457
            gen_op_lez();
2458
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2459
            goto likely;
2460
        case OPC_BLTZ:
2461
            gen_op_ltz();
2462
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2463
            goto not_likely;
2464
        case OPC_BLTZL:
2465
            gen_op_ltz();
2466
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2467
            goto likely;
2468
        case OPC_BLTZAL:
2469
            gen_op_ltz();
2470
            blink = 31;
2471
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2472
        not_likely:
2473
            ctx->hflags |= MIPS_HFLAG_BC;
2474
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2475
            break;
2476
        case OPC_BLTZALL:
2477
            gen_op_ltz();
2478
            blink = 31;
2479
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2480
        likely:
2481
            ctx->hflags |= MIPS_HFLAG_BL;
2482
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2483
            break;
2484
        default:
2485
            MIPS_INVAL("conditional branch/jump");
2486
            generate_exception(ctx, EXCP_RI);
2487
            return;
2488
        }
2489
    }
2490
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2491
               blink, ctx->hflags, btarget);
2492

    
2493
    ctx->btarget = btarget;
2494
    if (blink > 0) {
2495
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2496
        gen_store_gpr(cpu_T[0], blink);
2497
    }
2498
}
2499

    
2500
/* special3 bitfield operations */
2501
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2502
                       int rs, int lsb, int msb)
2503
{
2504
    gen_load_gpr(cpu_T[1], rs);
2505
    switch (opc) {
2506
    case OPC_EXT:
2507
        if (lsb + msb > 31)
2508
            goto fail;
2509
        gen_op_ext(lsb, msb + 1);
2510
        break;
2511
#if defined(TARGET_MIPS64)
2512
    case OPC_DEXTM:
2513
        if (lsb + msb > 63)
2514
            goto fail;
2515
        gen_op_dext(lsb, msb + 1 + 32);
2516
        break;
2517
    case OPC_DEXTU:
2518
        if (lsb + msb > 63)
2519
            goto fail;
2520
        gen_op_dext(lsb + 32, msb + 1);
2521
        break;
2522
    case OPC_DEXT:
2523
        if (lsb + msb > 63)
2524
            goto fail;
2525
        gen_op_dext(lsb, msb + 1);
2526
        break;
2527
#endif
2528
    case OPC_INS:
2529
        if (lsb > msb)
2530
            goto fail;
2531
        gen_load_gpr(cpu_T[0], rt);
2532
        gen_op_ins(lsb, msb - lsb + 1);
2533
        break;
2534
#if defined(TARGET_MIPS64)
2535
    case OPC_DINSM:
2536
        if (lsb > msb)
2537
            goto fail;
2538
        gen_load_gpr(cpu_T[0], rt);
2539
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2540
        break;
2541
    case OPC_DINSU:
2542
        if (lsb > msb)
2543
            goto fail;
2544
        gen_load_gpr(cpu_T[0], rt);
2545
        gen_op_dins(lsb + 32, msb - lsb + 1);
2546
        break;
2547
    case OPC_DINS:
2548
        if (lsb > msb)
2549
            goto fail;
2550
        gen_load_gpr(cpu_T[0], rt);
2551
        gen_op_dins(lsb, msb - lsb + 1);
2552
        break;
2553
#endif
2554
    default:
2555
fail:
2556
        MIPS_INVAL("bitops");
2557
        generate_exception(ctx, EXCP_RI);
2558
        return;
2559
    }
2560
    gen_store_gpr(cpu_T[0], rt);
2561
}
2562

    
2563
/* CP0 (MMU and control) */
2564
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2565
{
2566
    const char *rn = "invalid";
2567
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2568
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2569

    
2570
    if (sel != 0)
2571
        check_insn(env, ctx, ISA_MIPS32);
2572

    
2573
    switch (reg) {
2574
    case 0:
2575
        switch (sel) {
2576
        case 0:
2577
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
2578
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2579
            rn = "Index";
2580
            break;
2581
        case 1:
2582
            check_insn(env, ctx, ASE_MT);
2583
            gen_op_mfc0_mvpcontrol();
2584
            rn = "MVPControl";
2585
            break;
2586
        case 2:
2587
            check_insn(env, ctx, ASE_MT);
2588
            gen_op_mfc0_mvpconf0();
2589
            rn = "MVPConf0";
2590
            break;
2591
        case 3:
2592
            check_insn(env, ctx, ASE_MT);
2593
            gen_op_mfc0_mvpconf1();
2594
            rn = "MVPConf1";
2595
            break;
2596
        default:
2597
            goto die;
2598
        }
2599
        break;
2600
    case 1:
2601
        switch (sel) {
2602
        case 0:
2603
            gen_op_mfc0_random();
2604
            rn = "Random";
2605
            break;
2606
        case 1:
2607
            check_insn(env, ctx, ASE_MT);
2608
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
2609
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2610
            rn = "VPEControl";
2611
            break;
2612
        case 2:
2613
            check_insn(env, ctx, ASE_MT);
2614
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
2615
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2616
            rn = "VPEConf0";
2617
            break;
2618
        case 3:
2619
            check_insn(env, ctx, ASE_MT);
2620
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
2621
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2622
            rn = "VPEConf1";
2623
            break;
2624
        case 4:
2625
            check_insn(env, ctx, ASE_MT);
2626
            tcg_gen_ld_i64(r_tmp64, cpu_env, offsetof(CPUState, CP0_YQMask));
2627
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2628
            rn = "YQMask";
2629
            break;
2630
        case 5:
2631
            check_insn(env, ctx, ASE_MT);
2632
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPESchedule));
2633
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2634
            rn = "VPESchedule";
2635
            break;
2636
        case 6:
2637
            check_insn(env, ctx, ASE_MT);
2638
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
2639
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2640
            rn = "VPEScheFBack";
2641
            break;
2642
        case 7:
2643
            check_insn(env, ctx, ASE_MT);
2644
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
2645
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2646
            rn = "VPEOpt";
2647
            break;
2648
        default:
2649
            goto die;
2650
        }
2651
        break;
2652
    case 2:
2653
        switch (sel) {
2654
        case 0:
2655
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2656
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2657
            rn = "EntryLo0";
2658
            break;
2659
        case 1:
2660
            check_insn(env, ctx, ASE_MT);
2661
            gen_op_mfc0_tcstatus();
2662
            rn = "TCStatus";
2663
            break;
2664
        case 2:
2665
            check_insn(env, ctx, ASE_MT);
2666
            gen_op_mfc0_tcbind();
2667
            rn = "TCBind";
2668
            break;
2669
        case 3:
2670
            check_insn(env, ctx, ASE_MT);
2671
            gen_op_mfc0_tcrestart();
2672
            rn = "TCRestart";
2673
            break;
2674
        case 4:
2675
            check_insn(env, ctx, ASE_MT);
2676
            gen_op_mfc0_tchalt();
2677
            rn = "TCHalt";
2678
            break;
2679
        case 5:
2680
            check_insn(env, ctx, ASE_MT);
2681
            gen_op_mfc0_tccontext();
2682
            rn = "TCContext";
2683
            break;
2684
        case 6:
2685
            check_insn(env, ctx, ASE_MT);
2686
            gen_op_mfc0_tcschedule();
2687
            rn = "TCSchedule";
2688
            break;
2689
        case 7:
2690
            check_insn(env, ctx, ASE_MT);
2691
            gen_op_mfc0_tcschefback();
2692
            rn = "TCScheFBack";
2693
            break;
2694
        default:
2695
            goto die;
2696
        }
2697
        break;
2698
    case 3:
2699
        switch (sel) {
2700
        case 0:
2701
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2702
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2703
            rn = "EntryLo1";
2704
            break;
2705
        default:
2706
            goto die;
2707
        }
2708
        break;
2709
    case 4:
2710
        switch (sel) {
2711
        case 0:
2712
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2713
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2714
            rn = "Context";
2715
            break;
2716
        case 1:
2717
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2718
            rn = "ContextConfig";
2719
//            break;
2720
        default:
2721
            goto die;
2722
        }
2723
        break;
2724
    case 5:
2725
        switch (sel) {
2726
        case 0:
2727
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
2728
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2729
            rn = "PageMask";
2730
            break;
2731
        case 1:
2732
            check_insn(env, ctx, ISA_MIPS32R2);
2733
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
2734
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2735
            rn = "PageGrain";
2736
            break;
2737
        default:
2738
            goto die;
2739
        }
2740
        break;
2741
    case 6:
2742
        switch (sel) {
2743
        case 0:
2744
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
2745
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2746
            rn = "Wired";
2747
            break;
2748
        case 1:
2749
            check_insn(env, ctx, ISA_MIPS32R2);
2750
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
2751
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2752
            rn = "SRSConf0";
2753
            break;
2754
        case 2:
2755
            check_insn(env, ctx, ISA_MIPS32R2);
2756
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
2757
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2758
            rn = "SRSConf1";
2759
            break;
2760
        case 3:
2761
            check_insn(env, ctx, ISA_MIPS32R2);
2762
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
2763
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2764
            rn = "SRSConf2";
2765
            break;
2766
        case 4:
2767
            check_insn(env, ctx, ISA_MIPS32R2);
2768
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
2769
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2770
            rn = "SRSConf3";
2771
            break;
2772
        case 5:
2773
            check_insn(env, ctx, ISA_MIPS32R2);
2774
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
2775
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2776
            rn = "SRSConf4";
2777
            break;
2778
        default:
2779
            goto die;
2780
        }
2781
        break;
2782
    case 7:
2783
        switch (sel) {
2784
        case 0:
2785
            check_insn(env, ctx, ISA_MIPS32R2);
2786
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
2787
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2788
            rn = "HWREna";
2789
            break;
2790
        default:
2791
            goto die;
2792
        }
2793
        break;
2794
    case 8:
2795
        switch (sel) {
2796
        case 0:
2797
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2798
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2799
            rn = "BadVAddr";
2800
            break;
2801
        default:
2802
            goto die;
2803
       }
2804
        break;
2805
    case 9:
2806
        switch (sel) {
2807
        case 0:
2808
            gen_op_mfc0_count();
2809
            rn = "Count";
2810
            break;
2811
        /* 6,7 are implementation dependent */
2812
        default:
2813
            goto die;
2814
        }
2815
        break;
2816
    case 10:
2817
        switch (sel) {
2818
        case 0:
2819
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2820
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2821
            rn = "EntryHi";
2822
            break;
2823
        default:
2824
            goto die;
2825
        }
2826
        break;
2827
    case 11:
2828
        switch (sel) {
2829
        case 0:
2830
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
2831
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2832
            rn = "Compare";
2833
            break;
2834
        /* 6,7 are implementation dependent */
2835
        default:
2836
            goto die;
2837
        }
2838
        break;
2839
    case 12:
2840
        switch (sel) {
2841
        case 0:
2842
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
2843
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2844
            rn = "Status";
2845
            break;
2846
        case 1:
2847
            check_insn(env, ctx, ISA_MIPS32R2);
2848
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
2849
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2850
            rn = "IntCtl";
2851
            break;
2852
        case 2:
2853
            check_insn(env, ctx, ISA_MIPS32R2);
2854
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
2855
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2856
            rn = "SRSCtl";
2857
            break;
2858
        case 3:
2859
            check_insn(env, ctx, ISA_MIPS32R2);
2860
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
2861
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2862
            rn = "SRSMap";
2863
            break;
2864
        default:
2865
            goto die;
2866
       }
2867
        break;
2868
    case 13:
2869
        switch (sel) {
2870
        case 0:
2871
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
2872
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2873
            rn = "Cause";
2874
            break;
2875
        default:
2876
            goto die;
2877
       }
2878
        break;
2879
    case 14:
2880
        switch (sel) {
2881
        case 0:
2882
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2883
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2884
            rn = "EPC";
2885
            break;
2886
        default:
2887
            goto die;
2888
        }
2889
        break;
2890
    case 15:
2891
        switch (sel) {
2892
        case 0:
2893
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
2894
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2895
            rn = "PRid";
2896
            break;
2897
        case 1:
2898
            check_insn(env, ctx, ISA_MIPS32R2);
2899
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
2900
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2901
            rn = "EBase";
2902
            break;
2903
        default:
2904
            goto die;
2905
       }
2906
        break;
2907
    case 16:
2908
        switch (sel) {
2909
        case 0:
2910
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
2911
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2912
            rn = "Config";
2913
            break;
2914
        case 1:
2915
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
2916
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2917
            rn = "Config1";
2918
            break;
2919
        case 2:
2920
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
2921
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2922
            rn = "Config2";
2923
            break;
2924
        case 3:
2925
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
2926
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2927
            rn = "Config3";
2928
            break;
2929
        /* 4,5 are reserved */
2930
        /* 6,7 are implementation dependent */
2931
        case 6:
2932
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
2933
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2934
            rn = "Config6";
2935
            break;
2936
        case 7:
2937
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
2938
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2939
            rn = "Config7";
2940
            break;
2941
        default:
2942
            goto die;
2943
        }
2944
        break;
2945
    case 17:
2946
        switch (sel) {
2947
        case 0:
2948
            gen_op_mfc0_lladdr();
2949
            rn = "LLAddr";
2950
            break;
2951
        default:
2952
            goto die;
2953
        }
2954
        break;
2955
    case 18:
2956
        switch (sel) {
2957
        case 0 ... 7:
2958
            gen_op_mfc0_watchlo(sel);
2959
            rn = "WatchLo";
2960
            break;
2961
        default:
2962
            goto die;
2963
        }
2964
        break;
2965
    case 19:
2966
        switch (sel) {
2967
        case 0 ...7:
2968
            gen_op_mfc0_watchhi(sel);
2969
            rn = "WatchHi";
2970
            break;
2971
        default:
2972
            goto die;
2973
        }
2974
        break;
2975
    case 20:
2976
        switch (sel) {
2977
        case 0:
2978
#if defined(TARGET_MIPS64)
2979
            check_insn(env, ctx, ISA_MIPS3);
2980
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2981
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2982
            rn = "XContext";
2983
            break;
2984
#endif
2985
        default:
2986
            goto die;
2987
        }
2988
        break;
2989
    case 21:
2990
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2991
        switch (sel) {
2992
        case 0:
2993
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
2994
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2995
            rn = "Framemask";
2996
            break;
2997
        default:
2998
            goto die;
2999
        }
3000
        break;
3001
    case 22:
3002
        /* ignored */
3003
        rn = "'Diagnostic"; /* implementation dependent */
3004
        break;
3005
    case 23:
3006
        switch (sel) {
3007
        case 0:
3008
            gen_op_mfc0_debug(); /* EJTAG support */
3009
            rn = "Debug";
3010
            break;
3011
        case 1:
3012
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3013
            rn = "TraceControl";
3014
//            break;
3015
        case 2:
3016
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3017
            rn = "TraceControl2";
3018
//            break;
3019
        case 3:
3020
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3021
            rn = "UserTraceData";
3022
//            break;
3023
        case 4:
3024
//            gen_op_mfc0_debug(); /* PDtrace support */
3025
            rn = "TraceBPC";
3026
//            break;
3027
        default:
3028
            goto die;
3029
        }
3030
        break;
3031
    case 24:
3032
        switch (sel) {
3033
        case 0:
3034
            /* EJTAG support */
3035
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3036
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3037
            rn = "DEPC";
3038
            break;
3039
        default:
3040
            goto die;
3041
        }
3042
        break;
3043
    case 25:
3044
        switch (sel) {
3045
        case 0:
3046
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
3047
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3048
            rn = "Performance0";
3049
            break;
3050
        case 1:
3051
//            gen_op_mfc0_performance1();
3052
            rn = "Performance1";
3053
//            break;
3054
        case 2:
3055
//            gen_op_mfc0_performance2();
3056
            rn = "Performance2";
3057
//            break;
3058
        case 3:
3059
//            gen_op_mfc0_performance3();
3060
            rn = "Performance3";
3061
//            break;
3062
        case 4:
3063
//            gen_op_mfc0_performance4();
3064
            rn = "Performance4";
3065
//            break;
3066
        case 5:
3067
//            gen_op_mfc0_performance5();
3068
            rn = "Performance5";
3069
//            break;
3070
        case 6:
3071
//            gen_op_mfc0_performance6();
3072
            rn = "Performance6";
3073
//            break;
3074
        case 7:
3075
//            gen_op_mfc0_performance7();
3076
            rn = "Performance7";
3077
//            break;
3078
        default:
3079
            goto die;
3080
        }
3081
        break;
3082
    case 26:
3083
       rn = "ECC";
3084
       break;
3085
    case 27:
3086
        switch (sel) {
3087
        /* ignored */
3088
        case 0 ... 3:
3089
            rn = "CacheErr";
3090
            break;
3091
        default:
3092
            goto die;
3093
        }
3094
        break;
3095
    case 28:
3096
        switch (sel) {
3097
        case 0:
3098
        case 2:
3099
        case 4:
3100
        case 6:
3101
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
3102
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3103
            rn = "TagLo";
3104
            break;
3105
        case 1:
3106
        case 3:
3107
        case 5:
3108
        case 7:
3109
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
3110
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3111
            rn = "DataLo";
3112
            break;
3113
        default:
3114
            goto die;
3115
        }
3116
        break;
3117
    case 29:
3118
        switch (sel) {
3119
        case 0:
3120
        case 2:
3121
        case 4:
3122
        case 6:
3123
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
3124
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3125
            rn = "TagHi";
3126
            break;
3127
        case 1:
3128
        case 3:
3129
        case 5:
3130
        case 7:
3131
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
3132
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3133
            rn = "DataHi";
3134
            break;
3135
        default:
3136
            goto die;
3137
        }
3138
        break;
3139
    case 30:
3140
        switch (sel) {
3141
        case 0:
3142
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3143
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3144
            rn = "ErrorEPC";
3145
            break;
3146
        default:
3147
            goto die;
3148
        }
3149
        break;
3150
    case 31:
3151
        switch (sel) {
3152
        case 0:
3153
            /* EJTAG support */
3154
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
3155
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3156
            rn = "DESAVE";
3157
            break;
3158
        default:
3159
            goto die;
3160
        }
3161
        break;
3162
    default:
3163
       goto die;
3164
    }
3165
#if defined MIPS_DEBUG_DISAS
3166
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3167
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3168
                rn, reg, sel);
3169
    }
3170
#endif
3171
    return;
3172

    
3173
die:
3174
#if defined MIPS_DEBUG_DISAS
3175
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3176
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3177
                rn, reg, sel);
3178
    }
3179
#endif
3180
    generate_exception(ctx, EXCP_RI);
3181
}
3182

    
3183
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3184
{
3185
    const char *rn = "invalid";
3186

    
3187
    if (sel != 0)
3188
        check_insn(env, ctx, ISA_MIPS32);
3189

    
3190
    switch (reg) {
3191
    case 0:
3192
        switch (sel) {
3193
        case 0:
3194
            gen_op_mtc0_index();
3195
            rn = "Index";
3196
            break;
3197
        case 1:
3198
            check_insn(env, ctx, ASE_MT);
3199
            gen_op_mtc0_mvpcontrol();
3200
            rn = "MVPControl";
3201
            break;
3202
        case 2:
3203
            check_insn(env, ctx, ASE_MT);
3204
            /* ignored */
3205
            rn = "MVPConf0";
3206
            break;
3207
        case 3:
3208
            check_insn(env, ctx, ASE_MT);
3209
            /* ignored */
3210
            rn = "MVPConf1";
3211
            break;
3212
        default:
3213
            goto die;
3214
        }
3215
        break;
3216
    case 1:
3217
        switch (sel) {
3218
        case 0:
3219
            /* ignored */
3220
            rn = "Random";
3221
            break;
3222
        case 1:
3223
            check_insn(env, ctx, ASE_MT);
3224
            gen_op_mtc0_vpecontrol();
3225
            rn = "VPEControl";
3226
            break;
3227
        case 2:
3228
            check_insn(env, ctx, ASE_MT);
3229
            gen_op_mtc0_vpeconf0();
3230
            rn = "VPEConf0";
3231
            break;
3232
        case 3:
3233
            check_insn(env, ctx, ASE_MT);
3234
            gen_op_mtc0_vpeconf1();
3235
            rn = "VPEConf1";
3236
            break;
3237
        case 4:
3238
            check_insn(env, ctx, ASE_MT);
3239
            gen_op_mtc0_yqmask();
3240
            rn = "YQMask";
3241
            break;
3242
        case 5:
3243
            check_insn(env, ctx, ASE_MT);
3244
            gen_op_mtc0_vpeschedule();
3245
            rn = "VPESchedule";
3246
            break;
3247
        case 6:
3248
            check_insn(env, ctx, ASE_MT);
3249
            gen_op_mtc0_vpeschefback();
3250
            rn = "VPEScheFBack";
3251
            break;
3252
        case 7:
3253
            check_insn(env, ctx, ASE_MT);
3254
            gen_op_mtc0_vpeopt();
3255
            rn = "VPEOpt";
3256
            break;
3257
        default:
3258
            goto die;
3259
        }
3260
        break;
3261
    case 2:
3262
        switch (sel) {
3263
        case 0:
3264
            gen_op_mtc0_entrylo0();
3265
            rn = "EntryLo0";
3266
            break;
3267
        case 1:
3268
            check_insn(env, ctx, ASE_MT);
3269
            gen_op_mtc0_tcstatus();
3270
            rn = "TCStatus";
3271
            break;
3272
        case 2:
3273
            check_insn(env, ctx, ASE_MT);
3274
            gen_op_mtc0_tcbind();
3275
            rn = "TCBind";
3276
            break;
3277
        case 3:
3278
            check_insn(env, ctx, ASE_MT);
3279
            gen_op_mtc0_tcrestart();
3280
            rn = "TCRestart";
3281
            break;
3282
        case 4:
3283
            check_insn(env, ctx, ASE_MT);
3284
            gen_op_mtc0_tchalt();
3285
            rn = "TCHalt";
3286
            break;
3287
        case 5:
3288
            check_insn(env, ctx, ASE_MT);
3289
            gen_op_mtc0_tccontext();
3290
            rn = "TCContext";
3291
            break;
3292
        case 6:
3293
            check_insn(env, ctx, ASE_MT);
3294
            gen_op_mtc0_tcschedule();
3295
            rn = "TCSchedule";
3296
            break;
3297
        case 7:
3298
            check_insn(env, ctx, ASE_MT);
3299
            gen_op_mtc0_tcschefback();
3300
            rn = "TCScheFBack";
3301
            break;
3302
        default:
3303
            goto die;
3304
        }
3305
        break;
3306
    case 3:
3307
        switch (sel) {
3308
        case 0:
3309
            gen_op_mtc0_entrylo1();
3310
            rn = "EntryLo1";
3311
            break;
3312
        default:
3313
            goto die;
3314
        }
3315
        break;
3316
    case 4:
3317
        switch (sel) {
3318
        case 0:
3319
            gen_op_mtc0_context();
3320
            rn = "Context";
3321
            break;
3322
        case 1:
3323
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3324
            rn = "ContextConfig";
3325
//            break;
3326
        default:
3327
            goto die;
3328
        }
3329
        break;
3330
    case 5:
3331
        switch (sel) {
3332
        case 0:
3333
            gen_op_mtc0_pagemask();
3334
            rn = "PageMask";
3335
            break;
3336
        case 1:
3337
            check_insn(env, ctx, ISA_MIPS32R2);
3338
            gen_op_mtc0_pagegrain();
3339
            rn = "PageGrain";
3340
            break;
3341
        default:
3342
            goto die;
3343
        }
3344
        break;
3345
    case 6:
3346
        switch (sel) {
3347
        case 0:
3348
            gen_op_mtc0_wired();
3349
            rn = "Wired";
3350
            break;
3351
        case 1:
3352
            check_insn(env, ctx, ISA_MIPS32R2);
3353
            gen_op_mtc0_srsconf0();
3354
            rn = "SRSConf0";
3355
            break;
3356
        case 2:
3357
            check_insn(env, ctx, ISA_MIPS32R2);
3358
            gen_op_mtc0_srsconf1();
3359
            rn = "SRSConf1";
3360
            break;
3361
        case 3:
3362
            check_insn(env, ctx, ISA_MIPS32R2);
3363
            gen_op_mtc0_srsconf2();
3364
            rn = "SRSConf2";
3365
            break;
3366
        case 4:
3367
            check_insn(env, ctx, ISA_MIPS32R2);
3368
            gen_op_mtc0_srsconf3();
3369
            rn = "SRSConf3";
3370
            break;
3371
        case 5:
3372
            check_insn(env, ctx, ISA_MIPS32R2);
3373
            gen_op_mtc0_srsconf4();
3374
            rn = "SRSConf4";
3375
            break;
3376
        default:
3377
            goto die;
3378
        }
3379
        break;
3380
    case 7:
3381
        switch (sel) {
3382
        case 0:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mtc0_hwrena();
3385
            rn = "HWREna";
3386
            break;
3387
        default:
3388
            goto die;
3389
        }
3390
        break;
3391
    case 8:
3392
        /* ignored */
3393
        rn = "BadVAddr";
3394
        break;
3395
    case 9:
3396
        switch (sel) {
3397
        case 0:
3398
            gen_op_mtc0_count();
3399
            rn = "Count";
3400
            break;
3401
        /* 6,7 are implementation dependent */
3402
        default:
3403
            goto die;
3404
        }
3405
        /* Stop translation as we may have switched the execution mode */
3406
        ctx->bstate = BS_STOP;
3407
        break;
3408
    case 10:
3409
        switch (sel) {
3410
        case 0:
3411
            gen_op_mtc0_entryhi();
3412
            rn = "EntryHi";
3413
            break;
3414
        default:
3415
            goto die;
3416
        }
3417
        break;
3418
    case 11:
3419
        switch (sel) {
3420
        case 0:
3421
            gen_op_mtc0_compare();
3422
            rn = "Compare";
3423
            break;
3424
        /* 6,7 are implementation dependent */
3425
        default:
3426
            goto die;
3427
        }
3428
        /* Stop translation as we may have switched the execution mode */
3429
        ctx->bstate = BS_STOP;
3430
        break;
3431
    case 12:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mtc0_status();
3435
            /* BS_STOP isn't good enough here, hflags may have changed. */
3436
            gen_save_pc(ctx->pc + 4);
3437
            ctx->bstate = BS_EXCP;
3438
            rn = "Status";
3439
            break;
3440
        case 1:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_op_mtc0_intctl();
3443
            /* Stop translation as we may have switched the execution mode */
3444
            ctx->bstate = BS_STOP;
3445
            rn = "IntCtl";
3446
            break;
3447
        case 2:
3448
            check_insn(env, ctx, ISA_MIPS32R2);
3449
            gen_op_mtc0_srsctl();
3450
            /* Stop translation as we may have switched the execution mode */
3451
            ctx->bstate = BS_STOP;
3452
            rn = "SRSCtl";
3453
            break;
3454
        case 3:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_op_mtc0_srsmap();
3457
            /* Stop translation as we may have switched the execution mode */
3458
            ctx->bstate = BS_STOP;
3459
            rn = "SRSMap";
3460
            break;
3461
        default:
3462
            goto die;
3463
        }
3464
        break;
3465
    case 13:
3466
        switch (sel) {
3467
        case 0:
3468
            gen_op_mtc0_cause();
3469
            rn = "Cause";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        /* Stop translation as we may have switched the execution mode */
3475
        ctx->bstate = BS_STOP;
3476
        break;
3477
    case 14:
3478
        switch (sel) {
3479
        case 0:
3480
            gen_op_mtc0_epc();
3481
            rn = "EPC";
3482
            break;
3483
        default:
3484
            goto die;
3485
        }
3486
        break;
3487
    case 15:
3488
        switch (sel) {
3489
        case 0:
3490
            /* ignored */
3491
            rn = "PRid";
3492
            break;
3493
        case 1:
3494
            check_insn(env, ctx, ISA_MIPS32R2);
3495
            gen_op_mtc0_ebase();
3496
            rn = "EBase";
3497
            break;
3498
        default:
3499
            goto die;
3500
        }
3501
        break;
3502
    case 16:
3503
        switch (sel) {
3504
        case 0:
3505
            gen_op_mtc0_config0();
3506
            rn = "Config";
3507
            /* Stop translation as we may have switched the execution mode */
3508
            ctx->bstate = BS_STOP;
3509
            break;
3510
        case 1:
3511
            /* ignored, read only */
3512
            rn = "Config1";
3513
            break;
3514
        case 2:
3515
            gen_op_mtc0_config2();
3516
            rn = "Config2";
3517
            /* Stop translation as we may have switched the execution mode */
3518
            ctx->bstate = BS_STOP;
3519
            break;
3520
        case 3:
3521
            /* ignored, read only */
3522
            rn = "Config3";
3523
            break;
3524
        /* 4,5 are reserved */
3525
        /* 6,7 are implementation dependent */
3526
        case 6:
3527
            /* ignored */
3528
            rn = "Config6";
3529
            break;
3530
        case 7:
3531
            /* ignored */
3532
            rn = "Config7";
3533
            break;
3534
        default:
3535
            rn = "Invalid config selector";
3536
            goto die;
3537
        }
3538
        break;
3539
    case 17:
3540
        switch (sel) {
3541
        case 0:
3542
            /* ignored */
3543
            rn = "LLAddr";
3544
            break;
3545
        default:
3546
            goto die;
3547
        }
3548
        break;
3549
    case 18:
3550
        switch (sel) {
3551
        case 0 ... 7:
3552
            gen_op_mtc0_watchlo(sel);
3553
            rn = "WatchLo";
3554
            break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 19:
3560
        switch (sel) {
3561
        case 0 ... 7:
3562
            gen_op_mtc0_watchhi(sel);
3563
            rn = "WatchHi";
3564
            break;
3565
        default:
3566
            goto die;
3567
        }
3568
        break;
3569
    case 20:
3570
        switch (sel) {
3571
        case 0:
3572
#if defined(TARGET_MIPS64)
3573
            check_insn(env, ctx, ISA_MIPS3);
3574
            gen_op_mtc0_xcontext();
3575
            rn = "XContext";
3576
            break;
3577
#endif
3578
        default:
3579
            goto die;
3580
        }
3581
        break;
3582
    case 21:
3583
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584
        switch (sel) {
3585
        case 0:
3586
            gen_op_mtc0_framemask();
3587
            rn = "Framemask";
3588
            break;
3589
        default:
3590
            goto die;
3591
        }
3592
        break;
3593
    case 22:
3594
        /* ignored */
3595
        rn = "Diagnostic"; /* implementation dependent */
3596
        break;
3597
    case 23:
3598
        switch (sel) {
3599
        case 0:
3600
            gen_op_mtc0_debug(); /* EJTAG support */
3601
            /* BS_STOP isn't good enough here, hflags may have changed. */
3602
            gen_save_pc(ctx->pc + 4);
3603
            ctx->bstate = BS_EXCP;
3604
            rn = "Debug";
3605
            break;
3606
        case 1:
3607
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3608
            rn = "TraceControl";
3609
            /* Stop translation as we may have switched the execution mode */
3610
            ctx->bstate = BS_STOP;
3611
//            break;
3612
        case 2:
3613
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3614
            rn = "TraceControl2";
3615
            /* Stop translation as we may have switched the execution mode */
3616
            ctx->bstate = BS_STOP;
3617
//            break;
3618
        case 3:
3619
            /* Stop translation as we may have switched the execution mode */
3620
            ctx->bstate = BS_STOP;
3621
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3622
            rn = "UserTraceData";
3623
            /* Stop translation as we may have switched the execution mode */
3624
            ctx->bstate = BS_STOP;
3625
//            break;
3626
        case 4:
3627
//            gen_op_mtc0_debug(); /* PDtrace support */
3628
            /* Stop translation as we may have switched the execution mode */
3629
            ctx->bstate = BS_STOP;
3630
            rn = "TraceBPC";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 24:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_op_mtc0_depc(); /* EJTAG support */
3640
            rn = "DEPC";
3641
            break;
3642
        default:
3643
            goto die;
3644
        }
3645
        break;
3646
    case 25:
3647
        switch (sel) {
3648
        case 0:
3649
            gen_op_mtc0_performance0();
3650
            rn = "Performance0";
3651
            break;
3652
        case 1:
3653
//            gen_op_mtc0_performance1();
3654
            rn = "Performance1";
3655
//            break;
3656
        case 2:
3657
//            gen_op_mtc0_performance2();
3658
            rn = "Performance2";
3659
//            break;
3660
        case 3:
3661
//            gen_op_mtc0_performance3();
3662
            rn = "Performance3";
3663
//            break;
3664
        case 4:
3665
//            gen_op_mtc0_performance4();
3666
            rn = "Performance4";
3667
//            break;
3668
        case 5:
3669
//            gen_op_mtc0_performance5();
3670
            rn = "Performance5";
3671
//            break;
3672
        case 6:
3673
//            gen_op_mtc0_performance6();
3674
            rn = "Performance6";
3675
//            break;
3676
        case 7:
3677
//            gen_op_mtc0_performance7();
3678
            rn = "Performance7";
3679
//            break;
3680
        default:
3681
            goto die;
3682
        }
3683
       break;
3684
    case 26:
3685
        /* ignored */
3686
        rn = "ECC";
3687
        break;
3688
    case 27:
3689
        switch (sel) {
3690
        case 0 ... 3:
3691
            /* ignored */
3692
            rn = "CacheErr";
3693
            break;
3694
        default:
3695
            goto die;
3696
        }
3697
       break;
3698
    case 28:
3699
        switch (sel) {
3700
        case 0:
3701
        case 2:
3702
        case 4:
3703
        case 6:
3704
            gen_op_mtc0_taglo();
3705
            rn = "TagLo";
3706
            break;
3707
        case 1:
3708
        case 3:
3709
        case 5:
3710
        case 7:
3711
            gen_op_mtc0_datalo();
3712
            rn = "DataLo";
3713
            break;
3714
        default:
3715
            goto die;
3716
        }
3717
        break;
3718
    case 29:
3719
        switch (sel) {
3720
        case 0:
3721
        case 2:
3722
        case 4:
3723
        case 6:
3724
            gen_op_mtc0_taghi();
3725
            rn = "TagHi";
3726
            break;
3727
        case 1:
3728
        case 3:
3729
        case 5:
3730
        case 7:
3731
            gen_op_mtc0_datahi();
3732
            rn = "DataHi";
3733
            break;
3734
        default:
3735
            rn = "invalid sel";
3736
            goto die;
3737
        }
3738
       break;
3739
    case 30:
3740
        switch (sel) {
3741
        case 0:
3742
            gen_op_mtc0_errorepc();
3743
            rn = "ErrorEPC";
3744
            break;
3745
        default:
3746
            goto die;
3747
        }
3748
        break;
3749
    case 31:
3750
        switch (sel) {
3751
        case 0:
3752
            gen_op_mtc0_desave(); /* EJTAG support */
3753
            rn = "DESAVE";
3754
            break;
3755
        default:
3756
            goto die;
3757
        }
3758
        /* Stop translation as we may have switched the execution mode */
3759
        ctx->bstate = BS_STOP;
3760
        break;
3761
    default:
3762
       goto die;
3763
    }
3764
#if defined MIPS_DEBUG_DISAS
3765
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3766
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3767
                rn, reg, sel);
3768
    }
3769
#endif
3770
    return;
3771

    
3772
die:
3773
#if defined MIPS_DEBUG_DISAS
3774
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3775
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3776
                rn, reg, sel);
3777
    }
3778
#endif
3779
    generate_exception(ctx, EXCP_RI);
3780
}
3781

    
3782
#if defined(TARGET_MIPS64)
3783
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3784
{
3785
    const char *rn = "invalid";
3786
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3787

    
3788
    if (sel != 0)
3789
        check_insn(env, ctx, ISA_MIPS64);
3790

    
3791
    switch (reg) {
3792
    case 0:
3793
        switch (sel) {
3794
        case 0:
3795
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
3796
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3797
            rn = "Index";
3798
            break;
3799
        case 1:
3800
            check_insn(env, ctx, ASE_MT);
3801
            gen_op_mfc0_mvpcontrol();
3802
            rn = "MVPControl";
3803
            break;
3804
        case 2:
3805
            check_insn(env, ctx, ASE_MT);
3806
            gen_op_mfc0_mvpconf0();
3807
            rn = "MVPConf0";
3808
            break;
3809
        case 3:
3810
            check_insn(env, ctx, ASE_MT);
3811
            gen_op_mfc0_mvpconf1();
3812
            rn = "MVPConf1";
3813
            break;
3814
        default:
3815
            goto die;
3816
        }
3817
        break;
3818
    case 1:
3819
        switch (sel) {
3820
        case 0:
3821
            gen_op_mfc0_random();
3822
            rn = "Random";
3823
            break;
3824
        case 1:
3825
            check_insn(env, ctx, ASE_MT);
3826
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
3827
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3828
            rn = "VPEControl";
3829
            break;
3830
        case 2:
3831
            check_insn(env, ctx, ASE_MT);
3832
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
3833
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3834
            rn = "VPEConf0";
3835
            break;
3836
        case 3:
3837
            check_insn(env, ctx, ASE_MT);
3838
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
3839
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3840
            rn = "VPEConf1";
3841
            break;
3842
        case 4:
3843
            check_insn(env, ctx, ASE_MT);
3844
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3845
            rn = "YQMask";
3846
            break;
3847
        case 5:
3848
            check_insn(env, ctx, ASE_MT);
3849
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3850
            rn = "VPESchedule";
3851
            break;
3852
        case 6:
3853
            check_insn(env, ctx, ASE_MT);
3854
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3855
            rn = "VPEScheFBack";
3856
            break;
3857
        case 7:
3858
            check_insn(env, ctx, ASE_MT);
3859
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
3860
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3861
            rn = "VPEOpt";
3862
            break;
3863
        default:
3864
            goto die;
3865
        }
3866
        break;
3867
    case 2:
3868
        switch (sel) {
3869
        case 0:
3870
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3871
            rn = "EntryLo0";
3872
            break;
3873
        case 1:
3874
            check_insn(env, ctx, ASE_MT);
3875
            gen_op_mfc0_tcstatus();
3876
            rn = "TCStatus";
3877
            break;
3878
        case 2:
3879
            check_insn(env, ctx, ASE_MT);
3880
            gen_op_mfc0_tcbind();
3881
            rn = "TCBind";
3882
            break;
3883
        case 3:
3884
            check_insn(env, ctx, ASE_MT);
3885
            gen_op_dmfc0_tcrestart();
3886
            rn = "TCRestart";
3887
            break;
3888
        case 4:
3889
            check_insn(env, ctx, ASE_MT);
3890
            gen_op_dmfc0_tchalt();
3891
            rn = "TCHalt";
3892
            break;
3893
        case 5:
3894
            check_insn(env, ctx, ASE_MT);
3895
            gen_op_dmfc0_tccontext();
3896
            rn = "TCContext";
3897
            break;
3898
        case 6:
3899
            check_insn(env, ctx, ASE_MT);
3900
            gen_op_dmfc0_tcschedule();
3901
            rn = "TCSchedule";
3902
            break;
3903
        case 7:
3904
            check_insn(env, ctx, ASE_MT);
3905
            gen_op_dmfc0_tcschefback();
3906
            rn = "TCScheFBack";
3907
            break;
3908
        default:
3909
            goto die;
3910
        }
3911
        break;
3912
    case 3:
3913
        switch (sel) {
3914
        case 0:
3915
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3916
            rn = "EntryLo1";
3917
            break;
3918
        default:
3919
            goto die;
3920
        }
3921
        break;
3922
    case 4:
3923
        switch (sel) {
3924
        case 0:
3925
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3926
            rn = "Context";
3927
            break;
3928
        case 1:
3929
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3930
            rn = "ContextConfig";
3931
//            break;
3932
        default:
3933
            goto die;
3934
        }
3935
        break;
3936
    case 5:
3937
        switch (sel) {
3938
        case 0:
3939
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
3940
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3941
            rn = "PageMask";
3942
            break;
3943
        case 1:
3944
            check_insn(env, ctx, ISA_MIPS32R2);
3945
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
3946
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3947
            rn = "PageGrain";
3948
            break;
3949
        default:
3950
            goto die;
3951
        }
3952
        break;
3953
    case 6:
3954
        switch (sel) {
3955
        case 0:
3956
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
3957
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3958
            rn = "Wired";
3959
            break;
3960
        case 1:
3961
            check_insn(env, ctx, ISA_MIPS32R2);
3962
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
3963
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3964
            rn = "SRSConf0";
3965
            break;
3966
        case 2:
3967
            check_insn(env, ctx, ISA_MIPS32R2);
3968
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
3969
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3970
            rn = "SRSConf1";
3971
            break;
3972
        case 3:
3973
            check_insn(env, ctx, ISA_MIPS32R2);
3974
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
3975
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3976
            rn = "SRSConf2";
3977
            break;
3978
        case 4:
3979
            check_insn(env, ctx, ISA_MIPS32R2);
3980
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
3981
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3982
            rn = "SRSConf3";
3983
            break;
3984
        case 5:
3985
            check_insn(env, ctx, ISA_MIPS32R2);
3986
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
3987
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3988
            rn = "SRSConf4";
3989
            break;
3990
        default:
3991
            goto die;
3992
        }
3993
        break;
3994
    case 7:
3995
        switch (sel) {
3996
        case 0:
3997
            check_insn(env, ctx, ISA_MIPS32R2);
3998
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
3999
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4000
            rn = "HWREna";
4001
            break;
4002
        default:
4003
            goto die;
4004
        }
4005
        break;
4006
    case 8:
4007
        switch (sel) {
4008
        case 0:
4009
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4010
            rn = "BadVAddr";
4011
            break;
4012
        default:
4013
            goto die;
4014
        }
4015
        break;
4016
    case 9:
4017
        switch (sel) {
4018
        case 0:
4019
            gen_op_mfc0_count();
4020
            rn = "Count";
4021
            break;
4022
        /* 6,7 are implementation dependent */
4023
        default:
4024
            goto die;
4025
        }
4026
        break;
4027
    case 10:
4028
        switch (sel) {
4029
        case 0:
4030
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4031
            rn = "EntryHi";
4032
            break;
4033
        default:
4034
            goto die;
4035
        }
4036
        break;
4037
    case 11:
4038
        switch (sel) {
4039
        case 0:
4040
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
4041
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4042
            rn = "Compare";
4043
            break;
4044
        /* 6,7 are implementation dependent */
4045
        default:
4046
            goto die;
4047
        }
4048
        break;
4049
    case 12:
4050
        switch (sel) {
4051
        case 0:
4052
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
4053
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4054
            rn = "Status";
4055
            break;
4056
        case 1:
4057
            check_insn(env, ctx, ISA_MIPS32R2);
4058
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
4059
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4060
            rn = "IntCtl";
4061
            break;
4062
        case 2:
4063
            check_insn(env, ctx, ISA_MIPS32R2);
4064
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
4065
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4066
            rn = "SRSCtl";
4067
            break;
4068
        case 3:
4069
            check_insn(env, ctx, ISA_MIPS32R2);
4070
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
4071
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4072
            rn = "SRSMap";
4073
            break;
4074
        default:
4075
            goto die;
4076
        }
4077
        break;
4078
    case 13:
4079
        switch (sel) {
4080
        case 0:
4081
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
4082
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4083
            rn = "Cause";
4084
            break;
4085
        default:
4086
            goto die;
4087
        }
4088
        break;
4089
    case 14:
4090
        switch (sel) {
4091
        case 0:
4092
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4093
            rn = "EPC";
4094
            break;
4095
        default:
4096
            goto die;
4097
        }
4098
        break;
4099
    case 15:
4100
        switch (sel) {
4101
        case 0:
4102
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
4103
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4104
            rn = "PRid";
4105
            break;
4106
        case 1:
4107
            check_insn(env, ctx, ISA_MIPS32R2);
4108
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
4109
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4110
            rn = "EBase";
4111
            break;
4112
        default:
4113
            goto die;
4114
        }
4115
        break;
4116
    case 16:
4117
        switch (sel) {
4118
        case 0:
4119
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
4120
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4121
            rn = "Config";
4122
            break;
4123
        case 1:
4124
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
4125
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4126
            rn = "Config1";
4127
            break;
4128
        case 2:
4129
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
4130
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4131
            rn = "Config2";
4132
            break;
4133
        case 3:
4134
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
4135
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4136
            rn = "Config3";
4137
            break;
4138
       /* 6,7 are implementation dependent */
4139
        case 6:
4140
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
4141
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4142
            rn = "Config6";
4143
            break;
4144
        case 7:
4145
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
4146
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4147
            rn = "Config7";
4148
            break;
4149
        default:
4150
            goto die;
4151
        }
4152
        break;
4153
    case 17:
4154
        switch (sel) {
4155
        case 0:
4156
            gen_op_dmfc0_lladdr();
4157
            rn = "LLAddr";
4158
            break;
4159
        default:
4160
            goto die;
4161
        }
4162
        break;
4163
    case 18:
4164
        switch (sel) {
4165
        case 0 ... 7:
4166
            gen_op_dmfc0_watchlo(sel);
4167
            rn = "WatchLo";
4168
            break;
4169
        default:
4170
            goto die;
4171
        }
4172
        break;
4173
    case 19:
4174
        switch (sel) {
4175
        case 0 ... 7:
4176
            gen_op_mfc0_watchhi(sel);
4177
            rn = "WatchHi";
4178
            break;
4179
        default:
4180
            goto die;
4181
        }
4182
        break;
4183
    case 20:
4184
        switch (sel) {
4185
        case 0:
4186
            check_insn(env, ctx, ISA_MIPS3);
4187
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4188
            rn = "XContext";
4189
            break;
4190
        default:
4191
            goto die;
4192
        }
4193
        break;
4194
    case 21:
4195
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4196
        switch (sel) {
4197
        case 0:
4198
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
4199
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4200
            rn = "Framemask";
4201
            break;
4202
        default:
4203
            goto die;
4204
        }
4205
        break;
4206
    case 22:
4207
        /* ignored */
4208
        rn = "'Diagnostic"; /* implementation dependent */
4209
        break;
4210
    case 23:
4211
        switch (sel) {
4212
        case 0:
4213
            gen_op_mfc0_debug(); /* EJTAG support */
4214
            rn = "Debug";
4215
            break;
4216
        case 1:
4217
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4218
            rn = "TraceControl";
4219
//            break;
4220
        case 2:
4221
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4222
            rn = "TraceControl2";
4223
//            break;
4224
        case 3:
4225
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4226
            rn = "UserTraceData";
4227
//            break;
4228
        case 4:
4229
//            gen_op_dmfc0_debug(); /* PDtrace support */
4230
            rn = "TraceBPC";
4231
//            break;
4232
        default:
4233
            goto die;
4234
        }
4235
        break;
4236
    case 24:
4237
        switch (sel) {
4238
        case 0:
4239
            /* EJTAG support */
4240
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4241
            rn = "DEPC";
4242
            break;
4243
        default:
4244
            goto die;
4245
        }
4246
        break;
4247
    case 25:
4248
        switch (sel) {
4249
        case 0:
4250
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
4251
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4252
            rn = "Performance0";
4253
            break;
4254
        case 1:
4255
//            gen_op_dmfc0_performance1();
4256
            rn = "Performance1";
4257
//            break;
4258
        case 2:
4259
//            gen_op_dmfc0_performance2();
4260
            rn = "Performance2";
4261
//            break;
4262
        case 3:
4263
//            gen_op_dmfc0_performance3();
4264
            rn = "Performance3";
4265
//            break;
4266
        case 4:
4267
//            gen_op_dmfc0_performance4();
4268
            rn = "Performance4";
4269
//            break;
4270
        case 5:
4271
//            gen_op_dmfc0_performance5();
4272
            rn = "Performance5";
4273
//            break;
4274
        case 6:
4275
//            gen_op_dmfc0_performance6();
4276
            rn = "Performance6";
4277
//            break;
4278
        case 7:
4279
//            gen_op_dmfc0_performance7();
4280
            rn = "Performance7";
4281
//            break;
4282
        default:
4283
            goto die;
4284
        }
4285
        break;
4286
    case 26:
4287
       rn = "ECC";
4288
       break;
4289
    case 27:
4290
        switch (sel) {
4291
        /* ignored */
4292
        case 0 ... 3:
4293
            rn = "CacheErr";
4294
            break;
4295
        default:
4296
            goto die;
4297
        }
4298
        break;
4299
    case 28:
4300
        switch (sel) {
4301
        case 0:
4302
        case 2:
4303
        case 4:
4304
        case 6:
4305
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
4306
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4307
            rn = "TagLo";
4308
            break;
4309
        case 1:
4310
        case 3:
4311
        case 5:
4312
        case 7:
4313
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
4314
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4315
            rn = "DataLo";
4316
            break;
4317
        default:
4318
            goto die;
4319
        }
4320
        break;
4321
    case 29:
4322
        switch (sel) {
4323
        case 0:
4324
        case 2:
4325
        case 4:
4326
        case 6:
4327
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
4328
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4329
            rn = "TagHi";
4330
            break;
4331
        case 1:
4332
        case 3:
4333
        case 5:
4334
        case 7:
4335
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
4336
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4337
            rn = "DataHi";
4338
            break;
4339
        default:
4340
            goto die;
4341
        }
4342
        break;
4343
    case 30:
4344
        switch (sel) {
4345
        case 0:
4346
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4347
            rn = "ErrorEPC";
4348
            break;
4349
        default:
4350
            goto die;
4351
        }
4352
        break;
4353
    case 31:
4354
        switch (sel) {
4355
        case 0:
4356
            /* EJTAG support */
4357
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
4358
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4359
            rn = "DESAVE";
4360
            break;
4361
        default:
4362
            goto die;
4363
        }
4364
        break;
4365
    default:
4366
        goto die;
4367
    }
4368
#if defined MIPS_DEBUG_DISAS
4369
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4370
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4371
                rn, reg, sel);
4372
    }
4373
#endif
4374
    return;
4375

    
4376
die:
4377
#if defined MIPS_DEBUG_DISAS
4378
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4379
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4380
                rn, reg, sel);
4381
    }
4382
#endif
4383
    generate_exception(ctx, EXCP_RI);
4384
}
4385

    
4386
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4387
{
4388
    const char *rn = "invalid";
4389

    
4390
    if (sel != 0)
4391
        check_insn(env, ctx, ISA_MIPS64);
4392

    
4393
    switch (reg) {
4394
    case 0:
4395
        switch (sel) {
4396
        case 0:
4397
            gen_op_mtc0_index();
4398
            rn = "Index";
4399
            break;
4400
        case 1:
4401
            check_insn(env, ctx, ASE_MT);
4402
            gen_op_mtc0_mvpcontrol();
4403
            rn = "MVPControl";
4404
            break;
4405
        case 2:
4406
            check_insn(env, ctx, ASE_MT);
4407
            /* ignored */
4408
            rn = "MVPConf0";
4409
            break;
4410
        case 3:
4411
            check_insn(env, ctx, ASE_MT);
4412
            /* ignored */
4413
            rn = "MVPConf1";
4414
            break;
4415
        default:
4416
            goto die;
4417
        }
4418
        break;
4419
    case 1:
4420
        switch (sel) {
4421
        case 0:
4422
            /* ignored */
4423
            rn = "Random";
4424
            break;
4425
        case 1:
4426
            check_insn(env, ctx, ASE_MT);
4427
            gen_op_mtc0_vpecontrol();
4428
            rn = "VPEControl";
4429
            break;
4430
        case 2:
4431
            check_insn(env, ctx, ASE_MT);
4432
            gen_op_mtc0_vpeconf0();
4433
            rn = "VPEConf0";
4434
            break;
4435
        case 3:
4436
            check_insn(env, ctx, ASE_MT);
4437
            gen_op_mtc0_vpeconf1();
4438
            rn = "VPEConf1";
4439
            break;
4440
        case 4:
4441
            check_insn(env, ctx, ASE_MT);
4442
            gen_op_mtc0_yqmask();
4443
            rn = "YQMask";
4444
            break;
4445
        case 5:
4446
            check_insn(env, ctx, ASE_MT);
4447
            gen_op_mtc0_vpeschedule();
4448
            rn = "VPESchedule";
4449
            break;
4450
        case 6:
4451
            check_insn(env, ctx, ASE_MT);
4452
            gen_op_mtc0_vpeschefback();
4453
            rn = "VPEScheFBack";
4454
            break;
4455
        case 7:
4456
            check_insn(env, ctx, ASE_MT);
4457
            gen_op_mtc0_vpeopt();
4458
            rn = "VPEOpt";
4459
            break;
4460
        default:
4461
            goto die;
4462
        }
4463
        break;
4464
    case 2:
4465
        switch (sel) {
4466
        case 0:
4467
            gen_op_mtc0_entrylo0();
4468
            rn = "EntryLo0";
4469
            break;
4470
        case 1:
4471
            check_insn(env, ctx, ASE_MT);
4472
            gen_op_mtc0_tcstatus();
4473
            rn = "TCStatus";
4474
            break;
4475
        case 2:
4476
            check_insn(env, ctx, ASE_MT);
4477
            gen_op_mtc0_tcbind();
4478
            rn = "TCBind";
4479
            break;
4480
        case 3:
4481
            check_insn(env, ctx, ASE_MT);
4482
            gen_op_mtc0_tcrestart();
4483
            rn = "TCRestart";
4484
            break;
4485
        case 4:
4486
            check_insn(env, ctx, ASE_MT);
4487
            gen_op_mtc0_tchalt();
4488
            rn = "TCHalt";
4489
            break;
4490
        case 5:
4491
            check_insn(env, ctx, ASE_MT);
4492
            gen_op_mtc0_tccontext();
4493
            rn = "TCContext";
4494
            break;
4495
        case 6:
4496
            check_insn(env, ctx, ASE_MT);
4497
            gen_op_mtc0_tcschedule();
4498
            rn = "TCSchedule";
4499
            break;
4500
        case 7:
4501
            check_insn(env, ctx, ASE_MT);
4502
            gen_op_mtc0_tcschefback();
4503
            rn = "TCScheFBack";
4504
            break;
4505
        default:
4506
            goto die;
4507
        }
4508
        break;
4509
    case 3:
4510
        switch (sel) {
4511
        case 0:
4512
            gen_op_mtc0_entrylo1();
4513
            rn = "EntryLo1";
4514
            break;
4515
        default:
4516
            goto die;
4517
        }
4518
        break;
4519
    case 4:
4520
        switch (sel) {
4521
        case 0:
4522
            gen_op_mtc0_context();
4523
            rn = "Context";
4524
            break;
4525
        case 1:
4526
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4527
            rn = "ContextConfig";
4528
//           break;
4529
        default:
4530
            goto die;
4531
        }
4532
        break;
4533
    case 5:
4534
        switch (sel) {
4535
        case 0:
4536
            gen_op_mtc0_pagemask();
4537
            rn = "PageMask";
4538
            break;
4539
        case 1:
4540
            check_insn(env, ctx, ISA_MIPS32R2);
4541
            gen_op_mtc0_pagegrain();
4542
            rn = "PageGrain";
4543
            break;
4544
        default:
4545
            goto die;
4546
        }
4547
        break;
4548
    case 6:
4549
        switch (sel) {
4550
        case 0:
4551
            gen_op_mtc0_wired();
4552
            rn = "Wired";
4553
            break;
4554
        case 1:
4555
            check_insn(env, ctx, ISA_MIPS32R2);
4556
            gen_op_mtc0_srsconf0();
4557
            rn = "SRSConf0";
4558
            break;
4559
        case 2:
4560
            check_insn(env, ctx, ISA_MIPS32R2);
4561
            gen_op_mtc0_srsconf1();
4562
            rn = "SRSConf1";
4563
            break;
4564
        case 3:
4565
            check_insn(env, ctx, ISA_MIPS32R2);
4566
            gen_op_mtc0_srsconf2();
4567
            rn = "SRSConf2";
4568
            break;
4569
        case 4:
4570
            check_insn(env, ctx, ISA_MIPS32R2);
4571
            gen_op_mtc0_srsconf3();
4572
            rn = "SRSConf3";
4573
            break;
4574
        case 5:
4575
            check_insn(env, ctx, ISA_MIPS32R2);
4576
            gen_op_mtc0_srsconf4();
4577
            rn = "SRSConf4";
4578
            break;
4579
        default:
4580
            goto die;
4581
        }
4582
        break;
4583
    case 7:
4584
        switch (sel) {
4585
        case 0:
4586
            check_insn(env, ctx, ISA_MIPS32R2);
4587
            gen_op_mtc0_hwrena();
4588
            rn = "HWREna";
4589
            break;
4590
        default:
4591
            goto die;
4592
        }
4593
        break;
4594
    case 8:
4595
        /* ignored */
4596
        rn = "BadVAddr";
4597
        break;
4598
    case 9:
4599
        switch (sel) {
4600
        case 0:
4601
            gen_op_mtc0_count();
4602
            rn = "Count";
4603
            break;
4604
        /* 6,7 are implementation dependent */
4605
        default:
4606
            goto die;
4607
        }
4608
        /* Stop translation as we may have switched the execution mode */
4609
        ctx->bstate = BS_STOP;
4610
        break;
4611
    case 10:
4612
        switch (sel) {
4613
        case 0:
4614
            gen_op_mtc0_entryhi();
4615
            rn = "EntryHi";
4616
            break;
4617
        default:
4618
            goto die;
4619
        }
4620
        break;
4621
    case 11:
4622
        switch (sel) {
4623
        case 0:
4624
            gen_op_mtc0_compare();
4625
            rn = "Compare";
4626
            break;
4627
        /* 6,7 are implementation dependent */
4628
        default:
4629
            goto die;
4630
        }
4631
        /* Stop translation as we may have switched the execution mode */
4632
        ctx->bstate = BS_STOP;
4633
        break;
4634
    case 12:
4635
        switch (sel) {
4636
        case 0:
4637
            gen_op_mtc0_status();
4638
            /* BS_STOP isn't good enough here, hflags may have changed. */
4639
            gen_save_pc(ctx->pc + 4);
4640
            ctx->bstate = BS_EXCP;
4641
            rn = "Status";
4642
            break;
4643
        case 1:
4644
            check_insn(env, ctx, ISA_MIPS32R2);
4645
            gen_op_mtc0_intctl();
4646
            /* Stop translation as we may have switched the execution mode */
4647
            ctx->bstate = BS_STOP;
4648
            rn = "IntCtl";
4649
            break;
4650
        case 2:
4651
            check_insn(env, ctx, ISA_MIPS32R2);
4652
            gen_op_mtc0_srsctl();
4653
            /* Stop translation as we may have switched the execution mode */
4654
            ctx->bstate = BS_STOP;
4655
            rn = "SRSCtl";
4656
            break;
4657
        case 3:
4658
            check_insn(env, ctx, ISA_MIPS32R2);
4659
            gen_op_mtc0_srsmap();
4660
            /* Stop translation as we may have switched the execution mode */
4661
            ctx->bstate = BS_STOP;
4662
            rn = "SRSMap";
4663
            break;
4664
        default:
4665
            goto die;
4666
        }
4667
        break;
4668
    case 13:
4669
        switch (sel) {
4670
        case 0:
4671
            gen_op_mtc0_cause();
4672
            rn = "Cause";
4673
            break;
4674
        default:
4675
            goto die;
4676
        }
4677
        /* Stop translation as we may have switched the execution mode */
4678
        ctx->bstate = BS_STOP;
4679
        break;
4680
    case 14:
4681
        switch (sel) {
4682
        case 0:
4683
            gen_op_mtc0_epc();
4684
            rn = "EPC";
4685
            break;
4686
        default:
4687
            goto die;
4688
        }
4689
        break;
4690
    case 15:
4691
        switch (sel) {
4692
        case 0:
4693
            /* ignored */
4694
            rn = "PRid";
4695
            break;
4696
        case 1:
4697
            check_insn(env, ctx, ISA_MIPS32R2);
4698
            gen_op_mtc0_ebase();
4699
            rn = "EBase";
4700
            break;
4701
        default:
4702
            goto die;
4703
        }
4704
        break;
4705
    case 16:
4706
        switch (sel) {
4707
        case 0:
4708
            gen_op_mtc0_config0();
4709
            rn = "Config";
4710
            /* Stop translation as we may have switched the execution mode */
4711
            ctx->bstate = BS_STOP;
4712
            break;
4713
        case 1:
4714
            /* ignored */
4715
            rn = "Config1";
4716
            break;
4717
        case 2:
4718
            gen_op_mtc0_config2();
4719
            rn = "Config2";
4720
            /* Stop translation as we may have switched the execution mode */
4721
            ctx->bstate = BS_STOP;
4722
            break;
4723
        case 3:
4724
            /* ignored */
4725
            rn = "Config3";
4726
            break;
4727
        /* 6,7 are implementation dependent */
4728
        default:
4729
            rn = "Invalid config selector";
4730
            goto die;
4731
        }
4732
        break;
4733
    case 17:
4734
        switch (sel) {
4735
        case 0:
4736
            /* ignored */
4737
            rn = "LLAddr";
4738
            break;
4739
        default:
4740
            goto die;
4741
        }
4742
        break;
4743
    case 18:
4744
        switch (sel) {
4745
        case 0 ... 7:
4746
            gen_op_mtc0_watchlo(sel);
4747
            rn = "WatchLo";
4748
            break;
4749
        default:
4750
            goto die;
4751
        }
4752
        break;
4753
    case 19:
4754
        switch (sel) {
4755
        case 0 ... 7:
4756
            gen_op_mtc0_watchhi(sel);
4757
            rn = "WatchHi";
4758
            break;
4759
        default:
4760
            goto die;
4761
        }
4762
        break;
4763
    case 20:
4764
        switch (sel) {
4765
        case 0:
4766
            check_insn(env, ctx, ISA_MIPS3);
4767
            gen_op_mtc0_xcontext();
4768
            rn = "XContext";
4769
            break;
4770
        default:
4771
            goto die;
4772
        }
4773
        break;
4774
    case 21:
4775
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4776
        switch (sel) {
4777
        case 0:
4778
            gen_op_mtc0_framemask();
4779
            rn = "Framemask";
4780
            break;
4781
        default:
4782
            goto die;
4783
        }
4784
        break;
4785
    case 22:
4786
        /* ignored */
4787
        rn = "Diagnostic"; /* implementation dependent */
4788
        break;
4789
    case 23:
4790
        switch (sel) {
4791
        case 0:
4792
            gen_op_mtc0_debug(); /* EJTAG support */
4793
            /* BS_STOP isn't good enough here, hflags may have changed. */
4794
            gen_save_pc(ctx->pc + 4);
4795
            ctx->bstate = BS_EXCP;
4796
            rn = "Debug";
4797
            break;
4798
        case 1:
4799
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4800
            /* Stop translation as we may have switched the execution mode */
4801
            ctx->bstate = BS_STOP;
4802
            rn = "TraceControl";
4803
//            break;
4804
        case 2:
4805
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4806
            /* Stop translation as we may have switched the execution mode */
4807
            ctx->bstate = BS_STOP;
4808
            rn = "TraceControl2";
4809
//            break;
4810
        case 3:
4811
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4812
            /* Stop translation as we may have switched the execution mode */
4813
            ctx->bstate = BS_STOP;
4814
            rn = "UserTraceData";
4815
//            break;
4816
        case 4:
4817
//            gen_op_mtc0_debug(); /* PDtrace support */
4818
            /* Stop translation as we may have switched the execution mode */
4819
            ctx->bstate = BS_STOP;
4820
            rn = "TraceBPC";
4821
//            break;
4822
        default:
4823
            goto die;
4824
        }
4825
        break;
4826
    case 24:
4827
        switch (sel) {
4828
        case 0:
4829
            gen_op_mtc0_depc(); /* EJTAG support */
4830
            rn = "DEPC";
4831
            break;
4832
        default:
4833
            goto die;
4834
        }
4835
        break;
4836
    case 25:
4837
        switch (sel) {
4838
        case 0:
4839
            gen_op_mtc0_performance0();
4840
            rn = "Performance0";
4841
            break;
4842
        case 1:
4843
//            gen_op_mtc0_performance1();
4844
            rn = "Performance1";
4845
//            break;
4846
        case 2:
4847
//            gen_op_mtc0_performance2();
4848
            rn = "Performance2";
4849
//            break;
4850
        case 3:
4851
//            gen_op_mtc0_performance3();
4852
            rn = "Performance3";
4853
//            break;
4854
        case 4:
4855
//            gen_op_mtc0_performance4();
4856
            rn = "Performance4";
4857
//            break;
4858
        case 5:
4859
//            gen_op_mtc0_performance5();
4860
            rn = "Performance5";
4861
//            break;
4862
        case 6:
4863
//            gen_op_mtc0_performance6();
4864
            rn = "Performance6";
4865
//            break;
4866
        case 7:
4867
//            gen_op_mtc0_performance7();
4868
            rn = "Performance7";
4869
//            break;
4870
        default:
4871
            goto die;
4872
        }
4873
        break;
4874
    case 26:
4875
        /* ignored */
4876
        rn = "ECC";
4877
        break;
4878
    case 27:
4879
        switch (sel) {
4880
        case 0 ... 3:
4881
            /* ignored */
4882
            rn = "CacheErr";
4883
            break;
4884
        default:
4885
            goto die;
4886
        }
4887
        break;
4888
    case 28:
4889
        switch (sel) {
4890
        case 0:
4891
        case 2:
4892
        case 4:
4893
        case 6:
4894
            gen_op_mtc0_taglo();
4895
            rn = "TagLo";
4896
            break;
4897
        case 1:
4898
        case 3:
4899
        case 5:
4900
        case 7:
4901
            gen_op_mtc0_datalo();
4902
            rn = "DataLo";
4903
            break;
4904
        default:
4905
            goto die;
4906
        }
4907
        break;
4908
    case 29:
4909
        switch (sel) {
4910
        case 0:
4911
        case 2:
4912
        case 4:
4913
        case 6:
4914
            gen_op_mtc0_taghi();
4915
            rn = "TagHi";
4916
            break;
4917
        case 1:
4918
        case 3:
4919
        case 5:
4920
        case 7:
4921
            gen_op_mtc0_datahi();
4922
            rn = "DataHi";
4923
            break;
4924
        default:
4925
            rn = "invalid sel";
4926
            goto die;
4927
        }
4928
        break;
4929
    case 30:
4930
        switch (sel) {
4931
        case 0:
4932
            gen_op_mtc0_errorepc();
4933
            rn = "ErrorEPC";
4934
            break;
4935
        default:
4936
            goto die;
4937
        }
4938
        break;
4939
    case 31:
4940
        switch (sel) {
4941
        case 0:
4942
            gen_op_mtc0_desave(); /* EJTAG support */
4943
            rn = "DESAVE";
4944
            break;
4945
        default:
4946
            goto die;
4947
        }
4948
        /* Stop translation as we may have switched the execution mode */
4949
        ctx->bstate = BS_STOP;
4950
        break;
4951
    default:
4952
        goto die;
4953
    }
4954
#if defined MIPS_DEBUG_DISAS
4955
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4956
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4957
                rn, reg, sel);
4958
    }
4959
#endif
4960
    return;
4961

    
4962
die:
4963
#if defined MIPS_DEBUG_DISAS
4964
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4965
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4966
                rn, reg, sel);
4967
    }
4968
#endif
4969
    generate_exception(ctx, EXCP_RI);
4970
}
4971
#endif /* TARGET_MIPS64 */
4972

    
4973
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4974
                     int u, int sel, int h)
4975
{
4976
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4977

    
4978
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4979
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4980
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4981
        tcg_gen_movi_tl(cpu_T[0], -1);
4982
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4983
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4984
        tcg_gen_movi_tl(cpu_T[0], -1);
4985
    else if (u == 0) {
4986
        switch (rt) {
4987
        case 2:
4988
            switch (sel) {
4989
            case 1:
4990
                gen_op_mftc0_tcstatus();
4991
                break;
4992
            case 2:
4993
                gen_op_mftc0_tcbind();
4994
                break;
4995
            case 3:
4996
                gen_op_mftc0_tcrestart();
4997
                break;
4998
            case 4:
4999
                gen_op_mftc0_tchalt();
5000
                break;
5001
            case 5:
5002
                gen_op_mftc0_tccontext();
5003
                break;
5004
            case 6:
5005
                gen_op_mftc0_tcschedule();
5006
                break;
5007
            case 7:
5008
                gen_op_mftc0_tcschefback();
5009
                break;
5010
            default:
5011
                gen_mfc0(env, ctx, rt, sel);
5012
                break;
5013
            }
5014
            break;
5015
        case 10:
5016
            switch (sel) {
5017
            case 0:
5018
                gen_op_mftc0_entryhi();
5019
                break;
5020
            default:
5021
                gen_mfc0(env, ctx, rt, sel);
5022
                break;
5023
            }
5024
        case 12:
5025
            switch (sel) {
5026
            case 0:
5027
                gen_op_mftc0_status();
5028
                break;
5029
            default:
5030
                gen_mfc0(env, ctx, rt, sel);
5031
                break;
5032
            }
5033
        case 23:
5034
            switch (sel) {
5035
            case 0:
5036
                gen_op_mftc0_debug();
5037
                break;
5038
            default:
5039
                gen_mfc0(env, ctx, rt, sel);
5040
                break;
5041
            }
5042
            break;
5043
        default:
5044
            gen_mfc0(env, ctx, rt, sel);
5045
        }
5046
    } else switch (sel) {
5047
    /* GPR registers. */
5048
    case 0:
5049
        gen_op_mftgpr(rt);
5050
        break;
5051
    /* Auxiliary CPU registers */
5052
    case 1:
5053
        switch (rt) {
5054
        case 0:
5055
            gen_op_mftlo(0);
5056
            break;
5057
        case 1:
5058
            gen_op_mfthi(0);
5059
            break;
5060
        case 2:
5061
            gen_op_mftacx(0);
5062
            break;
5063
        case 4:
5064
            gen_op_mftlo(1);
5065
            break;
5066
        case 5:
5067
            gen_op_mfthi(1);
5068
            break;
5069
        case 6:
5070
            gen_op_mftacx(1);
5071
            break;
5072
        case 8:
5073
            gen_op_mftlo(2);
5074
            break;
5075
        case 9:
5076
            gen_op_mfthi(2);
5077
            break;
5078
        case 10:
5079
            gen_op_mftacx(2);
5080
            break;
5081
        case 12:
5082
            gen_op_mftlo(3);
5083
            break;
5084
        case 13:
5085
            gen_op_mfthi(3);
5086
            break;
5087
        case 14:
5088
            gen_op_mftacx(3);
5089
            break;
5090
        case 16:
5091
            gen_op_mftdsp();
5092
            break;
5093
        default:
5094
            goto die;
5095
        }
5096
        break;
5097
    /* Floating point (COP1). */
5098
    case 2:
5099
        /* XXX: For now we support only a single FPU context. */
5100
        if (h == 0) {
5101
            GEN_LOAD_FREG_FTN(WT0, rt);
5102
            gen_op_mfc1();
5103
        } else {
5104
            GEN_LOAD_FREG_FTN(WTH0, rt);
5105
            gen_op_mfhc1();
5106
        }
5107
        break;
5108
    case 3:
5109
        /* XXX: For now we support only a single FPU context. */
5110
        gen_op_cfc1(rt);
5111
        break;
5112
    /* COP2: Not implemented. */
5113
    case 4:
5114
    case 5:
5115
        /* fall through */
5116
    default:
5117
        goto die;
5118
    }
5119
#if defined MIPS_DEBUG_DISAS
5120
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5121
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5122
                rt, u, sel, h);
5123
    }
5124
#endif
5125
    return;
5126

    
5127
die:
5128
#if defined MIPS_DEBUG_DISAS
5129
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5130
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5131
                rt, u, sel, h);
5132
    }
5133
#endif
5134
    generate_exception(ctx, EXCP_RI);
5135
}
5136

    
5137
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5138
                     int u, int sel, int h)
5139
{
5140
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5141

    
5142
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5143
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5144
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5145
        /* NOP */ ;
5146
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5147
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5148
        /* NOP */ ;
5149
    else if (u == 0) {
5150
        switch (rd) {
5151
        case 2:
5152
            switch (sel) {
5153
            case 1:
5154
                gen_op_mttc0_tcstatus();
5155
                break;
5156
            case 2:
5157
                gen_op_mttc0_tcbind();
5158
                break;
5159
            case 3:
5160
                gen_op_mttc0_tcrestart();
5161
                break;
5162
            case 4:
5163
                gen_op_mttc0_tchalt();
5164
                break;
5165
            case 5:
5166
                gen_op_mttc0_tccontext();
5167
                break;
5168
            case 6:
5169
                gen_op_mttc0_tcschedule();
5170
                break;
5171
            case 7:
5172
                gen_op_mttc0_tcschefback();
5173
                break;
5174
            default:
5175
                gen_mtc0(env, ctx, rd, sel);
5176
                break;
5177
            }
5178
            break;
5179
        case 10:
5180
            switch (sel) {
5181
            case 0:
5182
                gen_op_mttc0_entryhi();
5183
                break;
5184
            default:
5185
                gen_mtc0(env, ctx, rd, sel);
5186
                break;
5187
            }
5188
        case 12:
5189
            switch (sel) {
5190
            case 0:
5191
                gen_op_mttc0_status();
5192
                break;
5193
            default:
5194
                gen_mtc0(env, ctx, rd, sel);
5195
                break;
5196
            }
5197
        case 23:
5198
            switch (sel) {
5199
            case 0:
5200
                gen_op_mttc0_debug();
5201
                break;
5202
            default:
5203
                gen_mtc0(env, ctx, rd, sel);
5204
                break;
5205
            }
5206
            break;
5207
        default:
5208
            gen_mtc0(env, ctx, rd, sel);
5209
        }
5210
    } else switch (sel) {
5211
    /* GPR registers. */
5212
    case 0:
5213
        gen_op_mttgpr(rd);
5214
        break;
5215
    /* Auxiliary CPU registers */
5216
    case 1:
5217
        switch (rd) {
5218
        case 0:
5219
            gen_op_mttlo(0);
5220
            break;
5221
        case 1:
5222
            gen_op_mtthi(0);
5223
            break;
5224
        case 2:
5225
            gen_op_mttacx(0);
5226
            break;
5227
        case 4:
5228
            gen_op_mttlo(1);
5229
            break;
5230
        case 5:
5231
            gen_op_mtthi(1);
5232
            break;
5233
        case 6:
5234
            gen_op_mttacx(1);
5235
            break;
5236
        case 8:
5237
            gen_op_mttlo(2);
5238
            break;
5239
        case 9:
5240
            gen_op_mtthi(2);
5241
            break;
5242
        case 10:
5243
            gen_op_mttacx(2);
5244
            break;
5245
        case 12:
5246
            gen_op_mttlo(3);
5247
            break;
5248
        case 13:
5249
            gen_op_mtthi(3);
5250
            break;
5251
        case 14:
5252
            gen_op_mttacx(3);
5253
            break;
5254
        case 16:
5255
            gen_op_mttdsp();
5256
            break;
5257
        default:
5258
            goto die;
5259
        }
5260
        break;
5261
    /* Floating point (COP1). */
5262
    case 2:
5263
        /* XXX: For now we support only a single FPU context. */
5264
        if (h == 0) {
5265
            gen_op_mtc1();
5266
            GEN_STORE_FTN_FREG(rd, WT0);
5267
        } else {
5268
            gen_op_mthc1();
5269
            GEN_STORE_FTN_FREG(rd, WTH0);
5270
        }
5271
        break;
5272
    case 3:
5273
        /* XXX: For now we support only a single FPU context. */
5274
        gen_op_ctc1(rd);
5275
        break;
5276
    /* COP2: Not implemented. */
5277
    case 4:
5278
    case 5:
5279
        /* fall through */
5280
    default:
5281
        goto die;
5282
    }
5283
#if defined MIPS_DEBUG_DISAS
5284
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5285
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5286
                rd, u, sel, h);
5287
    }
5288
#endif
5289
    return;
5290

    
5291
die:
5292
#if defined MIPS_DEBUG_DISAS
5293
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5294
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5295
                rd, u, sel, h);
5296
    }
5297
#endif
5298
    generate_exception(ctx, EXCP_RI);
5299
}
5300

    
5301
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5302
{
5303
    const char *opn = "ldst";
5304

    
5305
    switch (opc) {
5306
    case OPC_MFC0:
5307
        if (rt == 0) {
5308
            /* Treat as NOP. */
5309
            return;
5310
        }
5311
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5312
        gen_store_gpr(cpu_T[0], rt);
5313
        opn = "mfc0";
5314
        break;
5315
    case OPC_MTC0:
5316
        gen_load_gpr(cpu_T[0], rt);
5317
        save_cpu_state(ctx, 1);
5318
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5319
        opn = "mtc0";
5320
        break;
5321
#if defined(TARGET_MIPS64)
5322
    case OPC_DMFC0:
5323
        check_insn(env, ctx, ISA_MIPS3);
5324
        if (rt == 0) {
5325
            /* Treat as NOP. */
5326
            return;
5327
        }
5328
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5329
        gen_store_gpr(cpu_T[0], rt);
5330
        opn = "dmfc0";
5331
        break;
5332
    case OPC_DMTC0:
5333
        check_insn(env, ctx, ISA_MIPS3);
5334
        gen_load_gpr(cpu_T[0], rt);
5335
        save_cpu_state(ctx, 1);
5336
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5337
        opn = "dmtc0";
5338
        break;
5339
#endif
5340
    case OPC_MFTR:
5341
        check_insn(env, ctx, ASE_MT);
5342
        if (rd == 0) {
5343
            /* Treat as NOP. */
5344
            return;
5345
        }
5346
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5347
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5348
        gen_store_gpr(cpu_T[0], rd);
5349
        opn = "mftr";
5350
        break;
5351
    case OPC_MTTR:
5352
        check_insn(env, ctx, ASE_MT);
5353
        gen_load_gpr(cpu_T[0], rt);
5354
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5355
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5356
        opn = "mttr";
5357
        break;
5358
    case OPC_TLBWI:
5359
        opn = "tlbwi";
5360
        if (!env->tlb->do_tlbwi)
5361
            goto die;
5362
        gen_op_tlbwi();
5363
        break;
5364
    case OPC_TLBWR:
5365
        opn = "tlbwr";
5366
        if (!env->tlb->do_tlbwr)
5367
            goto die;
5368
        gen_op_tlbwr();
5369
        break;
5370
    case OPC_TLBP:
5371
        opn = "tlbp";
5372
        if (!env->tlb->do_tlbp)
5373
            goto die;
5374
        gen_op_tlbp();
5375
        break;
5376
    case OPC_TLBR:
5377
        opn = "tlbr";
5378
        if (!env->tlb->do_tlbr)
5379
            goto die;
5380
        gen_op_tlbr();
5381
        break;
5382
    case OPC_ERET:
5383
        opn = "eret";
5384
        check_insn(env, ctx, ISA_MIPS2);
5385
        save_cpu_state(ctx, 1);
5386
        gen_op_eret();
5387
        ctx->bstate = BS_EXCP;
5388
        break;
5389
    case OPC_DERET:
5390
        opn = "deret";
5391
        check_insn(env, ctx, ISA_MIPS32);
5392
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5393
            MIPS_INVAL(opn);
5394
            generate_exception(ctx, EXCP_RI);
5395
        } else {
5396
            save_cpu_state(ctx, 1);
5397
            gen_op_deret();
5398
            ctx->bstate = BS_EXCP;
5399
        }
5400
        break;
5401
    case OPC_WAIT:
5402
        opn = "wait";
5403
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5404
        /* If we get an exception, we want to restart at next instruction */
5405
        ctx->pc += 4;
5406
        save_cpu_state(ctx, 1);
5407
        ctx->pc -= 4;
5408
        gen_op_wait();
5409
        ctx->bstate = BS_EXCP;
5410
        break;
5411
    default:
5412
 die:
5413
        MIPS_INVAL(opn);
5414
        generate_exception(ctx, EXCP_RI);
5415
        return;
5416
    }
5417
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5418
}
5419

    
5420
/* CP1 Branches (before delay slot) */
5421
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5422
                                 int32_t cc, int32_t offset)
5423
{
5424
    target_ulong btarget;
5425
    const char *opn = "cp1 cond branch";
5426

    
5427
    if (cc != 0)
5428
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5429

    
5430
    btarget = ctx->pc + 4 + offset;
5431

    
5432
    switch (op) {
5433
    case OPC_BC1F:
5434
        gen_op_bc1f(cc);
5435
        opn = "bc1f";
5436
        goto not_likely;
5437
    case OPC_BC1FL:
5438
        gen_op_bc1f(cc);
5439
        opn = "bc1fl";
5440
        goto likely;
5441
    case OPC_BC1T:
5442
        gen_op_bc1t(cc);
5443
        opn = "bc1t";
5444
        goto not_likely;
5445
    case OPC_BC1TL:
5446
        gen_op_bc1t(cc);
5447
        opn = "bc1tl";
5448
    likely:
5449
        ctx->hflags |= MIPS_HFLAG_BL;
5450
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5451
        break;
5452
    case OPC_BC1FANY2:
5453
        gen_op_bc1any2f(cc);
5454
        opn = "bc1any2f";
5455
        goto not_likely;
5456
    case OPC_BC1TANY2:
5457
        gen_op_bc1any2t(cc);
5458
        opn = "bc1any2t";
5459
        goto not_likely;
5460
    case OPC_BC1FANY4:
5461
        gen_op_bc1any4f(cc);
5462
        opn = "bc1any4f";
5463
        goto not_likely;
5464
    case OPC_BC1TANY4:
5465
        gen_op_bc1any4t(cc);
5466
        opn = "bc1any4t";
5467
    not_likely:
5468
        ctx->hflags |= MIPS_HFLAG_BC;
5469
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5470
        break;
5471
    default:
5472
        MIPS_INVAL(opn);
5473
        generate_exception (ctx, EXCP_RI);
5474
        return;
5475
    }
5476
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5477
               ctx->hflags, btarget);
5478
    ctx->btarget = btarget;
5479
}
5480

    
5481
/* Coprocessor 1 (FPU) */
5482

    
5483
#define FOP(func, fmt) (((fmt) << 21) | (func))
5484

    
5485
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5486
{
5487
    const char *opn = "cp1 move";
5488

    
5489
    switch (opc) {
5490
    case OPC_MFC1:
5491
        GEN_LOAD_FREG_FTN(WT0, fs);
5492
        gen_op_mfc1();
5493
        gen_store_gpr(cpu_T[0], rt);
5494
        opn = "mfc1";
5495
        break;
5496
    case OPC_MTC1:
5497
        gen_load_gpr(cpu_T[0], rt);
5498
        gen_op_mtc1();
5499
        GEN_STORE_FTN_FREG(fs, WT0);
5500
        opn = "mtc1";
5501
        break;
5502
    case OPC_CFC1:
5503
        gen_op_cfc1(fs);
5504
        gen_store_gpr(cpu_T[0], rt);
5505
        opn = "cfc1";
5506
        break;
5507
    case OPC_CTC1:
5508
        gen_load_gpr(cpu_T[0], rt);
5509
        gen_op_ctc1(fs);
5510
        opn = "ctc1";
5511
        break;
5512
    case OPC_DMFC1:
5513
        GEN_LOAD_FREG_FTN(DT0, fs);
5514
        gen_op_dmfc1();
5515
        gen_store_gpr(cpu_T[0], rt);
5516
        opn = "dmfc1";
5517
        break;
5518
    case OPC_DMTC1:
5519
        gen_load_gpr(cpu_T[0], rt);
5520
        gen_op_dmtc1();
5521
        GEN_STORE_FTN_FREG(fs, DT0);
5522
        opn = "dmtc1";
5523
        break;
5524
    case OPC_MFHC1:
5525
        GEN_LOAD_FREG_FTN(WTH0, fs);
5526
        gen_op_mfhc1();
5527
        gen_store_gpr(cpu_T[0], rt);
5528
        opn = "mfhc1";
5529
        break;
5530
    case OPC_MTHC1:
5531
        gen_load_gpr(cpu_T[0], rt);
5532
        gen_op_mthc1();
5533
        GEN_STORE_FTN_FREG(fs, WTH0);
5534
        opn = "mthc1";
5535
        break;
5536
    default:
5537
        MIPS_INVAL(opn);
5538
        generate_exception (ctx, EXCP_RI);
5539
        return;
5540
    }
5541
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5542
}
5543

    
5544
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5545
{
5546
    int l1 = gen_new_label();
5547
    uint32_t ccbit;
5548
    TCGCond cond;
5549

    
5550
    if (cc)
5551
        ccbit = 1 << (24 + cc);
5552
    else
5553
        ccbit = 1 << 23;
5554
    if (tf)
5555
        cond = TCG_COND_EQ;
5556
    else
5557
        cond = TCG_COND_NE;
5558

    
5559
    gen_load_gpr(cpu_T[0], rd);
5560
    gen_load_gpr(cpu_T[1], rs);
5561
    {
5562
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5563
        TCGv r_tmp = new_tmp();
5564

    
5565
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5566
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5567
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5568
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5569
        dead_tmp(r_tmp);
5570
    }
5571
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5572

    
5573
    gen_set_label(l1);
5574
    gen_store_gpr(cpu_T[0], rd);
5575
}
5576

    
5577
#define GEN_MOVCF(fmt)                                                \
5578
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5579
{                                                                     \
5580
    uint32_t ccbit;                                                   \
5581
                                                                      \
5582
    if (cc) {                                                         \
5583
        ccbit = 1 << (24 + cc);                                       \
5584
    } else                                                            \
5585
        ccbit = 1 << 23;                                              \
5586
    if (!tf)                                                          \
5587
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5588
    else                                                              \
5589
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5590
}
5591
GEN_MOVCF(d);
5592
GEN_MOVCF(s);
5593
#undef GEN_MOVCF
5594

    
5595
static void gen_farith (DisasContext *ctx, uint32_t op1,
5596
                        int ft, int fs, int fd, int cc)
5597
{
5598
    const char *opn = "farith";
5599
    const char *condnames[] = {
5600
            "c.f",
5601
            "c.un",
5602
            "c.eq",
5603
            "c.ueq",
5604
            "c.olt",
5605
            "c.ult",
5606
            "c.ole",
5607
            "c.ule",
5608
            "c.sf",
5609
            "c.ngle",
5610
            "c.seq",
5611
            "c.ngl",
5612
            "c.lt",
5613
            "c.nge",
5614
            "c.le",
5615
            "c.ngt",
5616
    };
5617
    const char *condnames_abs[] = {
5618
            "cabs.f",
5619
            "cabs.un",
5620
            "cabs.eq",
5621
            "cabs.ueq",
5622
            "cabs.olt",
5623
            "cabs.ult",
5624
            "cabs.ole",
5625
            "cabs.ule",
5626
            "cabs.sf",
5627
            "cabs.ngle",
5628
            "cabs.seq",
5629
            "cabs.ngl",
5630
            "cabs.lt",
5631
            "cabs.nge",
5632
            "cabs.le",
5633
            "cabs.ngt",
5634
    };
5635
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5636
    uint32_t func = ctx->opcode & 0x3f;
5637

    
5638
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5639
    case FOP(0, 16):
5640
        GEN_LOAD_FREG_FTN(WT0, fs);
5641
        GEN_LOAD_FREG_FTN(WT1, ft);
5642
        gen_op_float_add_s();
5643
        GEN_STORE_FTN_FREG(fd, WT2);
5644
        opn = "add.s";
5645
        optype = BINOP;
5646
        break;
5647
    case FOP(1, 16):
5648
        GEN_LOAD_FREG_FTN(WT0, fs);
5649
        GEN_LOAD_FREG_FTN(WT1, ft);
5650
        gen_op_float_sub_s();
5651
        GEN_STORE_FTN_FREG(fd, WT2);
5652
        opn = "sub.s";
5653
        optype = BINOP;
5654
        break;
5655
    case FOP(2, 16):
5656
        GEN_LOAD_FREG_FTN(WT0, fs);
5657
        GEN_LOAD_FREG_FTN(WT1, ft);
5658
        gen_op_float_mul_s();
5659
        GEN_STORE_FTN_FREG(fd, WT2);
5660
        opn = "mul.s";
5661
        optype = BINOP;
5662
        break;
5663
    case FOP(3, 16):
5664
        GEN_LOAD_FREG_FTN(WT0, fs);
5665
        GEN_LOAD_FREG_FTN(WT1, ft);
5666
        gen_op_float_div_s();
5667
        GEN_STORE_FTN_FREG(fd, WT2);
5668
        opn = "div.s";
5669
        optype = BINOP;
5670
        break;
5671
    case FOP(4, 16):
5672
        GEN_LOAD_FREG_FTN(WT0, fs);
5673
        gen_op_float_sqrt_s();
5674
        GEN_STORE_FTN_FREG(fd, WT2);
5675
        opn = "sqrt.s";
5676
        break;
5677
    case FOP(5, 16):
5678
        GEN_LOAD_FREG_FTN(WT0, fs);
5679
        gen_op_float_abs_s();
5680
        GEN_STORE_FTN_FREG(fd, WT2);
5681
        opn = "abs.s";
5682
        break;
5683
    case FOP(6, 16):
5684
        GEN_LOAD_FREG_FTN(WT0, fs);
5685
        gen_op_float_mov_s();
5686
        GEN_STORE_FTN_FREG(fd, WT2);
5687
        opn = "mov.s";
5688
        break;
5689
    case FOP(7, 16):
5690
        GEN_LOAD_FREG_FTN(WT0, fs);
5691
        gen_op_float_chs_s();
5692
        GEN_STORE_FTN_FREG(fd, WT2);
5693
        opn = "neg.s";
5694
        break;
5695
    case FOP(8, 16):
5696
        check_cp1_64bitmode(ctx);
5697
        GEN_LOAD_FREG_FTN(WT0, fs);
5698
        gen_op_float_roundl_s();
5699
        GEN_STORE_FTN_FREG(fd, DT2);
5700
        opn = "round.l.s";
5701
        break;
5702
    case FOP(9, 16):
5703
        check_cp1_64bitmode(ctx);
5704
        GEN_LOAD_FREG_FTN(WT0, fs);
5705
        gen_op_float_truncl_s();
5706
        GEN_STORE_FTN_FREG(fd, DT2);
5707
        opn = "trunc.l.s";
5708
        break;
5709
    case FOP(10, 16):
5710
        check_cp1_64bitmode(ctx);
5711
        GEN_LOAD_FREG_FTN(WT0, fs);
5712
        gen_op_float_ceill_s();
5713
        GEN_STORE_FTN_FREG(fd, DT2);
5714
        opn = "ceil.l.s";
5715
        break;
5716
    case FOP(11, 16):
5717
        check_cp1_64bitmode(ctx);
5718
        GEN_LOAD_FREG_FTN(WT0, fs);
5719
        gen_op_float_floorl_s();
5720
        GEN_STORE_FTN_FREG(fd, DT2);
5721
        opn = "floor.l.s";
5722
        break;
5723
    case FOP(12, 16):
5724
        GEN_LOAD_FREG_FTN(WT0, fs);
5725
        gen_op_float_roundw_s();
5726
        GEN_STORE_FTN_FREG(fd, WT2);
5727
        opn = "round.w.s";
5728
        break;
5729
    case FOP(13, 16):
5730
        GEN_LOAD_FREG_FTN(WT0, fs);
5731
        gen_op_float_truncw_s();
5732
        GEN_STORE_FTN_FREG(fd, WT2);
5733
        opn = "trunc.w.s";
5734
        break;
5735
    case FOP(14, 16):
5736
        GEN_LOAD_FREG_FTN(WT0, fs);
5737
        gen_op_float_ceilw_s();
5738
        GEN_STORE_FTN_FREG(fd, WT2);
5739
        opn = "ceil.w.s";
5740
        break;
5741
    case FOP(15, 16):
5742
        GEN_LOAD_FREG_FTN(WT0, fs);
5743
        gen_op_float_floorw_s();
5744
        GEN_STORE_FTN_FREG(fd, WT2);
5745
        opn = "floor.w.s";
5746
        break;
5747
    case FOP(17, 16):
5748
        gen_load_gpr(cpu_T[0], ft);
5749
        GEN_LOAD_FREG_FTN(WT0, fs);
5750
        GEN_LOAD_FREG_FTN(WT2, fd);
5751
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5752
        GEN_STORE_FTN_FREG(fd, WT2);
5753
        opn = "movcf.s";
5754
        break;
5755
    case FOP(18, 16):
5756
        gen_load_gpr(cpu_T[0], ft);
5757
        GEN_LOAD_FREG_FTN(WT0, fs);
5758
        GEN_LOAD_FREG_FTN(WT2, fd);
5759
        gen_op_float_movz_s();
5760
        GEN_STORE_FTN_FREG(fd, WT2);
5761
        opn = "movz.s";
5762
        break;
5763
    case FOP(19, 16):
5764
        gen_load_gpr(cpu_T[0], ft);
5765
        GEN_LOAD_FREG_FTN(WT0, fs);
5766
        GEN_LOAD_FREG_FTN(WT2, fd);
5767
        gen_op_float_movn_s();
5768
        GEN_STORE_FTN_FREG(fd, WT2);
5769
        opn = "movn.s";
5770
        break;
5771
    case FOP(21, 16):
5772
        check_cop1x(ctx);
5773
        GEN_LOAD_FREG_FTN(WT0, fs);
5774
        gen_op_float_recip_s();
5775
        GEN_STORE_FTN_FREG(fd, WT2);
5776
        opn = "recip.s";
5777
        break;
5778
    case FOP(22, 16):
5779
        check_cop1x(ctx);
5780
        GEN_LOAD_FREG_FTN(WT0, fs);
5781
        gen_op_float_rsqrt_s();
5782
        GEN_STORE_FTN_FREG(fd, WT2);
5783
        opn = "rsqrt.s";
5784
        break;
5785
    case FOP(28, 16):
5786
        check_cp1_64bitmode(ctx);
5787
        GEN_LOAD_FREG_FTN(WT0, fs);
5788
        GEN_LOAD_FREG_FTN(WT2, fd);
5789
        gen_op_float_recip2_s();
5790
        GEN_STORE_FTN_FREG(fd, WT2);
5791
        opn = "recip2.s";
5792
        break;
5793
    case FOP(29, 16):
5794
        check_cp1_64bitmode(ctx);
5795
        GEN_LOAD_FREG_FTN(WT0, fs);
5796
        gen_op_float_recip1_s();
5797
        GEN_STORE_FTN_FREG(fd, WT2);
5798
        opn = "recip1.s";
5799
        break;
5800
    case FOP(30, 16):
5801
        check_cp1_64bitmode(ctx);
5802
        GEN_LOAD_FREG_FTN(WT0, fs);
5803
        gen_op_float_rsqrt1_s();
5804
        GEN_STORE_FTN_FREG(fd, WT2);
5805
        opn = "rsqrt1.s";
5806
        break;
5807
    case FOP(31, 16):
5808
        check_cp1_64bitmode(ctx);
5809
        GEN_LOAD_FREG_FTN(WT0, fs);
5810
        GEN_LOAD_FREG_FTN(WT2, ft);
5811
        gen_op_float_rsqrt2_s();
5812
        GEN_STORE_FTN_FREG(fd, WT2);
5813
        opn = "rsqrt2.s";
5814
        break;
5815
    case FOP(33, 16):
5816
        check_cp1_registers(ctx, fd);
5817
        GEN_LOAD_FREG_FTN(WT0, fs);
5818
        gen_op_float_cvtd_s();
5819
        GEN_STORE_FTN_FREG(fd, DT2);
5820
        opn = "cvt.d.s";
5821
        break;
5822
    case FOP(36, 16):
5823
        GEN_LOAD_FREG_FTN(WT0, fs);
5824
        gen_op_float_cvtw_s();
5825
        GEN_STORE_FTN_FREG(fd, WT2);
5826
        opn = "cvt.w.s";
5827
        break;
5828
    case FOP(37, 16):
5829
        check_cp1_64bitmode(ctx);
5830
        GEN_LOAD_FREG_FTN(WT0, fs);
5831
        gen_op_float_cvtl_s();
5832
        GEN_STORE_FTN_FREG(fd, DT2);
5833
        opn = "cvt.l.s";
5834
        break;
5835
    case FOP(38, 16):
5836
        check_cp1_64bitmode(ctx);
5837
        GEN_LOAD_FREG_FTN(WT1, fs);
5838
        GEN_LOAD_FREG_FTN(WT0, ft);
5839
        gen_op_float_cvtps_s();
5840
        GEN_STORE_FTN_FREG(fd, DT2);
5841
        opn = "cvt.ps.s";
5842
        break;
5843
    case FOP(48, 16):
5844
    case FOP(49, 16):
5845
    case FOP(50, 16):
5846
    case FOP(51, 16):
5847
    case FOP(52, 16):
5848
    case FOP(53, 16):
5849
    case FOP(54, 16):
5850
    case FOP(55, 16):
5851
    case FOP(56, 16):
5852
    case FOP(57, 16):
5853
    case FOP(58, 16):
5854
    case FOP(59, 16):
5855
    case FOP(60, 16):
5856
    case FOP(61, 16):
5857
    case FOP(62, 16):
5858
    case FOP(63, 16):
5859
        GEN_LOAD_FREG_FTN(WT0, fs);
5860
        GEN_LOAD_FREG_FTN(WT1, ft);
5861
        if (ctx->opcode & (1 << 6)) {
5862
            check_cop1x(ctx);
5863
            gen_cmpabs_s(func-48, cc);
5864
            opn = condnames_abs[func-48];
5865
        } else {
5866
            gen_cmp_s(func-48, cc);
5867
            opn = condnames[func-48];
5868
        }
5869
        break;
5870
    case FOP(0, 17):
5871
        check_cp1_registers(ctx, fs | ft | fd);
5872
        GEN_LOAD_FREG_FTN(DT0, fs);
5873
        GEN_LOAD_FREG_FTN(DT1, ft);
5874
        gen_op_float_add_d();
5875
        GEN_STORE_FTN_FREG(fd, DT2);
5876
        opn = "add.d";
5877
        optype = BINOP;
5878
        break;
5879
    case FOP(1, 17):
5880
        check_cp1_registers(ctx, fs | ft | fd);
5881
        GEN_LOAD_FREG_FTN(DT0, fs);
5882
        GEN_LOAD_FREG_FTN(DT1, ft);
5883
        gen_op_float_sub_d();
5884
        GEN_STORE_FTN_FREG(fd, DT2);
5885
        opn = "sub.d";
5886
        optype = BINOP;
5887
        break;
5888
    case FOP(2, 17):
5889
        check_cp1_registers(ctx, fs | ft | fd);
5890
        GEN_LOAD_FREG_FTN(DT0, fs);
5891
        GEN_LOAD_FREG_FTN(DT1, ft);
5892
        gen_op_float_mul_d();
5893
        GEN_STORE_FTN_FREG(fd, DT2);
5894
        opn = "mul.d";
5895
        optype = BINOP;
5896
        break;
5897
    case FOP(3, 17):
5898
        check_cp1_registers(ctx, fs | ft | fd);
5899
        GEN_LOAD_FREG_FTN(DT0, fs);
5900
        GEN_LOAD_FREG_FTN(DT1, ft);
5901
        gen_op_float_div_d();
5902
        GEN_STORE_FTN_FREG(fd, DT2);
5903
        opn = "div.d";
5904
        optype = BINOP;
5905
        break;
5906
    case FOP(4, 17):
5907
        check_cp1_registers(ctx, fs | fd);
5908
        GEN_LOAD_FREG_FTN(DT0, fs);
5909
        gen_op_float_sqrt_d();
5910
        GEN_STORE_FTN_FREG(fd, DT2);
5911
        opn = "sqrt.d";
5912
        break;
5913
    case FOP(5, 17):
5914
        check_cp1_registers(ctx, fs | fd);
5915
        GEN_LOAD_FREG_FTN(DT0, fs);
5916
        gen_op_float_abs_d();
5917
        GEN_STORE_FTN_FREG(fd, DT2);
5918
        opn = "abs.d";
5919
        break;
5920
    case FOP(6, 17):
5921
        check_cp1_registers(ctx, fs | fd);
5922
        GEN_LOAD_FREG_FTN(DT0, fs);
5923
        gen_op_float_mov_d();
5924
        GEN_STORE_FTN_FREG(fd, DT2);
5925
        opn = "mov.d";
5926
        break;
5927
    case FOP(7, 17):
5928
        check_cp1_registers(ctx, fs | fd);
5929
        GEN_LOAD_FREG_FTN(DT0, fs);
5930
        gen_op_float_chs_d();
5931
        GEN_STORE_FTN_FREG(fd, DT2);
5932
        opn = "neg.d";
5933
        break;
5934
    case FOP(8, 17):
5935
        check_cp1_64bitmode(ctx);
5936
        GEN_LOAD_FREG_FTN(DT0, fs);
5937
        gen_op_float_roundl_d();
5938
        GEN_STORE_FTN_FREG(fd, DT2);
5939
        opn = "round.l.d";
5940
        break;
5941
    case FOP(9, 17):
5942
        check_cp1_64bitmode(ctx);
5943
        GEN_LOAD_FREG_FTN(DT0, fs);
5944
        gen_op_float_truncl_d();
5945
        GEN_STORE_FTN_FREG(fd, DT2);
5946
        opn = "trunc.l.d";
5947
        break;
5948
    case FOP(10, 17):
5949
        check_cp1_64bitmode(ctx);
5950
        GEN_LOAD_FREG_FTN(DT0, fs);
5951
        gen_op_float_ceill_d();
5952
        GEN_STORE_FTN_FREG(fd, DT2);
5953
        opn = "ceil.l.d";
5954
        break;
5955
    case FOP(11, 17):
5956
        check_cp1_64bitmode(ctx);
5957
        GEN_LOAD_FREG_FTN(DT0, fs);
5958
        gen_op_float_floorl_d();
5959
        GEN_STORE_FTN_FREG(fd, DT2);
5960
        opn = "floor.l.d";
5961
        break;
5962
    case FOP(12, 17):
5963
        check_cp1_registers(ctx, fs);
5964
        GEN_LOAD_FREG_FTN(DT0, fs);
5965
        gen_op_float_roundw_d();
5966
        GEN_STORE_FTN_FREG(fd, WT2);
5967
        opn = "round.w.d";
5968
        break;
5969
    case FOP(13, 17):
5970
        check_cp1_registers(ctx, fs);
5971
        GEN_LOAD_FREG_FTN(DT0, fs);
5972
        gen_op_float_truncw_d();
5973
        GEN_STORE_FTN_FREG(fd, WT2);
5974
        opn = "trunc.w.d";
5975
        break;
5976
    case FOP(14, 17):
5977
        check_cp1_registers(ctx, fs);
5978
        GEN_LOAD_FREG_FTN(DT0, fs);
5979
        gen_op_float_ceilw_d();
5980
        GEN_STORE_FTN_FREG(fd, WT2);
5981
        opn = "ceil.w.d";
5982
        break;
5983
    case FOP(15, 17):
5984
        check_cp1_registers(ctx, fs);
5985
        GEN_LOAD_FREG_FTN(DT0, fs);
5986
        gen_op_float_floorw_d();
5987
        GEN_STORE_FTN_FREG(fd, WT2);
5988
        opn = "floor.w.d";
5989
        break;
5990
    case FOP(17, 17):
5991
        gen_load_gpr(cpu_T[0], ft);
5992
        GEN_LOAD_FREG_FTN(DT0, fs);
5993
        GEN_LOAD_FREG_FTN(DT2, fd);
5994
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5995
        GEN_STORE_FTN_FREG(fd, DT2);
5996
        opn = "movcf.d";
5997
        break;
5998
    case FOP(18, 17):
5999
        gen_load_gpr(cpu_T[0], ft);
6000
        GEN_LOAD_FREG_FTN(DT0, fs);
6001
        GEN_LOAD_FREG_FTN(DT2, fd);
6002
        gen_op_float_movz_d();
6003
        GEN_STORE_FTN_FREG(fd, DT2);
6004
        opn = "movz.d";
6005
        break;
6006
    case FOP(19, 17):
6007
        gen_load_gpr(cpu_T[0], ft);
6008
        GEN_LOAD_FREG_FTN(DT0, fs);
6009
        GEN_LOAD_FREG_FTN(DT2, fd);
6010
        gen_op_float_movn_d();
6011
        GEN_STORE_FTN_FREG(fd, DT2);
6012
        opn = "movn.d";
6013
        break;
6014
    case FOP(21, 17):
6015
        check_cp1_64bitmode(ctx);
6016
        GEN_LOAD_FREG_FTN(DT0, fs);
6017
        gen_op_float_recip_d();
6018
        GEN_STORE_FTN_FREG(fd, DT2);
6019
        opn = "recip.d";
6020
        break;
6021
    case FOP(22, 17):
6022
        check_cp1_64bitmode(ctx);
6023
        GEN_LOAD_FREG_FTN(DT0, fs);
6024
        gen_op_float_rsqrt_d();
6025
        GEN_STORE_FTN_FREG(fd, DT2);
6026
        opn = "rsqrt.d";
6027
        break;
6028
    case FOP(28, 17):
6029
        check_cp1_64bitmode(ctx);
6030
        GEN_LOAD_FREG_FTN(DT0, fs);
6031
        GEN_LOAD_FREG_FTN(DT2, ft);
6032
        gen_op_float_recip2_d();
6033
        GEN_STORE_FTN_FREG(fd, DT2);
6034
        opn = "recip2.d";
6035
        break;
6036
    case FOP(29, 17):
6037
        check_cp1_64bitmode(ctx);
6038
        GEN_LOAD_FREG_FTN(DT0, fs);
6039
        gen_op_float_recip1_d();
6040
        GEN_STORE_FTN_FREG(fd, DT2);
6041
        opn = "recip1.d";
6042
        break;
6043
    case FOP(30, 17):
6044
        check_cp1_64bitmode(ctx);
6045
        GEN_LOAD_FREG_FTN(DT0, fs);
6046
        gen_op_float_rsqrt1_d();
6047
        GEN_STORE_FTN_FREG(fd, DT2);
6048
        opn = "rsqrt1.d";
6049
        break;
6050
    case FOP(31, 17):
6051
        check_cp1_64bitmode(ctx);
6052
        GEN_LOAD_FREG_FTN(DT0, fs);
6053
        GEN_LOAD_FREG_FTN(DT2, ft);
6054
        gen_op_float_rsqrt2_d();
6055
        GEN_STORE_FTN_FREG(fd, DT2);
6056
        opn = "rsqrt2.d";
6057
        break;
6058
    case FOP(48, 17):
6059
    case FOP(49, 17):
6060
    case FOP(50, 17):
6061
    case FOP(51, 17):
6062
    case FOP(52, 17):
6063
    case FOP(53, 17):
6064
    case FOP(54, 17):
6065
    case FOP(55, 17):
6066
    case FOP(56, 17):
6067
    case FOP(57, 17):
6068
    case FOP(58, 17):
6069
    case FOP(59, 17):
6070
    case FOP(60, 17):
6071
    case FOP(61, 17):
6072
    case FOP(62, 17):
6073
    case FOP(63, 17):
6074
        GEN_LOAD_FREG_FTN(DT0, fs);
6075
        GEN_LOAD_FREG_FTN(DT1, ft);
6076
        if (ctx->opcode & (1 << 6)) {
6077
            check_cop1x(ctx);
6078
            check_cp1_registers(ctx, fs | ft);
6079
            gen_cmpabs_d(func-48, cc);
6080
            opn = condnames_abs[func-48];
6081
        } else {
6082
            check_cp1_registers(ctx, fs | ft);
6083
            gen_cmp_d(func-48, cc);
6084
            opn = condnames[func-48];
6085
        }
6086
        break;
6087
    case FOP(32, 17):
6088
        check_cp1_registers(ctx, fs);
6089
        GEN_LOAD_FREG_FTN(DT0, fs);
6090
        gen_op_float_cvts_d();
6091
        GEN_STORE_FTN_FREG(fd, WT2);
6092
        opn = "cvt.s.d";
6093
        break;
6094
    case FOP(36, 17):
6095
        check_cp1_registers(ctx, fs);
6096
        GEN_LOAD_FREG_FTN(DT0, fs);
6097
        gen_op_float_cvtw_d();
6098
        GEN_STORE_FTN_FREG(fd, WT2);
6099
        opn = "cvt.w.d";
6100
        break;
6101
    case FOP(37, 17):
6102
        check_cp1_64bitmode(ctx);
6103
        GEN_LOAD_FREG_FTN(DT0, fs);
6104
        gen_op_float_cvtl_d();
6105
        GEN_STORE_FTN_FREG(fd, DT2);
6106
        opn = "cvt.l.d";
6107
        break;
6108
    case FOP(32, 20):
6109
        GEN_LOAD_FREG_FTN(WT0, fs);
6110
        gen_op_float_cvts_w();
6111
        GEN_STORE_FTN_FREG(fd, WT2);
6112
        opn = "cvt.s.w";
6113
        break;
6114
    case FOP(33, 20):
6115
        check_cp1_registers(ctx, fd);
6116
        GEN_LOAD_FREG_FTN(WT0, fs);
6117
        gen_op_float_cvtd_w();
6118
        GEN_STORE_FTN_FREG(fd, DT2);
6119
        opn = "cvt.d.w";
6120
        break;
6121
    case FOP(32, 21):
6122
        check_cp1_64bitmode(ctx);
6123
        GEN_LOAD_FREG_FTN(DT0, fs);
6124
        gen_op_float_cvts_l();
6125
        GEN_STORE_FTN_FREG(fd, WT2);
6126
        opn = "cvt.s.l";
6127
        break;
6128
    case FOP(33, 21):
6129
        check_cp1_64bitmode(ctx);
6130
        GEN_LOAD_FREG_FTN(DT0, fs);
6131
        gen_op_float_cvtd_l();
6132
        GEN_STORE_FTN_FREG(fd, DT2);
6133
        opn = "cvt.d.l";
6134
        break;
6135
    case FOP(38, 20):
6136
        check_cp1_64bitmode(ctx);
6137
        GEN_LOAD_FREG_FTN(WT0, fs);
6138
        GEN_LOAD_FREG_FTN(WTH0, fs);
6139
        gen_op_float_cvtps_pw();
6140
        GEN_STORE_FTN_FREG(fd, WT2);
6141
        GEN_STORE_FTN_FREG(fd, WTH2);
6142
        opn = "cvt.ps.pw";
6143
        break;
6144
    case FOP(0, 22):
6145
        check_cp1_64bitmode(ctx);
6146
        GEN_LOAD_FREG_FTN(WT0, fs);
6147
        GEN_LOAD_FREG_FTN(WTH0, fs);
6148
        GEN_LOAD_FREG_FTN(WT1, ft);
6149
        GEN_LOAD_FREG_FTN(WTH1, ft);
6150
        gen_op_float_add_ps();
6151
        GEN_STORE_FTN_FREG(fd, WT2);
6152
        GEN_STORE_FTN_FREG(fd, WTH2);
6153
        opn = "add.ps";
6154
        break;
6155
    case FOP(1, 22):
6156
        check_cp1_64bitmode(ctx);
6157
        GEN_LOAD_FREG_FTN(WT0, fs);
6158
        GEN_LOAD_FREG_FTN(WTH0, fs);
6159
        GEN_LOAD_FREG_FTN(WT1, ft);
6160
        GEN_LOAD_FREG_FTN(WTH1, ft);
6161
        gen_op_float_sub_ps();
6162
        GEN_STORE_FTN_FREG(fd, WT2);
6163
        GEN_STORE_FTN_FREG(fd, WTH2);
6164
        opn = "sub.ps";
6165
        break;
6166
    case FOP(2, 22):
6167
        check_cp1_64bitmode(ctx);
6168
        GEN_LOAD_FREG_FTN(WT0, fs);
6169
        GEN_LOAD_FREG_FTN(WTH0, fs);
6170
        GEN_LOAD_FREG_FTN(WT1, ft);
6171
        GEN_LOAD_FREG_FTN(WTH1, ft);
6172
        gen_op_float_mul_ps();
6173
        GEN_STORE_FTN_FREG(fd, WT2);
6174
        GEN_STORE_FTN_FREG(fd, WTH2);
6175
        opn = "mul.ps";
6176
        break;
6177
    case FOP(5, 22):
6178
        check_cp1_64bitmode(ctx);
6179
        GEN_LOAD_FREG_FTN(WT0, fs);
6180
        GEN_LOAD_FREG_FTN(WTH0, fs);
6181
        gen_op_float_abs_ps();
6182
        GEN_STORE_FTN_FREG(fd, WT2);
6183
        GEN_STORE_FTN_FREG(fd, WTH2);
6184
        opn = "abs.ps";
6185
        break;
6186
    case FOP(6, 22):
6187
        check_cp1_64bitmode(ctx);
6188
        GEN_LOAD_FREG_FTN(WT0, fs);
6189
        GEN_LOAD_FREG_FTN(WTH0, fs);
6190
        gen_op_float_mov_ps();
6191
        GEN_STORE_FTN_FREG(fd, WT2);
6192
        GEN_STORE_FTN_FREG(fd, WTH2);
6193
        opn = "mov.ps";
6194
        break;
6195
    case FOP(7, 22):
6196
        check_cp1_64bitmode(ctx);
6197
        GEN_LOAD_FREG_FTN(WT0, fs);
6198
        GEN_LOAD_FREG_FTN(WTH0, fs);
6199
        gen_op_float_chs_ps();
6200
        GEN_STORE_FTN_FREG(fd, WT2);
6201
        GEN_STORE_FTN_FREG(fd, WTH2);
6202
        opn = "neg.ps";
6203
        break;
6204
    case FOP(17, 22):
6205
        check_cp1_64bitmode(ctx);
6206
        gen_load_gpr(cpu_T[0], ft);
6207
        GEN_LOAD_FREG_FTN(WT0, fs);
6208
        GEN_LOAD_FREG_FTN(WTH0, fs);
6209
        GEN_LOAD_FREG_FTN(WT2, fd);
6210
        GEN_LOAD_FREG_FTN(WTH2, fd);
6211
        if (ft & 0x1)
6212
            gen_op_float_movt_ps ((ft >> 2) & 0x7);
6213
        else
6214
            gen_op_float_movf_ps ((ft >> 2) & 0x7);
6215
        GEN_STORE_FTN_FREG(fd, WT2);
6216
        GEN_STORE_FTN_FREG(fd, WTH2);
6217
        opn = "movcf.ps";
6218
        break;
6219
    case FOP(18, 22):
6220
        check_cp1_64bitmode(ctx);
6221
        gen_load_gpr(cpu_T[0], ft);
6222
        GEN_LOAD_FREG_FTN(WT0, fs);
6223
        GEN_LOAD_FREG_FTN(WTH0, fs);
6224
        GEN_LOAD_FREG_FTN(WT2, fd);
6225
        GEN_LOAD_FREG_FTN(WTH2, fd);
6226
        gen_op_float_movz_ps();
6227
        GEN_STORE_FTN_FREG(fd, WT2);
6228
        GEN_STORE_FTN_FREG(fd, WTH2);
6229
        opn = "movz.ps";
6230
        break;
6231
    case FOP(19, 22):
6232
        check_cp1_64bitmode(ctx);
6233
        gen_load_gpr(cpu_T[0], ft);
6234
        GEN_LOAD_FREG_FTN(WT0, fs);
6235
        GEN_LOAD_FREG_FTN(WTH0, fs);
6236
        GEN_LOAD_FREG_FTN(WT2, fd);
6237
        GEN_LOAD_FREG_FTN(WTH2, fd);
6238
        gen_op_float_movn_ps();
6239
        GEN_STORE_FTN_FREG(fd, WT2);
6240
        GEN_STORE_FTN_FREG(fd, WTH2);
6241
        opn = "movn.ps";
6242
        break;
6243
    case FOP(24, 22):
6244
        check_cp1_64bitmode(ctx);
6245
        GEN_LOAD_FREG_FTN(WT0, ft);
6246
        GEN_LOAD_FREG_FTN(WTH0, ft);
6247
        GEN_LOAD_FREG_FTN(WT1, fs);
6248
        GEN_LOAD_FREG_FTN(WTH1, fs);
6249
        gen_op_float_addr_ps();
6250
        GEN_STORE_FTN_FREG(fd, WT2);
6251
        GEN_STORE_FTN_FREG(fd, WTH2);
6252
        opn = "addr.ps";
6253
        break;
6254
    case FOP(26, 22):
6255
        check_cp1_64bitmode(ctx);
6256
        GEN_LOAD_FREG_FTN(WT0, ft);
6257
        GEN_LOAD_FREG_FTN(WTH0, ft);
6258
        GEN_LOAD_FREG_FTN(WT1, fs);
6259
        GEN_LOAD_FREG_FTN(WTH1, fs);
6260
        gen_op_float_mulr_ps();
6261
        GEN_STORE_FTN_FREG(fd, WT2);
6262
        GEN_STORE_FTN_FREG(fd, WTH2);
6263
        opn = "mulr.ps";
6264
        break;
6265
    case FOP(28, 22):
6266
        check_cp1_64bitmode(ctx);
6267
        GEN_LOAD_FREG_FTN(WT0, fs);
6268
        GEN_LOAD_FREG_FTN(WTH0, fs);
6269
        GEN_LOAD_FREG_FTN(WT2, fd);
6270
        GEN_LOAD_FREG_FTN(WTH2, fd);
6271
        gen_op_float_recip2_ps();
6272
        GEN_STORE_FTN_FREG(fd, WT2);
6273
        GEN_STORE_FTN_FREG(fd, WTH2);
6274
        opn = "recip2.ps";
6275
        break;
6276
    case FOP(29, 22):
6277
        check_cp1_64bitmode(ctx);
6278
        GEN_LOAD_FREG_FTN(WT0, fs);
6279
        GEN_LOAD_FREG_FTN(WTH0, fs);
6280
        gen_op_float_recip1_ps();
6281
        GEN_STORE_FTN_FREG(fd, WT2);
6282
        GEN_STORE_FTN_FREG(fd, WTH2);
6283
        opn = "recip1.ps";
6284
        break;
6285
    case FOP(30, 22):
6286
        check_cp1_64bitmode(ctx);
6287
        GEN_LOAD_FREG_FTN(WT0, fs);
6288
        GEN_LOAD_FREG_FTN(WTH0, fs);
6289
        gen_op_float_rsqrt1_ps();
6290
        GEN_STORE_FTN_FREG(fd, WT2);
6291
        GEN_STORE_FTN_FREG(fd, WTH2);
6292
        opn = "rsqrt1.ps";
6293
        break;
6294
    case FOP(31, 22):
6295
        check_cp1_64bitmode(ctx);
6296
        GEN_LOAD_FREG_FTN(WT0, fs);
6297
        GEN_LOAD_FREG_FTN(WTH0, fs);
6298
        GEN_LOAD_FREG_FTN(WT2, ft);
6299
        GEN_LOAD_FREG_FTN(WTH2, ft);
6300
        gen_op_float_rsqrt2_ps();
6301
        GEN_STORE_FTN_FREG(fd, WT2);
6302
        GEN_STORE_FTN_FREG(fd, WTH2);
6303
        opn = "rsqrt2.ps";
6304
        break;
6305
    case FOP(32, 22):
6306
        check_cp1_64bitmode(ctx);
6307
        GEN_LOAD_FREG_FTN(WTH0, fs);
6308
        gen_op_float_cvts_pu();
6309
        GEN_STORE_FTN_FREG(fd, WT2);
6310
        opn = "cvt.s.pu";
6311
        break;
6312
    case FOP(36, 22):
6313
        check_cp1_64bitmode(ctx);
6314
        GEN_LOAD_FREG_FTN(WT0, fs);
6315
        GEN_LOAD_FREG_FTN(WTH0, fs);
6316
        gen_op_float_cvtpw_ps();
6317
        GEN_STORE_FTN_FREG(fd, WT2);
6318
        GEN_STORE_FTN_FREG(fd, WTH2);
6319
        opn = "cvt.pw.ps";
6320
        break;
6321
    case FOP(40, 22):
6322
        check_cp1_64bitmode(ctx);
6323
        GEN_LOAD_FREG_FTN(WT0, fs);
6324
        gen_op_float_cvts_pl();
6325
        GEN_STORE_FTN_FREG(fd, WT2);
6326
        opn = "cvt.s.pl";
6327
        break;
6328
    case FOP(44, 22):
6329
        check_cp1_64bitmode(ctx);
6330
        GEN_LOAD_FREG_FTN(WT0, fs);
6331
        GEN_LOAD_FREG_FTN(WT1, ft);
6332
        gen_op_float_pll_ps();
6333
        GEN_STORE_FTN_FREG(fd, DT2);
6334
        opn = "pll.ps";
6335
        break;
6336
    case FOP(45, 22):
6337
        check_cp1_64bitmode(ctx);
6338
        GEN_LOAD_FREG_FTN(WT0, fs);
6339
        GEN_LOAD_FREG_FTN(WTH1, ft);
6340
        gen_op_float_plu_ps();
6341
        GEN_STORE_FTN_FREG(fd, DT2);
6342
        opn = "plu.ps";
6343
        break;
6344
    case FOP(46, 22):
6345
        check_cp1_64bitmode(ctx);
6346
        GEN_LOAD_FREG_FTN(WTH0, fs);
6347
        GEN_LOAD_FREG_FTN(WT1, ft);
6348
        gen_op_float_pul_ps();
6349
        GEN_STORE_FTN_FREG(fd, DT2);
6350
        opn = "pul.ps";
6351
        break;
6352
    case FOP(47, 22):
6353
        check_cp1_64bitmode(ctx);
6354
        GEN_LOAD_FREG_FTN(WTH0, fs);
6355
        GEN_LOAD_FREG_FTN(WTH1, ft);
6356
        gen_op_float_puu_ps();
6357
        GEN_STORE_FTN_FREG(fd, DT2);
6358
        opn = "puu.ps";
6359
        break;
6360
    case FOP(48, 22):
6361
    case FOP(49, 22):
6362
    case FOP(50, 22):
6363
    case FOP(51, 22):
6364
    case FOP(52, 22):
6365
    case FOP(53, 22):
6366
    case FOP(54, 22):
6367
    case FOP(55, 22):
6368
    case FOP(56, 22):
6369
    case FOP(57, 22):
6370
    case FOP(58, 22):
6371
    case FOP(59, 22):
6372
    case FOP(60, 22):
6373
    case FOP(61, 22):
6374
    case FOP(62, 22):
6375
    case FOP(63, 22):
6376
        check_cp1_64bitmode(ctx);
6377
        GEN_LOAD_FREG_FTN(WT0, fs);
6378
        GEN_LOAD_FREG_FTN(WTH0, fs);
6379
        GEN_LOAD_FREG_FTN(WT1, ft);
6380
        GEN_LOAD_FREG_FTN(WTH1, ft);
6381
        if (ctx->opcode & (1 << 6)) {
6382
            gen_cmpabs_ps(func-48, cc);
6383
            opn = condnames_abs[func-48];
6384
        } else {
6385
            gen_cmp_ps(func-48, cc);
6386
            opn = condnames[func-48];
6387
        }
6388
        break;
6389
    default:
6390
        MIPS_INVAL(opn);
6391
        generate_exception (ctx, EXCP_RI);
6392
        return;
6393
    }
6394
    switch (optype) {
6395
    case BINOP:
6396
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6397
        break;
6398
    case CMPOP:
6399
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6400
        break;
6401
    default:
6402
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6403
        break;
6404
    }
6405
}
6406

    
6407
/* Coprocessor 3 (FPU) */
6408
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6409
                           int fd, int fs, int base, int index)
6410
{
6411
    const char *opn = "extended float load/store";
6412
    int store = 0;
6413

    
6414
    if (base == 0) {
6415
        gen_load_gpr(cpu_T[0], index);
6416
    } else if (index == 0) {
6417
        gen_load_gpr(cpu_T[0], base);
6418
    } else {
6419
        gen_load_gpr(cpu_T[0], base);
6420
        gen_load_gpr(cpu_T[1], index);
6421
        gen_op_addr_add();
6422
    }
6423
    /* Don't do NOP if destination is zero: we must perform the actual
6424
       memory access. */
6425
    switch (opc) {
6426
    case OPC_LWXC1:
6427
        check_cop1x(ctx);
6428
        op_ldst_lwc1(ctx);
6429
        GEN_STORE_FTN_FREG(fd, WT0);
6430
        opn = "lwxc1";
6431
        break;
6432
    case OPC_LDXC1:
6433
        check_cop1x(ctx);
6434
        check_cp1_registers(ctx, fd);
6435
        op_ldst_ldc1(ctx);
6436
        GEN_STORE_FTN_FREG(fd, DT0);
6437
        opn = "ldxc1";
6438
        break;
6439
    case OPC_LUXC1:
6440
        check_cp1_64bitmode(ctx);
6441
        op_ldst(luxc1);
6442
        GEN_STORE_FTN_FREG(fd, DT0);
6443
        opn = "luxc1";
6444
        break;
6445
    case OPC_SWXC1:
6446
        check_cop1x(ctx);
6447
        GEN_LOAD_FREG_FTN(WT0, fs);
6448
        op_ldst_swc1(ctx);
6449
        opn = "swxc1";
6450
        store = 1;
6451
        break;
6452
    case OPC_SDXC1:
6453
        check_cop1x(ctx);
6454
        check_cp1_registers(ctx, fs);
6455
        GEN_LOAD_FREG_FTN(DT0, fs);
6456
        op_ldst_sdc1(ctx);
6457
        opn = "sdxc1";
6458
        store = 1;
6459
        break;
6460
    case OPC_SUXC1:
6461
        check_cp1_64bitmode(ctx);
6462
        GEN_LOAD_FREG_FTN(DT0, fs);
6463
        op_ldst(suxc1);
6464
        opn = "suxc1";
6465
        store = 1;
6466
        break;
6467
    default:
6468
        MIPS_INVAL(opn);
6469
        generate_exception(ctx, EXCP_RI);
6470
        return;
6471
    }
6472
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6473
               regnames[index], regnames[base]);
6474
}
6475

    
6476
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6477
                            int fd, int fr, int fs, int ft)
6478
{
6479
    const char *opn = "flt3_arith";
6480

    
6481
    switch (opc) {
6482
    case OPC_ALNV_PS:
6483
        check_cp1_64bitmode(ctx);
6484
        gen_load_gpr(cpu_T[0], fr);
6485
        GEN_LOAD_FREG_FTN(DT0, fs);
6486
        GEN_LOAD_FREG_FTN(DT1, ft);
6487
        gen_op_float_alnv_ps();
6488
        GEN_STORE_FTN_FREG(fd, DT2);
6489
        opn = "alnv.ps";
6490
        break;
6491
    case OPC_MADD_S:
6492
        check_cop1x(ctx);
6493
        GEN_LOAD_FREG_FTN(WT0, fs);
6494
        GEN_LOAD_FREG_FTN(WT1, ft);
6495
        GEN_LOAD_FREG_FTN(WT2, fr);
6496
        gen_op_float_muladd_s();
6497
        GEN_STORE_FTN_FREG(fd, WT2);
6498
        opn = "madd.s";
6499
        break;
6500
    case OPC_MADD_D:
6501
        check_cop1x(ctx);
6502
        check_cp1_registers(ctx, fd | fs | ft | fr);
6503
        GEN_LOAD_FREG_FTN(DT0, fs);
6504
        GEN_LOAD_FREG_FTN(DT1, ft);
6505
        GEN_LOAD_FREG_FTN(DT2, fr);
6506
        gen_op_float_muladd_d();
6507
        GEN_STORE_FTN_FREG(fd, DT2);
6508
        opn = "madd.d";
6509
        break;
6510
    case OPC_MADD_PS:
6511
        check_cp1_64bitmode(ctx);
6512
        GEN_LOAD_FREG_FTN(WT0, fs);
6513
        GEN_LOAD_FREG_FTN(WTH0, fs);
6514
        GEN_LOAD_FREG_FTN(WT1, ft);
6515
        GEN_LOAD_FREG_FTN(WTH1, ft);
6516
        GEN_LOAD_FREG_FTN(WT2, fr);
6517
        GEN_LOAD_FREG_FTN(WTH2, fr);
6518
        gen_op_float_muladd_ps();
6519
        GEN_STORE_FTN_FREG(fd, WT2);
6520
        GEN_STORE_FTN_FREG(fd, WTH2);
6521
        opn = "madd.ps";
6522
        break;
6523
    case OPC_MSUB_S:
6524
        check_cop1x(ctx);
6525
        GEN_LOAD_FREG_FTN(WT0, fs);
6526
        GEN_LOAD_FREG_FTN(WT1, ft);
6527
        GEN_LOAD_FREG_FTN(WT2, fr);
6528
        gen_op_float_mulsub_s();
6529
        GEN_STORE_FTN_FREG(fd, WT2);
6530
        opn = "msub.s";
6531
        break;
6532
    case OPC_MSUB_D:
6533
        check_cop1x(ctx);
6534
        check_cp1_registers(ctx, fd | fs | ft | fr);
6535
        GEN_LOAD_FREG_FTN(DT0, fs);
6536
        GEN_LOAD_FREG_FTN(DT1, ft);
6537
        GEN_LOAD_FREG_FTN(DT2, fr);
6538
        gen_op_float_mulsub_d();
6539
        GEN_STORE_FTN_FREG(fd, DT2);
6540
        opn = "msub.d";
6541
        break;
6542
    case OPC_MSUB_PS:
6543
        check_cp1_64bitmode(ctx);
6544
        GEN_LOAD_FREG_FTN(WT0, fs);
6545
        GEN_LOAD_FREG_FTN(WTH0, fs);
6546
        GEN_LOAD_FREG_FTN(WT1, ft);
6547
        GEN_LOAD_FREG_FTN(WTH1, ft);
6548
        GEN_LOAD_FREG_FTN(WT2, fr);
6549
        GEN_LOAD_FREG_FTN(WTH2, fr);
6550
        gen_op_float_mulsub_ps();
6551
        GEN_STORE_FTN_FREG(fd, WT2);
6552
        GEN_STORE_FTN_FREG(fd, WTH2);
6553
        opn = "msub.ps";
6554
        break;
6555
    case OPC_NMADD_S:
6556
        check_cop1x(ctx);
6557
        GEN_LOAD_FREG_FTN(WT0, fs);
6558
        GEN_LOAD_FREG_FTN(WT1, ft);
6559
        GEN_LOAD_FREG_FTN(WT2, fr);
6560
        gen_op_float_nmuladd_s();
6561
        GEN_STORE_FTN_FREG(fd, WT2);
6562
        opn = "nmadd.s";
6563
        break;
6564
    case OPC_NMADD_D:
6565
        check_cop1x(ctx);
6566
        check_cp1_registers(ctx, fd | fs | ft | fr);
6567
        GEN_LOAD_FREG_FTN(DT0, fs);
6568
        GEN_LOAD_FREG_FTN(DT1, ft);
6569
        GEN_LOAD_FREG_FTN(DT2, fr);
6570
        gen_op_float_nmuladd_d();
6571
        GEN_STORE_FTN_FREG(fd, DT2);
6572
        opn = "nmadd.d";
6573
        break;
6574
    case OPC_NMADD_PS:
6575
        check_cp1_64bitmode(ctx);
6576
        GEN_LOAD_FREG_FTN(WT0, fs);
6577
        GEN_LOAD_FREG_FTN(WTH0, fs);
6578
        GEN_LOAD_FREG_FTN(WT1, ft);
6579
        GEN_LOAD_FREG_FTN(WTH1, ft);
6580
        GEN_LOAD_FREG_FTN(WT2, fr);
6581
        GEN_LOAD_FREG_FTN(WTH2, fr);
6582
        gen_op_float_nmuladd_ps();
6583
        GEN_STORE_FTN_FREG(fd, WT2);
6584
        GEN_STORE_FTN_FREG(fd, WTH2);
6585
        opn = "nmadd.ps";
6586
        break;
6587
    case OPC_NMSUB_S:
6588
        check_cop1x(ctx);
6589
        GEN_LOAD_FREG_FTN(WT0, fs);
6590
        GEN_LOAD_FREG_FTN(WT1, ft);
6591
        GEN_LOAD_FREG_FTN(WT2, fr);
6592
        gen_op_float_nmulsub_s();
6593
        GEN_STORE_FTN_FREG(fd, WT2);
6594
        opn = "nmsub.s";
6595
        break;
6596
    case OPC_NMSUB_D:
6597
        check_cop1x(ctx);
6598
        check_cp1_registers(ctx, fd | fs | ft | fr);
6599
        GEN_LOAD_FREG_FTN(DT0, fs);
6600
        GEN_LOAD_FREG_FTN(DT1, ft);
6601
        GEN_LOAD_FREG_FTN(DT2, fr);
6602
        gen_op_float_nmulsub_d();
6603
        GEN_STORE_FTN_FREG(fd, DT2);
6604
        opn = "nmsub.d";
6605
        break;
6606
    case OPC_NMSUB_PS:
6607
        check_cp1_64bitmode(ctx);
6608
        GEN_LOAD_FREG_FTN(WT0, fs);
6609
        GEN_LOAD_FREG_FTN(WTH0, fs);
6610
        GEN_LOAD_FREG_FTN(WT1, ft);
6611
        GEN_LOAD_FREG_FTN(WTH1, ft);
6612
        GEN_LOAD_FREG_FTN(WT2, fr);
6613
        GEN_LOAD_FREG_FTN(WTH2, fr);
6614
        gen_op_float_nmulsub_ps();
6615
        GEN_STORE_FTN_FREG(fd, WT2);
6616
        GEN_STORE_FTN_FREG(fd, WTH2);
6617
        opn = "nmsub.ps";
6618
        break;
6619
    default:
6620
        MIPS_INVAL(opn);
6621
        generate_exception (ctx, EXCP_RI);
6622
        return;
6623
    }
6624
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6625
               fregnames[fs], fregnames[ft]);
6626
}
6627

    
6628
/* ISA extensions (ASEs) */
6629
/* MIPS16 extension to MIPS32 */
6630
/* SmartMIPS extension to MIPS32 */
6631

    
6632
#if defined(TARGET_MIPS64)
6633

    
6634
/* MDMX extension to MIPS64 */
6635

    
6636
#endif
6637

    
6638
static void decode_opc (CPUState *env, DisasContext *ctx)
6639
{
6640
    int32_t offset;
6641
    int rs, rt, rd, sa;
6642
    uint32_t op, op1, op2;
6643
    int16_t imm;
6644

    
6645
    /* make sure instructions are on a word boundary */
6646
    if (ctx->pc & 0x3) {
6647
        env->CP0_BadVAddr = ctx->pc;
6648
        generate_exception(ctx, EXCP_AdEL);
6649
        return;
6650
    }
6651

    
6652
    /* Handle blikely not taken case */
6653
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6654
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6655
        int l1 = gen_new_label();
6656

    
6657
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6658
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6659
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6660
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6661
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6662
        gen_set_label(l1);
6663
    }
6664
    op = MASK_OP_MAJOR(ctx->opcode);
6665
    rs = (ctx->opcode >> 21) & 0x1f;
6666
    rt = (ctx->opcode >> 16) & 0x1f;
6667
    rd = (ctx->opcode >> 11) & 0x1f;
6668
    sa = (ctx->opcode >> 6) & 0x1f;
6669
    imm = (int16_t)ctx->opcode;
6670
    switch (op) {
6671
    case OPC_SPECIAL:
6672
        op1 = MASK_SPECIAL(ctx->opcode);
6673
        switch (op1) {
6674
        case OPC_SLL:          /* Arithmetic with immediate */
6675
        case OPC_SRL ... OPC_SRA:
6676
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6677
            break;
6678
        case OPC_MOVZ ... OPC_MOVN:
6679
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6680
        case OPC_SLLV:         /* Arithmetic */
6681
        case OPC_SRLV ... OPC_SRAV:
6682
        case OPC_ADD ... OPC_NOR:
6683
        case OPC_SLT ... OPC_SLTU:
6684
            gen_arith(env, ctx, op1, rd, rs, rt);
6685
            break;
6686
        case OPC_MULT ... OPC_DIVU:
6687
            if (sa) {
6688
                check_insn(env, ctx, INSN_VR54XX);
6689
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6690
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6691
            } else
6692
                gen_muldiv(ctx, op1, rs, rt);
6693
            break;
6694
        case OPC_JR ... OPC_JALR:
6695
            gen_compute_branch(ctx, op1, rs, rd, sa);
6696
            return;
6697
        case OPC_TGE ... OPC_TEQ: /* Traps */
6698
        case OPC_TNE:
6699
            gen_trap(ctx, op1, rs, rt, -1);
6700
            break;
6701
        case OPC_MFHI:          /* Move from HI/LO */
6702
        case OPC_MFLO:
6703
            gen_HILO(ctx, op1, rd);
6704
            break;
6705
        case OPC_MTHI:
6706
        case OPC_MTLO:          /* Move to HI/LO */
6707
            gen_HILO(ctx, op1, rs);
6708
            break;
6709
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6710
#ifdef MIPS_STRICT_STANDARD
6711
            MIPS_INVAL("PMON / selsl");
6712
            generate_exception(ctx, EXCP_RI);
6713
#else
6714
            gen_op_pmon(sa);
6715
#endif
6716
            break;
6717
        case OPC_SYSCALL:
6718
            generate_exception(ctx, EXCP_SYSCALL);
6719
            break;
6720
        case OPC_BREAK:
6721
            generate_exception(ctx, EXCP_BREAK);
6722
            break;
6723
        case OPC_SPIM:
6724
#ifdef MIPS_STRICT_STANDARD
6725
            MIPS_INVAL("SPIM");
6726
            generate_exception(ctx, EXCP_RI);
6727
#else
6728
           /* Implemented as RI exception for now. */
6729
            MIPS_INVAL("spim (unofficial)");
6730
            generate_exception(ctx, EXCP_RI);
6731
#endif
6732
            break;
6733
        case OPC_SYNC:
6734
            /* Treat as NOP. */
6735
            break;
6736

    
6737
        case OPC_MOVCI:
6738
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6739
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6740
                save_cpu_state(ctx, 1);
6741
                check_cp1_enabled(ctx);
6742
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6743
                          (ctx->opcode >> 16) & 1);
6744
            } else {
6745
                generate_exception_err(ctx, EXCP_CpU, 1);
6746
            }
6747
            break;
6748

    
6749
#if defined(TARGET_MIPS64)
6750
       /* MIPS64 specific opcodes */
6751
        case OPC_DSLL:
6752
        case OPC_DSRL ... OPC_DSRA:
6753
        case OPC_DSLL32:
6754
        case OPC_DSRL32 ... OPC_DSRA32:
6755
            check_insn(env, ctx, ISA_MIPS3);
6756
            check_mips_64(ctx);
6757
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6758
            break;
6759
        case OPC_DSLLV:
6760
        case OPC_DSRLV ... OPC_DSRAV:
6761
        case OPC_DADD ... OPC_DSUBU:
6762
            check_insn(env, ctx, ISA_MIPS3);
6763
            check_mips_64(ctx);
6764
            gen_arith(env, ctx, op1, rd, rs, rt);
6765
            break;
6766
        case OPC_DMULT ... OPC_DDIVU:
6767
            check_insn(env, ctx, ISA_MIPS3);
6768
            check_mips_64(ctx);
6769
            gen_muldiv(ctx, op1, rs, rt);
6770
            break;
6771
#endif
6772
        default:            /* Invalid */
6773
            MIPS_INVAL("special");
6774
            generate_exception(ctx, EXCP_RI);
6775
            break;
6776
        }
6777
        break;
6778
    case OPC_SPECIAL2:
6779
        op1 = MASK_SPECIAL2(ctx->opcode);
6780
        switch (op1) {
6781
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6782
        case OPC_MSUB ... OPC_MSUBU:
6783
            check_insn(env, ctx, ISA_MIPS32);
6784
            gen_muldiv(ctx, op1, rs, rt);
6785
            break;
6786
        case OPC_MUL:
6787
            gen_arith(env, ctx, op1, rd, rs, rt);
6788
            break;
6789
        case OPC_CLZ ... OPC_CLO:
6790
            check_insn(env, ctx, ISA_MIPS32);
6791
            gen_cl(ctx, op1, rd, rs);
6792
            break;
6793
        case OPC_SDBBP:
6794
            /* XXX: not clear which exception should be raised
6795
             *      when in debug mode...
6796
             */
6797
            check_insn(env, ctx, ISA_MIPS32);
6798
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6799
                generate_exception(ctx, EXCP_DBp);
6800
            } else {
6801
                generate_exception(ctx, EXCP_DBp);
6802
            }
6803
            /* Treat as NOP. */
6804
            break;
6805
#if defined(TARGET_MIPS64)
6806
        case OPC_DCLZ ... OPC_DCLO:
6807
            check_insn(env, ctx, ISA_MIPS64);
6808
            check_mips_64(ctx);
6809
            gen_cl(ctx, op1, rd, rs);
6810
            break;
6811
#endif
6812
        default:            /* Invalid */
6813
            MIPS_INVAL("special2");
6814
            generate_exception(ctx, EXCP_RI);
6815
            break;
6816
        }
6817
        break;
6818
    case OPC_SPECIAL3:
6819
         op1 = MASK_SPECIAL3(ctx->opcode);
6820
         switch (op1) {
6821
         case OPC_EXT:
6822
         case OPC_INS:
6823
             check_insn(env, ctx, ISA_MIPS32R2);
6824
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6825
             break;
6826
         case OPC_BSHFL:
6827
             check_insn(env, ctx, ISA_MIPS32R2);
6828
             op2 = MASK_BSHFL(ctx->opcode);
6829
             switch (op2) {
6830
             case OPC_WSBH:
6831
                 gen_load_gpr(cpu_T[1], rt);
6832
                 gen_op_wsbh();
6833
                 break;
6834
             case OPC_SEB:
6835
                 gen_load_gpr(cpu_T[1], rt);
6836
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6837
                 break;
6838
             case OPC_SEH:
6839
                 gen_load_gpr(cpu_T[1], rt);
6840
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6841
                 break;
6842
             default:            /* Invalid */
6843
                 MIPS_INVAL("bshfl");
6844
                 generate_exception(ctx, EXCP_RI);
6845
                 break;
6846
            }
6847
            gen_store_gpr(cpu_T[0], rd);
6848
            break;
6849
        case OPC_RDHWR:
6850
            check_insn(env, ctx, ISA_MIPS32R2);
6851
            switch (rd) {
6852
            case 0:
6853
                save_cpu_state(ctx, 1);
6854
                gen_op_rdhwr_cpunum();
6855
                break;
6856
            case 1:
6857
                save_cpu_state(ctx, 1);
6858
                gen_op_rdhwr_synci_step();
6859
                break;
6860
            case 2:
6861
                save_cpu_state(ctx, 1);
6862
                gen_op_rdhwr_cc();
6863
                break;
6864
            case 3:
6865
                save_cpu_state(ctx, 1);
6866
                gen_op_rdhwr_ccres();
6867
                break;
6868
            case 29:
6869
#if defined (CONFIG_USER_ONLY)
6870
                gen_op_tls_value();
6871
                break;
6872
#endif
6873
            default:            /* Invalid */
6874
                MIPS_INVAL("rdhwr");
6875
                generate_exception(ctx, EXCP_RI);
6876
                break;
6877
            }
6878
            gen_store_gpr(cpu_T[0], rt);
6879
            break;
6880
        case OPC_FORK:
6881
            check_insn(env, ctx, ASE_MT);
6882
            gen_load_gpr(cpu_T[0], rt);
6883
            gen_load_gpr(cpu_T[1], rs);
6884
            gen_op_fork();
6885
            break;
6886
        case OPC_YIELD:
6887
            check_insn(env, ctx, ASE_MT);
6888
            gen_load_gpr(cpu_T[0], rs);
6889
            gen_op_yield();
6890
            gen_store_gpr(cpu_T[0], rd);
6891
            break;
6892
#if defined(TARGET_MIPS64)
6893
        case OPC_DEXTM ... OPC_DEXT:
6894
        case OPC_DINSM ... OPC_DINS:
6895
            check_insn(env, ctx, ISA_MIPS64R2);
6896
            check_mips_64(ctx);
6897
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6898
            break;
6899
        case OPC_DBSHFL:
6900
            check_insn(env, ctx, ISA_MIPS64R2);
6901
            check_mips_64(ctx);
6902
            op2 = MASK_DBSHFL(ctx->opcode);
6903
            switch (op2) {
6904
            case OPC_DSBH:
6905
                gen_load_gpr(cpu_T[1], rt);
6906
                gen_op_dsbh();
6907
                break;
6908
            case OPC_DSHD:
6909
                gen_load_gpr(cpu_T[1], rt);
6910
                gen_op_dshd();
6911
                break;
6912
            default:            /* Invalid */
6913
                MIPS_INVAL("dbshfl");
6914
                generate_exception(ctx, EXCP_RI);
6915
                break;
6916
            }
6917
            gen_store_gpr(cpu_T[0], rd);
6918
            break;
6919
#endif
6920
        default:            /* Invalid */
6921
            MIPS_INVAL("special3");
6922
            generate_exception(ctx, EXCP_RI);
6923
            break;
6924
        }
6925
        break;
6926
    case OPC_REGIMM:
6927
        op1 = MASK_REGIMM(ctx->opcode);
6928
        switch (op1) {
6929
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6930
        case OPC_BLTZAL ... OPC_BGEZALL:
6931
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6932
            return;
6933
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6934
        case OPC_TNEI:
6935
            gen_trap(ctx, op1, rs, -1, imm);
6936
            break;
6937
        case OPC_SYNCI:
6938
            check_insn(env, ctx, ISA_MIPS32R2);
6939
            /* Treat as NOP. */
6940
            break;
6941
        default:            /* Invalid */
6942
            MIPS_INVAL("regimm");
6943
            generate_exception(ctx, EXCP_RI);
6944
            break;
6945
        }
6946
        break;
6947
    case OPC_CP0:
6948
        check_cp0_enabled(ctx);
6949
        op1 = MASK_CP0(ctx->opcode);
6950
        switch (op1) {
6951
        case OPC_MFC0:
6952
        case OPC_MTC0:
6953
        case OPC_MFTR:
6954
        case OPC_MTTR:
6955
#if defined(TARGET_MIPS64)
6956
        case OPC_DMFC0:
6957
        case OPC_DMTC0:
6958
#endif
6959
            gen_cp0(env, ctx, op1, rt, rd);
6960
            break;
6961
        case OPC_C0_FIRST ... OPC_C0_LAST:
6962
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6963
            break;
6964
        case OPC_MFMC0:
6965
            op2 = MASK_MFMC0(ctx->opcode);
6966
            switch (op2) {
6967
            case OPC_DMT:
6968
                check_insn(env, ctx, ASE_MT);
6969
                gen_op_dmt();
6970
                break;
6971
            case OPC_EMT:
6972
                check_insn(env, ctx, ASE_MT);
6973
                gen_op_emt();
6974
                break;
6975
            case OPC_DVPE:
6976
                check_insn(env, ctx, ASE_MT);
6977
                gen_op_dvpe();
6978
                break;
6979
            case OPC_EVPE:
6980
                check_insn(env, ctx, ASE_MT);
6981
                gen_op_evpe();
6982
                break;
6983
            case OPC_DI:
6984
                check_insn(env, ctx, ISA_MIPS32R2);
6985
                save_cpu_state(ctx, 1);
6986
                gen_op_di();
6987
                /* Stop translation as we may have switched the execution mode */
6988
                ctx->bstate = BS_STOP;
6989
                break;
6990
            case OPC_EI:
6991
                check_insn(env, ctx, ISA_MIPS32R2);
6992
                save_cpu_state(ctx, 1);
6993
                gen_op_ei();
6994
                /* Stop translation as we may have switched the execution mode */
6995
                ctx->bstate = BS_STOP;
6996
                break;
6997
            default:            /* Invalid */
6998
                MIPS_INVAL("mfmc0");
6999
                generate_exception(ctx, EXCP_RI);
7000
                break;
7001
            }
7002
            gen_store_gpr(cpu_T[0], rt);
7003
            break;
7004
        case OPC_RDPGPR:
7005
            check_insn(env, ctx, ISA_MIPS32R2);
7006
            gen_load_srsgpr(cpu_T[0], rt);
7007
            gen_store_gpr(cpu_T[0], rd);
7008
            break;
7009
        case OPC_WRPGPR:
7010
            check_insn(env, ctx, ISA_MIPS32R2);
7011
            gen_load_gpr(cpu_T[0], rt);
7012
            gen_store_srsgpr(cpu_T[0], rd);
7013
            break;
7014
        default:
7015
            MIPS_INVAL("cp0");
7016
            generate_exception(ctx, EXCP_RI);
7017
            break;
7018
        }
7019
        break;
7020
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7021
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7022
         break;
7023
    case OPC_J ... OPC_JAL: /* Jump */
7024
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7025
         gen_compute_branch(ctx, op, rs, rt, offset);
7026
         return;
7027
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7028
    case OPC_BEQL ... OPC_BGTZL:
7029
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7030
         return;
7031
    case OPC_LB ... OPC_LWR: /* Load and stores */
7032
    case OPC_SB ... OPC_SW:
7033
    case OPC_SWR:
7034
    case OPC_LL:
7035
    case OPC_SC:
7036
         gen_ldst(ctx, op, rt, rs, imm);
7037
         break;
7038
    case OPC_CACHE:
7039
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7040
        /* Treat as NOP. */
7041
        break;
7042
    case OPC_PREF:
7043
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7044
        /* Treat as NOP. */
7045
        break;
7046

    
7047
    /* Floating point (COP1). */
7048
    case OPC_LWC1:
7049
    case OPC_LDC1:
7050
    case OPC_SWC1:
7051
    case OPC_SDC1:
7052
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7053
            save_cpu_state(ctx, 1);
7054
            check_cp1_enabled(ctx);
7055
            gen_flt_ldst(ctx, op, rt, rs, imm);
7056
        } else {
7057
            generate_exception_err(ctx, EXCP_CpU, 1);
7058
        }
7059
        break;
7060

    
7061
    case OPC_CP1:
7062
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7063
            save_cpu_state(ctx, 1);
7064
            check_cp1_enabled(ctx);
7065
            op1 = MASK_CP1(ctx->opcode);
7066
            switch (op1) {
7067
            case OPC_MFHC1:
7068
            case OPC_MTHC1:
7069
                check_insn(env, ctx, ISA_MIPS32R2);
7070
            case OPC_MFC1:
7071
            case OPC_CFC1:
7072
            case OPC_MTC1:
7073
            case OPC_CTC1:
7074
                gen_cp1(ctx, op1, rt, rd);
7075
                break;
7076
#if defined(TARGET_MIPS64)
7077
            case OPC_DMFC1:
7078
            case OPC_DMTC1:
7079
                check_insn(env, ctx, ISA_MIPS3);
7080
                gen_cp1(ctx, op1, rt, rd);
7081
                break;
7082
#endif
7083
            case OPC_BC1ANY2:
7084
            case OPC_BC1ANY4:
7085
                check_cop1x(ctx);
7086
                check_insn(env, ctx, ASE_MIPS3D);
7087
                /* fall through */
7088
            case OPC_BC1:
7089
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7090
                                    (rt >> 2) & 0x7, imm << 2);
7091
                return;
7092
            case OPC_S_FMT:
7093
            case OPC_D_FMT:
7094
            case OPC_W_FMT:
7095
            case OPC_L_FMT:
7096
            case OPC_PS_FMT:
7097
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7098
                           (imm >> 8) & 0x7);
7099
                break;
7100
            default:
7101
                MIPS_INVAL("cp1");
7102
                generate_exception (ctx, EXCP_RI);
7103
                break;
7104
            }
7105
        } else {
7106
            generate_exception_err(ctx, EXCP_CpU, 1);
7107
        }
7108
        break;
7109

    
7110
    /* COP2.  */
7111
    case OPC_LWC2:
7112
    case OPC_LDC2:
7113
    case OPC_SWC2:
7114
    case OPC_SDC2:
7115
    case OPC_CP2:
7116
        /* COP2: Not implemented. */
7117
        generate_exception_err(ctx, EXCP_CpU, 2);
7118
        break;
7119

    
7120
    case OPC_CP3:
7121
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7122
            save_cpu_state(ctx, 1);
7123
            check_cp1_enabled(ctx);
7124
            op1 = MASK_CP3(ctx->opcode);
7125
            switch (op1) {
7126
            case OPC_LWXC1:
7127
            case OPC_LDXC1:
7128
            case OPC_LUXC1:
7129
            case OPC_SWXC1:
7130
            case OPC_SDXC1:
7131
            case OPC_SUXC1:
7132
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7133
                break;
7134
            case OPC_PREFX:
7135
                /* Treat as NOP. */
7136
                break;
7137
            case OPC_ALNV_PS:
7138
            case OPC_MADD_S:
7139
            case OPC_MADD_D:
7140
            case OPC_MADD_PS:
7141
            case OPC_MSUB_S:
7142
            case OPC_MSUB_D:
7143
            case OPC_MSUB_PS:
7144
            case OPC_NMADD_S:
7145
            case OPC_NMADD_D:
7146
            case OPC_NMADD_PS:
7147
            case OPC_NMSUB_S:
7148
            case OPC_NMSUB_D:
7149
            case OPC_NMSUB_PS:
7150
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7151
                break;
7152
            default:
7153
                MIPS_INVAL("cp3");
7154
                generate_exception (ctx, EXCP_RI);
7155
                break;
7156
            }
7157
        } else {
7158
            generate_exception_err(ctx, EXCP_CpU, 1);
7159
        }
7160
        break;
7161

    
7162
#if defined(TARGET_MIPS64)
7163
    /* MIPS64 opcodes */
7164
    case OPC_LWU:
7165
    case OPC_LDL ... OPC_LDR:
7166
    case OPC_SDL ... OPC_SDR:
7167
    case OPC_LLD:
7168
    case OPC_LD:
7169
    case OPC_SCD:
7170
    case OPC_SD:
7171
        check_insn(env, ctx, ISA_MIPS3);
7172
        check_mips_64(ctx);
7173
        gen_ldst(ctx, op, rt, rs, imm);
7174
        break;
7175
    case OPC_DADDI ... OPC_DADDIU:
7176
        check_insn(env, ctx, ISA_MIPS3);
7177
        check_mips_64(ctx);
7178
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7179
        break;
7180
#endif
7181
    case OPC_JALX:
7182
        check_insn(env, ctx, ASE_MIPS16);
7183
        /* MIPS16: Not implemented. */
7184
    case OPC_MDMX:
7185
        check_insn(env, ctx, ASE_MDMX);
7186
        /* MDMX: Not implemented. */
7187
    default:            /* Invalid */
7188
        MIPS_INVAL("major opcode");
7189
        generate_exception(ctx, EXCP_RI);
7190
        break;
7191
    }
7192
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7193
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7194
        /* Branches completion */
7195
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7196
        ctx->bstate = BS_BRANCH;
7197
        save_cpu_state(ctx, 0);
7198
        switch (hflags) {
7199
        case MIPS_HFLAG_B:
7200
            /* unconditional branch */
7201
            MIPS_DEBUG("unconditional branch");
7202
            gen_goto_tb(ctx, 0, ctx->btarget);
7203
            break;
7204
        case MIPS_HFLAG_BL:
7205
            /* blikely taken case */
7206
            MIPS_DEBUG("blikely branch taken");
7207
            gen_goto_tb(ctx, 0, ctx->btarget);
7208
            break;
7209
        case MIPS_HFLAG_BC:
7210
            /* Conditional branch */
7211
            MIPS_DEBUG("conditional branch");
7212
            {
7213
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7214
                int l1 = gen_new_label();
7215

    
7216
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7217
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7218
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7219
                gen_set_label(l1);
7220
                gen_goto_tb(ctx, 0, ctx->btarget);
7221
            }
7222
            break;
7223
        case MIPS_HFLAG_BR:
7224
            /* unconditional branch to register */
7225
            MIPS_DEBUG("branch to register");
7226
            gen_breg_pc();
7227
            tcg_gen_exit_tb(0);
7228
            break;
7229
        default:
7230
            MIPS_DEBUG("unknown branch");
7231
            break;
7232
        }
7233
    }
7234
}
7235

    
7236
static always_inline int
7237
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7238
                                int search_pc)
7239
{
7240
    DisasContext ctx;
7241
    target_ulong pc_start;
7242
    uint16_t *gen_opc_end;
7243
    int j, lj = -1;
7244

    
7245
    if (search_pc && loglevel)
7246
        fprintf (logfile, "search pc %d\n", search_pc);
7247

    
7248
    num_temps = 0;
7249
    memset(temps, 0, sizeof(temps));
7250

    
7251
    num_temps = 0;
7252
    memset(temps, 0, sizeof(temps));
7253

    
7254
    pc_start = tb->pc;
7255
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7256
    ctx.pc = pc_start;
7257
    ctx.saved_pc = -1;
7258
    ctx.tb = tb;
7259
    ctx.bstate = BS_NONE;
7260
    /* Restore delay slot state from the tb context.  */
7261
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7262
    restore_cpu_state(env, &ctx);
7263
#if defined(CONFIG_USER_ONLY)
7264
    ctx.mem_idx = MIPS_HFLAG_UM;
7265
#else
7266
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7267
#endif
7268
#ifdef DEBUG_DISAS
7269
    if (loglevel & CPU_LOG_TB_CPU) {
7270
        fprintf(logfile, "------------------------------------------------\n");
7271
        /* FIXME: This may print out stale hflags from env... */
7272
        cpu_dump_state(env, logfile, fprintf, 0);
7273
    }
7274
#endif
7275
#ifdef MIPS_DEBUG_DISAS
7276
    if (loglevel & CPU_LOG_TB_IN_ASM)
7277
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7278
                tb, ctx.mem_idx, ctx.hflags);
7279
#endif
7280
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7281
        if (env->nb_breakpoints > 0) {
7282
            for(j = 0; j < env->nb_breakpoints; j++) {
7283
                if (env->breakpoints[j] == ctx.pc) {
7284
                    save_cpu_state(&ctx, 1);
7285
                    ctx.bstate = BS_BRANCH;
7286
                    gen_op_debug();
7287
                    /* Include the breakpoint location or the tb won't
7288
                     * be flushed when it must be.  */
7289
                    ctx.pc += 4;
7290
                    goto done_generating;
7291
                }
7292
            }
7293
        }
7294

    
7295
        if (search_pc) {
7296
            j = gen_opc_ptr - gen_opc_buf;
7297
            if (lj < j) {
7298
                lj++;
7299
                while (lj < j)
7300
                    gen_opc_instr_start[lj++] = 0;
7301
            }
7302
            gen_opc_pc[lj] = ctx.pc;
7303
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7304
            gen_opc_instr_start[lj] = 1;
7305
        }
7306
        ctx.opcode = ldl_code(ctx.pc);
7307
        decode_opc(env, &ctx);
7308
        if (num_temps) {
7309
            fprintf(stderr,
7310
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7311
                    ctx.pc);
7312
            num_temps = 0;
7313
        }
7314
        ctx.pc += 4;
7315

    
7316
        if (env->singlestep_enabled)
7317
            break;
7318

    
7319
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7320
            break;
7321

    
7322
#if defined (MIPS_SINGLE_STEP)
7323
        break;
7324
#endif
7325
    }
7326
    if (env->singlestep_enabled) {
7327
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7328
        gen_op_debug();
7329
    } else {
7330
        switch (ctx.bstate) {
7331
        case BS_STOP:
7332
            tcg_gen_helper_0_0(do_interrupt_restart);
7333
            gen_goto_tb(&ctx, 0, ctx.pc);
7334
            break;
7335
        case BS_NONE:
7336
            save_cpu_state(&ctx, 0);
7337
            gen_goto_tb(&ctx, 0, ctx.pc);
7338
            break;
7339
        case BS_EXCP:
7340
            tcg_gen_helper_0_0(do_interrupt_restart);
7341
            tcg_gen_exit_tb(0);
7342
            break;
7343
        case BS_BRANCH:
7344
        default:
7345
            break;
7346
        }
7347
    }
7348
done_generating:
7349
    *gen_opc_ptr = INDEX_op_end;
7350
    if (search_pc) {
7351
        j = gen_opc_ptr - gen_opc_buf;
7352
        lj++;
7353
        while (lj <= j)
7354
            gen_opc_instr_start[lj++] = 0;
7355
    } else {
7356
        tb->size = ctx.pc - pc_start;
7357
    }
7358
#ifdef DEBUG_DISAS
7359
#if defined MIPS_DEBUG_DISAS
7360
    if (loglevel & CPU_LOG_TB_IN_ASM)
7361
        fprintf(logfile, "\n");
7362
#endif
7363
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7364
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7365
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7366
        fprintf(logfile, "\n");
7367
    }
7368
    if (loglevel & CPU_LOG_TB_CPU) {
7369
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7370
    }
7371
#endif
7372

    
7373
    return 0;
7374
}
7375

    
7376
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7377
{
7378
    return gen_intermediate_code_internal(env, tb, 0);
7379
}
7380

    
7381
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7382
{
7383
    return gen_intermediate_code_internal(env, tb, 1);
7384
}
7385

    
7386
void fpu_dump_state(CPUState *env, FILE *f,
7387
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7388
                    int flags)
7389
{
7390
    int i;
7391
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7392

    
7393
#define printfpr(fp)                                                        \
7394
    do {                                                                    \
7395
        if (is_fpu64)                                                       \
7396
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7397
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7398
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7399
        else {                                                              \
7400
            fpr_t tmp;                                                      \
7401
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7402
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7403
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7404
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7405
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7406
        }                                                                   \
7407
    } while(0)
7408

    
7409

    
7410
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7411
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7412
                get_float_exception_flags(&env->fpu->fp_status));
7413
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7414
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7415
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7416
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7417
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7418
        printfpr(&env->fpu->fpr[i]);
7419
    }
7420

    
7421
#undef printfpr
7422
}
7423

    
7424
void dump_fpu (CPUState *env)
7425
{
7426
    if (loglevel) {
7427
        fprintf(logfile,
7428
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7429
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7430
                " %04x\n",
7431
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7432
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7433
                env->bcond);
7434
       fpu_dump_state(env, logfile, fprintf, 0);
7435
    }
7436
}
7437

    
7438
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7439
/* Debug help: The architecture requires 32bit code to maintain proper
7440
   sign-extened values on 64bit machines.  */
7441

    
7442
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7443

    
7444
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7445
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7446
                     int flags)
7447
{
7448
    int i;
7449

    
7450
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7451
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7452
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7453
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7454
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7455
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7456
    if (!SIGN_EXT_P(env->btarget))
7457
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7458

    
7459
    for (i = 0; i < 32; i++) {
7460
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7461
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7462
    }
7463

    
7464
    if (!SIGN_EXT_P(env->CP0_EPC))
7465
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7466
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7467
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7468
}
7469
#endif
7470

    
7471
void cpu_dump_state (CPUState *env, FILE *f,
7472
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7473
                     int flags)
7474
{
7475
    int i;
7476

    
7477
    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",
7478
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7479
    for (i = 0; i < 32; i++) {
7480
        if ((i & 3) == 0)
7481
            cpu_fprintf(f, "GPR%02d:", i);
7482
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7483
        if ((i & 3) == 3)
7484
            cpu_fprintf(f, "\n");
7485
    }
7486

    
7487
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7488
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7489
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7490
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7491
    if (env->hflags & MIPS_HFLAG_FPU)
7492
        fpu_dump_state(env, f, cpu_fprintf, flags);
7493
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7494
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7495
#endif
7496
}
7497

    
7498
static void mips_tcg_init(void)
7499
{
7500
    static int inited;
7501

    
7502
    /* Initialize various static tables. */
7503
    if (inited)
7504
        return;
7505

    
7506
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7507
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7508
                                         TCG_AREG0,
7509
                                         offsetof(CPUState, current_tc_gprs),
7510
                                         "current_tc_gprs");
7511
    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7512
                                       TCG_AREG0,
7513
                                       offsetof(CPUState, current_tc_hi),
7514
                                       "current_tc_hi");
7515
#if TARGET_LONG_BITS > HOST_LONG_BITS
7516
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7517
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7518
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7519
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7520
#else
7521
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7522
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7523
#endif
7524

    
7525
    inited = 1;
7526
}
7527

    
7528
#include "translate_init.c"
7529

    
7530
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7531
{
7532
    CPUMIPSState *env;
7533
    const mips_def_t *def;
7534

    
7535
    def = cpu_mips_find_by_name(cpu_model);
7536
    if (!def)
7537
        return NULL;
7538
    env = qemu_mallocz(sizeof(CPUMIPSState));
7539
    if (!env)
7540
        return NULL;
7541
    env->cpu_model = def;
7542

    
7543
    cpu_exec_init(env);
7544
    env->cpu_model_str = cpu_model;
7545
    mips_tcg_init();
7546
    cpu_reset(env);
7547
    return env;
7548
}
7549

    
7550
void cpu_reset (CPUMIPSState *env)
7551
{
7552
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7553

    
7554
    tlb_flush(env, 1);
7555

    
7556
    /* Minimal init */
7557
#if !defined(CONFIG_USER_ONLY)
7558
    if (env->hflags & MIPS_HFLAG_BMASK) {
7559
        /* If the exception was raised from a delay slot,
7560
         * come back to the jump.  */
7561
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7562
    } else {
7563
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7564
    }
7565
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7566
    env->CP0_Wired = 0;
7567
    /* SMP not implemented */
7568
    env->CP0_EBase = 0x80000000;
7569
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7570
    /* vectored interrupts not implemented, timer on int 7,
7571
       no performance counters. */
7572
    env->CP0_IntCtl = 0xe0000000;
7573
    {
7574
        int i;
7575

    
7576
        for (i = 0; i < 7; i++) {
7577
            env->CP0_WatchLo[i] = 0;
7578
            env->CP0_WatchHi[i] = 0x80000000;
7579
        }
7580
        env->CP0_WatchLo[7] = 0;
7581
        env->CP0_WatchHi[7] = 0;
7582
    }
7583
    /* Count register increments in debug mode, EJTAG version 1 */
7584
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7585
#endif
7586
    env->exception_index = EXCP_NONE;
7587
#if defined(CONFIG_USER_ONLY)
7588
    env->hflags = MIPS_HFLAG_UM;
7589
    env->user_mode_only = 1;
7590
#else
7591
    env->hflags = MIPS_HFLAG_CP0;
7592
#endif
7593
    cpu_mips_register(env, env->cpu_model);
7594
}
7595

    
7596
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7597
                unsigned long searched_pc, int pc_pos, void *puc)
7598
{
7599
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7600
    env->hflags &= ~MIPS_HFLAG_BMASK;
7601
    env->hflags |= gen_opc_hflags[pc_pos];
7602
}