Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a1f6684d

History | View | Annotate | Download (245.2 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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 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 "tcg-op.h"
33
#include "qemu-common.h"
34

    
35
#include "helper.h"
36
#define GEN_HELPER 1
37
#include "helper.h"
38

    
39
//#define MIPS_DEBUG_DISAS
40
//#define MIPS_DEBUG_SIGN_EXTENSIONS
41
//#define MIPS_SINGLE_STEP
42

    
43
/* MIPS major opcodes */
44
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
45

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

    
121
/* MIPS special opcodes */
122
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
123

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

    
189
    /* Special */
190
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
191
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
192
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
193
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
194
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
195

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

    
205
/* Multiplication variants of the vr54xx. */
206
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
207

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

    
225
/* REGIMM (rt field) opcodes */
226
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
227

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

    
246
/* Special2 opcodes */
247
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
248

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

    
265
/* Special3 opcodes */
266
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
267

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

    
284
/* BSHFL opcodes */
285
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
286

    
287
enum {
288
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
289
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
290
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
291
};
292

    
293
/* DBSHFL opcodes */
294
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
295

    
296
enum {
297
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
298
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
299
};
300

    
301
/* Coprocessor 0 (rs field) */
302
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
303

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

    
319
/* MFMC0 opcodes */
320
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
321

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

    
331
/* Coprocessor 0 (with rs == C0) */
332
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
333

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

    
345
/* Coprocessor 1 (rs field) */
346
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
347

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

    
369
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
370
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
371

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

    
379
enum {
380
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
381
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
382
};
383

    
384
enum {
385
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
386
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
387
};
388

    
389
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
390

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

    
403
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
404

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

    
428
/* global register indices */
429
static TCGv_ptr cpu_env;
430
static TCGv cpu_gpr[32], cpu_PC;
431
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
432
static TCGv cpu_dspctrl, btarget;
433
static TCGv_i32 bcond;
434
static TCGv_i32 fpu_fpr32[32], fpu_fpr32h[32];
435
static TCGv_i64 fpu_fpr64[32];
436
static TCGv_i32 fpu_fcr0, fpu_fcr31;
437

    
438
#include "gen-icount.h"
439

    
440
#define gen_helper_0i(name, arg) do {                             \
441
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
442
    gen_helper_##name(helper_tmp);                                \
443
    tcg_temp_free_i32(helper_tmp);                                \
444
    } while(0)
445

    
446
#define gen_helper_1i(name, arg1, arg2) do {                      \
447
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
448
    gen_helper_##name(arg1, helper_tmp);                          \
449
    tcg_temp_free_i32(helper_tmp);                                \
450
    } while(0)
451

    
452
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
453
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
454
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
455
    tcg_temp_free_i32(helper_tmp);                                \
456
    } while(0)
457

    
458
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
459
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
460
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
461
    tcg_temp_free_i32(helper_tmp);                                \
462
    } while(0)
463

    
464
typedef struct DisasContext {
465
    struct TranslationBlock *tb;
466
    target_ulong pc, saved_pc;
467
    uint32_t opcode;
468
    /* Routine used to access memory */
469
    int mem_idx;
470
    uint32_t hflags, saved_hflags;
471
    int bstate;
472
    target_ulong btarget;
473
} DisasContext;
474

    
475
enum {
476
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
477
                      * exception condition */
478
    BS_STOP     = 1, /* We want to stop translation for any reason */
479
    BS_BRANCH   = 2, /* We reached a branch condition     */
480
    BS_EXCP     = 3, /* We reached an exception condition */
481
};
482

    
483
static const char *regnames[] =
484
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
485
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
486
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
487
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
488

    
489
static const char *regnames_HI[] =
490
    { "HI0", "HI1", "HI2", "HI3", };
491

    
492
static const char *regnames_LO[] =
493
    { "LO0", "LO1", "LO2", "LO3", };
494

    
495
static const char *regnames_ACX[] =
496
    { "ACX0", "ACX1", "ACX2", "ACX3", };
497

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

    
504
static const char *fregnames_64[] =
505
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
506
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
507
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
508
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
509

    
510
static const char *fregnames_h[] =
511
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
512
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
513
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
514
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
515

    
516
#ifdef MIPS_DEBUG_DISAS
517
#define MIPS_DEBUG(fmt, args...)                         \
518
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
519
                       TARGET_FMT_lx ": %08x " fmt "\n", \
520
                       ctx->pc, ctx->opcode , ##args)
521
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
522
#else
523
#define MIPS_DEBUG(fmt, args...) do { } while(0)
524
#define LOG_DISAS(...) do { } while (0)
525
#endif
526

    
527
#define MIPS_INVAL(op)                                                        \
528
do {                                                                          \
529
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
530
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
531
} while (0)
532

    
533
/* General purpose registers moves. */
534
static inline void gen_load_gpr (TCGv t, int reg)
535
{
536
    if (reg == 0)
537
        tcg_gen_movi_tl(t, 0);
538
    else
539
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
540
}
541

    
542
static inline void gen_store_gpr (TCGv t, int reg)
543
{
544
    if (reg != 0)
545
        tcg_gen_mov_tl(cpu_gpr[reg], t);
546
}
547

    
548
/* Moves to/from ACX register.  */
549
static inline void gen_load_ACX (TCGv t, int reg)
550
{
551
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
552
}
553

    
554
static inline void gen_store_ACX (TCGv t, int reg)
555
{
556
    tcg_gen_mov_tl(cpu_ACX[reg], t);
557
}
558

    
559
/* Moves to/from shadow registers. */
560
static inline void gen_load_srsgpr (int from, int to)
561
{
562
    TCGv r_tmp1 = tcg_temp_new();
563

    
564
    if (from == 0)
565
        tcg_gen_movi_tl(r_tmp1, 0);
566
    else {
567
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
568
        TCGv_ptr addr = tcg_temp_new_ptr();
569

    
570
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
571
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
572
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
573
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
574
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
575
        tcg_gen_add_ptr(addr, cpu_env, addr);
576

    
577
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
578
        tcg_temp_free_ptr(addr);
579
        tcg_temp_free_i32(r_tmp2);
580
    }
581
    gen_store_gpr(r_tmp1, to);
582
    tcg_temp_free(r_tmp1);
583
}
584

    
585
static inline void gen_store_srsgpr (int from, int to)
586
{
587
    if (to != 0) {
588
        TCGv r_tmp1 = tcg_temp_new();
589
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
590
        TCGv_ptr addr = tcg_temp_new_ptr();
591

    
592
        gen_load_gpr(r_tmp1, from);
593
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
594
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
595
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
596
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
597
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
598
        tcg_gen_add_ptr(addr, cpu_env, addr);
599

    
600
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
601
        tcg_temp_free_ptr(addr);
602
        tcg_temp_free_i32(r_tmp2);
603
        tcg_temp_free(r_tmp1);
604
    }
605
}
606

    
607
/* Floating point register moves. */
608
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
609
{
610
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
611
}
612

    
613
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
614
{
615
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
616
}
617

    
618
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
619
{
620
    if (ctx->hflags & MIPS_HFLAG_F64)
621
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
622
    else {
623
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
624
    }
625
}
626

    
627
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
628
{
629
    if (ctx->hflags & MIPS_HFLAG_F64)
630
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
631
    else {
632
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
633
        tcg_gen_shri_i64(t, t, 32);
634
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
635
    }
636
}
637

    
638
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
639
{
640
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
641
}
642

    
643
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
644
{
645
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
646
}
647

    
648
static inline void get_fp_cond (TCGv_i32 t)
649
{
650
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
651
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
652

    
653
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
654
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
655
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
656
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
657
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
658
    tcg_temp_free_i32(r_tmp1);
659
    tcg_temp_free_i32(r_tmp2);
660
}
661

    
662
#define FOP_CONDS(type, fmt, bits)                                            \
663
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
664
                                               TCGv_i##bits b, int cc)        \
665
{                                                                             \
666
    switch (n) {                                                              \
667
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
668
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
669
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
670
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
671
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
672
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
673
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
674
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
675
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
676
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
677
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
678
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
679
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
680
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
681
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
682
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
683
    default: abort();                                                         \
684
    }                                                                         \
685
}
686

    
687
FOP_CONDS(, d, 64)
688
FOP_CONDS(abs, d, 64)
689
FOP_CONDS(, s, 32)
690
FOP_CONDS(abs, s, 32)
691
FOP_CONDS(, ps, 64)
692
FOP_CONDS(abs, ps, 64)
693
#undef FOP_CONDS
694

    
695
/* Tests */
696
#define OP_COND(name, cond)                                   \
697
static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
698
{                                                             \
699
    int l1 = gen_new_label();                                 \
700
    int l2 = gen_new_label();                                 \
701
                                                              \
702
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
703
    tcg_gen_movi_tl(t0, 0);                                   \
704
    tcg_gen_br(l2);                                           \
705
    gen_set_label(l1);                                        \
706
    tcg_gen_movi_tl(t0, 1);                                   \
707
    gen_set_label(l2);                                        \
708
}
709
OP_COND(eq, TCG_COND_EQ);
710
OP_COND(ne, TCG_COND_NE);
711
OP_COND(ge, TCG_COND_GE);
712
OP_COND(geu, TCG_COND_GEU);
713
OP_COND(lt, TCG_COND_LT);
714
OP_COND(ltu, TCG_COND_LTU);
715
#undef OP_COND
716

    
717
#define OP_CONDI(name, cond)                                  \
718
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
719
{                                                             \
720
    int l1 = gen_new_label();                                 \
721
    int l2 = gen_new_label();                                 \
722
                                                              \
723
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
724
    tcg_gen_movi_tl(t, 0);                                    \
725
    tcg_gen_br(l2);                                           \
726
    gen_set_label(l1);                                        \
727
    tcg_gen_movi_tl(t, 1);                                    \
728
    gen_set_label(l2);                                        \
729
}
730
OP_CONDI(lti, TCG_COND_LT);
731
OP_CONDI(ltiu, TCG_COND_LTU);
732
#undef OP_CONDI
733

    
734
#define OP_CONDZ(name, cond)                                  \
735
static inline void glue(gen_op_, name) (TCGv t)               \
736
{                                                             \
737
    int l1 = gen_new_label();                                 \
738
    int l2 = gen_new_label();                                 \
739
                                                              \
740
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
741
    tcg_gen_movi_tl(t, 0);                                    \
742
    tcg_gen_br(l2);                                           \
743
    gen_set_label(l1);                                        \
744
    tcg_gen_movi_tl(t, 1);                                    \
745
    gen_set_label(l2);                                        \
746
}
747
OP_CONDZ(gez, TCG_COND_GE);
748
OP_CONDZ(gtz, TCG_COND_GT);
749
OP_CONDZ(lez, TCG_COND_LE);
750
OP_CONDZ(ltz, TCG_COND_LT);
751
#undef OP_CONDZ
752

    
753
static inline void gen_save_pc(target_ulong pc)
754
{
755
    tcg_gen_movi_tl(cpu_PC, pc);
756
}
757

    
758
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
759
{
760
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
761
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
762
        gen_save_pc(ctx->pc);
763
        ctx->saved_pc = ctx->pc;
764
    }
765
    if (ctx->hflags != ctx->saved_hflags) {
766
        TCGv_i32 r_tmp = tcg_temp_new_i32();
767

    
768
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
769
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
770
        tcg_temp_free_i32(r_tmp);
771
        ctx->saved_hflags = ctx->hflags;
772
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
773
        case MIPS_HFLAG_BR:
774
            break;
775
        case MIPS_HFLAG_BC:
776
        case MIPS_HFLAG_BL:
777
        case MIPS_HFLAG_B:
778
            tcg_gen_movi_tl(btarget, ctx->btarget);
779
            break;
780
        }
781
    }
782
}
783

    
784
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
785
{
786
    ctx->saved_hflags = ctx->hflags;
787
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
788
    case MIPS_HFLAG_BR:
789
        break;
790
    case MIPS_HFLAG_BC:
791
    case MIPS_HFLAG_BL:
792
    case MIPS_HFLAG_B:
793
        ctx->btarget = env->btarget;
794
        break;
795
    }
796
}
797

    
798
static inline void
799
generate_exception_err (DisasContext *ctx, int excp, int err)
800
{
801
    TCGv_i32 texcp = tcg_const_i32(excp);
802
    TCGv_i32 terr = tcg_const_i32(err);
803
    save_cpu_state(ctx, 1);
804
    gen_helper_raise_exception_err(texcp, terr);
805
    tcg_temp_free_i32(terr);
806
    tcg_temp_free_i32(texcp);
807
    gen_helper_interrupt_restart();
808
    tcg_gen_exit_tb(0);
809
}
810

    
811
static inline void
812
generate_exception (DisasContext *ctx, int excp)
813
{
814
    save_cpu_state(ctx, 1);
815
    gen_helper_0i(raise_exception, excp);
816
    gen_helper_interrupt_restart();
817
    tcg_gen_exit_tb(0);
818
}
819

    
820
/* Addresses computation */
821
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
822
{
823
    tcg_gen_add_tl(t0, t0, t1);
824

    
825
#if defined(TARGET_MIPS64)
826
    /* For compatibility with 32-bit code, data reference in user mode
827
       with Status_UX = 0 should be casted to 32-bit and sign extended.
828
       See the MIPS64 PRA manual, section 4.10. */
829
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
830
        !(ctx->hflags & MIPS_HFLAG_UX)) {
831
        tcg_gen_ext32s_i64(t0, t0);
832
    }
833
#endif
834
}
835

    
836
static inline void check_cp0_enabled(DisasContext *ctx)
837
{
838
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
839
        generate_exception_err(ctx, EXCP_CpU, 1);
840
}
841

    
842
static inline void check_cp1_enabled(DisasContext *ctx)
843
{
844
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
845
        generate_exception_err(ctx, EXCP_CpU, 1);
846
}
847

    
848
/* Verify that the processor is running with COP1X instructions enabled.
849
   This is associated with the nabla symbol in the MIPS32 and MIPS64
850
   opcode tables.  */
851

    
852
static inline void check_cop1x(DisasContext *ctx)
853
{
854
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
855
        generate_exception(ctx, EXCP_RI);
856
}
857

    
858
/* Verify that the processor is running with 64-bit floating-point
859
   operations enabled.  */
860

    
861
static inline void check_cp1_64bitmode(DisasContext *ctx)
862
{
863
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
864
        generate_exception(ctx, EXCP_RI);
865
}
866

    
867
/*
868
 * Verify if floating point register is valid; an operation is not defined
869
 * if bit 0 of any register specification is set and the FR bit in the
870
 * Status register equals zero, since the register numbers specify an
871
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
872
 * in the Status register equals one, both even and odd register numbers
873
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
874
 *
875
 * Multiple 64 bit wide registers can be checked by calling
876
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
877
 */
878
static inline void check_cp1_registers(DisasContext *ctx, int regs)
879
{
880
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
881
        generate_exception(ctx, EXCP_RI);
882
}
883

    
884
/* This code generates a "reserved instruction" exception if the
885
   CPU does not support the instruction set corresponding to flags. */
886
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
887
{
888
    if (unlikely(!(env->insn_flags & flags)))
889
        generate_exception(ctx, EXCP_RI);
890
}
891

    
892
/* This code generates a "reserved instruction" exception if 64-bit
893
   instructions are not enabled. */
894
static inline void check_mips_64(DisasContext *ctx)
895
{
896
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
897
        generate_exception(ctx, EXCP_RI);
898
}
899

    
900
/* load/store instructions. */
901
#define OP_LD(insn,fname)                                        \
902
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
903
{                                                                \
904
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
905
}
906
OP_LD(lb,ld8s);
907
OP_LD(lbu,ld8u);
908
OP_LD(lh,ld16s);
909
OP_LD(lhu,ld16u);
910
OP_LD(lw,ld32s);
911
#if defined(TARGET_MIPS64)
912
OP_LD(lwu,ld32u);
913
OP_LD(ld,ld64);
914
#endif
915
#undef OP_LD
916

    
917
#define OP_ST(insn,fname)                                        \
918
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
919
{                                                                \
920
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
921
}
922
OP_ST(sb,st8);
923
OP_ST(sh,st16);
924
OP_ST(sw,st32);
925
#if defined(TARGET_MIPS64)
926
OP_ST(sd,st64);
927
#endif
928
#undef OP_ST
929

    
930
#define OP_LD_ATOMIC(insn,fname)                                        \
931
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
932
{                                                                       \
933
    tcg_gen_mov_tl(t1, t0);                                             \
934
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
935
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
936
}
937
OP_LD_ATOMIC(ll,ld32s);
938
#if defined(TARGET_MIPS64)
939
OP_LD_ATOMIC(lld,ld64);
940
#endif
941
#undef OP_LD_ATOMIC
942

    
943
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
944
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
945
{                                                                       \
946
    TCGv r_tmp = tcg_temp_local_new();                       \
947
    int l1 = gen_new_label();                                           \
948
    int l2 = gen_new_label();                                           \
949
    int l3 = gen_new_label();                                           \
950
                                                                        \
951
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
952
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
953
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
954
    generate_exception(ctx, EXCP_AdES);                                 \
955
    gen_set_label(l1);                                                  \
956
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
957
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
958
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
959
    tcg_gen_movi_tl(t0, 1);                                             \
960
    tcg_gen_br(l3);                                                     \
961
    gen_set_label(l2);                                                  \
962
    tcg_gen_movi_tl(t0, 0);                                             \
963
    gen_set_label(l3);                                                  \
964
    tcg_temp_free(r_tmp);                                               \
965
}
966
OP_ST_ATOMIC(sc,st32,0x3);
967
#if defined(TARGET_MIPS64)
968
OP_ST_ATOMIC(scd,st64,0x7);
969
#endif
970
#undef OP_ST_ATOMIC
971

    
972
/* Load and store */
973
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
974
                      int base, int16_t offset)
975
{
976
    const char *opn = "ldst";
977
    TCGv t0 = tcg_temp_local_new();
978
    TCGv t1 = tcg_temp_local_new();
979

    
980
    if (base == 0) {
981
        tcg_gen_movi_tl(t0, offset);
982
    } else if (offset == 0) {
983
        gen_load_gpr(t0, base);
984
    } else {
985
        tcg_gen_movi_tl(t0, offset);
986
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
987
    }
988
    /* Don't do NOP if destination is zero: we must perform the actual
989
       memory access. */
990
    switch (opc) {
991
#if defined(TARGET_MIPS64)
992
    case OPC_LWU:
993
        op_ldst_lwu(t0, ctx);
994
        gen_store_gpr(t0, rt);
995
        opn = "lwu";
996
        break;
997
    case OPC_LD:
998
        op_ldst_ld(t0, ctx);
999
        gen_store_gpr(t0, rt);
1000
        opn = "ld";
1001
        break;
1002
    case OPC_LLD:
1003
        op_ldst_lld(t0, t1, ctx);
1004
        gen_store_gpr(t0, rt);
1005
        opn = "lld";
1006
        break;
1007
    case OPC_SD:
1008
        gen_load_gpr(t1, rt);
1009
        op_ldst_sd(t0, t1, ctx);
1010
        opn = "sd";
1011
        break;
1012
    case OPC_SCD:
1013
        save_cpu_state(ctx, 1);
1014
        gen_load_gpr(t1, rt);
1015
        op_ldst_scd(t0, t1, ctx);
1016
        gen_store_gpr(t0, rt);
1017
        opn = "scd";
1018
        break;
1019
    case OPC_LDL:
1020
        save_cpu_state(ctx, 1);
1021
        gen_load_gpr(t1, rt);
1022
        gen_helper_3i(ldl, t1, t0, t1, ctx->mem_idx);
1023
        gen_store_gpr(t1, rt);
1024
        opn = "ldl";
1025
        break;
1026
    case OPC_SDL:
1027
        save_cpu_state(ctx, 1);
1028
        gen_load_gpr(t1, rt);
1029
        gen_helper_2i(sdl, t0, t1, ctx->mem_idx);
1030
        opn = "sdl";
1031
        break;
1032
    case OPC_LDR:
1033
        save_cpu_state(ctx, 1);
1034
        gen_load_gpr(t1, rt);
1035
        gen_helper_3i(ldr, t1, t0, t1, ctx->mem_idx);
1036
        gen_store_gpr(t1, rt);
1037
        opn = "ldr";
1038
        break;
1039
    case OPC_SDR:
1040
        save_cpu_state(ctx, 1);
1041
        gen_load_gpr(t1, rt);
1042
        gen_helper_2i(sdr, t0, t1, ctx->mem_idx);
1043
        opn = "sdr";
1044
        break;
1045
#endif
1046
    case OPC_LW:
1047
        op_ldst_lw(t0, ctx);
1048
        gen_store_gpr(t0, rt);
1049
        opn = "lw";
1050
        break;
1051
    case OPC_SW:
1052
        gen_load_gpr(t1, rt);
1053
        op_ldst_sw(t0, t1, ctx);
1054
        opn = "sw";
1055
        break;
1056
    case OPC_LH:
1057
        op_ldst_lh(t0, ctx);
1058
        gen_store_gpr(t0, rt);
1059
        opn = "lh";
1060
        break;
1061
    case OPC_SH:
1062
        gen_load_gpr(t1, rt);
1063
        op_ldst_sh(t0, t1, ctx);
1064
        opn = "sh";
1065
        break;
1066
    case OPC_LHU:
1067
        op_ldst_lhu(t0, ctx);
1068
        gen_store_gpr(t0, rt);
1069
        opn = "lhu";
1070
        break;
1071
    case OPC_LB:
1072
        op_ldst_lb(t0, ctx);
1073
        gen_store_gpr(t0, rt);
1074
        opn = "lb";
1075
        break;
1076
    case OPC_SB:
1077
        gen_load_gpr(t1, rt);
1078
        op_ldst_sb(t0, t1, ctx);
1079
        opn = "sb";
1080
        break;
1081
    case OPC_LBU:
1082
        op_ldst_lbu(t0, ctx);
1083
        gen_store_gpr(t0, rt);
1084
        opn = "lbu";
1085
        break;
1086
    case OPC_LWL:
1087
        save_cpu_state(ctx, 1);
1088
        gen_load_gpr(t1, rt);
1089
        gen_helper_3i(lwl, t1, t0, t1, ctx->mem_idx);
1090
        gen_store_gpr(t1, rt);
1091
        opn = "lwl";
1092
        break;
1093
    case OPC_SWL:
1094
        save_cpu_state(ctx, 1);
1095
        gen_load_gpr(t1, rt);
1096
        gen_helper_2i(swl, t0, t1, ctx->mem_idx);
1097
        opn = "swr";
1098
        break;
1099
    case OPC_LWR:
1100
        save_cpu_state(ctx, 1);
1101
        gen_load_gpr(t1, rt);
1102
        gen_helper_3i(lwr, t1, t0, t1, ctx->mem_idx);
1103
        gen_store_gpr(t1, rt);
1104
        opn = "lwr";
1105
        break;
1106
    case OPC_SWR:
1107
        save_cpu_state(ctx, 1);
1108
        gen_load_gpr(t1, rt);
1109
        gen_helper_2i(swr, t0, t1, ctx->mem_idx);
1110
        opn = "swr";
1111
        break;
1112
    case OPC_LL:
1113
        op_ldst_ll(t0, t1, ctx);
1114
        gen_store_gpr(t0, rt);
1115
        opn = "ll";
1116
        break;
1117
    case OPC_SC:
1118
        save_cpu_state(ctx, 1);
1119
        gen_load_gpr(t1, rt);
1120
        op_ldst_sc(t0, t1, ctx);
1121
        gen_store_gpr(t0, rt);
1122
        opn = "sc";
1123
        break;
1124
    default:
1125
        MIPS_INVAL(opn);
1126
        generate_exception(ctx, EXCP_RI);
1127
        goto out;
1128
    }
1129
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1130
 out:
1131
    tcg_temp_free(t0);
1132
    tcg_temp_free(t1);
1133
}
1134

    
1135
/* Load and store */
1136
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1137
                          int base, int16_t offset)
1138
{
1139
    const char *opn = "flt_ldst";
1140
    TCGv t0 = tcg_temp_local_new();
1141

    
1142
    if (base == 0) {
1143
        tcg_gen_movi_tl(t0, offset);
1144
    } else if (offset == 0) {
1145
        gen_load_gpr(t0, base);
1146
    } else {
1147
        tcg_gen_movi_tl(t0, offset);
1148
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1149
    }
1150
    /* Don't do NOP if destination is zero: we must perform the actual
1151
       memory access. */
1152
    switch (opc) {
1153
    case OPC_LWC1:
1154
        {
1155
            TCGv_i32 fp0 = tcg_temp_new_i32();
1156
            TCGv t1 = tcg_temp_new();
1157

    
1158
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1159
            tcg_gen_trunc_tl_i32(fp0, t1);
1160
            gen_store_fpr32(fp0, ft);
1161
            tcg_temp_free(t1);
1162
            tcg_temp_free_i32(fp0);
1163
        }
1164
        opn = "lwc1";
1165
        break;
1166
    case OPC_SWC1:
1167
        {
1168
            TCGv_i32 fp0 = tcg_temp_new_i32();
1169
            TCGv t1 = tcg_temp_new();
1170

    
1171
            gen_load_fpr32(fp0, ft);
1172
            tcg_gen_extu_i32_tl(t1, fp0);
1173
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1174
            tcg_temp_free(t1);
1175
            tcg_temp_free_i32(fp0);
1176
        }
1177
        opn = "swc1";
1178
        break;
1179
    case OPC_LDC1:
1180
        {
1181
            TCGv_i64 fp0 = tcg_temp_new_i64();
1182

    
1183
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1184
            gen_store_fpr64(ctx, fp0, ft);
1185
            tcg_temp_free_i64(fp0);
1186
        }
1187
        opn = "ldc1";
1188
        break;
1189
    case OPC_SDC1:
1190
        {
1191
            TCGv_i64 fp0 = tcg_temp_new_i64();
1192

    
1193
            gen_load_fpr64(ctx, fp0, ft);
1194
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1195
            tcg_temp_free_i64(fp0);
1196
        }
1197
        opn = "sdc1";
1198
        break;
1199
    default:
1200
        MIPS_INVAL(opn);
1201
        generate_exception(ctx, EXCP_RI);
1202
        goto out;
1203
    }
1204
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1205
 out:
1206
    tcg_temp_free(t0);
1207
}
1208

    
1209
/* Arithmetic with immediate operand */
1210
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1211
                           int rt, int rs, int16_t imm)
1212
{
1213
    target_ulong uimm;
1214
    const char *opn = "imm arith";
1215
    TCGv t0 = tcg_temp_local_new();
1216

    
1217
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1218
        /* If no destination, treat it as a NOP.
1219
           For addi, we must generate the overflow exception when needed. */
1220
        MIPS_DEBUG("NOP");
1221
        goto out;
1222
    }
1223
    uimm = (uint16_t)imm;
1224
    switch (opc) {
1225
    case OPC_ADDI:
1226
    case OPC_ADDIU:
1227
#if defined(TARGET_MIPS64)
1228
    case OPC_DADDI:
1229
    case OPC_DADDIU:
1230
#endif
1231
    case OPC_SLTI:
1232
    case OPC_SLTIU:
1233
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1234
        /* Fall through. */
1235
    case OPC_ANDI:
1236
    case OPC_ORI:
1237
    case OPC_XORI:
1238
        gen_load_gpr(t0, rs);
1239
        break;
1240
    case OPC_LUI:
1241
        tcg_gen_movi_tl(t0, imm << 16);
1242
        break;
1243
    case OPC_SLL:
1244
    case OPC_SRA:
1245
    case OPC_SRL:
1246
#if defined(TARGET_MIPS64)
1247
    case OPC_DSLL:
1248
    case OPC_DSRA:
1249
    case OPC_DSRL:
1250
    case OPC_DSLL32:
1251
    case OPC_DSRA32:
1252
    case OPC_DSRL32:
1253
#endif
1254
        uimm &= 0x1f;
1255
        gen_load_gpr(t0, rs);
1256
        break;
1257
    }
1258
    switch (opc) {
1259
    case OPC_ADDI:
1260
        {
1261
            TCGv r_tmp1 = tcg_temp_new();
1262
            TCGv r_tmp2 = tcg_temp_new();
1263
            int l1 = gen_new_label();
1264

    
1265
            save_cpu_state(ctx, 1);
1266
            tcg_gen_ext32s_tl(r_tmp1, t0);
1267
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1268

    
1269
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1270
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1271
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1272
            tcg_temp_free(r_tmp2);
1273
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1274
            /* operands of same sign, result different sign */
1275
            generate_exception(ctx, EXCP_OVERFLOW);
1276
            gen_set_label(l1);
1277
            tcg_temp_free(r_tmp1);
1278

    
1279
            tcg_gen_ext32s_tl(t0, t0);
1280
        }
1281
        opn = "addi";
1282
        break;
1283
    case OPC_ADDIU:
1284
        tcg_gen_addi_tl(t0, t0, uimm);
1285
        tcg_gen_ext32s_tl(t0, t0);
1286
        opn = "addiu";
1287
        break;
1288
#if defined(TARGET_MIPS64)
1289
    case OPC_DADDI:
1290
        {
1291
            TCGv r_tmp1 = tcg_temp_new();
1292
            TCGv r_tmp2 = tcg_temp_new();
1293
            int l1 = gen_new_label();
1294

    
1295
            save_cpu_state(ctx, 1);
1296
            tcg_gen_mov_tl(r_tmp1, t0);
1297
            tcg_gen_addi_tl(t0, t0, uimm);
1298

    
1299
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1300
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1301
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1302
            tcg_temp_free(r_tmp2);
1303
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1304
            /* operands of same sign, result different sign */
1305
            generate_exception(ctx, EXCP_OVERFLOW);
1306
            gen_set_label(l1);
1307
            tcg_temp_free(r_tmp1);
1308
        }
1309
        opn = "daddi";
1310
        break;
1311
    case OPC_DADDIU:
1312
        tcg_gen_addi_tl(t0, t0, uimm);
1313
        opn = "daddiu";
1314
        break;
1315
#endif
1316
    case OPC_SLTI:
1317
        gen_op_lti(t0, uimm);
1318
        opn = "slti";
1319
        break;
1320
    case OPC_SLTIU:
1321
        gen_op_ltiu(t0, uimm);
1322
        opn = "sltiu";
1323
        break;
1324
    case OPC_ANDI:
1325
        tcg_gen_andi_tl(t0, t0, uimm);
1326
        opn = "andi";
1327
        break;
1328
    case OPC_ORI:
1329
        tcg_gen_ori_tl(t0, t0, uimm);
1330
        opn = "ori";
1331
        break;
1332
    case OPC_XORI:
1333
        tcg_gen_xori_tl(t0, t0, uimm);
1334
        opn = "xori";
1335
        break;
1336
    case OPC_LUI:
1337
        opn = "lui";
1338
        break;
1339
    case OPC_SLL:
1340
        tcg_gen_shli_tl(t0, t0, uimm);
1341
        tcg_gen_ext32s_tl(t0, t0);
1342
        opn = "sll";
1343
        break;
1344
    case OPC_SRA:
1345
        tcg_gen_ext32s_tl(t0, t0);
1346
        tcg_gen_sari_tl(t0, t0, uimm);
1347
        opn = "sra";
1348
        break;
1349
    case OPC_SRL:
1350
        switch ((ctx->opcode >> 21) & 0x1f) {
1351
        case 0:
1352
            if (uimm != 0) {
1353
                tcg_gen_ext32u_tl(t0, t0);
1354
                tcg_gen_shri_tl(t0, t0, uimm);
1355
            } else {
1356
                tcg_gen_ext32s_tl(t0, t0);
1357
            }
1358
            opn = "srl";
1359
            break;
1360
        case 1:
1361
            /* rotr is decoded as srl on non-R2 CPUs */
1362
            if (env->insn_flags & ISA_MIPS32R2) {
1363
                if (uimm != 0) {
1364
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1365

    
1366
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1367
                    tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
1368
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1369
                    tcg_temp_free_i32(r_tmp1);
1370
                }
1371
                opn = "rotr";
1372
            } else {
1373
                if (uimm != 0) {
1374
                    tcg_gen_ext32u_tl(t0, t0);
1375
                    tcg_gen_shri_tl(t0, t0, uimm);
1376
                } else {
1377
                    tcg_gen_ext32s_tl(t0, t0);
1378
                }
1379
                opn = "srl";
1380
            }
1381
            break;
1382
        default:
1383
            MIPS_INVAL("invalid srl flag");
1384
            generate_exception(ctx, EXCP_RI);
1385
            break;
1386
        }
1387
        break;
1388
#if defined(TARGET_MIPS64)
1389
    case OPC_DSLL:
1390
        tcg_gen_shli_tl(t0, t0, uimm);
1391
        opn = "dsll";
1392
        break;
1393
    case OPC_DSRA:
1394
        tcg_gen_sari_tl(t0, t0, uimm);
1395
        opn = "dsra";
1396
        break;
1397
    case OPC_DSRL:
1398
        switch ((ctx->opcode >> 21) & 0x1f) {
1399
        case 0:
1400
            tcg_gen_shri_tl(t0, t0, uimm);
1401
            opn = "dsrl";
1402
            break;
1403
        case 1:
1404
            /* drotr is decoded as dsrl on non-R2 CPUs */
1405
            if (env->insn_flags & ISA_MIPS32R2) {
1406
                if (uimm != 0) {
1407
                    tcg_gen_rotri_tl(t0, t0, uimm);
1408
                }
1409
                opn = "drotr";
1410
            } else {
1411
                tcg_gen_shri_tl(t0, t0, uimm);
1412
                opn = "dsrl";
1413
            }
1414
            break;
1415
        default:
1416
            MIPS_INVAL("invalid dsrl flag");
1417
            generate_exception(ctx, EXCP_RI);
1418
            break;
1419
        }
1420
        break;
1421
    case OPC_DSLL32:
1422
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1423
        opn = "dsll32";
1424
        break;
1425
    case OPC_DSRA32:
1426
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1427
        opn = "dsra32";
1428
        break;
1429
    case OPC_DSRL32:
1430
        switch ((ctx->opcode >> 21) & 0x1f) {
1431
        case 0:
1432
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1433
            opn = "dsrl32";
1434
            break;
1435
        case 1:
1436
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1437
            if (env->insn_flags & ISA_MIPS32R2) {
1438
                tcg_gen_rotri_tl(t0, t0, uimm + 32);
1439
                opn = "drotr32";
1440
            } else {
1441
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1442
                opn = "dsrl32";
1443
            }
1444
            break;
1445
        default:
1446
            MIPS_INVAL("invalid dsrl32 flag");
1447
            generate_exception(ctx, EXCP_RI);
1448
            break;
1449
        }
1450
        break;
1451
#endif
1452
    default:
1453
        MIPS_INVAL(opn);
1454
        generate_exception(ctx, EXCP_RI);
1455
        goto out;
1456
    }
