Statistics
| Branch: | Revision:

root / target-mips / translate.c @ aa0bf00b

History | View | Annotate | Download (224.6 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, current_fpu, cpu_T[2];
427

    
428
/* FPU TNs, global for now. */
429
static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3];
430

    
431
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg)
432
{
433
    TCGv t = tcg_const_i32(arg);
434

    
435
    tcg_gen_helper_0_1(func, t);
436
    tcg_temp_free(t);
437
}
438

    
439
static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2)
440
{
441
    TCGv t1 = tcg_const_i32(arg1);
442
    TCGv t2 = tcg_const_i32(arg2);
443

    
444
    tcg_gen_helper_0_2(func, t1, t2);
445
    tcg_temp_free(t1);
446
    tcg_temp_free(t2);
447
}
448

    
449
typedef struct DisasContext {
450
    struct TranslationBlock *tb;
451
    target_ulong pc, saved_pc;
452
    uint32_t opcode;
453
    uint32_t fp_status;
454
    /* Routine used to access memory */
455
    int mem_idx;
456
    uint32_t hflags, saved_hflags;
457
    int bstate;
458
    target_ulong btarget;
459
} DisasContext;
460

    
461
enum {
462
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
463
                      * exception condition
464
                      */
465
    BS_STOP     = 1, /* We want to stop translation for any reason */
466
    BS_BRANCH   = 2, /* We reached a branch condition     */
467
    BS_EXCP     = 3, /* We reached an exception condition */
468
};
469

    
470
static const char *regnames[] =
471
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
472
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
473
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
474
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
475

    
476
static const char *fregnames[] =
477
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
478
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
479
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
480
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
481

    
482
#ifdef MIPS_DEBUG_DISAS
483
#define MIPS_DEBUG(fmt, args...)                                              \
484
do {                                                                          \
485
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
486
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
487
                ctx->pc, ctx->opcode , ##args);                               \
488
    }                                                                         \
489
} while (0)
490
#else
491
#define MIPS_DEBUG(fmt, args...) do { } while(0)
492
#endif
493

    
494
#define MIPS_INVAL(op)                                                        \
495
do {                                                                          \
496
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
497
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
498
} while (0)
499

    
500
/* General purpose registers moves. */
501
static inline void gen_load_gpr (TCGv t, int reg)
502
{
503
    if (reg == 0)
504
        tcg_gen_movi_tl(t, 0);
505
    else
506
        tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
507
}
508

    
509
static inline void gen_store_gpr (TCGv t, int reg)
510
{
511
    if (reg != 0)
512
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
513
}
514

    
515
/* Moves to/from HI and LO registers.  */
516
static inline void gen_load_LO (TCGv t, int reg)
517
{
518
    tcg_gen_ld_tl(t, current_tc_hi,
519
                  offsetof(CPUState, LO)
520
                  - offsetof(CPUState, HI)
521
                  + sizeof(target_ulong) * reg);
522
}
523

    
524
static inline void gen_store_LO (TCGv t, int reg)
525
{
526
    tcg_gen_st_tl(t, current_tc_hi,
527
                  offsetof(CPUState, LO)
528
                  - offsetof(CPUState, HI)
529
                  + sizeof(target_ulong) * reg);
530
}
531

    
532
static inline void gen_load_HI (TCGv t, int reg)
533
{
534
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
535
}
536

    
537
static inline void gen_store_HI (TCGv t, int reg)
538
{
539
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
540
}
541

    
542
/* Moves to/from shadow registers. */
543
static inline void gen_load_srsgpr (TCGv t, int reg)
544
{
545
    if (reg == 0)
546
        tcg_gen_movi_tl(t, 0);
547
    else {
548
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
549

    
550
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
551
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
552
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
553
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
554
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
555

    
556
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
557
        tcg_temp_free(r_tmp);
558
    }
559
}
560

    
561
static inline void gen_store_srsgpr (TCGv t, int reg)
562
{
563
    if (reg != 0) {
564
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
565

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

    
572
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
573
        tcg_temp_free(r_tmp);
574
    }
575
}
576

    
577
/* Floating point register moves. */
578
static inline void gen_load_fpr32 (TCGv t, int reg)
579
{
580
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
581
}
582

    
583
static inline void gen_store_fpr32 (TCGv t, int reg)
584
{
585
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
586
}
587

    
588
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
589
{
590
    if (ctx->hflags & MIPS_HFLAG_F64) {
591
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
592
    } else {
593
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
594
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
595

    
596
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
597
        tcg_gen_extu_i32_i64(t, r_tmp1);
598
        tcg_gen_shli_i64(t, t, 32);
599
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
600
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
601
        tcg_gen_or_i64(t, t, r_tmp2);
602
        tcg_temp_free(r_tmp1);
603
        tcg_temp_free(r_tmp2);
604
    }
605
}
606

    
607
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
608
{
609
    if (ctx->hflags & MIPS_HFLAG_F64) {
610
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
611
    } else {
612
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
613

    
614
        tcg_gen_trunc_i64_i32(r_tmp, t);
615
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
616
        tcg_gen_shri_i64(t, t, 32);
617
        tcg_gen_trunc_i64_i32(r_tmp, t);
618
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
619
        tcg_temp_free(r_tmp);
620
    }
621
}
622

    
623
static inline void gen_load_fpr32h (TCGv t, int reg)
624
{
625
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
626
}
627

    
628
static inline void gen_store_fpr32h (TCGv t, int reg)
629
{
630
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
631
}
632

    
633
#define FOP_CONDS(type, fmt)                                            \
634
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
635
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
636
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
637
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
638
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
639
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
640
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
641
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
642
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
643
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
644
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
645
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
646
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
647
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
648
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
649
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
650
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
651
};                                                                      \
652
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
653
{                                                                       \
654
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
655
}
656

    
657
FOP_CONDS(, d)
658
FOP_CONDS(abs, d)
659
FOP_CONDS(, s)
660
FOP_CONDS(abs, s)
661
FOP_CONDS(, ps)
662
FOP_CONDS(abs, ps)
663

    
664
/* Tests */
665
#define OP_COND(name, cond)                                   \
666
void glue(gen_op_, name) (void)                               \
667
{                                                             \
668
    int l1 = gen_new_label();                                 \
669
    int l2 = gen_new_label();                                 \
670
                                                              \
671
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
672
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
673
    tcg_gen_br(l2);                                           \
674
    gen_set_label(l1);                                        \
675
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
676
    gen_set_label(l2);                                        \
677
}
678
OP_COND(eq, TCG_COND_EQ);
679
OP_COND(ne, TCG_COND_NE);
680
OP_COND(ge, TCG_COND_GE);
681
OP_COND(geu, TCG_COND_GEU);
682
OP_COND(lt, TCG_COND_LT);
683
OP_COND(ltu, TCG_COND_LTU);
684
#undef OP_COND
685

    
686
#define OP_CONDI(name, cond)                                  \
687
void glue(gen_op_, name) (target_ulong val)                   \
688
{                                                             \
689
    int l1 = gen_new_label();                                 \
690
    int l2 = gen_new_label();                                 \
691
                                                              \
692
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
693
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
694
    tcg_gen_br(l2);                                           \
695
    gen_set_label(l1);                                        \
696
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
697
    gen_set_label(l2);                                        \
698
}
699
OP_CONDI(lti, TCG_COND_LT);
700
OP_CONDI(ltiu, TCG_COND_LTU);
701
#undef OP_CONDI
702

    
703
#define OP_CONDZ(name, cond)                                  \
704
void glue(gen_op_, name) (void)                               \
705
{                                                             \
706
    int l1 = gen_new_label();                                 \
707
    int l2 = gen_new_label();                                 \
708
                                                              \
709
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, 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_CONDZ(gez, TCG_COND_GE);
717
OP_CONDZ(gtz, TCG_COND_GT);
718
OP_CONDZ(lez, TCG_COND_LE);
719
OP_CONDZ(ltz, TCG_COND_LT);
720
#undef OP_CONDZ
721

    
722
static inline void gen_save_pc(target_ulong pc)
723
{
724
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
725
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
726
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
727
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
728

    
729
    tcg_gen_movi_tl(r_tmp, pc);
730
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
731
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
732
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
733
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
734
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
735
    tcg_temp_free(r_tc_off);
736
    tcg_temp_free(r_tc_off_ptr);
737
    tcg_temp_free(r_ptr);
738
    tcg_temp_free(r_tmp);
739
}
740

    
741
static inline void gen_breg_pc(void)
742
{
743
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
744
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
745
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
746
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
747

    
748
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
749
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
750
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
751
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
752
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
753
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
754
    tcg_temp_free(r_tc_off);
755
    tcg_temp_free(r_tc_off_ptr);
756
    tcg_temp_free(r_ptr);
757
    tcg_temp_free(r_tmp);
758
}
759

    
760
static inline void gen_save_btarget(target_ulong btarget)
761
{
762
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
763

    
764
    tcg_gen_movi_tl(r_tmp, btarget);
765
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
766
    tcg_temp_free(r_tmp);
767
}
768

    
769
static always_inline void gen_save_breg_target(int reg)
770
{
771
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
772

    
773
    gen_load_gpr(r_tmp, reg);
774
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
775
    tcg_temp_free(r_tmp);
776
}
777

    
778
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
779
{
780
#if defined MIPS_DEBUG_DISAS
781
    if (loglevel & CPU_LOG_TB_IN_ASM) {
782
            fprintf(logfile, "hflags %08x saved %08x\n",
783
                    ctx->hflags, ctx->saved_hflags);
784
    }
785
#endif
786
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
787
        gen_save_pc(ctx->pc);
788
        ctx->saved_pc = ctx->pc;
789
    }
790
    if (ctx->hflags != ctx->saved_hflags) {
791
        gen_op_save_state(ctx->hflags);
792
        ctx->saved_hflags = ctx->hflags;
793
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
794
        case MIPS_HFLAG_BR:
795
            break;
796
        case MIPS_HFLAG_BC:
797
        case MIPS_HFLAG_BL:
798
        case MIPS_HFLAG_B:
799
            gen_save_btarget(ctx->btarget);
800
            break;
801
        }
802
    }
803
}
804

    
805
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
806
{
807
    ctx->saved_hflags = ctx->hflags;
808
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
809
    case MIPS_HFLAG_BR:
810
        break;
811
    case MIPS_HFLAG_BC:
812
    case MIPS_HFLAG_BL:
813
    case MIPS_HFLAG_B:
814
        ctx->btarget = env->btarget;
815
        break;
816
    }
817
}
818

    
819
static always_inline void
820
generate_exception_err (DisasContext *ctx, int excp, int err)
821
{
822
    save_cpu_state(ctx, 1);
823
    tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err);
824
    tcg_gen_helper_0_0(do_interrupt_restart);
825
    tcg_gen_exit_tb(0);
826
}
827

    
828
static always_inline void
829
generate_exception (DisasContext *ctx, int excp)
830
{
831
    save_cpu_state(ctx, 1);
832
    tcg_gen_helper_0_1i(do_raise_exception, excp);
833
    tcg_gen_helper_0_0(do_interrupt_restart);
834
    tcg_gen_exit_tb(0);
835
}
836

    
837
/* Addresses computation */
838
static inline void gen_op_addr_add (void)
839
{
840
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
841

    
842
#if defined(TARGET_MIPS64)
843
    /* For compatibility with 32-bit code, data reference in user mode
844
       with Status_UX = 0 should be casted to 32-bit and sign extended.
845
       See the MIPS64 PRA manual, section 4.10. */
846
    {
847
        int l1 = gen_new_label();
848
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
849

    
850
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
851
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
852
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
853
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
854
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
855
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
856
        tcg_temp_free(r_tmp);
857
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
858
        gen_set_label(l1);
859
    }
860
#endif
861
}
862

    
863
static always_inline void check_cp0_enabled(DisasContext *ctx)
864
{
865
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
866
        generate_exception_err(ctx, EXCP_CpU, 1);
867
}
868

    
869
static always_inline void check_cp1_enabled(DisasContext *ctx)
870
{
871
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
872
        generate_exception_err(ctx, EXCP_CpU, 1);
873
}
874

    
875
/* Verify that the processor is running with COP1X instructions enabled.
876
   This is associated with the nabla symbol in the MIPS32 and MIPS64
877
   opcode tables.  */
878

    
879
static always_inline void check_cop1x(DisasContext *ctx)
880
{
881
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
882
        generate_exception(ctx, EXCP_RI);
883
}
884

    
885
/* Verify that the processor is running with 64-bit floating-point
886
   operations enabled.  */
887

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

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

    
911
/* This code generates a "reserved instruction" exception if the
912
   CPU does not support the instruction set corresponding to flags. */
913
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
914
{
915
    if (unlikely(!(env->insn_flags & flags)))
916
        generate_exception(ctx, EXCP_RI);
917
}
918

    
919
/* This code generates a "reserved instruction" exception if 64-bit
920
   instructions are not enabled. */
921
static always_inline void check_mips_64(DisasContext *ctx)
922
{
923
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
924
        generate_exception(ctx, EXCP_RI);
925
}
926

    
927
/* load/store instructions. */
928
#if defined(CONFIG_USER_ONLY)
929
#define op_ldst(name)        gen_op_##name##_raw()
930
#define OP_LD_TABLE(width)
931
#define OP_ST_TABLE(width)
932
#else
933
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
934
#define OP_LD_TABLE(width)                                                    \
935
static GenOpFunc *gen_op_l##width[] = {                                       \
936
    &gen_op_l##width##_kernel,                                                \
937
    &gen_op_l##width##_super,                                                 \
938
    &gen_op_l##width##_user,                                                  \
939
}
940
#define OP_ST_TABLE(width)                                                    \
941
static GenOpFunc *gen_op_s##width[] = {                                       \
942
    &gen_op_s##width##_kernel,                                                \
943
    &gen_op_s##width##_super,                                                 \
944
    &gen_op_s##width##_user,                                                  \