1457
    gen_store_gpr(t0, rt);
1458
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1459
 out:
1460
    tcg_temp_free(t0);
1461
}
1462

    
1463
/* Arithmetic */
1464
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1465
                       int rd, int rs, int rt)
1466
{
1467
    const char *opn = "arith";
1468
    TCGv t0 = tcg_temp_local_new();
1469
    TCGv t1 = tcg_temp_local_new();
1470

    
1471
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1472
       && opc != OPC_DADD && opc != OPC_DSUB) {
1473
        /* If no destination, treat it as a NOP.
1474
           For add & sub, we must generate the overflow exception when needed. */
1475
        MIPS_DEBUG("NOP");
1476
        goto out;
1477
    }
1478
    gen_load_gpr(t0, rs);
1479
    /* Specialcase the conventional move operation. */
1480
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1481
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1482
        gen_store_gpr(t0, rd);
1483
        goto out;
1484
    }
1485
    gen_load_gpr(t1, rt);
1486
    switch (opc) {
1487
    case OPC_ADD:
1488
        {
1489
            TCGv r_tmp1 = tcg_temp_new();
1490
            TCGv r_tmp2 = tcg_temp_new();
1491
            int l1 = gen_new_label();
1492

    
1493
            save_cpu_state(ctx, 1);
1494
            tcg_gen_ext32s_tl(r_tmp1, t0);
1495
            tcg_gen_ext32s_tl(r_tmp2, t1);
1496
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1497

    
1498
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1499
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1500
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1501
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1502
            tcg_temp_free(r_tmp2);
1503
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1504
            /* operands of same sign, result different sign */
1505
            generate_exception(ctx, EXCP_OVERFLOW);
1506
            gen_set_label(l1);
1507
            tcg_temp_free(r_tmp1);
1508

    
1509
            tcg_gen_ext32s_tl(t0, t0);
1510
        }
1511
        opn = "add";
1512
        break;
1513
    case OPC_ADDU:
1514
        tcg_gen_add_tl(t0, t0, t1);
1515
        tcg_gen_ext32s_tl(t0, t0);
1516
        opn = "addu";
1517
        break;
1518
    case OPC_SUB:
1519
        {
1520
            TCGv r_tmp1 = tcg_temp_new();
1521
            TCGv r_tmp2 = tcg_temp_new();
1522
            int l1 = gen_new_label();
1523

    
1524
            save_cpu_state(ctx, 1);
1525
            tcg_gen_ext32s_tl(r_tmp1, t0);
1526
            tcg_gen_ext32s_tl(r_tmp2, t1);
1527
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1528

    
1529
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1530
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1531
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1532
            tcg_temp_free(r_tmp2);
1533
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1534
            /* operands of different sign, first operand and result different sign */
1535
            generate_exception(ctx, EXCP_OVERFLOW);
1536
            gen_set_label(l1);
1537
            tcg_temp_free(r_tmp1);
1538

    
1539
            tcg_gen_ext32s_tl(t0, t0);
1540
        }
1541
        opn = "sub";
1542
        break;
1543
    case OPC_SUBU:
1544
        tcg_gen_sub_tl(t0, t0, t1);
1545
        tcg_gen_ext32s_tl(t0, t0);
1546
        opn = "subu";
1547
        break;
1548
#if defined(TARGET_MIPS64)
1549
    case OPC_DADD:
1550
        {
1551
            TCGv r_tmp1 = tcg_temp_new();
1552
            TCGv r_tmp2 = tcg_temp_new();
1553
            int l1 = gen_new_label();
1554

    
1555
            save_cpu_state(ctx, 1);
1556
            tcg_gen_mov_tl(r_tmp1, t0);
1557
            tcg_gen_add_tl(t0, t0, t1);
1558

    
1559
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1560
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1561
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1562
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1563
            tcg_temp_free(r_tmp2);
1564
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1565
            /* operands of same sign, result different sign */
1566
            generate_exception(ctx, EXCP_OVERFLOW);
1567
            gen_set_label(l1);
1568
            tcg_temp_free(r_tmp1);
1569
        }
1570
        opn = "dadd";
1571
        break;
1572
    case OPC_DADDU:
1573
        tcg_gen_add_tl(t0, t0, t1);
1574
        opn = "daddu";
1575
        break;
1576
    case OPC_DSUB:
1577
        {
1578
            TCGv r_tmp1 = tcg_temp_new();
1579
            TCGv r_tmp2 = tcg_temp_new();
1580
            int l1 = gen_new_label();
1581

    
1582
            save_cpu_state(ctx, 1);
1583
            tcg_gen_mov_tl(r_tmp1, t0);
1584
            tcg_gen_sub_tl(t0, t0, t1);
1585

    
1586
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1587
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1588
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1589
            tcg_temp_free(r_tmp2);
1590
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1591
            /* operands of different sign, first operand and result different sign */
1592
            generate_exception(ctx, EXCP_OVERFLOW);
1593
            gen_set_label(l1);
1594
            tcg_temp_free(r_tmp1);
1595
        }
1596
        opn = "dsub";
1597
        break;
1598
    case OPC_DSUBU:
1599
        tcg_gen_sub_tl(t0, t0, t1);
1600
        opn = "dsubu";
1601
        break;
1602
#endif
1603
    case OPC_SLT:
1604
        gen_op_lt(t0, t1);
1605
        opn = "slt";
1606
        break;
1607
    case OPC_SLTU:
1608
        gen_op_ltu(t0, t1);
1609
        opn = "sltu";
1610
        break;
1611
    case OPC_AND:
1612
        tcg_gen_and_tl(t0, t0, t1);
1613
        opn = "and";
1614
        break;
1615
    case OPC_NOR:
1616
        tcg_gen_or_tl(t0, t0, t1);
1617
        tcg_gen_not_tl(t0, t0);
1618
        opn = "nor";
1619
        break;
1620
    case OPC_OR:
1621
        tcg_gen_or_tl(t0, t0, t1);
1622
        opn = "or";
1623
        break;
1624
    case OPC_XOR:
1625
        tcg_gen_xor_tl(t0, t0, t1);
1626
        opn = "xor";
1627
        break;
1628
    case OPC_MUL:
1629
        tcg_gen_mul_tl(t0, t0, t1);
1630
        tcg_gen_ext32s_tl(t0, t0);
1631
        opn = "mul";
1632
        break;
1633
    case OPC_MOVN:
1634
        {
1635
            int l1 = gen_new_label();
1636

    
1637
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1638
            gen_store_gpr(t0, rd);
1639
            gen_set_label(l1);
1640
        }
1641
        opn = "movn";
1642
        goto print;
1643
    case OPC_MOVZ:
1644
        {
1645
            int l1 = gen_new_label();
1646

    
1647
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1648
            gen_store_gpr(t0, rd);
1649
            gen_set_label(l1);
1650
        }
1651
        opn = "movz";
1652
        goto print;
1653
    case OPC_SLLV:
1654
        tcg_gen_andi_tl(t0, t0, 0x1f);
1655
        tcg_gen_shl_tl(t0, t1, t0);
1656
        tcg_gen_ext32s_tl(t0, t0);
1657
        opn = "sllv";
1658
        break;
1659
    case OPC_SRAV:
1660
        tcg_gen_ext32s_tl(t1, t1);
1661
        tcg_gen_andi_tl(t0, t0, 0x1f);
1662
        tcg_gen_sar_tl(t0, t1, t0);
1663
        opn = "srav";
1664
        break;
1665
    case OPC_SRLV:
1666
        switch ((ctx->opcode >> 6) & 0x1f) {
1667
        case 0:
1668
            tcg_gen_ext32u_tl(t1, t1);
1669
            tcg_gen_andi_tl(t0, t0, 0x1f);
1670
            tcg_gen_shr_tl(t0, t1, t0);
1671
            tcg_gen_ext32s_tl(t0, t0);
1672
            opn = "srlv";
1673
            break;
1674
        case 1:
1675
            /* rotrv is decoded as srlv on non-R2 CPUs */
1676
            if (env->insn_flags & ISA_MIPS32R2) {
1677
                int l1 = gen_new_label();
1678
                int l2 = gen_new_label();
1679

    
1680
                tcg_gen_andi_tl(t0, t0, 0x1f);
1681
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1682
                {
1683
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1684
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1685

    
1686
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1687
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1688
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1689
                    tcg_temp_free_i32(r_tmp1);
1690
                    tcg_temp_free_i32(r_tmp2);
1691
                    tcg_gen_br(l2);
1692
                }
1693
                gen_set_label(l1);
1694
                tcg_gen_mov_tl(t0, t1);
1695
                gen_set_label(l2);
1696
                opn = "rotrv";
1697
            } else {
1698
                tcg_gen_ext32u_tl(t1, t1);
1699
                tcg_gen_andi_tl(t0, t0, 0x1f);
1700
                tcg_gen_shr_tl(t0, t1, t0);
1701
                tcg_gen_ext32s_tl(t0, t0);
1702
                opn = "srlv";
1703
            }
1704
            break;
1705
        default:
1706
            MIPS_INVAL("invalid srlv flag");
1707
            generate_exception(ctx, EXCP_RI);
1708
            break;
1709
        }
1710
        break;
1711
#if defined(TARGET_MIPS64)
1712
    case OPC_DSLLV:
1713
        tcg_gen_andi_tl(t0, t0, 0x3f);
1714
        tcg_gen_shl_tl(t0, t1, t0);
1715
        opn = "dsllv";
1716
        break;
1717
    case OPC_DSRAV:
1718
        tcg_gen_andi_tl(t0, t0, 0x3f);
1719
        tcg_gen_sar_tl(t0, t1, t0);
1720
        opn = "dsrav";
1721
        break;
1722
    case OPC_DSRLV:
1723
        switch ((ctx->opcode >> 6) & 0x1f) {
1724
        case 0:
1725
            tcg_gen_andi_tl(t0, t0, 0x3f);
1726
            tcg_gen_shr_tl(t0, t1, t0);
1727
            opn = "dsrlv";
1728
            break;
1729
        case 1:
1730
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1731
            if (env->insn_flags & ISA_MIPS32R2) {
1732
                int l1 = gen_new_label();
1733
                int l2 = gen_new_label();
1734

    
1735
                tcg_gen_andi_tl(t0, t0, 0x3f);
1736
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1737
                {
1738
                    tcg_gen_rotr_tl(t0, t1, t0);
1739
                    tcg_gen_br(l2);
1740
                }
1741
                gen_set_label(l1);
1742
                tcg_gen_mov_tl(t0, t1);
1743
                gen_set_label(l2);
1744
                opn = "drotrv";
1745
            } else {
1746
                tcg_gen_andi_tl(t0, t0, 0x3f);
1747
                tcg_gen_shr_tl(t0, t1, t0);
1748
                opn = "dsrlv";
1749
            }
1750
            break;
1751
        default:
1752
            MIPS_INVAL("invalid dsrlv flag");
1753
            generate_exception(ctx, EXCP_RI);
1754
            break;
1755
        }
1756
        break;
1757
#endif
1758
    default:
1759
        MIPS_INVAL(opn);
1760
        generate_exception(ctx, EXCP_RI);
1761
        goto out;
1762
    }
1763
    gen_store_gpr(t0, rd);
1764
 print:
1765
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1766
 out:
1767
    tcg_temp_free(t0);
1768
    tcg_temp_free(t1);
1769
}
1770

    
1771
/* Arithmetic on HI/LO registers */
1772
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1773
{
1774
    const char *opn = "hilo";
1775

    
1776
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1777
        /* Treat as NOP. */
1778
        MIPS_DEBUG("NOP");
1779
        return;
1780
    }
1781
    switch (opc) {
1782
    case OPC_MFHI:
1783
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1784
        opn = "mfhi";
1785
        break;
1786
    case OPC_MFLO:
1787
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1788
        opn = "mflo";
1789
        break;
1790
    case OPC_MTHI:
1791
        if (reg != 0)
1792
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1793
        else
1794
            tcg_gen_movi_tl(cpu_HI[0], 0);
1795
        opn = "mthi";
1796
        break;
1797
    case OPC_MTLO:
1798
        if (reg != 0)
1799
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1800
        else
1801
            tcg_gen_movi_tl(cpu_LO[0], 0);
1802
        opn = "mtlo";
1803
        break;
1804
    default:
1805
        MIPS_INVAL(opn);
1806
        generate_exception(ctx, EXCP_RI);
1807
        return;
1808
    }
1809
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1810
}
1811

    
1812
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1813
                        int rs, int rt)
1814
{
1815
    const char *opn = "mul/div";
1816
    TCGv t0 = tcg_temp_local_new();
1817
    TCGv t1 = tcg_temp_local_new();
1818

    
1819
    gen_load_gpr(t0, rs);
1820
    gen_load_gpr(t1, rt);
1821
    switch (opc) {
1822
    case OPC_DIV:
1823
        {
1824
            int l1 = gen_new_label();
1825

    
1826
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1827
            {
1828
                int l2 = gen_new_label();
1829
                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1830
                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1831
                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1832

    
1833
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1834
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1835
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1836
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1837
                tcg_gen_ext32s_tl(cpu_LO[0], t0);
1838
                tcg_gen_movi_tl(cpu_HI[0], 0);
1839
                tcg_gen_br(l1);
1840
                gen_set_label(l2);
1841
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1842
                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1843
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1844
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1845
                tcg_temp_free_i32(r_tmp1);
1846
                tcg_temp_free_i32(r_tmp2);
1847
                tcg_temp_free_i32(r_tmp3);
1848
            }
1849
            gen_set_label(l1);
1850
        }
1851
        opn = "div";
1852
        break;
1853
    case OPC_DIVU:
1854
        {
1855
            int l1 = gen_new_label();
1856

    
1857
            tcg_gen_ext32s_tl(t1, t1);
1858
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1859
            {
1860
                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1861
                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1862
                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1863

    
1864
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1865
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1866
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1867
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1868
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1869
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1870
                tcg_temp_free_i32(r_tmp1);
1871
                tcg_temp_free_i32(r_tmp2);
1872
                tcg_temp_free_i32(r_tmp3);
1873
            }
1874
            gen_set_label(l1);
1875
        }
1876
        opn = "divu";
1877
        break;
1878
    case OPC_MULT:
1879
        {
1880
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1881
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1882

    
1883
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1884
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1885
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1886
            tcg_temp_free_i64(r_tmp2);
1887
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1888
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1889
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1890
            tcg_temp_free_i64(r_tmp1);
1891
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1892
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1893
        }
1894
        opn = "mult";
1895
        break;
1896
    case OPC_MULTU:
1897
        {
1898
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1899
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1900

    
1901
            tcg_gen_ext32u_tl(t0, t0);
1902
            tcg_gen_ext32u_tl(t1, t1);
1903
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1904
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1905
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1906
            tcg_temp_free_i64(r_tmp2);
1907
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1908
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1909
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1910
            tcg_temp_free_i64(r_tmp1);
1911
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1912
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1913
        }
1914
        opn = "multu";
1915
        break;
1916
#if defined(TARGET_MIPS64)
1917
    case OPC_DDIV:
1918
        {
1919
            int l1 = gen_new_label();
1920

    
1921
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1922
            {
1923
                int l2 = gen_new_label();
1924

    
1925
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1926
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1927
                tcg_gen_mov_tl(cpu_LO[0], t0);
1928
                tcg_gen_movi_tl(cpu_HI[0], 0);
1929
                tcg_gen_br(l1);
1930
                gen_set_label(l2);
1931
                tcg_gen_div_i64(cpu_LO[0], t0, t1);
1932
                tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1933
            }
1934
            gen_set_label(l1);
1935
        }
1936
        opn = "ddiv";
1937
        break;
1938
    case OPC_DDIVU:
1939
        {
1940
            int l1 = gen_new_label();
1941

    
1942
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1943
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1944
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1945
            gen_set_label(l1);
1946
        }
1947
        opn = "ddivu";
1948
        break;
1949
    case OPC_DMULT:
1950
        gen_helper_dmult(t0, t1);
1951
        opn = "dmult";
1952
        break;
1953
    case OPC_DMULTU:
1954
        gen_helper_dmultu(t0, t1);
1955
        opn = "dmultu";
1956
        break;
1957
#endif
1958
    case OPC_MADD:
1959
        {
1960
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1961
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1962

    
1963
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1964
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1965
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1966
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1967
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1968
            tcg_temp_free_i64(r_tmp2);
1969
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1970
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1971
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1972
            tcg_temp_free_i64(r_tmp1);
1973
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1974
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1975
        }
1976
        opn = "madd";
1977
        break;
1978
    case OPC_MADDU:
1979
       {
1980
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1981
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1982

    
1983
            tcg_gen_ext32u_tl(t0, t0);
1984
            tcg_gen_ext32u_tl(t1, t1);
1985
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1986
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1987
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1988
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1989
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1990
            tcg_temp_free_i64(r_tmp2);
1991
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1992
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1993
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1994
            tcg_temp_free_i64(r_tmp1);
1995
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1996
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1997
        }
1998
        opn = "maddu";
1999
        break;
2000
    case OPC_MSUB:
2001
        {
2002
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2003
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2004

    
2005
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2006
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2007
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2008
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2009
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2010
            tcg_temp_free_i64(r_tmp2);
2011
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2012
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2013
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2014
            tcg_temp_free_i64(r_tmp1);
2015
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2016
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2017
        }
2018
        opn = "msub";
2019
        break;
2020
    case OPC_MSUBU:
2021
        {
2022
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2023
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2024

    
2025
            tcg_gen_ext32u_tl(t0, t0);
2026
            tcg_gen_ext32u_tl(t1, t1);
2027
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2028
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2029
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2030
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2031
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2032
            tcg_temp_free_i64(r_tmp2);
2033
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2034
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2035
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2036
            tcg_temp_free_i64(r_tmp1);
2037
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2038
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2039
        }
2040
        opn = "msubu";
2041
        break;
2042
    default:
2043
        MIPS_INVAL(opn);
2044
        generate_exception(ctx, EXCP_RI);
2045
        goto out;
2046
    }
2047
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2048
 out:
2049
    tcg_temp_free(t0);
2050
    tcg_temp_free(t1);
2051
}
2052

    
2053
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2054
                            int rd, int rs, int rt)
2055
{
2056
    const char *opn = "mul vr54xx";
2057
    TCGv t0 = tcg_temp_local_new();
2058
    TCGv t1 = tcg_temp_local_new();
2059

    
2060
    gen_load_gpr(t0, rs);
2061
    gen_load_gpr(t1, rt);
2062

    
2063
    switch (opc) {
2064
    case OPC_VR54XX_MULS:
2065
        gen_helper_muls(t0, t0, t1);
2066
        opn = "muls";
2067
        break;
2068
    case OPC_VR54XX_MULSU:
2069
        gen_helper_mulsu(t0, t0, t1);
2070
        opn = "mulsu";
2071
        break;
2072
    case OPC_VR54XX_MACC:
2073
        gen_helper_macc(t0, t0, t1);
2074
        opn = "macc";
2075
        break;
2076
    case OPC_VR54XX_MACCU:
2077
        gen_helper_maccu(t0, t0, t1);
2078
        opn = "maccu";
2079
        break;
2080
    case OPC_VR54XX_MSAC:
2081
        gen_helper_msac(t0, t0, t1);
2082
        opn = "msac";
2083
        break;
2084
    case OPC_VR54XX_MSACU:
2085
        gen_helper_msacu(t0, t0, t1);
2086
        opn = "msacu";
2087
        break;
2088
    case OPC_VR54XX_MULHI:
2089
        gen_helper_mulhi(t0, t0, t1);
2090
        opn = "mulhi";
2091
        break;
2092
    case OPC_VR54XX_MULHIU:
2093
        gen_helper_mulhiu(t0, t0, t1);
2094
        opn = "mulhiu";
2095
        break;
2096
    case OPC_VR54XX_MULSHI:
2097
        gen_helper_mulshi(t0, t0, t1);
2098
        opn = "mulshi";
2099
        break;
2100
    case OPC_VR54XX_MULSHIU:
2101
        gen_helper_mulshiu(t0, t0, t1);
2102
        opn = "mulshiu";
2103
        break;
2104
    case OPC_VR54XX_MACCHI:
2105
        gen_helper_macchi(t0, t0, t1);
2106
        opn = "macchi";
2107
        break;
2108
    case OPC_VR54XX_MACCHIU:
2109
        gen_helper_macchiu(t0, t0, t1);
2110
        opn = "macchiu";
2111
        break;
2112
    case OPC_VR54XX_MSACHI:
2113
        gen_helper_msachi(t0, t0, t1);
2114
        opn = "msachi";
2115
        break;
2116
    case OPC_VR54XX_MSACHIU:
2117
        gen_helper_msachiu(t0, t0, t1);
2118
        opn = "msachiu";
2119
        break;
2120
    default:
2121
        MIPS_INVAL("mul vr54xx");
2122
        generate_exception(ctx, EXCP_RI);
2123
        goto out;
2124
    }
2125
    gen_store_gpr(t0, rd);
2126
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2127

    
2128
 out:
2129
    tcg_temp_free(t0);
2130
    tcg_temp_free(t1);
2131
}
2132

    
2133
static void gen_cl (DisasContext *ctx, uint32_t opc,
2134
                    int rd, int rs)
2135
{
2136
    const char *opn = "CLx";
2137
    TCGv t0 = tcg_temp_local_new();
2138

    
2139
    if (rd == 0) {
2140
        /* Treat as NOP. */
2141
        MIPS_DEBUG("NOP");
2142
        goto out;
2143
    }
2144
    gen_load_gpr(t0, rs);
2145
    switch (opc) {
2146
    case OPC_CLO:
2147
        gen_helper_clo(t0, t0);
2148
        opn = "clo";
2149
        break;
2150
    case OPC_CLZ:
2151
        gen_helper_clz(t0, t0);
2152
        opn = "clz";
2153
        break;
2154
#if defined(TARGET_MIPS64)
2155
    case OPC_DCLO:
2156
        gen_helper_dclo(t0, t0);
2157
        opn = "dclo";
2158
        break;
2159
    case OPC_DCLZ:
2160
        gen_helper_dclz(t0, t0);
2161
        opn = "dclz";
2162
        break;
2163
#endif
2164
    default:
2165
        MIPS_INVAL(opn);
2166
        generate_exception(ctx, EXCP_RI);
2167
        goto out;
2168
    }
2169
    gen_store_gpr(t0, rd);
2170
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2171

    
2172
 out:
2173
    tcg_temp_free(t0);
2174
}
2175

    
2176
/* Traps */
2177
static void gen_trap (DisasContext *ctx, uint32_t opc,
2178
                      int rs, int rt, int16_t imm)
2179
{
2180
    int cond;
2181
    TCGv t0 = tcg_temp_local_new();
2182
    TCGv t1 = tcg_temp_local_new();
2183

    
2184
    cond = 0;
2185
    /* Load needed operands */
2186
    switch (opc) {
2187
    case OPC_TEQ:
2188
    case OPC_TGE:
2189
    case OPC_TGEU:
2190
    case OPC_TLT:
2191
    case OPC_TLTU:
2192
    case OPC_TNE:
2193
        /* Compare two registers */
2194
        if (rs != rt) {
2195
            gen_load_gpr(t0, rs);
2196
            gen_load_gpr(t1, rt);
2197
            cond = 1;
2198
        }
2199
        break;
2200
    case OPC_TEQI:
2201
    case OPC_TGEI:
2202
    case OPC_TGEIU:
2203
    case OPC_TLTI:
2204
    case OPC_TLTIU:
2205
    case OPC_TNEI:
2206
        /* Compare register to immediate */
2207
        if (rs != 0 || imm != 0) {
2208
            gen_load_gpr(t0, rs);
2209
            tcg_gen_movi_tl(t1, (int32_t)imm);
2210
            cond = 1;
2211
        }
2212
        break;
2213
    }
2214
    if (cond == 0) {
2215
        switch (opc) {
2216
        case OPC_TEQ:   /* rs == rs */
2217
        case OPC_TEQI:  /* r0 == 0  */
2218
        case OPC_TGE:   /* rs >= rs */
2219
        case OPC_TGEI:  /* r0 >= 0  */
2220
        case OPC_TGEU:  /* rs >= rs unsigned */
2221
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2222
            /* Always trap */
2223
            tcg_gen_movi_tl(t0, 1);
2224
            break;
2225
        case OPC_TLT:   /* rs < rs           */
2226
        case OPC_TLTI:  /* r0 < 0            */
2227
        case OPC_TLTU:  /* rs < rs unsigned  */
2228
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2229
        case OPC_TNE:   /* rs != rs          */
2230
        case OPC_TNEI:  /* r0 != 0           */
2231
            /* Never trap: treat as NOP. */
2232
            goto out;
2233
        default:
2234
            MIPS_INVAL("trap");
2235
            generate_exception(ctx, EXCP_RI);
2236
            goto out;
2237
        }
2238
    } else {
2239
        switch (opc) {
2240
        case OPC_TEQ:
2241
        case OPC_TEQI:
2242
            gen_op_eq(t0, t1);
2243
            break;
2244
        case OPC_TGE:
2245
        case OPC_TGEI:
2246
            gen_op_ge(t0, t1);
2247
            break;
2248
        case OPC_TGEU:
2249
        case OPC_TGEIU:
2250
            gen_op_geu(t0, t1);
2251
            break;
2252
        case OPC_TLT:
2253
        case OPC_TLTI:
2254
            gen_op_lt(t0, t1);
2255
            break;
2256
        case OPC_TLTU:
2257
        case OPC_TLTIU:
2258
            gen_op_ltu(t0, t1);
2259
            break;
2260
        case OPC_TNE:
2261
        case OPC_TNEI:
2262
            gen_op_ne(t0, t1);
2263
            break;
2264
        default:
2265
            MIPS_INVAL("trap");
2266
            generate_exception(ctx, EXCP_RI);
2267
            goto out;
2268
        }
2269
    }
2270
    save_cpu_state(ctx, 1);
2271
    {
2272
        int l1 = gen_new_label();
2273

    
2274
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2275
        gen_helper_0i(raise_exception, EXCP_TRAP);
2276
        gen_set_label(l1);
2277
    }
2278
    ctx->bstate = BS_STOP;
2279
 out:
2280
    tcg_temp_free(t0);
2281
    tcg_temp_free(t1);
2282
}
2283

    
2284
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2285
{
2286
    TranslationBlock *tb;
2287
    tb = ctx->tb;
2288
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2289
        tcg_gen_goto_tb(n);
2290
        gen_save_pc(dest);
2291
        tcg_gen_exit_tb((long)tb + n);
2292
    } else {
2293
        gen_save_pc(dest);
2294
        tcg_gen_exit_tb(0);
2295
    }
2296
}
2297

    
2298
/* Branches (before delay slot) */
2299
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2300
                                int rs, int rt, int32_t offset)
2301
{
2302
    target_ulong btgt = -1;
2303
    int blink = 0;
2304
    int bcond_compute = 0;
2305
    TCGv t0 = tcg_temp_local_new();
2306
    TCGv t1 = tcg_temp_local_new();
2307

    
2308
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2309
#ifdef MIPS_DEBUG_DISAS
2310
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2311
#endif
2312
        generate_exception(ctx, EXCP_RI);
2313
        goto out;
2314
    }
2315

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

    
2528
    ctx->btarget = btgt;
2529
    if (blink > 0) {
2530
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2531
        gen_store_gpr(t0, blink);
2532
    }
2533

    
2534
 out:
2535
    tcg_temp_free(t0);
2536
    tcg_temp_free(t1);
2537
}
2538

    
2539
/* special3 bitfield operations */
2540
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2541
                        int rs, int lsb, int msb)