945
}
946
#endif
947

    
948
#if defined(TARGET_MIPS64)
949
OP_LD_TABLE(dl);
950
OP_LD_TABLE(dr);
951
OP_ST_TABLE(dl);
952
OP_ST_TABLE(dr);
953
#endif
954
OP_LD_TABLE(wl);
955
OP_LD_TABLE(wr);
956
OP_ST_TABLE(wl);
957
OP_ST_TABLE(wr);
958
OP_LD_TABLE(uxc1);
959
OP_ST_TABLE(uxc1);
960

    
961
#define OP_LD(insn,fname)                                        \
962
void inline op_ldst_##insn(DisasContext *ctx)                    \
963
{                                                                \
964
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
965
}
966
OP_LD(lb,ld8s);
967
OP_LD(lbu,ld8u);
968
OP_LD(lh,ld16s);
969
OP_LD(lhu,ld16u);
970
OP_LD(lw,ld32s);
971
#if defined(TARGET_MIPS64)
972
OP_LD(lwu,ld32u);
973
OP_LD(ld,ld64);
974
#endif
975
#undef OP_LD
976

    
977
#define OP_ST(insn,fname)                                        \
978
void inline op_ldst_##insn(DisasContext *ctx)                    \
979
{                                                                \
980
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
981
}
982
OP_ST(sb,st8);
983
OP_ST(sh,st16);
984
OP_ST(sw,st32);
985
#if defined(TARGET_MIPS64)
986
OP_ST(sd,st64);
987
#endif
988
#undef OP_ST
989

    
990
#define OP_LD_ATOMIC(insn,fname)                                        \
991
void inline op_ldst_##insn(DisasContext *ctx)                           \
992
{                                                                       \
993
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
994
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
995
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
996
}
997
OP_LD_ATOMIC(ll,ld32s);
998
#if defined(TARGET_MIPS64)
999
OP_LD_ATOMIC(lld,ld64);
1000
#endif
1001
#undef OP_LD_ATOMIC
1002

    
1003
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1004
void inline op_ldst_##insn(DisasContext *ctx)                           \
1005
{                                                                       \
1006
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1007
    int l1 = gen_new_label();                                           \
1008
    int l2 = gen_new_label();                                           \
1009
    int l3 = gen_new_label();                                           \
1010
                                                                        \
1011
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1012
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1013
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1014
    generate_exception(ctx, EXCP_AdES);                                 \
1015
    gen_set_label(l1);                                                  \
1016
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1017
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1018
    tcg_temp_free(r_tmp);                                               \
1019
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1020
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1021
    tcg_gen_br(l3);                                                     \
1022
    gen_set_label(l2);                                                  \
1023
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1024
    gen_set_label(l3);                                                  \
1025
}
1026
OP_ST_ATOMIC(sc,st32,0x3);
1027
#if defined(TARGET_MIPS64)
1028
OP_ST_ATOMIC(scd,st64,0x7);
1029
#endif
1030
#undef OP_ST_ATOMIC
1031

    
1032
/* Load and store */
1033
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1034
                      int base, int16_t offset)
1035
{
1036
    const char *opn = "ldst";
1037

    
1038
    if (base == 0) {
1039
        tcg_gen_movi_tl(cpu_T[0], offset);
1040
    } else if (offset == 0) {
1041
        gen_load_gpr(cpu_T[0], base);
1042
    } else {
1043
        gen_load_gpr(cpu_T[0], base);
1044
        tcg_gen_movi_tl(cpu_T[1], offset);
1045
        gen_op_addr_add();
1046
    }
1047
    /* Don't do NOP if destination is zero: we must perform the actual
1048
       memory access. */
1049
    switch (opc) {
1050
#if defined(TARGET_MIPS64)
1051
    case OPC_LWU:
1052
        op_ldst_lwu(ctx);
1053
        gen_store_gpr(cpu_T[0], rt);
1054
        opn = "lwu";
1055
        break;
1056
    case OPC_LD:
1057
        op_ldst_ld(ctx);
1058
        gen_store_gpr(cpu_T[0], rt);
1059
        opn = "ld";
1060
        break;
1061
    case OPC_LLD:
1062
        op_ldst_lld(ctx);
1063
        gen_store_gpr(cpu_T[0], rt);
1064
        opn = "lld";
1065
        break;
1066
    case OPC_SD:
1067
        gen_load_gpr(cpu_T[1], rt);
1068
        op_ldst_sd(ctx);
1069
        opn = "sd";
1070
        break;
1071
    case OPC_SCD:
1072
        save_cpu_state(ctx, 1);
1073
        gen_load_gpr(cpu_T[1], rt);
1074
        op_ldst_scd(ctx);
1075
        gen_store_gpr(cpu_T[0], rt);
1076
        opn = "scd";
1077
        break;
1078
    case OPC_LDL:
1079
        gen_load_gpr(cpu_T[1], rt);
1080
        op_ldst(ldl);
1081
        gen_store_gpr(cpu_T[1], rt);
1082
        opn = "ldl";
1083
        break;
1084
    case OPC_SDL:
1085
        gen_load_gpr(cpu_T[1], rt);
1086
        op_ldst(sdl);
1087
        opn = "sdl";
1088
        break;
1089
    case OPC_LDR:
1090
        gen_load_gpr(cpu_T[1], rt);
1091
        op_ldst(ldr);
1092
        gen_store_gpr(cpu_T[1], rt);
1093
        opn = "ldr";
1094
        break;
1095
    case OPC_SDR:
1096
        gen_load_gpr(cpu_T[1], rt);
1097
        op_ldst(sdr);
1098
        opn = "sdr";
1099
        break;
1100
#endif
1101
    case OPC_LW:
1102
        op_ldst_lw(ctx);
1103
        gen_store_gpr(cpu_T[0], rt);
1104
        opn = "lw";
1105
        break;
1106
    case OPC_SW:
1107
        gen_load_gpr(cpu_T[1], rt);
1108
        op_ldst_sw(ctx);
1109
        opn = "sw";
1110
        break;
1111
    case OPC_LH:
1112
        op_ldst_lh(ctx);
1113
        gen_store_gpr(cpu_T[0], rt);
1114
        opn = "lh";
1115
        break;
1116
    case OPC_SH:
1117
        gen_load_gpr(cpu_T[1], rt);
1118
        op_ldst_sh(ctx);
1119
        opn = "sh";
1120
        break;
1121
    case OPC_LHU:
1122
        op_ldst_lhu(ctx);
1123
        gen_store_gpr(cpu_T[0], rt);
1124
        opn = "lhu";
1125
        break;
1126
    case OPC_LB:
1127
        op_ldst_lb(ctx);
1128
        gen_store_gpr(cpu_T[0], rt);
1129
        opn = "lb";
1130
        break;
1131
    case OPC_SB:
1132
        gen_load_gpr(cpu_T[1], rt);
1133
        op_ldst_sb(ctx);
1134
        opn = "sb";
1135
        break;
1136
    case OPC_LBU:
1137
        op_ldst_lbu(ctx);
1138
        gen_store_gpr(cpu_T[0], rt);
1139
        opn = "lbu";
1140
        break;
1141
    case OPC_LWL:
1142
        gen_load_gpr(cpu_T[1], rt);
1143
        op_ldst(lwl);
1144
        gen_store_gpr(cpu_T[1], rt);
1145
        opn = "lwl";
1146
        break;
1147
    case OPC_SWL:
1148
        gen_load_gpr(cpu_T[1], rt);
1149
        op_ldst(swl);
1150
        opn = "swr";
1151
        break;
1152
    case OPC_LWR:
1153
        gen_load_gpr(cpu_T[1], rt);
1154
        op_ldst(lwr);
1155
        gen_store_gpr(cpu_T[1], rt);
1156
        opn = "lwr";
1157
        break;
1158
    case OPC_SWR:
1159
        gen_load_gpr(cpu_T[1], rt);
1160
        op_ldst(swr);
1161
        opn = "swr";
1162
        break;
1163
    case OPC_LL:
1164
        op_ldst_ll(ctx);
1165
        gen_store_gpr(cpu_T[0], rt);
1166
        opn = "ll";
1167
        break;
1168
    case OPC_SC:
1169
        save_cpu_state(ctx, 1);
1170
        gen_load_gpr(cpu_T[1], rt);
1171
        op_ldst_sc(ctx);
1172
        gen_store_gpr(cpu_T[0], rt);
1173
        opn = "sc";
1174
        break;
1175
    default:
1176
        MIPS_INVAL(opn);
1177
        generate_exception(ctx, EXCP_RI);
1178
        return;
1179
    }
1180
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1181
}
1182

    
1183
/* Load and store */
1184
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1185
                      int base, int16_t offset)
1186
{
1187
    const char *opn = "flt_ldst";
1188

    
1189
    if (base == 0) {
1190
        tcg_gen_movi_tl(cpu_T[0], offset);
1191
    } else if (offset == 0) {
1192
        gen_load_gpr(cpu_T[0], base);
1193
    } else {
1194
        gen_load_gpr(cpu_T[0], base);
1195
        tcg_gen_movi_tl(cpu_T[1], offset);
1196
        gen_op_addr_add();
1197
    }
1198
    /* Don't do NOP if destination is zero: we must perform the actual
1199
       memory access. */
1200
    switch (opc) {
1201
    case OPC_LWC1:
1202
        tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1203
        gen_store_fpr32(fpu32_T[0], ft);
1204
        opn = "lwc1";
1205
        break;
1206
    case OPC_SWC1:
1207
        gen_load_fpr32(fpu32_T[0], ft);
1208
        tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1209
        opn = "swc1";
1210
        break;
1211
    case OPC_LDC1:
1212
        tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1213
        gen_store_fpr64(ctx, fpu64_T[0], ft);
1214
        opn = "ldc1";
1215
        break;
1216
    case OPC_SDC1:
1217
        gen_load_fpr64(ctx, fpu64_T[0], ft);
1218
        tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1219
        opn = "sdc1";
1220
        break;
1221
    default:
1222
        MIPS_INVAL(opn);
1223
        generate_exception(ctx, EXCP_RI);
1224
        return;
1225
    }
1226
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1227
}
1228

    
1229
/* Arithmetic with immediate operand */
1230
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1231
                           int rt, int rs, int16_t imm)
1232
{
1233
    target_ulong uimm;
1234
    const char *opn = "imm arith";
1235

    
1236
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1237
        /* If no destination, treat it as a NOP.
1238
           For addi, we must generate the overflow exception when needed. */
1239
        MIPS_DEBUG("NOP");
1240
        return;
1241
    }
1242
    uimm = (uint16_t)imm;
1243
    switch (opc) {
1244
    case OPC_ADDI:
1245
    case OPC_ADDIU:
1246
#if defined(TARGET_MIPS64)
1247
    case OPC_DADDI:
1248
    case OPC_DADDIU:
1249
#endif
1250
    case OPC_SLTI:
1251
    case OPC_SLTIU:
1252
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1253
        tcg_gen_movi_tl(cpu_T[1], uimm);
1254
        /* Fall through. */
1255
    case OPC_ANDI:
1256
    case OPC_ORI:
1257
    case OPC_XORI:
1258
        gen_load_gpr(cpu_T[0], rs);
1259
        break;
1260
    case OPC_LUI:
1261
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1262
        break;
1263
    case OPC_SLL:
1264
    case OPC_SRA:
1265
    case OPC_SRL:
1266
#if defined(TARGET_MIPS64)
1267
    case OPC_DSLL:
1268
    case OPC_DSRA:
1269
    case OPC_DSRL:
1270
    case OPC_DSLL32:
1271
    case OPC_DSRA32:
1272
    case OPC_DSRL32:
1273
#endif
1274
        uimm &= 0x1f;
1275
        gen_load_gpr(cpu_T[0], rs);
1276
        break;
1277
    }
1278
    switch (opc) {
1279
    case OPC_ADDI:
1280
        {
1281
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1282
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1283
            int l1 = gen_new_label();
1284

    
1285
            save_cpu_state(ctx, 1);
1286
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1287
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1288

    
1289
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1290
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1291
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1292
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1293
            tcg_temp_free(r_tmp2);
1294
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1295
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1296
            tcg_temp_free(r_tmp1);
1297
            /* operands of same sign, result different sign */
1298
            generate_exception(ctx, EXCP_OVERFLOW);
1299
            gen_set_label(l1);
1300

    
1301
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1302
        }
1303
        opn = "addi";
1304
        break;
1305
    case OPC_ADDIU:
1306
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1307
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1308
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1309
        opn = "addiu";
1310
        break;
1311
#if defined(TARGET_MIPS64)
1312
    case OPC_DADDI:
1313
        {
1314
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1315
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1316
            int l1 = gen_new_label();
1317

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

    
1322
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1323
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1324
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1325
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1326
            tcg_temp_free(r_tmp2);
1327
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1328
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1329
            tcg_temp_free(r_tmp1);
1330
            /* operands of same sign, result different sign */
1331
            generate_exception(ctx, EXCP_OVERFLOW);
1332
            gen_set_label(l1);
1333
        }
1334
        opn = "daddi";
1335
        break;
1336
    case OPC_DADDIU:
1337
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1338
        opn = "daddiu";
1339
        break;
1340
#endif
1341
    case OPC_SLTI:
1342
        gen_op_lti(uimm);
1343
        opn = "slti";
1344
        break;
1345
    case OPC_SLTIU:
1346
        gen_op_ltiu(uimm);
1347
        opn = "sltiu";
1348
        break;
1349
    case OPC_ANDI:
1350
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1351
        opn = "andi";
1352
        break;
1353
    case OPC_ORI:
1354
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1355
        opn = "ori";
1356
        break;
1357
    case OPC_XORI:
1358
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1359
        opn = "xori";
1360
        break;
1361
    case OPC_LUI:
1362
        opn = "lui";
1363
        break;
1364
    case OPC_SLL:
1365
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1366
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1367
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1368
        opn = "sll";
1369
        break;
1370
    case OPC_SRA:
1371
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1372
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1373
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1374
        opn = "sra";
1375
        break;
1376
    case OPC_SRL:
1377
        switch ((ctx->opcode >> 21) & 0x1f) {
1378
        case 0:
1379
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1380
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1381
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1382
            opn = "srl";
1383
            break;
1384
        case 1:
1385
            /* rotr is decoded as srl on non-R2 CPUs */
1386
            if (env->insn_flags & ISA_MIPS32R2) {
1387
                if (uimm != 0) {
1388
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1389
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1390

    
1391
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1392
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1393
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1394
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1395
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1396
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1397
                    tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1398
                    tcg_temp_free(r_tmp1);
1399
                    tcg_temp_free(r_tmp2);
1400
                }
1401
                opn = "rotr";
1402
            } else {
1403
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1404
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1405
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1406
                opn = "srl";
1407
            }
1408
            break;
1409
        default:
1410
            MIPS_INVAL("invalid srl flag");
1411
            generate_exception(ctx, EXCP_RI);
1412
            break;
1413
        }
1414
        break;
1415
#if defined(TARGET_MIPS64)
1416
    case OPC_DSLL:
1417
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1418
        opn = "dsll";
1419
        break;
1420
    case OPC_DSRA:
1421
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1422
        opn = "dsra";
1423
        break;
1424
    case OPC_DSRL:
1425
        switch ((ctx->opcode >> 21) & 0x1f) {
1426
        case 0:
1427
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1428
            opn = "dsrl";
1429
            break;
1430
        case 1:
1431
            /* drotr is decoded as dsrl on non-R2 CPUs */
1432
            if (env->insn_flags & ISA_MIPS32R2) {
1433
                if (uimm != 0) {
1434
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1435

    
1436
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1437
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1438
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1439
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1440
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1441
                    tcg_temp_free(r_tmp1);
1442
                }
1443
                opn = "drotr";
1444
            } else {
1445
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1446
                opn = "dsrl";
1447
            }
1448
            break;
1449
        default:
1450
            MIPS_INVAL("invalid dsrl flag");
1451
            generate_exception(ctx, EXCP_RI);
1452
            break;
1453
        }
1454
        break;
1455
    case OPC_DSLL32:
1456
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1457
        opn = "dsll32";
1458
        break;
1459
    case OPC_DSRA32:
1460
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1461
        opn = "dsra32";
1462
        break;
1463
    case OPC_DSRL32:
1464
        switch ((ctx->opcode >> 21) & 0x1f) {
1465
        case 0:
1466
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1467
            opn = "dsrl32";
1468
            break;
1469
        case 1:
1470
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1471
            if (env->insn_flags & ISA_MIPS32R2) {
1472
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1473
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1474

    
1475
                tcg_gen_movi_tl(r_tmp1, 0x40);
1476
                tcg_gen_movi_tl(r_tmp2, 32);
1477
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1478
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1479
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1480
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1481
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1482
                tcg_temp_free(r_tmp1);
1483
                tcg_temp_free(r_tmp2);
1484
                opn = "drotr32";
1485
            } else {
1486
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1487
                opn = "dsrl32";
1488
            }
1489
            break;
1490
        default:
1491
            MIPS_INVAL("invalid dsrl32 flag");
1492
            generate_exception(ctx, EXCP_RI);
1493
            break;
1494
        }
1495
        break;
1496
#endif
1497
    default:
1498
        MIPS_INVAL(opn);
1499
        generate_exception(ctx, EXCP_RI);
1500
        return;
1501
    }