2542
{
2543
    TCGv t0 = tcg_temp_new();
2544
    TCGv t1 = tcg_temp_new();
2545
    target_ulong mask;
2546

    
2547
    gen_load_gpr(t1, rs);
2548
    switch (opc) {
2549
    case OPC_EXT:
2550
        if (lsb + msb > 31)
2551
            goto fail;
2552
        tcg_gen_shri_tl(t0, t1, lsb);
2553
        if (msb != 31) {
2554
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2555
        } else {
2556
            tcg_gen_ext32s_tl(t0, t0);
2557
        }
2558
        break;
2559
#if defined(TARGET_MIPS64)
2560
    case OPC_DEXTM:
2561
        tcg_gen_shri_tl(t0, t1, lsb);
2562
        if (msb != 31) {
2563
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2564
        }
2565
        break;
2566
    case OPC_DEXTU:
2567
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2568
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2569
        break;
2570
    case OPC_DEXT:
2571
        tcg_gen_shri_tl(t0, t1, lsb);
2572
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2573
        break;
2574
#endif
2575
    case OPC_INS:
2576
        if (lsb > msb)
2577
            goto fail;
2578
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2579
        gen_load_gpr(t0, rt);
2580
        tcg_gen_andi_tl(t0, t0, ~mask);
2581
        tcg_gen_shli_tl(t1, t1, lsb);
2582
        tcg_gen_andi_tl(t1, t1, mask);
2583
        tcg_gen_or_tl(t0, t0, t1);
2584
        tcg_gen_ext32s_tl(t0, t0);
2585
        break;
2586
#if defined(TARGET_MIPS64)
2587
    case OPC_DINSM:
2588
        if (lsb > msb)
2589
            goto fail;
2590
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2591
        gen_load_gpr(t0, rt);
2592
        tcg_gen_andi_tl(t0, t0, ~mask);
2593
        tcg_gen_shli_tl(t1, t1, lsb);
2594
        tcg_gen_andi_tl(t1, t1, mask);
2595
        tcg_gen_or_tl(t0, t0, t1);
2596
        break;
2597
    case OPC_DINSU:
2598
        if (lsb > msb)
2599
            goto fail;
2600
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2601
        gen_load_gpr(t0, rt);
2602
        tcg_gen_andi_tl(t0, t0, ~mask);
2603
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2604
        tcg_gen_andi_tl(t1, t1, mask);
2605
        tcg_gen_or_tl(t0, t0, t1);
2606
        break;
2607
    case OPC_DINS:
2608
        if (lsb > msb)
2609
            goto fail;
2610
        gen_load_gpr(t0, rt);
2611
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2612
        gen_load_gpr(t0, rt);
2613
        tcg_gen_andi_tl(t0, t0, ~mask);
2614
        tcg_gen_shli_tl(t1, t1, lsb);
2615
        tcg_gen_andi_tl(t1, t1, mask);
2616
        tcg_gen_or_tl(t0, t0, t1);
2617
        break;
2618
#endif
2619
    default:
2620
fail:
2621
        MIPS_INVAL("bitops");
2622
        generate_exception(ctx, EXCP_RI);
2623
        tcg_temp_free(t0);
2624
        tcg_temp_free(t1);
2625
        return;
2626
    }
2627
    gen_store_gpr(t0, rt);
2628
    tcg_temp_free(t0);
2629
    tcg_temp_free(t1);
2630
}
2631

    
2632
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2633
{
2634
    TCGv t0 = tcg_temp_new();
2635
    TCGv t1 = tcg_temp_new();
2636

    
2637
    gen_load_gpr(t1, rt);
2638
    switch (op2) {
2639
    case OPC_WSBH:
2640
        tcg_gen_shri_tl(t0, t1, 8);
2641
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
2642
        tcg_gen_shli_tl(t1, t1, 8);
2643
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
2644
        tcg_gen_or_tl(t0, t0, t1);
2645
        tcg_gen_ext32s_tl(t0, t0);
2646
        break;
2647
    case OPC_SEB:
2648
        tcg_gen_ext8s_tl(t0, t1);
2649
        break;
2650
    case OPC_SEH:
2651
        tcg_gen_ext16s_tl(t0, t1);
2652
        break;
2653
#if defined(TARGET_MIPS64)
2654
    case OPC_DSBH:
2655
        gen_load_gpr(t1, rt);
2656
        tcg_gen_shri_tl(t0, t1, 8);
2657
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
2658
        tcg_gen_shli_tl(t1, t1, 8);
2659
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
2660
        tcg_gen_or_tl(t0, t0, t1);
2661
        break;
2662
    case OPC_DSHD:
2663
        gen_load_gpr(t1, rt);
2664
        tcg_gen_shri_tl(t0, t1, 16);
2665
        tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
2666
        tcg_gen_shli_tl(t1, t1, 16);
2667
        tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
2668
        tcg_gen_or_tl(t1, t0, t1);
2669
        tcg_gen_shri_tl(t0, t1, 32);
2670
        tcg_gen_shli_tl(t1, t1, 32);
2671
        tcg_gen_or_tl(t0, t0, t1);
2672
        break;
2673
#endif
2674
    default:
2675
        MIPS_INVAL("bsfhl");
2676
        generate_exception(ctx, EXCP_RI);
2677
        tcg_temp_free(t0);
2678
        tcg_temp_free(t1);
2679
        return;
2680
    }
2681
    gen_store_gpr(t0, rd);
2682
    tcg_temp_free(t0);
2683
    tcg_temp_free(t1);
2684
}
2685

    
2686
#ifndef CONFIG_USER_ONLY
2687
/* CP0 (MMU and control) */
2688
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2689
{
2690
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2691

    
2692
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2693
    tcg_gen_ext_i32_tl(t, r_tmp);
2694
    tcg_temp_free_i32(r_tmp);
2695
}
2696

    
2697
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2698
{
2699
    tcg_gen_ld_tl(t, cpu_env, off);
2700
    tcg_gen_ext32s_tl(t, t);
2701
}
2702

    
2703
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2704
{
2705
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2706

    
2707
    tcg_gen_trunc_tl_i32(r_tmp, t);
2708
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2709
    tcg_temp_free_i32(r_tmp);
2710
}
2711

    
2712
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2713
{
2714
    tcg_gen_ext32s_tl(t, t);
2715
    tcg_gen_st_tl(t, cpu_env, off);
2716
}
2717

    
2718
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2719
{
2720
    const char *rn = "invalid";
2721

    
2722
    if (sel != 0)
2723
        check_insn(env, ctx, ISA_MIPS32);
2724

    
2725
    switch (reg) {
2726
    case 0:
2727
        switch (sel) {
2728
        case 0:
2729
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
2730
            rn = "Index";
2731
            break;
2732
        case 1:
2733
            check_insn(env, ctx, ASE_MT);
2734
            gen_helper_mfc0_mvpcontrol(t0);
2735
            rn = "MVPControl";
2736
            break;
2737
        case 2:
2738
            check_insn(env, ctx, ASE_MT);
2739
            gen_helper_mfc0_mvpconf0(t0);
2740
            rn = "MVPConf0";
2741
            break;
2742
        case 3:
2743
            check_insn(env, ctx, ASE_MT);
2744
            gen_helper_mfc0_mvpconf1(t0);
2745
            rn = "MVPConf1";
2746
            break;
2747
        default:
2748
            goto die;
2749
        }
2750
        break;
2751
    case 1:
2752
        switch (sel) {
2753
        case 0:
2754
            gen_helper_mfc0_random(t0);
2755
            rn = "Random";
2756
            break;
2757
        case 1:
2758
            check_insn(env, ctx, ASE_MT);
2759
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
2760
            rn = "VPEControl";
2761
            break;
2762
        case 2:
2763
            check_insn(env, ctx, ASE_MT);
2764
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
2765
            rn = "VPEConf0";
2766
            break;
2767
        case 3:
2768
            check_insn(env, ctx, ASE_MT);
2769
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
2770
            rn = "VPEConf1";
2771
            break;
2772
        case 4:
2773
            check_insn(env, ctx, ASE_MT);
2774
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
2775
            rn = "YQMask";
2776
            break;
2777
        case 5:
2778
            check_insn(env, ctx, ASE_MT);
2779
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
2780
            rn = "VPESchedule";
2781
            break;
2782
        case 6:
2783
            check_insn(env, ctx, ASE_MT);
2784
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
2785
            rn = "VPEScheFBack";
2786
            break;
2787
        case 7:
2788
            check_insn(env, ctx, ASE_MT);
2789
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
2790
            rn = "VPEOpt";
2791
            break;
2792
        default:
2793
            goto die;
2794
        }
2795
        break;
2796
    case 2:
2797
        switch (sel) {
2798
        case 0:
2799
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2800
            tcg_gen_ext32s_tl(t0, t0);
2801
            rn = "EntryLo0";
2802
            break;
2803
        case 1:
2804
            check_insn(env, ctx, ASE_MT);
2805
            gen_helper_mfc0_tcstatus(t0);
2806
            rn = "TCStatus";
2807
            break;
2808
        case 2:
2809
            check_insn(env, ctx, ASE_MT);
2810
            gen_helper_mfc0_tcbind(t0);
2811
            rn = "TCBind";
2812
            break;
2813
        case 3:
2814
            check_insn(env, ctx, ASE_MT);
2815
            gen_helper_mfc0_tcrestart(t0);
2816
            rn = "TCRestart";
2817
            break;
2818
        case 4:
2819
            check_insn(env, ctx, ASE_MT);
2820
            gen_helper_mfc0_tchalt(t0);
2821
            rn = "TCHalt";
2822
            break;
2823
        case 5:
2824
            check_insn(env, ctx, ASE_MT);
2825
            gen_helper_mfc0_tccontext(t0);
2826
            rn = "TCContext";
2827
            break;
2828
        case 6:
2829
            check_insn(env, ctx, ASE_MT);
2830
            gen_helper_mfc0_tcschedule(t0);
2831
            rn = "TCSchedule";
2832
            break;
2833
        case 7:
2834
            check_insn(env, ctx, ASE_MT);
2835
            gen_helper_mfc0_tcschefback(t0);
2836
            rn = "TCScheFBack";
2837
            break;
2838
        default:
2839
            goto die;
2840
        }
2841
        break;
2842
    case 3:
2843
        switch (sel) {
2844
        case 0:
2845
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
2846
            tcg_gen_ext32s_tl(t0, t0);
2847
            rn = "EntryLo1";
2848
            break;
2849
        default:
2850
            goto die;
2851
        }
2852
        break;
2853
    case 4:
2854
        switch (sel) {
2855
        case 0:
2856
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
2857
            tcg_gen_ext32s_tl(t0, t0);
2858
            rn = "Context";
2859
            break;
2860
        case 1:
2861
//            gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
2862
            rn = "ContextConfig";
2863
//            break;
2864
        default:
2865
            goto die;
2866
        }
2867
        break;
2868
    case 5:
2869
        switch (sel) {
2870
        case 0:
2871
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
2872
            rn = "PageMask";
2873
            break;
2874
        case 1:
2875
            check_insn(env, ctx, ISA_MIPS32R2);
2876
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
2877
            rn = "PageGrain";
2878
            break;
2879
        default:
2880
            goto die;
2881
        }
2882
        break;
2883
    case 6:
2884
        switch (sel) {
2885
        case 0:
2886
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
2887
            rn = "Wired";
2888
            break;
2889
        case 1:
2890
            check_insn(env, ctx, ISA_MIPS32R2);
2891
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
2892
            rn = "SRSConf0";
2893
            break;
2894
        case 2:
2895
            check_insn(env, ctx, ISA_MIPS32R2);
2896
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
2897
            rn = "SRSConf1";
2898
            break;
2899
        case 3:
2900
            check_insn(env, ctx, ISA_MIPS32R2);
2901
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
2902
            rn = "SRSConf2";
2903
            break;
2904
        case 4:
2905
            check_insn(env, ctx, ISA_MIPS32R2);
2906
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
2907
            rn = "SRSConf3";
2908
            break;
2909
        case 5:
2910
            check_insn(env, ctx, ISA_MIPS32R2);
2911
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
2912
            rn = "SRSConf4";
2913
            break;
2914
        default:
2915
            goto die;
2916
        }
2917
        break;
2918
    case 7:
2919
        switch (sel) {
2920
        case 0:
2921
            check_insn(env, ctx, ISA_MIPS32R2);
2922
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
2923
            rn = "HWREna";
2924
            break;
2925
        default:
2926
            goto die;
2927
        }
2928
        break;
2929
    case 8:
2930
        switch (sel) {
2931
        case 0:
2932
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
2933
            tcg_gen_ext32s_tl(t0, t0);
2934
            rn = "BadVAddr";
2935
            break;
2936
        default:
2937
            goto die;
2938
       }
2939
        break;
2940
    case 9:
2941
        switch (sel) {
2942
        case 0:
2943
            /* Mark as an IO operation because we read the time.  */
2944
            if (use_icount)
2945
                gen_io_start();
2946
            gen_helper_mfc0_count(t0);
2947
            if (use_icount) {
2948
                gen_io_end();
2949
                ctx->bstate = BS_STOP;
2950
            }
2951
            rn = "Count";
2952
            break;
2953
        /* 6,7 are implementation dependent */
2954
        default:
2955
            goto die;
2956
        }
2957
        break;
2958
    case 10:
2959
        switch (sel) {
2960
        case 0:
2961
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
2962
            tcg_gen_ext32s_tl(t0, t0);
2963
            rn = "EntryHi";
2964
            break;
2965
        default:
2966
            goto die;
2967
        }
2968
        break;
2969
    case 11:
2970
        switch (sel) {
2971
        case 0:
2972
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
2973
            rn = "Compare";
2974
            break;
2975
        /* 6,7 are implementation dependent */
2976
        default:
2977
            goto die;
2978
        }
2979
        break;
2980
    case 12:
2981
        switch (sel) {
2982
        case 0:
2983
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
2984
            rn = "Status";
2985
            break;
2986
        case 1:
2987
            check_insn(env, ctx, ISA_MIPS32R2);
2988
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
2989
            rn = "IntCtl";
2990
            break;
2991
        case 2:
2992
            check_insn(env, ctx, ISA_MIPS32R2);
2993
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
2994
            rn = "SRSCtl";
2995
            break;
2996
        case 3:
2997
            check_insn(env, ctx, ISA_MIPS32R2);
2998
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
2999
            rn = "SRSMap";
3000
            break;
3001
        default:
3002
            goto die;
3003
       }
3004
        break;
3005
    case 13:
3006
        switch (sel) {
3007
        case 0:
3008
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
3009
            rn = "Cause";
3010
            break;
3011
        default:
3012
            goto die;
3013
       }
3014
        break;
3015
    case 14:
3016
        switch (sel) {
3017
        case 0:
3018
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
3019
            tcg_gen_ext32s_tl(t0, t0);
3020
            rn = "EPC";
3021
            break;
3022
        default:
3023
            goto die;
3024
        }
3025
        break;
3026
    case 15:
3027
        switch (sel) {
3028
        case 0:
3029
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
3030
            rn = "PRid";
3031
            break;
3032
        case 1:
3033
            check_insn(env, ctx, ISA_MIPS32R2);
3034
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
3035
            rn = "EBase";
3036
            break;
3037
        default:
3038
            goto die;
3039
       }
3040
        break;
3041
    case 16:
3042
        switch (sel) {
3043
        case 0:
3044
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
3045
            rn = "Config";
3046
            break;
3047
        case 1:
3048
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
3049
            rn = "Config1";
3050
            break;
3051
        case 2:
3052
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
3053
            rn = "Config2";
3054
            break;
3055
        case 3:
3056
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
3057
            rn = "Config3";
3058
            break;
3059
        /* 4,5 are reserved */
3060
        /* 6,7 are implementation dependent */
3061
        case 6:
3062
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
3063
            rn = "Config6";
3064
            break;
3065
        case 7:
3066
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
3067
            rn = "Config7";
3068
            break;
3069
        default:
3070
            goto die;
3071
        }
3072
        break;
3073
    case 17:
3074
        switch (sel) {
3075
        case 0:
3076
            gen_helper_mfc0_lladdr(t0);
3077
            rn = "LLAddr";
3078
            break;
3079
        default:
3080
            goto die;
3081
        }
3082
        break;
3083
    case 18:
3084
        switch (sel) {
3085
        case 0 ... 7:
3086
            gen_helper_1i(mfc0_watchlo, t0, sel);
3087
            rn = "WatchLo";
3088
            break;
3089
        default:
3090
            goto die;
3091
        }
3092
        break;
3093
    case 19:
3094
        switch (sel) {
3095
        case 0 ...7:
3096
            gen_helper_1i(mfc0_watchhi, t0, sel);
3097
            rn = "WatchHi";
3098
            break;
3099
        default:
3100
            goto die;
3101
        }
3102
        break;
3103
    case 20:
3104
        switch (sel) {
3105
        case 0:
3106
#if defined(TARGET_MIPS64)
3107
            check_insn(env, ctx, ISA_MIPS3);
3108
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
3109
            tcg_gen_ext32s_tl(t0, t0);
3110
            rn = "XContext";
3111
            break;
3112
#endif
3113
        default:
3114
            goto die;
3115
        }
3116
        break;
3117
    case 21:
3118
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3119
        switch (sel) {
3120
        case 0:
3121
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
3122
            rn = "Framemask";
3123
            break;
3124
        default:
3125
            goto die;
3126
        }
3127
        break;
3128
    case 22:
3129
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3130
        rn = "'Diagnostic"; /* implementation dependent */
3131
        break;
3132
    case 23:
3133
        switch (sel) {
3134
        case 0:
3135
            gen_helper_mfc0_debug(t0); /* EJTAG support */
3136
            rn = "Debug";
3137
            break;
3138
        case 1:
3139
//            gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
3140
            rn = "TraceControl";
3141
//            break;
3142
        case 2:
3143
//            gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
3144
            rn = "TraceControl2";
3145
//            break;
3146
        case 3:
3147
//            gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
3148
            rn = "UserTraceData";
3149
//            break;
3150
        case 4:
3151
//            gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
3152
            rn = "TraceBPC";
3153
//            break;
3154
        default:
3155
            goto die;
3156
        }
3157
        break;
3158
    case 24:
3159
        switch (sel) {
3160
        case 0:
3161
            /* EJTAG support */
3162
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
3163
            tcg_gen_ext32s_tl(t0, t0);
3164
            rn = "DEPC";
3165
            break;
3166
        default:
3167
            goto die;
3168
        }
3169
        break;
3170
    case 25:
3171
        switch (sel) {
3172
        case 0:
3173
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
3174
            rn = "Performance0";
3175
            break;
3176
        case 1:
3177
//            gen_helper_mfc0_performance1(t0);
3178
            rn = "Performance1";
3179
//            break;
3180
        case 2:
3181
//            gen_helper_mfc0_performance2(t0);
3182
            rn = "Performance2";
3183
//            break;
3184
        case 3:
3185
//            gen_helper_mfc0_performance3(t0);
3186
            rn = "Performance3";
3187
//            break;
3188
        case 4:
3189
//            gen_helper_mfc0_performance4(t0);
3190
            rn = "Performance4";
3191
//            break;
3192
        case 5:
3193
//            gen_helper_mfc0_performance5(t0);
3194
            rn = "Performance5";
3195
//            break;
3196
        case 6:
3197
//            gen_helper_mfc0_performance6(t0);
3198
            rn = "Performance6";
3199
//            break;
3200
        case 7:
3201
//            gen_helper_mfc0_performance7(t0);
3202
            rn = "Performance7";
3203
//            break;
3204
        default:
3205
            goto die;
3206
        }
3207
        break;
3208
    case 26:
3209
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3210
        rn = "ECC";
3211
        break;
3212
    case 27:
3213
        switch (sel) {
3214
        case 0 ... 3:
3215
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
3216
            rn = "CacheErr";
3217
            break;
3218
        default:
3219
            goto die;
3220
        }
3221
        break;
3222
    case 28:
3223
        switch (sel) {
3224
        case 0:
3225
        case 2:
3226
        case 4:
3227
        case 6:
3228
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
3229
            rn = "TagLo";
3230
            break;
3231
        case 1:
3232
        case 3:
3233
        case 5:
3234
        case 7:
3235
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
3236
            rn = "DataLo";
3237
            break;
3238
        default:
3239
            goto die;
3240
        }
3241
        break;
3242
    case 29:
3243
        switch (sel) {
3244
        case 0:
3245
        case 2:
3246
        case 4:
3247
        case 6:
3248
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
3249
            rn = "TagHi";
3250
            break;
3251
        case 1:
3252
        case 3:
3253
        case 5:
3254
        case 7:
3255
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
3256
            rn = "DataHi";
3257
            break;
3258
        default:
3259
            goto die;
3260
        }
3261
        break;
3262
    case 30:
3263
        switch (sel) {
3264
        case 0:
3265
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3266
            tcg_gen_ext32s_tl(t0, t0);
3267
            rn = "ErrorEPC";
3268
            break;
3269
        default:
3270
            goto die;
3271
        }
3272
        break;
3273
    case 31:
3274
        switch (sel) {
3275
        case 0:
3276
            /* EJTAG support */
3277
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
3278
            rn = "DESAVE";
3279
            break;
3280
        default:
3281
            goto die;
3282
        }
3283
        break;
3284
    default:
3285
       goto die;
3286
    }
3287
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3288
    return;
3289

    
3290
die:
3291
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3292
    generate_exception(ctx, EXCP_RI);
3293
}
3294

    
3295
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3296
{
3297
    const char *rn = "invalid";
3298

    
3299
    if (sel != 0)
3300
        check_insn(env, ctx, ISA_MIPS32);
3301

    
3302
    if (use_icount)
3303
        gen_io_start();
3304

    
3305
    switch (reg) {
3306
    case 0:
3307
        switch (sel) {
3308
        case 0:
3309
            gen_helper_mtc0_index(t0);
3310
            rn = "Index";
3311
            break;
3312
        case 1:
3313
            check_insn(env, ctx, ASE_MT);
3314
            gen_helper_mtc0_mvpcontrol(t0);
3315
            rn = "MVPControl";
3316
            break;
3317
        case 2:
3318
            check_insn(env, ctx, ASE_MT);
3319
            /* ignored */
3320
            rn = "MVPConf0";
3321
            break;
3322
        case 3:
3323
            check_insn(env, ctx, ASE_MT);
3324
            /* ignored */
3325
            rn = "MVPConf1";
3326
            break;
3327
        default:
3328
            goto die;
3329
        }
3330
        break;
3331
    case 1:
3332
        switch (sel) {
3333
        case 0:
3334
            /* ignored */
3335
            rn = "Random";
3336
            break;
3337
        case 1:
3338
            check_insn(env, ctx, ASE_MT);
3339
            gen_helper_mtc0_vpecontrol(t0);
3340
            rn = "VPEControl";
3341
            break;
3342
        case 2:
3343
            check_insn(env, ctx, ASE_MT);
3344
            gen_helper_mtc0_vpeconf0(t0);
3345
            rn = "VPEConf0";
3346
            break;
3347
        case 3:
3348
            check_insn(env, ctx, ASE_MT);
3349
            gen_helper_mtc0_vpeconf1(t0);
3350
            rn = "VPEConf1";
3351
            break;
3352
        case 4:
3353
            check_insn(env, ctx, ASE_MT);
3354
            gen_helper_mtc0_yqmask(t0);
3355
            rn = "YQMask";
3356
            break;
3357
        case 5:
3358
            check_insn(env, ctx, ASE_MT);
3359
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3360
            rn = "VPESchedule";
3361
            break;
3362
        case 6:
3363
            check_insn(env, ctx, ASE_MT);
3364
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3365
            rn = "VPEScheFBack";
3366
            break;
3367
        case 7:
3368
            check_insn(env, ctx, ASE_MT);
3369
            gen_helper_mtc0_vpeopt(t0);
3370
            rn = "VPEOpt";
3371
            break;
3372
        default:
3373
            goto die;
3374
        }
3375
        break;
3376
    case 2:
3377
        switch (sel) {
3378
        case 0:
3379
            gen_helper_mtc0_entrylo0(t0);
3380
            rn = "EntryLo0";
3381
            break;
3382
        case 1:
3383
            check_insn(env, ctx, ASE_MT);
3384
            gen_helper_mtc0_tcstatus(t0);
3385
            rn = "TCStatus";
3386
            break;
3387
        case 2:
3388
            check_insn(env, ctx, ASE_MT);
3389
            gen_helper_mtc0_tcbind(t0);
3390
            rn = "TCBind";
3391
            break;
3392
        case 3:
3393
            check_insn(env, ctx, ASE_MT);
3394
            gen_helper_mtc0_tcrestart(t0);
3395
            rn = "TCRestart";
3396
            break;
3397
        case 4:
3398
            check_insn(env, ctx, ASE_MT);
3399
            gen_helper_mtc0_tchalt(t0);
3400
            rn = "TCHalt";
3401
            break;
3402
        case 5:
3403
            check_insn(env, ctx, ASE_MT);
3404
            gen_helper_mtc0_tccontext(t0);
3405
            rn = "TCContext";
3406
            break;
3407
        case 6:
3408
            check_insn(env, ctx, ASE_MT);
3409
            gen_helper_mtc0_tcschedule(t0);
3410
            rn = "TCSchedule";
3411
            break;
3412
        case 7:
3413
            check_insn(env, ctx, ASE_MT);
3414
            gen_helper_mtc0_tcschefback(t0);
3415
            rn = "TCScheFBack";
3416
            break;
3417
        default:
3418
            goto die;
3419
        }
3420
        break;
3421
    case 3:
3422
        switch (sel) {
3423
        case 0:
3424
            gen_helper_mtc0_entrylo1(t0);
3425
            rn = "EntryLo1";
3426
            break;
3427
        default:
3428
            goto die;
3429
        }
3430
        break;
3431
    case 4:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_helper_mtc0_context(t0);
3435
            rn = "Context";
3436
            break;
3437
        case 1:
3438
//            gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
3439
            rn = "ContextConfig";
3440
//            break;
3441
        default:
3442
            goto die;
3443
        }
3444
        break;
3445
    case 5:
3446
        switch (sel) {
3447
        case 0:
3448
            gen_helper_mtc0_pagemask(t0);
3449
            rn = "PageMask";
3450
            break;
3451
        case 1:
3452
            check_insn(env, ctx, ISA_MIPS32R2);
3453
            gen_helper_mtc0_pagegrain(t0);
3454
            rn = "PageGrain";
3455
            break;
3456
        default:
3457
            goto die;
3458
        }
3459
        break;
3460
    case 6:
3461
        switch (sel) {
3462
        case 0:
3463
            gen_helper_mtc0_wired(t0);
3464
            rn = "Wired";
3465
            break;
3466
        case 1:
3467
            check_insn(env, ctx, ISA_MIPS32R2);
3468
            gen_helper_mtc0_srsconf0(t0);
3469
            rn = "SRSConf0";
3470
            break;
3471
        case 2:
3472
            check_insn(env, ctx, ISA_MIPS32R2);
3473
            gen_helper_mtc0_srsconf1(t0);
3474
            rn = "SRSConf1";
3475
            break;
3476
        case 3:
3477
            check_insn(env, ctx, ISA_MIPS32R2);
3478
            gen_helper_mtc0_srsconf2(t0);
3479
            rn = "SRSConf2";
3480
            break;
3481
        case 4:
3482
            check_insn(env, ctx, ISA_MIPS32R2);
3483
            gen_helper_mtc0_srsconf3(t0);
3484
            rn = "SRSConf3";
3485
            break;
3486
        case 5:
3487
            check_insn(env, ctx, ISA_MIPS32R2);
3488
            gen_helper_mtc0_srsconf4(t0);
3489
            rn = "SRSConf4";
3490
            break;
3491
        default:
3492
            goto die;
3493
        }
3494
        break;
3495
    case 7:
3496
        switch (sel) {
3497
        case 0:
3498
            check_insn(env, ctx, ISA_MIPS32R2);
3499
            gen_helper_mtc0_hwrena(t0);
3500
            rn = "HWREna";
3501
            break;
3502
        default:
3503
            goto die;
3504
        }
3505
        break;
3506
    case 8:
3507
        /* ignored */
3508
        rn = "BadVAddr";
3509
        break;
3510
    case 9:
3511
        switch (sel) {
3512
        case 0:
3513
            gen_helper_mtc0_count(t0);
3514
            rn = "Count";
3515
            break;
3516
        /* 6,7 are implementation dependent */
3517
        default:
3518
            goto die;
3519
        }
3520
        /* Stop translation as we may have switched the execution mode */
3521
        ctx->bstate = BS_STOP;
3522
        break;
3523
    case 10:
3524
        switch (sel) {
3525
        case 0:
3526
            gen_helper_mtc0_entryhi(t0);
3527
            rn = "EntryHi";
3528
            break;
3529
        default:
3530
            goto die;
3531
        }
3532
        break;
3533
    case 11:
3534
        switch (sel) {
3535
        case 0:
3536
            gen_helper_mtc0_compare(t0);
3537
            rn = "Compare";
3538
            break;
3539
        /* 6,7 are implementation dependent */
3540
        default:
3541
            goto die;
3542
        }
3543
        /* Stop translation as we may have switched the execution mode */
3544
        ctx->bstate = BS_STOP;
3545
        break;
3546
    case 12:
3547
        switch (sel) {
3548
        case 0:
3549
            gen_helper_mtc0_status(t0);
3550
            /* BS_STOP isn't good enough here, hflags may have changed. */
3551
            gen_save_pc(ctx->pc + 4);
3552
            ctx->bstate = BS_EXCP;
3553
            rn = "Status";
3554
            break;
3555
        case 1:
3556
            check_insn(env, ctx, ISA_MIPS32R2);
3557
            gen_helper_mtc0_intctl(t0);
3558
            /* Stop translation as we may have switched the execution mode */
3559
            ctx->bstate = BS_STOP;
3560
            rn = "IntCtl";
3561
            break;
3562
        case 2:
3563
            check_insn(env, ctx, ISA_MIPS32R2);
3564
            gen_helper_mtc0_srsctl(t0);
3565
            /* Stop translation as we may have switched the execution mode */
3566
            ctx->bstate = BS_STOP;
3567
            rn = "SRSCtl";
3568
            break;
3569
        case 3:
3570
            check_insn(env, ctx, ISA_MIPS32R2);
3571
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3572
            /* Stop translation as we may have switched the execution mode */
3573
            ctx->bstate = BS_STOP;
3574
            rn = "SRSMap";
3575
            break;
3576
        default:
3577
            goto die;
3578
        }
3579
        break;
3580
    case 13:
3581
        switch (sel) {
3582
        case 0:
3583
            gen_helper_mtc0_cause(t0);
3584
            rn = "Cause";
3585
            break;
3586
        default:
3587
            goto die;
3588
        }
3589
        /* Stop translation as we may have switched the execution mode */
3590
        ctx->bstate = BS_STOP;
3591
        break;
3592
    case 14:
3593
        switch (sel) {
3594
        case 0:
3595
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3596
            rn = "EPC";
3597
            break;
3598
        default:
3599
            goto die;
3600
        }
3601
        break;
3602
    case 15:
3603
        switch (sel) {
3604
        case 0:
3605
            /* ignored */
3606
            rn = "PRid";
3607
            break;
3608
        case 1:
3609
            check_insn(env, ctx, ISA_MIPS32R2);
3610
            gen_helper_mtc0_ebase(t0);
3611
            rn = "EBase";
3612
            break;
3613
        default:
3614
            goto die;
3615
        }
3616
        break;
3617
    case 16:
3618
        switch (sel) {
3619
        case 0:
3620
            gen_helper_mtc0_config0(t0);
3621
            rn = "Config";
3622
            /* Stop translation as we may have switched the execution mode */
3623
            ctx->bstate = BS_STOP;
3624
            break;
3625
        case 1:
3626
            /* ignored, read only */
3627
            rn = "Config1";
3628
            break;
3629
        case 2:
3630
            gen_helper_mtc0_config2(t0);
3631
            rn = "Config2";
3632
            /* Stop translation as we may have switched the execution mode */
3633
            ctx->bstate = BS_STOP;
3634
            break;
3635
        case 3:
3636
            /* ignored, read only */
3637
            rn = "Config3";
3638
            break;
3639
        /* 4,5 are reserved */
3640
        /* 6,7 are implementation dependent */
3641
        case 6:
3642
            /* ignored */
3643
            rn = "Config6";
3644
            break;
3645
        case 7:
3646
            /* ignored */
3647
            rn = "Config7";
3648
            break;
3649
        default:
3650
            rn = "Invalid config selector";
3651
            goto die;
3652
        }
3653
        break;
3654
    case 17:
3655
        switch (sel) {
3656
        case 0:
3657
            /* ignored */
3658
            rn = "LLAddr";
3659
            break;
3660
        default:
3661
            goto die;
3662
        }
3663
        break;
3664
    case 18:
3665
        switch (sel) {
3666
        case 0 ... 7:
3667
            gen_helper_1i(mtc0_watchlo, t0, sel);
3668
            rn = "WatchLo";
3669
            break;
3670
        default:
3671
            goto die;
3672
        }
3673
        break;
3674
    case 19:
3675
        switch (sel) {
3676
        case 0 ... 7:
3677
            gen_helper_1i(mtc0_watchhi, t0, sel);
3678
            rn = "WatchHi";
3679
            break;
3680
        default:
3681
            goto die;
3682
        }
3683
        break;
3684
    case 20:
3685
        switch (sel) {
3686
        case 0:
3687
#if defined(TARGET_MIPS64)
3688
            check_insn(env, ctx, ISA_MIPS3);
3689
            gen_helper_mtc0_xcontext(t0);
3690
            rn = "XContext";
3691
            break;
3692
#endif
3693
        default:
3694
            goto die;
3695
        }
3696
        break;
3697
    case 21:
3698
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3699
        switch (sel) {
3700
        case 0:
3701
            gen_helper_mtc0_framemask(t0);
3702
            rn = "Framemask";
3703
            break;
3704
        default:
3705
            goto die;
3706
        }
3707
        break;
3708
    case 22:
3709
        /* ignored */
3710
        rn = "Diagnostic"; /* implementation dependent */
3711
        break;
3712
    case 23:
3713
        switch (sel) {
3714
        case 0:
3715
            gen_helper_mtc0_debug(t0); /* EJTAG support */
3716
            /* BS_STOP isn't good enough here, hflags may have changed. */
3717
            gen_save_pc(ctx->pc + 4);
3718
            ctx->bstate = BS_EXCP;
3719
            rn = "Debug";
3720
            break;
3721
        case 1:
3722
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
3723
            rn = "TraceControl";
3724
            /* Stop translation as we may have switched the execution mode */
3725
            ctx->bstate = BS_STOP;
3726
//            break;
3727
        case 2:
3728
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
3729
            rn = "TraceControl2";
3730
            /* Stop translation as we may have switched the execution mode */
3731
            ctx->bstate = BS_STOP;
3732
//            break;
3733
        case 3:
3734
            /* Stop translation as we may have switched the execution mode */
3735
            ctx->bstate = BS_STOP;
3736
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
3737
            rn = "UserTraceData";
3738
            /* Stop translation as we may have switched the execution mode */
3739
            ctx->bstate = BS_STOP;
3740
//            break;
3741
        case 4:
3742
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
3743
            /* Stop translation as we may have switched the execution mode */
3744
            ctx->bstate = BS_STOP;
3745
            rn = "TraceBPC";
3746
//            break;
3747
        default:
3748
            goto die;
3749
        }
3750
        break;
3751
    case 24:
3752
        switch (sel) {
3753
        case 0:
3754
            /* EJTAG support */
3755
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3756
            rn = "DEPC";
3757
            break;
3758
        default:
3759
            goto die;
3760
        }
3761
        break;
3762
    case 25:
3763
        switch (sel) {
3764
        case 0:
3765
            gen_helper_mtc0_performance0(t0);
3766
            rn = "Performance0";
3767
            break;
3768
        case 1:
3769
//            gen_helper_mtc0_performance1(t0);
3770
            rn = "Performance1";
3771
//            break;
3772
        case 2:
3773
//            gen_helper_mtc0_performance2(t0);
3774
            rn = "Performance2";
3775
//            break;
3776
        case 3:
3777
//            gen_helper_mtc0_performance3(t0);
3778
            rn = "Performance3";
3779
//            break;
3780
        case 4:
3781
//            gen_helper_mtc0_performance4(t0);
3782
            rn = "Performance4";
3783
//            break;
3784
        case 5:
3785
//            gen_helper_mtc0_performance5(t0);
3786
            rn = "Performance5";
3787
//            break;
3788
        case 6:
3789
//            gen_helper_mtc0_performance6(t0);
3790
            rn = "Performance6";
3791
//            break;
3792
        case 7:
3793
//            gen_helper_mtc0_performance7(t0);
3794
            rn = "Performance7";
3795
//            break;
3796
        default:
3797
            goto die;
3798
        }
3799
       break;
3800
    case 26:
3801
        /* ignored */
3802
        rn = "ECC";
3803
        break;
3804
    case 27:
3805
        switch (sel) {
3806
        case 0 ... 3:
3807
            /* ignored */
3808
            rn = "CacheErr";
3809
            break;
3810
        default:
3811
            goto die;
3812
        }
3813
       break;
3814
    case 28:
3815
        switch (sel) {
3816
        case 0:
3817
        case 2:
3818
        case 4:
3819
        case 6:
3820
            gen_helper_mtc0_taglo(t0);
3821
            rn = "TagLo";
3822
            break;
3823
        case 1:
3824
        case 3:
3825
        case 5:
3826
        case 7:
3827
            gen_helper_mtc0_datalo(t0);
3828
            rn = "DataLo";
3829
            break;
3830
        default:
3831
            goto die;
3832
        }
3833
        break;
3834
    case 29:
3835
        switch (sel) {
3836
        case 0:
3837
        case 2:
3838
        case 4:
3839
        case 6:
3840
            gen_helper_mtc0_taghi(t0);
3841
            rn = "TagHi";
3842
            break;
3843
        case 1:
3844
        case 3:
3845
        case 5:
3846
        case 7:
3847
            gen_helper_mtc0_datahi(t0);
3848
            rn = "DataHi";
3849
            break;
3850
        default:
3851
            rn = "invalid sel";
3852
            goto die;
3853
        }
3854
       break;
3855
    case 30:
3856
        switch (sel) {
3857
        case 0:
3858
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3859
            rn = "ErrorEPC";
3860
            break;
3861
        default:
3862
            goto die;
3863
        }
3864
        break;
3865
    case 31:
3866
        switch (sel) {
3867
        case 0:
3868
            /* EJTAG support */
3869
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3870
            rn = "DESAVE";
3871
            break;
3872
        default:
3873
            goto die;
3874
        }
3875
        /* Stop translation as we may have switched the execution mode */
3876
        ctx->bstate = BS_STOP;
3877
        break;
3878
    default:
3879
       goto die;
3880
    }