1502
    gen_store_gpr(cpu_T[0], rt);
1503
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1504
}
1505

    
1506
/* Arithmetic */
1507
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1508
                       int rd, int rs, int rt)
1509
{
1510
    const char *opn = "arith";
1511

    
1512
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1513
       && opc != OPC_DADD && opc != OPC_DSUB) {
1514
        /* If no destination, treat it as a NOP.
1515
           For add & sub, we must generate the overflow exception when needed. */
1516
        MIPS_DEBUG("NOP");
1517
        return;
1518
    }
1519
    gen_load_gpr(cpu_T[0], rs);
1520
    /* Specialcase the conventional move operation. */
1521
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1522
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1523
        gen_store_gpr(cpu_T[0], rd);
1524
        return;
1525
    }
1526
    gen_load_gpr(cpu_T[1], rt);
1527
    switch (opc) {
1528
    case OPC_ADD:
1529
        {
1530
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1531
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1532
            int l1 = gen_new_label();
1533

    
1534
            save_cpu_state(ctx, 1);
1535
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1536
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1537
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1538

    
1539
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1540
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1541
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1542
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1543
            tcg_temp_free(r_tmp2);
1544
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1545
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1546
            tcg_temp_free(r_tmp1);
1547
            /* operands of same sign, result different sign */
1548
            generate_exception(ctx, EXCP_OVERFLOW);
1549
            gen_set_label(l1);
1550

    
1551
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1552
        }
1553
        opn = "add";
1554
        break;
1555
    case OPC_ADDU:
1556
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1557
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1558
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1559
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1560
        opn = "addu";
1561
        break;
1562
    case OPC_SUB:
1563
        {
1564
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1565
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1566
            int l1 = gen_new_label();
1567

    
1568
            save_cpu_state(ctx, 1);
1569
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1570
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1571
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1572

    
1573
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1574
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1575
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1576
            tcg_temp_free(r_tmp2);
1577
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1578
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1579
            tcg_temp_free(r_tmp1);
1580
            /* operands of different sign, first operand and result different sign */
1581
            generate_exception(ctx, EXCP_OVERFLOW);
1582
            gen_set_label(l1);
1583

    
1584
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1585
        }
1586
        opn = "sub";
1587
        break;
1588
    case OPC_SUBU:
1589
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1590
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1591
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1592
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1593
        opn = "subu";
1594
        break;
1595
#if defined(TARGET_MIPS64)
1596
    case OPC_DADD:
1597
        {
1598
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1599
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1600
            int l1 = gen_new_label();
1601

    
1602
            save_cpu_state(ctx, 1);
1603
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1604
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1605

    
1606
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1607
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1608
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1609
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1610
            tcg_temp_free(r_tmp2);
1611
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1612
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1613
            tcg_temp_free(r_tmp1);
1614
            /* operands of same sign, result different sign */
1615
            generate_exception(ctx, EXCP_OVERFLOW);
1616
            gen_set_label(l1);
1617
        }
1618
        opn = "dadd";
1619
        break;
1620
    case OPC_DADDU:
1621
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1622
        opn = "daddu";
1623
        break;
1624
    case OPC_DSUB:
1625
        {
1626
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1627
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1628
            int l1 = gen_new_label();
1629

    
1630
            save_cpu_state(ctx, 1);
1631
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1632
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1633

    
1634
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1635
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1636
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1637
            tcg_temp_free(r_tmp2);
1638
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1639
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1640
            tcg_temp_free(r_tmp1);
1641
            /* operands of different sign, first operand and result different sign */
1642
            generate_exception(ctx, EXCP_OVERFLOW);
1643
            gen_set_label(l1);
1644
        }
1645
        opn = "dsub";
1646
        break;
1647
    case OPC_DSUBU:
1648
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1649
        opn = "dsubu";
1650
        break;
1651
#endif
1652
    case OPC_SLT:
1653
        gen_op_lt();
1654
        opn = "slt";
1655
        break;
1656
    case OPC_SLTU:
1657
        gen_op_ltu();
1658
        opn = "sltu";
1659
        break;
1660
    case OPC_AND:
1661
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1662
        opn = "and";
1663
        break;
1664
    case OPC_NOR:
1665
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1666
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1667
        opn = "nor";
1668
        break;
1669
    case OPC_OR:
1670
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1671
        opn = "or";
1672
        break;
1673
    case OPC_XOR:
1674
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1675
        opn = "xor";
1676
        break;
1677
    case OPC_MUL:
1678
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1679
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1680
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1681
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1682
        opn = "mul";
1683
        break;
1684
    case OPC_MOVN:
1685
        {
1686
            int l1 = gen_new_label();
1687

    
1688
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1689
            gen_store_gpr(cpu_T[0], rd);
1690
            gen_set_label(l1);
1691
        }
1692
        opn = "movn";
1693
        goto print;
1694
    case OPC_MOVZ:
1695
        {
1696
            int l1 = gen_new_label();
1697

    
1698
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1699
            gen_store_gpr(cpu_T[0], rd);
1700
            gen_set_label(l1);
1701
        }
1702
        opn = "movz";
1703
        goto print;
1704
    case OPC_SLLV:
1705
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1706
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1707
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1708
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1709
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1710
        opn = "sllv";
1711
        break;
1712
    case OPC_SRAV:
1713
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1714
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1715
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1716
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1717
        opn = "srav";
1718
        break;
1719
    case OPC_SRLV:
1720
        switch ((ctx->opcode >> 6) & 0x1f) {
1721
        case 0:
1722
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1723
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1724
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1725
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1726
            opn = "srlv";
1727
            break;
1728
        case 1:
1729
            /* rotrv is decoded as srlv on non-R2 CPUs */
1730
            if (env->insn_flags & ISA_MIPS32R2) {
1731
                int l1 = gen_new_label();
1732
                int l2 = gen_new_label();
1733

    
1734
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1735
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1736
                {
1737
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1738
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1739
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1740

    
1741
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1742
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1743
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1744
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1745
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1746
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1747
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1748
                    tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1749
                    tcg_temp_free(r_tmp1);
1750
                    tcg_temp_free(r_tmp2);
1751
                    tcg_temp_free(r_tmp3);
1752
                    tcg_gen_br(l2);
1753
                }
1754
                gen_set_label(l1);
1755
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1756
                gen_set_label(l2);
1757
                opn = "rotrv";
1758
            } else {
1759
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1760
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1761
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1762
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1763
                opn = "srlv";
1764
            }
1765
            break;
1766
        default:
1767
            MIPS_INVAL("invalid srlv flag");
1768
            generate_exception(ctx, EXCP_RI);
1769
            break;
1770
        }
1771
        break;
1772
#if defined(TARGET_MIPS64)
1773
    case OPC_DSLLV:
1774
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1775
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1776
        opn = "dsllv";
1777
        break;
1778
    case OPC_DSRAV:
1779
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1780
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1781
        opn = "dsrav";
1782
        break;
1783
    case OPC_DSRLV:
1784
        switch ((ctx->opcode >> 6) & 0x1f) {
1785
        case 0:
1786
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1787
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1788
            opn = "dsrlv";
1789
            break;
1790
        case 1:
1791
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1792
            if (env->insn_flags & ISA_MIPS32R2) {
1793
                int l1 = gen_new_label();
1794
                int l2 = gen_new_label();
1795

    
1796
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1797
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1798
                {
1799
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1800

    
1801
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1802
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1803
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1804
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1805
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1806
                    tcg_temp_free(r_tmp1);
1807
                    tcg_gen_br(l2);
1808
                }
1809
                gen_set_label(l1);
1810
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1811
                gen_set_label(l2);
1812
                opn = "drotrv";
1813
            } else {
1814
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1815
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1816
                opn = "dsrlv";
1817
            }
1818
            break;
1819
        default:
1820
            MIPS_INVAL("invalid dsrlv flag");
1821
            generate_exception(ctx, EXCP_RI);
1822
            break;
1823
        }
1824
        break;
1825
#endif
1826
    default:
1827
        MIPS_INVAL(opn);
1828
        generate_exception(ctx, EXCP_RI);
1829
        return;
1830
    }
1831
    gen_store_gpr(cpu_T[0], rd);
1832
 print:
1833
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1834
}
1835

    
1836
/* Arithmetic on HI/LO registers */
1837
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1838
{
1839
    const char *opn = "hilo";
1840

    
1841
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1842
        /* Treat as NOP. */
1843
        MIPS_DEBUG("NOP");
1844
        return;
1845
    }
1846
    switch (opc) {
1847
    case OPC_MFHI:
1848
        gen_load_HI(cpu_T[0], 0);
1849
        gen_store_gpr(cpu_T[0], reg);
1850
        opn = "mfhi";
1851
        break;
1852
    case OPC_MFLO:
1853
        gen_load_LO(cpu_T[0], 0);
1854
        gen_store_gpr(cpu_T[0], reg);
1855
        opn = "mflo";
1856
        break;
1857
    case OPC_MTHI:
1858
        gen_load_gpr(cpu_T[0], reg);
1859
        gen_store_HI(cpu_T[0], 0);
1860
        opn = "mthi";
1861
        break;
1862
    case OPC_MTLO:
1863
        gen_load_gpr(cpu_T[0], reg);
1864
        gen_store_LO(cpu_T[0], 0);
1865
        opn = "mtlo";
1866
        break;
1867
    default:
1868
        MIPS_INVAL(opn);
1869
        generate_exception(ctx, EXCP_RI);
1870
        return;
1871
    }
1872
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1873
}
1874

    
1875
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1876
                        int rs, int rt)
1877
{
1878
    const char *opn = "mul/div";
1879

    
1880
    gen_load_gpr(cpu_T[0], rs);
1881
    gen_load_gpr(cpu_T[1], rt);
1882
    switch (opc) {
1883
    case OPC_DIV:
1884
        {
1885
            int l1 = gen_new_label();
1886

    
1887
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1888
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1889
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1890
            {
1891
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1892
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1893
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1894

    
1895
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1896
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1897
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1898
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1899
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1900
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1901
                tcg_temp_free(r_tmp1);
1902
                tcg_temp_free(r_tmp2);
1903
                tcg_temp_free(r_tmp3);
1904
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1905
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1906
                gen_store_LO(cpu_T[0], 0);
1907
                gen_store_HI(cpu_T[1], 0);
1908
            }
1909
            gen_set_label(l1);
1910
        }
1911
        opn = "div";
1912
        break;
1913
    case OPC_DIVU:
1914
        {
1915
            int l1 = gen_new_label();
1916

    
1917
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1918
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1919
            {
1920
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1921
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1922
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1923

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

    
1953
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1954
            {
1955
                int l2 = gen_new_label();
1956

    
1957
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
1958
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
1959
                {
1960
                    tcg_gen_movi_tl(cpu_T[1], 0);
1961
                    gen_store_LO(cpu_T[0], 0);
1962
                    gen_store_HI(cpu_T[1], 0);
1963
                    tcg_gen_br(l1);
1964
                }
1965
                gen_set_label(l2);
1966
                {
1967
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1968
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1969

    
1970
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1971
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1972
                    gen_store_LO(r_tmp1, 0);
1973
                    gen_store_HI(r_tmp2, 0);
1974
                    tcg_temp_free(r_tmp1);
1975
                    tcg_temp_free(r_tmp2);
1976
                }
1977
            }
1978
            gen_set_label(l1);
1979
        }
1980
        opn = "ddiv";
1981
        break;
1982
    case OPC_DDIVU:
1983
        {
1984
            int l1 = gen_new_label();
1985

    
1986
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1987
            {
1988
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1989
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1990

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

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

    
2040
    gen_load_gpr(cpu_T[0], rs);
2041
    gen_load_gpr(cpu_T[1], rt);
2042

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

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

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

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

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

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

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

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

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

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

    
2560
/* CP0 (MMU and control) */
2561
#ifndef CONFIG_USER_ONLY
2562
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2563
{
2564
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2565

    
2566
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2567
    tcg_gen_ext_i32_tl(t, r_tmp);
2568
    tcg_temp_free(r_tmp);
2569
}
2570

    
2571
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2572
{
2573
    tcg_gen_ld_tl(t, cpu_env, off);
2574
    tcg_gen_ext32s_tl(t, t);
2575
}
2576

    
2577
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2578
{
2579
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2580

    
2581
    tcg_gen_trunc_tl_i32(r_tmp, t);
2582
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2583
    tcg_temp_free(r_tmp);
2584
}
2585

    
2586
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2587
{
2588
    tcg_gen_ext32s_tl(t, t);
2589
    tcg_gen_st_tl(t, cpu_env, off);
2590
}
2591

    
2592
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2593
{
2594
    const char *rn = "invalid";
2595

    
2596
    if (sel != 0)
2597
        check_insn(env, ctx, ISA_MIPS32);
2598

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

    
3161
die:
3162
#if defined MIPS_DEBUG_DISAS
3163
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3164
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3165
                rn, reg, sel);
3166
    }
3167
#endif
3168
    generate_exception(ctx, EXCP_RI);
3169
}
3170

    
3171
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3172
{
3173
    const char *rn = "invalid";
3174

    
3175
    if (sel != 0)
3176
        check_insn(env, ctx, ISA_MIPS32);
3177

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

    
3762
die:
3763
#if defined MIPS_DEBUG_DISAS
3764
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3765
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3766
                rn, reg, sel);
3767
    }
3768
#endif
3769
    generate_exception(ctx, EXCP_RI);
3770
}
3771

    
3772
#if defined(TARGET_MIPS64)
3773
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3774
{
3775
    const char *rn = "invalid";
3776

    
3777
    if (sel != 0)
3778
        check_insn(env, ctx, ISA_MIPS64);
3779

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

    
4330
die:
4331
#if defined MIPS_DEBUG_DISAS
4332
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4333
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4334
                rn, reg, sel);
4335
    }
4336
#endif
4337
    generate_exception(ctx, EXCP_RI);
4338
}
4339

    
4340
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4341
{
4342
    const char *rn = "invalid";
4343

    
4344
    if (sel != 0)
4345
        check_insn(env, ctx, ISA_MIPS64);
4346

    
4347
    switch (reg) {
4348
    case 0:
4349
        switch (sel) {
4350
        case 0:
4351
            tcg_gen_helper_0_0(do_mtc0_index);
4352
            rn = "Index";
4353
            break;
4354
        case 1:
4355
            check_insn(env, ctx, ASE_MT);
4356
            tcg_gen_helper_0_0(do_mtc0_mvpcontrol);
4357
            rn = "MVPControl";
4358
            break;
4359
        case 2:
4360
            check_insn(env, ctx, ASE_MT);
4361
            /* ignored */
4362
            rn = "MVPConf0";
4363
            break;
4364
        case 3:
4365
            check_insn(env, ctx, ASE_MT);
4366
            /* ignored */
4367
            rn = "MVPConf1";
4368
            break;
4369
        default:
4370
            goto die;
4371
        }
4372
        break;
4373
    case 1:
4374
        switch (sel) {
4375
        case 0:
4376
            /* ignored */
4377
            rn = "Random";
4378
            break;
4379
        case 1:
4380
            check_insn(env, ctx, ASE_MT);
4381
            tcg_gen_helper_0_0(do_mtc0_vpecontrol);
4382
            rn = "VPEControl";
4383
            break;
4384
        case 2:
4385
            check_insn(env, ctx, ASE_MT);
4386
            tcg_gen_helper_0_0(do_mtc0_vpeconf0);
4387
            rn = "VPEConf0";
4388
            break;
4389
        case 3:
4390
            check_insn(env, ctx, ASE_MT);
4391
            tcg_gen_helper_0_0(do_mtc0_vpeconf1);
4392
            rn = "VPEConf1";
4393
            break;
4394
        case 4:
4395
            check_insn(env, ctx, ASE_MT);
4396
            tcg_gen_helper_0_0(do_mtc0_yqmask);
4397
            rn = "YQMask";
4398
            break;
4399
        case 5:
4400
            check_insn(env, ctx, ASE_MT);
4401
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
4402
            rn = "VPESchedule";
4403
            break;
4404
        case 6:
4405
            check_insn(env, ctx, ASE_MT);
4406
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4407
            rn = "VPEScheFBack";
4408
            break;
4409
        case 7:
4410
            check_insn(env, ctx, ASE_MT);
4411
            tcg_gen_helper_0_0(do_mtc0_vpeopt);
4412
            rn = "VPEOpt";
4413
            break;
4414
        default:
4415
            goto die;
4416
        }
4417
        break;
4418
    case 2:
4419
        switch (sel) {
4420
        case 0:
4421
            tcg_gen_helper_0_0(do_mtc0_entrylo0);
4422
            rn = "EntryLo0";
4423
            break;
4424
        case 1:
4425
            check_insn(env, ctx, ASE_MT);
4426
            tcg_gen_helper_0_0(do_mtc0_tcstatus);
4427
            rn = "TCStatus";
4428
            break;
4429
        case 2:
4430
            check_insn(env, ctx, ASE_MT);
4431
            tcg_gen_helper_0_0(do_mtc0_tcbind);
4432
            rn = "TCBind";
4433
            break;
4434
        case 3:
4435
            check_insn(env, ctx, ASE_MT);
4436
            tcg_gen_helper_0_0(do_mtc0_tcrestart);
4437
            rn = "TCRestart";
4438
            break;
4439
        case 4:
4440
            check_insn(env, ctx, ASE_MT);
4441
            tcg_gen_helper_0_0(do_mtc0_tchalt);
4442
            rn = "TCHalt";
4443
            break;
4444
        case 5:
4445
            check_insn(env, ctx, ASE_MT);
4446
            tcg_gen_helper_0_0(do_mtc0_tccontext);
4447
            rn = "TCContext";
4448
            break;
4449
        case 6:
4450
            check_insn(env, ctx, ASE_MT);
4451
            tcg_gen_helper_0_0(do_mtc0_tcschedule);
4452
            rn = "TCSchedule";
4453
            break;
4454
        case 7:
4455
            check_insn(env, ctx, ASE_MT);
4456
            tcg_gen_helper_0_0(do_mtc0_tcschefback);
4457
            rn = "TCScheFBack";
4458
            break;
4459
        default:
4460
            goto die;
4461
        }
4462
        break;
4463
    case 3:
4464
        switch (sel) {
4465
        case 0:
4466
            tcg_gen_helper_0_0(do_mtc0_entrylo1);
4467
            rn = "EntryLo1";
4468
            break;
4469
        default:
4470
            goto die;
4471
        }
4472
        break;
4473
    case 4:
4474
        switch (sel) {
4475
        case 0:
4476
            tcg_gen_helper_0_0(do_mtc0_context);
4477
            rn = "Context";
4478
            break;
4479
        case 1:
4480
//           tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */
4481
            rn = "ContextConfig";
4482
//           break;
4483
        default:
4484
            goto die;
4485
        }
4486
        break;
4487
    case 5:
4488
        switch (sel) {
4489
        case 0:
4490
            tcg_gen_helper_0_0(do_mtc0_pagemask);
4491
            rn = "PageMask";
4492
            break;
4493
        case 1:
4494
            check_insn(env, ctx, ISA_MIPS32R2);
4495
            tcg_gen_helper_0_0(do_mtc0_pagegrain);
4496
            rn = "PageGrain";
4497
            break;
4498
        default:
4499
            goto die;
4500
        }
4501
        break;
4502
    case 6:
4503
        switch (sel) {
4504
        case 0:
4505
            tcg_gen_helper_0_0(do_mtc0_wired);
4506
            rn = "Wired";
4507
            break;
4508
        case 1:
4509
            check_insn(env, ctx, ISA_MIPS32R2);
4510
            tcg_gen_helper_0_0(do_mtc0_srsconf0);
4511
            rn = "SRSConf0";
4512
            break;
4513
        case 2:
4514
            check_insn(env, ctx, ISA_MIPS32R2);
4515
            tcg_gen_helper_0_0(do_mtc0_srsconf1);
4516
            rn = "SRSConf1";
4517
            break;
4518
        case 3:
4519
            check_insn(env, ctx, ISA_MIPS32R2);
4520
            tcg_gen_helper_0_0(do_mtc0_srsconf2);
4521
            rn = "SRSConf2";
4522
            break;
4523
        case 4:
4524
            check_insn(env, ctx, ISA_MIPS32R2);
4525
            tcg_gen_helper_0_0(do_mtc0_srsconf3);
4526
            rn = "SRSConf3";
4527
            break;
4528
        case 5:
4529
            check_insn(env, ctx, ISA_MIPS32R2);
4530
            tcg_gen_helper_0_0(do_mtc0_srsconf4);
4531
            rn = "SRSConf4";
4532
            break;
4533
        default:
4534
            goto die;
4535
        }
4536
        break;
4537
    case 7:
4538
        switch (sel) {
4539
        case 0:
4540
            check_insn(env, ctx, ISA_MIPS32R2);
4541
            tcg_gen_helper_0_0(do_mtc0_hwrena);
4542
            rn = "HWREna";
4543
            break;
4544
        default:
4545
            goto die;
4546
        }
4547
        break;
4548
    case 8:
4549
        /* ignored */
4550
        rn = "BadVAddr";
4551
        break;
4552
    case 9:
4553
        switch (sel) {
4554
        case 0:
4555
            tcg_gen_helper_0_0(do_mtc0_count);
4556
            rn = "Count";
4557
            break;
4558
        /* 6,7 are implementation dependent */
4559
        default:
4560
            goto die;
4561
        }
4562
        /* Stop translation as we may have switched the execution mode */
4563
        ctx->bstate = BS_STOP;
4564
        break;
4565
    case 10:
4566
        switch (sel) {
4567
        case 0:
4568
            tcg_gen_helper_0_0(do_mtc0_entryhi);
4569
            rn = "EntryHi";
4570
            break;
4571
        default:
4572
            goto die;
4573
        }
4574
        break;
4575
    case 11:
4576
        switch (sel) {
4577
        case 0:
4578
            tcg_gen_helper_0_0(do_mtc0_compare);
4579
            rn = "Compare";
4580
            break;
4581
        /* 6,7 are implementation dependent */
4582
        default:
4583
            goto die;
4584
        }
4585
        /* Stop translation as we may have switched the execution mode */
4586
        ctx->bstate = BS_STOP;
4587
        break;
4588
    case 12:
4589
        switch (sel) {
4590
        case 0:
4591
            tcg_gen_helper_0_0(do_mtc0_status);
4592
            /* BS_STOP isn't good enough here, hflags may have changed. */
4593
            gen_save_pc(ctx->pc + 4);
4594
            ctx->bstate = BS_EXCP;
4595
            rn = "Status";
4596
            break;
4597
        case 1:
4598
            check_insn(env, ctx, ISA_MIPS32R2);
4599
            tcg_gen_helper_0_0(do_mtc0_intctl);
4600
            /* Stop translation as we may have switched the execution mode */
4601
            ctx->bstate = BS_STOP;
4602
            rn = "IntCtl";
4603
            break;
4604
        case 2:
4605
            check_insn(env, ctx, ISA_MIPS32R2);
4606
            tcg_gen_helper_0_0(do_mtc0_srsctl);
4607
            /* Stop translation as we may have switched the execution mode */
4608
            ctx->bstate = BS_STOP;
4609
            rn = "SRSCtl";
4610
            break;
4611
        case 3:
4612
            check_insn(env, ctx, ISA_MIPS32R2);
4613
            gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4614
            /* Stop translation as we may have switched the execution mode */
4615
            ctx->bstate = BS_STOP;
4616
            rn = "SRSMap";
4617
            break;
4618
        default:
4619
            goto die;
4620
        }
4621
        break;
4622
    case 13:
4623
        switch (sel) {
4624
        case 0:
4625
            tcg_gen_helper_0_0(do_mtc0_cause);
4626
            rn = "Cause";
4627
            break;
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 14:
4635
        switch (sel) {
4636
        case 0:
4637
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4638
            rn = "EPC";
4639
            break;
4640
        default:
4641
            goto die;
4642
        }
4643
        break;
4644
    case 15:
4645
        switch (sel) {
4646
        case 0:
4647
            /* ignored */
4648
            rn = "PRid";
4649
            break;
4650
        case 1:
4651
            check_insn(env, ctx, ISA_MIPS32R2);
4652
            tcg_gen_helper_0_0(do_mtc0_ebase);
4653
            rn = "EBase";
4654
            break;
4655
        default:
4656
            goto die;
4657
        }
4658
        break;
4659
    case 16:
4660
        switch (sel) {
4661
        case 0:
4662
            tcg_gen_helper_0_0(do_mtc0_config0);
4663
            rn = "Config";
4664
            /* Stop translation as we may have switched the execution mode */
4665
            ctx->bstate = BS_STOP;
4666
            break;
4667
        case 1:
4668
            /* ignored */
4669
            rn = "Config1";
4670
            break;
4671
        case 2:
4672
            tcg_gen_helper_0_0(do_mtc0_config2);
4673
            rn = "Config2";
4674
            /* Stop translation as we may have switched the execution mode */
4675
            ctx->bstate = BS_STOP;
4676
            break;
4677
        case 3:
4678
            /* ignored */
4679
            rn = "Config3";
4680
            break;
4681
        /* 6,7 are implementation dependent */
4682
        default:
4683
            rn = "Invalid config selector";
4684
            goto die;
4685
        }
4686
        break;
4687
    case 17:
4688
        switch (sel) {
4689
        case 0:
4690
            /* ignored */
4691
            rn = "LLAddr";
4692
            break;
4693
        default:
4694
            goto die;
4695
        }
4696
        break;
4697
    case 18:
4698
        switch (sel) {
4699
        case 0 ... 7:
4700
            tcg_gen_helper_0_1i(do_mtc0_watchlo, sel);
4701
            rn = "WatchLo";
4702
            break;
4703
        default:
4704
            goto die;
4705
        }
4706
        break;
4707
    case 19:
4708
        switch (sel) {
4709
        case 0 ... 7:
4710
            tcg_gen_helper_0_1i(do_mtc0_watchhi, sel);
4711
            rn = "WatchHi";
4712
            break;
4713
        default:
4714
            goto die;
4715
        }
4716
        break;
4717
    case 20:
4718
        switch (sel) {
4719
        case 0:
4720
            check_insn(env, ctx, ISA_MIPS3);
4721
            tcg_gen_helper_0_0(do_mtc0_xcontext);
4722
            rn = "XContext";
4723
            break;
4724
        default:
4725
            goto die;
4726
        }
4727
        break;
4728
    case 21:
4729
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4730
        switch (sel) {
4731
        case 0:
4732
            tcg_gen_helper_0_0(do_mtc0_framemask);
4733
            rn = "Framemask";
4734
            break;
4735
        default:
4736
            goto die;
4737
        }
4738
        break;
4739
    case 22:
4740
        /* ignored */
4741
        rn = "Diagnostic"; /* implementation dependent */
4742
        break;
4743
    case 23:
4744
        switch (sel) {
4745
        case 0:
4746
            tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */
4747
            /* BS_STOP isn't good enough here, hflags may have changed. */
4748
            gen_save_pc(ctx->pc + 4);
4749
            ctx->bstate = BS_EXCP;
4750
            rn = "Debug";
4751
            break;
4752
        case 1:
4753
//            tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */
4754
            /* Stop translation as we may have switched the execution mode */
4755
            ctx->bstate = BS_STOP;
4756
            rn = "TraceControl";
4757
//            break;
4758
        case 2:
4759
//            tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */
4760
            /* Stop translation as we may have switched the execution mode */
4761
            ctx->bstate = BS_STOP;
4762
            rn = "TraceControl2";
4763
//            break;
4764
        case 3:
4765
//            tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */
4766
            /* Stop translation as we may have switched the execution mode */
4767
            ctx->bstate = BS_STOP;
4768
            rn = "UserTraceData";
4769
//            break;
4770
        case 4:
4771
//            tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */
4772
            /* Stop translation as we may have switched the execution mode */
4773
            ctx->bstate = BS_STOP;
4774
            rn = "TraceBPC";
4775
//            break;
4776
        default:
4777
            goto die;
4778
        }
4779
        break;
4780
    case 24:
4781
        switch (sel) {
4782
        case 0:
4783
            /* EJTAG support */
4784
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4785
            rn = "DEPC";
4786
            break;
4787
        default:
4788
            goto die;
4789
        }
4790
        break;
4791
    case 25:
4792
        switch (sel) {
4793
        case 0:
4794
            tcg_gen_helper_0_0(do_mtc0_performance0);
4795
            rn = "Performance0";
4796
            break;
4797
        case 1:
4798
//            tcg_gen_helper_0_0(do_mtc0_performance1);
4799
            rn = "Performance1";
4800
//            break;
4801
        case 2:
4802
//            tcg_gen_helper_0_0(do_mtc0_performance2);
4803
            rn = "Performance2";
4804
//            break;
4805
        case 3:
4806
//            tcg_gen_helper_0_0(do_mtc0_performance3);
4807
            rn = "Performance3";
4808
//            break;
4809
        case 4:
4810
//            tcg_gen_helper_0_0(do_mtc0_performance4);
4811
            rn = "Performance4";
4812
//            break;
4813
        case 5:
4814
//            tcg_gen_helper_0_0(do_mtc0_performance5);
4815
            rn = "Performance5";
4816
//            break;
4817
        case 6:
4818
//            tcg_gen_helper_0_0(do_mtc0_performance6);
4819
            rn = "Performance6";
4820
//            break;
4821
        case 7:
4822
//            tcg_gen_helper_0_0(do_mtc0_performance7);
4823
            rn = "Performance7";
4824
//            break;
4825
        default:
4826
            goto die;
4827
        }
4828
        break;
4829
    case 26:
4830
        /* ignored */
4831
        rn = "ECC";
4832
        break;
4833
    case 27:
4834
        switch (sel) {
4835
        case 0 ... 3:
4836
            /* ignored */
4837
            rn = "CacheErr";
4838
            break;
4839
        default:
4840
            goto die;
4841
        }
4842
        break;
4843
    case 28:
4844
        switch (sel) {
4845
        case 0:
4846
        case 2:
4847
        case 4:
4848
        case 6:
4849
            tcg_gen_helper_0_0(do_mtc0_taglo);
4850
            rn = "TagLo";
4851
            break;
4852
        case 1:
4853
        case 3:
4854
        case 5:
4855
        case 7:
4856
            tcg_gen_helper_0_0(do_mtc0_datalo);
4857
            rn = "DataLo";
4858
            break;
4859
        default:
4860
            goto die;
4861
        }
4862
        break;
4863
    case 29:
4864
        switch (sel) {
4865
        case 0:
4866
        case 2:
4867
        case 4:
4868
        case 6:
4869
            tcg_gen_helper_0_0(do_mtc0_taghi);
4870
            rn = "TagHi";
4871
            break;
4872
        case 1:
4873
        case 3:
4874
        case 5:
4875
        case 7:
4876
            tcg_gen_helper_0_0(do_mtc0_datahi);
4877
            rn = "DataHi";
4878
            break;
4879
        default:
4880
            rn = "invalid sel";
4881
            goto die;
4882
        }
4883
        break;
4884
    case 30:
4885
        switch (sel) {
4886
        case 0:
4887
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4888
            rn = "ErrorEPC";
4889
            break;
4890
        default:
4891
            goto die;
4892
        }
4893
        break;
4894
    case 31:
4895
        switch (sel) {
4896
        case 0:
4897
            /* EJTAG support */
4898
            gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4899
            rn = "DESAVE";
4900
            break;
4901
        default:
4902
            goto die;
4903
        }
4904
        /* Stop translation as we may have switched the execution mode */
4905
        ctx->bstate = BS_STOP;
4906
        break;
4907
    default:
4908
        goto die;
4909
    }
4910
#if defined MIPS_DEBUG_DISAS
4911
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4912
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4913
                rn, reg, sel);
4914
    }