3881
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3882
    /* For simplicity assume that all writes can cause interrupts.  */
3883
    if (use_icount) {
3884
        gen_io_end();
3885
        ctx->bstate = BS_STOP;
3886
    }
3887
    return;
3888

    
3889
die:
3890
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3891
    generate_exception(ctx, EXCP_RI);
3892
}
3893

    
3894
#if defined(TARGET_MIPS64)
3895
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3896
{
3897
    const char *rn = "invalid";
3898

    
3899
    if (sel != 0)
3900
        check_insn(env, ctx, ISA_MIPS64);
3901

    
3902
    switch (reg) {
3903
    case 0:
3904
        switch (sel) {
3905
        case 0:
3906
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
3907
            rn = "Index";
3908
            break;
3909
        case 1:
3910
            check_insn(env, ctx, ASE_MT);
3911
            gen_helper_mfc0_mvpcontrol(t0);
3912
            rn = "MVPControl";
3913
            break;
3914
        case 2:
3915
            check_insn(env, ctx, ASE_MT);
3916
            gen_helper_mfc0_mvpconf0(t0);
3917
            rn = "MVPConf0";
3918
            break;
3919
        case 3:
3920
            check_insn(env, ctx, ASE_MT);
3921
            gen_helper_mfc0_mvpconf1(t0);
3922
            rn = "MVPConf1";
3923
            break;
3924
        default:
3925
            goto die;
3926
        }
3927
        break;
3928
    case 1:
3929
        switch (sel) {
3930
        case 0:
3931
            gen_helper_mfc0_random(t0);
3932
            rn = "Random";
3933
            break;
3934
        case 1:
3935
            check_insn(env, ctx, ASE_MT);
3936
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
3937
            rn = "VPEControl";
3938
            break;
3939
        case 2:
3940
            check_insn(env, ctx, ASE_MT);
3941
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
3942
            rn = "VPEConf0";
3943
            break;
3944
        case 3:
3945
            check_insn(env, ctx, ASE_MT);
3946
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
3947
            rn = "VPEConf1";
3948
            break;
3949
        case 4:
3950
            check_insn(env, ctx, ASE_MT);
3951
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
3952
            rn = "YQMask";
3953
            break;
3954
        case 5:
3955
            check_insn(env, ctx, ASE_MT);
3956
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
3957
            rn = "VPESchedule";
3958
            break;
3959
        case 6:
3960
            check_insn(env, ctx, ASE_MT);
3961
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3962
            rn = "VPEScheFBack";
3963
            break;
3964
        case 7:
3965
            check_insn(env, ctx, ASE_MT);
3966
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
3967
            rn = "VPEOpt";
3968
            break;
3969
        default:
3970
            goto die;
3971
        }
3972
        break;
3973
    case 2:
3974
        switch (sel) {
3975
        case 0:
3976
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3977
            rn = "EntryLo0";
3978
            break;
3979
        case 1:
3980
            check_insn(env, ctx, ASE_MT);
3981
            gen_helper_mfc0_tcstatus(t0);
3982
            rn = "TCStatus";
3983
            break;
3984
        case 2:
3985
            check_insn(env, ctx, ASE_MT);
3986
            gen_helper_mfc0_tcbind(t0);
3987
            rn = "TCBind";
3988
            break;
3989
        case 3:
3990
            check_insn(env, ctx, ASE_MT);
3991
            gen_helper_dmfc0_tcrestart(t0);
3992
            rn = "TCRestart";
3993
            break;
3994
        case 4:
3995
            check_insn(env, ctx, ASE_MT);
3996
            gen_helper_dmfc0_tchalt(t0);
3997
            rn = "TCHalt";
3998
            break;
3999
        case 5:
4000
            check_insn(env, ctx, ASE_MT);
4001
            gen_helper_dmfc0_tccontext(t0);
4002
            rn = "TCContext";
4003
            break;
4004
        case 6:
4005
            check_insn(env, ctx, ASE_MT);
4006
            gen_helper_dmfc0_tcschedule(t0);
4007
            rn = "TCSchedule";
4008
            break;
4009
        case 7:
4010
            check_insn(env, ctx, ASE_MT);
4011
            gen_helper_dmfc0_tcschefback(t0);
4012
            rn = "TCScheFBack";
4013
            break;
4014
        default:
4015
            goto die;
4016
        }
4017
        break;
4018
    case 3:
4019
        switch (sel) {
4020
        case 0:
4021
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4022
            rn = "EntryLo1";
4023
            break;
4024
        default:
4025
            goto die;
4026
        }
4027
        break;
4028
    case 4:
4029
        switch (sel) {
4030
        case 0:
4031
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
4032
            rn = "Context";
4033
            break;
4034
        case 1:
4035
//            gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
4036
            rn = "ContextConfig";
4037
//            break;
4038
        default:
4039
            goto die;
4040
        }
4041
        break;
4042
    case 5:
4043
        switch (sel) {
4044
        case 0:
4045
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
4046
            rn = "PageMask";
4047
            break;
4048
        case 1:
4049
            check_insn(env, ctx, ISA_MIPS32R2);
4050
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
4051
            rn = "PageGrain";
4052
            break;
4053
        default:
4054
            goto die;
4055
        }
4056
        break;
4057
    case 6:
4058
        switch (sel) {
4059
        case 0:
4060
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
4061
            rn = "Wired";
4062
            break;
4063
        case 1:
4064
            check_insn(env, ctx, ISA_MIPS32R2);
4065
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
4066
            rn = "SRSConf0";
4067
            break;
4068
        case 2:
4069
            check_insn(env, ctx, ISA_MIPS32R2);
4070
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
4071
            rn = "SRSConf1";
4072
            break;
4073
        case 3:
4074
            check_insn(env, ctx, ISA_MIPS32R2);
4075
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
4076
            rn = "SRSConf2";
4077
            break;
4078
        case 4:
4079
            check_insn(env, ctx, ISA_MIPS32R2);
4080
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
4081
            rn = "SRSConf3";
4082
            break;
4083
        case 5:
4084
            check_insn(env, ctx, ISA_MIPS32R2);
4085
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
4086
            rn = "SRSConf4";
4087
            break;
4088
        default:
4089
            goto die;
4090
        }
4091
        break;
4092
    case 7:
4093
        switch (sel) {
4094
        case 0:
4095
            check_insn(env, ctx, ISA_MIPS32R2);
4096
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
4097
            rn = "HWREna";
4098
            break;
4099
        default:
4100
            goto die;
4101
        }
4102
        break;
4103
    case 8:
4104
        switch (sel) {
4105
        case 0:
4106
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4107
            rn = "BadVAddr";
4108
            break;
4109
        default:
4110
            goto die;
4111
        }
4112
        break;
4113
    case 9:
4114
        switch (sel) {
4115
        case 0:
4116
            /* Mark as an IO operation because we read the time.  */
4117
            if (use_icount)
4118
                gen_io_start();
4119
            gen_helper_mfc0_count(t0);
4120
            if (use_icount) {
4121
                gen_io_end();
4122
                ctx->bstate = BS_STOP;
4123
            }
4124
            rn = "Count";
4125
            break;
4126
        /* 6,7 are implementation dependent */
4127
        default:
4128
            goto die;
4129
        }
4130
        break;
4131
    case 10:
4132
        switch (sel) {
4133
        case 0:
4134
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
4135
            rn = "EntryHi";
4136
            break;
4137
        default:
4138
            goto die;
4139
        }
4140
        break;
4141
    case 11:
4142
        switch (sel) {
4143
        case 0:
4144
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
4145
            rn = "Compare";
4146
            break;
4147
        /* 6,7 are implementation dependent */
4148
        default:
4149
            goto die;
4150
        }
4151
        break;
4152
    case 12:
4153
        switch (sel) {
4154
        case 0:
4155
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
4156
            rn = "Status";
4157
            break;
4158
        case 1:
4159
            check_insn(env, ctx, ISA_MIPS32R2);
4160
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
4161
            rn = "IntCtl";
4162
            break;
4163
        case 2:
4164
            check_insn(env, ctx, ISA_MIPS32R2);
4165
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
4166
            rn = "SRSCtl";
4167
            break;
4168
        case 3:
4169
            check_insn(env, ctx, ISA_MIPS32R2);
4170
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
4171
            rn = "SRSMap";
4172
            break;
4173
        default:
4174
            goto die;
4175
        }
4176
        break;
4177
    case 13:
4178
        switch (sel) {
4179
        case 0:
4180
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
4181
            rn = "Cause";
4182
            break;
4183
        default:
4184
            goto die;
4185
        }
4186
        break;
4187
    case 14:
4188
        switch (sel) {
4189
        case 0:
4190
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4191
            rn = "EPC";
4192
            break;
4193
        default:
4194
            goto die;
4195
        }
4196
        break;
4197
    case 15:
4198
        switch (sel) {
4199
        case 0:
4200
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
4201
            rn = "PRid";
4202
            break;
4203
        case 1:
4204
            check_insn(env, ctx, ISA_MIPS32R2);
4205
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
4206
            rn = "EBase";
4207
            break;
4208
        default:
4209
            goto die;
4210
        }
4211
        break;
4212
    case 16:
4213
        switch (sel) {
4214
        case 0:
4215
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
4216
            rn = "Config";
4217
            break;
4218
        case 1:
4219
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
4220
            rn = "Config1";
4221
            break;
4222
        case 2:
4223
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
4224
            rn = "Config2";
4225
            break;
4226
        case 3:
4227
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
4228
            rn = "Config3";
4229
            break;
4230
       /* 6,7 are implementation dependent */
4231
        case 6:
4232
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
4233
            rn = "Config6";
4234
            break;
4235
        case 7:
4236
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
4237
            rn = "Config7";
4238
            break;
4239
        default:
4240
            goto die;
4241
        }
4242
        break;
4243
    case 17:
4244
        switch (sel) {
4245
        case 0:
4246
            gen_helper_dmfc0_lladdr(t0);
4247
            rn = "LLAddr";
4248
            break;
4249
        default:
4250
            goto die;
4251
        }
4252
        break;
4253
    case 18:
4254
        switch (sel) {
4255
        case 0 ... 7:
4256
            gen_helper_1i(dmfc0_watchlo, t0, sel);
4257
            rn = "WatchLo";
4258
            break;
4259
        default:
4260
            goto die;
4261
        }
4262
        break;
4263
    case 19:
4264
        switch (sel) {
4265
        case 0 ... 7:
4266
            gen_helper_1i(mfc0_watchhi, t0, sel);
4267
            rn = "WatchHi";
4268
            break;
4269
        default:
4270
            goto die;
4271
        }
4272
        break;
4273
    case 20:
4274
        switch (sel) {
4275
        case 0:
4276
            check_insn(env, ctx, ISA_MIPS3);
4277
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
4278
            rn = "XContext";
4279
            break;
4280
        default:
4281
            goto die;
4282
        }
4283
        break;
4284
    case 21:
4285
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4286
        switch (sel) {
4287
        case 0:
4288
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
4289
            rn = "Framemask";
4290
            break;
4291
        default:
4292
            goto die;
4293
        }
4294
        break;
4295
    case 22:
4296
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4297
        rn = "'Diagnostic"; /* implementation dependent */
4298
        break;
4299
    case 23:
4300
        switch (sel) {
4301
        case 0:
4302
            gen_helper_mfc0_debug(t0); /* EJTAG support */
4303
            rn = "Debug";
4304
            break;
4305
        case 1:
4306
//            gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
4307
            rn = "TraceControl";
4308
//            break;
4309
        case 2:
4310
//            gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
4311
            rn = "TraceControl2";
4312
//            break;
4313
        case 3:
4314
//            gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
4315
            rn = "UserTraceData";
4316
//            break;
4317
        case 4:
4318
//            gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
4319
            rn = "TraceBPC";
4320
//            break;
4321
        default:
4322
            goto die;
4323
        }
4324
        break;
4325
    case 24:
4326
        switch (sel) {
4327
        case 0:
4328
            /* EJTAG support */
4329
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4330
            rn = "DEPC";
4331
            break;
4332
        default:
4333
            goto die;
4334
        }
4335
        break;
4336
    case 25:
4337
        switch (sel) {
4338
        case 0:
4339
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
4340
            rn = "Performance0";
4341
            break;
4342
        case 1:
4343
//            gen_helper_dmfc0_performance1(t0);
4344
            rn = "Performance1";
4345
//            break;
4346
        case 2:
4347
//            gen_helper_dmfc0_performance2(t0);
4348
            rn = "Performance2";
4349
//            break;
4350
        case 3:
4351
//            gen_helper_dmfc0_performance3(t0);
4352
            rn = "Performance3";
4353
//            break;
4354
        case 4:
4355
//            gen_helper_dmfc0_performance4(t0);
4356
            rn = "Performance4";
4357
//            break;
4358
        case 5:
4359
//            gen_helper_dmfc0_performance5(t0);
4360
            rn = "Performance5";
4361
//            break;
4362
        case 6:
4363
//            gen_helper_dmfc0_performance6(t0);
4364
            rn = "Performance6";
4365
//            break;
4366
        case 7:
4367
//            gen_helper_dmfc0_performance7(t0);
4368
            rn = "Performance7";
4369
//            break;
4370
        default:
4371
            goto die;
4372
        }
4373
        break;
4374
    case 26:
4375
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4376
        rn = "ECC";
4377
        break;
4378
    case 27:
4379
        switch (sel) {
4380
        /* ignored */
4381
        case 0 ... 3:
4382
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
4383
            rn = "CacheErr";
4384
            break;
4385
        default:
4386
            goto die;
4387
        }
4388
        break;
4389
    case 28:
4390
        switch (sel) {
4391
        case 0:
4392
        case 2:
4393
        case 4:
4394
        case 6:
4395
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
4396
            rn = "TagLo";
4397
            break;
4398
        case 1:
4399
        case 3:
4400
        case 5:
4401
        case 7:
4402
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
4403
            rn = "DataLo";
4404
            break;
4405
        default:
4406
            goto die;
4407
        }
4408
        break;
4409
    case 29:
4410
        switch (sel) {
4411
        case 0:
4412
        case 2:
4413
        case 4:
4414
        case 6:
4415
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
4416
            rn = "TagHi";
4417
            break;
4418
        case 1:
4419
        case 3:
4420
        case 5:
4421
        case 7:
4422
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
4423
            rn = "DataHi";
4424
            break;
4425
        default:
4426
            goto die;
4427
        }
4428
        break;
4429
    case 30:
4430
        switch (sel) {
4431
        case 0:
4432
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4433
            rn = "ErrorEPC";
4434
            break;
4435
        default:
4436
            goto die;
4437
        }
4438
        break;
4439
    case 31:
4440
        switch (sel) {
4441
        case 0:
4442
            /* EJTAG support */
4443
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
4444
            rn = "DESAVE";
4445
            break;
4446
        default:
4447
            goto die;
4448
        }
4449
        break;
4450
    default:
4451
        goto die;
4452
    }
4453
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4454
    return;
4455

    
4456
die:
4457
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4458
    generate_exception(ctx, EXCP_RI);
4459
}
4460

    
4461
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4462
{
4463
    const char *rn = "invalid";
4464

    
4465
    if (sel != 0)
4466
        check_insn(env, ctx, ISA_MIPS64);
4467

    
4468
    if (use_icount)
4469
        gen_io_start();
4470

    
4471
    switch (reg) {
4472
    case 0:
4473
        switch (sel) {
4474
        case 0:
4475
            gen_helper_mtc0_index(t0);
4476
            rn = "Index";
4477
            break;
4478
        case 1:
4479
            check_insn(env, ctx, ASE_MT);
4480
            gen_helper_mtc0_mvpcontrol(t0);
4481
            rn = "MVPControl";
4482
            break;
4483
        case 2:
4484
            check_insn(env, ctx, ASE_MT);
4485
            /* ignored */
4486
            rn = "MVPConf0";
4487
            break;
4488
        case 3:
4489
            check_insn(env, ctx, ASE_MT);
4490
            /* ignored */
4491
            rn = "MVPConf1";
4492
            break;
4493
        default:
4494
            goto die;
4495
        }
4496
        break;
4497
    case 1:
4498
        switch (sel) {
4499
        case 0:
4500
            /* ignored */
4501
            rn = "Random";
4502
            break;
4503
        case 1:
4504
            check_insn(env, ctx, ASE_MT);
4505
            gen_helper_mtc0_vpecontrol(t0);
4506
            rn = "VPEControl";
4507
            break;
4508
        case 2:
4509
            check_insn(env, ctx, ASE_MT);
4510
            gen_helper_mtc0_vpeconf0(t0);
4511
            rn = "VPEConf0";
4512
            break;
4513
        case 3:
4514
            check_insn(env, ctx, ASE_MT);
4515
            gen_helper_mtc0_vpeconf1(t0);
4516
            rn = "VPEConf1";
4517
            break;
4518
        case 4:
4519
            check_insn(env, ctx, ASE_MT);
4520
            gen_helper_mtc0_yqmask(t0);
4521
            rn = "YQMask";
4522
            break;
4523
        case 5:
4524
            check_insn(env, ctx, ASE_MT);
4525
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4526
            rn = "VPESchedule";
4527
            break;
4528
        case 6:
4529
            check_insn(env, ctx, ASE_MT);
4530
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4531
            rn = "VPEScheFBack";
4532
            break;
4533
        case 7:
4534
            check_insn(env, ctx, ASE_MT);
4535
            gen_helper_mtc0_vpeopt(t0);
4536
            rn = "VPEOpt";
4537
            break;
4538
        default:
4539
            goto die;
4540
        }
4541
        break;
4542
    case 2:
4543
        switch (sel) {
4544
        case 0:
4545
            gen_helper_mtc0_entrylo0(t0);
4546
            rn = "EntryLo0";
4547
            break;
4548
        case 1:
4549
            check_insn(env, ctx, ASE_MT);
4550
            gen_helper_mtc0_tcstatus(t0);
4551
            rn = "TCStatus";
4552
            break;
4553
        case 2:
4554
            check_insn(env, ctx, ASE_MT);
4555
            gen_helper_mtc0_tcbind(t0);
4556
            rn = "TCBind";
4557
            break;
4558
        case 3:
4559
            check_insn(env, ctx, ASE_MT);
4560
            gen_helper_mtc0_tcrestart(t0);
4561
            rn = "TCRestart";
4562
            break;
4563
        case 4:
4564
            check_insn(env, ctx, ASE_MT);
4565
            gen_helper_mtc0_tchalt(t0);
4566
            rn = "TCHalt";
4567
            break;
4568
        case 5:
4569
            check_insn(env, ctx, ASE_MT);
4570
            gen_helper_mtc0_tccontext(t0);
4571
            rn = "TCContext";
4572
            break;
4573
        case 6:
4574
            check_insn(env, ctx, ASE_MT);
4575
            gen_helper_mtc0_tcschedule(t0);
4576
            rn = "TCSchedule";
4577
            break;
4578
        case 7:
4579
            check_insn(env, ctx, ASE_MT);
4580
            gen_helper_mtc0_tcschefback(t0);
4581
            rn = "TCScheFBack";
4582
            break;
4583
        default:
4584
            goto die;
4585
        }
4586
        break;
4587
    case 3:
4588
        switch (sel) {
4589
        case 0:
4590
            gen_helper_mtc0_entrylo1(t0);
4591
            rn = "EntryLo1";
4592
            break;
4593
        default:
4594
            goto die;
4595
        }
4596
        break;
4597
    case 4:
4598
        switch (sel) {
4599
        case 0:
4600
            gen_helper_mtc0_context(t0);
4601
            rn = "Context";
4602
            break;
4603
        case 1:
4604
//           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4605
            rn = "ContextConfig";
4606
//           break;
4607
        default:
4608
            goto die;
4609
        }
4610
        break;
4611
    case 5:
4612
        switch (sel) {
4613
        case 0:
4614
            gen_helper_mtc0_pagemask(t0);
4615
            rn = "PageMask";
4616
            break;
4617
        case 1:
4618
            check_insn(env, ctx, ISA_MIPS32R2);
4619
            gen_helper_mtc0_pagegrain(t0);
4620
            rn = "PageGrain";
4621
            break;
4622
        default:
4623
            goto die;
4624
        }
4625
        break;
4626
    case 6:
4627
        switch (sel) {
4628
        case 0:
4629
            gen_helper_mtc0_wired(t0);
4630
            rn = "Wired";
4631
            break;
4632
        case 1:
4633
            check_insn(env, ctx, ISA_MIPS32R2);
4634
            gen_helper_mtc0_srsconf0(t0);
4635
            rn = "SRSConf0";
4636
            break;
4637
        case 2:
4638
            check_insn(env, ctx, ISA_MIPS32R2);
4639
            gen_helper_mtc0_srsconf1(t0);
4640
            rn = "SRSConf1";
4641
            break;
4642
        case 3:
4643
            check_insn(env, ctx, ISA_MIPS32R2);
4644
            gen_helper_mtc0_srsconf2(t0);
4645
            rn = "SRSConf2";
4646
            break;
4647
        case 4:
4648
            check_insn(env, ctx, ISA_MIPS32R2);
4649
            gen_helper_mtc0_srsconf3(t0);
4650
            rn = "SRSConf3";
4651
            break;
4652
        case 5:
4653
            check_insn(env, ctx, ISA_MIPS32R2);
4654
            gen_helper_mtc0_srsconf4(t0);
4655
            rn = "SRSConf4";
4656
            break;
4657
        default:
4658
            goto die;
4659
        }
4660
        break;
4661
    case 7:
4662
        switch (sel) {
4663
        case 0:
4664
            check_insn(env, ctx, ISA_MIPS32R2);
4665
            gen_helper_mtc0_hwrena(t0);
4666
            rn = "HWREna";
4667
            break;
4668
        default:
4669
            goto die;
4670
        }
4671
        break;
4672
    case 8:
4673
        /* ignored */
4674
        rn = "BadVAddr";
4675
        break;
4676
    case 9:
4677
        switch (sel) {
4678
        case 0:
4679
            gen_helper_mtc0_count(t0);
4680
            rn = "Count";
4681
            break;
4682
        /* 6,7 are implementation dependent */
4683
        default:
4684
            goto die;
4685
        }
4686
        /* Stop translation as we may have switched the execution mode */
4687
        ctx->bstate = BS_STOP;
4688
        break;
4689
    case 10:
4690
        switch (sel) {
4691
        case 0:
4692
            gen_helper_mtc0_entryhi(t0);
4693
            rn = "EntryHi";
4694
            break;
4695
        default:
4696
            goto die;
4697
        }
4698
        break;
4699
    case 11:
4700
        switch (sel) {
4701
        case 0:
4702
            gen_helper_mtc0_compare(t0);
4703
            rn = "Compare";
4704
            break;
4705
        /* 6,7 are implementation dependent */
4706
        default:
4707
            goto die;
4708
        }
4709
        /* Stop translation as we may have switched the execution mode */
4710
        ctx->bstate = BS_STOP;
4711
        break;
4712
    case 12:
4713
        switch (sel) {
4714
        case 0:
4715
            gen_helper_mtc0_status(t0);
4716
            /* BS_STOP isn't good enough here, hflags may have changed. */
4717
            gen_save_pc(ctx->pc + 4);
4718
            ctx->bstate = BS_EXCP;
4719
            rn = "Status";
4720
            break;
4721
        case 1:
4722
            check_insn(env, ctx, ISA_MIPS32R2);
4723
            gen_helper_mtc0_intctl(t0);
4724
            /* Stop translation as we may have switched the execution mode */
4725
            ctx->bstate = BS_STOP;
4726
            rn = "IntCtl";
4727
            break;
4728
        case 2:
4729
            check_insn(env, ctx, ISA_MIPS32R2);
4730
            gen_helper_mtc0_srsctl(t0);
4731
            /* Stop translation as we may have switched the execution mode */
4732
            ctx->bstate = BS_STOP;
4733
            rn = "SRSCtl";
4734
            break;
4735
        case 3:
4736
            check_insn(env, ctx, ISA_MIPS32R2);
4737
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4738
            /* Stop translation as we may have switched the execution mode */
4739
            ctx->bstate = BS_STOP;
4740
            rn = "SRSMap";
4741
            break;
4742
        default:
4743
            goto die;
4744
        }
4745
        break;
4746
    case 13:
4747
        switch (sel) {
4748
        case 0:
4749
            gen_helper_mtc0_cause(t0);
4750
            rn = "Cause";
4751
            break;
4752
        default:
4753
            goto die;
4754
        }
4755
        /* Stop translation as we may have switched the execution mode */
4756
        ctx->bstate = BS_STOP;
4757
        break;
4758
    case 14:
4759
        switch (sel) {
4760
        case 0:
4761
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4762
            rn = "EPC";
4763
            break;
4764
        default:
4765
            goto die;
4766
        }
4767
        break;
4768
    case 15:
4769
        switch (sel) {
4770
        case 0:
4771
            /* ignored */
4772
            rn = "PRid";
4773
            break;
4774
        case 1:
4775
            check_insn(env, ctx, ISA_MIPS32R2);
4776
            gen_helper_mtc0_ebase(t0);
4777
            rn = "EBase";
4778
            break;
4779
        default:
4780
            goto die;
4781
        }
4782
        break;
4783
    case 16:
4784
        switch (sel) {
4785
        case 0:
4786
            gen_helper_mtc0_config0(t0);
4787
            rn = "Config";
4788
            /* Stop translation as we may have switched the execution mode */
4789
            ctx->bstate = BS_STOP;
4790
            break;
4791
        case 1:
4792
            /* ignored */
4793
            rn = "Config1";
4794
            break;
4795
        case 2:
4796
            gen_helper_mtc0_config2(t0);
4797
            rn = "Config2";
4798
            /* Stop translation as we may have switched the execution mode */
4799
            ctx->bstate = BS_STOP;
4800
            break;
4801
        case 3:
4802
            /* ignored */
4803
            rn = "Config3";
4804
            break;
4805
        /* 6,7 are implementation dependent */
4806
        default:
4807
            rn = "Invalid config selector";
4808
            goto die;
4809
        }
4810
        break;
4811
    case 17:
4812
        switch (sel) {
4813
        case 0:
4814
            /* ignored */
4815
            rn = "LLAddr";
4816
            break;
4817
        default:
4818
            goto die;
4819
        }
4820
        break;
4821
    case 18:
4822
        switch (sel) {
4823
        case 0 ... 7:
4824
            gen_helper_1i(mtc0_watchlo, t0, sel);
4825
            rn = "WatchLo";
4826
            break;
4827
        default:
4828
            goto die;
4829
        }
4830
        break;
4831
    case 19:
4832
        switch (sel) {
4833
        case 0 ... 7:
4834
            gen_helper_1i(mtc0_watchhi, t0, sel);
4835
            rn = "WatchHi";
4836
            break;
4837
        default:
4838
            goto die;
4839
        }
4840
        break;
4841
    case 20:
4842
        switch (sel) {
4843
        case 0:
4844
            check_insn(env, ctx, ISA_MIPS3);
4845
            gen_helper_mtc0_xcontext(t0);
4846
            rn = "XContext";
4847
            break;
4848
        default:
4849
            goto die;
4850
        }
4851
        break;
4852
    case 21:
4853
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4854
        switch (sel) {
4855
        case 0:
4856
            gen_helper_mtc0_framemask(t0);
4857
            rn = "Framemask";
4858
            break;
4859
        default:
4860
            goto die;
4861
        }
4862
        break;
4863
    case 22:
4864
        /* ignored */
4865
        rn = "Diagnostic"; /* implementation dependent */
4866
        break;
4867
    case 23:
4868
        switch (sel) {
4869
        case 0:
4870
            gen_helper_mtc0_debug(t0); /* EJTAG support */
4871
            /* BS_STOP isn't good enough here, hflags may have changed. */
4872
            gen_save_pc(ctx->pc + 4);
4873
            ctx->bstate = BS_EXCP;
4874
            rn = "Debug";
4875
            break;
4876
        case 1:
4877
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
4878
            /* Stop translation as we may have switched the execution mode */
4879
            ctx->bstate = BS_STOP;
4880
            rn = "TraceControl";
4881
//            break;
4882
        case 2:
4883
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
4884
            /* Stop translation as we may have switched the execution mode */
4885
            ctx->bstate = BS_STOP;
4886
            rn = "TraceControl2";
4887
//            break;
4888
        case 3:
4889
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
4890
            /* Stop translation as we may have switched the execution mode */
4891
            ctx->bstate = BS_STOP;
4892
            rn = "UserTraceData";
4893
//            break;
4894
        case 4:
4895
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
4896
            /* Stop translation as we may have switched the execution mode */
4897
            ctx->bstate = BS_STOP;
4898
            rn = "TraceBPC";
4899
//            break;
4900
        default:
4901
            goto die;
4902
        }
4903
        break;
4904
    case 24:
4905
        switch (sel) {
4906
        case 0:
4907
            /* EJTAG support */
4908
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4909
            rn = "DEPC";
4910
            break;
4911
        default:
4912
            goto die;
4913
        }
4914
        break;
4915
    case 25:
4916
        switch (sel) {
4917
        case 0:
4918
            gen_helper_mtc0_performance0(t0);
4919
            rn = "Performance0";
4920
            break;
4921
        case 1:
4922
//            gen_helper_mtc0_performance1(t0);
4923
            rn = "Performance1";
4924
//            break;
4925
        case 2:
4926
//            gen_helper_mtc0_performance2(t0);
4927
            rn = "Performance2";
4928
//            break;
4929
        case 3:
4930
//            gen_helper_mtc0_performance3(t0);
4931
            rn = "Performance3";
4932
//            break;
4933
        case 4:
4934
//            gen_helper_mtc0_performance4(t0);
4935
            rn = "Performance4";
4936
//            break;
4937
        case 5:
4938
//            gen_helper_mtc0_performance5(t0);
4939
            rn = "Performance5";
4940
//            break;
4941
        case 6:
4942
//            gen_helper_mtc0_performance6(t0);
4943
            rn = "Performance6";
4944
//            break;
4945
        case 7:
4946
//            gen_helper_mtc0_performance7(t0);
4947
            rn = "Performance7";
4948
//            break;
4949
        default:
4950
            goto die;
4951
        }
4952
        break;
4953
    case 26:
4954
        /* ignored */
4955
        rn = "ECC";
4956
        break;
4957
    case 27:
4958
        switch (sel) {
4959
        case 0 ... 3:
4960
            /* ignored */
4961
            rn = "CacheErr";
4962
            break;
4963
        default:
4964
            goto die;
4965
        }
4966
        break;
4967
    case 28:
4968
        switch (sel) {
4969
        case 0:
4970
        case 2:
4971
        case 4:
4972
        case 6:
4973
            gen_helper_mtc0_taglo(t0);
4974
            rn = "TagLo";
4975
            break;
4976
        case 1:
4977
        case 3:
4978
        case 5:
4979
        case 7:
4980
            gen_helper_mtc0_datalo(t0);
4981
            rn = "DataLo";
4982
            break;
4983
        default:
4984
            goto die;
4985
        }
4986
        break;
4987
    case 29:
4988
        switch (sel) {
4989
        case 0:
4990
        case 2:
4991
        case 4:
4992
        case 6:
4993
            gen_helper_mtc0_taghi(t0);
4994
            rn = "TagHi";
4995
            break;
4996
        case 1:
4997
        case 3:
4998
        case 5:
4999
        case 7:
5000
            gen_helper_mtc0_datahi(t0);
5001
            rn = "DataHi";
5002
            break;
5003
        default:
5004
            rn = "invalid sel";
5005
            goto die;
5006
        }
5007
        break;
5008
    case 30:
5009
        switch (sel) {
5010
        case 0:
5011
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5012
            rn = "ErrorEPC";
5013
            break;
5014
        default:
5015
            goto die;
5016
        }
5017
        break;
5018
    case 31:
5019
        switch (sel) {
5020
        case 0:
5021
            /* EJTAG support */
5022
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
5023
            rn = "DESAVE";
5024
            break;
5025
        default:
5026
            goto die;
5027
        }
5028
        /* Stop translation as we may have switched the execution mode */
5029
        ctx->bstate = BS_STOP;
5030
        break;
5031
    default:
5032
        goto die;
5033
    }
5034
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5035
    /* For simplicity assume that all writes can cause interrupts.  */
5036
    if (use_icount) {
5037
        gen_io_end();
5038
        ctx->bstate = BS_STOP;
5039
    }
5040
    return;
5041

    
5042
die:
5043
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5044
    generate_exception(ctx, EXCP_RI);
5045
}
5046
#endif /* TARGET_MIPS64 */
5047

    
5048
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5049
                     int u, int sel, int h)