4915
#endif
4916
    return;
4917

    
4918
die:
4919
#if defined MIPS_DEBUG_DISAS
4920
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4921
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4922
                rn, reg, sel);
4923
    }
4924
#endif
4925
    generate_exception(ctx, EXCP_RI);
4926
}
4927
#endif /* TARGET_MIPS64 */
4928

    
4929
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4930
                     int u, int sel, int h)
4931
{
4932
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4933

    
4934
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4935
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4936
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4937
        tcg_gen_movi_tl(cpu_T[0], -1);
4938
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4939
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4940
        tcg_gen_movi_tl(cpu_T[0], -1);
4941
    else if (u == 0) {
4942
        switch (rt) {
4943
        case 2:
4944
            switch (sel) {
4945
            case 1:
4946
                tcg_gen_helper_0_0(do_mftc0_tcstatus);
4947
                break;
4948
            case 2:
4949
                tcg_gen_helper_0_0(do_mftc0_tcbind);
4950
                break;
4951
            case 3:
4952
                tcg_gen_helper_0_0(do_mftc0_tcrestart);
4953
                break;
4954
            case 4:
4955
                tcg_gen_helper_0_0(do_mftc0_tchalt);
4956
                break;
4957
            case 5:
4958
                tcg_gen_helper_0_0(do_mftc0_tccontext);
4959
                break;
4960
            case 6:
4961
                tcg_gen_helper_0_0(do_mftc0_tcschedule);
4962
                break;
4963
            case 7:
4964
                tcg_gen_helper_0_0(do_mftc0_tcschefback);
4965
                break;
4966
            default:
4967
                gen_mfc0(env, ctx, rt, sel);
4968
                break;
4969
            }
4970
            break;
4971
        case 10:
4972
            switch (sel) {
4973
            case 0:
4974
                tcg_gen_helper_0_0(do_mftc0_entryhi);
4975
                break;
4976
            default:
4977
                gen_mfc0(env, ctx, rt, sel);
4978
                break;
4979
            }
4980
        case 12:
4981
            switch (sel) {
4982
            case 0:
4983
                tcg_gen_helper_0_0(do_mftc0_status);
4984
                break;
4985
            default:
4986
                gen_mfc0(env, ctx, rt, sel);
4987
                break;
4988
            }
4989
        case 23:
4990
            switch (sel) {
4991
            case 0:
4992
                tcg_gen_helper_0_0(do_mftc0_debug);
4993
                break;
4994
            default:
4995
                gen_mfc0(env, ctx, rt, sel);
4996
                break;
4997
            }
4998
            break;
4999
        default:
5000
            gen_mfc0(env, ctx, rt, sel);
5001
        }
5002
    } else switch (sel) {
5003
    /* GPR registers. */
5004
    case 0:
5005
        tcg_gen_helper_0_1i(do_mftgpr, rt);
5006
        break;
5007
    /* Auxiliary CPU registers */
5008
    case 1:
5009
        switch (rt) {
5010
        case 0:
5011
            tcg_gen_helper_0_1i(do_mftlo, 0);
5012
            break;
5013
        case 1:
5014
            tcg_gen_helper_0_1i(do_mfthi, 0);
5015
            break;
5016
        case 2:
5017
            tcg_gen_helper_0_1i(do_mftacx, 0);
5018
            break;
5019
        case 4:
5020
            tcg_gen_helper_0_1i(do_mftlo, 1);
5021
            break;
5022
        case 5:
5023
            tcg_gen_helper_0_1i(do_mfthi, 1);
5024
            break;
5025
        case 6:
5026
            tcg_gen_helper_0_1i(do_mftacx, 1);
5027
            break;
5028
        case 8:
5029
            tcg_gen_helper_0_1i(do_mftlo, 2);
5030
            break;
5031
        case 9:
5032
            tcg_gen_helper_0_1i(do_mfthi, 2);
5033
            break;
5034
        case 10:
5035
            tcg_gen_helper_0_1i(do_mftacx, 2);
5036
            break;
5037
        case 12:
5038
            tcg_gen_helper_0_1i(do_mftlo, 3);
5039
            break;
5040
        case 13:
5041
            tcg_gen_helper_0_1i(do_mfthi, 3);
5042
            break;
5043
        case 14:
5044
            tcg_gen_helper_0_1i(do_mftacx, 3);
5045
            break;
5046
        case 16:
5047
            tcg_gen_helper_0_0(do_mftdsp);
5048
            break;
5049
        default:
5050
            goto die;
5051
        }
5052
        break;
5053
    /* Floating point (COP1). */
5054
    case 2:
5055
        /* XXX: For now we support only a single FPU context. */
5056
        if (h == 0) {
5057
            gen_load_fpr32(fpu32_T[0], rt);
5058
            tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]);
5059
        } else {
5060
            gen_load_fpr32h(fpu32h_T[0], rt);
5061
            tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]);
5062
        }
5063
        break;
5064
    case 3:
5065
        /* XXX: For now we support only a single FPU context. */
5066
        tcg_gen_helper_0_1i(do_cfc1, rt);
5067
        break;
5068
    /* COP2: Not implemented. */
5069
    case 4:
5070
    case 5:
5071
        /* fall through */
5072
    default:
5073
        goto die;
5074
    }
5075
#if defined MIPS_DEBUG_DISAS
5076
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5077
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5078
                rt, u, sel, h);
5079
    }
5080
#endif
5081
    return;
5082

    
5083
die:
5084
#if defined MIPS_DEBUG_DISAS
5085
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5086
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5087
                rt, u, sel, h);
5088
    }
5089
#endif
5090
    generate_exception(ctx, EXCP_RI);
5091
}
5092

    
5093
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5094
                     int u, int sel, int h)
5095
{
5096
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5097

    
5098
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5099
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5100
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5101
        /* NOP */ ;
5102
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5103
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5104
        /* NOP */ ;
5105
    else if (u == 0) {
5106
        switch (rd) {
5107
        case 2:
5108
            switch (sel) {
5109
            case 1:
5110
                tcg_gen_helper_0_0(do_mttc0_tcstatus);
5111
                break;
5112
            case 2:
5113
                tcg_gen_helper_0_0(do_mttc0_tcbind);
5114
                break;
5115
            case 3:
5116
                tcg_gen_helper_0_0(do_mttc0_tcrestart);
5117
                break;
5118
            case 4:
5119
                tcg_gen_helper_0_0(do_mttc0_tchalt);
5120
                break;
5121
            case 5:
5122
                tcg_gen_helper_0_0(do_mttc0_tccontext);
5123
                break;
5124
            case 6:
5125
                tcg_gen_helper_0_0(do_mttc0_tcschedule);
5126
                break;
5127
            case 7:
5128
                tcg_gen_helper_0_0(do_mttc0_tcschefback);
5129
                break;
5130
            default:
5131
                gen_mtc0(env, ctx, rd, sel);
5132
                break;
5133
            }
5134
            break;
5135
        case 10:
5136
            switch (sel) {
5137
            case 0:
5138
                tcg_gen_helper_0_0(do_mttc0_entryhi);
5139
                break;
5140
            default:
5141
                gen_mtc0(env, ctx, rd, sel);
5142
                break;
5143
            }
5144
        case 12:
5145
            switch (sel) {
5146
            case 0:
5147
                tcg_gen_helper_0_0(do_mttc0_status);
5148
                break;
5149
            default:
5150
                gen_mtc0(env, ctx, rd, sel);
5151
                break;
5152
            }
5153
        case 23:
5154
            switch (sel) {
5155
            case 0:
5156
                tcg_gen_helper_0_0(do_mttc0_debug);
5157
                break;
5158
            default:
5159
                gen_mtc0(env, ctx, rd, sel);
5160
                break;
5161
            }
5162
            break;
5163
        default:
5164
            gen_mtc0(env, ctx, rd, sel);
5165
        }
5166
    } else switch (sel) {
5167
    /* GPR registers. */
5168
    case 0:
5169
        tcg_gen_helper_0_1i(do_mttgpr, rd);
5170
        break;
5171
    /* Auxiliary CPU registers */
5172
    case 1:
5173
        switch (rd) {
5174
        case 0:
5175
            tcg_gen_helper_0_1i(do_mttlo, 0);
5176
            break;
5177
        case 1:
5178
            tcg_gen_helper_0_1i(do_mtthi, 0);
5179
            break;
5180
        case 2:
5181
            tcg_gen_helper_0_1i(do_mttacx, 0);
5182
            break;
5183
        case 4:
5184
            tcg_gen_helper_0_1i(do_mttlo, 1);
5185
            break;
5186
        case 5:
5187
            tcg_gen_helper_0_1i(do_mtthi, 1);
5188
            break;
5189
        case 6:
5190
            tcg_gen_helper_0_1i(do_mttacx, 1);
5191
            break;
5192
        case 8:
5193
            tcg_gen_helper_0_1i(do_mttlo, 2);
5194
            break;
5195
        case 9:
5196
            tcg_gen_helper_0_1i(do_mtthi, 2);
5197
            break;
5198
        case 10:
5199
            tcg_gen_helper_0_1i(do_mttacx, 2);
5200
            break;
5201
        case 12:
5202
            tcg_gen_helper_0_1i(do_mttlo, 3);
5203
            break;
5204
        case 13:
5205
            tcg_gen_helper_0_1i(do_mtthi, 3);
5206
            break;
5207
        case 14:
5208
            tcg_gen_helper_0_1i(do_mttacx, 3);
5209
            break;
5210
        case 16:
5211
            tcg_gen_helper_0_0(do_mttdsp);
5212
            break;
5213
        default:
5214
            goto die;
5215
        }
5216
        break;
5217
    /* Floating point (COP1). */
5218
    case 2:
5219
        /* XXX: For now we support only a single FPU context. */
5220
        if (h == 0) {
5221
            tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]);
5222
            gen_store_fpr32(fpu32_T[0], rd);
5223
        } else {
5224
            tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]);
5225
            gen_store_fpr32h(fpu32h_T[0], rd);
5226
        }
5227
        break;
5228
    case 3:
5229
        /* XXX: For now we support only a single FPU context. */
5230
        tcg_gen_helper_0_1i(do_ctc1, rd);
5231
        break;
5232
    /* COP2: Not implemented. */
5233
    case 4:
5234
    case 5:
5235
        /* fall through */
5236
    default:
5237
        goto die;
5238
    }
5239
#if defined MIPS_DEBUG_DISAS
5240
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5241
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5242
                rd, u, sel, h);
5243
    }
5244
#endif
5245
    return;
5246

    
5247
die:
5248
#if defined MIPS_DEBUG_DISAS
5249
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5250
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5251
                rd, u, sel, h);
5252
    }
5253
#endif
5254
    generate_exception(ctx, EXCP_RI);
5255
}
5256

    
5257
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5258
{
5259
    const char *opn = "ldst";
5260

    
5261
    switch (opc) {
5262
    case OPC_MFC0:
5263
        if (rt == 0) {
5264
            /* Treat as NOP. */
5265
            return;
5266
        }
5267
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5268
        gen_store_gpr(cpu_T[0], rt);
5269
        opn = "mfc0";
5270
        break;
5271
    case OPC_MTC0:
5272
        gen_load_gpr(cpu_T[0], rt);
5273
        save_cpu_state(ctx, 1);
5274
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5275
        opn = "mtc0";
5276
        break;
5277
#if defined(TARGET_MIPS64)
5278
    case OPC_DMFC0:
5279
        check_insn(env, ctx, ISA_MIPS3);
5280
        if (rt == 0) {
5281
            /* Treat as NOP. */
5282
            return;
5283
        }
5284
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5285
        gen_store_gpr(cpu_T[0], rt);
5286
        opn = "dmfc0";
5287
        break;
5288
    case OPC_DMTC0:
5289
        check_insn(env, ctx, ISA_MIPS3);
5290
        gen_load_gpr(cpu_T[0], rt);
5291
        save_cpu_state(ctx, 1);
5292
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5293
        opn = "dmtc0";
5294
        break;
5295
#endif
5296
    case OPC_MFTR:
5297
        check_insn(env, ctx, ASE_MT);
5298
        if (rd == 0) {
5299
            /* Treat as NOP. */
5300
            return;
5301
        }
5302
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5303
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5304
        gen_store_gpr(cpu_T[0], rd);
5305
        opn = "mftr";
5306
        break;
5307
    case OPC_MTTR:
5308
        check_insn(env, ctx, ASE_MT);
5309
        gen_load_gpr(cpu_T[0], rt);
5310
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5311
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5312
        opn = "mttr";
5313
        break;
5314
    case OPC_TLBWI:
5315
        opn = "tlbwi";
5316
        if (!env->tlb->do_tlbwi)
5317
            goto die;
5318
        gen_op_tlbwi();
5319
        break;
5320
    case OPC_TLBWR:
5321
        opn = "tlbwr";
5322
        if (!env->tlb->do_tlbwr)
5323
            goto die;
5324
        gen_op_tlbwr();
5325
        break;
5326
    case OPC_TLBP:
5327
        opn = "tlbp";
5328
        if (!env->tlb->do_tlbp)
5329
            goto die;
5330
        gen_op_tlbp();
5331
        break;
5332
    case OPC_TLBR:
5333
        opn = "tlbr";
5334
        if (!env->tlb->do_tlbr)
5335
            goto die;
5336
        gen_op_tlbr();
5337
        break;
5338
    case OPC_ERET:
5339
        opn = "eret";
5340
        check_insn(env, ctx, ISA_MIPS2);
5341
        save_cpu_state(ctx, 1);
5342
        gen_op_eret();
5343
        ctx->bstate = BS_EXCP;
5344
        break;
5345
    case OPC_DERET:
5346
        opn = "deret";
5347
        check_insn(env, ctx, ISA_MIPS32);
5348
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5349
            MIPS_INVAL(opn);
5350
            generate_exception(ctx, EXCP_RI);
5351
        } else {
5352
            save_cpu_state(ctx, 1);
5353
            gen_op_deret();
5354
            ctx->bstate = BS_EXCP;
5355
        }
5356
        break;
5357
    case OPC_WAIT:
5358
        opn = "wait";
5359
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5360
        /* If we get an exception, we want to restart at next instruction */
5361
        ctx->pc += 4;
5362
        save_cpu_state(ctx, 1);
5363
        ctx->pc -= 4;
5364
        gen_op_wait();
5365
        ctx->bstate = BS_EXCP;
5366
        break;
5367
    default:
5368
 die:
5369
        MIPS_INVAL(opn);
5370
        generate_exception(ctx, EXCP_RI);
5371
        return;
5372
    }
5373
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5374
}
5375
#endif /* !CONFIG_USER_ONLY */
5376

    
5377
/* CP1 Branches (before delay slot) */
5378
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5379
                                 int32_t cc, int32_t offset)
5380
{
5381
    target_ulong btarget;
5382
    const char *opn = "cp1 cond branch";
5383

    
5384
    if (cc != 0)
5385
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5386

    
5387
    btarget = ctx->pc + 4 + offset;
5388

    
5389
    switch (op) {
5390
    case OPC_BC1F:
5391
        gen_op_bc1f(cc);
5392
        opn = "bc1f";
5393
        goto not_likely;
5394
    case OPC_BC1FL:
5395
        gen_op_bc1f(cc);
5396
        opn = "bc1fl";
5397
        goto likely;
5398
    case OPC_BC1T:
5399
        gen_op_bc1t(cc);
5400
        opn = "bc1t";
5401
        goto not_likely;
5402
    case OPC_BC1TL:
5403
        gen_op_bc1t(cc);
5404
        opn = "bc1tl";
5405
    likely:
5406
        ctx->hflags |= MIPS_HFLAG_BL;
5407
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5408
        break;
5409
    case OPC_BC1FANY2:
5410
        gen_op_bc1any2f(cc);
5411
        opn = "bc1any2f";
5412
        goto not_likely;
5413
    case OPC_BC1TANY2:
5414
        gen_op_bc1any2t(cc);
5415
        opn = "bc1any2t";
5416
        goto not_likely;
5417
    case OPC_BC1FANY4:
5418
        gen_op_bc1any4f(cc);
5419
        opn = "bc1any4f";
5420
        goto not_likely;
5421
    case OPC_BC1TANY4:
5422
        gen_op_bc1any4t(cc);
5423
        opn = "bc1any4t";
5424
    not_likely:
5425
        ctx->hflags |= MIPS_HFLAG_BC;
5426
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5427
        break;
5428
    default:
5429
        MIPS_INVAL(opn);
5430
        generate_exception (ctx, EXCP_RI);
5431
        return;
5432
    }
5433
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5434
               ctx->hflags, btarget);
5435
    ctx->btarget = btarget;
5436
}
5437

    
5438
/* Coprocessor 1 (FPU) */
5439

    
5440
#define FOP(func, fmt) (((fmt) << 21) | (func))
5441

    
5442
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5443
{
5444
    const char *opn = "cp1 move";
5445

    
5446
    switch (opc) {
5447
    case OPC_MFC1:
5448
        gen_load_fpr32(fpu32_T[0], fs);
5449
        tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]);
5450
        gen_store_gpr(cpu_T[0], rt);
5451
        opn = "mfc1";
5452
        break;
5453
    case OPC_MTC1:
5454
        gen_load_gpr(cpu_T[0], rt);
5455
        tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]);
5456
        gen_store_fpr32(fpu32_T[0], fs);
5457
        opn = "mtc1";
5458
        break;
5459
    case OPC_CFC1:
5460
        tcg_gen_helper_0_1i(do_cfc1, fs);
5461
        gen_store_gpr(cpu_T[0], rt);
5462
        opn = "cfc1";
5463
        break;
5464
    case OPC_CTC1:
5465
        gen_load_gpr(cpu_T[0], rt);
5466
        tcg_gen_helper_0_1i(do_ctc1, fs);
5467
        opn = "ctc1";
5468
        break;
5469
    case OPC_DMFC1:
5470
        gen_load_fpr64(ctx, fpu64_T[0], fs);
5471
        tcg_gen_mov_tl(cpu_T[0], fpu64_T[0]);
5472
        gen_store_gpr(cpu_T[0], rt);
5473
        opn = "dmfc1";
5474
        break;
5475
    case OPC_DMTC1:
5476
        gen_load_gpr(cpu_T[0], rt);
5477
        tcg_gen_mov_tl(fpu64_T[0], cpu_T[0]);
5478
        gen_store_fpr64(ctx, fpu64_T[0], fs);
5479
        opn = "dmtc1";
5480
        break;
5481
    case OPC_MFHC1:
5482
        gen_load_fpr32h(fpu32h_T[0], fs);
5483
        tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]);
5484
        gen_store_gpr(cpu_T[0], rt);
5485
        opn = "mfhc1";
5486
        break;
5487
    case OPC_MTHC1:
5488
        gen_load_gpr(cpu_T[0], rt);
5489
        tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]);
5490
        gen_store_fpr32h(fpu32h_T[0], fs);
5491
        opn = "mthc1";
5492
        break;
5493
    default:
5494
        MIPS_INVAL(opn);
5495
        generate_exception (ctx, EXCP_RI);
5496
        return;
5497
    }
5498
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5499
}
5500

    
5501
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5502
{
5503
    int l1 = gen_new_label();
5504
    uint32_t ccbit;
5505
    TCGCond cond;
5506

    
5507
    if (cc)
5508
        ccbit = 1 << (24 + cc);
5509
    else
5510
        ccbit = 1 << 23;
5511
    if (tf)
5512
        cond = TCG_COND_EQ;
5513
    else
5514
        cond = TCG_COND_NE;
5515

    
5516
    gen_load_gpr(cpu_T[0], rd);
5517
    gen_load_gpr(cpu_T[1], rs);
5518
    {
5519
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5520
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
5521

    
5522
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5523
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5524
        tcg_temp_free(r_ptr);
5525
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5526
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5527
        tcg_temp_free(r_tmp);
5528
    }
5529
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5530

    
5531
    gen_set_label(l1);
5532
    gen_store_gpr(cpu_T[0], rd);
5533
}
5534

    
5535
#define GEN_MOVCF(fmt)                                                \
5536
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5537
{                                                                     \
5538
    uint32_t ccbit;                                                   \
5539
                                                                      \
5540
    if (cc) {                                                         \
5541
        ccbit = 1 << (24 + cc);                                       \
5542
    } else                                                            \
5543
        ccbit = 1 << 23;                                              \
5544
    if (!tf)                                                          \
5545
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5546
    else                                                              \
5547
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5548
}
5549
GEN_MOVCF(d);
5550
GEN_MOVCF(s);
5551
#undef GEN_MOVCF
5552

    
5553
static void gen_farith (DisasContext *ctx, uint32_t op1,
5554
                        int ft, int fs, int fd, int cc)
5555
{
5556
    const char *opn = "farith";
5557
    const char *condnames[] = {
5558
            "c.f",
5559
            "c.un",
5560
            "c.eq",
5561
            "c.ueq",
5562
            "c.olt",
5563
            "c.ult",
5564
            "c.ole",
5565
            "c.ule",
5566
            "c.sf",
5567
            "c.ngle",
5568
            "c.seq",
5569
            "c.ngl",
5570
            "c.lt",
5571
            "c.nge",
5572
            "c.le",
5573
            "c.ngt",
5574
    };
5575
    const char *condnames_abs[] = {
5576
            "cabs.f",
5577
            "cabs.un",
5578
            "cabs.eq",
5579
            "cabs.ueq",
5580
            "cabs.olt",
5581
            "cabs.ult",
5582
            "cabs.ole",
5583
            "cabs.ule",
5584
            "cabs.sf",
5585
            "cabs.ngle",
5586
            "cabs.seq",
5587
            "cabs.ngl",
5588
            "cabs.lt",
5589
            "cabs.nge",
5590
            "cabs.le",
5591
            "cabs.ngt",
5592
    };
5593
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5594
    uint32_t func = ctx->opcode & 0x3f;
5595

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

    
6365
/* Coprocessor 3 (FPU) */
6366
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6367
                           int fd, int fs, int base, int index)
6368
{
6369
    const char *opn = "extended float load/store";
6370
    int store = 0;
6371

    
6372
    if (base == 0) {
6373
        gen_load_gpr(cpu_T[0], index);
6374
    } else if (index == 0) {
6375
        gen_load_gpr(cpu_T[0], base);
6376
    } else {
6377
        gen_load_gpr(cpu_T[0], base);
6378
        gen_load_gpr(cpu_T[1], index);
6379
        gen_op_addr_add();
6380
    }
6381
    /* Don't do NOP if destination is zero: we must perform the actual
6382
       memory access. */
6383
    switch (opc) {
6384
    case OPC_LWXC1:
6385
        check_cop1x(ctx);
6386
        tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx);
6387
        gen_store_fpr32(fpu32_T[0], fd);
6388
        opn = "lwxc1";
6389
        break;
6390
    case OPC_LDXC1:
6391
        check_cop1x(ctx);
6392
        check_cp1_registers(ctx, fd);
6393
        tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6394
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6395
        opn = "ldxc1";
6396
        break;
6397
    case OPC_LUXC1:
6398
        check_cp1_64bitmode(ctx);
6399
        op_ldst(luxc1);
6400
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6401
        opn = "luxc1";
6402
        break;
6403
    case OPC_SWXC1:
6404
        check_cop1x(ctx);
6405
        gen_load_fpr32(fpu32_T[0], fs);
6406
        tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx);
6407
        opn = "swxc1";
6408
        store = 1;
6409
        break;
6410
    case OPC_SDXC1:
6411
        check_cop1x(ctx);
6412
        check_cp1_registers(ctx, fs);
6413
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6414
        tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6415
        opn = "sdxc1";
6416
        store = 1;
6417
        break;
6418
    case OPC_SUXC1:
6419
        check_cp1_64bitmode(ctx);
6420
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6421
        op_ldst(suxc1);
6422
        opn = "suxc1";
6423
        store = 1;
6424
        break;
6425
    default:
6426
        MIPS_INVAL(opn);
6427
        generate_exception(ctx, EXCP_RI);
6428
        return;
6429
    }
6430
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6431
               regnames[index], regnames[base]);
6432
}
6433

    
6434
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6435
                            int fd, int fr, int fs, int ft)