5050
{
5051
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5052
    TCGv t0 = tcg_temp_local_new();
5053

    
5054
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5055
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5056
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5057
        tcg_gen_movi_tl(t0, -1);
5058
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5059
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5060
        tcg_gen_movi_tl(t0, -1);
5061
    else if (u == 0) {
5062
        switch (rt) {
5063
        case 2:
5064
            switch (sel) {
5065
            case 1:
5066
                gen_helper_mftc0_tcstatus(t0);
5067
                break;
5068
            case 2:
5069
                gen_helper_mftc0_tcbind(t0);
5070
                break;
5071
            case 3:
5072
                gen_helper_mftc0_tcrestart(t0);
5073
                break;
5074
            case 4:
5075
                gen_helper_mftc0_tchalt(t0);
5076
                break;
5077
            case 5:
5078
                gen_helper_mftc0_tccontext(t0);
5079
                break;
5080
            case 6:
5081
                gen_helper_mftc0_tcschedule(t0);
5082
                break;
5083
            case 7:
5084
                gen_helper_mftc0_tcschefback(t0);
5085
                break;
5086
            default:
5087
                gen_mfc0(env, ctx, t0, rt, sel);
5088
                break;
5089
            }
5090
            break;
5091
        case 10:
5092
            switch (sel) {
5093
            case 0:
5094
                gen_helper_mftc0_entryhi(t0);
5095
                break;
5096
            default:
5097
                gen_mfc0(env, ctx, t0, rt, sel);
5098
                break;
5099
            }
5100
        case 12:
5101
            switch (sel) {
5102
            case 0:
5103
                gen_helper_mftc0_status(t0);
5104
                break;
5105
            default:
5106
                gen_mfc0(env, ctx, t0, rt, sel);
5107
                break;
5108
            }
5109
        case 23:
5110
            switch (sel) {
5111
            case 0:
5112
                gen_helper_mftc0_debug(t0);
5113
                break;
5114
            default:
5115
                gen_mfc0(env, ctx, t0, rt, sel);
5116
                break;
5117
            }
5118
            break;
5119
        default:
5120
            gen_mfc0(env, ctx, t0, rt, sel);
5121
        }
5122
    } else switch (sel) {
5123
    /* GPR registers. */
5124
    case 0:
5125
        gen_helper_1i(mftgpr, t0, rt);
5126
        break;
5127
    /* Auxiliary CPU registers */
5128
    case 1:
5129
        switch (rt) {
5130
        case 0:
5131
            gen_helper_1i(mftlo, t0, 0);
5132
            break;
5133
        case 1:
5134
            gen_helper_1i(mfthi, t0, 0);
5135
            break;
5136
        case 2:
5137
            gen_helper_1i(mftacx, t0, 0);
5138
            break;
5139
        case 4:
5140
            gen_helper_1i(mftlo, t0, 1);
5141
            break;
5142
        case 5:
5143
            gen_helper_1i(mfthi, t0, 1);
5144
            break;
5145
        case 6:
5146
            gen_helper_1i(mftacx, t0, 1);
5147
            break;
5148
        case 8:
5149
            gen_helper_1i(mftlo, t0, 2);
5150
            break;
5151
        case 9:
5152
            gen_helper_1i(mfthi, t0, 2);
5153
            break;
5154
        case 10:
5155
            gen_helper_1i(mftacx, t0, 2);
5156
            break;
5157
        case 12:
5158
            gen_helper_1i(mftlo, t0, 3);
5159
            break;
5160
        case 13:
5161
            gen_helper_1i(mfthi, t0, 3);
5162
            break;
5163
        case 14:
5164
            gen_helper_1i(mftacx, t0, 3);
5165
            break;
5166
        case 16:
5167
            gen_helper_mftdsp(t0);
5168
            break;
5169
        default:
5170
            goto die;
5171
        }
5172
        break;
5173
    /* Floating point (COP1). */
5174
    case 2:
5175
        /* XXX: For now we support only a single FPU context. */
5176
        if (h == 0) {
5177
            TCGv_i32 fp0 = tcg_temp_new_i32();
5178

    
5179
            gen_load_fpr32(fp0, rt);
5180
            tcg_gen_ext_i32_tl(t0, fp0);
5181
            tcg_temp_free_i32(fp0);
5182
        } else {
5183
            TCGv_i32 fp0 = tcg_temp_new_i32();
5184

    
5185
            gen_load_fpr32h(fp0, rt);
5186
            tcg_gen_ext_i32_tl(t0, fp0);
5187
            tcg_temp_free_i32(fp0);
5188
        }
5189
        break;
5190
    case 3:
5191
        /* XXX: For now we support only a single FPU context. */
5192
        gen_helper_1i(cfc1, t0, rt);
5193
        break;
5194
    /* COP2: Not implemented. */
5195
    case 4:
5196
    case 5:
5197
        /* fall through */
5198
    default:
5199
        goto die;
5200
    }
5201
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5202
    gen_store_gpr(t0, rd);
5203
    tcg_temp_free(t0);
5204
    return;
5205

    
5206
die:
5207
    tcg_temp_free(t0);
5208
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5209
    generate_exception(ctx, EXCP_RI);
5210
}
5211

    
5212
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5213
                     int u, int sel, int h)
5214
{
5215
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5216
    TCGv t0 = tcg_temp_local_new();
5217

    
5218
    gen_load_gpr(t0, rt);
5219
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5220
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5221
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5222
        /* NOP */ ;
5223
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5224
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5225
        /* NOP */ ;
5226
    else if (u == 0) {
5227
        switch (rd) {
5228
        case 2:
5229
            switch (sel) {
5230
            case 1:
5231
                gen_helper_mttc0_tcstatus(t0);
5232
                break;
5233
            case 2:
5234
                gen_helper_mttc0_tcbind(t0);
5235
                break;
5236
            case 3:
5237
                gen_helper_mttc0_tcrestart(t0);
5238
                break;
5239
            case 4:
5240
                gen_helper_mttc0_tchalt(t0);
5241
                break;
5242
            case 5:
5243
                gen_helper_mttc0_tccontext(t0);
5244
                break;
5245
            case 6:
5246
                gen_helper_mttc0_tcschedule(t0);
5247
                break;
5248
            case 7:
5249
                gen_helper_mttc0_tcschefback(t0);
5250
                break;
5251
            default:
5252
                gen_mtc0(env, ctx, t0, rd, sel);
5253
                break;
5254
            }
5255
            break;
5256
        case 10:
5257
            switch (sel) {
5258
            case 0:
5259
                gen_helper_mttc0_entryhi(t0);
5260
                break;
5261
            default:
5262
                gen_mtc0(env, ctx, t0, rd, sel);
5263
                break;
5264
            }
5265
        case 12:
5266
            switch (sel) {
5267
            case 0:
5268
                gen_helper_mttc0_status(t0);
5269
                break;
5270
            default:
5271
                gen_mtc0(env, ctx, t0, rd, sel);
5272
                break;
5273
            }
5274
        case 23:
5275
            switch (sel) {
5276
            case 0:
5277
                gen_helper_mttc0_debug(t0);
5278
                break;
5279
            default:
5280
                gen_mtc0(env, ctx, t0, rd, sel);
5281
                break;
5282
            }
5283
            break;
5284
        default:
5285
            gen_mtc0(env, ctx, t0, rd, sel);
5286
        }
5287
    } else switch (sel) {
5288
    /* GPR registers. */
5289
    case 0:
5290
        gen_helper_1i(mttgpr, t0, rd);
5291
        break;
5292
    /* Auxiliary CPU registers */
5293
    case 1:
5294
        switch (rd) {
5295
        case 0:
5296
            gen_helper_1i(mttlo, t0, 0);
5297
            break;
5298
        case 1:
5299
            gen_helper_1i(mtthi, t0, 0);
5300
            break;
5301
        case 2:
5302
            gen_helper_1i(mttacx, t0, 0);
5303
            break;
5304
        case 4:
5305
            gen_helper_1i(mttlo, t0, 1);
5306
            break;
5307
        case 5:
5308
            gen_helper_1i(mtthi, t0, 1);
5309
            break;
5310
        case 6:
5311
            gen_helper_1i(mttacx, t0, 1);
5312
            break;
5313
        case 8:
5314
            gen_helper_1i(mttlo, t0, 2);
5315
            break;
5316
        case 9:
5317
            gen_helper_1i(mtthi, t0, 2);
5318
            break;
5319
        case 10:
5320
            gen_helper_1i(mttacx, t0, 2);
5321
            break;
5322
        case 12:
5323
            gen_helper_1i(mttlo, t0, 3);
5324
            break;
5325
        case 13:
5326
            gen_helper_1i(mtthi, t0, 3);
5327
            break;
5328
        case 14:
5329
            gen_helper_1i(mttacx, t0, 3);
5330
            break;
5331
        case 16:
5332
            gen_helper_mttdsp(t0);
5333
            break;
5334
        default:
5335
            goto die;
5336
        }
5337
        break;
5338
    /* Floating point (COP1). */
5339
    case 2:
5340
        /* XXX: For now we support only a single FPU context. */
5341
        if (h == 0) {
5342
            TCGv_i32 fp0 = tcg_temp_new_i32();
5343

    
5344
            tcg_gen_trunc_tl_i32(fp0, t0);
5345
            gen_store_fpr32(fp0, rd);
5346
            tcg_temp_free_i32(fp0);
5347
        } else {
5348
            TCGv_i32 fp0 = tcg_temp_new_i32();
5349

    
5350
            tcg_gen_trunc_tl_i32(fp0, t0);
5351
            gen_store_fpr32h(fp0, rd);
5352
            tcg_temp_free_i32(fp0);
5353
        }
5354
        break;
5355
    case 3:
5356
        /* XXX: For now we support only a single FPU context. */
5357
        gen_helper_1i(ctc1, t0, rd);
5358
        break;
5359
    /* COP2: Not implemented. */
5360
    case 4:
5361
    case 5:
5362
        /* fall through */
5363
    default:
5364
        goto die;
5365
    }
5366
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5367
    tcg_temp_free(t0);
5368
    return;
5369

    
5370
die:
5371
    tcg_temp_free(t0);
5372
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5373
    generate_exception(ctx, EXCP_RI);
5374
}
5375

    
5376
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5377
{
5378
    const char *opn = "ldst";
5379

    
5380
    switch (opc) {
5381
    case OPC_MFC0:
5382
        if (rt == 0) {
5383
            /* Treat as NOP. */
5384
            return;
5385
        }
5386
        {
5387
            TCGv t0 = tcg_temp_local_new();
5388

    
5389
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5390
            gen_store_gpr(t0, rt);
5391
            tcg_temp_free(t0);
5392
        }
5393
        opn = "mfc0";
5394
        break;
5395
    case OPC_MTC0:
5396
        {
5397
            TCGv t0 = tcg_temp_local_new();
5398

    
5399
            gen_load_gpr(t0, rt);
5400
            save_cpu_state(ctx, 1);
5401
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5402
            tcg_temp_free(t0);
5403
        }
5404
        opn = "mtc0";
5405
        break;
5406
#if defined(TARGET_MIPS64)
5407
    case OPC_DMFC0:
5408
        check_insn(env, ctx, ISA_MIPS3);
5409
        if (rt == 0) {
5410
            /* Treat as NOP. */
5411
            return;
5412
        }
5413
        {
5414
            TCGv t0 = tcg_temp_local_new();
5415

    
5416
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5417
            gen_store_gpr(t0, rt);
5418
            tcg_temp_free(t0);
5419
        }
5420
        opn = "dmfc0";
5421
        break;
5422
    case OPC_DMTC0:
5423
        check_insn(env, ctx, ISA_MIPS3);
5424
        {
5425
            TCGv t0 = tcg_temp_local_new();
5426

    
5427
            gen_load_gpr(t0, rt);
5428
            save_cpu_state(ctx, 1);
5429
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5430
            tcg_temp_free(t0);
5431
        }
5432
        opn = "dmtc0";
5433
        break;
5434
#endif
5435
    case OPC_MFTR:
5436
        check_insn(env, ctx, ASE_MT);
5437
        if (rd == 0) {
5438
            /* Treat as NOP. */
5439
            return;
5440
        }
5441
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5442
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5443
        opn = "mftr";
5444
        break;
5445
    case OPC_MTTR:
5446
        check_insn(env, ctx, ASE_MT);
5447
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5448
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5449
        opn = "mttr";
5450
        break;
5451
    case OPC_TLBWI:
5452
        opn = "tlbwi";
5453
        if (!env->tlb->helper_tlbwi)
5454
            goto die;
5455
        gen_helper_tlbwi();
5456
        break;
5457
    case OPC_TLBWR:
5458
        opn = "tlbwr";
5459
        if (!env->tlb->helper_tlbwr)
5460
            goto die;
5461
        gen_helper_tlbwr();
5462
        break;
5463
    case OPC_TLBP:
5464
        opn = "tlbp";
5465
        if (!env->tlb->helper_tlbp)
5466
            goto die;
5467
        gen_helper_tlbp();
5468
        break;
5469
    case OPC_TLBR:
5470
        opn = "tlbr";
5471
        if (!env->tlb->helper_tlbr)
5472
            goto die;
5473
        gen_helper_tlbr();
5474
        break;
5475
    case OPC_ERET:
5476
        opn = "eret";
5477
        check_insn(env, ctx, ISA_MIPS2);
5478
        save_cpu_state(ctx, 1);
5479
        gen_helper_eret();
5480
        ctx->bstate = BS_EXCP;
5481
        break;
5482
    case OPC_DERET:
5483
        opn = "deret";
5484
        check_insn(env, ctx, ISA_MIPS32);
5485
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5486
            MIPS_INVAL(opn);
5487
            generate_exception(ctx, EXCP_RI);
5488
        } else {
5489
            save_cpu_state(ctx, 1);
5490
            gen_helper_deret();
5491
            ctx->bstate = BS_EXCP;
5492
        }
5493
        break;
5494
    case OPC_WAIT:
5495
        opn = "wait";
5496
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5497
        /* If we get an exception, we want to restart at next instruction */
5498
        ctx->pc += 4;
5499
        save_cpu_state(ctx, 1);
5500
        ctx->pc -= 4;
5501
        gen_helper_wait();
5502
        ctx->bstate = BS_EXCP;
5503
        break;
5504
    default:
5505
 die:
5506
        MIPS_INVAL(opn);
5507
        generate_exception(ctx, EXCP_RI);
5508
        return;
5509
    }
5510
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5511
}
5512
#endif /* !CONFIG_USER_ONLY */
5513

    
5514
/* CP1 Branches (before delay slot) */
5515
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5516
                                 int32_t cc, int32_t offset)
5517
{
5518
    target_ulong btarget;
5519
    const char *opn = "cp1 cond branch";
5520
    TCGv_i32 t0 = tcg_temp_new_i32();
5521

    
5522
    if (cc != 0)
5523
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5524

    
5525
    btarget = ctx->pc + 4 + offset;
5526

    
5527
    switch (op) {
5528
    case OPC_BC1F:
5529
        {
5530
            int l1 = gen_new_label();
5531
            int l2 = gen_new_label();
5532

    
5533
            get_fp_cond(t0);
5534
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5535
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5536
            tcg_gen_movi_i32(bcond, 0);
5537
            tcg_gen_br(l2);
5538
            gen_set_label(l1);
5539
            tcg_gen_movi_i32(bcond, 1);
5540
            gen_set_label(l2);
5541
        }
5542
        opn = "bc1f";
5543
        goto not_likely;
5544
    case OPC_BC1FL:
5545
        {
5546
            int l1 = gen_new_label();
5547
            int l2 = gen_new_label();
5548

    
5549
            get_fp_cond(t0);
5550
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5551
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5552
            tcg_gen_movi_i32(bcond, 0);
5553
            tcg_gen_br(l2);
5554
            gen_set_label(l1);
5555
            tcg_gen_movi_i32(bcond, 1);
5556
            gen_set_label(l2);
5557
        }
5558
        opn = "bc1fl";
5559
        goto likely;
5560
    case OPC_BC1T:
5561
        {
5562
            int l1 = gen_new_label();
5563
            int l2 = gen_new_label();
5564

    
5565
            get_fp_cond(t0);
5566
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5567
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5568
            tcg_gen_movi_i32(bcond, 0);
5569
            tcg_gen_br(l2);
5570
            gen_set_label(l1);
5571
            tcg_gen_movi_i32(bcond, 1);
5572
            gen_set_label(l2);
5573
        }
5574
        opn = "bc1t";
5575
        goto not_likely;
5576
    case OPC_BC1TL:
5577
        {
5578
            int l1 = gen_new_label();
5579
            int l2 = gen_new_label();
5580

    
5581
            get_fp_cond(t0);
5582
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5583
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5584
            tcg_gen_movi_i32(bcond, 0);
5585
            tcg_gen_br(l2);
5586
            gen_set_label(l1);
5587
            tcg_gen_movi_i32(bcond, 1);
5588
            gen_set_label(l2);
5589
        }
5590
        opn = "bc1tl";
5591
    likely:
5592
        ctx->hflags |= MIPS_HFLAG_BL;
5593
        break;
5594
    case OPC_BC1FANY2:
5595
        {
5596
            int l1 = gen_new_label();
5597
            int l2 = gen_new_label();
5598

    
5599
            get_fp_cond(t0);
5600
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5601
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5602
            tcg_gen_movi_i32(bcond, 0);
5603
            tcg_gen_br(l2);
5604
            gen_set_label(l1);
5605
            tcg_gen_movi_i32(bcond, 1);
5606
            gen_set_label(l2);
5607
        }
5608
        opn = "bc1any2f";
5609
        goto not_likely;
5610
    case OPC_BC1TANY2:
5611
        {
5612
            int l1 = gen_new_label();
5613
            int l2 = gen_new_label();
5614

    
5615
            get_fp_cond(t0);
5616
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5617
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5618
            tcg_gen_movi_i32(bcond, 0);
5619
            tcg_gen_br(l2);
5620
            gen_set_label(l1);
5621
            tcg_gen_movi_i32(bcond, 1);
5622
            gen_set_label(l2);
5623
        }
5624
        opn = "bc1any2t";
5625
        goto not_likely;
5626
    case OPC_BC1FANY4:
5627
        {
5628
            int l1 = gen_new_label();
5629
            int l2 = gen_new_label();
5630

    
5631
            get_fp_cond(t0);
5632
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5633
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5634
            tcg_gen_movi_i32(bcond, 0);
5635
            tcg_gen_br(l2);
5636
            gen_set_label(l1);
5637
            tcg_gen_movi_i32(bcond, 1);
5638
            gen_set_label(l2);
5639
        }
5640
        opn = "bc1any4f";
5641
        goto not_likely;
5642
    case OPC_BC1TANY4:
5643
        {
5644
            int l1 = gen_new_label();
5645
            int l2 = gen_new_label();
5646

    
5647
            get_fp_cond(t0);
5648
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5649
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5650
            tcg_gen_movi_i32(bcond, 0);
5651
            tcg_gen_br(l2);
5652
            gen_set_label(l1);
5653
            tcg_gen_movi_i32(bcond, 1);
5654
            gen_set_label(l2);
5655
        }
5656
        opn = "bc1any4t";
5657
    not_likely:
5658
        ctx->hflags |= MIPS_HFLAG_BC;
5659
        break;
5660
    default:
5661
        MIPS_INVAL(opn);
5662
        generate_exception (ctx, EXCP_RI);
5663
        goto out;
5664
    }
5665
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5666
               ctx->hflags, btarget);
5667
    ctx->btarget = btarget;
5668

    
5669
 out:
5670
    tcg_temp_free_i32(t0);
5671
}
5672

    
5673
/* Coprocessor 1 (FPU) */
5674

    
5675
#define FOP(func, fmt) (((fmt) << 21) | (func))
5676

    
5677
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5678
{
5679
    const char *opn = "cp1 move";
5680
    TCGv t0 = tcg_temp_local_new();
5681

    
5682
    switch (opc) {
5683
    case OPC_MFC1:
5684
        {
5685
            TCGv_i32 fp0 = tcg_temp_new_i32();
5686

    
5687
            gen_load_fpr32(fp0, fs);
5688
            tcg_gen_ext_i32_tl(t0, fp0);
5689
            tcg_temp_free_i32(fp0);
5690
        }
5691
        gen_store_gpr(t0, rt);
5692
        opn = "mfc1";
5693
        break;
5694
    case OPC_MTC1:
5695
        gen_load_gpr(t0, rt);
5696
        {
5697
            TCGv_i32 fp0 = tcg_temp_new_i32();
5698

    
5699
            tcg_gen_trunc_tl_i32(fp0, t0);
5700
            gen_store_fpr32(fp0, fs);
5701
            tcg_temp_free_i32(fp0);
5702
        }
5703
        opn = "mtc1";
5704
        break;
5705
    case OPC_CFC1:
5706
        gen_helper_1i(cfc1, t0, fs);
5707
        gen_store_gpr(t0, rt);
5708
        opn = "cfc1";
5709
        break;
5710
    case OPC_CTC1:
5711
        gen_load_gpr(t0, rt);
5712
        gen_helper_1i(ctc1, t0, fs);
5713
        opn = "ctc1";
5714
        break;
5715
    case OPC_DMFC1:
5716
        {
5717
            TCGv_i64 fp0 = tcg_temp_new_i64();
5718

    
5719
            gen_load_fpr64(ctx, fp0, fs);
5720
            tcg_gen_trunc_i64_tl(t0, fp0);
5721
            tcg_temp_free_i64(fp0);
5722
        }
5723
        gen_store_gpr(t0, rt);
5724
        opn = "dmfc1";
5725
        break;
5726
    case OPC_DMTC1:
5727
        gen_load_gpr(t0, rt);
5728
        {
5729
            TCGv_i64 fp0 = tcg_temp_new_i64();
5730

    
5731
            tcg_gen_extu_tl_i64(fp0, t0);
5732
            gen_store_fpr64(ctx, fp0, fs);
5733
            tcg_temp_free_i64(fp0);
5734
        }
5735
        opn = "dmtc1";
5736
        break;
5737
    case OPC_MFHC1:
5738
        {
5739
            TCGv_i32 fp0 = tcg_temp_new_i32();
5740

    
5741
            gen_load_fpr32h(fp0, fs);
5742
            tcg_gen_ext_i32_tl(t0, fp0);
5743
            tcg_temp_free_i32(fp0);
5744
        }
5745
        gen_store_gpr(t0, rt);
5746
        opn = "mfhc1";
5747
        break;
5748
    case OPC_MTHC1:
5749
        gen_load_gpr(t0, rt);
5750
        {
5751
            TCGv_i32 fp0 = tcg_temp_new_i32();
5752

    
5753
            tcg_gen_trunc_tl_i32(fp0, t0);
5754
            gen_store_fpr32h(fp0, fs);
5755
            tcg_temp_free_i32(fp0);
5756
        }
5757
        opn = "mthc1";
5758
        break;
5759
    default:
5760
        MIPS_INVAL(opn);
5761
        generate_exception (ctx, EXCP_RI);
5762
        goto out;
5763
    }
5764
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5765

    
5766
 out:
5767
    tcg_temp_free(t0);
5768
}
5769

    
5770
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5771
{
5772
    int l1 = gen_new_label();
5773
    uint32_t ccbit;
5774
    TCGCond cond;
5775
    TCGv t0 = tcg_temp_local_new();
5776
    TCGv_i32 r_tmp = tcg_temp_new_i32();
5777

    
5778
    if (cc)
5779
        ccbit = 1 << (24 + cc);
5780
    else
5781
        ccbit = 1 << 23;
5782
    if (tf)
5783
        cond = TCG_COND_EQ;
5784
    else
5785
        cond = TCG_COND_NE;
5786

    
5787
    gen_load_gpr(t0, rd);
5788
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5789
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5790
    tcg_temp_free_i32(r_tmp);
5791
    gen_load_gpr(t0, rs);
5792
    gen_set_label(l1);
5793
    gen_store_gpr(t0, rd);
5794
    tcg_temp_free(t0);
5795
}
5796

    
5797
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5798
{
5799
    uint32_t ccbit;
5800
    int cond;
5801
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5802
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5803
    int l1 = gen_new_label();
5804

    
5805
    if (cc)
5806
        ccbit = 1 << (24 + cc);
5807
    else
5808
        ccbit = 1 << 23;
5809

    
5810
    if (tf)
5811
        cond = TCG_COND_EQ;
5812
    else
5813
        cond = TCG_COND_NE;
5814

    
5815
    gen_load_fpr32(fp0, fd);
5816
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5817
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5818
    tcg_temp_free_i32(r_tmp1);
5819
    gen_load_fpr32(fp0, fs);
5820
    gen_set_label(l1);
5821
    gen_store_fpr32(fp0, fd);
5822
    tcg_temp_free_i32(fp0);
5823
}
5824

    
5825
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5826
{
5827
    uint32_t ccbit;
5828
    int cond;
5829
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5830
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5831
    int l1 = gen_new_label();
5832

    
5833
    if (cc)
5834
        ccbit = 1 << (24 + cc);
5835
    else
5836
        ccbit = 1 << 23;
5837

    
5838
    if (tf)
5839
        cond = TCG_COND_EQ;
5840
    else
5841
        cond = TCG_COND_NE;
5842

    
5843
    gen_load_fpr64(ctx, fp0, fd);
5844
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5845
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5846
    tcg_temp_free_i32(r_tmp1);
5847
    gen_load_fpr64(ctx, fp0, fs);
5848
    gen_set_label(l1);
5849
    gen_store_fpr64(ctx, fp0, fd);
5850
    tcg_temp_free_i64(fp0);
5851
}
5852

    
5853
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5854
{
5855
    uint32_t ccbit1, ccbit2;
5856
    int cond;
5857
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5858
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5859
    int l1 = gen_new_label();
5860
    int l2 = gen_new_label();
5861

    
5862
    if (cc) {
5863
        ccbit1 = 1 << (24 + cc);
5864
        ccbit2 = 1 << (25 + cc);
5865
    } else {
5866
        ccbit1 = 1 << 23;
5867
        ccbit2 = 1 << 25;
5868
    }
5869

    
5870
    if (tf)
5871
        cond = TCG_COND_EQ;
5872
    else
5873
        cond = TCG_COND_NE;
5874

    
5875
    gen_load_fpr32(fp0, fd);
5876
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5877
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5878
    gen_load_fpr32(fp0, fs);
5879
    gen_set_label(l1);
5880
    gen_store_fpr32(fp0, fd);
5881

    
5882
    gen_load_fpr32h(fp0, fd);
5883
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5884
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5885
    gen_load_fpr32h(fp0, fs);
5886
    gen_set_label(l2);
5887
    gen_store_fpr32h(fp0, fd);
5888

    
5889
    tcg_temp_free_i32(r_tmp1);
5890
    tcg_temp_free_i32(fp0);
5891
}
5892

    
5893

    
5894
static void gen_farith (DisasContext *ctx, uint32_t op1,
5895
                        int ft, int fs, int fd, int cc)