6436
{
6437
    const char *opn = "flt3_arith";
6438

    
6439
    switch (opc) {
6440
    case OPC_ALNV_PS:
6441
        check_cp1_64bitmode(ctx);
6442
        gen_load_gpr(cpu_T[0], fr);
6443
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6444
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6445
        gen_op_float_alnv_ps();
6446
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6447
        opn = "alnv.ps";
6448
        break;
6449
    case OPC_MADD_S:
6450
        check_cop1x(ctx);
6451
        gen_load_fpr32(fpu32_T[0], fs);
6452
        gen_load_fpr32(fpu32_T[1], ft);
6453
        gen_load_fpr32(fpu32_T[2], fr);
6454
        gen_op_float_muladd_s();
6455
        gen_store_fpr32(fpu32_T[2], fd);
6456
        opn = "madd.s";
6457
        break;
6458
    case OPC_MADD_D:
6459
        check_cop1x(ctx);
6460
        check_cp1_registers(ctx, fd | fs | ft | fr);
6461
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6462
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6463
        gen_load_fpr64(ctx, fpu64_T[2], fr);
6464
        gen_op_float_muladd_d();
6465
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6466
        opn = "madd.d";
6467
        break;
6468
    case OPC_MADD_PS:
6469
        check_cp1_64bitmode(ctx);
6470
        gen_load_fpr32(fpu32_T[0], fs);
6471
        gen_load_fpr32h(fpu32h_T[0], fs);
6472
        gen_load_fpr32(fpu32_T[1], ft);
6473
        gen_load_fpr32h(fpu32h_T[1], ft);
6474
        gen_load_fpr32(fpu32_T[2], fr);
6475
        gen_load_fpr32h(fpu32h_T[2], fr);
6476
        gen_op_float_muladd_ps();
6477
        gen_store_fpr32(fpu32_T[2], fd);
6478
        gen_store_fpr32h(fpu32h_T[2], fd);
6479
        opn = "madd.ps";
6480
        break;
6481
    case OPC_MSUB_S:
6482
        check_cop1x(ctx);
6483
        gen_load_fpr32(fpu32_T[0], fs);
6484
        gen_load_fpr32(fpu32_T[1], ft);
6485
        gen_load_fpr32(fpu32_T[2], fr);
6486
        gen_op_float_mulsub_s();
6487
        gen_store_fpr32(fpu32_T[2], fd);
6488
        opn = "msub.s";
6489
        break;
6490
    case OPC_MSUB_D:
6491
        check_cop1x(ctx);
6492
        check_cp1_registers(ctx, fd | fs | ft | fr);
6493
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6494
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6495
        gen_load_fpr64(ctx, fpu64_T[2], fr);
6496
        gen_op_float_mulsub_d();
6497
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6498
        opn = "msub.d";
6499
        break;
6500
    case OPC_MSUB_PS:
6501
        check_cp1_64bitmode(ctx);
6502
        gen_load_fpr32(fpu32_T[0], fs);
6503
        gen_load_fpr32h(fpu32h_T[0], fs);
6504
        gen_load_fpr32(fpu32_T[1], ft);
6505
        gen_load_fpr32h(fpu32h_T[1], ft);
6506
        gen_load_fpr32(fpu32_T[2], fr);
6507
        gen_load_fpr32h(fpu32h_T[2], fr);
6508
        gen_op_float_mulsub_ps();
6509
        gen_store_fpr32(fpu32_T[2], fd);
6510
        gen_store_fpr32h(fpu32h_T[2], fd);
6511
        opn = "msub.ps";
6512
        break;
6513
    case OPC_NMADD_S:
6514
        check_cop1x(ctx);
6515
        gen_load_fpr32(fpu32_T[0], fs);
6516
        gen_load_fpr32(fpu32_T[1], ft);
6517
        gen_load_fpr32(fpu32_T[2], fr);
6518
        gen_op_float_nmuladd_s();
6519
        gen_store_fpr32(fpu32_T[2], fd);
6520
        opn = "nmadd.s";
6521
        break;
6522
    case OPC_NMADD_D:
6523
        check_cop1x(ctx);
6524
        check_cp1_registers(ctx, fd | fs | ft | fr);
6525
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6526
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6527
        gen_load_fpr64(ctx, fpu64_T[2], fr);
6528
        gen_op_float_nmuladd_d();
6529
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6530
        opn = "nmadd.d";
6531
        break;
6532
    case OPC_NMADD_PS:
6533
        check_cp1_64bitmode(ctx);
6534
        gen_load_fpr32(fpu32_T[0], fs);
6535
        gen_load_fpr32h(fpu32h_T[0], fs);
6536
        gen_load_fpr32(fpu32_T[1], ft);
6537
        gen_load_fpr32h(fpu32h_T[1], ft);
6538
        gen_load_fpr32(fpu32_T[2], fr);
6539
        gen_load_fpr32h(fpu32h_T[2], fr);
6540
        gen_op_float_nmuladd_ps();
6541
        gen_store_fpr32(fpu32_T[2], fd);
6542
        gen_store_fpr32h(fpu32h_T[2], fd);
6543
        opn = "nmadd.ps";
6544
        break;
6545
    case OPC_NMSUB_S:
6546
        check_cop1x(ctx);
6547
        gen_load_fpr32(fpu32_T[0], fs);
6548
        gen_load_fpr32(fpu32_T[1], ft);
6549
        gen_load_fpr32(fpu32_T[2], fr);
6550
        gen_op_float_nmulsub_s();
6551
        gen_store_fpr32(fpu32_T[2], fd);
6552
        opn = "nmsub.s";
6553
        break;
6554
    case OPC_NMSUB_D:
6555
        check_cop1x(ctx);
6556
        check_cp1_registers(ctx, fd | fs | ft | fr);
6557
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6558
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6559
        gen_load_fpr64(ctx, fpu64_T[2], fr);
6560
        gen_op_float_nmulsub_d();
6561
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6562
        opn = "nmsub.d";
6563
        break;
6564
    case OPC_NMSUB_PS:
6565
        check_cp1_64bitmode(ctx);
6566
        gen_load_fpr32(fpu32_T[0], fs);
6567
        gen_load_fpr32h(fpu32h_T[0], fs);
6568
        gen_load_fpr32(fpu32_T[1], ft);
6569
        gen_load_fpr32h(fpu32h_T[1], ft);
6570
        gen_load_fpr32(fpu32_T[2], fr);
6571
        gen_load_fpr32h(fpu32h_T[2], fr);
6572
        gen_op_float_nmulsub_ps();
6573
        gen_store_fpr32(fpu32_T[2], fd);
6574
        gen_store_fpr32h(fpu32h_T[2], fd);
6575
        opn = "nmsub.ps";
6576
        break;
6577
    default:
6578
        MIPS_INVAL(opn);
6579
        generate_exception (ctx, EXCP_RI);
6580
        return;
6581
    }
6582
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6583
               fregnames[fs], fregnames[ft]);
6584
}
6585

    
6586
/* ISA extensions (ASEs) */
6587
/* MIPS16 extension to MIPS32 */
6588
/* SmartMIPS extension to MIPS32 */
6589

    
6590
#if defined(TARGET_MIPS64)
6591

    
6592
/* MDMX extension to MIPS64 */
6593

    
6594
#endif
6595

    
6596
static void decode_opc (CPUState *env, DisasContext *ctx)
6597
{
6598
    int32_t offset;
6599
    int rs, rt, rd, sa;
6600
    uint32_t op, op1, op2;
6601
    int16_t imm;
6602

    
6603
    /* make sure instructions are on a word boundary */
6604
    if (ctx->pc & 0x3) {
6605
        env->CP0_BadVAddr = ctx->pc;
6606
        generate_exception(ctx, EXCP_AdEL);
6607
        return;
6608
    }
6609

    
6610
    /* Handle blikely not taken case */
6611
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6612
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
6613
        int l1 = gen_new_label();
6614

    
6615
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6616
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6617
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6618
        tcg_temp_free(r_tmp);
6619
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6620
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6621
        gen_set_label(l1);
6622
    }
6623
    op = MASK_OP_MAJOR(ctx->opcode);
6624
    rs = (ctx->opcode >> 21) & 0x1f;
6625
    rt = (ctx->opcode >> 16) & 0x1f;
6626
    rd = (ctx->opcode >> 11) & 0x1f;
6627
    sa = (ctx->opcode >> 6) & 0x1f;
6628
    imm = (int16_t)ctx->opcode;
6629
    switch (op) {
6630
    case OPC_SPECIAL:
6631
        op1 = MASK_SPECIAL(ctx->opcode);
6632
        switch (op1) {
6633
        case OPC_SLL:          /* Arithmetic with immediate */
6634
        case OPC_SRL ... OPC_SRA:
6635
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6636
            break;
6637
        case OPC_MOVZ ... OPC_MOVN:
6638
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6639
        case OPC_SLLV:         /* Arithmetic */
6640
        case OPC_SRLV ... OPC_SRAV:
6641
        case OPC_ADD ... OPC_NOR:
6642
        case OPC_SLT ... OPC_SLTU:
6643
            gen_arith(env, ctx, op1, rd, rs, rt);
6644
            break;
6645
        case OPC_MULT ... OPC_DIVU:
6646
            if (sa) {
6647
                check_insn(env, ctx, INSN_VR54XX);
6648
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6649
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6650
            } else
6651
                gen_muldiv(ctx, op1, rs, rt);
6652
            break;
6653
        case OPC_JR ... OPC_JALR:
6654
            gen_compute_branch(ctx, op1, rs, rd, sa);
6655
            return;
6656
        case OPC_TGE ... OPC_TEQ: /* Traps */
6657
        case OPC_TNE:
6658
            gen_trap(ctx, op1, rs, rt, -1);
6659
            break;
6660
        case OPC_MFHI:          /* Move from HI/LO */
6661
        case OPC_MFLO:
6662
            gen_HILO(ctx, op1, rd);
6663
            break;
6664
        case OPC_MTHI:
6665
        case OPC_MTLO:          /* Move to HI/LO */
6666
            gen_HILO(ctx, op1, rs);
6667
            break;
6668
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6669
#ifdef MIPS_STRICT_STANDARD
6670
            MIPS_INVAL("PMON / selsl");
6671
            generate_exception(ctx, EXCP_RI);
6672
#else
6673
            gen_op_pmon(sa);
6674
#endif
6675
            break;
6676
        case OPC_SYSCALL:
6677
            generate_exception(ctx, EXCP_SYSCALL);
6678
            break;
6679
        case OPC_BREAK:
6680
            generate_exception(ctx, EXCP_BREAK);
6681
            break;
6682
        case OPC_SPIM:
6683
#ifdef MIPS_STRICT_STANDARD
6684
            MIPS_INVAL("SPIM");
6685
            generate_exception(ctx, EXCP_RI);
6686
#else
6687
           /* Implemented as RI exception for now. */
6688
            MIPS_INVAL("spim (unofficial)");
6689
            generate_exception(ctx, EXCP_RI);
6690
#endif
6691
            break;
6692
        case OPC_SYNC:
6693
            /* Treat as NOP. */
6694
            break;
6695

    
6696
        case OPC_MOVCI:
6697
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6698
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6699
                save_cpu_state(ctx, 1);
6700
                check_cp1_enabled(ctx);
6701
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6702
                          (ctx->opcode >> 16) & 1);
6703
            } else {
6704
                generate_exception_err(ctx, EXCP_CpU, 1);
6705
            }
6706
            break;
6707

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

    
7010
    /* Floating point (COP1). */
7011
    case OPC_LWC1:
7012
    case OPC_LDC1:
7013
    case OPC_SWC1:
7014
    case OPC_SDC1:
7015
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7016
            save_cpu_state(ctx, 1);
7017
            check_cp1_enabled(ctx);
7018
            gen_flt_ldst(ctx, op, rt, rs, imm);
7019
        } else {
7020
            generate_exception_err(ctx, EXCP_CpU, 1);
7021
        }
7022
        break;
7023

    
7024
    case OPC_CP1:
7025
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7026
            save_cpu_state(ctx, 1);
7027
            check_cp1_enabled(ctx);
7028
            op1 = MASK_CP1(ctx->opcode);
7029
            switch (op1) {
7030
            case OPC_MFHC1:
7031
            case OPC_MTHC1:
7032
                check_insn(env, ctx, ISA_MIPS32R2);
7033
            case OPC_MFC1:
7034
            case OPC_CFC1:
7035
            case OPC_MTC1:
7036
            case OPC_CTC1:
7037
                gen_cp1(ctx, op1, rt, rd);
7038
                break;
7039
#if defined(TARGET_MIPS64)
7040
            case OPC_DMFC1:
7041
            case OPC_DMTC1:
7042
                check_insn(env, ctx, ISA_MIPS3);
7043
                gen_cp1(ctx, op1, rt, rd);
7044
                break;
7045
#endif
7046
            case OPC_BC1ANY2:
7047
            case OPC_BC1ANY4:
7048
                check_cop1x(ctx);
7049
                check_insn(env, ctx, ASE_MIPS3D);
7050
                /* fall through */
7051
            case OPC_BC1:
7052
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7053
                                    (rt >> 2) & 0x7, imm << 2);
7054
                return;
7055
            case OPC_S_FMT:
7056
            case OPC_D_FMT:
7057
            case OPC_W_FMT:
7058
            case OPC_L_FMT:
7059
            case OPC_PS_FMT:
7060
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7061
                           (imm >> 8) & 0x7);
7062
                break;
7063
            default:
7064
                MIPS_INVAL("cp1");
7065
                generate_exception (ctx, EXCP_RI);
7066
                break;
7067
            }
7068
        } else {
7069
            generate_exception_err(ctx, EXCP_CpU, 1);
7070
        }
7071
        break;
7072

    
7073
    /* COP2.  */
7074
    case OPC_LWC2:
7075
    case OPC_LDC2:
7076
    case OPC_SWC2:
7077
    case OPC_SDC2:
7078
    case OPC_CP2:
7079
        /* COP2: Not implemented. */
7080
        generate_exception_err(ctx, EXCP_CpU, 2);
7081
        break;
7082

    
7083
    case OPC_CP3:
7084
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7085
            save_cpu_state(ctx, 1);
7086
            check_cp1_enabled(ctx);
7087
            op1 = MASK_CP3(ctx->opcode);