5896
{
5897
    const char *opn = "farith";
5898
    const char *condnames[] = {
5899
            "c.f",
5900
            "c.un",
5901
            "c.eq",
5902
            "c.ueq",
5903
            "c.olt",
5904
            "c.ult",
5905
            "c.ole",
5906
            "c.ule",
5907
            "c.sf",
5908
            "c.ngle",
5909
            "c.seq",
5910
            "c.ngl",
5911
            "c.lt",
5912
            "c.nge",
5913
            "c.le",
5914
            "c.ngt",
5915
    };
5916
    const char *condnames_abs[] = {
5917
            "cabs.f",
5918
            "cabs.un",
5919
            "cabs.eq",
5920
            "cabs.ueq",
5921
            "cabs.olt",
5922
            "cabs.ult",
5923
            "cabs.ole",
5924
            "cabs.ule",
5925
            "cabs.sf",
5926
            "cabs.ngle",
5927
            "cabs.seq",
5928
            "cabs.ngl",
5929
            "cabs.lt",
5930
            "cabs.nge",
5931
            "cabs.le",
5932
            "cabs.ngt",
5933
    };
5934
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5935
    uint32_t func = ctx->opcode & 0x3f;
5936

    
5937
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5938
    case FOP(0, 16):
5939
        {
5940
            TCGv_i32 fp0 = tcg_temp_new_i32();
5941
            TCGv_i32 fp1 = tcg_temp_new_i32();
5942

    
5943
            gen_load_fpr32(fp0, fs);
5944
            gen_load_fpr32(fp1, ft);
5945
            gen_helper_float_add_s(fp0, fp0, fp1);
5946
            tcg_temp_free_i32(fp1);
5947
            gen_store_fpr32(fp0, fd);
5948
            tcg_temp_free_i32(fp0);
5949
        }
5950
        opn = "add.s";
5951
        optype = BINOP;
5952
        break;
5953
    case FOP(1, 16):
5954
        {
5955
            TCGv_i32 fp0 = tcg_temp_new_i32();
5956
            TCGv_i32 fp1 = tcg_temp_new_i32();
5957

    
5958
            gen_load_fpr32(fp0, fs);
5959
            gen_load_fpr32(fp1, ft);
5960
            gen_helper_float_sub_s(fp0, fp0, fp1);
5961
            tcg_temp_free_i32(fp1);
5962
            gen_store_fpr32(fp0, fd);
5963
            tcg_temp_free_i32(fp0);
5964
        }
5965
        opn = "sub.s";
5966
        optype = BINOP;
5967
        break;
5968
    case FOP(2, 16):
5969
        {
5970
            TCGv_i32 fp0 = tcg_temp_new_i32();
5971
            TCGv_i32 fp1 = tcg_temp_new_i32();
5972

    
5973
            gen_load_fpr32(fp0, fs);
5974
            gen_load_fpr32(fp1, ft);
5975
            gen_helper_float_mul_s(fp0, fp0, fp1);
5976
            tcg_temp_free_i32(fp1);
5977
            gen_store_fpr32(fp0, fd);
5978
            tcg_temp_free_i32(fp0);
5979
        }
5980
        opn = "mul.s";
5981
        optype = BINOP;
5982
        break;
5983
    case FOP(3, 16):
5984
        {
5985
            TCGv_i32 fp0 = tcg_temp_new_i32();
5986
            TCGv_i32 fp1 = tcg_temp_new_i32();
5987

    
5988
            gen_load_fpr32(fp0, fs);
5989
            gen_load_fpr32(fp1, ft);
5990
            gen_helper_float_div_s(fp0, fp0, fp1);
5991
            tcg_temp_free_i32(fp1);
5992
            gen_store_fpr32(fp0, fd);
5993
            tcg_temp_free_i32(fp0);
5994
        }
5995
        opn = "div.s";
5996
        optype = BINOP;
5997
        break;
5998
    case FOP(4, 16):
5999
        {
6000
            TCGv_i32 fp0 = tcg_temp_new_i32();
6001

    
6002
            gen_load_fpr32(fp0, fs);
6003
            gen_helper_float_sqrt_s(fp0, fp0);
6004
            gen_store_fpr32(fp0, fd);
6005
            tcg_temp_free_i32(fp0);
6006
        }
6007
        opn = "sqrt.s";
6008
        break;
6009
    case FOP(5, 16):
6010
        {
6011
            TCGv_i32 fp0 = tcg_temp_new_i32();
6012

    
6013
            gen_load_fpr32(fp0, fs);
6014
            gen_helper_float_abs_s(fp0, fp0);
6015
            gen_store_fpr32(fp0, fd);
6016
            tcg_temp_free_i32(fp0);
6017
        }
6018
        opn = "abs.s";
6019
        break;
6020
    case FOP(6, 16):
6021
        {
6022
            TCGv_i32 fp0 = tcg_temp_new_i32();
6023

    
6024
            gen_load_fpr32(fp0, fs);
6025
            gen_store_fpr32(fp0, fd);
6026
            tcg_temp_free_i32(fp0);
6027
        }
6028
        opn = "mov.s";
6029
        break;
6030
    case FOP(7, 16):
6031
        {
6032
            TCGv_i32 fp0 = tcg_temp_new_i32();
6033

    
6034
            gen_load_fpr32(fp0, fs);
6035
            gen_helper_float_chs_s(fp0, fp0);
6036
            gen_store_fpr32(fp0, fd);
6037
            tcg_temp_free_i32(fp0);
6038
        }
6039
        opn = "neg.s";
6040
        break;
6041
    case FOP(8, 16):
6042
        check_cp1_64bitmode(ctx);
6043
        {
6044
            TCGv_i32 fp32 = tcg_temp_new_i32();
6045
            TCGv_i64 fp64 = tcg_temp_new_i64();
6046

    
6047
            gen_load_fpr32(fp32, fs);
6048
            gen_helper_float_roundl_s(fp64, fp32);
6049
            tcg_temp_free_i32(fp32);
6050
            gen_store_fpr64(ctx, fp64, fd);
6051
            tcg_temp_free_i64(fp64);
6052
        }
6053
        opn = "round.l.s";
6054
        break;
6055
    case FOP(9, 16):
6056
        check_cp1_64bitmode(ctx);
6057
        {
6058
            TCGv_i32 fp32 = tcg_temp_new_i32();
6059
            TCGv_i64 fp64 = tcg_temp_new_i64();
6060

    
6061
            gen_load_fpr32(fp32, fs);
6062
            gen_helper_float_truncl_s(fp64, fp32);
6063
            tcg_temp_free_i32(fp32);
6064
            gen_store_fpr64(ctx, fp64, fd);
6065
            tcg_temp_free_i64(fp64);
6066
        }
6067
        opn = "trunc.l.s";
6068
        break;
6069
    case FOP(10, 16):
6070
        check_cp1_64bitmode(ctx);
6071
        {
6072
            TCGv_i32 fp32 = tcg_temp_new_i32();
6073
            TCGv_i64 fp64 = tcg_temp_new_i64();
6074

    
6075
            gen_load_fpr32(fp32, fs);
6076
            gen_helper_float_ceill_s(fp64, fp32);
6077
            tcg_temp_free_i32(fp32);
6078
            gen_store_fpr64(ctx, fp64, fd);
6079
            tcg_temp_free_i64(fp64);
6080
        }
6081
        opn = "ceil.l.s";
6082
        break;
6083
    case FOP(11, 16):
6084
        check_cp1_64bitmode(ctx);
6085
        {
6086
            TCGv_i32 fp32 = tcg_temp_new_i32();
6087
            TCGv_i64 fp64 = tcg_temp_new_i64();
6088

    
6089
            gen_load_fpr32(fp32, fs);
6090
            gen_helper_float_floorl_s(fp64, fp32);
6091
            tcg_temp_free_i32(fp32);
6092
            gen_store_fpr64(ctx, fp64, fd);
6093
            tcg_temp_free_i64(fp64);
6094
        }
6095
        opn = "floor.l.s";
6096
        break;
6097
    case FOP(12, 16):
6098
        {
6099
            TCGv_i32 fp0 = tcg_temp_new_i32();
6100

    
6101
            gen_load_fpr32(fp0, fs);
6102
            gen_helper_float_roundw_s(fp0, fp0);
6103
            gen_store_fpr32(fp0, fd);
6104
            tcg_temp_free_i32(fp0);
6105
        }
6106
        opn = "round.w.s";
6107
        break;
6108
    case FOP(13, 16):
6109
        {
6110
            TCGv_i32 fp0 = tcg_temp_new_i32();
6111

    
6112
            gen_load_fpr32(fp0, fs);
6113
            gen_helper_float_truncw_s(fp0, fp0);
6114
            gen_store_fpr32(fp0, fd);
6115
            tcg_temp_free_i32(fp0);
6116
        }
6117
        opn = "trunc.w.s";
6118
        break;
6119
    case FOP(14, 16):
6120
        {
6121
            TCGv_i32 fp0 = tcg_temp_new_i32();
6122

    
6123
            gen_load_fpr32(fp0, fs);
6124
            gen_helper_float_ceilw_s(fp0, fp0);
6125
            gen_store_fpr32(fp0, fd);
6126
            tcg_temp_free_i32(fp0);
6127
        }
6128
        opn = "ceil.w.s";
6129
        break;
6130
    case FOP(15, 16):
6131
        {
6132
            TCGv_i32 fp0 = tcg_temp_new_i32();
6133

    
6134
            gen_load_fpr32(fp0, fs);
6135
            gen_helper_float_floorw_s(fp0, fp0);
6136
            gen_store_fpr32(fp0, fd);
6137
            tcg_temp_free_i32(fp0);
6138
        }
6139
        opn = "floor.w.s";
6140
        break;
6141
    case FOP(17, 16):
6142
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6143
        opn = "movcf.s";
6144
        break;
6145
    case FOP(18, 16):
6146
        {
6147
            int l1 = gen_new_label();
6148
            TCGv t0 = tcg_temp_new();
6149
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6150

    
6151
            gen_load_gpr(t0, ft);
6152
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6153
            gen_load_fpr32(fp0, fs);
6154
            gen_store_fpr32(fp0, fd);
6155
            tcg_temp_free_i32(fp0);
6156
            gen_set_label(l1);
6157
            tcg_temp_free(t0);
6158
        }
6159
        opn = "movz.s";
6160
        break;
6161
    case FOP(19, 16):
6162
        {
6163
            int l1 = gen_new_label();
6164
            TCGv t0 = tcg_temp_new();
6165
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6166

    
6167
            gen_load_gpr(t0, ft);
6168
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6169
            gen_load_fpr32(fp0, fs);
6170
            gen_store_fpr32(fp0, fd);
6171
            tcg_temp_free_i32(fp0);
6172
            gen_set_label(l1);
6173
            tcg_temp_free(t0);
6174
        }
6175
        opn = "movn.s";
6176
        break;
6177
    case FOP(21, 16):
6178
        check_cop1x(ctx);
6179
        {
6180
            TCGv_i32 fp0 = tcg_temp_new_i32();
6181

    
6182
            gen_load_fpr32(fp0, fs);
6183
            gen_helper_float_recip_s(fp0, fp0);
6184
            gen_store_fpr32(fp0, fd);
6185
            tcg_temp_free_i32(fp0);
6186
        }
6187
        opn = "recip.s";
6188
        break;
6189
    case FOP(22, 16):
6190
        check_cop1x(ctx);
6191
        {
6192
            TCGv_i32 fp0 = tcg_temp_new_i32();
6193

    
6194
            gen_load_fpr32(fp0, fs);
6195
            gen_helper_float_rsqrt_s(fp0, fp0);
6196
            gen_store_fpr32(fp0, fd);
6197
            tcg_temp_free_i32(fp0);
6198
        }
6199
        opn = "rsqrt.s";
6200
        break;
6201
    case FOP(28, 16):
6202
        check_cp1_64bitmode(ctx);
6203
        {
6204
            TCGv_i32 fp0 = tcg_temp_new_i32();
6205
            TCGv_i32 fp1 = tcg_temp_new_i32();
6206

    
6207
            gen_load_fpr32(fp0, fs);
6208
            gen_load_fpr32(fp1, fd);
6209
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6210
            tcg_temp_free_i32(fp1);
6211
            gen_store_fpr32(fp0, fd);
6212
            tcg_temp_free_i32(fp0);
6213
        }
6214
        opn = "recip2.s";
6215
        break;
6216
    case FOP(29, 16):
6217
        check_cp1_64bitmode(ctx);
6218
        {
6219
            TCGv_i32 fp0 = tcg_temp_new_i32();
6220

    
6221
            gen_load_fpr32(fp0, fs);
6222
            gen_helper_float_recip1_s(fp0, fp0);
6223
            gen_store_fpr32(fp0, fd);
6224
            tcg_temp_free_i32(fp0);
6225
        }
6226
        opn = "recip1.s";
6227
        break;
6228
    case FOP(30, 16):
6229
        check_cp1_64bitmode(ctx);
6230
        {
6231
            TCGv_i32 fp0 = tcg_temp_new_i32();
6232

    
6233
            gen_load_fpr32(fp0, fs);
6234
            gen_helper_float_rsqrt1_s(fp0, fp0);
6235
            gen_store_fpr32(fp0, fd);
6236
            tcg_temp_free_i32(fp0);
6237
        }
6238
        opn = "rsqrt1.s";
6239
        break;
6240
    case FOP(31, 16):
6241
        check_cp1_64bitmode(ctx);
6242
        {
6243
            TCGv_i32 fp0 = tcg_temp_new_i32();
6244
            TCGv_i32 fp1 = tcg_temp_new_i32();
6245

    
6246
            gen_load_fpr32(fp0, fs);
6247
            gen_load_fpr32(fp1, ft);
6248
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6249
            tcg_temp_free_i32(fp1);
6250
            gen_store_fpr32(fp0, fd);
6251
            tcg_temp_free_i32(fp0);
6252
        }
6253
        opn = "rsqrt2.s";
6254
        break;
6255
    case FOP(33, 16):
6256
        check_cp1_registers(ctx, fd);
6257
        {
6258
            TCGv_i32 fp32 = tcg_temp_new_i32();
6259
            TCGv_i64 fp64 = tcg_temp_new_i64();
6260

    
6261
            gen_load_fpr32(fp32, fs);
6262
            gen_helper_float_cvtd_s(fp64, fp32);
6263
            tcg_temp_free_i32(fp32);
6264
            gen_store_fpr64(ctx, fp64, fd);
6265
            tcg_temp_free_i64(fp64);
6266
        }
6267
        opn = "cvt.d.s";
6268
        break;
6269
    case FOP(36, 16):
6270
        {
6271
            TCGv_i32 fp0 = tcg_temp_new_i32();
6272

    
6273
            gen_load_fpr32(fp0, fs);
6274
            gen_helper_float_cvtw_s(fp0, fp0);
6275
            gen_store_fpr32(fp0, fd);
6276
            tcg_temp_free_i32(fp0);
6277
        }
6278
        opn = "cvt.w.s";
6279
        break;
6280
    case FOP(37, 16):
6281
        check_cp1_64bitmode(ctx);
6282
        {
6283
            TCGv_i32 fp32 = tcg_temp_new_i32();
6284
            TCGv_i64 fp64 = tcg_temp_new_i64();
6285

    
6286
            gen_load_fpr32(fp32, fs);
6287
            gen_helper_float_cvtl_s(fp64, fp32);
6288
            tcg_temp_free_i32(fp32);
6289
            gen_store_fpr64(ctx, fp64, fd);
6290
            tcg_temp_free_i64(fp64);
6291
        }
6292
        opn = "cvt.l.s";
6293
        break;
6294
    case FOP(38, 16):
6295
        check_cp1_64bitmode(ctx);
6296
        {
6297
            TCGv_i64 fp64 = tcg_temp_new_i64();
6298
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6299
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6300

    
6301
            gen_load_fpr32(fp32_0, fs);
6302
            gen_load_fpr32(fp32_1, ft);
6303
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6304
            tcg_temp_free_i32(fp32_1);
6305
            tcg_temp_free_i32(fp32_0);
6306
            gen_store_fpr64(ctx, fp64, fd);
6307
            tcg_temp_free_i64(fp64);
6308
        }
6309
        opn = "cvt.ps.s";
6310
        break;
6311
    case FOP(48, 16):
6312
    case FOP(49, 16):
6313
    case FOP(50, 16):
6314
    case FOP(51, 16):
6315
    case FOP(52, 16):
6316
    case FOP(53, 16):
6317
    case FOP(54, 16):
6318
    case FOP(55, 16):
6319
    case FOP(56, 16):
6320
    case FOP(57, 16):
6321
    case FOP(58, 16):
6322
    case FOP(59, 16):
6323
    case FOP(60, 16):
6324
    case FOP(61, 16):
6325
    case FOP(62, 16):
6326
    case FOP(63, 16):
6327
        {
6328
            TCGv_i32 fp0 = tcg_temp_new_i32();
6329
            TCGv_i32 fp1 = tcg_temp_new_i32();
6330

    
6331
            gen_load_fpr32(fp0, fs);
6332
            gen_load_fpr32(fp1, ft);
6333
            if (ctx->opcode & (1 << 6)) {
6334
                check_cop1x(ctx);
6335
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6336
                opn = condnames_abs[func-48];
6337
            } else {
6338
                gen_cmp_s(func-48, fp0, fp1, cc);
6339
                opn = condnames[func-48];
6340
            }
6341
            tcg_temp_free_i32(fp0);
6342
            tcg_temp_free_i32(fp1);
6343
        }
6344
        break;
6345
    case FOP(0, 17):
6346
        check_cp1_registers(ctx, fs | ft | fd);
6347
        {
6348
            TCGv_i64 fp0 = tcg_temp_new_i64();
6349
            TCGv_i64 fp1 = tcg_temp_new_i64();
6350

    
6351
            gen_load_fpr64(ctx, fp0, fs);
6352
            gen_load_fpr64(ctx, fp1, ft);
6353
            gen_helper_float_add_d(fp0, fp0, fp1);
6354
            tcg_temp_free_i64(fp1);
6355
            gen_store_fpr64(ctx, fp0, fd);
6356
            tcg_temp_free_i64(fp0);
6357
        }
6358
        opn = "add.d";
6359
        optype = BINOP;
6360
        break;
6361
    case FOP(1, 17):
6362
        check_cp1_registers(ctx, fs | ft | fd);
6363
        {
6364
            TCGv_i64 fp0 = tcg_temp_new_i64();
6365
            TCGv_i64 fp1 = tcg_temp_new_i64();
6366

    
6367
            gen_load_fpr64(ctx, fp0, fs);
6368
            gen_load_fpr64(ctx, fp1, ft);
6369
            gen_helper_float_sub_d(fp0, fp0, fp1);
6370
            tcg_temp_free_i64(fp1);
6371
            gen_store_fpr64(ctx, fp0, fd);
6372
            tcg_temp_free_i64(fp0);
6373
        }
6374
        opn = "sub.d";
6375
        optype = BINOP;
6376
        break;
6377
    case FOP(2, 17):
6378
        check_cp1_registers(ctx, fs | ft | fd);
6379
        {
6380
            TCGv_i64 fp0 = tcg_temp_new_i64();
6381
            TCGv_i64 fp1 = tcg_temp_new_i64();
6382

    
6383
            gen_load_fpr64(ctx, fp0, fs);
6384
            gen_load_fpr64(ctx, fp1, ft);
6385
            gen_helper_float_mul_d(fp0, fp0, fp1);
6386
            tcg_temp_free_i64(fp1);
6387
            gen_store_fpr64(ctx, fp0, fd);
6388
            tcg_temp_free_i64(fp0);
6389
        }
6390
        opn = "mul.d";
6391
        optype = BINOP;
6392
        break;
6393
    case FOP(3, 17):
6394
        check_cp1_registers(ctx, fs | ft | fd);
6395
        {
6396
            TCGv_i64 fp0 = tcg_temp_new_i64();
6397
            TCGv_i64 fp1 = tcg_temp_new_i64();
6398

    
6399
            gen_load_fpr64(ctx, fp0, fs);
6400
            gen_load_fpr64(ctx, fp1, ft);
6401
            gen_helper_float_div_d(fp0, fp0, fp1);
6402
            tcg_temp_free_i64(fp1);
6403
            gen_store_fpr64(ctx, fp0, fd);
6404
            tcg_temp_free_i64(fp0);
6405
        }
6406
        opn = "div.d";
6407
        optype = BINOP;
6408
        break;
6409
    case FOP(4, 17):
6410
        check_cp1_registers(ctx, fs | fd);
6411
        {
6412
            TCGv_i64 fp0 = tcg_temp_new_i64();
6413

    
6414
            gen_load_fpr64(ctx, fp0, fs);
6415
            gen_helper_float_sqrt_d(fp0, fp0);
6416
            gen_store_fpr64(ctx, fp0, fd);
6417
            tcg_temp_free_i64(fp0);
6418
        }
6419
        opn = "sqrt.d";
6420
        break;
6421
    case FOP(5, 17):
6422
        check_cp1_registers(ctx, fs | fd);
6423
        {
6424
            TCGv_i64 fp0 = tcg_temp_new_i64();
6425

    
6426
            gen_load_fpr64(ctx, fp0, fs);
6427
            gen_helper_float_abs_d(fp0, fp0);
6428
            gen_store_fpr64(ctx, fp0, fd);
6429
            tcg_temp_free_i64(fp0);
6430
        }
6431
        opn = "abs.d";
6432
        break;
6433
    case FOP(6, 17):
6434
        check_cp1_registers(ctx, fs | fd);
6435
        {
6436
            TCGv_i64 fp0 = tcg_temp_new_i64();
6437

    
6438
            gen_load_fpr64(ctx, fp0, fs);
6439
            gen_store_fpr64(ctx, fp0, fd);
6440
            tcg_temp_free_i64(fp0);
6441
        }
6442
        opn = "mov.d";
6443
        break;
6444
    case FOP(7, 17):
6445
        check_cp1_registers(ctx, fs | fd);
6446
        {
6447
            TCGv_i64 fp0 = tcg_temp_new_i64();
6448

    
6449
            gen_load_fpr64(ctx, fp0, fs);
6450
            gen_helper_float_chs_d(fp0, fp0);
6451
            gen_store_fpr64(ctx, fp0, fd);
6452
            tcg_temp_free_i64(fp0);
6453
        }
6454
        opn = "neg.d";
6455
        break;
6456
    case FOP(8, 17):
6457
        check_cp1_64bitmode(ctx);
6458
        {
6459
            TCGv_i64 fp0 = tcg_temp_new_i64();
6460

    
6461
            gen_load_fpr64(ctx, fp0, fs);
6462
            gen_helper_float_roundl_d(fp0, fp0);
6463
            gen_store_fpr64(ctx, fp0, fd);
6464
            tcg_temp_free_i64(fp0);
6465
        }
6466
        opn = "round.l.d";
6467
        break;
6468
    case FOP(9, 17):
6469
        check_cp1_64bitmode(ctx);
6470
        {
6471
            TCGv_i64 fp0 = tcg_temp_new_i64();
6472

    
6473
            gen_load_fpr64(ctx, fp0, fs);
6474
            gen_helper_float_truncl_d(fp0, fp0);
6475
            gen_store_fpr64(ctx, fp0, fd);
6476
            tcg_temp_free_i64(fp0);
6477
        }
6478
        opn = "trunc.l.d";
6479
        break;
6480
    case FOP(10, 17):
6481
        check_cp1_64bitmode(ctx);
6482
        {
6483
            TCGv_i64 fp0 = tcg_temp_new_i64();
6484

    
6485
            gen_load_fpr64(ctx, fp0, fs);
6486
            gen_helper_float_ceill_d(fp0, fp0);
6487
            gen_store_fpr64(ctx, fp0, fd);
6488
            tcg_temp_free_i64(fp0);
6489
        }
6490
        opn = "ceil.l.d";
6491
        break;
6492
    case FOP(11, 17):
6493
        check_cp1_64bitmode(ctx);
6494
        {
6495
            TCGv_i64 fp0 = tcg_temp_new_i64();
6496

    
6497
            gen_load_fpr64(ctx, fp0, fs);
6498
            gen_helper_float_floorl_d(fp0, fp0);
6499
            gen_store_fpr64(ctx, fp0, fd);
6500
            tcg_temp_free_i64(fp0);
6501
        }
6502
        opn = "floor.l.d";
6503
        break;
6504
    case FOP(12, 17):
6505
        check_cp1_registers(ctx, fs);
6506
        {
6507
            TCGv_i32 fp32 = tcg_temp_new_i32();
6508
            TCGv_i64 fp64 = tcg_temp_new_i64();
6509

    
6510
            gen_load_fpr64(ctx, fp64, fs);
6511
            gen_helper_float_roundw_d(fp32, fp64);
6512
            tcg_temp_free_i64(fp64);
6513
            gen_store_fpr32(fp32, fd);
6514
            tcg_temp_free_i32(fp32);
6515
        }
6516
        opn = "round.w.d";
6517
        break;
6518
    case FOP(13, 17):
6519
        check_cp1_registers(ctx, fs);
6520
        {
6521
            TCGv_i32 fp32 = tcg_temp_new_i32();
6522
            TCGv_i64 fp64 = tcg_temp_new_i64();
6523

    
6524
            gen_load_fpr64(ctx, fp64, fs);
6525
            gen_helper_float_truncw_d(fp32, fp64);
6526
            tcg_temp_free_i64(fp64);
6527
            gen_store_fpr32(fp32, fd);
6528
            tcg_temp_free_i32(fp32);
6529
        }
6530
        opn = "trunc.w.d";
6531
        break;
6532
    case FOP(14, 17):
6533
        check_cp1_registers(ctx, fs);
6534
        {
6535
            TCGv_i32 fp32 = tcg_temp_new_i32();
6536
            TCGv_i64 fp64 = tcg_temp_new_i64();
6537

    
6538
            gen_load_fpr64(ctx, fp64, fs);
6539
            gen_helper_float_ceilw_d(fp32, fp64);
6540
            tcg_temp_free_i64(fp64);
6541
            gen_store_fpr32(fp32, fd);
6542
            tcg_temp_free_i32(fp32);
6543
        }
6544
        opn = "ceil.w.d";
6545
        break;
6546
    case FOP(15, 17):
6547
        check_cp1_registers(ctx, fs);
6548
        {
6549
            TCGv_i32 fp32 = tcg_temp_new_i32();
6550
            TCGv_i64 fp64 = tcg_temp_new_i64();
6551

    
6552
            gen_load_fpr64(ctx, fp64, fs);
6553
            gen_helper_float_floorw_d(fp32, fp64);
6554
            tcg_temp_free_i64(fp64);
6555
            gen_store_fpr32(fp32, fd);
6556
            tcg_temp_free_i32(fp32);
6557
        }
6558
        opn = "floor.w.d";
6559
        break;
6560
    case FOP(17, 17):
6561
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6562
        opn = "movcf.d";
6563
        break;
6564
    case FOP(18, 17):
6565
        {
6566
            int l1 = gen_new_label();
6567
            TCGv t0 = tcg_temp_new();
6568
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6569

    
6570
            gen_load_gpr(t0, ft);
6571
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6572
            gen_load_fpr64(ctx, fp0, fs);
6573
            gen_store_fpr64(ctx, fp0, fd);
6574
            tcg_temp_free_i64(fp0);
6575
            gen_set_label(l1);
6576
            tcg_temp_free(t0);
6577
        }
6578
        opn = "movz.d";
6579
        break;
6580
    case FOP(19, 17):
6581
        {
6582
            int l1 = gen_new_label();
6583
            TCGv t0 = tcg_temp_new();
6584
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6585

    
6586
            gen_load_gpr(t0, ft);
6587
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6588
            gen_load_fpr64(ctx, fp0, fs);
6589
            gen_store_fpr64(ctx, fp0, fd);
6590
            tcg_temp_free_i64(fp0);
6591
            gen_set_label(l1);
6592
            tcg_temp_free(t0);
6593
        }
6594
        opn = "movn.d";
6595
        break;
6596
    case FOP(21, 17):
6597
        check_cp1_64bitmode(ctx);
6598
        {
6599
            TCGv_i64 fp0 = tcg_temp_new_i64();
6600

    
6601
            gen_load_fpr64(ctx, fp0, fs);
6602
            gen_helper_float_recip_d(fp0, fp0);
6603
            gen_store_fpr64(ctx, fp0, fd);
6604
            tcg_temp_free_i64(fp0);
6605
        }
6606
        opn = "recip.d";
6607
        break;
6608
    case FOP(22, 17):
6609
        check_cp1_64bitmode(ctx);
6610
        {
6611
            TCGv_i64 fp0 = tcg_temp_new_i64();
6612

    
6613
            gen_load_fpr64(ctx, fp0, fs);
6614
            gen_helper_float_rsqrt_d(fp0, fp0);
6615
            gen_store_fpr64(ctx, fp0, fd);
6616
            tcg_temp_free_i64(fp0);
6617
        }
6618
        opn = "rsqrt.d";
6619
        break;
6620
    case FOP(28, 17):
6621
        check_cp1_64bitmode(ctx);
6622
        {
6623
            TCGv_i64 fp0 = tcg_temp_new_i64();
6624
            TCGv_i64 fp1 = tcg_temp_new_i64();
6625

    
6626
            gen_load_fpr64(ctx, fp0, fs);
6627
            gen_load_fpr64(ctx, fp1, ft);
6628
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6629
            tcg_temp_free_i64(fp1);
6630
            gen_store_fpr64(ctx, fp0, fd);
6631
            tcg_temp_free_i64(fp0);
6632
        }
6633
        opn = "recip2.d";
6634
        break;
6635
    case FOP(29, 17):
6636
        check_cp1_64bitmode(ctx);
6637
        {
6638
            TCGv_i64 fp0 = tcg_temp_new_i64();
6639

    
6640
            gen_load_fpr64(ctx, fp0, fs);
6641
            gen_helper_float_recip1_d(fp0, fp0);
6642
            gen_store_fpr64(ctx, fp0, fd);
6643
            tcg_temp_free_i64(fp0);
6644
        }
6645
        opn = "recip1.d";
6646
        break;
6647
    case FOP(30, 17):
6648
        check_cp1_64bitmode(ctx);
6649
        {
6650
            TCGv_i64 fp0 = tcg_temp_new_i64();
6651

    
6652
            gen_load_fpr64(ctx, fp0, fs);
6653
            gen_helper_float_rsqrt1_d(fp0, fp0);
6654
            gen_store_fpr64(ctx, fp0, fd);
6655
            tcg_temp_free_i64(fp0);
6656
        }
6657
        opn = "rsqrt1.d";
6658
        break;
6659
    case FOP(31, 17):
6660
        check_cp1_64bitmode(ctx);
6661
        {
6662
            TCGv_i64 fp0 = tcg_temp_new_i64();
6663
            TCGv_i64 fp1 = tcg_temp_new_i64();
6664

    
6665
            gen_load_fpr64(ctx, fp0, fs);
6666
            gen_load_fpr64(ctx, fp1, ft);
6667
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6668
            tcg_temp_free_i64(fp1);
6669
            gen_store_fpr64(ctx, fp0, fd);
6670
            tcg_temp_free_i64(fp0);
6671
        }
6672
        opn = "rsqrt2.d";
6673
        break;
6674
    case FOP(48, 17):
6675
    case FOP(49, 17):
6676
    case FOP(50, 17):
6677
    case FOP(51, 17):
6678
    case FOP(52, 17):
6679
    case FOP(53, 17):
6680
    case FOP(54, 17):
6681
    case FOP(55, 17):
6682
    case FOP(56, 17):
6683
    case FOP(57, 17):
6684
    case FOP(58, 17):
6685
    case FOP(59, 17):
6686
    case FOP(60, 17):
6687
    case FOP(61, 17):
6688
    case FOP(62, 17):
6689
    case FOP(63, 17):
6690
        {
6691
            TCGv_i64 fp0 = tcg_temp_new_i64();
6692
            TCGv_i64 fp1 = tcg_temp_new_i64();
6693

    
6694
            gen_load_fpr64(ctx, fp0, fs);
6695
            gen_load_fpr64(ctx, fp1, ft);
6696
            if (ctx->opcode & (1 << 6)) {
6697
                check_cop1x(ctx);
6698
                check_cp1_registers(ctx, fs | ft);
6699
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6700
                opn = condnames_abs[func-48];
6701
            } else {
6702
                check_cp1_registers(ctx, fs | ft);
6703
                gen_cmp_d(func-48, fp0, fp1, cc);
6704
                opn = condnames[func-48];
6705
            }
6706
            tcg_temp_free_i64(fp0);
6707
            tcg_temp_free_i64(fp1);
6708
        }
6709
        break;
6710
    case FOP(32, 17):
6711
        check_cp1_registers(ctx, fs);
6712
        {
6713
            TCGv_i32 fp32 = tcg_temp_new_i32();
6714
            TCGv_i64 fp64 = tcg_temp_new_i64();
6715

    
6716
            gen_load_fpr64(ctx, fp64, fs);
6717
            gen_helper_float_cvts_d(fp32, fp64);
6718
            tcg_temp_free_i64(fp64);
6719
            gen_store_fpr32(fp32, fd);
6720
            tcg_temp_free_i32(fp32);
6721
        }
6722
        opn = "cvt.s.d";
6723
        break;
6724
    case FOP(36, 17):
6725
        check_cp1_registers(ctx, fs);
6726
        {
6727
            TCGv_i32 fp32 = tcg_temp_new_i32();
6728
            TCGv_i64 fp64 = tcg_temp_new_i64();
6729

    
6730
            gen_load_fpr64(ctx, fp64, fs);
6731
            gen_helper_float_cvtw_d(fp32, fp64);
6732
            tcg_temp_free_i64(fp64);
6733
            gen_store_fpr32(fp32, fd);
6734
            tcg_temp_free_i32(fp32);
6735
        }
6736
        opn = "cvt.w.d";
6737
        break;
6738
    case FOP(37, 17):
6739
        check_cp1_64bitmode(ctx);
6740
        {
6741
            TCGv_i64 fp0 = tcg_temp_new_i64();
6742

    
6743
            gen_load_fpr64(ctx, fp0, fs);
6744
            gen_helper_float_cvtl_d(fp0, fp0);
6745
            gen_store_fpr64(ctx, fp0, fd);
6746
            tcg_temp_free_i64(fp0);
6747
        }
6748
        opn = "cvt.l.d";
6749
        break;
6750
    case FOP(32, 20):
6751
        {
6752
            TCGv_i32 fp0 = tcg_temp_new_i32();
6753

    
6754
            gen_load_fpr32(fp0, fs);
6755
            gen_helper_float_cvts_w(fp0, fp0);
6756
            gen_store_fpr32(fp0, fd);
6757
            tcg_temp_free_i32(fp0);
6758
        }
6759
        opn = "cvt.s.w";
6760
        break;
6761
    case FOP(33, 20):
6762
        check_cp1_registers(ctx, fd);
6763
        {
6764
            TCGv_i32 fp32 = tcg_temp_new_i32();
6765
            TCGv_i64 fp64 = tcg_temp_new_i64();
6766

    
6767
            gen_load_fpr32(fp32, fs);
6768
            gen_helper_float_cvtd_w(fp64, fp32);
6769
            tcg_temp_free_i32(fp32);
6770
            gen_store_fpr64(ctx, fp64, fd);
6771
            tcg_temp_free_i64(fp64);
6772
        }
6773
        opn = "cvt.d.w";
6774
        break;
6775
    case FOP(32, 21):
6776
        check_cp1_64bitmode(ctx);
6777
        {
6778
            TCGv_i32 fp32 = tcg_temp_new_i32();
6779
            TCGv_i64 fp64 = tcg_temp_new_i64();
6780

    
6781
            gen_load_fpr64(ctx, fp64, fs);
6782
            gen_helper_float_cvts_l(fp32, fp64);
6783
            tcg_temp_free_i64(fp64);
6784
            gen_store_fpr32(fp32, fd);
6785
            tcg_temp_free_i32(fp32);
6786
        }
6787
        opn = "cvt.s.l";
6788
        break;
6789
    case FOP(33, 21):
6790
        check_cp1_64bitmode(ctx);
6791
        {
6792
            TCGv_i64 fp0 = tcg_temp_new_i64();
6793

    
6794
            gen_load_fpr64(ctx, fp0, fs);
6795
            gen_helper_float_cvtd_l(fp0, fp0);
6796
            gen_store_fpr64(ctx, fp0, fd);
6797
            tcg_temp_free_i64(fp0);
6798
        }
6799
        opn = "cvt.d.l";
6800
        break;
6801
    case FOP(38, 20):
6802
        check_cp1_64bitmode(ctx);
6803
        {
6804
            TCGv_i64 fp0 = tcg_temp_new_i64();
6805

    
6806
            gen_load_fpr64(ctx, fp0, fs);
6807
            gen_helper_float_cvtps_pw(fp0, fp0);
6808
            gen_store_fpr64(ctx, fp0, fd);
6809
            tcg_temp_free_i64(fp0);
6810
        }
6811
        opn = "cvt.ps.pw";
6812
        break;
6813
    case FOP(0, 22):
6814
        check_cp1_64bitmode(ctx);
6815
        {
6816
            TCGv_i64 fp0 = tcg_temp_new_i64();
6817
            TCGv_i64 fp1 = tcg_temp_new_i64();
6818

    
6819
            gen_load_fpr64(ctx, fp0, fs);
6820
            gen_load_fpr64(ctx, fp1, ft);
6821
            gen_helper_float_add_ps(fp0, fp0, fp1);
6822
            tcg_temp_free_i64(fp1);
6823
            gen_store_fpr64(ctx, fp0, fd);
6824
            tcg_temp_free_i64(fp0);
6825
        }
6826
        opn = "add.ps";
6827
        break;
6828
    case FOP(1, 22):
6829
        check_cp1_64bitmode(ctx);
6830
        {
6831
            TCGv_i64 fp0 = tcg_temp_new_i64();
6832
            TCGv_i64 fp1 = tcg_temp_new_i64();
6833

    
6834
            gen_load_fpr64(ctx, fp0, fs);
6835
            gen_load_fpr64(ctx, fp1, ft);
6836
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6837
            tcg_temp_free_i64(fp1);
6838
            gen_store_fpr64(ctx, fp0, fd);
6839
            tcg_temp_free_i64(fp0);
6840
        }
6841
        opn = "sub.ps";
6842
        break;
6843
    case FOP(2, 22):
6844
        check_cp1_64bitmode(ctx);
6845
        {
6846
            TCGv_i64 fp0 = tcg_temp_new_i64();
6847
            TCGv_i64 fp1 = tcg_temp_new_i64();
6848

    
6849
            gen_load_fpr64(ctx, fp0, fs);
6850
            gen_load_fpr64(ctx, fp1, ft);
6851
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6852
            tcg_temp_free_i64(fp1);
6853
            gen_store_fpr64(ctx, fp0, fd);
6854
            tcg_temp_free_i64(fp0);
6855
        }
6856
        opn = "mul.ps";
6857
        break;
6858
    case FOP(5, 22):
6859
        check_cp1_64bitmode(ctx);
6860
        {
6861
            TCGv_i64 fp0 = tcg_temp_new_i64();
6862

    
6863
            gen_load_fpr64(ctx, fp0, fs);
6864
            gen_helper_float_abs_ps(fp0, fp0);
6865
            gen_store_fpr64(ctx, fp0, fd);
6866
            tcg_temp_free_i64(fp0);
6867
        }
6868
        opn = "abs.ps";
6869
        break;
6870
    case FOP(6, 22):
6871
        check_cp1_64bitmode(ctx);
6872
        {
6873
            TCGv_i64 fp0 = tcg_temp_new_i64();
6874

    
6875
            gen_load_fpr64(ctx, fp0, fs);
6876
            gen_store_fpr64(ctx, fp0, fd);
6877
            tcg_temp_free_i64(fp0);
6878
        }
6879
        opn = "mov.ps";
6880
        break;
6881
    case FOP(7, 22):
6882
        check_cp1_64bitmode(ctx);
6883
        {
6884
            TCGv_i64 fp0 = tcg_temp_new_i64();
6885

    
6886
            gen_load_fpr64(ctx, fp0, fs);
6887
            gen_helper_float_chs_ps(fp0, fp0);
6888
            gen_store_fpr64(ctx, fp0, fd);
6889
            tcg_temp_free_i64(fp0);
6890
        }
6891
        opn = "neg.ps";
6892
        break;
6893
    case FOP(17, 22):
6894
        check_cp1_64bitmode(ctx);
6895
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6896
        opn = "movcf.ps";
6897
        break;
6898
    case FOP(18, 22):
6899
        check_cp1_64bitmode(ctx);
6900
        {
6901
            int l1 = gen_new_label();
6902
            TCGv t0 = tcg_temp_new();
6903
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6904
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6905

    
6906
            gen_load_gpr(t0, ft);
6907
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6908
            gen_load_fpr32(fp0, fs);
6909
            gen_load_fpr32h(fph0, fs);
6910
            gen_store_fpr32(fp0, fd);
6911
            gen_store_fpr32h(fph0, fd);
6912
            tcg_temp_free_i32(fp0);
6913
            tcg_temp_free_i32(fph0);
6914
            gen_set_label(l1);
6915
            tcg_temp_free(t0);
6916
        }
6917
        opn = "movz.ps";
6918
        break;
6919
    case FOP(19, 22):
6920
        check_cp1_64bitmode(ctx);
6921
        {
6922
            int l1 = gen_new_label();
6923
            TCGv t0 = tcg_temp_new();
6924
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6925
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6926

    
6927
            gen_load_gpr(t0, ft);
6928
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6929
            gen_load_fpr32(fp0, fs);
6930
            gen_load_fpr32h(fph0, fs);
6931
            gen_store_fpr32(fp0, fd);
6932
            gen_store_fpr32h(fph0, fd);
6933
            tcg_temp_free_i32(fp0);
6934
            tcg_temp_free_i32(fph0);
6935
            gen_set_label(l1);
6936
            tcg_temp_free(t0);
6937
        }
6938
        opn = "movn.ps";
6939
        break;
6940
    case FOP(24, 22):
6941
        check_cp1_64bitmode(ctx);
6942
        {
6943
            TCGv_i64 fp0 = tcg_temp_new_i64();
6944
            TCGv_i64 fp1 = tcg_temp_new_i64();
6945

    
6946
            gen_load_fpr64(ctx, fp0, ft);
6947
            gen_load_fpr64(ctx, fp1, fs);
6948
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6949
            tcg_temp_free_i64(fp1);
6950
            gen_store_fpr64(ctx, fp0, fd);
6951
            tcg_temp_free_i64(fp0);
6952
        }
6953
        opn = "addr.ps";
6954
        break;
6955
    case FOP(26, 22):
6956
        check_cp1_64bitmode(ctx);
6957
        {
6958
            TCGv_i64 fp0 = tcg_temp_new_i64();
6959
            TCGv_i64 fp1 = tcg_temp_new_i64();
6960

    
6961
            gen_load_fpr64(ctx, fp0, ft);
6962
            gen_load_fpr64(ctx, fp1, fs);
6963
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6964
            tcg_temp_free_i64(fp1);
6965
            gen_store_fpr64(ctx, fp0, fd);
6966
            tcg_temp_free_i64(fp0);
6967
        }
6968
        opn = "mulr.ps";
6969
        break;
6970
    case FOP(28, 22):
6971
        check_cp1_64bitmode(ctx);
6972
        {
6973
            TCGv_i64 fp0 = tcg_temp_new_i64();
6974
            TCGv_i64 fp1 = tcg_temp_new_i64();
6975

    
6976
            gen_load_fpr64(ctx, fp0, fs);
6977
            gen_load_fpr64(ctx, fp1, fd);
6978
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6979
            tcg_temp_free_i64(fp1);
6980
            gen_store_fpr64(ctx, fp0, fd);
6981
            tcg_temp_free_i64(fp0);
6982
        }
6983
        opn = "recip2.ps";
6984
        break;
6985
    case FOP(29, 22):
6986
        check_cp1_64bitmode(ctx);
6987
        {
6988
            TCGv_i64 fp0 = tcg_temp_new_i64();
6989

    
6990
            gen_load_fpr64(ctx, fp0, fs);
6991
            gen_helper_float_recip1_ps(fp0, fp0);
6992
            gen_store_fpr64(ctx, fp0, fd);
6993
            tcg_temp_free_i64(fp0);
6994
        }
6995
        opn = "recip1.ps";
6996
        break;
6997
    case FOP(30, 22):
6998
        check_cp1_64bitmode(ctx);
6999
        {
7000
            TCGv_i64 fp0 = tcg_temp_new_i64();
7001

    
7002
            gen_load_fpr64(ctx, fp0, fs);
7003
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7004
            gen_store_fpr64(ctx, fp0, fd);
7005
            tcg_temp_free_i64(fp0);
7006
        }
7007
        opn = "rsqrt1.ps";
7008
        break;
7009
    case FOP(31, 22):
7010
        check_cp1_64bitmode(ctx);
7011
        {
7012
            TCGv_i64 fp0 = tcg_temp_new_i64();
7013
            TCGv_i64 fp1 = tcg_temp_new_i64();
7014

    
7015
            gen_load_fpr64(ctx, fp0, fs);
7016
            gen_load_fpr64(ctx, fp1, ft);
7017
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7018
            tcg_temp_free_i64(fp1);
7019
            gen_store_fpr64(ctx, fp0, fd);
7020
            tcg_temp_free_i64(fp0);
7021
        }
7022
        opn = "rsqrt2.ps";
7023
        break;
7024
    case FOP(32, 22):
7025
        check_cp1_64bitmode(ctx);
7026
        {
7027
            TCGv_i32 fp0 = tcg_temp_new_i32();
7028

    
7029
            gen_load_fpr32h(fp0, fs);
7030
            gen_helper_float_cvts_pu(fp0, fp0);
7031
            gen_store_fpr32(fp0, fd);
7032
            tcg_temp_free_i32(fp0);
7033
        }
7034
        opn = "cvt.s.pu";
7035
        break;
7036
    case FOP(36, 22):
7037
        check_cp1_64bitmode(ctx);
7038
        {
7039
            TCGv_i64 fp0 = tcg_temp_new_i64();
7040

    
7041
            gen_load_fpr64(ctx, fp0, fs);
7042
            gen_helper_float_cvtpw_ps(fp0, fp0);
7043
            gen_store_fpr64(ctx, fp0, fd);
7044
            tcg_temp_free_i64(fp0);
7045
        }
7046
        opn = "cvt.pw.ps";
7047
        break;
7048
    case FOP(40, 22):
7049
        check_cp1_64bitmode(ctx);
7050
        {
7051
            TCGv_i32 fp0 = tcg_temp_new_i32();
7052

    
7053
            gen_load_fpr32(fp0, fs);
7054
            gen_helper_float_cvts_pl(fp0, fp0);
7055
            gen_store_fpr32(fp0, fd);
7056
            tcg_temp_free_i32(fp0);
7057
        }
7058
        opn = "cvt.s.pl";
7059
        break;
7060
    case FOP(44, 22):
7061
        check_cp1_64bitmode(ctx);
7062
        {
7063
            TCGv_i32 fp0 = tcg_temp_new_i32();
7064
            TCGv_i32 fp1 = tcg_temp_new_i32();
7065

    
7066
            gen_load_fpr32(fp0, fs);
7067
            gen_load_fpr32(fp1, ft);
7068
            gen_store_fpr32h(fp0, fd);
7069
            gen_store_fpr32(fp1, fd);
7070
            tcg_temp_free_i32(fp0);
7071
            tcg_temp_free_i32(fp1);
7072
        }
7073
        opn = "pll.ps";
7074
        break;
7075
    case FOP(45, 22):
7076
        check_cp1_64bitmode(ctx);
7077
        {
7078
            TCGv_i32 fp0 = tcg_temp_new_i32();
7079
            TCGv_i32 fp1 = tcg_temp_new_i32();
7080

    
7081
            gen_load_fpr32(fp0, fs);
7082
            gen_load_fpr32h(fp1, ft);
7083
            gen_store_fpr32(fp1, fd);
7084
            gen_store_fpr32h(fp0, fd);
7085
            tcg_temp_free_i32(fp0);
7086
            tcg_temp_free_i32(fp1);
7087
        }
7088
        opn = "plu.ps";
7089
        break;
7090
    case FOP(46, 22):
7091
        check_cp1_64bitmode(ctx);
7092
        {
7093
            TCGv_i32 fp0 = tcg_temp_new_i32();
7094
            TCGv_i32 fp1 = tcg_temp_new_i32();
7095

    
7096
            gen_load_fpr32h(fp0, fs);
7097
            gen_load_fpr32(fp1, ft);
7098
            gen_store_fpr32(fp1, fd);
7099
            gen_store_fpr32h(fp0, fd);
7100
            tcg_temp_free_i32(fp0);
7101
            tcg_temp_free_i32(fp1);
7102
        }
7103
        opn = "pul.ps";
7104
        break;
7105
    case FOP(47, 22):
7106
        check_cp1_64bitmode(ctx);
7107
        {
7108
            TCGv_i32 fp0 = tcg_temp_new_i32();
7109
            TCGv_i32 fp1 = tcg_temp_new_i32();
7110

    
7111
            gen_load_fpr32h(fp0, fs);
7112
            gen_load_fpr32h(fp1, ft);
7113
            gen_store_fpr32(fp1, fd);
7114
            gen_store_fpr32h(fp0, fd);
7115
            tcg_temp_free_i32(fp0);
7116
            tcg_temp_free_i32(fp1);
7117
        }
7118
        opn = "puu.ps";
7119
        break;
7120
    case FOP(48, 22):
7121
    case FOP(49, 22):
7122
    case FOP(50, 22):
7123
    case FOP(51, 22):
7124
    case FOP(52, 22):
7125
    case FOP(53, 22):
7126
    case FOP(54, 22):
7127
    case FOP(55, 22):
7128
    case FOP(56, 22):
7129
    case FOP(57, 22):
7130
    case FOP(58, 22):
7131
    case FOP(59, 22):
7132
    case FOP(60, 22):
7133
    case FOP(61, 22):
7134
    case FOP(62, 22):
7135
    case FOP(63, 22):
7136
        check_cp1_64bitmode(ctx);
7137
        {
7138
            TCGv_i64 fp0 = tcg_temp_new_i64();
7139
            TCGv_i64 fp1 = tcg_temp_new_i64();
7140

    
7141
            gen_load_fpr64(ctx, fp0, fs);
7142
            gen_load_fpr64(ctx, fp1, ft);
7143
            if (ctx->opcode & (1 << 6)) {
7144
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7145
                opn = condnames_abs[func-48];
7146
            } else {
7147
                gen_cmp_ps(func-48, fp0, fp1, cc);
7148
                opn = condnames[func-48];
7149
            }
7150
            tcg_temp_free_i64(fp0);
7151
            tcg_temp_free_i64(fp1);
7152
        }
7153
        break;
7154
    default:
7155
        MIPS_INVAL(opn);
7156
        generate_exception (ctx, EXCP_RI);
7157
        return;
7158
    }
7159
    switch (optype) {
7160
    case BINOP:
7161
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7162
        break;
7163
    case CMPOP:
7164
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7165
        break;
7166
    default:
7167
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7168
        break;
7169
    }
7170
}
7171

    
7172
/* Coprocessor 3 (FPU) */
7173
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7174
                           int fd, int fs, int base, int index)
7175
{
7176
    const char *opn = "extended float load/store";
7177
    int store = 0;
7178
    TCGv t0 = tcg_temp_local_new();
7179
    TCGv t1 = tcg_temp_local_new();
7180

    
7181
    if (base == 0) {
7182
        gen_load_gpr(t0, index);
7183
    } else if (index == 0) {
7184
        gen_load_gpr(t0, base);
7185
    } else {
7186
        gen_load_gpr(t0, index);
7187
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7188
    }
7189
    /* Don't do NOP if destination is zero: we must perform the actual
7190
       memory access. */
7191
    switch (opc) {
7192
    case OPC_LWXC1:
7193
        check_cop1x(ctx);
7194
        {
7195
            TCGv_i32 fp0 = tcg_temp_new_i32();
7196

    
7197
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7198
            tcg_gen_trunc_tl_i32(fp0, t1);
7199
            gen_store_fpr32(fp0, fd);
7200
            tcg_temp_free_i32(fp0);
7201
        }
7202
        opn = "lwxc1";
7203
        break;
7204
    case OPC_LDXC1:
7205
        check_cop1x(ctx);
7206
        check_cp1_registers(ctx, fd);
7207
        {
7208
            TCGv_i64 fp0 = tcg_temp_new_i64();
7209

    
7210
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7211
            gen_store_fpr64(ctx, fp0, fd);
7212
            tcg_temp_free_i64(fp0);
7213
        }
7214
        opn = "ldxc1";
7215
        break;
7216
    case OPC_LUXC1:
7217
        check_cp1_64bitmode(ctx);
7218
        tcg_gen_andi_tl(t0, t0, ~0x7);
7219
        {
7220
            TCGv_i64 fp0 = tcg_temp_new_i64();
7221

    
7222
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7223
            gen_store_fpr64(ctx, fp0, fd);
7224
            tcg_temp_free_i64(fp0);
7225
        }
7226
        opn = "luxc1";
7227
        break;
7228
    case OPC_SWXC1:
7229
        check_cop1x(ctx);
7230
        {
7231
            TCGv_i32 fp0 = tcg_temp_new_i32();
7232

    
7233
            gen_load_fpr32(fp0, fs);
7234
            tcg_gen_extu_i32_tl(t1, fp0);
7235
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7236
            tcg_temp_free_i32(fp0);
7237
        }
7238
        opn = "swxc1";
7239
        store = 1;
7240
        break;
7241
    case OPC_SDXC1:
7242
        check_cop1x(ctx);
7243
        check_cp1_registers(ctx, fs);
7244
        {
7245
            TCGv_i64 fp0 = tcg_temp_new_i64();
7246

    
7247
            gen_load_fpr64(ctx, fp0, fs);
7248
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7249
            tcg_temp_free_i64(fp0);
7250
        }
7251
        opn = "sdxc1";
7252
        store = 1;
7253
        break;
7254
    case OPC_SUXC1:
7255
        check_cp1_64bitmode(ctx);
7256
        tcg_gen_andi_tl(t0, t0, ~0x7);
7257
        {
7258
            TCGv_i64 fp0 = tcg_temp_new_i64();
7259

    
7260
            gen_load_fpr64(ctx, fp0, fs);
7261
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7262
            tcg_temp_free_i64(fp0);
7263
        }
7264
        opn = "suxc1";
7265
        store = 1;
7266
        break;
7267
    default:
7268
        MIPS_INVAL(opn);
7269
        generate_exception(ctx, EXCP_RI);
7270
        tcg_temp_free(t0);
7271
        tcg_temp_free(t1);
7272
        return;
7273
    }
7274
    tcg_temp_free(t0);
7275
    tcg_temp_free(t1);
7276
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7277
               regnames[index], regnames[base]);
7278
}
7279

    
7280
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7281
                            int fd, int fr, int fs, int ft)
7282
{
7283
    const char *opn = "flt3_arith";
7284

    
7285
    switch (opc) {
7286
    case OPC_ALNV_PS:
7287
        check_cp1_64bitmode(ctx);
7288
        {
7289
            TCGv t0 = tcg_temp_local_new();
7290
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7291
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7292
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7293
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7294
            int l1 = gen_new_label();
7295
            int l2 = gen_new_label();
7296

    
7297
            gen_load_gpr(t0, fr);
7298
            tcg_gen_andi_tl(t0, t0, 0x7);
7299
            gen_load_fpr32(fp0, fs);
7300
            gen_load_fpr32h(fph0, fs);
7301
            gen_load_fpr32(fp1, ft);
7302
            gen_load_fpr32h(fph1, ft);
7303

    
7304
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7305
            gen_store_fpr32(fp0, fd);
7306
            gen_store_fpr32h(fph0, fd);
7307
            tcg_gen_br(l2);
7308
            gen_set_label(l1);
7309
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7310
            tcg_temp_free(t0);
7311
#ifdef TARGET_WORDS_BIGENDIAN
7312
            gen_store_fpr32(fph1, fd);
7313
            gen_store_fpr32h(fp0, fd);
7314
#else
7315
            gen_store_fpr32(fph0, fd);
7316
            gen_store_fpr32h(fp1, fd);
7317
#endif
7318
            gen_set_label(l2);
7319
            tcg_temp_free_i32(fp0);
7320
            tcg_temp_free_i32(fph0);
7321
            tcg_temp_free_i32(fp1);
7322
            tcg_temp_free_i32(fph1);
7323
        }
7324
        opn = "alnv.ps";
7325
        break;
7326
    case OPC_MADD_S:
7327
        check_cop1x(ctx);
7328
        {
7329
            TCGv_i32 fp0 = tcg_temp_new_i32();
7330
            TCGv_i32 fp1 = tcg_temp_new_i32();
7331
            TCGv_i32 fp2 = tcg_temp_new_i32();
7332

    
7333
            gen_load_fpr32(fp0, fs);
7334
            gen_load_fpr32(fp1, ft);
7335
            gen_load_fpr32(fp2, fr);
7336
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7337
            tcg_temp_free_i32(fp0);
7338
            tcg_temp_free_i32(fp1);
7339
            gen_store_fpr32(fp2, fd);
7340
            tcg_temp_free_i32(fp2);
7341
        }
7342
        opn = "madd.s";
7343
        break;
7344
    case OPC_MADD_D:
7345
        check_cop1x(ctx);
7346
        check_cp1_registers(ctx, fd | fs | ft | fr);
7347
        {
7348
            TCGv_i64 fp0 = tcg_temp_new_i64();
7349
            TCGv_i64 fp1 = tcg_temp_new_i64();
7350
            TCGv_i64 fp2 = tcg_temp_new_i64();
7351

    
7352
            gen_load_fpr64(ctx, fp0, fs);
7353
            gen_load_fpr64(ctx, fp1, ft);
7354
            gen_load_fpr64(ctx, fp2, fr);
7355
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7356
            tcg_temp_free_i64(fp0);
7357
            tcg_temp_free_i64(fp1);
7358
            gen_store_fpr64(ctx, fp2, fd);
7359
            tcg_temp_free_i64(fp2);
7360
        }
7361
        opn = "madd.d";
7362
        break;
7363
    case OPC_MADD_PS:
7364
        check_cp1_64bitmode(ctx);
7365
        {
7366
            TCGv_i64 fp0 = tcg_temp_new_i64();
7367
            TCGv_i64 fp1 = tcg_temp_new_i64();
7368
            TCGv_i64 fp2 = tcg_temp_new_i64();
7369

    
7370
            gen_load_fpr64(ctx, fp0, fs);
7371
            gen_load_fpr64(ctx, fp1, ft);
7372
            gen_load_fpr64(ctx, fp2, fr);
7373
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7374
            tcg_temp_free_i64(fp0);
7375
            tcg_temp_free_i64(fp1);
7376
            gen_store_fpr64(ctx, fp2, fd);
7377
            tcg_temp_free_i64(fp2);
7378
        }
7379
        opn = "madd.ps";
7380
        break;
7381
    case OPC_MSUB_S:
7382
        check_cop1x(ctx);
7383
        {
7384
            TCGv_i32 fp0 = tcg_temp_new_i32();
7385
            TCGv_i32 fp1 = tcg_temp_new_i32();
7386
            TCGv_i32 fp2 = tcg_temp_new_i32();
7387

    
7388
            gen_load_fpr32(fp0, fs);
7389
            gen_load_fpr32(fp1, ft);
7390
            gen_load_fpr32(fp2, fr);
7391
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7392
            tcg_temp_free_i32(fp0);
7393
            tcg_temp_free_i32(fp1);
7394
            gen_store_fpr32(fp2, fd);
7395
            tcg_temp_free_i32(fp2);
7396
        }
7397
        opn = "msub.s";
7398
        break;
7399
    case OPC_MSUB_D:
7400
        check_cop1x(ctx);
7401
        check_cp1_registers(ctx, fd | fs | ft | fr);
7402
        {
7403
            TCGv_i64 fp0 = tcg_temp_new_i64();
7404
            TCGv_i64 fp1 = tcg_temp_new_i64();
7405
            TCGv_i64 fp2 = tcg_temp_new_i64();
7406

    
7407
            gen_load_fpr64(ctx, fp0, fs);
7408
            gen_load_fpr64(ctx, fp1, ft);
7409
            gen_load_fpr64(ctx, fp2, fr);
7410
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7411
            tcg_temp_free_i64(fp0);
7412
            tcg_temp_free_i64(fp1);
7413
            gen_store_fpr64(ctx, fp2, fd);
7414
            tcg_temp_free_i64(fp2);
7415
        }
7416
        opn = "msub.d";
7417
        break;
7418
    case OPC_MSUB_PS:
7419
        check_cp1_64bitmode(ctx);
7420
        {
7421
            TCGv_i64 fp0 = tcg_temp_new_i64();
7422
            TCGv_i64 fp1 = tcg_temp_new_i64();
7423
            TCGv_i64 fp2 = tcg_temp_new_i64();
7424

    
7425
            gen_load_fpr64(ctx, fp0, fs);
7426
            gen_load_fpr64(ctx, fp1, ft);
7427
            gen_load_fpr64(ctx, fp2, fr);
7428
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7429
            tcg_temp_free_i64(fp0);
7430
            tcg_temp_free_i64(fp1);
7431
            gen_store_fpr64(ctx, fp2, fd);
7432
            tcg_temp_free_i64(fp2);
7433
        }
7434
        opn = "msub.ps";
7435
        break;
7436
    case OPC_NMADD_S:
7437
        check_cop1x(ctx);
7438
        {
7439
            TCGv_i32 fp0 = tcg_temp_new_i32();
7440
            TCGv_i32 fp1 = tcg_temp_new_i32();
7441
            TCGv_i32 fp2 = tcg_temp_new_i32();
7442

    
7443
            gen_load_fpr32(fp0, fs);
7444
            gen_load_fpr32(fp1, ft);
7445
            gen_load_fpr32(fp2, fr);
7446
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7447
            tcg_temp_free_i32(fp0);
7448
            tcg_temp_free_i32(fp1);
7449
            gen_store_fpr32(fp2, fd);
7450
            tcg_temp_free_i32(fp2);
7451
        }
7452
        opn = "nmadd.s";
7453
        break;
7454
    case OPC_NMADD_D:
7455
        check_cop1x(ctx);
7456
        check_cp1_registers(ctx, fd | fs | ft | fr);
7457
        {
7458
            TCGv_i64 fp0 = tcg_temp_new_i64();
7459
            TCGv_i64 fp1 = tcg_temp_new_i64();
7460
            TCGv_i64 fp2 = tcg_temp_new_i64();
7461

    
7462
            gen_load_fpr64(ctx, fp0, fs);
7463
            gen_load_fpr64(ctx, fp1, ft);
7464
            gen_load_fpr64(ctx, fp2, fr);
7465
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7466
            tcg_temp_free_i64(fp0);
7467
            tcg_temp_free_i64(fp1);
7468
            gen_store_fpr64(ctx, fp2, fd);
7469
            tcg_temp_free_i64(fp2);
7470
        }
7471
        opn = "nmadd.d";
7472
        break;
7473
    case OPC_NMADD_PS:
7474
        check_cp1_64bitmode(ctx);
7475
        {
7476
            TCGv_i64 fp0 = tcg_temp_new_i64();
7477
            TCGv_i64 fp1 = tcg_temp_new_i64();
7478
            TCGv_i64 fp2 = tcg_temp_new_i64();
7479

    
7480
            gen_load_fpr64(ctx, fp0, fs);
7481
            gen_load_fpr64(ctx, fp1, ft);
7482
            gen_load_fpr64(ctx, fp2, fr);
7483
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7484
            tcg_temp_free_i64(fp0);
7485
            tcg_temp_free_i64(fp1);
7486
            gen_store_fpr64(ctx, fp2, fd);
7487
            tcg_temp_free_i64(fp2);
7488
        }
7489
        opn = "nmadd.ps";
7490
        break;
7491
    case OPC_NMSUB_S:
7492
        check_cop1x(ctx);
7493
        {
7494
            TCGv_i32 fp0 = tcg_temp_new_i32();
7495
            TCGv_i32 fp1 = tcg_temp_new_i32();
7496
            TCGv_i32 fp2 = tcg_temp_new_i32();
7497

    
7498
            gen_load_fpr32(fp0, fs);
7499
            gen_load_fpr32(fp1, ft);
7500
            gen_load_fpr32(fp2, fr);
7501
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7502
            tcg_temp_free_i32(fp0);
7503
            tcg_temp_free_i32(fp1);
7504
            gen_store_fpr32(fp2, fd);
7505
            tcg_temp_free_i32(fp2);
7506
        }
7507
        opn = "nmsub.s";
7508
        break;
7509
    case OPC_NMSUB_D:
7510
        check_cop1x(ctx);
7511
        check_cp1_registers(ctx, fd | fs | ft | fr);
7512
        {
7513
            TCGv_i64 fp0 = tcg_temp_new_i64();
7514
            TCGv_i64 fp1 = tcg_temp_new_i64();
7515
            TCGv_i64 fp2 = tcg_temp_new_i64();
7516

    
7517
            gen_load_fpr64(ctx, fp0, fs);
7518
            gen_load_fpr64(ctx, fp1, ft);
7519
            gen_load_fpr64(ctx, fp2, fr);
7520
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7521
            tcg_temp_free_i64(fp0);
7522
            tcg_temp_free_i64(fp1);
7523
            gen_store_fpr64(ctx, fp2, fd);
7524
            tcg_temp_free_i64(fp2);
7525
        }
7526
        opn = "nmsub.d";
7527
        break;
7528
    case OPC_NMSUB_PS:
7529
        check_cp1_64bitmode(ctx);
7530
        {
7531
            TCGv_i64 fp0 = tcg_temp_new_i64();
7532
            TCGv_i64 fp1 = tcg_temp_new_i64();
7533
            TCGv_i64 fp2 = tcg_temp_new_i64();
7534

    
7535
            gen_load_fpr64(ctx, fp0, fs);
7536
            gen_load_fpr64(ctx, fp1, ft);
7537
            gen_load_fpr64(ctx, fp2, fr);
7538
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7539
            tcg_temp_free_i64(fp0);
7540
            tcg_temp_free_i64(fp1);
7541
            gen_store_fpr64(ctx, fp2, fd);
7542
            tcg_temp_free_i64(fp2);
7543
        }
7544
        opn = "nmsub.ps";
7545
        break;
7546
    default:
7547
        MIPS_INVAL(opn);
7548
        generate_exception (ctx, EXCP_RI);
7549
        return;
7550
    }
7551
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7552
               fregnames[fs], fregnames[ft]);
7553
}
7554

    
7555
/* ISA extensions (ASEs) */
7556
/* MIPS16 extension to MIPS32 */
7557
/* SmartMIPS extension to MIPS32 */
7558

    
7559
#if defined(TARGET_MIPS64)
7560

    
7561
/* MDMX extension to MIPS64 */
7562

    
7563
#endif
7564

    
7565
static void decode_opc (CPUState *env, DisasContext *ctx)
7566
{
7567
    int32_t offset;
7568
    int rs, rt, rd, sa;
7569
    uint32_t op, op1, op2;
7570
    int16_t imm;
7571

    
7572
    /* make sure instructions are on a word boundary */
7573
    if (ctx->pc & 0x3) {
7574
        env->CP0_BadVAddr = ctx->pc;
7575
        generate_exception(ctx, EXCP_AdEL);
7576
        return;
7577
    }
7578

    
7579
    /* Handle blikely not taken case */
7580
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7581
        int l1 = gen_new_label();
7582

    
7583
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7584
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7585
        {
7586
            TCGv_i32 r_tmp = tcg_temp_new_i32();
7587

    
7588
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7589
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7590
            tcg_temp_free_i32(r_tmp);
7591
        }
7592
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7593
        gen_set_label(l1);
7594
    }
7595
    op = MASK_OP_MAJOR(ctx->opcode);
7596
    rs = (ctx->opcode >> 21) & 0x1f;