7088
            switch (op1) {
7089
            case OPC_LWXC1:
7090
            case OPC_LDXC1:
7091
            case OPC_LUXC1:
7092
            case OPC_SWXC1:
7093
            case OPC_SDXC1:
7094
            case OPC_SUXC1:
7095
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7096
                break;
7097
            case OPC_PREFX:
7098
                /* Treat as NOP. */
7099
                break;
7100
            case OPC_ALNV_PS:
7101
            case OPC_MADD_S:
7102
            case OPC_MADD_D:
7103
            case OPC_MADD_PS:
7104
            case OPC_MSUB_S:
7105
            case OPC_MSUB_D:
7106
            case OPC_MSUB_PS:
7107
            case OPC_NMADD_S:
7108
            case OPC_NMADD_D:
7109
            case OPC_NMADD_PS:
7110
            case OPC_NMSUB_S:
7111
            case OPC_NMSUB_D:
7112
            case OPC_NMSUB_PS:
7113
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7114
                break;
7115
            default:
7116
                MIPS_INVAL("cp3");
7117
                generate_exception (ctx, EXCP_RI);
7118
                break;
7119
            }
7120
        } else {
7121
            generate_exception_err(ctx, EXCP_CpU, 1);
7122
        }
7123
        break;
7124

    
7125
#if defined(TARGET_MIPS64)
7126
    /* MIPS64 opcodes */
7127
    case OPC_LWU:
7128
    case OPC_LDL ... OPC_LDR:
7129
    case OPC_SDL ... OPC_SDR:
7130
    case OPC_LLD:
7131
    case OPC_LD:
7132
    case OPC_SCD:
7133
    case OPC_SD:
7134
        check_insn(env, ctx, ISA_MIPS3);
7135
        check_mips_64(ctx);
7136
        gen_ldst(ctx, op, rt, rs, imm);
7137
        break;
7138
    case OPC_DADDI ... OPC_DADDIU:
7139
        check_insn(env, ctx, ISA_MIPS3);
7140
        check_mips_64(ctx);
7141
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7142
        break;
7143
#endif
7144
    case OPC_JALX:
7145
        check_insn(env, ctx, ASE_MIPS16);
7146
        /* MIPS16: Not implemented. */
7147
    case OPC_MDMX:
7148
        check_insn(env, ctx, ASE_MDMX);
7149
        /* MDMX: Not implemented. */
7150
    default:            /* Invalid */
7151
        MIPS_INVAL("major opcode");
7152
        generate_exception(ctx, EXCP_RI);
7153
        break;
7154
    }
7155
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7156
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7157
        /* Branches completion */
7158
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7159
        ctx->bstate = BS_BRANCH;
7160
        save_cpu_state(ctx, 0);
7161
        switch (hflags) {
7162
        case MIPS_HFLAG_B:
7163
            /* unconditional branch */
7164
            MIPS_DEBUG("unconditional branch");
7165
            gen_goto_tb(ctx, 0, ctx->btarget);
7166
            break;
7167
        case MIPS_HFLAG_BL:
7168
            /* blikely taken case */
7169
            MIPS_DEBUG("blikely branch taken");
7170
            gen_goto_tb(ctx, 0, ctx->btarget);
7171
            break;
7172
        case MIPS_HFLAG_BC:
7173
            /* Conditional branch */
7174
            MIPS_DEBUG("conditional branch");
7175
            {
7176
                TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
7177
                int l1 = gen_new_label();
7178

    
7179
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7180
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7181
                tcg_temp_free(r_tmp);
7182
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7183
                gen_set_label(l1);
7184
                gen_goto_tb(ctx, 0, ctx->btarget);
7185
            }
7186
            break;
7187
        case MIPS_HFLAG_BR:
7188
            /* unconditional branch to register */
7189
            MIPS_DEBUG("branch to register");
7190
            gen_breg_pc();
7191
            tcg_gen_exit_tb(0);
7192
            break;
7193
        default:
7194
            MIPS_DEBUG("unknown branch");
7195
            break;
7196
        }
7197
    }
7198
}
7199

    
7200
static always_inline int
7201
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7202
                                int search_pc)
7203
{
7204
    DisasContext ctx;
7205
    target_ulong pc_start;
7206
    uint16_t *gen_opc_end;
7207
    int j, lj = -1;
7208

    
7209
    if (search_pc && loglevel)
7210
        fprintf (logfile, "search pc %d\n", search_pc);
7211

    
7212
    pc_start = tb->pc;
7213
    /* Leave some spare opc slots for branch handling. */
7214
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
7215
    ctx.pc = pc_start;
7216
    ctx.saved_pc = -1;
7217
    ctx.tb = tb;
7218
    ctx.bstate = BS_NONE;
7219
    /* Restore delay slot state from the tb context.  */
7220
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7221
    restore_cpu_state(env, &ctx);
7222
#if defined(CONFIG_USER_ONLY)
7223
    ctx.mem_idx = MIPS_HFLAG_UM;
7224
#else
7225
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7226
#endif
7227
#ifdef DEBUG_DISAS
7228
    if (loglevel & CPU_LOG_TB_CPU) {
7229
        fprintf(logfile, "------------------------------------------------\n");
7230
        /* FIXME: This may print out stale hflags from env... */
7231
        cpu_dump_state(env, logfile, fprintf, 0);
7232
    }
7233
#endif
7234
#ifdef MIPS_DEBUG_DISAS
7235
    if (loglevel & CPU_LOG_TB_IN_ASM)
7236
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7237
                tb, ctx.mem_idx, ctx.hflags);
7238
#endif
7239
    while (ctx.bstate == BS_NONE) {
7240
        if (env->nb_breakpoints > 0) {
7241
            for(j = 0; j < env->nb_breakpoints; j++) {
7242
                if (env->breakpoints[j] == ctx.pc) {
7243
                    save_cpu_state(&ctx, 1);
7244
                    ctx.bstate = BS_BRANCH;
7245
                    gen_op_debug();
7246
                    /* Include the breakpoint location or the tb won't
7247
                     * be flushed when it must be.  */
7248
                    ctx.pc += 4;
7249
                    goto done_generating;
7250
                }
7251
            }
7252
        }
7253

    
7254
        if (search_pc) {
7255
            j = gen_opc_ptr - gen_opc_buf;
7256
            if (lj < j) {
7257
                lj++;
7258
                while (lj < j)
7259
                    gen_opc_instr_start[lj++] = 0;
7260
            }
7261
            gen_opc_pc[lj] = ctx.pc;
7262
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7263
            gen_opc_instr_start[lj] = 1;
7264
        }
7265
        ctx.opcode = ldl_code(ctx.pc);
7266
        decode_opc(env, &ctx);
7267
        ctx.pc += 4;
7268

    
7269
        if (env->singlestep_enabled)
7270
            break;
7271

    
7272
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7273
            break;
7274

    
7275
        if (gen_opc_ptr >= gen_opc_end)
7276
            break;
7277

    
7278
        if (gen_opc_ptr >= gen_opc_end)
7279
            break;
7280

    
7281
#if defined (MIPS_SINGLE_STEP)
7282
        break;
7283
#endif
7284
    }
7285
    if (env->singlestep_enabled) {
7286
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7287
        gen_op_debug();
7288
    } else {
7289
        switch (ctx.bstate) {
7290
        case BS_STOP:
7291
            tcg_gen_helper_0_0(do_interrupt_restart);
7292
            gen_goto_tb(&ctx, 0, ctx.pc);
7293
            break;
7294
        case BS_NONE:
7295
            save_cpu_state(&ctx, 0);
7296
            gen_goto_tb(&ctx, 0, ctx.pc);
7297
            break;
7298
        case BS_EXCP:
7299
            tcg_gen_helper_0_0(do_interrupt_restart);
7300
            tcg_gen_exit_tb(0);
7301
            break;
7302
        case BS_BRANCH:
7303
        default:
7304
            break;
7305
        }
7306
    }
7307
done_generating:
7308
    *gen_opc_ptr = INDEX_op_end;
7309
    if (search_pc) {
7310
        j = gen_opc_ptr - gen_opc_buf;
7311
        lj++;
7312
        while (lj <= j)
7313
            gen_opc_instr_start[lj++] = 0;
7314
    } else {
7315
        tb->size = ctx.pc - pc_start;
7316
    }
7317
#ifdef DEBUG_DISAS
7318
#if defined MIPS_DEBUG_DISAS
7319
    if (loglevel & CPU_LOG_TB_IN_ASM)
7320
        fprintf(logfile, "\n");
7321
#endif
7322
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7323
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7324
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7325
        fprintf(logfile, "\n");
7326
    }
7327
    if (loglevel & CPU_LOG_TB_CPU) {
7328
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7329
    }
7330
#endif
7331

    
7332
    return 0;
7333
}
7334

    
7335
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7336
{
7337
    return gen_intermediate_code_internal(env, tb, 0);
7338
}
7339

    
7340
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7341
{
7342
    return gen_intermediate_code_internal(env, tb, 1);
7343
}
7344

    
7345
void fpu_dump_state(CPUState *env, FILE *f,
7346
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7347
                    int flags)
7348
{
7349
    int i;
7350
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7351

    
7352
#define printfpr(fp)                                                        \
7353
    do {                                                                    \
7354
        if (is_fpu64)                                                       \
7355
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7356
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7357
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7358
        else {                                                              \
7359
            fpr_t tmp;                                                      \
7360
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7361
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7362
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7363
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7364
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7365
        }                                                                   \
7366
    } while(0)
7367

    
7368

    
7369
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7370
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7371
                get_float_exception_flags(&env->fpu->fp_status));
7372
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
7373
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
7374
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
7375
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7376
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7377
        printfpr(&env->fpu->fpr[i]);
7378
    }
7379

    
7380
#undef printfpr
7381
}
7382

    
7383
void dump_fpu (CPUState *env)
7384
{
7385
    if (loglevel) {
7386
        fprintf(logfile,
7387
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7388
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7389
                " %04x\n",
7390
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7391
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7392
                env->bcond);
7393
       fpu_dump_state(env, logfile, fprintf, 0);
7394
    }
7395
}
7396

    
7397
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7398
/* Debug help: The architecture requires 32bit code to maintain proper
7399
   sign-extened values on 64bit machines.  */
7400

    
7401
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7402

    
7403
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7404
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7405
                     int flags)
7406
{
7407
    int i;
7408

    
7409
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7410
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7411
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7412
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7413
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7414
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7415
    if (!SIGN_EXT_P(env->btarget))
7416
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7417

    
7418
    for (i = 0; i < 32; i++) {
7419
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7420
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7421
    }
7422

    
7423
    if (!SIGN_EXT_P(env->CP0_EPC))
7424
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7425
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7426
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7427
}
7428
#endif
7429

    
7430
void cpu_dump_state (CPUState *env, FILE *f,
7431
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7432
                     int flags)
7433
{
7434
    int i;
7435

    
7436
    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",
7437
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7438
    for (i = 0; i < 32; i++) {
7439
        if ((i & 3) == 0)
7440
            cpu_fprintf(f, "GPR%02d:", i);
7441
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7442
        if ((i & 3) == 3)
7443
            cpu_fprintf(f, "\n");
7444
    }
7445

    
7446
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7447
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7448
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7449
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7450
    if (env->hflags & MIPS_HFLAG_FPU)
7451
        fpu_dump_state(env, f, cpu_fprintf, flags);
7452
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7453
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7454
#endif
7455
}
7456

    
7457
static void mips_tcg_init(void)
7458
{
7459
    static int inited;
7460

    
7461
    /* Initialize various static tables. */
7462
    if (inited)
7463
        return;
7464

    
7465
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7466
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7467
                                         TCG_AREG0,
7468
                                         offsetof(CPUState, current_tc_gprs),
7469
                                         "current_tc_gprs");
7470
    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7471
                                       TCG_AREG0,
7472
                                       offsetof(CPUState, current_tc_hi),
7473
                                       "current_tc_hi");
7474
    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
7475
                                     TCG_AREG0,
7476
                                     offsetof(CPUState, fpu),
7477
                                     "current_fpu");
7478
#if TARGET_LONG_BITS > HOST_LONG_BITS
7479
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7480
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7481
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7482
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7483
#else
7484
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7485
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7486
#endif
7487

    
7488
    /* register helpers */
7489
#undef DEF_HELPER
7490
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
7491
#include "helper.h"
7492

    
7493
    fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0");
7494
    fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1");
7495
    fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2");
7496
    fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0");
7497
    fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1");
7498
    fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2");
7499
    fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0");
7500
    fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1");
7501
    fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2");
7502

    
7503
    inited = 1;
7504
}
7505

    
7506
#include "translate_init.c"
7507

    
7508
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7509
{
7510
    CPUMIPSState *env;
7511
    const mips_def_t *def;
7512

    
7513
    def = cpu_mips_find_by_name(cpu_model);
7514
    if (!def)
7515
        return NULL;
7516
    env = qemu_mallocz(sizeof(CPUMIPSState));
7517
    if (!env)
7518
        return NULL;
7519
    env->cpu_model = def;
7520

    
7521
    cpu_exec_init(env);
7522
    env->cpu_model_str = cpu_model;
7523
    mips_tcg_init();
7524
    cpu_reset(env);
7525
    return env;
7526
}
7527

    
7528
void cpu_reset (CPUMIPSState *env)
7529
{
7530
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7531

    
7532
    tlb_flush(env, 1);
7533

    
7534
    /* Minimal init */
7535
#if !defined(CONFIG_USER_ONLY)
7536
    if (env->hflags & MIPS_HFLAG_BMASK) {
7537
        /* If the exception was raised from a delay slot,
7538
         * come back to the jump.  */
7539
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7540
    } else {
7541
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7542
    }
7543
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7544
    env->CP0_Wired = 0;
7545
    /* SMP not implemented */
7546
    env->CP0_EBase = 0x80000000;
7547
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7548
    /* vectored interrupts not implemented, timer on int 7,
7549
       no performance counters. */
7550
    env->CP0_IntCtl = 0xe0000000;
7551
    {
7552
        int i;
7553

    
7554
        for (i = 0; i < 7; i++) {
7555
            env->CP0_WatchLo[i] = 0;
7556
            env->CP0_WatchHi[i] = 0x80000000;
7557
        }
7558
        env->CP0_WatchLo[7] = 0;
7559
        env->CP0_WatchHi[7] = 0;
7560
    }
7561
    /* Count register increments in debug mode, EJTAG version 1 */
7562
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7563
#endif
7564
    env->exception_index = EXCP_NONE;
7565
#if defined(CONFIG_USER_ONLY)
7566
    env->hflags = MIPS_HFLAG_UM;
7567
    env->user_mode_only = 1;
7568
#else
7569
    env->hflags = MIPS_HFLAG_CP0;
7570
#endif
7571
    cpu_mips_register(env, env->cpu_model);
7572
}
7573

    
7574
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7575
                unsigned long searched_pc, int pc_pos, void *puc)
7576
{
7577
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7578
    env->hflags &= ~MIPS_HFLAG_BMASK;
7579
    env->hflags |= gen_opc_hflags[pc_pos];
7580
}