7597
    rt = (ctx->opcode >> 16) & 0x1f;
7598
    rd = (ctx->opcode >> 11) & 0x1f;
7599
    sa = (ctx->opcode >> 6) & 0x1f;
7600
    imm = (int16_t)ctx->opcode;
7601
    switch (op) {
7602
    case OPC_SPECIAL:
7603
        op1 = MASK_SPECIAL(ctx->opcode);
7604
        switch (op1) {
7605
        case OPC_SLL:          /* Arithmetic with immediate */
7606
        case OPC_SRL ... OPC_SRA:
7607
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7608
            break;
7609
        case OPC_MOVZ ... OPC_MOVN:
7610
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7611
        case OPC_SLLV:         /* Arithmetic */
7612
        case OPC_SRLV ... OPC_SRAV:
7613
        case OPC_ADD ... OPC_NOR:
7614
        case OPC_SLT ... OPC_SLTU:
7615
            gen_arith(env, ctx, op1, rd, rs, rt);
7616
            break;
7617
        case OPC_MULT ... OPC_DIVU:
7618
            if (sa) {
7619
                check_insn(env, ctx, INSN_VR54XX);
7620
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7621
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7622
            } else
7623
                gen_muldiv(ctx, op1, rs, rt);
7624
            break;
7625
        case OPC_JR ... OPC_JALR:
7626
            gen_compute_branch(ctx, op1, rs, rd, sa);
7627
            return;
7628
        case OPC_TGE ... OPC_TEQ: /* Traps */
7629
        case OPC_TNE:
7630
            gen_trap(ctx, op1, rs, rt, -1);
7631
            break;
7632
        case OPC_MFHI:          /* Move from HI/LO */
7633
        case OPC_MFLO:
7634
            gen_HILO(ctx, op1, rd);
7635
            break;
7636
        case OPC_MTHI:
7637
        case OPC_MTLO:          /* Move to HI/LO */
7638
            gen_HILO(ctx, op1, rs);
7639
            break;
7640
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7641
#ifdef MIPS_STRICT_STANDARD
7642
            MIPS_INVAL("PMON / selsl");
7643
            generate_exception(ctx, EXCP_RI);
7644
#else
7645
            gen_helper_0i(pmon, sa);
7646
#endif
7647
            break;
7648
        case OPC_SYSCALL:
7649
            generate_exception(ctx, EXCP_SYSCALL);
7650
            break;
7651
        case OPC_BREAK:
7652
            generate_exception(ctx, EXCP_BREAK);
7653
            break;
7654
        case OPC_SPIM:
7655
#ifdef MIPS_STRICT_STANDARD
7656
            MIPS_INVAL("SPIM");
7657
            generate_exception(ctx, EXCP_RI);
7658
#else
7659
           /* Implemented as RI exception for now. */
7660
            MIPS_INVAL("spim (unofficial)");
7661
            generate_exception(ctx, EXCP_RI);
7662
#endif
7663
            break;
7664
        case OPC_SYNC:
7665
            /* Treat as NOP. */
7666
            break;
7667

    
7668
        case OPC_MOVCI:
7669
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7670
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7671
                save_cpu_state(ctx, 1);
7672
                check_cp1_enabled(ctx);
7673
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7674
                          (ctx->opcode >> 16) & 1);
7675
            } else {
7676
                generate_exception_err(ctx, EXCP_CpU, 1);
7677
            }
7678
            break;
7679

    
7680
#if defined(TARGET_MIPS64)
7681
       /* MIPS64 specific opcodes */
7682
        case OPC_DSLL:
7683
        case OPC_DSRL ... OPC_DSRA:
7684
        case OPC_DSLL32:
7685
        case OPC_DSRL32 ... OPC_DSRA32:
7686
            check_insn(env, ctx, ISA_MIPS3);
7687
            check_mips_64(ctx);
7688
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7689
            break;
7690
        case OPC_DSLLV:
7691
        case OPC_DSRLV ... OPC_DSRAV:
7692
        case OPC_DADD ... OPC_DSUBU:
7693
            check_insn(env, ctx, ISA_MIPS3);
7694
            check_mips_64(ctx);
7695
            gen_arith(env, ctx, op1, rd, rs, rt);
7696
            break;
7697
        case OPC_DMULT ... OPC_DDIVU:
7698
            check_insn(env, ctx, ISA_MIPS3);
7699
            check_mips_64(ctx);
7700
            gen_muldiv(ctx, op1, rs, rt);
7701
            break;
7702
#endif
7703
        default:            /* Invalid */
7704
            MIPS_INVAL("special");
7705
            generate_exception(ctx, EXCP_RI);
7706
            break;
7707
        }
7708
        break;
7709
    case OPC_SPECIAL2:
7710
        op1 = MASK_SPECIAL2(ctx->opcode);
7711
        switch (op1) {
7712
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7713
        case OPC_MSUB ... OPC_MSUBU:
7714
            check_insn(env, ctx, ISA_MIPS32);
7715
            gen_muldiv(ctx, op1, rs, rt);
7716
            break;
7717
        case OPC_MUL:
7718
            gen_arith(env, ctx, op1, rd, rs, rt);
7719
            break;
7720
        case OPC_CLZ ... OPC_CLO:
7721
            check_insn(env, ctx, ISA_MIPS32);
7722
            gen_cl(ctx, op1, rd, rs);
7723
            break;
7724
        case OPC_SDBBP:
7725
            /* XXX: not clear which exception should be raised
7726
             *      when in debug mode...
7727
             */
7728
            check_insn(env, ctx, ISA_MIPS32);
7729
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7730
                generate_exception(ctx, EXCP_DBp);
7731
            } else {
7732
                generate_exception(ctx, EXCP_DBp);
7733
            }
7734
            /* Treat as NOP. */
7735
            break;
7736
#if defined(TARGET_MIPS64)
7737
        case OPC_DCLZ ... OPC_DCLO:
7738
            check_insn(env, ctx, ISA_MIPS64);
7739
            check_mips_64(ctx);
7740
            gen_cl(ctx, op1, rd, rs);
7741
            break;
7742
#endif
7743
        default:            /* Invalid */
7744
            MIPS_INVAL("special2");
7745
            generate_exception(ctx, EXCP_RI);
7746
            break;
7747
        }
7748
        break;
7749
    case OPC_SPECIAL3:
7750
        op1 = MASK_SPECIAL3(ctx->opcode);
7751
        switch (op1) {
7752
        case OPC_EXT:
7753
        case OPC_INS:
7754
            check_insn(env, ctx, ISA_MIPS32R2);
7755
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7756
            break;
7757
        case OPC_BSHFL:
7758
            check_insn(env, ctx, ISA_MIPS32R2);
7759
            op2 = MASK_BSHFL(ctx->opcode);
7760
            gen_bshfl(ctx, op2, rt, rd);
7761
            break;
7762
        case OPC_RDHWR:
7763
            check_insn(env, ctx, ISA_MIPS32R2);
7764
            {
7765
                TCGv t0 = tcg_temp_local_new();
7766

    
7767
                switch (rd) {
7768
                case 0:
7769
                    save_cpu_state(ctx, 1);
7770
                    gen_helper_rdhwr_cpunum(t0);
7771
                    break;
7772
                case 1:
7773
                    save_cpu_state(ctx, 1);
7774
                    gen_helper_rdhwr_synci_step(t0);
7775
                    break;
7776
                case 2:
7777
                    save_cpu_state(ctx, 1);
7778
                    gen_helper_rdhwr_cc(t0);
7779
                    break;
7780
                case 3:
7781
                    save_cpu_state(ctx, 1);
7782
                    gen_helper_rdhwr_ccres(t0);
7783
                    break;
7784
                case 29:
7785
#if defined(CONFIG_USER_ONLY)
7786
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7787
                    break;
7788
#else
7789
                    /* XXX: Some CPUs implement this in hardware.
7790
                       Not supported yet. */
7791
#endif
7792
                default:            /* Invalid */
7793
                    MIPS_INVAL("rdhwr");
7794
                    generate_exception(ctx, EXCP_RI);
7795
                    break;
7796
                }
7797
                gen_store_gpr(t0, rt);
7798
                tcg_temp_free(t0);
7799
            }
7800
            break;
7801
        case OPC_FORK:
7802
            check_insn(env, ctx, ASE_MT);
7803
            {
7804
                TCGv t0 = tcg_temp_local_new();
7805
                TCGv t1 = tcg_temp_local_new();
7806

    
7807
                gen_load_gpr(t0, rt);
7808
                gen_load_gpr(t1, rs);
7809
                gen_helper_fork(t0, t1);
7810
                tcg_temp_free(t0);
7811
                tcg_temp_free(t1);
7812
            }
7813
            break;
7814
        case OPC_YIELD:
7815
            check_insn(env, ctx, ASE_MT);
7816
            {
7817
                TCGv t0 = tcg_temp_local_new();
7818

    
7819
                gen_load_gpr(t0, rs);
7820
                gen_helper_yield(t0, t0);
7821
                gen_store_gpr(t0, rd);
7822
                tcg_temp_free(t0);
7823
            }
7824
            break;
7825
#if defined(TARGET_MIPS64)
7826
        case OPC_DEXTM ... OPC_DEXT:
7827
        case OPC_DINSM ... OPC_DINS:
7828
            check_insn(env, ctx, ISA_MIPS64R2);
7829
            check_mips_64(ctx);
7830
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7831
            break;
7832
        case OPC_DBSHFL:
7833
            check_insn(env, ctx, ISA_MIPS64R2);
7834
            check_mips_64(ctx);
7835
            op2 = MASK_DBSHFL(ctx->opcode);
7836
            gen_bshfl(ctx, op2, rt, rd);
7837
            break;
7838
#endif
7839
        default:            /* Invalid */
7840
            MIPS_INVAL("special3");
7841
            generate_exception(ctx, EXCP_RI);
7842
            break;
7843
        }
7844
        break;
7845
    case OPC_REGIMM:
7846
        op1 = MASK_REGIMM(ctx->opcode);
7847
        switch (op1) {
7848
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7849
        case OPC_BLTZAL ... OPC_BGEZALL:
7850
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7851
            return;
7852
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7853
        case OPC_TNEI:
7854
            gen_trap(ctx, op1, rs, -1, imm);
7855
            break;
7856
        case OPC_SYNCI:
7857
            check_insn(env, ctx, ISA_MIPS32R2);
7858
            /* Treat as NOP. */
7859
            break;
7860
        default:            /* Invalid */
7861
            MIPS_INVAL("regimm");
7862
            generate_exception(ctx, EXCP_RI);
7863
            break;
7864
        }
7865
        break;
7866
    case OPC_CP0:
7867
        check_cp0_enabled(ctx);
7868
        op1 = MASK_CP0(ctx->opcode);
7869
        switch (op1) {
7870
        case OPC_MFC0:
7871
        case OPC_MTC0:
7872
        case OPC_MFTR:
7873
        case OPC_MTTR:
7874
#if defined(TARGET_MIPS64)
7875
        case OPC_DMFC0:
7876
        case OPC_DMTC0:
7877
#endif
7878
#ifndef CONFIG_USER_ONLY
7879
            gen_cp0(env, ctx, op1, rt, rd);
7880
#endif /* !CONFIG_USER_ONLY */
7881
            break;
7882
        case OPC_C0_FIRST ... OPC_C0_LAST:
7883
#ifndef CONFIG_USER_ONLY
7884
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7885
#endif /* !CONFIG_USER_ONLY */
7886
            break;
7887
        case OPC_MFMC0:
7888
#ifndef CONFIG_USER_ONLY
7889
            {
7890
                TCGv t0 = tcg_temp_local_new();
7891

    
7892
                op2 = MASK_MFMC0(ctx->opcode);
7893
                switch (op2) {
7894
                case OPC_DMT:
7895
                    check_insn(env, ctx, ASE_MT);
7896
                    gen_helper_dmt(t0, t0);
7897
                    break;
7898
                case OPC_EMT:
7899
                    check_insn(env, ctx, ASE_MT);
7900
                    gen_helper_emt(t0, t0);
7901
                    break;
7902
                case OPC_DVPE:
7903
                    check_insn(env, ctx, ASE_MT);
7904
                    gen_helper_dvpe(t0, t0);
7905
                    break;
7906
                case OPC_EVPE:
7907
                    check_insn(env, ctx, ASE_MT);
7908
                    gen_helper_evpe(t0, t0);
7909
                    break;
7910
                case OPC_DI:
7911
                    check_insn(env, ctx, ISA_MIPS32R2);
7912
                    save_cpu_state(ctx, 1);
7913
                    gen_helper_di(t0);
7914
                    /* Stop translation as we may have switched the execution mode */
7915
                    ctx->bstate = BS_STOP;
7916
                    break;
7917
                case OPC_EI:
7918
                    check_insn(env, ctx, ISA_MIPS32R2);
7919
                    save_cpu_state(ctx, 1);
7920
                    gen_helper_ei(t0);
7921
                    /* Stop translation as we may have switched the execution mode */
7922
                    ctx->bstate = BS_STOP;
7923
                    break;
7924
                default:            /* Invalid */
7925
                    MIPS_INVAL("mfmc0");
7926
                    generate_exception(ctx, EXCP_RI);
7927
                    break;
7928
                }
7929
                gen_store_gpr(t0, rt);
7930
                tcg_temp_free(t0);
7931
            }
7932
#endif /* !CONFIG_USER_ONLY */
7933
            break;
7934
        case OPC_RDPGPR:
7935
            check_insn(env, ctx, ISA_MIPS32R2);
7936
            gen_load_srsgpr(rt, rd);
7937
            break;
7938
        case OPC_WRPGPR:
7939
            check_insn(env, ctx, ISA_MIPS32R2);
7940
            gen_store_srsgpr(rt, rd);
7941
            break;
7942
        default:
7943
            MIPS_INVAL("cp0");
7944
            generate_exception(ctx, EXCP_RI);
7945
            break;
7946
        }
7947
        break;
7948
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7949
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7950
         break;
7951
    case OPC_J ... OPC_JAL: /* Jump */
7952
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7953
         gen_compute_branch(ctx, op, rs, rt, offset);
7954
         return;
7955
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7956
    case OPC_BEQL ... OPC_BGTZL:
7957
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7958
         return;
7959
    case OPC_LB ... OPC_LWR: /* Load and stores */
7960
    case OPC_SB ... OPC_SW:
7961
    case OPC_SWR:
7962
    case OPC_LL:
7963
    case OPC_SC:
7964
         gen_ldst(ctx, op, rt, rs, imm);
7965
         break;
7966
    case OPC_CACHE:
7967
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7968
        /* Treat as NOP. */
7969
        break;
7970
    case OPC_PREF:
7971
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7972
        /* Treat as NOP. */
7973
        break;
7974

    
7975
    /* Floating point (COP1). */
7976
    case OPC_LWC1:
7977
    case OPC_LDC1:
7978
    case OPC_SWC1:
7979
    case OPC_SDC1:
7980
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7981
            save_cpu_state(ctx, 1);
7982
            check_cp1_enabled(ctx);
7983
            gen_flt_ldst(ctx, op, rt, rs, imm);
7984
        } else {
7985
            generate_exception_err(ctx, EXCP_CpU, 1);
7986
        }
7987
        break;
7988

    
7989
    case OPC_CP1:
7990
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7991
            save_cpu_state(ctx, 1);
7992
            check_cp1_enabled(ctx);
7993
            op1 = MASK_CP1(ctx->opcode);
7994
            switch (op1) {
7995
            case OPC_MFHC1:
7996
            case OPC_MTHC1:
7997
                check_insn(env, ctx, ISA_MIPS32R2);
7998
            case OPC_MFC1:
7999
            case OPC_CFC1:
8000
            case OPC_MTC1:
8001
            case OPC_CTC1:
8002
                gen_cp1(ctx, op1, rt, rd);
8003
                break;
8004
#if defined(TARGET_MIPS64)
8005
            case OPC_DMFC1:
8006
            case OPC_DMTC1:
8007
                check_insn(env, ctx, ISA_MIPS3);
8008
                gen_cp1(ctx, op1, rt, rd);
8009
                break;
8010
#endif
8011
            case OPC_BC1ANY2:
8012
            case OPC_BC1ANY4:
8013
                check_cop1x(ctx);
8014
                check_insn(env, ctx, ASE_MIPS3D);
8015
                /* fall through */
8016
            case OPC_BC1:
8017
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8018
                                    (rt >> 2) & 0x7, imm << 2);
8019
                return;
8020
            case OPC_S_FMT:
8021
            case OPC_D_FMT:
8022
            case OPC_W_FMT:
8023
            case OPC_L_FMT:
8024
            case OPC_PS_FMT:
8025
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8026
                           (imm >> 8) & 0x7);
8027
                break;
8028
            default:
8029
                MIPS_INVAL("cp1");
8030
                generate_exception (ctx, EXCP_RI);
8031
                break;
8032
            }
8033
        } else {
8034
            generate_exception_err(ctx, EXCP_CpU, 1);
8035
        }
8036
        break;
8037

    
8038
    /* COP2.  */
8039
    case OPC_LWC2:
8040
    case OPC_LDC2:
8041
    case OPC_SWC2:
8042
    case OPC_SDC2:
8043
    case OPC_CP2:
8044
        /* COP2: Not implemented. */
8045
        generate_exception_err(ctx, EXCP_CpU, 2);
8046
        break;
8047

    
8048
    case OPC_CP3:
8049
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8050
            save_cpu_state(ctx, 1);
8051
            check_cp1_enabled(ctx);
8052
            op1 = MASK_CP3(ctx->opcode);
8053
            switch (op1) {
8054
            case OPC_LWXC1:
8055
            case OPC_LDXC1:
8056
            case OPC_LUXC1:
8057
            case OPC_SWXC1:
8058
            case OPC_SDXC1:
8059
            case OPC_SUXC1:
8060
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8061
                break;
8062
            case OPC_PREFX:
8063
                /* Treat as NOP. */
8064
                break;
8065
            case OPC_ALNV_PS:
8066
            case OPC_MADD_S:
8067
            case OPC_MADD_D:
8068
            case OPC_MADD_PS:
8069
            case OPC_MSUB_S:
8070
            case OPC_MSUB_D:
8071
            case OPC_MSUB_PS:
8072
            case OPC_NMADD_S:
8073
            case OPC_NMADD_D:
8074
            case OPC_NMADD_PS:
8075
            case OPC_NMSUB_S:
8076
            case OPC_NMSUB_D:
8077
            case OPC_NMSUB_PS:
8078
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8079
                break;
8080
            default:
8081
                MIPS_INVAL("cp3");
8082
                generate_exception (ctx, EXCP_RI);
8083
                break;
8084
            }
8085
        } else {
8086
            generate_exception_err(ctx, EXCP_CpU, 1);
8087
        }
8088
        break;
8089

    
8090
#if defined(TARGET_MIPS64)
8091
    /* MIPS64 opcodes */
8092
    case OPC_LWU:
8093
    case OPC_LDL ... OPC_LDR:
8094
    case OPC_SDL ... OPC_SDR:
8095
    case OPC_LLD:
8096
    case OPC_LD:
8097
    case OPC_SCD:
8098
    case OPC_SD:
8099
        check_insn(env, ctx, ISA_MIPS3);
8100
        check_mips_64(ctx);
8101
        gen_ldst(ctx, op, rt, rs, imm);
8102
        break;
8103
    case OPC_DADDI ... OPC_DADDIU:
8104
        check_insn(env, ctx, ISA_MIPS3);
8105
        check_mips_64(ctx);
8106
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8107
        break;
8108
#endif
8109
    case OPC_JALX:
8110
        check_insn(env, ctx, ASE_MIPS16);
8111
        /* MIPS16: Not implemented. */
8112
    case OPC_MDMX:
8113
        check_insn(env, ctx, ASE_MDMX);
8114
        /* MDMX: Not implemented. */
8115
    default:            /* Invalid */
8116
        MIPS_INVAL("major opcode");
8117
        generate_exception(ctx, EXCP_RI);
8118
        break;
8119
    }
8120
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8121
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8122
        /* Branches completion */
8123
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8124
        ctx->bstate = BS_BRANCH;
8125
        save_cpu_state(ctx, 0);
8126
        /* FIXME: Need to clear can_do_io.  */
8127
        switch (hflags) {
8128
        case MIPS_HFLAG_B:
8129
            /* unconditional branch */
8130
            MIPS_DEBUG("unconditional branch");
8131
            gen_goto_tb(ctx, 0, ctx->btarget);
8132
            break;
8133
        case MIPS_HFLAG_BL:
8134
            /* blikely taken case */
8135
            MIPS_DEBUG("blikely branch taken");
8136
            gen_goto_tb(ctx, 0, ctx->btarget);
8137
            break;
8138
        case MIPS_HFLAG_BC:
8139
            /* Conditional branch */
8140
            MIPS_DEBUG("conditional branch");
8141
            {
8142
                int l1 = gen_new_label();
8143

    
8144
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8145
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8146
                gen_set_label(l1);
8147
                gen_goto_tb(ctx, 0, ctx->btarget);
8148
            }
8149
            break;
8150
        case MIPS_HFLAG_BR:
8151
            /* unconditional branch to register */
8152
            MIPS_DEBUG("branch to register");
8153
            tcg_gen_mov_tl(cpu_PC, btarget);
8154
            tcg_gen_exit_tb(0);
8155
            break;
8156
        default:
8157
            MIPS_DEBUG("unknown branch");
8158
            break;
8159
        }
8160
    }
8161
}
8162

    
8163
static inline void
8164
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8165
                                int search_pc)
8166
{
8167
    DisasContext ctx;
8168
    target_ulong pc_start;
8169
    uint16_t *gen_opc_end;
8170
    CPUBreakpoint *bp;
8171
    int j, lj = -1;
8172
    int num_insns;
8173
    int max_insns;
8174

    
8175
    if (search_pc)
8176
        qemu_log("search pc %d\n", search_pc);
8177

    
8178
    pc_start = tb->pc;
8179
    /* Leave some spare opc slots for branch handling. */
8180
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8181
    ctx.pc = pc_start;
8182
    ctx.saved_pc = -1;
8183
    ctx.tb = tb;
8184
    ctx.bstate = BS_NONE;
8185
    /* Restore delay slot state from the tb context.  */
8186
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8187
    restore_cpu_state(env, &ctx);
8188
#ifdef CONFIG_USER_ONLY
8189
        ctx.mem_idx = MIPS_HFLAG_UM;
8190
#else
8191
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8192
#endif
8193
    num_insns = 0;
8194
    max_insns = tb->cflags & CF_COUNT_MASK;
8195
    if (max_insns == 0)
8196
        max_insns = CF_COUNT_MASK;
8197
#ifdef DEBUG_DISAS
8198
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8199
    /* FIXME: This may print out stale hflags from env... */
8200
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8201
#endif
8202
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8203
    gen_icount_start();
8204
    while (ctx.bstate == BS_NONE) {
8205
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8206
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8207
                if (bp->pc == ctx.pc) {
8208
                    save_cpu_state(&ctx, 1);
8209
                    ctx.bstate = BS_BRANCH;
8210
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8211
                    /* Include the breakpoint location or the tb won't
8212
                     * be flushed when it must be.  */
8213
                    ctx.pc += 4;
8214
                    goto done_generating;
8215
                }
8216
            }
8217
        }
8218

    
8219
        if (search_pc) {
8220
            j = gen_opc_ptr - gen_opc_buf;
8221
            if (lj < j) {
8222
                lj++;
8223
                while (lj < j)
8224
                    gen_opc_instr_start[lj++] = 0;
8225
            }
8226
            gen_opc_pc[lj] = ctx.pc;
8227
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8228
            gen_opc_instr_start[lj] = 1;
8229
            gen_opc_icount[lj] = num_insns;
8230
        }
8231
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8232
            gen_io_start();
8233
        ctx.opcode = ldl_code(ctx.pc);
8234
        decode_opc(env, &ctx);
8235
        ctx.pc += 4;
8236
        num_insns++;
8237

    
8238
        if (env->singlestep_enabled)
8239
            break;
8240

    
8241
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8242
            break;
8243

    
8244
        if (gen_opc_ptr >= gen_opc_end)
8245
            break;
8246

    
8247
        if (num_insns >= max_insns)
8248
            break;
8249
#if defined (MIPS_SINGLE_STEP)
8250
        break;
8251
#endif
8252
    }
8253
    if (tb->cflags & CF_LAST_IO)
8254
        gen_io_end();
8255
    if (env->singlestep_enabled) {
8256
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8257
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8258
    } else {
8259
        switch (ctx.bstate) {
8260
        case BS_STOP:
8261
            gen_helper_interrupt_restart();
8262
            gen_goto_tb(&ctx, 0, ctx.pc);
8263
            break;
8264
        case BS_NONE:
8265
            save_cpu_state(&ctx, 0);
8266
            gen_goto_tb(&ctx, 0, ctx.pc);
8267
            break;
8268
        case BS_EXCP:
8269
            gen_helper_interrupt_restart();
8270
            tcg_gen_exit_tb(0);
8271
            break;
8272
        case BS_BRANCH:
8273
        default:
8274
            break;
8275
        }
8276
    }
8277
done_generating:
8278
    gen_icount_end(tb, num_insns);
8279
    *gen_opc_ptr = INDEX_op_end;
8280
    if (search_pc) {
8281
        j = gen_opc_ptr - gen_opc_buf;
8282
        lj++;
8283
        while (lj <= j)
8284
            gen_opc_instr_start[lj++] = 0;
8285
    } else {
8286
        tb->size = ctx.pc - pc_start;
8287
        tb->icount = num_insns;
8288
    }
8289
#ifdef DEBUG_DISAS
8290
    LOG_DISAS("\n");
8291
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8292
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8293
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8294
        qemu_log("\n");
8295
    }
8296
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8297
#endif
8298
}
8299

    
8300
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8301
{
8302
    gen_intermediate_code_internal(env, tb, 0);
8303
}
8304

    
8305
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8306
{
8307
    gen_intermediate_code_internal(env, tb, 1);
8308
}
8309

    
8310
static void fpu_dump_state(CPUState *env, FILE *f,
8311
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8312
                           int flags)
8313
{
8314
    int i;
8315
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8316

    
8317
#define printfpr(fp)                                                        \
8318
    do {                                                                    \
8319
        if (is_fpu64)                                                       \
8320
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8321
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8322
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8323
        else {                                                              \
8324
            fpr_t tmp;                                                      \
8325
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8326
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8327
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8328
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8329
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8330
        }                                                                   \
8331
    } while(0)
8332

    
8333

    
8334
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8335
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8336
                get_float_exception_flags(&env->active_fpu.fp_status));
8337
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8338
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8339
        printfpr(&env->active_fpu.fpr[i]);
8340
    }
8341

    
8342
#undef printfpr
8343
}
8344

    
8345
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8346
/* Debug help: The architecture requires 32bit code to maintain proper
8347
   sign-extended values on 64bit machines.  */
8348

    
8349
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8350

    
8351
static void
8352
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8353
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8354
                                int flags)
8355
{
8356
    int i;
8357

    
8358
    if (!SIGN_EXT_P(env->active_tc.PC))
8359
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8360
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8361
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8362
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8363
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8364
    if (!SIGN_EXT_P(env->btarget))
8365
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8366

    
8367
    for (i = 0; i < 32; i++) {
8368
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8369
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8370
    }
8371

    
8372
    if (!SIGN_EXT_P(env->CP0_EPC))
8373
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8374
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8375
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8376
}
8377
#endif
8378

    
8379
void cpu_dump_state (CPUState *env, FILE *f,
8380
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8381
                     int flags)
8382
{
8383
    int i;
8384

    
8385
    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",
8386
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8387
                env->hflags, env->btarget, env->bcond);
8388
    for (i = 0; i < 32; i++) {
8389
        if ((i & 3) == 0)
8390
            cpu_fprintf(f, "GPR%02d:", i);
8391
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8392
        if ((i & 3) == 3)
8393
            cpu_fprintf(f, "\n");
8394
    }
8395

    
8396
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8397
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8398
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8399
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8400
    if (env->hflags & MIPS_HFLAG_FPU)
8401
        fpu_dump_state(env, f, cpu_fprintf, flags);
8402
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8403
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8404
#endif
8405
}
8406

    
8407
static void mips_tcg_init(void)
8408
{
8409
    int i;
8410
    static int inited;
8411

    
8412
    /* Initialize various static tables. */
8413
    if (inited)
8414
        return;
8415

    
8416
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8417
    for (i = 0; i < 32; i++)
8418
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8419
                                        offsetof(CPUState, active_tc.gpr[i]),
8420
                                        regnames[i]);
8421
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8422
                                offsetof(CPUState, active_tc.PC), "PC");
8423
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8424
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8425
                                       offsetof(CPUState, active_tc.HI[i]),
8426
                                       regnames_HI[i]);
8427
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8428
                                       offsetof(CPUState, active_tc.LO[i]),
8429
                                       regnames_LO[i]);
8430
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8431
                                        offsetof(CPUState, active_tc.ACX[i]),
8432
                                        regnames_ACX[i]);
8433
    }
8434
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8435
                                     offsetof(CPUState, active_tc.DSPControl),
8436
                                     "DSPControl");
8437
    bcond = tcg_global_mem_new_i32(TCG_AREG0,
8438
                                   offsetof(CPUState, bcond), "bcond");
8439
    btarget = tcg_global_mem_new(TCG_AREG0,
8440
                                 offsetof(CPUState, btarget), "btarget");
8441
    for (i = 0; i < 32; i++)
8442
        fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8443
            offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8444
            fregnames[i]);
8445
    for (i = 0; i < 32; i++)
8446
        fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
8447
            offsetof(CPUState, active_fpu.fpr[i]),
8448
            fregnames_64[i]);
8449
    for (i = 0; i < 32; i++)
8450
        fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8451
            offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8452
            fregnames_h[i]);
8453
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8454
                                      offsetof(CPUState, active_fpu.fcr0),
8455
                                      "fcr0");
8456
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8457
                                       offsetof(CPUState, active_fpu.fcr31),
8458
                                       "fcr31");
8459

    
8460
    /* register helpers */
8461
#define GEN_HELPER 2
8462
#include "helper.h"
8463

    
8464
    inited = 1;
8465
}
8466

    
8467
#include "translate_init.c"
8468

    
8469
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8470
{
8471
    CPUMIPSState *env;
8472
    const mips_def_t *def;
8473

    
8474
    def = cpu_mips_find_by_name(cpu_model);
8475
    if (!def)
8476
        return NULL;
8477
    env = qemu_mallocz(sizeof(CPUMIPSState));
8478
    env->cpu_model = def;
8479

    
8480
    cpu_exec_init(env);
8481
    env->cpu_model_str = cpu_model;
8482
    mips_tcg_init();
8483
    cpu_reset(env);
8484
    return env;
8485
}
8486

    
8487
void cpu_reset (CPUMIPSState *env)
8488
{
8489
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8490
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8491
        log_cpu_state(env, 0);
8492
    }
8493

    
8494
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8495

    
8496
    tlb_flush(env, 1);
8497

    
8498
    /* Minimal init */
8499
#if defined(CONFIG_USER_ONLY)
8500
    env->hflags = MIPS_HFLAG_UM;
8501
#else
8502
    if (env->hflags & MIPS_HFLAG_BMASK) {
8503
        /* If the exception was raised from a delay slot,
8504
           come back to the jump.  */
8505
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8506
    } else {
8507
        env->CP0_ErrorEPC = env->active_tc.PC;
8508
    }
8509
    env->active_tc.PC = (int32_t)0xBFC00000;
8510
    env->CP0_Wired = 0;
8511
    /* SMP not implemented */
8512
    env->CP0_EBase = 0x80000000;
8513
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8514
    /* vectored interrupts not implemented, timer on int 7,
8515
       no performance counters. */
8516
    env->CP0_IntCtl = 0xe0000000;
8517
    {
8518
        int i;
8519

    
8520
        for (i = 0; i < 7; i++) {
8521
            env->CP0_WatchLo[i] = 0;
8522
            env->CP0_WatchHi[i] = 0x80000000;
8523
        }
8524
        env->CP0_WatchLo[7] = 0;
8525
        env->CP0_WatchHi[7] = 0;
8526
    }
8527
    /* Count register increments in debug mode, EJTAG version 1 */
8528
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8529
    env->hflags = MIPS_HFLAG_CP0;
8530
#endif
8531
    env->exception_index = EXCP_NONE;
8532
    cpu_mips_register(env, env->cpu_model);
8533
}
8534

    
8535
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8536
                unsigned long searched_pc, int pc_pos, void *puc)
8537
{
8538
    env->active_tc.PC = gen_opc_pc[pc_pos];
8539
    env->hflags &= ~MIPS_HFLAG_BMASK;
8540
    env->hflags |= gen_opc_hflags[pc_pos];
8541
}