Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c227f099

History | View | Annotate | Download (251.4 kB)

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

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

    
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31
#include "tcg-op.h"
32
#include "qemu-common.h"
33

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

    
38
//#define MIPS_DEBUG_DISAS
39
//#define MIPS_DEBUG_SIGN_EXTENSIONS
40

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

    
44
enum {
45
    /* indirect opcode tables */
46
    OPC_SPECIAL  = (0x00 << 26),
47
    OPC_REGIMM   = (0x01 << 26),
48
    OPC_CP0      = (0x10 << 26),
49
    OPC_CP1      = (0x11 << 26),
50
    OPC_CP2      = (0x12 << 26),
51
    OPC_CP3      = (0x13 << 26),
52
    OPC_SPECIAL2 = (0x1C << 26),
53
    OPC_SPECIAL3 = (0x1F << 26),
54
    /* arithmetic with immediate */
55
    OPC_ADDI     = (0x08 << 26),
56
    OPC_ADDIU    = (0x09 << 26),
57
    OPC_SLTI     = (0x0A << 26),
58
    OPC_SLTIU    = (0x0B << 26),
59
    /* logic with immediate */
60
    OPC_ANDI     = (0x0C << 26),
61
    OPC_ORI      = (0x0D << 26),
62
    OPC_XORI     = (0x0E << 26),
63
    OPC_LUI      = (0x0F << 26),
64
    /* arithmetic with immediate */
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, /* unofficial */
191
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
192
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
193
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
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, bcond;
433
static TCGv_i32 hflags;
434
static TCGv_i32 fpu_fcr0, fpu_fcr31;
435

    
436
#include "gen-icount.h"
437

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

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

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

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

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

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

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

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

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

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

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

    
503
#ifdef MIPS_DEBUG_DISAS
504
#define MIPS_DEBUG(fmt, ...)                         \
505
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
506
                       TARGET_FMT_lx ": %08x " fmt "\n", \
507
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
508
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
509
#else
510
#define MIPS_DEBUG(fmt, ...) do { } while(0)
511
#define LOG_DISAS(...) do { } while (0)
512
#endif
513

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

    
520
/* General purpose registers moves. */
521
static inline void gen_load_gpr (TCGv t, int reg)
522
{
523
    if (reg == 0)
524
        tcg_gen_movi_tl(t, 0);
525
    else
526
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
527
}
528

    
529
static inline void gen_store_gpr (TCGv t, int reg)
530
{
531
    if (reg != 0)
532
        tcg_gen_mov_tl(cpu_gpr[reg], t);
533
}
534

    
535
/* Moves to/from ACX register.  */
536
static inline void gen_load_ACX (TCGv t, int reg)
537
{
538
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
539
}
540

    
541
static inline void gen_store_ACX (TCGv t, int reg)
542
{
543
    tcg_gen_mov_tl(cpu_ACX[reg], t);
544
}
545

    
546
/* Moves to/from shadow registers. */
547
static inline void gen_load_srsgpr (int from, int to)
548
{
549
    TCGv t0 = tcg_temp_new();
550

    
551
    if (from == 0)
552
        tcg_gen_movi_tl(t0, 0);
553
    else {
554
        TCGv_i32 t2 = tcg_temp_new_i32();
555
        TCGv_ptr addr = tcg_temp_new_ptr();
556

    
557
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
558
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
559
        tcg_gen_andi_i32(t2, t2, 0xf);
560
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
561
        tcg_gen_ext_i32_ptr(addr, t2);
562
        tcg_gen_add_ptr(addr, cpu_env, addr);
563

    
564
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
565
        tcg_temp_free_ptr(addr);
566
        tcg_temp_free_i32(t2);
567
    }
568
    gen_store_gpr(t0, to);
569
    tcg_temp_free(t0);
570
}
571

    
572
static inline void gen_store_srsgpr (int from, int to)
573
{
574
    if (to != 0) {
575
        TCGv t0 = tcg_temp_new();
576
        TCGv_i32 t2 = tcg_temp_new_i32();
577
        TCGv_ptr addr = tcg_temp_new_ptr();
578

    
579
        gen_load_gpr(t0, from);
580
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
581
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
582
        tcg_gen_andi_i32(t2, t2, 0xf);
583
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
584
        tcg_gen_ext_i32_ptr(addr, t2);
585
        tcg_gen_add_ptr(addr, cpu_env, addr);
586

    
587
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
588
        tcg_temp_free_ptr(addr);
589
        tcg_temp_free_i32(t2);
590
        tcg_temp_free(t0);
591
    }
592
}
593

    
594
/* Floating point register moves. */
595
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
596
{
597
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
598
}
599

    
600
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
601
{
602
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
603
}
604

    
605
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
606
{
607
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
608
}
609

    
610
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
611
{
612
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
613
}
614

    
615
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
616
{
617
    if (ctx->hflags & MIPS_HFLAG_F64) {
618
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
619
    } else {
620
        TCGv_i32 t0 = tcg_temp_new_i32();
621
        TCGv_i32 t1 = tcg_temp_new_i32();
622
        gen_load_fpr32(t0, reg & ~1);
623
        gen_load_fpr32(t1, reg | 1);
624
        tcg_gen_concat_i32_i64(t, t0, t1);
625
        tcg_temp_free_i32(t0);
626
        tcg_temp_free_i32(t1);
627
    }
628
}
629

    
630
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
631
{
632
    if (ctx->hflags & MIPS_HFLAG_F64) {
633
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
634
    } else {
635
        TCGv_i64 t0 = tcg_temp_new_i64();
636
        TCGv_i32 t1 = tcg_temp_new_i32();
637
        tcg_gen_trunc_i64_i32(t1, t);
638
        gen_store_fpr32(t1, reg & ~1);
639
        tcg_gen_shri_i64(t0, t, 32);
640
        tcg_gen_trunc_i64_i32(t1, t0);
641
        gen_store_fpr32(t1, reg | 1);
642
        tcg_temp_free_i32(t1);
643
        tcg_temp_free_i64(t0);
644
    }
645
}
646

    
647
static inline int get_fp_bit (int cc)
648
{
649
    if (cc)
650
        return 24 + cc;
651
    else
652
        return 23;
653
}
654

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

    
680
FOP_CONDS(, d, 64)
681
FOP_CONDS(abs, d, 64)
682
FOP_CONDS(, s, 32)
683
FOP_CONDS(abs, s, 32)
684
FOP_CONDS(, ps, 64)
685
FOP_CONDS(abs, ps, 64)
686
#undef FOP_CONDS
687

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

    
710
#define OP_CONDI(name, cond)                                                 \
711
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
712
{                                                                            \
713
    int l1 = gen_new_label();                                                \
714
    int l2 = gen_new_label();                                                \
715
                                                                             \
716
    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
717
    tcg_gen_movi_tl(ret, 0);                                                 \
718
    tcg_gen_br(l2);                                                          \
719
    gen_set_label(l1);                                                       \
720
    tcg_gen_movi_tl(ret, 1);                                                 \
721
    gen_set_label(l2);                                                       \
722
}
723
OP_CONDI(lti, TCG_COND_LT);
724
OP_CONDI(ltiu, TCG_COND_LTU);
725
#undef OP_CONDI
726

    
727
#define OP_CONDZ(name, cond)                                  \
728
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
729
{                                                             \
730
    int l1 = gen_new_label();                                 \
731
    int l2 = gen_new_label();                                 \
732
                                                              \
733
    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
734
    tcg_gen_movi_tl(ret, 0);                                  \
735
    tcg_gen_br(l2);                                           \
736
    gen_set_label(l1);                                        \
737
    tcg_gen_movi_tl(ret, 1);                                  \
738
    gen_set_label(l2);                                        \
739
}
740
OP_CONDZ(gez, TCG_COND_GE);
741
OP_CONDZ(gtz, TCG_COND_GT);
742
OP_CONDZ(lez, TCG_COND_LE);
743
OP_CONDZ(ltz, TCG_COND_LT);
744
#undef OP_CONDZ
745

    
746
static inline void gen_save_pc(target_ulong pc)
747
{
748
    tcg_gen_movi_tl(cpu_PC, pc);
749
}
750

    
751
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
752
{
753
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
754
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
755
        gen_save_pc(ctx->pc);
756
        ctx->saved_pc = ctx->pc;
757
    }
758
    if (ctx->hflags != ctx->saved_hflags) {
759
        tcg_gen_movi_i32(hflags, ctx->hflags);
760
        ctx->saved_hflags = ctx->hflags;
761
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
762
        case MIPS_HFLAG_BR:
763
            break;
764
        case MIPS_HFLAG_BC:
765
        case MIPS_HFLAG_BL:
766
        case MIPS_HFLAG_B:
767
            tcg_gen_movi_tl(btarget, ctx->btarget);
768
            break;
769
        }
770
    }
771
}
772

    
773
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
774
{
775
    ctx->saved_hflags = ctx->hflags;
776
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
777
    case MIPS_HFLAG_BR:
778
        break;
779
    case MIPS_HFLAG_BC:
780
    case MIPS_HFLAG_BL:
781
    case MIPS_HFLAG_B:
782
        ctx->btarget = env->btarget;
783
        break;
784
    }
785
}
786

    
787
static inline void
788
generate_exception_err (DisasContext *ctx, int excp, int err)
789
{
790
    TCGv_i32 texcp = tcg_const_i32(excp);
791
    TCGv_i32 terr = tcg_const_i32(err);
792
    save_cpu_state(ctx, 1);
793
    gen_helper_raise_exception_err(texcp, terr);
794
    tcg_temp_free_i32(terr);
795
    tcg_temp_free_i32(texcp);
796
}
797

    
798
static inline void
799
generate_exception (DisasContext *ctx, int excp)
800
{
801
    save_cpu_state(ctx, 1);
802
    gen_helper_0i(raise_exception, excp);
803
}
804

    
805
/* Addresses computation */
806
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
807
{
808
    tcg_gen_add_tl(ret, arg0, arg1);
809

    
810
#if defined(TARGET_MIPS64)
811
    /* For compatibility with 32-bit code, data reference in user mode
812
       with Status_UX = 0 should be casted to 32-bit and sign extended.
813
       See the MIPS64 PRA manual, section 4.10. */
814
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
815
        !(ctx->hflags & MIPS_HFLAG_UX)) {
816
        tcg_gen_ext32s_i64(ret, ret);
817
    }
818
#endif
819
}
820

    
821
static inline void check_cp0_enabled(DisasContext *ctx)
822
{
823
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
824
        generate_exception_err(ctx, EXCP_CpU, 1);
825
}
826

    
827
static inline void check_cp1_enabled(DisasContext *ctx)
828
{
829
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
830
        generate_exception_err(ctx, EXCP_CpU, 1);
831
}
832

    
833
/* Verify that the processor is running with COP1X instructions enabled.
834
   This is associated with the nabla symbol in the MIPS32 and MIPS64
835
   opcode tables.  */
836

    
837
static inline void check_cop1x(DisasContext *ctx)
838
{
839
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
840
        generate_exception(ctx, EXCP_RI);
841
}
842

    
843
/* Verify that the processor is running with 64-bit floating-point
844
   operations enabled.  */
845

    
846
static inline void check_cp1_64bitmode(DisasContext *ctx)
847
{
848
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/*
853
 * Verify if floating point register is valid; an operation is not defined
854
 * if bit 0 of any register specification is set and the FR bit in the
855
 * Status register equals zero, since the register numbers specify an
856
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
857
 * in the Status register equals one, both even and odd register numbers
858
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
859
 *
860
 * Multiple 64 bit wide registers can be checked by calling
861
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
862
 */
863
static inline void check_cp1_registers(DisasContext *ctx, int regs)
864
{
865
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
866
        generate_exception(ctx, EXCP_RI);
867
}
868

    
869
/* This code generates a "reserved instruction" exception if the
870
   CPU does not support the instruction set corresponding to flags. */
871
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
872
{
873
    if (unlikely(!(env->insn_flags & flags)))
874
        generate_exception(ctx, EXCP_RI);
875
}
876

    
877
/* This code generates a "reserved instruction" exception if 64-bit
878
   instructions are not enabled. */
879
static inline void check_mips_64(DisasContext *ctx)
880
{
881
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
882
        generate_exception(ctx, EXCP_RI);
883
}
884

    
885
/* load/store instructions. */
886
#define OP_LD(insn,fname)                                                 \
887
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
888
{                                                                         \
889
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
890
}
891
OP_LD(lb,ld8s);
892
OP_LD(lbu,ld8u);
893
OP_LD(lh,ld16s);
894
OP_LD(lhu,ld16u);
895
OP_LD(lw,ld32s);
896
#if defined(TARGET_MIPS64)
897
OP_LD(lwu,ld32u);
898
OP_LD(ld,ld64);
899
#endif
900
#undef OP_LD
901

    
902
#define OP_ST(insn,fname)                                                  \
903
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
904
{                                                                          \
905
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
906
}
907
OP_ST(sb,st8);
908
OP_ST(sh,st16);
909
OP_ST(sw,st32);
910
#if defined(TARGET_MIPS64)
911
OP_ST(sd,st64);
912
#endif
913
#undef OP_ST
914

    
915
#define OP_LD_ATOMIC(insn,fname)                                           \
916
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
917
{                                                                          \
918
    TCGv t0 = tcg_temp_new();                                              \
919
    tcg_gen_mov_tl(t0, arg1);                                              \
920
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
921
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));            \
922
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
923
    tcg_temp_free(t0);                                                     \
924
}
925
OP_LD_ATOMIC(ll,ld32s);
926
#if defined(TARGET_MIPS64)
927
OP_LD_ATOMIC(lld,ld64);
928
#endif
929
#undef OP_LD_ATOMIC
930

    
931
#ifdef CONFIG_USER_ONLY
932
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
933
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
934
{                                                                            \
935
    TCGv t0 = tcg_temp_new();                                                \
936
    int l1 = gen_new_label();                                                \
937
    int l2 = gen_new_label();                                                \
938
                                                                             \
939
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
940
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
941
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
942
    generate_exception(ctx, EXCP_AdES);                                      \
943
    gen_set_label(l1);                                                       \
944
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
945
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
946
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
947
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
948
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
949
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
950
    gen_set_label(l2);                                                       \
951
    tcg_gen_movi_tl(t0, 0);                                                  \
952
    gen_store_gpr(t0, rt);                                                   \
953
    tcg_temp_free(t0);                                                       \
954
}
955
#else
956
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
957
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
958
{                                                                            \
959
    TCGv t0 = tcg_temp_new();                                                \
960
    TCGv t1 = tcg_temp_new();                                                \
961
    int l1 = gen_new_label();                                                \
962
    int l2 = gen_new_label();                                                \
963
    int l3 = gen_new_label();                                                \
964
                                                                             \
965
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
966
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
967
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
968
    generate_exception(ctx, EXCP_AdES);                                      \
969
    gen_set_label(l1);                                                       \
970
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
971
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
972
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, llval));                   \
973
    tcg_gen_qemu_##ldname(t1, arg2, ctx->mem_idx);                           \
974
    tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l2);                              \
975
    tcg_temp_free(t1);                                                       \
976
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                          \
977
    tcg_gen_movi_tl(t0, 1);                                                  \
978
    gen_store_gpr(t0, rt);                                                   \
979
    tcg_gen_br(l3);                                                          \
980
    gen_set_label(l2);                                                       \
981
    tcg_gen_movi_tl(t0, 0);                                                  \
982
    gen_store_gpr(t0, rt);                                                   \
983
    gen_set_label(l3);                                                       \
984
    tcg_temp_free(t0);                                                       \
985
}
986
#endif
987

    
988
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
989
#if defined(TARGET_MIPS64)
990
OP_ST_ATOMIC(scd,st64,ld64,0x7);
991
#endif
992
#undef OP_ST_ATOMIC
993

    
994
/* Load and store */
995
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
996
                      int base, int16_t offset)
997
{
998
    const char *opn = "ldst";
999
    TCGv t0 = tcg_temp_new();
1000
    TCGv t1 = tcg_temp_new();
1001

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

    
1151
/* Store conditional */
1152
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1153
                         int base, int16_t offset)
1154
{
1155
    const char *opn = "st_cond";
1156
    TCGv t0, t1;
1157

    
1158
    t0 = tcg_temp_local_new();
1159

    
1160
    if (base == 0) {
1161
        tcg_gen_movi_tl(t0, offset);
1162
    } else if (offset == 0) {
1163
        gen_load_gpr(t0, base);
1164
    } else {
1165
        tcg_gen_movi_tl(t0, offset);
1166
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1167
    }
1168
    /* Don't do NOP if destination is zero: we must perform the actual
1169
       memory access. */
1170

    
1171
    t1 = tcg_temp_local_new();
1172
    gen_load_gpr(t1, rt);
1173
    switch (opc) {
1174
#if defined(TARGET_MIPS64)
1175
    case OPC_SCD:
1176
        save_cpu_state(ctx, 0);
1177
        op_ldst_scd(t1, t0, rt, ctx);
1178
        opn = "scd";
1179
        break;
1180
#endif
1181
    case OPC_SC:
1182
        save_cpu_state(ctx, 0);
1183
        op_ldst_sc(t1, t0, rt, ctx);
1184
        opn = "sc";
1185
        break;
1186
    }
1187
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1188
    tcg_temp_free(t1);
1189
    tcg_temp_free(t0);
1190
}
1191

    
1192
/* Load and store */
1193
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1194
                          int base, int16_t offset)
1195
{
1196
    const char *opn = "flt_ldst";
1197
    TCGv t0 = tcg_temp_new();
1198

    
1199
    if (base == 0) {
1200
        tcg_gen_movi_tl(t0, offset);
1201
    } else if (offset == 0) {
1202
        gen_load_gpr(t0, base);
1203
    } else {
1204
        tcg_gen_movi_tl(t0, offset);
1205
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1206
    }
1207
    /* Don't do NOP if destination is zero: we must perform the actual
1208
       memory access. */
1209
    switch (opc) {
1210
    case OPC_LWC1:
1211
        {
1212
            TCGv_i32 fp0 = tcg_temp_new_i32();
1213

    
1214
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1215
            tcg_gen_trunc_tl_i32(fp0, t0);
1216
            gen_store_fpr32(fp0, ft);
1217
            tcg_temp_free_i32(fp0);
1218
        }
1219
        opn = "lwc1";
1220
        break;
1221
    case OPC_SWC1:
1222
        {
1223
            TCGv_i32 fp0 = tcg_temp_new_i32();
1224
            TCGv t1 = tcg_temp_new();
1225

    
1226
            gen_load_fpr32(fp0, ft);
1227
            tcg_gen_extu_i32_tl(t1, fp0);
1228
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1229
            tcg_temp_free(t1);
1230
            tcg_temp_free_i32(fp0);
1231
        }
1232
        opn = "swc1";
1233
        break;
1234
    case OPC_LDC1:
1235
        {
1236
            TCGv_i64 fp0 = tcg_temp_new_i64();
1237

    
1238
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1239
            gen_store_fpr64(ctx, fp0, ft);
1240
            tcg_temp_free_i64(fp0);
1241
        }
1242
        opn = "ldc1";
1243
        break;
1244
    case OPC_SDC1:
1245
        {
1246
            TCGv_i64 fp0 = tcg_temp_new_i64();
1247

    
1248
            gen_load_fpr64(ctx, fp0, ft);
1249
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1250
            tcg_temp_free_i64(fp0);
1251
        }
1252
        opn = "sdc1";
1253
        break;
1254
    default:
1255
        MIPS_INVAL(opn);
1256
        generate_exception(ctx, EXCP_RI);
1257
        goto out;
1258
    }
1259
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1260
 out:
1261
    tcg_temp_free(t0);
1262
}
1263

    
1264
/* Arithmetic with immediate operand */
1265
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1266
                           int rt, int rs, int16_t imm)
1267
{
1268
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1269
    const char *opn = "imm arith";
1270

    
1271
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1272
        /* If no destination, treat it as a NOP.
1273
           For addi, we must generate the overflow exception when needed. */
1274
        MIPS_DEBUG("NOP");
1275
        return;
1276
    }
1277
    switch (opc) {
1278
    case OPC_ADDI:
1279
        {
1280
            TCGv t0 = tcg_temp_local_new();
1281
            TCGv t1 = tcg_temp_new();
1282
            TCGv t2 = tcg_temp_new();
1283
            int l1 = gen_new_label();
1284

    
1285
            gen_load_gpr(t1, rs);
1286
            tcg_gen_addi_tl(t0, t1, uimm);
1287
            tcg_gen_ext32s_tl(t0, t0);
1288

    
1289
            tcg_gen_xori_tl(t1, t1, ~uimm);
1290
            tcg_gen_xori_tl(t2, t0, uimm);
1291
            tcg_gen_and_tl(t1, t1, t2);
1292
            tcg_temp_free(t2);
1293
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1294
            tcg_temp_free(t1);
1295
            /* operands of same sign, result different sign */
1296
            generate_exception(ctx, EXCP_OVERFLOW);
1297
            gen_set_label(l1);
1298
            tcg_gen_ext32s_tl(t0, t0);
1299
            gen_store_gpr(t0, rt);
1300
            tcg_temp_free(t0);
1301
        }
1302
        opn = "addi";
1303
        break;
1304
    case OPC_ADDIU:
1305
        if (rs != 0) {
1306
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1307
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1308
        } else {
1309
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1310
        }
1311
        opn = "addiu";
1312
        break;
1313
#if defined(TARGET_MIPS64)
1314
    case OPC_DADDI:
1315
        {
1316
            TCGv t0 = tcg_temp_local_new();
1317
            TCGv t1 = tcg_temp_new();
1318
            TCGv t2 = tcg_temp_new();
1319
            int l1 = gen_new_label();
1320

    
1321
            gen_load_gpr(t1, rs);
1322
            tcg_gen_addi_tl(t0, t1, uimm);
1323

    
1324
            tcg_gen_xori_tl(t1, t1, ~uimm);
1325
            tcg_gen_xori_tl(t2, t0, uimm);
1326
            tcg_gen_and_tl(t1, t1, t2);
1327
            tcg_temp_free(t2);
1328
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1329
            tcg_temp_free(t1);
1330
            /* operands of same sign, result different sign */
1331
            generate_exception(ctx, EXCP_OVERFLOW);
1332
            gen_set_label(l1);
1333
            gen_store_gpr(t0, rt);
1334
            tcg_temp_free(t0);
1335
        }
1336
        opn = "daddi";
1337
        break;
1338
    case OPC_DADDIU:
1339
        if (rs != 0) {
1340
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1341
        } else {
1342
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1343
        }
1344
        opn = "daddiu";
1345
        break;
1346
#endif
1347
    }
1348
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1349
}
1350

    
1351
/* Logic with immediate operand */
1352
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1353
{
1354
    target_ulong uimm;
1355
    const char *opn = "imm logic";
1356

    
1357
    if (rt == 0) {
1358
        /* If no destination, treat it as a NOP. */
1359
        MIPS_DEBUG("NOP");
1360
        return;
1361
    }
1362
    uimm = (uint16_t)imm;
1363
    switch (opc) {
1364
    case OPC_ANDI:
1365
        if (likely(rs != 0))
1366
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1367
        else
1368
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1369
        opn = "andi";
1370
        break;
1371
    case OPC_ORI:
1372
        if (rs != 0)
1373
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1374
        else
1375
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1376
        opn = "ori";
1377
        break;
1378
    case OPC_XORI:
1379
        if (likely(rs != 0))
1380
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1381
        else
1382
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1383
        opn = "xori";
1384
        break;
1385
    case OPC_LUI:
1386
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1387
        opn = "lui";
1388
        break;
1389
    }
1390
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1391
}
1392

    
1393
/* Set on less than with immediate operand */
1394
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1395
{
1396
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1397
    const char *opn = "imm arith";
1398
    TCGv t0;
1399

    
1400
    if (rt == 0) {
1401
        /* If no destination, treat it as a NOP. */
1402
        MIPS_DEBUG("NOP");
1403
        return;
1404
    }
1405
    t0 = tcg_temp_new();
1406
    gen_load_gpr(t0, rs);
1407
    switch (opc) {
1408
    case OPC_SLTI:
1409
        gen_op_lti(cpu_gpr[rt], t0, uimm);
1410
        opn = "slti";
1411
        break;
1412
    case OPC_SLTIU:
1413
        gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1414
        opn = "sltiu";
1415
        break;
1416
    }
1417
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1418
    tcg_temp_free(t0);
1419
}
1420

    
1421
/* Shifts with immediate operand */
1422
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1423
                          int rt, int rs, int16_t imm)
1424
{
1425
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1426
    const char *opn = "imm shift";
1427
    TCGv t0;
1428

    
1429
    if (rt == 0) {
1430
        /* If no destination, treat it as a NOP. */
1431
        MIPS_DEBUG("NOP");
1432
        return;
1433
    }
1434

    
1435
    t0 = tcg_temp_new();
1436
    gen_load_gpr(t0, rs);
1437
    switch (opc) {
1438
    case OPC_SLL:
1439
        tcg_gen_shli_tl(t0, t0, uimm);
1440
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1441
        opn = "sll";
1442
        break;
1443
    case OPC_SRA:
1444
        tcg_gen_ext32s_tl(t0, t0);
1445
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1446
        opn = "sra";
1447
        break;
1448
    case OPC_SRL:
1449
        switch ((ctx->opcode >> 21) & 0x1f) {
1450
        case 0:
1451
            if (uimm != 0) {
1452
                tcg_gen_ext32u_tl(t0, t0);
1453
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1454
            } else {
1455
                tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1456
            }
1457
            opn = "srl";
1458
            break;
1459
        case 1:
1460
            /* rotr is decoded as srl on non-R2 CPUs */
1461
            if (env->insn_flags & ISA_MIPS32R2) {
1462
                if (uimm != 0) {
1463
                    TCGv_i32 t1 = tcg_temp_new_i32();
1464

    
1465
                    tcg_gen_trunc_tl_i32(t1, t0);
1466
                    tcg_gen_rotri_i32(t1, t1, uimm);
1467
                    tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1468
                    tcg_temp_free_i32(t1);
1469
                }
1470
                opn = "rotr";
1471
            } else {
1472
                if (uimm != 0) {
1473
                    tcg_gen_ext32u_tl(t0, t0);
1474
                    tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1475
                } else {
1476
                    tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1477
                }
1478
                opn = "srl";
1479
            }
1480
            break;
1481
        default:
1482
            MIPS_INVAL("invalid srl flag");
1483
            generate_exception(ctx, EXCP_RI);
1484
            break;
1485
        }
1486
        break;
1487
#if defined(TARGET_MIPS64)
1488
    case OPC_DSLL:
1489
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1490
        opn = "dsll";
1491
        break;
1492
    case OPC_DSRA:
1493
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1494
        opn = "dsra";
1495
        break;
1496
    case OPC_DSRL:
1497
        switch ((ctx->opcode >> 21) & 0x1f) {
1498
        case 0:
1499
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1500
            opn = "dsrl";
1501
            break;
1502
        case 1:
1503
            /* drotr is decoded as dsrl on non-R2 CPUs */
1504
            if (env->insn_flags & ISA_MIPS32R2) {
1505
                if (uimm != 0) {
1506
                    tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1507
                }
1508
                opn = "drotr";
1509
            } else {
1510
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1511
                opn = "dsrl";
1512
            }
1513
            break;
1514
        default:
1515
            MIPS_INVAL("invalid dsrl flag");
1516
            generate_exception(ctx, EXCP_RI);
1517
            break;
1518
        }
1519
        break;
1520
    case OPC_DSLL32:
1521
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1522
        opn = "dsll32";
1523
        break;
1524
    case OPC_DSRA32:
1525
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1526
        opn = "dsra32";
1527
        break;
1528
    case OPC_DSRL32:
1529
        switch ((ctx->opcode >> 21) & 0x1f) {
1530
        case 0:
1531
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1532
            opn = "dsrl32";
1533
            break;
1534
        case 1:
1535
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1536
            if (env->insn_flags & ISA_MIPS32R2) {
1537
                tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1538
                opn = "drotr32";
1539
            } else {
1540
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1541
                opn = "dsrl32";
1542
            }
1543
            break;
1544
        default:
1545
            MIPS_INVAL("invalid dsrl32 flag");
1546
            generate_exception(ctx, EXCP_RI);
1547
            break;
1548
        }
1549
        break;
1550
#endif
1551
    }
1552
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1553
    tcg_temp_free(t0);
1554
}
1555

    
1556
/* Arithmetic */
1557
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1558
                       int rd, int rs, int rt)
1559
{
1560
    const char *opn = "arith";
1561

    
1562
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1563
       && opc != OPC_DADD && opc != OPC_DSUB) {
1564
        /* If no destination, treat it as a NOP.
1565
           For add & sub, we must generate the overflow exception when needed. */
1566
        MIPS_DEBUG("NOP");
1567
        return;
1568
    }
1569

    
1570
    switch (opc) {
1571
    case OPC_ADD:
1572
        {
1573
            TCGv t0 = tcg_temp_local_new();
1574
            TCGv t1 = tcg_temp_new();
1575
            TCGv t2 = tcg_temp_new();
1576
            int l1 = gen_new_label();
1577

    
1578
            gen_load_gpr(t1, rs);
1579
            gen_load_gpr(t2, rt);
1580
            tcg_gen_add_tl(t0, t1, t2);
1581
            tcg_gen_ext32s_tl(t0, t0);
1582
            tcg_gen_xor_tl(t1, t1, t2);
1583
            tcg_gen_not_tl(t1, t1);
1584
            tcg_gen_xor_tl(t2, t0, t2);
1585
            tcg_gen_and_tl(t1, t1, t2);
1586
            tcg_temp_free(t2);
1587
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1588
            tcg_temp_free(t1);
1589
            /* operands of same sign, result different sign */
1590
            generate_exception(ctx, EXCP_OVERFLOW);
1591
            gen_set_label(l1);
1592
            gen_store_gpr(t0, rd);
1593
            tcg_temp_free(t0);
1594
        }
1595
        opn = "add";
1596
        break;
1597
    case OPC_ADDU:
1598
        if (rs != 0 && rt != 0) {
1599
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1600
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1601
        } else if (rs == 0 && rt != 0) {
1602
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1603
        } else if (rs != 0 && rt == 0) {
1604
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1605
        } else {
1606
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1607
        }
1608
        opn = "addu";
1609
        break;
1610
    case OPC_SUB:
1611
        {
1612
            TCGv t0 = tcg_temp_local_new();
1613
            TCGv t1 = tcg_temp_new();
1614
            TCGv t2 = tcg_temp_new();
1615
            int l1 = gen_new_label();
1616

    
1617
            gen_load_gpr(t1, rs);
1618
            gen_load_gpr(t2, rt);
1619
            tcg_gen_sub_tl(t0, t1, t2);
1620
            tcg_gen_ext32s_tl(t0, t0);
1621
            tcg_gen_xor_tl(t2, t1, t2);
1622
            tcg_gen_xor_tl(t1, t0, t1);
1623
            tcg_gen_and_tl(t1, t1, t2);
1624
            tcg_temp_free(t2);
1625
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1626
            tcg_temp_free(t1);
1627
            /* operands of different sign, first operand and result different sign */
1628
            generate_exception(ctx, EXCP_OVERFLOW);
1629
            gen_set_label(l1);
1630
            gen_store_gpr(t0, rd);
1631
            tcg_temp_free(t0);
1632
        }
1633
        opn = "sub";
1634
        break;
1635
    case OPC_SUBU:
1636
        if (rs != 0 && rt != 0) {
1637
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1638
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1639
        } else if (rs == 0 && rt != 0) {
1640
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1641
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1642
        } else if (rs != 0 && rt == 0) {
1643
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1644
        } else {
1645
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1646
        }
1647
        opn = "subu";
1648
        break;
1649
#if defined(TARGET_MIPS64)
1650
    case OPC_DADD:
1651
        {
1652
            TCGv t0 = tcg_temp_local_new();
1653
            TCGv t1 = tcg_temp_new();
1654
            TCGv t2 = tcg_temp_new();
1655
            int l1 = gen_new_label();
1656

    
1657
            gen_load_gpr(t1, rs);
1658
            gen_load_gpr(t2, rt);
1659
            tcg_gen_add_tl(t0, t1, t2);
1660
            tcg_gen_xor_tl(t1, t1, t2);
1661
            tcg_gen_not_tl(t1, t1);
1662
            tcg_gen_xor_tl(t2, t0, t2);
1663
            tcg_gen_and_tl(t1, t1, t2);
1664
            tcg_temp_free(t2);
1665
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1666
            tcg_temp_free(t1);
1667
            /* operands of same sign, result different sign */
1668
            generate_exception(ctx, EXCP_OVERFLOW);
1669
            gen_set_label(l1);
1670
            gen_store_gpr(t0, rd);
1671
            tcg_temp_free(t0);
1672
        }
1673
        opn = "dadd";
1674
        break;
1675
    case OPC_DADDU:
1676
        if (rs != 0 && rt != 0) {
1677
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1678
        } else if (rs == 0 && rt != 0) {
1679
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1680
        } else if (rs != 0 && rt == 0) {
1681
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1682
        } else {
1683
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1684
        }
1685
        opn = "daddu";
1686
        break;
1687
    case OPC_DSUB:
1688
        {
1689
            TCGv t0 = tcg_temp_local_new();
1690
            TCGv t1 = tcg_temp_new();
1691
            TCGv t2 = tcg_temp_new();
1692
            int l1 = gen_new_label();
1693

    
1694
            gen_load_gpr(t1, rs);
1695
            gen_load_gpr(t2, rt);
1696
            tcg_gen_sub_tl(t0, t1, t2);
1697
            tcg_gen_xor_tl(t2, t1, t2);
1698
            tcg_gen_xor_tl(t1, t0, t1);
1699
            tcg_gen_and_tl(t1, t1, t2);
1700
            tcg_temp_free(t2);
1701
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1702
            tcg_temp_free(t1);
1703
            /* operands of different sign, first operand and result different sign */
1704
            generate_exception(ctx, EXCP_OVERFLOW);
1705
            gen_set_label(l1);
1706
            gen_store_gpr(t0, rd);
1707
            tcg_temp_free(t0);
1708
        }
1709
        opn = "dsub";
1710
        break;
1711
    case OPC_DSUBU:
1712
        if (rs != 0 && rt != 0) {
1713
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1714
        } else if (rs == 0 && rt != 0) {
1715
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1716
        } else if (rs != 0 && rt == 0) {
1717
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1718
        } else {
1719
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1720
        }
1721
        opn = "dsubu";
1722
        break;
1723
#endif
1724
    case OPC_MUL:
1725
        if (likely(rs != 0 && rt != 0)) {
1726
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1727
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1728
        } else {
1729
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1730
        }
1731
        opn = "mul";
1732
        break;
1733
    }
1734
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1735
}
1736

    
1737
/* Conditional move */
1738
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1739
{
1740
    const char *opn = "cond move";
1741
    int l1;
1742

    
1743
    if (rd == 0) {
1744
        /* If no destination, treat it as a NOP.
1745
           For add & sub, we must generate the overflow exception when needed. */
1746
        MIPS_DEBUG("NOP");
1747
        return;
1748
    }
1749

    
1750
    l1 = gen_new_label();
1751
    switch (opc) {
1752
    case OPC_MOVN:
1753
        if (likely(rt != 0))
1754
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1755
        else
1756
            tcg_gen_br(l1);
1757
        opn = "movn";
1758
        break;
1759
    case OPC_MOVZ:
1760
        if (likely(rt != 0))
1761
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1762
        opn = "movz";
1763
        break;
1764
    }
1765
    if (rs != 0)
1766
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1767
    else
1768
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1769
    gen_set_label(l1);
1770

    
1771
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1772
}
1773

    
1774
/* Logic */
1775
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1776
{
1777
    const char *opn = "logic";
1778

    
1779
    if (rd == 0) {
1780
        /* If no destination, treat it as a NOP. */
1781
        MIPS_DEBUG("NOP");
1782
        return;
1783
    }
1784

    
1785
    switch (opc) {
1786
    case OPC_AND:
1787
        if (likely(rs != 0 && rt != 0)) {
1788
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1789
        } else {
1790
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1791
        }
1792
        opn = "and";
1793
        break;
1794
    case OPC_NOR:
1795
        if (rs != 0 && rt != 0) {
1796
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1797
        } else if (rs == 0 && rt != 0) {
1798
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1799
        } else if (rs != 0 && rt == 0) {
1800
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1801
        } else {
1802
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1803
        }
1804
        opn = "nor";
1805
        break;
1806
    case OPC_OR:
1807
        if (likely(rs != 0 && rt != 0)) {
1808
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1809
        } else if (rs == 0 && rt != 0) {
1810
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1811
        } else if (rs != 0 && rt == 0) {
1812
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1813
        } else {
1814
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1815
        }
1816
        opn = "or";
1817
        break;
1818
    case OPC_XOR:
1819
        if (likely(rs != 0 && rt != 0)) {
1820
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1821
        } else if (rs == 0 && rt != 0) {
1822
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1823
        } else if (rs != 0 && rt == 0) {
1824
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1825
        } else {
1826
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1827
        }
1828
        opn = "xor";
1829
        break;
1830
    }
1831
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1832
}
1833

    
1834
/* Set on lower than */
1835
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1836
{
1837
    const char *opn = "slt";
1838
    TCGv t0, t1;
1839

    
1840
    if (rd == 0) {
1841
        /* If no destination, treat it as a NOP. */
1842
        MIPS_DEBUG("NOP");
1843
        return;
1844
    }
1845

    
1846
    t0 = tcg_temp_new();
1847
    t1 = tcg_temp_new();
1848
    gen_load_gpr(t0, rs);
1849
    gen_load_gpr(t1, rt);
1850
    switch (opc) {
1851
    case OPC_SLT:
1852
        gen_op_lt(cpu_gpr[rd], t0, t1);
1853
        opn = "slt";
1854
        break;
1855
    case OPC_SLTU:
1856
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1857
        opn = "sltu";
1858
        break;
1859
    }
1860
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1861
    tcg_temp_free(t0);
1862
    tcg_temp_free(t1);
1863
}
1864

    
1865
/* Shifts */
1866
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1867
                       int rd, int rs, int rt)
1868
{
1869
    const char *opn = "shifts";
1870
    TCGv t0, t1;
1871

    
1872
    if (rd == 0) {
1873
        /* If no destination, treat it as a NOP.
1874
           For add & sub, we must generate the overflow exception when needed. */
1875
        MIPS_DEBUG("NOP");
1876
        return;
1877
    }
1878

    
1879
    t0 = tcg_temp_new();
1880
    t1 = tcg_temp_new();
1881
    gen_load_gpr(t0, rs);
1882
    gen_load_gpr(t1, rt);
1883
    switch (opc) {
1884
    case OPC_SLLV:
1885
        tcg_gen_andi_tl(t0, t0, 0x1f);
1886
        tcg_gen_shl_tl(t0, t1, t0);
1887
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1888
        opn = "sllv";
1889
        break;
1890
    case OPC_SRAV:
1891
        tcg_gen_ext32s_tl(t1, t1);
1892
        tcg_gen_andi_tl(t0, t0, 0x1f);
1893
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1894
        opn = "srav";
1895
        break;
1896
    case OPC_SRLV:
1897
        switch ((ctx->opcode >> 6) & 0x1f) {
1898
        case 0:
1899
            tcg_gen_ext32u_tl(t1, t1);
1900
            tcg_gen_andi_tl(t0, t0, 0x1f);
1901
            tcg_gen_shr_tl(t0, t1, t0);
1902
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1903
            opn = "srlv";
1904
            break;
1905
        case 1:
1906
            /* rotrv is decoded as srlv on non-R2 CPUs */
1907
            if (env->insn_flags & ISA_MIPS32R2) {
1908
                TCGv_i32 t2 = tcg_temp_new_i32();
1909
                TCGv_i32 t3 = tcg_temp_new_i32();
1910

    
1911
                tcg_gen_trunc_tl_i32(t2, t0);
1912
                tcg_gen_trunc_tl_i32(t3, t1);
1913
                tcg_gen_andi_i32(t2, t2, 0x1f);
1914
                tcg_gen_rotr_i32(t2, t3, t2);
1915
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1916
                tcg_temp_free_i32(t2);
1917
                tcg_temp_free_i32(t3);
1918
                opn = "rotrv";
1919
            } else {
1920
                tcg_gen_ext32u_tl(t1, t1);
1921
                tcg_gen_andi_tl(t0, t0, 0x1f);
1922
                tcg_gen_shr_tl(t0, t1, t0);
1923
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1924
                opn = "srlv";
1925
            }
1926
            break;
1927
        default:
1928
            MIPS_INVAL("invalid srlv flag");
1929
            generate_exception(ctx, EXCP_RI);
1930
            break;
1931
        }
1932
        break;
1933
#if defined(TARGET_MIPS64)
1934
    case OPC_DSLLV:
1935
        tcg_gen_andi_tl(t0, t0, 0x3f);
1936
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1937
        opn = "dsllv";
1938
        break;
1939
    case OPC_DSRAV:
1940
        tcg_gen_andi_tl(t0, t0, 0x3f);
1941
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1942
        opn = "dsrav";
1943
        break;
1944
    case OPC_DSRLV:
1945
        switch ((ctx->opcode >> 6) & 0x1f) {
1946
        case 0:
1947
            tcg_gen_andi_tl(t0, t0, 0x3f);
1948
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1949
            opn = "dsrlv";
1950
            break;
1951
        case 1:
1952
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1953
            if (env->insn_flags & ISA_MIPS32R2) {
1954
                tcg_gen_andi_tl(t0, t0, 0x3f);
1955
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1956
                opn = "drotrv";
1957
            } else {
1958
                tcg_gen_andi_tl(t0, t0, 0x3f);
1959
                tcg_gen_shr_tl(t0, t1, t0);
1960
                opn = "dsrlv";
1961
            }
1962
            break;
1963
        default:
1964
            MIPS_INVAL("invalid dsrlv flag");
1965
            generate_exception(ctx, EXCP_RI);
1966
            break;
1967
        }
1968
        break;
1969
#endif
1970
    }
1971
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1972
    tcg_temp_free(t0);
1973
    tcg_temp_free(t1);
1974
}
1975

    
1976
/* Arithmetic on HI/LO registers */
1977
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1978
{
1979
    const char *opn = "hilo";
1980

    
1981
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1982
        /* Treat as NOP. */
1983
        MIPS_DEBUG("NOP");
1984
        return;
1985
    }
1986
    switch (opc) {
1987
    case OPC_MFHI:
1988
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1989
        opn = "mfhi";
1990
        break;
1991
    case OPC_MFLO:
1992
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1993
        opn = "mflo";
1994
        break;
1995
    case OPC_MTHI:
1996
        if (reg != 0)
1997
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1998
        else
1999
            tcg_gen_movi_tl(cpu_HI[0], 0);
2000
        opn = "mthi";
2001
        break;
2002
    case OPC_MTLO:
2003
        if (reg != 0)
2004
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2005
        else
2006
            tcg_gen_movi_tl(cpu_LO[0], 0);
2007
        opn = "mtlo";
2008
        break;
2009
    }
2010
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2011
}
2012

    
2013
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2014
                        int rs, int rt)
2015
{
2016
    const char *opn = "mul/div";
2017
    TCGv t0, t1;
2018

    
2019
    switch (opc) {
2020
    case OPC_DIV:
2021
    case OPC_DIVU:
2022
#if defined(TARGET_MIPS64)
2023
    case OPC_DDIV:
2024
    case OPC_DDIVU:
2025
#endif
2026
        t0 = tcg_temp_local_new();
2027
        t1 = tcg_temp_local_new();
2028
        break;
2029
    default:
2030
        t0 = tcg_temp_new();
2031
        t1 = tcg_temp_new();
2032
        break;
2033
    }
2034

    
2035
    gen_load_gpr(t0, rs);
2036
    gen_load_gpr(t1, rt);
2037
    switch (opc) {
2038
    case OPC_DIV:
2039
        {
2040
            int l1 = gen_new_label();
2041
            int l2 = gen_new_label();
2042

    
2043
            tcg_gen_ext32s_tl(t0, t0);
2044
            tcg_gen_ext32s_tl(t1, t1);
2045
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2046
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2047
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2048

    
2049
            tcg_gen_mov_tl(cpu_LO[0], t0);
2050
            tcg_gen_movi_tl(cpu_HI[0], 0);
2051
            tcg_gen_br(l1);
2052
            gen_set_label(l2);
2053
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2054
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2055
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2056
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2057
            gen_set_label(l1);
2058
        }
2059
        opn = "div";
2060
        break;
2061
    case OPC_DIVU:
2062
        {
2063
            int l1 = gen_new_label();
2064

    
2065
            tcg_gen_ext32u_tl(t0, t0);
2066
            tcg_gen_ext32u_tl(t1, t1);
2067
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2068
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2069
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2070
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2071
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2072
            gen_set_label(l1);
2073
        }
2074
        opn = "divu";
2075
        break;
2076
    case OPC_MULT:
2077
        {
2078
            TCGv_i64 t2 = tcg_temp_new_i64();
2079
            TCGv_i64 t3 = tcg_temp_new_i64();
2080

    
2081
            tcg_gen_ext_tl_i64(t2, t0);
2082
            tcg_gen_ext_tl_i64(t3, t1);
2083
            tcg_gen_mul_i64(t2, t2, t3);
2084
            tcg_temp_free_i64(t3);
2085
            tcg_gen_trunc_i64_tl(t0, t2);
2086
            tcg_gen_shri_i64(t2, t2, 32);
2087
            tcg_gen_trunc_i64_tl(t1, t2);
2088
            tcg_temp_free_i64(t2);
2089
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2090
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2091
        }
2092
        opn = "mult";
2093
        break;
2094
    case OPC_MULTU:
2095
        {
2096
            TCGv_i64 t2 = tcg_temp_new_i64();
2097
            TCGv_i64 t3 = tcg_temp_new_i64();
2098

    
2099
            tcg_gen_ext32u_tl(t0, t0);
2100
            tcg_gen_ext32u_tl(t1, t1);
2101
            tcg_gen_extu_tl_i64(t2, t0);
2102
            tcg_gen_extu_tl_i64(t3, t1);
2103
            tcg_gen_mul_i64(t2, t2, t3);
2104
            tcg_temp_free_i64(t3);
2105
            tcg_gen_trunc_i64_tl(t0, t2);
2106
            tcg_gen_shri_i64(t2, t2, 32);
2107
            tcg_gen_trunc_i64_tl(t1, t2);
2108
            tcg_temp_free_i64(t2);
2109
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2110
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2111
        }
2112
        opn = "multu";
2113
        break;
2114
#if defined(TARGET_MIPS64)
2115
    case OPC_DDIV:
2116
        {
2117
            int l1 = gen_new_label();
2118
            int l2 = gen_new_label();
2119

    
2120
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2121
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2122
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2123
            tcg_gen_mov_tl(cpu_LO[0], t0);
2124
            tcg_gen_movi_tl(cpu_HI[0], 0);
2125
            tcg_gen_br(l1);
2126
            gen_set_label(l2);
2127
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2128
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2129
            gen_set_label(l1);
2130
        }
2131
        opn = "ddiv";
2132
        break;
2133
    case OPC_DDIVU:
2134
        {
2135
            int l1 = gen_new_label();
2136

    
2137
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2138
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2139
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2140
            gen_set_label(l1);
2141
        }
2142
        opn = "ddivu";
2143
        break;
2144
    case OPC_DMULT:
2145
        gen_helper_dmult(t0, t1);
2146
        opn = "dmult";
2147
        break;
2148
    case OPC_DMULTU:
2149
        gen_helper_dmultu(t0, t1);
2150
        opn = "dmultu";
2151
        break;
2152
#endif
2153
    case OPC_MADD:
2154
        {
2155
            TCGv_i64 t2 = tcg_temp_new_i64();
2156
            TCGv_i64 t3 = tcg_temp_new_i64();
2157

    
2158
            tcg_gen_ext_tl_i64(t2, t0);
2159
            tcg_gen_ext_tl_i64(t3, t1);
2160
            tcg_gen_mul_i64(t2, t2, t3);
2161
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2162
            tcg_gen_add_i64(t2, t2, t3);
2163
            tcg_temp_free_i64(t3);
2164
            tcg_gen_trunc_i64_tl(t0, t2);
2165
            tcg_gen_shri_i64(t2, t2, 32);
2166
            tcg_gen_trunc_i64_tl(t1, t2);
2167
            tcg_temp_free_i64(t2);
2168
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2169
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2170
        }
2171
        opn = "madd";
2172
        break;
2173
    case OPC_MADDU:
2174
       {
2175
            TCGv_i64 t2 = tcg_temp_new_i64();
2176
            TCGv_i64 t3 = tcg_temp_new_i64();
2177

    
2178
            tcg_gen_ext32u_tl(t0, t0);
2179
            tcg_gen_ext32u_tl(t1, t1);
2180
            tcg_gen_extu_tl_i64(t2, t0);
2181
            tcg_gen_extu_tl_i64(t3, t1);
2182
            tcg_gen_mul_i64(t2, t2, t3);
2183
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2184
            tcg_gen_add_i64(t2, t2, t3);
2185
            tcg_temp_free_i64(t3);
2186
            tcg_gen_trunc_i64_tl(t0, t2);
2187
            tcg_gen_shri_i64(t2, t2, 32);
2188
            tcg_gen_trunc_i64_tl(t1, t2);
2189
            tcg_temp_free_i64(t2);
2190
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2191
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2192
        }
2193
        opn = "maddu";
2194
        break;
2195
    case OPC_MSUB:
2196
        {
2197
            TCGv_i64 t2 = tcg_temp_new_i64();
2198
            TCGv_i64 t3 = tcg_temp_new_i64();
2199

    
2200
            tcg_gen_ext_tl_i64(t2, t0);
2201
            tcg_gen_ext_tl_i64(t3, t1);
2202
            tcg_gen_mul_i64(t2, t2, t3);
2203
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2204
            tcg_gen_sub_i64(t2, t3, t2);
2205
            tcg_temp_free_i64(t3);
2206
            tcg_gen_trunc_i64_tl(t0, t2);
2207
            tcg_gen_shri_i64(t2, t2, 32);
2208
            tcg_gen_trunc_i64_tl(t1, t2);
2209
            tcg_temp_free_i64(t2);
2210
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2211
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2212
        }
2213
        opn = "msub";
2214
        break;
2215
    case OPC_MSUBU:
2216
        {
2217
            TCGv_i64 t2 = tcg_temp_new_i64();
2218
            TCGv_i64 t3 = tcg_temp_new_i64();
2219

    
2220
            tcg_gen_ext32u_tl(t0, t0);
2221
            tcg_gen_ext32u_tl(t1, t1);
2222
            tcg_gen_extu_tl_i64(t2, t0);
2223
            tcg_gen_extu_tl_i64(t3, t1);
2224
            tcg_gen_mul_i64(t2, t2, t3);
2225
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2226
            tcg_gen_sub_i64(t2, t3, t2);
2227
            tcg_temp_free_i64(t3);
2228
            tcg_gen_trunc_i64_tl(t0, t2);
2229
            tcg_gen_shri_i64(t2, t2, 32);
2230
            tcg_gen_trunc_i64_tl(t1, t2);
2231
            tcg_temp_free_i64(t2);
2232
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2233
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2234
        }
2235
        opn = "msubu";
2236
        break;
2237
    default:
2238
        MIPS_INVAL(opn);
2239
        generate_exception(ctx, EXCP_RI);
2240
        goto out;
2241
    }
2242
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2243
 out:
2244
    tcg_temp_free(t0);
2245
    tcg_temp_free(t1);
2246
}
2247

    
2248
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2249
                            int rd, int rs, int rt)
2250
{
2251
    const char *opn = "mul vr54xx";
2252
    TCGv t0 = tcg_temp_new();
2253
    TCGv t1 = tcg_temp_new();
2254

    
2255
    gen_load_gpr(t0, rs);
2256
    gen_load_gpr(t1, rt);
2257

    
2258
    switch (opc) {
2259
    case OPC_VR54XX_MULS:
2260
        gen_helper_muls(t0, t0, t1);
2261
        opn = "muls";
2262
        break;
2263
    case OPC_VR54XX_MULSU:
2264
        gen_helper_mulsu(t0, t0, t1);
2265
        opn = "mulsu";
2266
        break;
2267
    case OPC_VR54XX_MACC:
2268
        gen_helper_macc(t0, t0, t1);
2269
        opn = "macc";
2270
        break;
2271
    case OPC_VR54XX_MACCU:
2272
        gen_helper_maccu(t0, t0, t1);
2273
        opn = "maccu";
2274
        break;
2275
    case OPC_VR54XX_MSAC:
2276
        gen_helper_msac(t0, t0, t1);
2277
        opn = "msac";
2278
        break;
2279
    case OPC_VR54XX_MSACU:
2280
        gen_helper_msacu(t0, t0, t1);
2281
        opn = "msacu";
2282
        break;
2283
    case OPC_VR54XX_MULHI:
2284
        gen_helper_mulhi(t0, t0, t1);
2285
        opn = "mulhi";
2286
        break;
2287
    case OPC_VR54XX_MULHIU:
2288
        gen_helper_mulhiu(t0, t0, t1);
2289
        opn = "mulhiu";
2290
        break;
2291
    case OPC_VR54XX_MULSHI:
2292
        gen_helper_mulshi(t0, t0, t1);
2293
        opn = "mulshi";
2294
        break;
2295
    case OPC_VR54XX_MULSHIU:
2296
        gen_helper_mulshiu(t0, t0, t1);
2297
        opn = "mulshiu";
2298
        break;
2299
    case OPC_VR54XX_MACCHI:
2300
        gen_helper_macchi(t0, t0, t1);
2301
        opn = "macchi";
2302
        break;
2303
    case OPC_VR54XX_MACCHIU:
2304
        gen_helper_macchiu(t0, t0, t1);
2305
        opn = "macchiu";
2306
        break;
2307
    case OPC_VR54XX_MSACHI:
2308
        gen_helper_msachi(t0, t0, t1);
2309
        opn = "msachi";
2310
        break;
2311
    case OPC_VR54XX_MSACHIU:
2312
        gen_helper_msachiu(t0, t0, t1);
2313
        opn = "msachiu";
2314
        break;
2315
    default:
2316
        MIPS_INVAL("mul vr54xx");
2317
        generate_exception(ctx, EXCP_RI);
2318
        goto out;
2319
    }
2320
    gen_store_gpr(t0, rd);
2321
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2322

    
2323
 out:
2324
    tcg_temp_free(t0);
2325
    tcg_temp_free(t1);
2326
}
2327

    
2328
static void gen_cl (DisasContext *ctx, uint32_t opc,
2329
                    int rd, int rs)
2330
{
2331
    const char *opn = "CLx";
2332
    TCGv t0;
2333

    
2334
    if (rd == 0) {
2335
        /* Treat as NOP. */
2336
        MIPS_DEBUG("NOP");
2337
        return;
2338
    }
2339
    t0 = tcg_temp_new();
2340
    gen_load_gpr(t0, rs);
2341
    switch (opc) {
2342
    case OPC_CLO:
2343
        gen_helper_clo(cpu_gpr[rd], t0);
2344
        opn = "clo";
2345
        break;
2346
    case OPC_CLZ:
2347
        gen_helper_clz(cpu_gpr[rd], t0);
2348
        opn = "clz";
2349
        break;
2350
#if defined(TARGET_MIPS64)
2351
    case OPC_DCLO:
2352
        gen_helper_dclo(cpu_gpr[rd], t0);
2353
        opn = "dclo";
2354
        break;
2355
    case OPC_DCLZ:
2356
        gen_helper_dclz(cpu_gpr[rd], t0);
2357
        opn = "dclz";
2358
        break;
2359
#endif
2360
    }
2361
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2362
    tcg_temp_free(t0);
2363
}
2364

    
2365
/* Traps */
2366
static void gen_trap (DisasContext *ctx, uint32_t opc,
2367
                      int rs, int rt, int16_t imm)
2368
{
2369
    int cond;
2370
    TCGv t0 = tcg_temp_new();
2371
    TCGv t1 = tcg_temp_new();
2372

    
2373
    cond = 0;
2374
    /* Load needed operands */
2375
    switch (opc) {
2376
    case OPC_TEQ:
2377
    case OPC_TGE:
2378
    case OPC_TGEU:
2379
    case OPC_TLT:
2380
    case OPC_TLTU:
2381
    case OPC_TNE:
2382
        /* Compare two registers */
2383
        if (rs != rt) {
2384
            gen_load_gpr(t0, rs);
2385
            gen_load_gpr(t1, rt);
2386
            cond = 1;
2387
        }
2388
        break;
2389
    case OPC_TEQI:
2390
    case OPC_TGEI:
2391
    case OPC_TGEIU:
2392
    case OPC_TLTI:
2393
    case OPC_TLTIU:
2394
    case OPC_TNEI:
2395
        /* Compare register to immediate */
2396
        if (rs != 0 || imm != 0) {
2397
            gen_load_gpr(t0, rs);
2398
            tcg_gen_movi_tl(t1, (int32_t)imm);
2399
            cond = 1;
2400
        }
2401
        break;
2402
    }
2403
    if (cond == 0) {
2404
        switch (opc) {
2405
        case OPC_TEQ:   /* rs == rs */
2406
        case OPC_TEQI:  /* r0 == 0  */
2407
        case OPC_TGE:   /* rs >= rs */
2408
        case OPC_TGEI:  /* r0 >= 0  */
2409
        case OPC_TGEU:  /* rs >= rs unsigned */
2410
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2411
            /* Always trap */
2412
            generate_exception(ctx, EXCP_TRAP);
2413
            break;
2414
        case OPC_TLT:   /* rs < rs           */
2415
        case OPC_TLTI:  /* r0 < 0            */
2416
        case OPC_TLTU:  /* rs < rs unsigned  */
2417
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2418
        case OPC_TNE:   /* rs != rs          */
2419
        case OPC_TNEI:  /* r0 != 0           */
2420
            /* Never trap: treat as NOP. */
2421
            break;
2422
        }
2423
    } else {
2424
        int l1 = gen_new_label();
2425

    
2426
        switch (opc) {
2427
        case OPC_TEQ:
2428
        case OPC_TEQI:
2429
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2430
            break;
2431
        case OPC_TGE:
2432
        case OPC_TGEI:
2433
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2434
            break;
2435
        case OPC_TGEU:
2436
        case OPC_TGEIU:
2437
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2438
            break;
2439
        case OPC_TLT:
2440
        case OPC_TLTI:
2441
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2442
            break;
2443
        case OPC_TLTU:
2444
        case OPC_TLTIU:
2445
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2446
            break;
2447
        case OPC_TNE:
2448
        case OPC_TNEI:
2449
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2450
            break;
2451
        }
2452
        generate_exception(ctx, EXCP_TRAP);
2453
        gen_set_label(l1);
2454
    }
2455
    tcg_temp_free(t0);
2456
    tcg_temp_free(t1);
2457
}
2458

    
2459
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2460
{
2461
    TranslationBlock *tb;
2462
    tb = ctx->tb;
2463
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2464
        likely(!ctx->singlestep_enabled)) {
2465
        tcg_gen_goto_tb(n);
2466
        gen_save_pc(dest);
2467
        tcg_gen_exit_tb((long)tb + n);
2468
    } else {
2469
        gen_save_pc(dest);
2470
        if (ctx->singlestep_enabled) {
2471
            save_cpu_state(ctx, 0);
2472
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2473
        }
2474
        tcg_gen_exit_tb(0);
2475
    }
2476
}
2477

    
2478
/* Branches (before delay slot) */
2479
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2480
                                int rs, int rt, int32_t offset)
2481
{
2482
    target_ulong btgt = -1;
2483
    int blink = 0;
2484
    int bcond_compute = 0;
2485
    TCGv t0 = tcg_temp_new();
2486
    TCGv t1 = tcg_temp_new();
2487

    
2488
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2489
#ifdef MIPS_DEBUG_DISAS
2490
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2491
#endif
2492
        generate_exception(ctx, EXCP_RI);
2493
        goto out;
2494
    }
2495

    
2496
    /* Load needed operands */
2497
    switch (opc) {
2498
    case OPC_BEQ:
2499
    case OPC_BEQL:
2500
    case OPC_BNE:
2501
    case OPC_BNEL:
2502
        /* Compare two registers */
2503
        if (rs != rt) {
2504
            gen_load_gpr(t0, rs);
2505
            gen_load_gpr(t1, rt);
2506
            bcond_compute = 1;
2507
        }
2508
        btgt = ctx->pc + 4 + offset;
2509
        break;
2510
    case OPC_BGEZ:
2511
    case OPC_BGEZAL:
2512
    case OPC_BGEZALL:
2513
    case OPC_BGEZL:
2514
    case OPC_BGTZ:
2515
    case OPC_BGTZL:
2516
    case OPC_BLEZ:
2517
    case OPC_BLEZL:
2518
    case OPC_BLTZ:
2519
    case OPC_BLTZAL:
2520
    case OPC_BLTZALL:
2521
    case OPC_BLTZL:
2522
        /* Compare to zero */
2523
        if (rs != 0) {
2524
            gen_load_gpr(t0, rs);
2525
            bcond_compute = 1;
2526
        }
2527
        btgt = ctx->pc + 4 + offset;
2528
        break;
2529
    case OPC_J:
2530
    case OPC_JAL:
2531
        /* Jump to immediate */
2532
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2533
        break;
2534
    case OPC_JR:
2535
    case OPC_JALR:
2536
        /* Jump to register */
2537
        if (offset != 0 && offset != 16) {
2538
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2539
               others are reserved. */
2540
            MIPS_INVAL("jump hint");
2541
            generate_exception(ctx, EXCP_RI);
2542
            goto out;
2543
        }
2544
        gen_load_gpr(btarget, rs);
2545
        break;
2546
    default:
2547
        MIPS_INVAL("branch/jump");
2548
        generate_exception(ctx, EXCP_RI);
2549
        goto out;
2550
    }
2551
    if (bcond_compute == 0) {
2552
        /* No condition to be computed */
2553
        switch (opc) {
2554
        case OPC_BEQ:     /* rx == rx        */
2555
        case OPC_BEQL:    /* rx == rx likely */
2556
        case OPC_BGEZ:    /* 0 >= 0          */
2557
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2558
        case OPC_BLEZ:    /* 0 <= 0          */
2559
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2560
            /* Always take */
2561
            ctx->hflags |= MIPS_HFLAG_B;
2562
            MIPS_DEBUG("balways");
2563
            break;
2564
        case OPC_BGEZAL:  /* 0 >= 0          */
2565
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2566
            /* Always take and link */
2567
            blink = 31;
2568
            ctx->hflags |= MIPS_HFLAG_B;
2569
            MIPS_DEBUG("balways and link");
2570
            break;
2571
        case OPC_BNE:     /* rx != rx        */
2572
        case OPC_BGTZ:    /* 0 > 0           */
2573
        case OPC_BLTZ:    /* 0 < 0           */
2574
            /* Treat as NOP. */
2575
            MIPS_DEBUG("bnever (NOP)");
2576
            goto out;
2577
        case OPC_BLTZAL:  /* 0 < 0           */
2578
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2579
            MIPS_DEBUG("bnever and link");
2580
            goto out;
2581
        case OPC_BLTZALL: /* 0 < 0 likely */
2582
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2583
            /* Skip the instruction in the delay slot */
2584
            MIPS_DEBUG("bnever, link and skip");
2585
            ctx->pc += 4;
2586
            goto out;
2587
        case OPC_BNEL:    /* rx != rx likely */
2588
        case OPC_BGTZL:   /* 0 > 0 likely */
2589
        case OPC_BLTZL:   /* 0 < 0 likely */
2590
            /* Skip the instruction in the delay slot */
2591
            MIPS_DEBUG("bnever and skip");
2592
            ctx->pc += 4;
2593
            goto out;
2594
        case OPC_J:
2595
            ctx->hflags |= MIPS_HFLAG_B;
2596
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2597
            break;
2598
        case OPC_JAL:
2599
            blink = 31;
2600
            ctx->hflags |= MIPS_HFLAG_B;
2601
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2602
            break;
2603
        case OPC_JR:
2604
            ctx->hflags |= MIPS_HFLAG_BR;
2605
            MIPS_DEBUG("jr %s", regnames[rs]);
2606
            break;
2607
        case OPC_JALR:
2608
            blink = rt;
2609
            ctx->hflags |= MIPS_HFLAG_BR;
2610
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2611
            break;
2612
        default:
2613
            MIPS_INVAL("branch/jump");
2614
            generate_exception(ctx, EXCP_RI);
2615
            goto out;
2616
        }
2617
    } else {
2618
        switch (opc) {
2619
        case OPC_BEQ:
2620
            gen_op_eq(bcond, t0, t1);
2621
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2622
                       regnames[rs], regnames[rt], btgt);
2623
            goto not_likely;
2624
        case OPC_BEQL:
2625
            gen_op_eq(bcond, t0, t1);
2626
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2627
                       regnames[rs], regnames[rt], btgt);
2628
            goto likely;
2629
        case OPC_BNE:
2630
            gen_op_ne(bcond, t0, t1);
2631
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2632
                       regnames[rs], regnames[rt], btgt);
2633
            goto not_likely;
2634
        case OPC_BNEL:
2635
            gen_op_ne(bcond, t0, t1);
2636
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2637
                       regnames[rs], regnames[rt], btgt);
2638
            goto likely;
2639
        case OPC_BGEZ:
2640
            gen_op_gez(bcond, t0);
2641
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2642
            goto not_likely;
2643
        case OPC_BGEZL:
2644
            gen_op_gez(bcond, t0);
2645
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2646
            goto likely;
2647
        case OPC_BGEZAL:
2648
            gen_op_gez(bcond, t0);
2649
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2650
            blink = 31;
2651
            goto not_likely;
2652
        case OPC_BGEZALL:
2653
            gen_op_gez(bcond, t0);
2654
            blink = 31;
2655
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656
            goto likely;
2657
        case OPC_BGTZ:
2658
            gen_op_gtz(bcond, t0);
2659
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660
            goto not_likely;
2661
        case OPC_BGTZL:
2662
            gen_op_gtz(bcond, t0);
2663
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2664
            goto likely;
2665
        case OPC_BLEZ:
2666
            gen_op_lez(bcond, t0);
2667
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2668
            goto not_likely;
2669
        case OPC_BLEZL:
2670
            gen_op_lez(bcond, t0);
2671
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2672
            goto likely;
2673
        case OPC_BLTZ:
2674
            gen_op_ltz(bcond, t0);
2675
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676
            goto not_likely;
2677
        case OPC_BLTZL:
2678
            gen_op_ltz(bcond, t0);
2679
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2680
            goto likely;
2681
        case OPC_BLTZAL:
2682
            gen_op_ltz(bcond, t0);
2683
            blink = 31;
2684
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2685
        not_likely:
2686
            ctx->hflags |= MIPS_HFLAG_BC;
2687
            break;
2688
        case OPC_BLTZALL:
2689
            gen_op_ltz(bcond, t0);
2690
            blink = 31;
2691
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2692
        likely:
2693
            ctx->hflags |= MIPS_HFLAG_BL;
2694
            break;
2695
        default:
2696
            MIPS_INVAL("conditional branch/jump");
2697
            generate_exception(ctx, EXCP_RI);
2698
            goto out;
2699
        }
2700
    }
2701
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2702
               blink, ctx->hflags, btgt);
2703

    
2704
    ctx->btarget = btgt;
2705
    if (blink > 0) {
2706
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2707
    }
2708

    
2709
 out:
2710
    tcg_temp_free(t0);
2711
    tcg_temp_free(t1);
2712
}
2713

    
2714
/* special3 bitfield operations */
2715
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2716
                        int rs, int lsb, int msb)
2717
{
2718
    TCGv t0 = tcg_temp_new();
2719
    TCGv t1 = tcg_temp_new();
2720
    target_ulong mask;
2721

    
2722
    gen_load_gpr(t1, rs);
2723
    switch (opc) {
2724
    case OPC_EXT:
2725
        if (lsb + msb > 31)
2726
            goto fail;
2727
        tcg_gen_shri_tl(t0, t1, lsb);
2728
        if (msb != 31) {
2729
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2730
        } else {
2731
            tcg_gen_ext32s_tl(t0, t0);
2732
        }
2733
        break;
2734
#if defined(TARGET_MIPS64)
2735
    case OPC_DEXTM:
2736
        tcg_gen_shri_tl(t0, t1, lsb);
2737
        if (msb != 31) {
2738
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2739
        }
2740
        break;
2741
    case OPC_DEXTU:
2742
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2743
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2744
        break;
2745
    case OPC_DEXT:
2746
        tcg_gen_shri_tl(t0, t1, lsb);
2747
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2748
        break;
2749
#endif
2750
    case OPC_INS:
2751
        if (lsb > msb)
2752
            goto fail;
2753
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2754
        gen_load_gpr(t0, rt);
2755
        tcg_gen_andi_tl(t0, t0, ~mask);
2756
        tcg_gen_shli_tl(t1, t1, lsb);
2757
        tcg_gen_andi_tl(t1, t1, mask);
2758
        tcg_gen_or_tl(t0, t0, t1);
2759
        tcg_gen_ext32s_tl(t0, t0);
2760
        break;
2761
#if defined(TARGET_MIPS64)
2762
    case OPC_DINSM:
2763
        if (lsb > msb)
2764
            goto fail;
2765
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2766
        gen_load_gpr(t0, rt);
2767
        tcg_gen_andi_tl(t0, t0, ~mask);
2768
        tcg_gen_shli_tl(t1, t1, lsb);
2769
        tcg_gen_andi_tl(t1, t1, mask);
2770
        tcg_gen_or_tl(t0, t0, t1);
2771
        break;
2772
    case OPC_DINSU:
2773
        if (lsb > msb)
2774
            goto fail;
2775
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2776
        gen_load_gpr(t0, rt);
2777
        tcg_gen_andi_tl(t0, t0, ~mask);
2778
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2779
        tcg_gen_andi_tl(t1, t1, mask);
2780
        tcg_gen_or_tl(t0, t0, t1);
2781
        break;
2782
    case OPC_DINS:
2783
        if (lsb > msb)
2784
            goto fail;
2785
        gen_load_gpr(t0, rt);
2786
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2787
        gen_load_gpr(t0, rt);
2788
        tcg_gen_andi_tl(t0, t0, ~mask);
2789
        tcg_gen_shli_tl(t1, t1, lsb);
2790
        tcg_gen_andi_tl(t1, t1, mask);
2791
        tcg_gen_or_tl(t0, t0, t1);
2792
        break;
2793
#endif
2794
    default:
2795
fail:
2796
        MIPS_INVAL("bitops");
2797
        generate_exception(ctx, EXCP_RI);
2798
        tcg_temp_free(t0);
2799
        tcg_temp_free(t1);
2800
        return;
2801
    }
2802
    gen_store_gpr(t0, rt);
2803
    tcg_temp_free(t0);
2804
    tcg_temp_free(t1);
2805
}
2806

    
2807
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2808
{
2809
    TCGv t0;
2810

    
2811
    if (rd == 0) {
2812
        /* If no destination, treat it as a NOP. */
2813
        MIPS_DEBUG("NOP");
2814
        return;
2815
    }
2816

    
2817
    t0 = tcg_temp_new();
2818
    gen_load_gpr(t0, rt);
2819
    switch (op2) {
2820
    case OPC_WSBH:
2821
        {
2822
            TCGv t1 = tcg_temp_new();
2823

    
2824
            tcg_gen_shri_tl(t1, t0, 8);
2825
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2826
            tcg_gen_shli_tl(t0, t0, 8);
2827
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2828
            tcg_gen_or_tl(t0, t0, t1);
2829
            tcg_temp_free(t1);
2830
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2831
        }
2832
        break;
2833
    case OPC_SEB:
2834
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2835
        break;
2836
    case OPC_SEH:
2837
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2838
        break;
2839
#if defined(TARGET_MIPS64)
2840
    case OPC_DSBH:
2841
        {
2842
            TCGv t1 = tcg_temp_new();
2843

    
2844
            tcg_gen_shri_tl(t1, t0, 8);
2845
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2846
            tcg_gen_shli_tl(t0, t0, 8);
2847
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2848
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2849
            tcg_temp_free(t1);
2850
        }
2851
        break;
2852
    case OPC_DSHD:
2853
        {
2854
            TCGv t1 = tcg_temp_new();
2855

    
2856
            tcg_gen_shri_tl(t1, t0, 16);
2857
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2858
            tcg_gen_shli_tl(t0, t0, 16);
2859
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2860
            tcg_gen_or_tl(t0, t0, t1);
2861
            tcg_gen_shri_tl(t1, t0, 32);
2862
            tcg_gen_shli_tl(t0, t0, 32);
2863
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2864
            tcg_temp_free(t1);
2865
        }
2866
        break;
2867
#endif
2868
    default:
2869
        MIPS_INVAL("bsfhl");
2870
        generate_exception(ctx, EXCP_RI);
2871
        tcg_temp_free(t0);
2872
        return;
2873
    }
2874
    tcg_temp_free(t0);
2875
}
2876

    
2877
#ifndef CONFIG_USER_ONLY
2878
/* CP0 (MMU and control) */
2879
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2880
{
2881
    TCGv_i32 t0 = tcg_temp_new_i32();
2882

    
2883
    tcg_gen_ld_i32(t0, cpu_env, off);
2884
    tcg_gen_ext_i32_tl(arg, t0);
2885
    tcg_temp_free_i32(t0);
2886
}
2887

    
2888
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2889
{
2890
    tcg_gen_ld_tl(arg, cpu_env, off);
2891
    tcg_gen_ext32s_tl(arg, arg);
2892
}
2893

    
2894
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2895
{
2896
    TCGv_i32 t0 = tcg_temp_new_i32();
2897

    
2898
    tcg_gen_trunc_tl_i32(t0, arg);
2899
    tcg_gen_st_i32(t0, cpu_env, off);
2900
    tcg_temp_free_i32(t0);
2901
}
2902

    
2903
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2904
{
2905
    tcg_gen_ext32s_tl(arg, arg);
2906
    tcg_gen_st_tl(arg, cpu_env, off);
2907
}
2908

    
2909
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2910
{
2911
    const char *rn = "invalid";
2912

    
2913
    if (sel != 0)
2914
        check_insn(env, ctx, ISA_MIPS32);
2915

    
2916
    switch (reg) {
2917
    case 0:
2918
        switch (sel) {
2919
        case 0:
2920
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2921
            rn = "Index";
2922
            break;
2923
        case 1:
2924
            check_insn(env, ctx, ASE_MT);
2925
            gen_helper_mfc0_mvpcontrol(arg);
2926
            rn = "MVPControl";
2927
            break;
2928
        case 2:
2929
            check_insn(env, ctx, ASE_MT);
2930
            gen_helper_mfc0_mvpconf0(arg);
2931
            rn = "MVPConf0";
2932
            break;
2933
        case 3:
2934
            check_insn(env, ctx, ASE_MT);
2935
            gen_helper_mfc0_mvpconf1(arg);
2936
            rn = "MVPConf1";
2937
            break;
2938
        default:
2939
            goto die;
2940
        }
2941
        break;
2942
    case 1:
2943
        switch (sel) {
2944
        case 0:
2945
            gen_helper_mfc0_random(arg);
2946
            rn = "Random";
2947
            break;
2948
        case 1:
2949
            check_insn(env, ctx, ASE_MT);
2950
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2951
            rn = "VPEControl";
2952
            break;
2953
        case 2:
2954
            check_insn(env, ctx, ASE_MT);
2955
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2956
            rn = "VPEConf0";
2957
            break;
2958
        case 3:
2959
            check_insn(env, ctx, ASE_MT);
2960
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2961
            rn = "VPEConf1";
2962
            break;
2963
        case 4:
2964
            check_insn(env, ctx, ASE_MT);
2965
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2966
            rn = "YQMask";
2967
            break;
2968
        case 5:
2969
            check_insn(env, ctx, ASE_MT);
2970
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2971
            rn = "VPESchedule";
2972
            break;
2973
        case 6:
2974
            check_insn(env, ctx, ASE_MT);
2975
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2976
            rn = "VPEScheFBack";
2977
            break;
2978
        case 7:
2979
            check_insn(env, ctx, ASE_MT);
2980
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2981
            rn = "VPEOpt";
2982
            break;
2983
        default:
2984
            goto die;
2985
        }
2986
        break;
2987
    case 2:
2988
        switch (sel) {
2989
        case 0:
2990
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2991
            tcg_gen_ext32s_tl(arg, arg);
2992
            rn = "EntryLo0";
2993
            break;
2994
        case 1:
2995
            check_insn(env, ctx, ASE_MT);
2996
            gen_helper_mfc0_tcstatus(arg);
2997
            rn = "TCStatus";
2998
            break;
2999
        case 2:
3000
            check_insn(env, ctx, ASE_MT);
3001
            gen_helper_mfc0_tcbind(arg);
3002
            rn = "TCBind";
3003
            break;
3004
        case 3:
3005
            check_insn(env, ctx, ASE_MT);
3006
            gen_helper_mfc0_tcrestart(arg);
3007
            rn = "TCRestart";
3008
            break;
3009
        case 4:
3010
            check_insn(env, ctx, ASE_MT);
3011
            gen_helper_mfc0_tchalt(arg);
3012
            rn = "TCHalt";
3013
            break;
3014
        case 5:
3015
            check_insn(env, ctx, ASE_MT);
3016
            gen_helper_mfc0_tccontext(arg);
3017
            rn = "TCContext";
3018
            break;
3019
        case 6:
3020
            check_insn(env, ctx, ASE_MT);
3021
            gen_helper_mfc0_tcschedule(arg);
3022
            rn = "TCSchedule";
3023
            break;
3024
        case 7:
3025
            check_insn(env, ctx, ASE_MT);
3026
            gen_helper_mfc0_tcschefback(arg);
3027
            rn = "TCScheFBack";
3028
            break;
3029
        default:
3030
            goto die;
3031
        }
3032
        break;
3033
    case 3:
3034
        switch (sel) {
3035
        case 0:
3036
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3037
            tcg_gen_ext32s_tl(arg, arg);
3038
            rn = "EntryLo1";
3039
            break;
3040
        default:
3041
            goto die;
3042
        }
3043
        break;
3044
    case 4:
3045
        switch (sel) {
3046
        case 0:
3047
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3048
            tcg_gen_ext32s_tl(arg, arg);
3049
            rn = "Context";
3050
            break;
3051
        case 1:
3052
//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3053
            rn = "ContextConfig";
3054
//            break;
3055
        default:
3056
            goto die;
3057
        }
3058
        break;
3059
    case 5:
3060
        switch (sel) {
3061
        case 0:
3062
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3063
            rn = "PageMask";
3064
            break;
3065
        case 1:
3066
            check_insn(env, ctx, ISA_MIPS32R2);
3067
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3068
            rn = "PageGrain";
3069
            break;
3070
        default:
3071
            goto die;
3072
        }
3073
        break;
3074
    case 6:
3075
        switch (sel) {
3076
        case 0:
3077
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3078
            rn = "Wired";
3079
            break;
3080
        case 1:
3081
            check_insn(env, ctx, ISA_MIPS32R2);
3082
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3083
            rn = "SRSConf0";
3084
            break;
3085
        case 2:
3086
            check_insn(env, ctx, ISA_MIPS32R2);
3087
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3088
            rn = "SRSConf1";
3089
            break;
3090
        case 3:
3091
            check_insn(env, ctx, ISA_MIPS32R2);
3092
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3093
            rn = "SRSConf2";
3094
            break;
3095
        case 4:
3096
            check_insn(env, ctx, ISA_MIPS32R2);
3097
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3098
            rn = "SRSConf3";
3099
            break;
3100
        case 5:
3101
            check_insn(env, ctx, ISA_MIPS32R2);
3102
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3103
            rn = "SRSConf4";
3104
            break;
3105
        default:
3106
            goto die;
3107
        }
3108
        break;
3109
    case 7:
3110
        switch (sel) {
3111
        case 0:
3112
            check_insn(env, ctx, ISA_MIPS32R2);
3113
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3114
            rn = "HWREna";
3115
            break;
3116
        default:
3117
            goto die;
3118
        }
3119
        break;
3120
    case 8:
3121
        switch (sel) {
3122
        case 0:
3123
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3124
            tcg_gen_ext32s_tl(arg, arg);
3125
            rn = "BadVAddr";
3126
            break;
3127
        default:
3128
            goto die;
3129
       }
3130
        break;
3131
    case 9:
3132
        switch (sel) {
3133
        case 0:
3134
            /* Mark as an IO operation because we read the time.  */
3135
            if (use_icount)
3136
                gen_io_start();
3137
            gen_helper_mfc0_count(arg);
3138
            if (use_icount) {
3139
                gen_io_end();
3140
                ctx->bstate = BS_STOP;
3141
            }
3142
            rn = "Count";
3143
            break;
3144
        /* 6,7 are implementation dependent */
3145
        default:
3146
            goto die;
3147
        }
3148
        break;
3149
    case 10:
3150
        switch (sel) {
3151
        case 0:
3152
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3153
            tcg_gen_ext32s_tl(arg, arg);
3154
            rn = "EntryHi";
3155
            break;
3156
        default:
3157
            goto die;
3158
        }
3159
        break;
3160
    case 11:
3161
        switch (sel) {
3162
        case 0:
3163
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3164
            rn = "Compare";
3165
            break;
3166
        /* 6,7 are implementation dependent */
3167
        default:
3168
            goto die;
3169
        }
3170
        break;
3171
    case 12:
3172
        switch (sel) {
3173
        case 0:
3174
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3175
            rn = "Status";
3176
            break;
3177
        case 1:
3178
            check_insn(env, ctx, ISA_MIPS32R2);
3179
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3180
            rn = "IntCtl";
3181
            break;
3182
        case 2:
3183
            check_insn(env, ctx, ISA_MIPS32R2);
3184
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3185
            rn = "SRSCtl";
3186
            break;
3187
        case 3:
3188
            check_insn(env, ctx, ISA_MIPS32R2);
3189
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3190
            rn = "SRSMap";
3191
            break;
3192
        default:
3193
            goto die;
3194
       }
3195
        break;
3196
    case 13:
3197
        switch (sel) {
3198
        case 0:
3199
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3200
            rn = "Cause";
3201
            break;
3202
        default:
3203
            goto die;
3204
       }
3205
        break;
3206
    case 14:
3207
        switch (sel) {
3208
        case 0:
3209
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3210
            tcg_gen_ext32s_tl(arg, arg);
3211
            rn = "EPC";
3212
            break;
3213
        default:
3214
            goto die;
3215
        }
3216
        break;
3217
    case 15:
3218
        switch (sel) {
3219
        case 0:
3220
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3221
            rn = "PRid";
3222
            break;
3223
        case 1:
3224
            check_insn(env, ctx, ISA_MIPS32R2);
3225
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3226
            rn = "EBase";
3227
            break;
3228
        default:
3229
            goto die;
3230
       }
3231
        break;
3232
    case 16:
3233
        switch (sel) {
3234
        case 0:
3235
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3236
            rn = "Config";
3237
            break;
3238
        case 1:
3239
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3240
            rn = "Config1";
3241
            break;
3242
        case 2:
3243
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3244
            rn = "Config2";
3245
            break;
3246
        case 3:
3247
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3248
            rn = "Config3";
3249
            break;
3250
        /* 4,5 are reserved */
3251
        /* 6,7 are implementation dependent */
3252
        case 6:
3253
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3254
            rn = "Config6";
3255
            break;
3256
        case 7:
3257
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3258
            rn = "Config7";
3259
            break;
3260
        default:
3261
            goto die;
3262
        }
3263
        break;
3264
    case 17:
3265
        switch (sel) {
3266
        case 0:
3267
            gen_helper_mfc0_lladdr(arg);
3268
            rn = "LLAddr";
3269
            break;
3270
        default:
3271
            goto die;
3272
        }
3273
        break;
3274
    case 18:
3275
        switch (sel) {
3276
        case 0 ... 7:
3277
            gen_helper_1i(mfc0_watchlo, arg, sel);
3278
            rn = "WatchLo";
3279
            break;
3280
        default:
3281
            goto die;
3282
        }
3283
        break;
3284
    case 19:
3285
        switch (sel) {
3286
        case 0 ...7:
3287
            gen_helper_1i(mfc0_watchhi, arg, sel);
3288
            rn = "WatchHi";
3289
            break;
3290
        default:
3291
            goto die;
3292
        }
3293
        break;
3294
    case 20:
3295
        switch (sel) {
3296
        case 0:
3297
#if defined(TARGET_MIPS64)
3298
            check_insn(env, ctx, ISA_MIPS3);
3299
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3300
            tcg_gen_ext32s_tl(arg, arg);
3301
            rn = "XContext";
3302
            break;
3303
#endif
3304
        default:
3305
            goto die;
3306
        }
3307
        break;
3308
    case 21:
3309
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3310
        switch (sel) {
3311
        case 0:
3312
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3313
            rn = "Framemask";
3314
            break;
3315
        default:
3316
            goto die;
3317
        }
3318
        break;
3319
    case 22:
3320
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3321
        rn = "'Diagnostic"; /* implementation dependent */
3322
        break;
3323
    case 23:
3324
        switch (sel) {
3325
        case 0:
3326
            gen_helper_mfc0_debug(arg); /* EJTAG support */
3327
            rn = "Debug";
3328
            break;
3329
        case 1:
3330
//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3331
            rn = "TraceControl";
3332
//            break;
3333
        case 2:
3334
//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3335
            rn = "TraceControl2";
3336
//            break;
3337
        case 3:
3338
//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3339
            rn = "UserTraceData";
3340
//            break;
3341
        case 4:
3342
//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3343
            rn = "TraceBPC";
3344
//            break;
3345
        default:
3346
            goto die;
3347
        }
3348
        break;
3349
    case 24:
3350
        switch (sel) {
3351
        case 0:
3352
            /* EJTAG support */
3353
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3354
            tcg_gen_ext32s_tl(arg, arg);
3355
            rn = "DEPC";
3356
            break;
3357
        default:
3358
            goto die;
3359
        }
3360
        break;
3361
    case 25:
3362
        switch (sel) {
3363
        case 0:
3364
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3365
            rn = "Performance0";
3366
            break;
3367
        case 1:
3368
//            gen_helper_mfc0_performance1(arg);
3369
            rn = "Performance1";
3370
//            break;
3371
        case 2:
3372
//            gen_helper_mfc0_performance2(arg);
3373
            rn = "Performance2";
3374
//            break;
3375
        case 3:
3376
//            gen_helper_mfc0_performance3(arg);
3377
            rn = "Performance3";
3378
//            break;
3379
        case 4:
3380
//            gen_helper_mfc0_performance4(arg);
3381
            rn = "Performance4";
3382
//            break;
3383
        case 5:
3384
//            gen_helper_mfc0_performance5(arg);
3385
            rn = "Performance5";
3386
//            break;
3387
        case 6:
3388
//            gen_helper_mfc0_performance6(arg);
3389
            rn = "Performance6";
3390
//            break;
3391
        case 7:
3392
//            gen_helper_mfc0_performance7(arg);
3393
            rn = "Performance7";
3394
//            break;
3395
        default:
3396
            goto die;
3397
        }
3398
        break;
3399
    case 26:
3400
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3401
        rn = "ECC";
3402
        break;
3403
    case 27:
3404
        switch (sel) {
3405
        case 0 ... 3:
3406
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
3407
            rn = "CacheErr";
3408
            break;
3409
        default:
3410
            goto die;
3411
        }
3412
        break;
3413
    case 28:
3414
        switch (sel) {
3415
        case 0:
3416
        case 2:
3417
        case 4:
3418
        case 6:
3419
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3420
            rn = "TagLo";
3421
            break;
3422
        case 1:
3423
        case 3:
3424
        case 5:
3425
        case 7:
3426
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3427
            rn = "DataLo";
3428
            break;
3429
        default:
3430
            goto die;
3431
        }
3432
        break;
3433
    case 29:
3434
        switch (sel) {
3435
        case 0:
3436
        case 2:
3437
        case 4:
3438
        case 6:
3439
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3440
            rn = "TagHi";
3441
            break;
3442
        case 1:
3443
        case 3:
3444
        case 5:
3445
        case 7:
3446
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3447
            rn = "DataHi";
3448
            break;
3449
        default:
3450
            goto die;
3451
        }
3452
        break;
3453
    case 30:
3454
        switch (sel) {
3455
        case 0:
3456
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3457
            tcg_gen_ext32s_tl(arg, arg);
3458
            rn = "ErrorEPC";
3459
            break;
3460
        default:
3461
            goto die;
3462
        }
3463
        break;
3464
    case 31:
3465
        switch (sel) {
3466
        case 0:
3467
            /* EJTAG support */
3468
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3469
            rn = "DESAVE";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        break;
3475
    default:
3476
       goto die;
3477
    }
3478
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3479
    return;
3480

    
3481
die:
3482
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3483
    generate_exception(ctx, EXCP_RI);
3484
}
3485

    
3486
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3487
{
3488
    const char *rn = "invalid";
3489

    
3490
    if (sel != 0)
3491
        check_insn(env, ctx, ISA_MIPS32);
3492

    
3493
    if (use_icount)
3494
        gen_io_start();
3495

    
3496
    switch (reg) {
3497
    case 0:
3498
        switch (sel) {
3499
        case 0:
3500
            gen_helper_mtc0_index(arg);
3501
            rn = "Index";
3502
            break;
3503
        case 1:
3504
            check_insn(env, ctx, ASE_MT);
3505
            gen_helper_mtc0_mvpcontrol(arg);
3506
            rn = "MVPControl";
3507
            break;
3508
        case 2:
3509
            check_insn(env, ctx, ASE_MT);
3510
            /* ignored */
3511
            rn = "MVPConf0";
3512
            break;
3513
        case 3:
3514
            check_insn(env, ctx, ASE_MT);
3515
            /* ignored */
3516
            rn = "MVPConf1";
3517
            break;
3518
        default:
3519
            goto die;
3520
        }
3521
        break;
3522
    case 1:
3523
        switch (sel) {
3524
        case 0:
3525
            /* ignored */
3526
            rn = "Random";
3527
            break;
3528
        case 1:
3529
            check_insn(env, ctx, ASE_MT);
3530
            gen_helper_mtc0_vpecontrol(arg);
3531
            rn = "VPEControl";
3532
            break;
3533
        case 2:
3534
            check_insn(env, ctx, ASE_MT);
3535
            gen_helper_mtc0_vpeconf0(arg);
3536
            rn = "VPEConf0";
3537
            break;
3538
        case 3:
3539
            check_insn(env, ctx, ASE_MT);
3540
            gen_helper_mtc0_vpeconf1(arg);
3541
            rn = "VPEConf1";
3542
            break;
3543
        case 4:
3544
            check_insn(env, ctx, ASE_MT);
3545
            gen_helper_mtc0_yqmask(arg);
3546
            rn = "YQMask";
3547
            break;
3548
        case 5:
3549
            check_insn(env, ctx, ASE_MT);
3550
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3551
            rn = "VPESchedule";
3552
            break;
3553
        case 6:
3554
            check_insn(env, ctx, ASE_MT);
3555
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3556
            rn = "VPEScheFBack";
3557
            break;
3558
        case 7:
3559
            check_insn(env, ctx, ASE_MT);
3560
            gen_helper_mtc0_vpeopt(arg);
3561
            rn = "VPEOpt";
3562
            break;
3563
        default:
3564
            goto die;
3565
        }
3566
        break;
3567
    case 2:
3568
        switch (sel) {
3569
        case 0:
3570
            gen_helper_mtc0_entrylo0(arg);
3571
            rn = "EntryLo0";
3572
            break;
3573
        case 1:
3574
            check_insn(env, ctx, ASE_MT);
3575
            gen_helper_mtc0_tcstatus(arg);
3576
            rn = "TCStatus";
3577
            break;
3578
        case 2:
3579
            check_insn(env, ctx, ASE_MT);
3580
            gen_helper_mtc0_tcbind(arg);
3581
            rn = "TCBind";
3582
            break;
3583
        case 3:
3584
            check_insn(env, ctx, ASE_MT);
3585
            gen_helper_mtc0_tcrestart(arg);
3586
            rn = "TCRestart";
3587
            break;
3588
        case 4:
3589
            check_insn(env, ctx, ASE_MT);
3590
            gen_helper_mtc0_tchalt(arg);
3591
            rn = "TCHalt";
3592
            break;
3593
        case 5:
3594
            check_insn(env, ctx, ASE_MT);
3595
            gen_helper_mtc0_tccontext(arg);
3596
            rn = "TCContext";
3597
            break;
3598
        case 6:
3599
            check_insn(env, ctx, ASE_MT);
3600
            gen_helper_mtc0_tcschedule(arg);
3601
            rn = "TCSchedule";
3602
            break;
3603
        case 7:
3604
            check_insn(env, ctx, ASE_MT);
3605
            gen_helper_mtc0_tcschefback(arg);
3606
            rn = "TCScheFBack";
3607
            break;
3608
        default:
3609
            goto die;
3610
        }
3611
        break;
3612
    case 3:
3613
        switch (sel) {
3614
        case 0:
3615
            gen_helper_mtc0_entrylo1(arg);
3616
            rn = "EntryLo1";
3617
            break;
3618
        default:
3619
            goto die;
3620
        }
3621
        break;
3622
    case 4:
3623
        switch (sel) {
3624
        case 0:
3625
            gen_helper_mtc0_context(arg);
3626
            rn = "Context";
3627
            break;
3628
        case 1:
3629
//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3630
            rn = "ContextConfig";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 5:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_helper_mtc0_pagemask(arg);
3640
            rn = "PageMask";
3641
            break;
3642
        case 1:
3643
            check_insn(env, ctx, ISA_MIPS32R2);
3644
            gen_helper_mtc0_pagegrain(arg);
3645
            rn = "PageGrain";
3646
            break;
3647
        default:
3648
            goto die;
3649
        }
3650
        break;
3651
    case 6:
3652
        switch (sel) {
3653
        case 0:
3654
            gen_helper_mtc0_wired(arg);
3655
            rn = "Wired";
3656
            break;
3657
        case 1:
3658
            check_insn(env, ctx, ISA_MIPS32R2);
3659
            gen_helper_mtc0_srsconf0(arg);
3660
            rn = "SRSConf0";
3661
            break;
3662
        case 2:
3663
            check_insn(env, ctx, ISA_MIPS32R2);
3664
            gen_helper_mtc0_srsconf1(arg);
3665
            rn = "SRSConf1";
3666
            break;
3667
        case 3:
3668
            check_insn(env, ctx, ISA_MIPS32R2);
3669
            gen_helper_mtc0_srsconf2(arg);
3670
            rn = "SRSConf2";
3671
            break;
3672
        case 4:
3673
            check_insn(env, ctx, ISA_MIPS32R2);
3674
            gen_helper_mtc0_srsconf3(arg);
3675
            rn = "SRSConf3";
3676
            break;
3677
        case 5:
3678
            check_insn(env, ctx, ISA_MIPS32R2);
3679
            gen_helper_mtc0_srsconf4(arg);
3680
            rn = "SRSConf4";
3681
            break;
3682
        default:
3683
            goto die;
3684
        }
3685
        break;
3686
    case 7:
3687
        switch (sel) {
3688
        case 0:
3689
            check_insn(env, ctx, ISA_MIPS32R2);
3690
            gen_helper_mtc0_hwrena(arg);
3691
            rn = "HWREna";
3692
            break;
3693
        default:
3694
            goto die;
3695
        }
3696
        break;
3697
    case 8:
3698
        /* ignored */
3699
        rn = "BadVAddr";
3700
        break;
3701
    case 9:
3702
        switch (sel) {
3703
        case 0:
3704
            gen_helper_mtc0_count(arg);
3705
            rn = "Count";
3706
            break;
3707
        /* 6,7 are implementation dependent */
3708
        default:
3709
            goto die;
3710
        }
3711
        break;
3712
    case 10:
3713
        switch (sel) {
3714
        case 0:
3715
            gen_helper_mtc0_entryhi(arg);
3716
            rn = "EntryHi";
3717
            break;
3718
        default:
3719
            goto die;
3720
        }
3721
        break;
3722
    case 11:
3723
        switch (sel) {
3724
        case 0:
3725
            gen_helper_mtc0_compare(arg);
3726
            rn = "Compare";
3727
            break;
3728
        /* 6,7 are implementation dependent */
3729
        default:
3730
            goto die;
3731
        }
3732
        break;
3733
    case 12:
3734
        switch (sel) {
3735
        case 0:
3736
            save_cpu_state(ctx, 1);
3737
            gen_helper_mtc0_status(arg);
3738
            /* BS_STOP isn't good enough here, hflags may have changed. */
3739
            gen_save_pc(ctx->pc + 4);
3740
            ctx->bstate = BS_EXCP;
3741
            rn = "Status";
3742
            break;
3743
        case 1:
3744
            check_insn(env, ctx, ISA_MIPS32R2);
3745
            gen_helper_mtc0_intctl(arg);
3746
            /* Stop translation as we may have switched the execution mode */
3747
            ctx->bstate = BS_STOP;
3748
            rn = "IntCtl";
3749
            break;
3750
        case 2:
3751
            check_insn(env, ctx, ISA_MIPS32R2);
3752
            gen_helper_mtc0_srsctl(arg);
3753
            /* Stop translation as we may have switched the execution mode */
3754
            ctx->bstate = BS_STOP;
3755
            rn = "SRSCtl";
3756
            break;
3757
        case 3:
3758
            check_insn(env, ctx, ISA_MIPS32R2);
3759
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3760
            /* Stop translation as we may have switched the execution mode */
3761
            ctx->bstate = BS_STOP;
3762
            rn = "SRSMap";
3763
            break;
3764
        default:
3765
            goto die;
3766
        }
3767
        break;
3768
    case 13:
3769
        switch (sel) {
3770
        case 0:
3771
            save_cpu_state(ctx, 1);
3772
            gen_helper_mtc0_cause(arg);
3773
            rn = "Cause";
3774
            break;
3775
        default:
3776
            goto die;
3777
        }
3778
        break;
3779
    case 14:
3780
        switch (sel) {
3781
        case 0:
3782
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3783
            rn = "EPC";
3784
            break;
3785
        default:
3786
            goto die;
3787
        }
3788
        break;
3789
    case 15:
3790
        switch (sel) {
3791
        case 0:
3792
            /* ignored */
3793
            rn = "PRid";
3794
            break;
3795
        case 1:
3796
            check_insn(env, ctx, ISA_MIPS32R2);
3797
            gen_helper_mtc0_ebase(arg);
3798
            rn = "EBase";
3799
            break;
3800
        default:
3801
            goto die;
3802
        }
3803
        break;
3804
    case 16:
3805
        switch (sel) {
3806
        case 0:
3807
            gen_helper_mtc0_config0(arg);
3808
            rn = "Config";
3809
            /* Stop translation as we may have switched the execution mode */
3810
            ctx->bstate = BS_STOP;
3811
            break;
3812
        case 1:
3813
            /* ignored, read only */
3814
            rn = "Config1";
3815
            break;
3816
        case 2:
3817
            gen_helper_mtc0_config2(arg);
3818
            rn = "Config2";
3819
            /* Stop translation as we may have switched the execution mode */
3820
            ctx->bstate = BS_STOP;
3821
            break;
3822
        case 3:
3823
            /* ignored, read only */
3824
            rn = "Config3";
3825
            break;
3826
        /* 4,5 are reserved */
3827
        /* 6,7 are implementation dependent */
3828
        case 6:
3829
            /* ignored */
3830
            rn = "Config6";
3831
            break;
3832
        case 7:
3833
            /* ignored */
3834
            rn = "Config7";
3835
            break;
3836
        default:
3837
            rn = "Invalid config selector";
3838
            goto die;
3839
        }
3840
        break;
3841
    case 17:
3842
        switch (sel) {
3843
        case 0:
3844
            /* ignored */
3845
            rn = "LLAddr";
3846
            break;
3847
        default:
3848
            goto die;
3849
        }
3850
        break;
3851
    case 18:
3852
        switch (sel) {
3853
        case 0 ... 7:
3854
            gen_helper_1i(mtc0_watchlo, arg, sel);
3855
            rn = "WatchLo";
3856
            break;
3857
        default:
3858
            goto die;
3859
        }
3860
        break;
3861
    case 19:
3862
        switch (sel) {
3863
        case 0 ... 7:
3864
            gen_helper_1i(mtc0_watchhi, arg, sel);
3865
            rn = "WatchHi";
3866
            break;
3867
        default:
3868
            goto die;
3869
        }
3870
        break;
3871
    case 20:
3872
        switch (sel) {
3873
        case 0:
3874
#if defined(TARGET_MIPS64)
3875
            check_insn(env, ctx, ISA_MIPS3);
3876
            gen_helper_mtc0_xcontext(arg);
3877
            rn = "XContext";
3878
            break;
3879
#endif
3880
        default:
3881
            goto die;
3882
        }
3883
        break;
3884
    case 21:
3885
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3886
        switch (sel) {
3887
        case 0:
3888
            gen_helper_mtc0_framemask(arg);
3889
            rn = "Framemask";
3890
            break;
3891
        default:
3892
            goto die;
3893
        }
3894
        break;
3895
    case 22:
3896
        /* ignored */
3897
        rn = "Diagnostic"; /* implementation dependent */
3898
        break;
3899
    case 23:
3900
        switch (sel) {
3901
        case 0:
3902
            gen_helper_mtc0_debug(arg); /* EJTAG support */
3903
            /* BS_STOP isn't good enough here, hflags may have changed. */
3904
            gen_save_pc(ctx->pc + 4);
3905
            ctx->bstate = BS_EXCP;
3906
            rn = "Debug";
3907
            break;
3908
        case 1:
3909
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3910
            rn = "TraceControl";
3911
            /* Stop translation as we may have switched the execution mode */
3912
            ctx->bstate = BS_STOP;
3913
//            break;
3914
        case 2:
3915
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3916
            rn = "TraceControl2";
3917
            /* Stop translation as we may have switched the execution mode */
3918
            ctx->bstate = BS_STOP;
3919
//            break;
3920
        case 3:
3921
            /* Stop translation as we may have switched the execution mode */
3922
            ctx->bstate = BS_STOP;
3923
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3924
            rn = "UserTraceData";
3925
            /* Stop translation as we may have switched the execution mode */
3926
            ctx->bstate = BS_STOP;
3927
//            break;
3928
        case 4:
3929
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3930
            /* Stop translation as we may have switched the execution mode */
3931
            ctx->bstate = BS_STOP;
3932
            rn = "TraceBPC";
3933
//            break;
3934
        default:
3935
            goto die;
3936
        }
3937
        break;
3938
    case 24:
3939
        switch (sel) {
3940
        case 0:
3941
            /* EJTAG support */
3942
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3943
            rn = "DEPC";
3944
            break;
3945
        default:
3946
            goto die;
3947
        }
3948
        break;
3949
    case 25:
3950
        switch (sel) {
3951
        case 0:
3952
            gen_helper_mtc0_performance0(arg);
3953
            rn = "Performance0";
3954
            break;
3955
        case 1:
3956
//            gen_helper_mtc0_performance1(arg);
3957
            rn = "Performance1";
3958
//            break;
3959
        case 2:
3960
//            gen_helper_mtc0_performance2(arg);
3961
            rn = "Performance2";
3962
//            break;
3963
        case 3:
3964
//            gen_helper_mtc0_performance3(arg);
3965
            rn = "Performance3";
3966
//            break;
3967
        case 4:
3968
//            gen_helper_mtc0_performance4(arg);
3969
            rn = "Performance4";
3970
//            break;
3971
        case 5:
3972
//            gen_helper_mtc0_performance5(arg);
3973
            rn = "Performance5";
3974
//            break;
3975
        case 6:
3976
//            gen_helper_mtc0_performance6(arg);
3977
            rn = "Performance6";
3978
//            break;
3979
        case 7:
3980
//            gen_helper_mtc0_performance7(arg);
3981
            rn = "Performance7";
3982
//            break;
3983
        default:
3984
            goto die;
3985
        }
3986
       break;
3987
    case 26:
3988
        /* ignored */
3989
        rn = "ECC";
3990
        break;
3991
    case 27:
3992
        switch (sel) {
3993
        case 0 ... 3:
3994
            /* ignored */
3995
            rn = "CacheErr";
3996
            break;
3997
        default:
3998
            goto die;
3999
        }
4000
       break;
4001
    case 28:
4002
        switch (sel) {
4003
        case 0:
4004
        case 2:
4005
        case 4:
4006
        case 6:
4007
            gen_helper_mtc0_taglo(arg);
4008
            rn = "TagLo";
4009
            break;
4010
        case 1:
4011
        case 3:
4012
        case 5:
4013
        case 7:
4014
            gen_helper_mtc0_datalo(arg);
4015
            rn = "DataLo";
4016
            break;
4017
        default:
4018
            goto die;
4019
        }
4020
        break;
4021
    case 29:
4022
        switch (sel) {
4023
        case 0:
4024
        case 2:
4025
        case 4:
4026
        case 6:
4027
            gen_helper_mtc0_taghi(arg);
4028
            rn = "TagHi";
4029
            break;
4030
        case 1:
4031
        case 3:
4032
        case 5:
4033
        case 7:
4034
            gen_helper_mtc0_datahi(arg);
4035
            rn = "DataHi";
4036
            break;
4037
        default:
4038
            rn = "invalid sel";
4039
            goto die;
4040
        }
4041
       break;
4042
    case 30:
4043
        switch (sel) {
4044
        case 0:
4045
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4046
            rn = "ErrorEPC";
4047
            break;
4048
        default:
4049
            goto die;
4050
        }
4051
        break;
4052
    case 31:
4053
        switch (sel) {
4054
        case 0:
4055
            /* EJTAG support */
4056
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4057
            rn = "DESAVE";
4058
            break;
4059
        default:
4060
            goto die;
4061
        }
4062
        /* Stop translation as we may have switched the execution mode */
4063
        ctx->bstate = BS_STOP;
4064
        break;
4065
    default:
4066
       goto die;
4067
    }
4068
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4069
    /* For simplicity assume that all writes can cause interrupts.  */
4070
    if (use_icount) {
4071
        gen_io_end();
4072
        ctx->bstate = BS_STOP;
4073
    }
4074
    return;
4075

    
4076
die:
4077
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4078
    generate_exception(ctx, EXCP_RI);
4079
}
4080

    
4081
#if defined(TARGET_MIPS64)
4082
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4083
{
4084
    const char *rn = "invalid";
4085

    
4086
    if (sel != 0)
4087
        check_insn(env, ctx, ISA_MIPS64);
4088

    
4089
    switch (reg) {
4090
    case 0:
4091
        switch (sel) {
4092
        case 0:
4093
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4094
            rn = "Index";
4095
            break;
4096
        case 1:
4097
            check_insn(env, ctx, ASE_MT);
4098
            gen_helper_mfc0_mvpcontrol(arg);
4099
            rn = "MVPControl";
4100
            break;
4101
        case 2:
4102
            check_insn(env, ctx, ASE_MT);
4103
            gen_helper_mfc0_mvpconf0(arg);
4104
            rn = "MVPConf0";
4105
            break;
4106
        case 3:
4107
            check_insn(env, ctx, ASE_MT);
4108
            gen_helper_mfc0_mvpconf1(arg);
4109
            rn = "MVPConf1";
4110
            break;
4111
        default:
4112
            goto die;
4113
        }
4114
        break;
4115
    case 1:
4116
        switch (sel) {
4117
        case 0:
4118
            gen_helper_mfc0_random(arg);
4119
            rn = "Random";
4120
            break;
4121
        case 1:
4122
            check_insn(env, ctx, ASE_MT);
4123
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4124
            rn = "VPEControl";
4125
            break;
4126
        case 2:
4127
            check_insn(env, ctx, ASE_MT);
4128
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4129
            rn = "VPEConf0";
4130
            break;
4131
        case 3:
4132
            check_insn(env, ctx, ASE_MT);
4133
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4134
            rn = "VPEConf1";
4135
            break;
4136
        case 4:
4137
            check_insn(env, ctx, ASE_MT);
4138
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4139
            rn = "YQMask";
4140
            break;
4141
        case 5:
4142
            check_insn(env, ctx, ASE_MT);
4143
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4144
            rn = "VPESchedule";
4145
            break;
4146
        case 6:
4147
            check_insn(env, ctx, ASE_MT);
4148
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4149
            rn = "VPEScheFBack";
4150
            break;
4151
        case 7:
4152
            check_insn(env, ctx, ASE_MT);
4153
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4154
            rn = "VPEOpt";
4155
            break;
4156
        default:
4157
            goto die;
4158
        }
4159
        break;
4160
    case 2:
4161
        switch (sel) {
4162
        case 0:
4163
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4164
            rn = "EntryLo0";
4165
            break;
4166
        case 1:
4167
            check_insn(env, ctx, ASE_MT);
4168
            gen_helper_mfc0_tcstatus(arg);
4169
            rn = "TCStatus";
4170
            break;
4171
        case 2:
4172
            check_insn(env, ctx, ASE_MT);
4173
            gen_helper_mfc0_tcbind(arg);
4174
            rn = "TCBind";
4175
            break;
4176
        case 3:
4177
            check_insn(env, ctx, ASE_MT);
4178
            gen_helper_dmfc0_tcrestart(arg);
4179
            rn = "TCRestart";
4180
            break;
4181
        case 4:
4182
            check_insn(env, ctx, ASE_MT);
4183
            gen_helper_dmfc0_tchalt(arg);
4184
            rn = "TCHalt";
4185
            break;
4186
        case 5:
4187
            check_insn(env, ctx, ASE_MT);
4188
            gen_helper_dmfc0_tccontext(arg);
4189
            rn = "TCContext";
4190
            break;
4191
        case 6:
4192
            check_insn(env, ctx, ASE_MT);
4193
            gen_helper_dmfc0_tcschedule(arg);
4194
            rn = "TCSchedule";
4195
            break;
4196
        case 7:
4197
            check_insn(env, ctx, ASE_MT);
4198
            gen_helper_dmfc0_tcschefback(arg);
4199
            rn = "TCScheFBack";
4200
            break;
4201
        default:
4202
            goto die;
4203
        }
4204
        break;
4205
    case 3:
4206
        switch (sel) {
4207
        case 0:
4208
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4209
            rn = "EntryLo1";
4210
            break;
4211
        default:
4212
            goto die;
4213
        }
4214
        break;
4215
    case 4:
4216
        switch (sel) {
4217
        case 0:
4218
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4219
            rn = "Context";
4220
            break;
4221
        case 1:
4222
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4223
            rn = "ContextConfig";
4224
//            break;
4225
        default:
4226
            goto die;
4227
        }
4228
        break;
4229
    case 5:
4230
        switch (sel) {
4231
        case 0:
4232
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4233
            rn = "PageMask";
4234
            break;
4235
        case 1:
4236
            check_insn(env, ctx, ISA_MIPS32R2);
4237
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4238
            rn = "PageGrain";
4239
            break;
4240
        default:
4241
            goto die;
4242
        }
4243
        break;
4244
    case 6:
4245
        switch (sel) {
4246
        case 0:
4247
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4248
            rn = "Wired";
4249
            break;
4250
        case 1:
4251
            check_insn(env, ctx, ISA_MIPS32R2);
4252
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4253
            rn = "SRSConf0";
4254
            break;
4255
        case 2:
4256
            check_insn(env, ctx, ISA_MIPS32R2);
4257
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4258
            rn = "SRSConf1";
4259
            break;
4260
        case 3:
4261
            check_insn(env, ctx, ISA_MIPS32R2);
4262
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4263
            rn = "SRSConf2";
4264
            break;
4265
        case 4:
4266
            check_insn(env, ctx, ISA_MIPS32R2);
4267
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4268
            rn = "SRSConf3";
4269
            break;
4270
        case 5:
4271
            check_insn(env, ctx, ISA_MIPS32R2);
4272
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4273
            rn = "SRSConf4";
4274
            break;
4275
        default:
4276
            goto die;
4277
        }
4278
        break;
4279
    case 7:
4280
        switch (sel) {
4281
        case 0:
4282
            check_insn(env, ctx, ISA_MIPS32R2);
4283
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4284
            rn = "HWREna";
4285
            break;
4286
        default:
4287
            goto die;
4288
        }
4289
        break;
4290
    case 8:
4291
        switch (sel) {
4292
        case 0:
4293
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4294
            rn = "BadVAddr";
4295
            break;
4296
        default:
4297
            goto die;
4298
        }
4299
        break;
4300
    case 9:
4301
        switch (sel) {
4302
        case 0:
4303
            /* Mark as an IO operation because we read the time.  */
4304
            if (use_icount)
4305
                gen_io_start();
4306
            gen_helper_mfc0_count(arg);
4307
            if (use_icount) {
4308
                gen_io_end();
4309
                ctx->bstate = BS_STOP;
4310
            }
4311
            rn = "Count";
4312
            break;
4313
        /* 6,7 are implementation dependent */
4314
        default:
4315
            goto die;
4316
        }
4317
        break;
4318
    case 10:
4319
        switch (sel) {
4320
        case 0:
4321
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4322
            rn = "EntryHi";
4323
            break;
4324
        default:
4325
            goto die;
4326
        }
4327
        break;
4328
    case 11:
4329
        switch (sel) {
4330
        case 0:
4331
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4332
            rn = "Compare";
4333
            break;
4334
        /* 6,7 are implementation dependent */
4335
        default:
4336
            goto die;
4337
        }
4338
        break;
4339
    case 12:
4340
        switch (sel) {
4341
        case 0:
4342
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4343
            rn = "Status";
4344
            break;
4345
        case 1:
4346
            check_insn(env, ctx, ISA_MIPS32R2);
4347
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4348
            rn = "IntCtl";
4349
            break;
4350
        case 2:
4351
            check_insn(env, ctx, ISA_MIPS32R2);
4352
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4353
            rn = "SRSCtl";
4354
            break;
4355
        case 3:
4356
            check_insn(env, ctx, ISA_MIPS32R2);
4357
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4358
            rn = "SRSMap";
4359
            break;
4360
        default:
4361
            goto die;
4362
        }
4363
        break;
4364
    case 13:
4365
        switch (sel) {
4366
        case 0:
4367
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4368
            rn = "Cause";
4369
            break;
4370
        default:
4371
            goto die;
4372
        }
4373
        break;
4374
    case 14:
4375
        switch (sel) {
4376
        case 0:
4377
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4378
            rn = "EPC";
4379
            break;
4380
        default:
4381
            goto die;
4382
        }
4383
        break;
4384
    case 15:
4385
        switch (sel) {
4386
        case 0:
4387
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4388
            rn = "PRid";
4389
            break;
4390
        case 1:
4391
            check_insn(env, ctx, ISA_MIPS32R2);
4392
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4393
            rn = "EBase";
4394
            break;
4395
        default:
4396
            goto die;
4397
        }
4398
        break;
4399
    case 16:
4400
        switch (sel) {
4401
        case 0:
4402
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4403
            rn = "Config";
4404
            break;
4405
        case 1:
4406
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4407
            rn = "Config1";
4408
            break;
4409
        case 2:
4410
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4411
            rn = "Config2";
4412
            break;
4413
        case 3:
4414
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4415
            rn = "Config3";
4416
            break;
4417
       /* 6,7 are implementation dependent */
4418
        case 6:
4419
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4420
            rn = "Config6";
4421
            break;
4422
        case 7:
4423
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4424
            rn = "Config7";
4425
            break;
4426
        default:
4427
            goto die;
4428
        }
4429
        break;
4430
    case 17:
4431
        switch (sel) {
4432
        case 0:
4433
            gen_helper_dmfc0_lladdr(arg);
4434
            rn = "LLAddr";
4435
            break;
4436
        default:
4437
            goto die;
4438
        }
4439
        break;
4440
    case 18:
4441
        switch (sel) {
4442
        case 0 ... 7:
4443
            gen_helper_1i(dmfc0_watchlo, arg, sel);
4444
            rn = "WatchLo";
4445
            break;
4446
        default:
4447
            goto die;
4448
        }
4449
        break;
4450
    case 19:
4451
        switch (sel) {
4452
        case 0 ... 7:
4453
            gen_helper_1i(mfc0_watchhi, arg, sel);
4454
            rn = "WatchHi";
4455
            break;
4456
        default:
4457
            goto die;
4458
        }
4459
        break;
4460
    case 20:
4461
        switch (sel) {
4462
        case 0:
4463
            check_insn(env, ctx, ISA_MIPS3);
4464
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4465
            rn = "XContext";
4466
            break;
4467
        default:
4468
            goto die;
4469
        }
4470
        break;
4471
    case 21:
4472
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4473
        switch (sel) {
4474
        case 0:
4475
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4476
            rn = "Framemask";
4477
            break;
4478
        default:
4479
            goto die;
4480
        }
4481
        break;
4482
    case 22:
4483
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4484
        rn = "'Diagnostic"; /* implementation dependent */
4485
        break;
4486
    case 23:
4487
        switch (sel) {
4488
        case 0:
4489
            gen_helper_mfc0_debug(arg); /* EJTAG support */
4490
            rn = "Debug";
4491
            break;
4492
        case 1:
4493
//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4494
            rn = "TraceControl";
4495
//            break;
4496
        case 2:
4497
//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4498
            rn = "TraceControl2";
4499
//            break;
4500
        case 3:
4501
//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4502
            rn = "UserTraceData";
4503
//            break;
4504
        case 4:
4505
//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4506
            rn = "TraceBPC";
4507
//            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    case 24:
4513
        switch (sel) {
4514
        case 0:
4515
            /* EJTAG support */
4516
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4517
            rn = "DEPC";
4518
            break;
4519
        default:
4520
            goto die;
4521
        }
4522
        break;
4523
    case 25:
4524
        switch (sel) {
4525
        case 0:
4526
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4527
            rn = "Performance0";
4528
            break;
4529
        case 1:
4530
//            gen_helper_dmfc0_performance1(arg);
4531
            rn = "Performance1";
4532
//            break;
4533
        case 2:
4534
//            gen_helper_dmfc0_performance2(arg);
4535
            rn = "Performance2";
4536
//            break;
4537
        case 3:
4538
//            gen_helper_dmfc0_performance3(arg);
4539
            rn = "Performance3";
4540
//            break;
4541
        case 4:
4542
//            gen_helper_dmfc0_performance4(arg);
4543
            rn = "Performance4";
4544
//            break;
4545
        case 5:
4546
//            gen_helper_dmfc0_performance5(arg);
4547
            rn = "Performance5";
4548
//            break;
4549
        case 6:
4550
//            gen_helper_dmfc0_performance6(arg);
4551
            rn = "Performance6";
4552
//            break;
4553
        case 7:
4554
//            gen_helper_dmfc0_performance7(arg);
4555
            rn = "Performance7";
4556
//            break;
4557
        default:
4558
            goto die;
4559
        }
4560
        break;
4561
    case 26:
4562
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4563
        rn = "ECC";
4564
        break;
4565
    case 27:
4566
        switch (sel) {
4567
        /* ignored */
4568
        case 0 ... 3:
4569
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4570
            rn = "CacheErr";
4571
            break;
4572
        default:
4573
            goto die;
4574
        }
4575
        break;
4576
    case 28:
4577
        switch (sel) {
4578
        case 0:
4579
        case 2:
4580
        case 4:
4581
        case 6:
4582
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4583
            rn = "TagLo";
4584
            break;
4585
        case 1:
4586
        case 3:
4587
        case 5:
4588
        case 7:
4589
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4590
            rn = "DataLo";
4591
            break;
4592
        default:
4593
            goto die;
4594
        }
4595
        break;
4596
    case 29:
4597
        switch (sel) {
4598
        case 0:
4599
        case 2:
4600
        case 4:
4601
        case 6:
4602
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4603
            rn = "TagHi";
4604
            break;
4605
        case 1:
4606
        case 3:
4607
        case 5:
4608
        case 7:
4609
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4610
            rn = "DataHi";
4611
            break;
4612
        default:
4613
            goto die;
4614
        }
4615
        break;
4616
    case 30:
4617
        switch (sel) {
4618
        case 0:
4619
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4620
            rn = "ErrorEPC";
4621
            break;
4622
        default:
4623
            goto die;
4624
        }
4625
        break;
4626
    case 31:
4627
        switch (sel) {
4628
        case 0:
4629
            /* EJTAG support */
4630
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4631
            rn = "DESAVE";
4632
            break;
4633
        default:
4634
            goto die;
4635
        }
4636
        break;
4637
    default:
4638
        goto die;
4639
    }
4640
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4641
    return;
4642

    
4643
die:
4644
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4645
    generate_exception(ctx, EXCP_RI);
4646
}
4647

    
4648
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4649
{
4650
    const char *rn = "invalid";
4651

    
4652
    if (sel != 0)
4653
        check_insn(env, ctx, ISA_MIPS64);
4654

    
4655
    if (use_icount)
4656
        gen_io_start();
4657

    
4658
    switch (reg) {
4659
    case 0:
4660
        switch (sel) {
4661
        case 0:
4662
            gen_helper_mtc0_index(arg);
4663
            rn = "Index";
4664
            break;
4665
        case 1:
4666
            check_insn(env, ctx, ASE_MT);
4667
            gen_helper_mtc0_mvpcontrol(arg);
4668
            rn = "MVPControl";
4669
            break;
4670
        case 2:
4671
            check_insn(env, ctx, ASE_MT);
4672
            /* ignored */
4673
            rn = "MVPConf0";
4674
            break;
4675
        case 3:
4676
            check_insn(env, ctx, ASE_MT);
4677
            /* ignored */
4678
            rn = "MVPConf1";
4679
            break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    case 1:
4685
        switch (sel) {
4686
        case 0:
4687
            /* ignored */
4688
            rn = "Random";
4689
            break;
4690
        case 1:
4691
            check_insn(env, ctx, ASE_MT);
4692
            gen_helper_mtc0_vpecontrol(arg);
4693
            rn = "VPEControl";
4694
            break;
4695
        case 2:
4696
            check_insn(env, ctx, ASE_MT);
4697
            gen_helper_mtc0_vpeconf0(arg);
4698
            rn = "VPEConf0";
4699
            break;
4700
        case 3:
4701
            check_insn(env, ctx, ASE_MT);
4702
            gen_helper_mtc0_vpeconf1(arg);
4703
            rn = "VPEConf1";
4704
            break;
4705
        case 4:
4706
            check_insn(env, ctx, ASE_MT);
4707
            gen_helper_mtc0_yqmask(arg);
4708
            rn = "YQMask";
4709
            break;
4710
        case 5:
4711
            check_insn(env, ctx, ASE_MT);
4712
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4713
            rn = "VPESchedule";
4714
            break;
4715
        case 6:
4716
            check_insn(env, ctx, ASE_MT);
4717
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4718
            rn = "VPEScheFBack";
4719
            break;
4720
        case 7:
4721
            check_insn(env, ctx, ASE_MT);
4722
            gen_helper_mtc0_vpeopt(arg);
4723
            rn = "VPEOpt";
4724
            break;
4725
        default:
4726
            goto die;
4727
        }
4728
        break;
4729
    case 2:
4730
        switch (sel) {
4731
        case 0:
4732
            gen_helper_mtc0_entrylo0(arg);
4733
            rn = "EntryLo0";
4734
            break;
4735
        case 1:
4736
            check_insn(env, ctx, ASE_MT);
4737
            gen_helper_mtc0_tcstatus(arg);
4738
            rn = "TCStatus";
4739
            break;
4740
        case 2:
4741
            check_insn(env, ctx, ASE_MT);
4742
            gen_helper_mtc0_tcbind(arg);
4743
            rn = "TCBind";
4744
            break;
4745
        case 3:
4746
            check_insn(env, ctx, ASE_MT);
4747
            gen_helper_mtc0_tcrestart(arg);
4748
            rn = "TCRestart";
4749
            break;
4750
        case 4:
4751
            check_insn(env, ctx, ASE_MT);
4752
            gen_helper_mtc0_tchalt(arg);
4753
            rn = "TCHalt";
4754
            break;
4755
        case 5:
4756
            check_insn(env, ctx, ASE_MT);
4757
            gen_helper_mtc0_tccontext(arg);
4758
            rn = "TCContext";
4759
            break;
4760
        case 6:
4761
            check_insn(env, ctx, ASE_MT);
4762
            gen_helper_mtc0_tcschedule(arg);
4763
            rn = "TCSchedule";
4764
            break;
4765
        case 7:
4766
            check_insn(env, ctx, ASE_MT);
4767
            gen_helper_mtc0_tcschefback(arg);
4768
            rn = "TCScheFBack";
4769
            break;
4770
        default:
4771
            goto die;
4772
        }
4773
        break;
4774
    case 3:
4775
        switch (sel) {
4776
        case 0:
4777
            gen_helper_mtc0_entrylo1(arg);
4778
            rn = "EntryLo1";
4779
            break;
4780
        default:
4781
            goto die;
4782
        }
4783
        break;
4784
    case 4:
4785
        switch (sel) {
4786
        case 0:
4787
            gen_helper_mtc0_context(arg);
4788
            rn = "Context";
4789
            break;
4790
        case 1:
4791
//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4792
            rn = "ContextConfig";
4793
//           break;
4794
        default:
4795
            goto die;
4796
        }
4797
        break;
4798
    case 5:
4799
        switch (sel) {
4800
        case 0:
4801
            gen_helper_mtc0_pagemask(arg);
4802
            rn = "PageMask";
4803
            break;
4804
        case 1:
4805
            check_insn(env, ctx, ISA_MIPS32R2);
4806
            gen_helper_mtc0_pagegrain(arg);
4807
            rn = "PageGrain";
4808
            break;
4809
        default:
4810
            goto die;
4811
        }
4812
        break;
4813
    case 6:
4814
        switch (sel) {
4815
        case 0:
4816
            gen_helper_mtc0_wired(arg);
4817
            rn = "Wired";
4818
            break;
4819
        case 1:
4820
            check_insn(env, ctx, ISA_MIPS32R2);
4821
            gen_helper_mtc0_srsconf0(arg);
4822
            rn = "SRSConf0";
4823
            break;
4824
        case 2:
4825
            check_insn(env, ctx, ISA_MIPS32R2);
4826
            gen_helper_mtc0_srsconf1(arg);
4827
            rn = "SRSConf1";
4828
            break;
4829
        case 3:
4830
            check_insn(env, ctx, ISA_MIPS32R2);
4831
            gen_helper_mtc0_srsconf2(arg);
4832
            rn = "SRSConf2";
4833
            break;
4834
        case 4:
4835
            check_insn(env, ctx, ISA_MIPS32R2);
4836
            gen_helper_mtc0_srsconf3(arg);
4837
            rn = "SRSConf3";
4838
            break;
4839
        case 5:
4840
            check_insn(env, ctx, ISA_MIPS32R2);
4841
            gen_helper_mtc0_srsconf4(arg);
4842
            rn = "SRSConf4";
4843
            break;
4844
        default:
4845
            goto die;
4846
        }
4847
        break;
4848
    case 7:
4849
        switch (sel) {
4850
        case 0:
4851
            check_insn(env, ctx, ISA_MIPS32R2);
4852
            gen_helper_mtc0_hwrena(arg);
4853
            rn = "HWREna";
4854
            break;
4855
        default:
4856
            goto die;
4857
        }
4858
        break;
4859
    case 8:
4860
        /* ignored */
4861
        rn = "BadVAddr";
4862
        break;
4863
    case 9:
4864
        switch (sel) {
4865
        case 0:
4866
            gen_helper_mtc0_count(arg);
4867
            rn = "Count";
4868
            break;
4869
        /* 6,7 are implementation dependent */
4870
        default:
4871
            goto die;
4872
        }
4873
        /* Stop translation as we may have switched the execution mode */
4874
        ctx->bstate = BS_STOP;
4875
        break;
4876
    case 10:
4877
        switch (sel) {
4878
        case 0:
4879
            gen_helper_mtc0_entryhi(arg);
4880
            rn = "EntryHi";
4881
            break;
4882
        default:
4883
            goto die;
4884
        }
4885
        break;
4886
    case 11:
4887
        switch (sel) {
4888
        case 0:
4889
            gen_helper_mtc0_compare(arg);
4890
            rn = "Compare";
4891
            break;
4892
        /* 6,7 are implementation dependent */
4893
        default:
4894
            goto die;
4895
        }
4896
        /* Stop translation as we may have switched the execution mode */
4897
        ctx->bstate = BS_STOP;
4898
        break;
4899
    case 12:
4900
        switch (sel) {
4901
        case 0:
4902
            save_cpu_state(ctx, 1);
4903
            gen_helper_mtc0_status(arg);
4904
            /* BS_STOP isn't good enough here, hflags may have changed. */
4905
            gen_save_pc(ctx->pc + 4);
4906
            ctx->bstate = BS_EXCP;
4907
            rn = "Status";
4908
            break;
4909
        case 1:
4910
            check_insn(env, ctx, ISA_MIPS32R2);
4911
            gen_helper_mtc0_intctl(arg);
4912
            /* Stop translation as we may have switched the execution mode */
4913
            ctx->bstate = BS_STOP;
4914
            rn = "IntCtl";
4915
            break;
4916
        case 2:
4917
            check_insn(env, ctx, ISA_MIPS32R2);
4918
            gen_helper_mtc0_srsctl(arg);
4919
            /* Stop translation as we may have switched the execution mode */
4920
            ctx->bstate = BS_STOP;
4921
            rn = "SRSCtl";
4922
            break;
4923
        case 3:
4924
            check_insn(env, ctx, ISA_MIPS32R2);
4925
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4926
            /* Stop translation as we may have switched the execution mode */
4927
            ctx->bstate = BS_STOP;
4928
            rn = "SRSMap";
4929
            break;
4930
        default:
4931
            goto die;
4932
        }
4933
        break;
4934
    case 13:
4935
        switch (sel) {
4936
        case 0:
4937
            save_cpu_state(ctx, 1);
4938
            gen_helper_mtc0_cause(arg);
4939
            rn = "Cause";
4940
            break;
4941
        default:
4942
            goto die;
4943
        }
4944
        break;
4945
    case 14:
4946
        switch (sel) {
4947
        case 0:
4948
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4949
            rn = "EPC";
4950
            break;
4951
        default:
4952
            goto die;
4953
        }
4954
        break;
4955
    case 15:
4956
        switch (sel) {
4957
        case 0:
4958
            /* ignored */
4959
            rn = "PRid";
4960
            break;
4961
        case 1:
4962
            check_insn(env, ctx, ISA_MIPS32R2);
4963
            gen_helper_mtc0_ebase(arg);
4964
            rn = "EBase";
4965
            break;
4966
        default:
4967
            goto die;
4968
        }
4969
        break;
4970
    case 16:
4971
        switch (sel) {
4972
        case 0:
4973
            gen_helper_mtc0_config0(arg);
4974
            rn = "Config";
4975
            /* Stop translation as we may have switched the execution mode */
4976
            ctx->bstate = BS_STOP;
4977
            break;
4978
        case 1:
4979
            /* ignored, read only */
4980
            rn = "Config1";
4981
            break;
4982
        case 2:
4983
            gen_helper_mtc0_config2(arg);
4984
            rn = "Config2";
4985
            /* Stop translation as we may have switched the execution mode */
4986
            ctx->bstate = BS_STOP;
4987
            break;
4988
        case 3:
4989
            /* ignored */
4990
            rn = "Config3";
4991
            break;
4992
        /* 6,7 are implementation dependent */
4993
        default:
4994
            rn = "Invalid config selector";
4995
            goto die;
4996
        }
4997
        break;
4998
    case 17:
4999
        switch (sel) {
5000
        case 0:
5001
            /* ignored */
5002
            rn = "LLAddr";
5003
            break;
5004
        default:
5005
            goto die;
5006
        }
5007
        break;
5008
    case 18:
5009
        switch (sel) {
5010
        case 0 ... 7:
5011
            gen_helper_1i(mtc0_watchlo, arg, sel);
5012
            rn = "WatchLo";
5013
            break;
5014
        default:
5015
            goto die;
5016
        }
5017
        break;
5018
    case 19:
5019
        switch (sel) {
5020
        case 0 ... 7:
5021
            gen_helper_1i(mtc0_watchhi, arg, sel);
5022
            rn = "WatchHi";
5023
            break;
5024
        default:
5025
            goto die;
5026
        }
5027
        break;
5028
    case 20:
5029
        switch (sel) {
5030
        case 0:
5031
            check_insn(env, ctx, ISA_MIPS3);
5032
            gen_helper_mtc0_xcontext(arg);
5033
            rn = "XContext";
5034
            break;
5035
        default:
5036
            goto die;
5037
        }
5038
        break;
5039
    case 21:
5040
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5041
        switch (sel) {
5042
        case 0:
5043
            gen_helper_mtc0_framemask(arg);
5044
            rn = "Framemask";
5045
            break;
5046
        default:
5047
            goto die;
5048
        }
5049
        break;
5050
    case 22:
5051
        /* ignored */
5052
        rn = "Diagnostic"; /* implementation dependent */
5053
        break;
5054
    case 23:
5055
        switch (sel) {
5056
        case 0:
5057
            gen_helper_mtc0_debug(arg); /* EJTAG support */
5058
            /* BS_STOP isn't good enough here, hflags may have changed. */
5059
            gen_save_pc(ctx->pc + 4);
5060
            ctx->bstate = BS_EXCP;
5061
            rn = "Debug";
5062
            break;
5063
        case 1:
5064
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5065
            /* Stop translation as we may have switched the execution mode */
5066
            ctx->bstate = BS_STOP;
5067
            rn = "TraceControl";
5068
//            break;
5069
        case 2:
5070
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5071
            /* Stop translation as we may have switched the execution mode */
5072
            ctx->bstate = BS_STOP;
5073
            rn = "TraceControl2";
5074
//            break;
5075
        case 3:
5076
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5077
            /* Stop translation as we may have switched the execution mode */
5078
            ctx->bstate = BS_STOP;
5079
            rn = "UserTraceData";
5080
//            break;
5081
        case 4:
5082
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5083
            /* Stop translation as we may have switched the execution mode */
5084
            ctx->bstate = BS_STOP;
5085
            rn = "TraceBPC";
5086
//            break;
5087
        default:
5088
            goto die;
5089
        }
5090
        break;
5091
    case 24:
5092
        switch (sel) {
5093
        case 0:
5094
            /* EJTAG support */
5095
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5096
            rn = "DEPC";
5097
            break;
5098
        default:
5099
            goto die;
5100
        }
5101
        break;
5102
    case 25:
5103
        switch (sel) {
5104
        case 0:
5105
            gen_helper_mtc0_performance0(arg);
5106
            rn = "Performance0";
5107
            break;
5108
        case 1:
5109
//            gen_helper_mtc0_performance1(arg);
5110
            rn = "Performance1";
5111
//            break;
5112
        case 2:
5113
//            gen_helper_mtc0_performance2(arg);
5114
            rn = "Performance2";
5115
//            break;
5116
        case 3:
5117
//            gen_helper_mtc0_performance3(arg);
5118
            rn = "Performance3";
5119
//            break;
5120
        case 4:
5121
//            gen_helper_mtc0_performance4(arg);
5122
            rn = "Performance4";
5123
//            break;
5124
        case 5:
5125
//            gen_helper_mtc0_performance5(arg);
5126
            rn = "Performance5";
5127
//            break;
5128
        case 6:
5129
//            gen_helper_mtc0_performance6(arg);
5130
            rn = "Performance6";
5131
//            break;
5132
        case 7:
5133
//            gen_helper_mtc0_performance7(arg);
5134
            rn = "Performance7";
5135
//            break;
5136
        default:
5137
            goto die;
5138
        }
5139
        break;
5140
    case 26:
5141
        /* ignored */
5142
        rn = "ECC";
5143
        break;
5144
    case 27:
5145
        switch (sel) {
5146
        case 0 ... 3:
5147
            /* ignored */
5148
            rn = "CacheErr";
5149
            break;
5150
        default:
5151
            goto die;
5152
        }
5153
        break;
5154
    case 28:
5155
        switch (sel) {
5156
        case 0:
5157
        case 2:
5158
        case 4:
5159
        case 6:
5160
            gen_helper_mtc0_taglo(arg);
5161
            rn = "TagLo";
5162
            break;
5163
        case 1:
5164
        case 3:
5165
        case 5:
5166
        case 7:
5167
            gen_helper_mtc0_datalo(arg);
5168
            rn = "DataLo";
5169
            break;
5170
        default:
5171
            goto die;
5172
        }
5173
        break;
5174
    case 29:
5175
        switch (sel) {
5176
        case 0:
5177
        case 2:
5178
        case 4:
5179
        case 6:
5180
            gen_helper_mtc0_taghi(arg);
5181
            rn = "TagHi";
5182
            break;
5183
        case 1:
5184
        case 3:
5185
        case 5:
5186
        case 7:
5187
            gen_helper_mtc0_datahi(arg);
5188
            rn = "DataHi";
5189
            break;
5190
        default:
5191
            rn = "invalid sel";
5192
            goto die;
5193
        }
5194
        break;
5195
    case 30:
5196
        switch (sel) {
5197
        case 0:
5198
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5199
            rn = "ErrorEPC";
5200
            break;
5201
        default:
5202
            goto die;
5203
        }
5204
        break;
5205
    case 31:
5206
        switch (sel) {
5207
        case 0:
5208
            /* EJTAG support */
5209
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5210
            rn = "DESAVE";
5211
            break;
5212
        default:
5213
            goto die;
5214
        }
5215
        /* Stop translation as we may have switched the execution mode */
5216
        ctx->bstate = BS_STOP;
5217
        break;
5218
    default:
5219
        goto die;
5220
    }
5221
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5222
    /* For simplicity assume that all writes can cause interrupts.  */
5223
    if (use_icount) {
5224
        gen_io_end();
5225
        ctx->bstate = BS_STOP;
5226
    }
5227
    return;
5228

    
5229
die:
5230
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5231
    generate_exception(ctx, EXCP_RI);
5232
}
5233
#endif /* TARGET_MIPS64 */
5234

    
5235
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5236
                     int u, int sel, int h)
5237
{
5238
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5239
    TCGv t0 = tcg_temp_local_new();
5240

    
5241
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5242
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5243
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5244
        tcg_gen_movi_tl(t0, -1);
5245
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5246
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5247
        tcg_gen_movi_tl(t0, -1);
5248
    else if (u == 0) {
5249
        switch (rt) {
5250
        case 2:
5251
            switch (sel) {
5252
            case 1:
5253
                gen_helper_mftc0_tcstatus(t0);
5254
                break;
5255
            case 2:
5256
                gen_helper_mftc0_tcbind(t0);
5257
                break;
5258
            case 3:
5259
                gen_helper_mftc0_tcrestart(t0);
5260
                break;
5261
            case 4:
5262
                gen_helper_mftc0_tchalt(t0);
5263
                break;
5264
            case 5:
5265
                gen_helper_mftc0_tccontext(t0);
5266
                break;
5267
            case 6:
5268
                gen_helper_mftc0_tcschedule(t0);
5269
                break;
5270
            case 7:
5271
                gen_helper_mftc0_tcschefback(t0);
5272
                break;
5273
            default:
5274
                gen_mfc0(env, ctx, t0, rt, sel);
5275
                break;
5276
            }
5277
            break;
5278
        case 10:
5279
            switch (sel) {
5280
            case 0:
5281
                gen_helper_mftc0_entryhi(t0);
5282
                break;
5283
            default:
5284
                gen_mfc0(env, ctx, t0, rt, sel);
5285
                break;
5286
            }
5287
        case 12:
5288
            switch (sel) {
5289
            case 0:
5290
                gen_helper_mftc0_status(t0);
5291
                break;
5292
            default:
5293
                gen_mfc0(env, ctx, t0, rt, sel);
5294
                break;
5295
            }
5296
        case 23:
5297
            switch (sel) {
5298
            case 0:
5299
                gen_helper_mftc0_debug(t0);
5300
                break;
5301
            default:
5302
                gen_mfc0(env, ctx, t0, rt, sel);
5303
                break;
5304
            }
5305
            break;
5306
        default:
5307
            gen_mfc0(env, ctx, t0, rt, sel);
5308
        }
5309
    } else switch (sel) {
5310
    /* GPR registers. */
5311
    case 0:
5312
        gen_helper_1i(mftgpr, t0, rt);
5313
        break;
5314
    /* Auxiliary CPU registers */
5315
    case 1:
5316
        switch (rt) {
5317
        case 0:
5318
            gen_helper_1i(mftlo, t0, 0);
5319
            break;
5320
        case 1:
5321
            gen_helper_1i(mfthi, t0, 0);
5322
            break;
5323
        case 2:
5324
            gen_helper_1i(mftacx, t0, 0);
5325
            break;
5326
        case 4:
5327
            gen_helper_1i(mftlo, t0, 1);
5328
            break;
5329
        case 5:
5330
            gen_helper_1i(mfthi, t0, 1);
5331
            break;
5332
        case 6:
5333
            gen_helper_1i(mftacx, t0, 1);
5334
            break;
5335
        case 8:
5336
            gen_helper_1i(mftlo, t0, 2);
5337
            break;
5338
        case 9:
5339
            gen_helper_1i(mfthi, t0, 2);
5340
            break;
5341
        case 10:
5342
            gen_helper_1i(mftacx, t0, 2);
5343
            break;
5344
        case 12:
5345
            gen_helper_1i(mftlo, t0, 3);
5346
            break;
5347
        case 13:
5348
            gen_helper_1i(mfthi, t0, 3);
5349
            break;
5350
        case 14:
5351
            gen_helper_1i(mftacx, t0, 3);
5352
            break;
5353
        case 16:
5354
            gen_helper_mftdsp(t0);
5355
            break;
5356
        default:
5357
            goto die;
5358
        }
5359
        break;
5360
    /* Floating point (COP1). */
5361
    case 2:
5362
        /* XXX: For now we support only a single FPU context. */
5363
        if (h == 0) {
5364
            TCGv_i32 fp0 = tcg_temp_new_i32();
5365

    
5366
            gen_load_fpr32(fp0, rt);
5367
            tcg_gen_ext_i32_tl(t0, fp0);
5368
            tcg_temp_free_i32(fp0);
5369
        } else {
5370
            TCGv_i32 fp0 = tcg_temp_new_i32();
5371

    
5372
            gen_load_fpr32h(fp0, rt);
5373
            tcg_gen_ext_i32_tl(t0, fp0);
5374
            tcg_temp_free_i32(fp0);
5375
        }
5376
        break;
5377
    case 3:
5378
        /* XXX: For now we support only a single FPU context. */
5379
        gen_helper_1i(cfc1, t0, rt);
5380
        break;
5381
    /* COP2: Not implemented. */
5382
    case 4:
5383
    case 5:
5384
        /* fall through */
5385
    default:
5386
        goto die;
5387
    }
5388
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5389
    gen_store_gpr(t0, rd);
5390
    tcg_temp_free(t0);
5391
    return;
5392

    
5393
die:
5394
    tcg_temp_free(t0);
5395
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5396
    generate_exception(ctx, EXCP_RI);
5397
}
5398

    
5399
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5400
                     int u, int sel, int h)
5401
{
5402
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5403
    TCGv t0 = tcg_temp_local_new();
5404

    
5405
    gen_load_gpr(t0, rt);
5406
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5407
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5408
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5409
        /* NOP */ ;
5410
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5411
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5412
        /* NOP */ ;
5413
    else if (u == 0) {
5414
        switch (rd) {
5415
        case 2:
5416
            switch (sel) {
5417
            case 1:
5418
                gen_helper_mttc0_tcstatus(t0);
5419
                break;
5420
            case 2:
5421
                gen_helper_mttc0_tcbind(t0);
5422
                break;
5423
            case 3:
5424
                gen_helper_mttc0_tcrestart(t0);
5425
                break;
5426
            case 4:
5427
                gen_helper_mttc0_tchalt(t0);
5428
                break;
5429
            case 5:
5430
                gen_helper_mttc0_tccontext(t0);
5431
                break;
5432
            case 6:
5433
                gen_helper_mttc0_tcschedule(t0);
5434
                break;
5435
            case 7:
5436
                gen_helper_mttc0_tcschefback(t0);
5437
                break;
5438
            default:
5439
                gen_mtc0(env, ctx, t0, rd, sel);
5440
                break;
5441
            }
5442
            break;
5443
        case 10:
5444
            switch (sel) {
5445
            case 0:
5446
                gen_helper_mttc0_entryhi(t0);
5447
                break;
5448
            default:
5449
                gen_mtc0(env, ctx, t0, rd, sel);
5450
                break;
5451
            }
5452
        case 12:
5453
            switch (sel) {
5454
            case 0:
5455
                gen_helper_mttc0_status(t0);
5456
                break;
5457
            default:
5458
                gen_mtc0(env, ctx, t0, rd, sel);
5459
                break;
5460
            }
5461
        case 23:
5462
            switch (sel) {
5463
            case 0:
5464
                gen_helper_mttc0_debug(t0);
5465
                break;
5466
            default:
5467
                gen_mtc0(env, ctx, t0, rd, sel);
5468
                break;
5469
            }
5470
            break;
5471
        default:
5472
            gen_mtc0(env, ctx, t0, rd, sel);
5473
        }
5474
    } else switch (sel) {
5475
    /* GPR registers. */
5476
    case 0:
5477
        gen_helper_1i(mttgpr, t0, rd);
5478
        break;
5479
    /* Auxiliary CPU registers */
5480
    case 1:
5481
        switch (rd) {
5482
        case 0:
5483
            gen_helper_1i(mttlo, t0, 0);
5484
            break;
5485
        case 1:
5486
            gen_helper_1i(mtthi, t0, 0);
5487
            break;
5488
        case 2:
5489
            gen_helper_1i(mttacx, t0, 0);
5490
            break;
5491
        case 4:
5492
            gen_helper_1i(mttlo, t0, 1);
5493
            break;
5494
        case 5:
5495
            gen_helper_1i(mtthi, t0, 1);
5496
            break;
5497
        case 6:
5498
            gen_helper_1i(mttacx, t0, 1);
5499
            break;
5500
        case 8:
5501
            gen_helper_1i(mttlo, t0, 2);
5502
            break;
5503
        case 9:
5504
            gen_helper_1i(mtthi, t0, 2);
5505
            break;
5506
        case 10:
5507
            gen_helper_1i(mttacx, t0, 2);
5508
            break;
5509
        case 12:
5510
            gen_helper_1i(mttlo, t0, 3);
5511
            break;
5512
        case 13:
5513
            gen_helper_1i(mtthi, t0, 3);
5514
            break;
5515
        case 14:
5516
            gen_helper_1i(mttacx, t0, 3);
5517
            break;
5518
        case 16:
5519
            gen_helper_mttdsp(t0);
5520
            break;
5521
        default:
5522
            goto die;
5523
        }
5524
        break;
5525
    /* Floating point (COP1). */
5526
    case 2:
5527
        /* XXX: For now we support only a single FPU context. */
5528
        if (h == 0) {
5529
            TCGv_i32 fp0 = tcg_temp_new_i32();
5530

    
5531
            tcg_gen_trunc_tl_i32(fp0, t0);
5532
            gen_store_fpr32(fp0, rd);
5533
            tcg_temp_free_i32(fp0);
5534
        } else {
5535
            TCGv_i32 fp0 = tcg_temp_new_i32();
5536

    
5537
            tcg_gen_trunc_tl_i32(fp0, t0);
5538
            gen_store_fpr32h(fp0, rd);
5539
            tcg_temp_free_i32(fp0);
5540
        }
5541
        break;
5542
    case 3:
5543
        /* XXX: For now we support only a single FPU context. */
5544
        gen_helper_1i(ctc1, t0, rd);
5545
        break;
5546
    /* COP2: Not implemented. */
5547
    case 4:
5548
    case 5:
5549
        /* fall through */
5550
    default:
5551
        goto die;
5552
    }
5553
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5554
    tcg_temp_free(t0);
5555
    return;
5556

    
5557
die:
5558
    tcg_temp_free(t0);
5559
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5560
    generate_exception(ctx, EXCP_RI);
5561
}
5562

    
5563
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5564
{
5565
    const char *opn = "ldst";
5566

    
5567
    switch (opc) {
5568
    case OPC_MFC0:
5569
        if (rt == 0) {
5570
            /* Treat as NOP. */
5571
            return;
5572
        }
5573
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5574
        opn = "mfc0";
5575
        break;
5576
    case OPC_MTC0:
5577
        {
5578
            TCGv t0 = tcg_temp_new();
5579

    
5580
            gen_load_gpr(t0, rt);
5581
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5582
            tcg_temp_free(t0);
5583
        }
5584
        opn = "mtc0";
5585
        break;
5586
#if defined(TARGET_MIPS64)
5587
    case OPC_DMFC0:
5588
        check_insn(env, ctx, ISA_MIPS3);
5589
        if (rt == 0) {
5590
            /* Treat as NOP. */
5591
            return;
5592
        }
5593
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5594
        opn = "dmfc0";
5595
        break;
5596
    case OPC_DMTC0:
5597
        check_insn(env, ctx, ISA_MIPS3);
5598
        {
5599
            TCGv t0 = tcg_temp_new();
5600

    
5601
            gen_load_gpr(t0, rt);
5602
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5603
            tcg_temp_free(t0);
5604
        }
5605
        opn = "dmtc0";
5606
        break;
5607
#endif
5608
    case OPC_MFTR:
5609
        check_insn(env, ctx, ASE_MT);
5610
        if (rd == 0) {
5611
            /* Treat as NOP. */
5612
            return;
5613
        }
5614
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5615
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5616
        opn = "mftr";
5617
        break;
5618
    case OPC_MTTR:
5619
        check_insn(env, ctx, ASE_MT);
5620
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5621
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5622
        opn = "mttr";
5623
        break;
5624
    case OPC_TLBWI:
5625
        opn = "tlbwi";
5626
        if (!env->tlb->helper_tlbwi)
5627
            goto die;
5628
        gen_helper_tlbwi();
5629
        break;
5630
    case OPC_TLBWR:
5631
        opn = "tlbwr";
5632
        if (!env->tlb->helper_tlbwr)
5633
            goto die;
5634
        gen_helper_tlbwr();
5635
        break;
5636
    case OPC_TLBP:
5637
        opn = "tlbp";
5638
        if (!env->tlb->helper_tlbp)
5639
            goto die;
5640
        gen_helper_tlbp();
5641
        break;
5642
    case OPC_TLBR:
5643
        opn = "tlbr";
5644
        if (!env->tlb->helper_tlbr)
5645
            goto die;
5646
        gen_helper_tlbr();
5647
        break;
5648
    case OPC_ERET:
5649
        opn = "eret";
5650
        check_insn(env, ctx, ISA_MIPS2);
5651
        gen_helper_eret();
5652
        ctx->bstate = BS_EXCP;
5653
        break;
5654
    case OPC_DERET:
5655
        opn = "deret";
5656
        check_insn(env, ctx, ISA_MIPS32);
5657
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5658
            MIPS_INVAL(opn);
5659
            generate_exception(ctx, EXCP_RI);
5660
        } else {
5661
            gen_helper_deret();
5662
            ctx->bstate = BS_EXCP;
5663
        }
5664
        break;
5665
    case OPC_WAIT:
5666
        opn = "wait";
5667
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5668
        /* If we get an exception, we want to restart at next instruction */
5669
        ctx->pc += 4;
5670
        save_cpu_state(ctx, 1);
5671
        ctx->pc -= 4;
5672
        gen_helper_wait();
5673
        ctx->bstate = BS_EXCP;
5674
        break;
5675
    default:
5676
 die:
5677
        MIPS_INVAL(opn);
5678
        generate_exception(ctx, EXCP_RI);
5679
        return;
5680
    }
5681
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5682
}
5683
#endif /* !CONFIG_USER_ONLY */
5684

    
5685
/* CP1 Branches (before delay slot) */
5686
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5687
                                 int32_t cc, int32_t offset)
5688
{
5689
    target_ulong btarget;
5690
    const char *opn = "cp1 cond branch";
5691
    TCGv_i32 t0 = tcg_temp_new_i32();
5692

    
5693
    if (cc != 0)
5694
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5695

    
5696
    btarget = ctx->pc + 4 + offset;
5697

    
5698
    switch (op) {
5699
    case OPC_BC1F:
5700
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5701
        tcg_gen_not_i32(t0, t0);
5702
        tcg_gen_andi_i32(t0, t0, 1);
5703
        tcg_gen_extu_i32_tl(bcond, t0);
5704
        opn = "bc1f";
5705
        goto not_likely;
5706
    case OPC_BC1FL:
5707
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5708
        tcg_gen_not_i32(t0, t0);
5709
        tcg_gen_andi_i32(t0, t0, 1);
5710
        tcg_gen_extu_i32_tl(bcond, t0);
5711
        opn = "bc1fl";
5712
        goto likely;
5713
    case OPC_BC1T:
5714
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5715
        tcg_gen_andi_i32(t0, t0, 1);
5716
        tcg_gen_extu_i32_tl(bcond, t0);
5717
        opn = "bc1t";
5718
        goto not_likely;
5719
    case OPC_BC1TL:
5720
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5721
        tcg_gen_andi_i32(t0, t0, 1);
5722
        tcg_gen_extu_i32_tl(bcond, t0);
5723
        opn = "bc1tl";
5724
    likely:
5725
        ctx->hflags |= MIPS_HFLAG_BL;
5726
        break;
5727
    case OPC_BC1FANY2:
5728
        {
5729
            TCGv_i32 t1 = tcg_temp_new_i32();
5730
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5731
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5732
            tcg_gen_or_i32(t0, t0, t1);
5733
            tcg_temp_free_i32(t1);
5734
            tcg_gen_not_i32(t0, t0);
5735
            tcg_gen_andi_i32(t0, t0, 1);
5736
            tcg_gen_extu_i32_tl(bcond, t0);
5737
        }
5738
        opn = "bc1any2f";
5739
        goto not_likely;
5740
    case OPC_BC1TANY2:
5741
        {
5742
            TCGv_i32 t1 = tcg_temp_new_i32();
5743
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5744
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5745
            tcg_gen_or_i32(t0, t0, t1);
5746
            tcg_temp_free_i32(t1);
5747
            tcg_gen_andi_i32(t0, t0, 1);
5748
            tcg_gen_extu_i32_tl(bcond, t0);
5749
        }
5750
        opn = "bc1any2t";
5751
        goto not_likely;
5752
    case OPC_BC1FANY4:
5753
        {
5754
            TCGv_i32 t1 = tcg_temp_new_i32();
5755
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5756
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5757
            tcg_gen_or_i32(t0, t0, t1);
5758
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5759
            tcg_gen_or_i32(t0, t0, t1);
5760
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5761
            tcg_gen_or_i32(t0, t0, t1);
5762
            tcg_temp_free_i32(t1);
5763
            tcg_gen_not_i32(t0, t0);
5764
            tcg_gen_andi_i32(t0, t0, 1);
5765
            tcg_gen_extu_i32_tl(bcond, t0);
5766
        }
5767
        opn = "bc1any4f";
5768
        goto not_likely;
5769
    case OPC_BC1TANY4:
5770
        {
5771
            TCGv_i32 t1 = tcg_temp_new_i32();
5772
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5773
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5774
            tcg_gen_or_i32(t0, t0, t1);
5775
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5776
            tcg_gen_or_i32(t0, t0, t1);
5777
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5778
            tcg_gen_or_i32(t0, t0, t1);
5779
            tcg_temp_free_i32(t1);
5780
            tcg_gen_andi_i32(t0, t0, 1);
5781
            tcg_gen_extu_i32_tl(bcond, t0);
5782
        }
5783
        opn = "bc1any4t";
5784
    not_likely:
5785
        ctx->hflags |= MIPS_HFLAG_BC;
5786
        break;
5787
    default:
5788
        MIPS_INVAL(opn);
5789
        generate_exception (ctx, EXCP_RI);
5790
        goto out;
5791
    }
5792
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5793
               ctx->hflags, btarget);
5794
    ctx->btarget = btarget;
5795

    
5796
 out:
5797
    tcg_temp_free_i32(t0);
5798
}
5799

    
5800
/* Coprocessor 1 (FPU) */
5801

    
5802
#define FOP(func, fmt) (((fmt) << 21) | (func))
5803

    
5804
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5805
{
5806
    const char *opn = "cp1 move";
5807
    TCGv t0 = tcg_temp_new();
5808

    
5809
    switch (opc) {
5810
    case OPC_MFC1:
5811
        {
5812
            TCGv_i32 fp0 = tcg_temp_new_i32();
5813

    
5814
            gen_load_fpr32(fp0, fs);
5815
            tcg_gen_ext_i32_tl(t0, fp0);
5816
            tcg_temp_free_i32(fp0);
5817
        }
5818
        gen_store_gpr(t0, rt);
5819
        opn = "mfc1";
5820
        break;
5821
    case OPC_MTC1:
5822
        gen_load_gpr(t0, rt);
5823
        {
5824
            TCGv_i32 fp0 = tcg_temp_new_i32();
5825

    
5826
            tcg_gen_trunc_tl_i32(fp0, t0);
5827
            gen_store_fpr32(fp0, fs);
5828
            tcg_temp_free_i32(fp0);
5829
        }
5830
        opn = "mtc1";
5831
        break;
5832
    case OPC_CFC1:
5833
        gen_helper_1i(cfc1, t0, fs);
5834
        gen_store_gpr(t0, rt);
5835
        opn = "cfc1";
5836
        break;
5837
    case OPC_CTC1:
5838
        gen_load_gpr(t0, rt);
5839
        gen_helper_1i(ctc1, t0, fs);
5840
        opn = "ctc1";
5841
        break;
5842
#if defined(TARGET_MIPS64)
5843
    case OPC_DMFC1:
5844
        gen_load_fpr64(ctx, t0, fs);
5845
        gen_store_gpr(t0, rt);
5846
        opn = "dmfc1";
5847
        break;
5848
    case OPC_DMTC1:
5849
        gen_load_gpr(t0, rt);
5850
        gen_store_fpr64(ctx, t0, fs);
5851
        opn = "dmtc1";
5852
        break;
5853
#endif
5854
    case OPC_MFHC1:
5855
        {
5856
            TCGv_i32 fp0 = tcg_temp_new_i32();
5857

    
5858
            gen_load_fpr32h(fp0, fs);
5859
            tcg_gen_ext_i32_tl(t0, fp0);
5860
            tcg_temp_free_i32(fp0);
5861
        }
5862
        gen_store_gpr(t0, rt);
5863
        opn = "mfhc1";
5864
        break;
5865
    case OPC_MTHC1:
5866
        gen_load_gpr(t0, rt);
5867
        {
5868
            TCGv_i32 fp0 = tcg_temp_new_i32();
5869

    
5870
            tcg_gen_trunc_tl_i32(fp0, t0);
5871
            gen_store_fpr32h(fp0, fs);
5872
            tcg_temp_free_i32(fp0);
5873
        }
5874
        opn = "mthc1";
5875
        break;
5876
    default:
5877
        MIPS_INVAL(opn);
5878
        generate_exception (ctx, EXCP_RI);
5879
        goto out;
5880
    }
5881
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5882

    
5883
 out:
5884
    tcg_temp_free(t0);
5885
}
5886

    
5887
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5888
{
5889
    int l1;
5890
    TCGCond cond;
5891
    TCGv_i32 t0;
5892

    
5893
    if (rd == 0) {
5894
        /* Treat as NOP. */
5895
        return;
5896
    }
5897

    
5898
    if (tf)
5899
        cond = TCG_COND_EQ;
5900
    else
5901
        cond = TCG_COND_NE;
5902

    
5903
    l1 = gen_new_label();
5904
    t0 = tcg_temp_new_i32();
5905
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5906
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5907
    tcg_temp_free_i32(t0);
5908
    if (rs == 0) {
5909
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5910
    } else {
5911
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5912
    }
5913
    gen_set_label(l1);
5914
}
5915

    
5916
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5917
{
5918
    int cond;
5919
    TCGv_i32 t0 = tcg_temp_new_i32();
5920
    int l1 = gen_new_label();
5921

    
5922
    if (tf)
5923
        cond = TCG_COND_EQ;
5924
    else
5925
        cond = TCG_COND_NE;
5926

    
5927
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5928
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5929
    gen_load_fpr32(t0, fs);
5930
    gen_store_fpr32(t0, fd);
5931
    gen_set_label(l1);
5932
    tcg_temp_free_i32(t0);
5933
}
5934

    
5935
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5936
{
5937
    int cond;
5938
    TCGv_i32 t0 = tcg_temp_new_i32();
5939
    TCGv_i64 fp0;
5940
    int l1 = gen_new_label();
5941

    
5942
    if (tf)
5943
        cond = TCG_COND_EQ;
5944
    else
5945
        cond = TCG_COND_NE;
5946

    
5947
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5948
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5949
    tcg_temp_free_i32(t0);
5950
    fp0 = tcg_temp_new_i64();
5951
    gen_load_fpr64(ctx, fp0, fs);
5952
    gen_store_fpr64(ctx, fp0, fd);
5953
    tcg_temp_free_i64(fp0);
5954
    gen_set_label(l1);
5955
}
5956

    
5957
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5958
{
5959
    int cond;
5960
    TCGv_i32 t0 = tcg_temp_new_i32();
5961
    int l1 = gen_new_label();
5962
    int l2 = gen_new_label();
5963

    
5964
    if (tf)
5965
        cond = TCG_COND_EQ;
5966
    else
5967
        cond = TCG_COND_NE;
5968

    
5969
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5970
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5971
    gen_load_fpr32(t0, fs);
5972
    gen_store_fpr32(t0, fd);
5973
    gen_set_label(l1);
5974

    
5975
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
5976
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5977
    gen_load_fpr32h(t0, fs);
5978
    gen_store_fpr32h(t0, fd);
5979
    tcg_temp_free_i32(t0);
5980
    gen_set_label(l2);
5981
}
5982

    
5983

    
5984
static void gen_farith (DisasContext *ctx, uint32_t op1,
5985
                        int ft, int fs, int fd, int cc)
5986
{
5987
    const char *opn = "farith";
5988
    const char *condnames[] = {
5989
            "c.f",
5990
            "c.un",
5991
            "c.eq",
5992
            "c.ueq",
5993
            "c.olt",
5994
            "c.ult",
5995
            "c.ole",
5996
            "c.ule",
5997
            "c.sf",
5998
            "c.ngle",
5999
            "c.seq",
6000
            "c.ngl",
6001
            "c.lt",
6002
            "c.nge",
6003
            "c.le",
6004
            "c.ngt",
6005
    };
6006
    const char *condnames_abs[] = {
6007
            "cabs.f",
6008
            "cabs.un",
6009
            "cabs.eq",
6010
            "cabs.ueq",
6011
            "cabs.olt",
6012
            "cabs.ult",
6013
            "cabs.ole",
6014
            "cabs.ule",
6015
            "cabs.sf",
6016
            "cabs.ngle",
6017
            "cabs.seq",
6018
            "cabs.ngl",
6019
            "cabs.lt",
6020
            "cabs.nge",
6021
            "cabs.le",
6022
            "cabs.ngt",
6023
    };
6024
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6025
    uint32_t func = ctx->opcode & 0x3f;
6026

    
6027
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6028
    case FOP(0, 16):
6029
        {
6030
            TCGv_i32 fp0 = tcg_temp_new_i32();
6031
            TCGv_i32 fp1 = tcg_temp_new_i32();
6032

    
6033
            gen_load_fpr32(fp0, fs);
6034
            gen_load_fpr32(fp1, ft);
6035
            gen_helper_float_add_s(fp0, fp0, fp1);
6036
            tcg_temp_free_i32(fp1);
6037
            gen_store_fpr32(fp0, fd);
6038
            tcg_temp_free_i32(fp0);
6039
        }
6040
        opn = "add.s";
6041
        optype = BINOP;
6042
        break;
6043
    case FOP(1, 16):
6044
        {
6045
            TCGv_i32 fp0 = tcg_temp_new_i32();
6046
            TCGv_i32 fp1 = tcg_temp_new_i32();
6047

    
6048
            gen_load_fpr32(fp0, fs);
6049
            gen_load_fpr32(fp1, ft);
6050
            gen_helper_float_sub_s(fp0, fp0, fp1);
6051
            tcg_temp_free_i32(fp1);
6052
            gen_store_fpr32(fp0, fd);
6053
            tcg_temp_free_i32(fp0);
6054
        }
6055
        opn = "sub.s";
6056
        optype = BINOP;
6057
        break;
6058
    case FOP(2, 16):
6059
        {
6060
            TCGv_i32 fp0 = tcg_temp_new_i32();
6061
            TCGv_i32 fp1 = tcg_temp_new_i32();
6062

    
6063
            gen_load_fpr32(fp0, fs);
6064
            gen_load_fpr32(fp1, ft);
6065
            gen_helper_float_mul_s(fp0, fp0, fp1);
6066
            tcg_temp_free_i32(fp1);
6067
            gen_store_fpr32(fp0, fd);
6068
            tcg_temp_free_i32(fp0);
6069
        }
6070
        opn = "mul.s";
6071
        optype = BINOP;
6072
        break;
6073
    case FOP(3, 16):
6074
        {
6075
            TCGv_i32 fp0 = tcg_temp_new_i32();
6076
            TCGv_i32 fp1 = tcg_temp_new_i32();
6077

    
6078
            gen_load_fpr32(fp0, fs);
6079
            gen_load_fpr32(fp1, ft);
6080
            gen_helper_float_div_s(fp0, fp0, fp1);
6081
            tcg_temp_free_i32(fp1);
6082
            gen_store_fpr32(fp0, fd);
6083
            tcg_temp_free_i32(fp0);
6084
        }
6085
        opn = "div.s";
6086
        optype = BINOP;
6087
        break;
6088
    case FOP(4, 16):
6089
        {
6090
            TCGv_i32 fp0 = tcg_temp_new_i32();
6091

    
6092
            gen_load_fpr32(fp0, fs);
6093
            gen_helper_float_sqrt_s(fp0, fp0);
6094
            gen_store_fpr32(fp0, fd);
6095
            tcg_temp_free_i32(fp0);
6096
        }
6097
        opn = "sqrt.s";
6098
        break;
6099
    case FOP(5, 16):
6100
        {
6101
            TCGv_i32 fp0 = tcg_temp_new_i32();
6102

    
6103
            gen_load_fpr32(fp0, fs);
6104
            gen_helper_float_abs_s(fp0, fp0);
6105
            gen_store_fpr32(fp0, fd);
6106
            tcg_temp_free_i32(fp0);
6107
        }
6108
        opn = "abs.s";
6109
        break;
6110
    case FOP(6, 16):
6111
        {
6112
            TCGv_i32 fp0 = tcg_temp_new_i32();
6113

    
6114
            gen_load_fpr32(fp0, fs);
6115
            gen_store_fpr32(fp0, fd);
6116
            tcg_temp_free_i32(fp0);
6117
        }
6118
        opn = "mov.s";
6119
        break;
6120
    case FOP(7, 16):
6121
        {
6122
            TCGv_i32 fp0 = tcg_temp_new_i32();
6123

    
6124
            gen_load_fpr32(fp0, fs);
6125
            gen_helper_float_chs_s(fp0, fp0);
6126
            gen_store_fpr32(fp0, fd);
6127
            tcg_temp_free_i32(fp0);
6128
        }
6129
        opn = "neg.s";
6130
        break;
6131
    case FOP(8, 16):
6132
        check_cp1_64bitmode(ctx);
6133
        {
6134
            TCGv_i32 fp32 = tcg_temp_new_i32();
6135
            TCGv_i64 fp64 = tcg_temp_new_i64();
6136

    
6137
            gen_load_fpr32(fp32, fs);
6138
            gen_helper_float_roundl_s(fp64, fp32);
6139
            tcg_temp_free_i32(fp32);
6140
            gen_store_fpr64(ctx, fp64, fd);
6141
            tcg_temp_free_i64(fp64);
6142
        }
6143
        opn = "round.l.s";
6144
        break;
6145
    case FOP(9, 16):
6146
        check_cp1_64bitmode(ctx);
6147
        {
6148
            TCGv_i32 fp32 = tcg_temp_new_i32();
6149
            TCGv_i64 fp64 = tcg_temp_new_i64();
6150

    
6151
            gen_load_fpr32(fp32, fs);
6152
            gen_helper_float_truncl_s(fp64, fp32);
6153
            tcg_temp_free_i32(fp32);
6154
            gen_store_fpr64(ctx, fp64, fd);
6155
            tcg_temp_free_i64(fp64);
6156
        }
6157
        opn = "trunc.l.s";
6158
        break;
6159
    case FOP(10, 16):
6160
        check_cp1_64bitmode(ctx);
6161
        {
6162
            TCGv_i32 fp32 = tcg_temp_new_i32();
6163
            TCGv_i64 fp64 = tcg_temp_new_i64();
6164

    
6165
            gen_load_fpr32(fp32, fs);
6166
            gen_helper_float_ceill_s(fp64, fp32);
6167
            tcg_temp_free_i32(fp32);
6168
            gen_store_fpr64(ctx, fp64, fd);
6169
            tcg_temp_free_i64(fp64);
6170
        }
6171
        opn = "ceil.l.s";
6172
        break;
6173
    case FOP(11, 16):
6174
        check_cp1_64bitmode(ctx);
6175
        {
6176
            TCGv_i32 fp32 = tcg_temp_new_i32();
6177
            TCGv_i64 fp64 = tcg_temp_new_i64();
6178

    
6179
            gen_load_fpr32(fp32, fs);
6180
            gen_helper_float_floorl_s(fp64, fp32);
6181
            tcg_temp_free_i32(fp32);
6182
            gen_store_fpr64(ctx, fp64, fd);
6183
            tcg_temp_free_i64(fp64);
6184
        }
6185
        opn = "floor.l.s";
6186
        break;
6187
    case FOP(12, 16):
6188
        {
6189
            TCGv_i32 fp0 = tcg_temp_new_i32();
6190

    
6191
            gen_load_fpr32(fp0, fs);
6192
            gen_helper_float_roundw_s(fp0, fp0);
6193
            gen_store_fpr32(fp0, fd);
6194
            tcg_temp_free_i32(fp0);
6195
        }
6196
        opn = "round.w.s";
6197
        break;
6198
    case FOP(13, 16):
6199
        {
6200
            TCGv_i32 fp0 = tcg_temp_new_i32();
6201

    
6202
            gen_load_fpr32(fp0, fs);
6203
            gen_helper_float_truncw_s(fp0, fp0);
6204
            gen_store_fpr32(fp0, fd);
6205
            tcg_temp_free_i32(fp0);
6206
        }
6207
        opn = "trunc.w.s";
6208
        break;
6209
    case FOP(14, 16):
6210
        {
6211
            TCGv_i32 fp0 = tcg_temp_new_i32();
6212

    
6213
            gen_load_fpr32(fp0, fs);
6214
            gen_helper_float_ceilw_s(fp0, fp0);
6215
            gen_store_fpr32(fp0, fd);
6216
            tcg_temp_free_i32(fp0);
6217
        }
6218
        opn = "ceil.w.s";
6219
        break;
6220
    case FOP(15, 16):
6221
        {
6222
            TCGv_i32 fp0 = tcg_temp_new_i32();
6223

    
6224
            gen_load_fpr32(fp0, fs);
6225
            gen_helper_float_floorw_s(fp0, fp0);
6226
            gen_store_fpr32(fp0, fd);
6227
            tcg_temp_free_i32(fp0);
6228
        }
6229
        opn = "floor.w.s";
6230
        break;
6231
    case FOP(17, 16):
6232
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6233
        opn = "movcf.s";
6234
        break;
6235
    case FOP(18, 16):
6236
        {
6237
            int l1 = gen_new_label();
6238
            TCGv_i32 fp0;
6239

    
6240
            if (ft != 0) {
6241
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6242
            }
6243
            fp0 = tcg_temp_new_i32();
6244
            gen_load_fpr32(fp0, fs);
6245
            gen_store_fpr32(fp0, fd);
6246
            tcg_temp_free_i32(fp0);
6247
            gen_set_label(l1);
6248
        }
6249
        opn = "movz.s";
6250
        break;
6251
    case FOP(19, 16):
6252
        {
6253
            int l1 = gen_new_label();
6254
            TCGv_i32 fp0;
6255

    
6256
            if (ft != 0) {
6257
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6258
                fp0 = tcg_temp_new_i32();
6259
                gen_load_fpr32(fp0, fs);
6260
                gen_store_fpr32(fp0, fd);
6261
                tcg_temp_free_i32(fp0);
6262
                gen_set_label(l1);
6263
            }
6264
        }
6265
        opn = "movn.s";
6266
        break;
6267
    case FOP(21, 16):
6268
        check_cop1x(ctx);
6269
        {
6270
            TCGv_i32 fp0 = tcg_temp_new_i32();
6271

    
6272
            gen_load_fpr32(fp0, fs);
6273
            gen_helper_float_recip_s(fp0, fp0);
6274
            gen_store_fpr32(fp0, fd);
6275
            tcg_temp_free_i32(fp0);
6276
        }
6277
        opn = "recip.s";
6278
        break;
6279
    case FOP(22, 16):
6280
        check_cop1x(ctx);
6281
        {
6282
            TCGv_i32 fp0 = tcg_temp_new_i32();
6283

    
6284
            gen_load_fpr32(fp0, fs);
6285
            gen_helper_float_rsqrt_s(fp0, fp0);
6286
            gen_store_fpr32(fp0, fd);
6287
            tcg_temp_free_i32(fp0);
6288
        }
6289
        opn = "rsqrt.s";
6290
        break;
6291
    case FOP(28, 16):
6292
        check_cp1_64bitmode(ctx);
6293
        {
6294
            TCGv_i32 fp0 = tcg_temp_new_i32();
6295
            TCGv_i32 fp1 = tcg_temp_new_i32();
6296

    
6297
            gen_load_fpr32(fp0, fs);
6298
            gen_load_fpr32(fp1, fd);
6299
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6300
            tcg_temp_free_i32(fp1);
6301
            gen_store_fpr32(fp0, fd);
6302
            tcg_temp_free_i32(fp0);
6303
        }
6304
        opn = "recip2.s";
6305
        break;
6306
    case FOP(29, 16):
6307
        check_cp1_64bitmode(ctx);
6308
        {
6309
            TCGv_i32 fp0 = tcg_temp_new_i32();
6310

    
6311
            gen_load_fpr32(fp0, fs);
6312
            gen_helper_float_recip1_s(fp0, fp0);
6313
            gen_store_fpr32(fp0, fd);
6314
            tcg_temp_free_i32(fp0);
6315
        }
6316
        opn = "recip1.s";
6317
        break;
6318
    case FOP(30, 16):
6319
        check_cp1_64bitmode(ctx);
6320
        {
6321
            TCGv_i32 fp0 = tcg_temp_new_i32();
6322

    
6323
            gen_load_fpr32(fp0, fs);
6324
            gen_helper_float_rsqrt1_s(fp0, fp0);
6325
            gen_store_fpr32(fp0, fd);
6326
            tcg_temp_free_i32(fp0);
6327
        }
6328
        opn = "rsqrt1.s";
6329
        break;
6330
    case FOP(31, 16):
6331
        check_cp1_64bitmode(ctx);
6332
        {
6333
            TCGv_i32 fp0 = tcg_temp_new_i32();
6334
            TCGv_i32 fp1 = tcg_temp_new_i32();
6335

    
6336
            gen_load_fpr32(fp0, fs);
6337
            gen_load_fpr32(fp1, ft);
6338
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6339
            tcg_temp_free_i32(fp1);
6340
            gen_store_fpr32(fp0, fd);
6341
            tcg_temp_free_i32(fp0);
6342
        }
6343
        opn = "rsqrt2.s";
6344
        break;
6345
    case FOP(33, 16):
6346
        check_cp1_registers(ctx, fd);
6347
        {
6348
            TCGv_i32 fp32 = tcg_temp_new_i32();
6349
            TCGv_i64 fp64 = tcg_temp_new_i64();
6350

    
6351
            gen_load_fpr32(fp32, fs);
6352
            gen_helper_float_cvtd_s(fp64, fp32);
6353
            tcg_temp_free_i32(fp32);
6354
            gen_store_fpr64(ctx, fp64, fd);
6355
            tcg_temp_free_i64(fp64);
6356
        }
6357
        opn = "cvt.d.s";
6358
        break;
6359
    case FOP(36, 16):
6360
        {
6361
            TCGv_i32 fp0 = tcg_temp_new_i32();
6362

    
6363
            gen_load_fpr32(fp0, fs);
6364
            gen_helper_float_cvtw_s(fp0, fp0);
6365
            gen_store_fpr32(fp0, fd);
6366
            tcg_temp_free_i32(fp0);
6367
        }
6368
        opn = "cvt.w.s";
6369
        break;
6370
    case FOP(37, 16):
6371
        check_cp1_64bitmode(ctx);
6372
        {
6373
            TCGv_i32 fp32 = tcg_temp_new_i32();
6374
            TCGv_i64 fp64 = tcg_temp_new_i64();
6375

    
6376
            gen_load_fpr32(fp32, fs);
6377
            gen_helper_float_cvtl_s(fp64, fp32);
6378
            tcg_temp_free_i32(fp32);
6379
            gen_store_fpr64(ctx, fp64, fd);
6380
            tcg_temp_free_i64(fp64);
6381
        }
6382
        opn = "cvt.l.s";
6383
        break;
6384
    case FOP(38, 16):
6385
        check_cp1_64bitmode(ctx);
6386
        {
6387
            TCGv_i64 fp64 = tcg_temp_new_i64();
6388
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6389
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6390

    
6391
            gen_load_fpr32(fp32_0, fs);
6392
            gen_load_fpr32(fp32_1, ft);
6393
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6394
            tcg_temp_free_i32(fp32_1);
6395
            tcg_temp_free_i32(fp32_0);
6396
            gen_store_fpr64(ctx, fp64, fd);
6397
            tcg_temp_free_i64(fp64);
6398
        }
6399
        opn = "cvt.ps.s";
6400
        break;
6401
    case FOP(48, 16):
6402
    case FOP(49, 16):
6403
    case FOP(50, 16):
6404
    case FOP(51, 16):
6405
    case FOP(52, 16):
6406
    case FOP(53, 16):
6407
    case FOP(54, 16):
6408
    case FOP(55, 16):
6409
    case FOP(56, 16):
6410
    case FOP(57, 16):
6411
    case FOP(58, 16):
6412
    case FOP(59, 16):
6413
    case FOP(60, 16):
6414
    case FOP(61, 16):
6415
    case FOP(62, 16):
6416
    case FOP(63, 16):
6417
        {
6418
            TCGv_i32 fp0 = tcg_temp_new_i32();
6419
            TCGv_i32 fp1 = tcg_temp_new_i32();
6420

    
6421
            gen_load_fpr32(fp0, fs);
6422
            gen_load_fpr32(fp1, ft);
6423
            if (ctx->opcode & (1 << 6)) {
6424
                check_cop1x(ctx);
6425
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6426
                opn = condnames_abs[func-48];
6427
            } else {
6428
                gen_cmp_s(func-48, fp0, fp1, cc);
6429
                opn = condnames[func-48];
6430
            }
6431
            tcg_temp_free_i32(fp0);
6432
            tcg_temp_free_i32(fp1);
6433
        }
6434
        break;
6435
    case FOP(0, 17):
6436
        check_cp1_registers(ctx, fs | ft | fd);
6437
        {
6438
            TCGv_i64 fp0 = tcg_temp_new_i64();
6439
            TCGv_i64 fp1 = tcg_temp_new_i64();
6440

    
6441
            gen_load_fpr64(ctx, fp0, fs);
6442
            gen_load_fpr64(ctx, fp1, ft);
6443
            gen_helper_float_add_d(fp0, fp0, fp1);
6444
            tcg_temp_free_i64(fp1);
6445
            gen_store_fpr64(ctx, fp0, fd);
6446
            tcg_temp_free_i64(fp0);
6447
        }
6448
        opn = "add.d";
6449
        optype = BINOP;
6450
        break;
6451
    case FOP(1, 17):
6452
        check_cp1_registers(ctx, fs | ft | fd);
6453
        {
6454
            TCGv_i64 fp0 = tcg_temp_new_i64();
6455
            TCGv_i64 fp1 = tcg_temp_new_i64();
6456

    
6457
            gen_load_fpr64(ctx, fp0, fs);
6458
            gen_load_fpr64(ctx, fp1, ft);
6459
            gen_helper_float_sub_d(fp0, fp0, fp1);
6460
            tcg_temp_free_i64(fp1);
6461
            gen_store_fpr64(ctx, fp0, fd);
6462
            tcg_temp_free_i64(fp0);
6463
        }
6464
        opn = "sub.d";
6465
        optype = BINOP;
6466
        break;
6467
    case FOP(2, 17):
6468
        check_cp1_registers(ctx, fs | ft | fd);
6469
        {
6470
            TCGv_i64 fp0 = tcg_temp_new_i64();
6471
            TCGv_i64 fp1 = tcg_temp_new_i64();
6472

    
6473
            gen_load_fpr64(ctx, fp0, fs);
6474
            gen_load_fpr64(ctx, fp1, ft);
6475
            gen_helper_float_mul_d(fp0, fp0, fp1);
6476
            tcg_temp_free_i64(fp1);
6477
            gen_store_fpr64(ctx, fp0, fd);
6478
            tcg_temp_free_i64(fp0);
6479
        }
6480
        opn = "mul.d";
6481
        optype = BINOP;
6482
        break;
6483
    case FOP(3, 17):
6484
        check_cp1_registers(ctx, fs | ft | fd);
6485
        {
6486
            TCGv_i64 fp0 = tcg_temp_new_i64();
6487
            TCGv_i64 fp1 = tcg_temp_new_i64();
6488

    
6489
            gen_load_fpr64(ctx, fp0, fs);
6490
            gen_load_fpr64(ctx, fp1, ft);
6491
            gen_helper_float_div_d(fp0, fp0, fp1);
6492
            tcg_temp_free_i64(fp1);
6493
            gen_store_fpr64(ctx, fp0, fd);
6494
            tcg_temp_free_i64(fp0);
6495
        }
6496
        opn = "div.d";
6497
        optype = BINOP;
6498
        break;
6499
    case FOP(4, 17):
6500
        check_cp1_registers(ctx, fs | fd);
6501
        {
6502
            TCGv_i64 fp0 = tcg_temp_new_i64();
6503

    
6504
            gen_load_fpr64(ctx, fp0, fs);
6505
            gen_helper_float_sqrt_d(fp0, fp0);
6506
            gen_store_fpr64(ctx, fp0, fd);
6507
            tcg_temp_free_i64(fp0);
6508
        }
6509
        opn = "sqrt.d";
6510
        break;
6511
    case FOP(5, 17):
6512
        check_cp1_registers(ctx, fs | fd);
6513
        {
6514
            TCGv_i64 fp0 = tcg_temp_new_i64();
6515

    
6516
            gen_load_fpr64(ctx, fp0, fs);
6517
            gen_helper_float_abs_d(fp0, fp0);
6518
            gen_store_fpr64(ctx, fp0, fd);
6519
            tcg_temp_free_i64(fp0);
6520
        }
6521
        opn = "abs.d";
6522
        break;
6523
    case FOP(6, 17):
6524
        check_cp1_registers(ctx, fs | fd);
6525
        {
6526
            TCGv_i64 fp0 = tcg_temp_new_i64();
6527

    
6528
            gen_load_fpr64(ctx, fp0, fs);
6529
            gen_store_fpr64(ctx, fp0, fd);
6530
            tcg_temp_free_i64(fp0);
6531
        }
6532
        opn = "mov.d";
6533
        break;
6534
    case FOP(7, 17):
6535
        check_cp1_registers(ctx, fs | fd);
6536
        {
6537
            TCGv_i64 fp0 = tcg_temp_new_i64();
6538

    
6539
            gen_load_fpr64(ctx, fp0, fs);
6540
            gen_helper_float_chs_d(fp0, fp0);
6541
            gen_store_fpr64(ctx, fp0, fd);
6542
            tcg_temp_free_i64(fp0);
6543
        }
6544
        opn = "neg.d";
6545
        break;
6546
    case FOP(8, 17):
6547
        check_cp1_64bitmode(ctx);
6548
        {
6549
            TCGv_i64 fp0 = tcg_temp_new_i64();
6550

    
6551
            gen_load_fpr64(ctx, fp0, fs);
6552
            gen_helper_float_roundl_d(fp0, fp0);
6553
            gen_store_fpr64(ctx, fp0, fd);
6554
            tcg_temp_free_i64(fp0);
6555
        }
6556
        opn = "round.l.d";
6557
        break;
6558
    case FOP(9, 17):
6559
        check_cp1_64bitmode(ctx);
6560
        {
6561
            TCGv_i64 fp0 = tcg_temp_new_i64();
6562

    
6563
            gen_load_fpr64(ctx, fp0, fs);
6564
            gen_helper_float_truncl_d(fp0, fp0);
6565
            gen_store_fpr64(ctx, fp0, fd);
6566
            tcg_temp_free_i64(fp0);
6567
        }
6568
        opn = "trunc.l.d";
6569
        break;
6570
    case FOP(10, 17):
6571
        check_cp1_64bitmode(ctx);
6572
        {
6573
            TCGv_i64 fp0 = tcg_temp_new_i64();
6574

    
6575
            gen_load_fpr64(ctx, fp0, fs);
6576
            gen_helper_float_ceill_d(fp0, fp0);
6577
            gen_store_fpr64(ctx, fp0, fd);
6578
            tcg_temp_free_i64(fp0);
6579
        }
6580
        opn = "ceil.l.d";
6581
        break;
6582
    case FOP(11, 17):
6583
        check_cp1_64bitmode(ctx);
6584
        {
6585
            TCGv_i64 fp0 = tcg_temp_new_i64();
6586

    
6587
            gen_load_fpr64(ctx, fp0, fs);
6588
            gen_helper_float_floorl_d(fp0, fp0);
6589
            gen_store_fpr64(ctx, fp0, fd);
6590
            tcg_temp_free_i64(fp0);
6591
        }
6592
        opn = "floor.l.d";
6593
        break;
6594
    case FOP(12, 17):
6595
        check_cp1_registers(ctx, fs);
6596
        {
6597
            TCGv_i32 fp32 = tcg_temp_new_i32();
6598
            TCGv_i64 fp64 = tcg_temp_new_i64();
6599

    
6600
            gen_load_fpr64(ctx, fp64, fs);
6601
            gen_helper_float_roundw_d(fp32, fp64);
6602
            tcg_temp_free_i64(fp64);
6603
            gen_store_fpr32(fp32, fd);
6604
            tcg_temp_free_i32(fp32);
6605
        }
6606
        opn = "round.w.d";
6607
        break;
6608
    case FOP(13, 17):
6609
        check_cp1_registers(ctx, fs);
6610
        {
6611
            TCGv_i32 fp32 = tcg_temp_new_i32();
6612
            TCGv_i64 fp64 = tcg_temp_new_i64();
6613

    
6614
            gen_load_fpr64(ctx, fp64, fs);
6615
            gen_helper_float_truncw_d(fp32, fp64);
6616
            tcg_temp_free_i64(fp64);
6617
            gen_store_fpr32(fp32, fd);
6618
            tcg_temp_free_i32(fp32);
6619
        }
6620
        opn = "trunc.w.d";
6621
        break;
6622
    case FOP(14, 17):
6623
        check_cp1_registers(ctx, fs);
6624
        {
6625
            TCGv_i32 fp32 = tcg_temp_new_i32();
6626
            TCGv_i64 fp64 = tcg_temp_new_i64();
6627

    
6628
            gen_load_fpr64(ctx, fp64, fs);
6629
            gen_helper_float_ceilw_d(fp32, fp64);
6630
            tcg_temp_free_i64(fp64);
6631
            gen_store_fpr32(fp32, fd);
6632
            tcg_temp_free_i32(fp32);
6633
        }
6634
        opn = "ceil.w.d";
6635
        break;
6636
    case FOP(15, 17):
6637
        check_cp1_registers(ctx, fs);
6638
        {
6639
            TCGv_i32 fp32 = tcg_temp_new_i32();
6640
            TCGv_i64 fp64 = tcg_temp_new_i64();
6641

    
6642
            gen_load_fpr64(ctx, fp64, fs);
6643
            gen_helper_float_floorw_d(fp32, fp64);
6644
            tcg_temp_free_i64(fp64);
6645
            gen_store_fpr32(fp32, fd);
6646
            tcg_temp_free_i32(fp32);
6647
        }
6648
        opn = "floor.w.d";
6649
        break;
6650
    case FOP(17, 17):
6651
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6652
        opn = "movcf.d";
6653
        break;
6654
    case FOP(18, 17):
6655
        {
6656
            int l1 = gen_new_label();
6657
            TCGv_i64 fp0;
6658

    
6659
            if (ft != 0) {
6660
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6661
            }
6662
            fp0 = tcg_temp_new_i64();
6663
            gen_load_fpr64(ctx, fp0, fs);
6664
            gen_store_fpr64(ctx, fp0, fd);
6665
            tcg_temp_free_i64(fp0);
6666
            gen_set_label(l1);
6667
        }
6668
        opn = "movz.d";
6669
        break;
6670
    case FOP(19, 17):
6671
        {
6672
            int l1 = gen_new_label();
6673
            TCGv_i64 fp0;
6674

    
6675
            if (ft != 0) {
6676
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6677
                fp0 = tcg_temp_new_i64();
6678
                gen_load_fpr64(ctx, fp0, fs);
6679
                gen_store_fpr64(ctx, fp0, fd);
6680
                tcg_temp_free_i64(fp0);
6681
                gen_set_label(l1);
6682
            }
6683
        }
6684
        opn = "movn.d";
6685
        break;
6686
    case FOP(21, 17):
6687
        check_cp1_64bitmode(ctx);
6688
        {
6689
            TCGv_i64 fp0 = tcg_temp_new_i64();
6690

    
6691
            gen_load_fpr64(ctx, fp0, fs);
6692
            gen_helper_float_recip_d(fp0, fp0);
6693
            gen_store_fpr64(ctx, fp0, fd);
6694
            tcg_temp_free_i64(fp0);
6695
        }
6696
        opn = "recip.d";
6697
        break;
6698
    case FOP(22, 17):
6699
        check_cp1_64bitmode(ctx);
6700
        {
6701
            TCGv_i64 fp0 = tcg_temp_new_i64();
6702

    
6703
            gen_load_fpr64(ctx, fp0, fs);
6704
            gen_helper_float_rsqrt_d(fp0, fp0);
6705
            gen_store_fpr64(ctx, fp0, fd);
6706
            tcg_temp_free_i64(fp0);
6707
        }
6708
        opn = "rsqrt.d";
6709
        break;
6710
    case FOP(28, 17):
6711
        check_cp1_64bitmode(ctx);
6712
        {
6713
            TCGv_i64 fp0 = tcg_temp_new_i64();
6714
            TCGv_i64 fp1 = tcg_temp_new_i64();
6715

    
6716
            gen_load_fpr64(ctx, fp0, fs);
6717
            gen_load_fpr64(ctx, fp1, ft);
6718
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6719
            tcg_temp_free_i64(fp1);
6720
            gen_store_fpr64(ctx, fp0, fd);
6721
            tcg_temp_free_i64(fp0);
6722
        }
6723
        opn = "recip2.d";
6724
        break;
6725
    case FOP(29, 17):
6726
        check_cp1_64bitmode(ctx);
6727
        {
6728
            TCGv_i64 fp0 = tcg_temp_new_i64();
6729

    
6730
            gen_load_fpr64(ctx, fp0, fs);
6731
            gen_helper_float_recip1_d(fp0, fp0);
6732
            gen_store_fpr64(ctx, fp0, fd);
6733
            tcg_temp_free_i64(fp0);
6734
        }
6735
        opn = "recip1.d";
6736
        break;
6737
    case FOP(30, 17):
6738
        check_cp1_64bitmode(ctx);
6739
        {
6740
            TCGv_i64 fp0 = tcg_temp_new_i64();
6741

    
6742
            gen_load_fpr64(ctx, fp0, fs);
6743
            gen_helper_float_rsqrt1_d(fp0, fp0);
6744
            gen_store_fpr64(ctx, fp0, fd);
6745
            tcg_temp_free_i64(fp0);
6746
        }
6747
        opn = "rsqrt1.d";
6748
        break;
6749
    case FOP(31, 17):
6750
        check_cp1_64bitmode(ctx);
6751
        {
6752
            TCGv_i64 fp0 = tcg_temp_new_i64();
6753
            TCGv_i64 fp1 = tcg_temp_new_i64();
6754

    
6755
            gen_load_fpr64(ctx, fp0, fs);
6756
            gen_load_fpr64(ctx, fp1, ft);
6757
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6758
            tcg_temp_free_i64(fp1);
6759
            gen_store_fpr64(ctx, fp0, fd);
6760
            tcg_temp_free_i64(fp0);
6761
        }
6762
        opn = "rsqrt2.d";
6763
        break;
6764
    case FOP(48, 17):
6765
    case FOP(49, 17):
6766
    case FOP(50, 17):
6767
    case FOP(51, 17):
6768
    case FOP(52, 17):
6769
    case FOP(53, 17):
6770
    case FOP(54, 17):
6771
    case FOP(55, 17):
6772
    case FOP(56, 17):
6773
    case FOP(57, 17):
6774
    case FOP(58, 17):
6775
    case FOP(59, 17):
6776
    case FOP(60, 17):
6777
    case FOP(61, 17):
6778
    case FOP(62, 17):
6779
    case FOP(63, 17):
6780
        {
6781
            TCGv_i64 fp0 = tcg_temp_new_i64();
6782
            TCGv_i64 fp1 = tcg_temp_new_i64();
6783

    
6784
            gen_load_fpr64(ctx, fp0, fs);
6785
            gen_load_fpr64(ctx, fp1, ft);
6786
            if (ctx->opcode & (1 << 6)) {
6787
                check_cop1x(ctx);
6788
                check_cp1_registers(ctx, fs | ft);
6789
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6790
                opn = condnames_abs[func-48];
6791
            } else {
6792
                check_cp1_registers(ctx, fs | ft);
6793
                gen_cmp_d(func-48, fp0, fp1, cc);
6794
                opn = condnames[func-48];
6795
            }
6796
            tcg_temp_free_i64(fp0);
6797
            tcg_temp_free_i64(fp1);
6798
        }
6799
        break;
6800
    case FOP(32, 17):
6801
        check_cp1_registers(ctx, fs);
6802
        {
6803
            TCGv_i32 fp32 = tcg_temp_new_i32();
6804
            TCGv_i64 fp64 = tcg_temp_new_i64();
6805

    
6806
            gen_load_fpr64(ctx, fp64, fs);
6807
            gen_helper_float_cvts_d(fp32, fp64);
6808
            tcg_temp_free_i64(fp64);
6809
            gen_store_fpr32(fp32, fd);
6810
            tcg_temp_free_i32(fp32);
6811
        }
6812
        opn = "cvt.s.d";
6813
        break;
6814
    case FOP(36, 17):
6815
        check_cp1_registers(ctx, fs);
6816
        {
6817
            TCGv_i32 fp32 = tcg_temp_new_i32();
6818
            TCGv_i64 fp64 = tcg_temp_new_i64();
6819

    
6820
            gen_load_fpr64(ctx, fp64, fs);
6821
            gen_helper_float_cvtw_d(fp32, fp64);
6822
            tcg_temp_free_i64(fp64);
6823
            gen_store_fpr32(fp32, fd);
6824
            tcg_temp_free_i32(fp32);
6825
        }
6826
        opn = "cvt.w.d";
6827
        break;
6828
    case FOP(37, 17):
6829
        check_cp1_64bitmode(ctx);
6830
        {
6831
            TCGv_i64 fp0 = tcg_temp_new_i64();
6832

    
6833
            gen_load_fpr64(ctx, fp0, fs);
6834
            gen_helper_float_cvtl_d(fp0, fp0);
6835
            gen_store_fpr64(ctx, fp0, fd);
6836
            tcg_temp_free_i64(fp0);
6837
        }
6838
        opn = "cvt.l.d";
6839
        break;
6840
    case FOP(32, 20):
6841
        {
6842
            TCGv_i32 fp0 = tcg_temp_new_i32();
6843

    
6844
            gen_load_fpr32(fp0, fs);
6845
            gen_helper_float_cvts_w(fp0, fp0);
6846
            gen_store_fpr32(fp0, fd);
6847
            tcg_temp_free_i32(fp0);
6848
        }
6849
        opn = "cvt.s.w";
6850
        break;
6851
    case FOP(33, 20):
6852
        check_cp1_registers(ctx, fd);
6853
        {
6854
            TCGv_i32 fp32 = tcg_temp_new_i32();
6855
            TCGv_i64 fp64 = tcg_temp_new_i64();
6856

    
6857
            gen_load_fpr32(fp32, fs);
6858
            gen_helper_float_cvtd_w(fp64, fp32);
6859
            tcg_temp_free_i32(fp32);
6860
            gen_store_fpr64(ctx, fp64, fd);
6861
            tcg_temp_free_i64(fp64);
6862
        }
6863
        opn = "cvt.d.w";
6864
        break;
6865
    case FOP(32, 21):
6866
        check_cp1_64bitmode(ctx);
6867
        {
6868
            TCGv_i32 fp32 = tcg_temp_new_i32();
6869
            TCGv_i64 fp64 = tcg_temp_new_i64();
6870

    
6871
            gen_load_fpr64(ctx, fp64, fs);
6872
            gen_helper_float_cvts_l(fp32, fp64);
6873
            tcg_temp_free_i64(fp64);
6874
            gen_store_fpr32(fp32, fd);
6875
            tcg_temp_free_i32(fp32);
6876
        }
6877
        opn = "cvt.s.l";
6878
        break;
6879
    case FOP(33, 21):
6880
        check_cp1_64bitmode(ctx);
6881
        {
6882
            TCGv_i64 fp0 = tcg_temp_new_i64();
6883

    
6884
            gen_load_fpr64(ctx, fp0, fs);
6885
            gen_helper_float_cvtd_l(fp0, fp0);
6886
            gen_store_fpr64(ctx, fp0, fd);
6887
            tcg_temp_free_i64(fp0);
6888
        }
6889
        opn = "cvt.d.l";
6890
        break;
6891
    case FOP(38, 20):
6892
        check_cp1_64bitmode(ctx);
6893
        {
6894
            TCGv_i64 fp0 = tcg_temp_new_i64();
6895

    
6896
            gen_load_fpr64(ctx, fp0, fs);
6897
            gen_helper_float_cvtps_pw(fp0, fp0);
6898
            gen_store_fpr64(ctx, fp0, fd);
6899
            tcg_temp_free_i64(fp0);
6900
        }
6901
        opn = "cvt.ps.pw";
6902
        break;
6903
    case FOP(0, 22):
6904
        check_cp1_64bitmode(ctx);
6905
        {
6906
            TCGv_i64 fp0 = tcg_temp_new_i64();
6907
            TCGv_i64 fp1 = tcg_temp_new_i64();
6908

    
6909
            gen_load_fpr64(ctx, fp0, fs);
6910
            gen_load_fpr64(ctx, fp1, ft);
6911
            gen_helper_float_add_ps(fp0, fp0, fp1);
6912
            tcg_temp_free_i64(fp1);
6913
            gen_store_fpr64(ctx, fp0, fd);
6914
            tcg_temp_free_i64(fp0);
6915
        }
6916
        opn = "add.ps";
6917
        break;
6918
    case FOP(1, 22):
6919
        check_cp1_64bitmode(ctx);
6920
        {
6921
            TCGv_i64 fp0 = tcg_temp_new_i64();
6922
            TCGv_i64 fp1 = tcg_temp_new_i64();
6923

    
6924
            gen_load_fpr64(ctx, fp0, fs);
6925
            gen_load_fpr64(ctx, fp1, ft);
6926
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6927
            tcg_temp_free_i64(fp1);
6928
            gen_store_fpr64(ctx, fp0, fd);
6929
            tcg_temp_free_i64(fp0);
6930
        }
6931
        opn = "sub.ps";
6932
        break;
6933
    case FOP(2, 22):
6934
        check_cp1_64bitmode(ctx);
6935
        {
6936
            TCGv_i64 fp0 = tcg_temp_new_i64();
6937
            TCGv_i64 fp1 = tcg_temp_new_i64();
6938

    
6939
            gen_load_fpr64(ctx, fp0, fs);
6940
            gen_load_fpr64(ctx, fp1, ft);
6941
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6942
            tcg_temp_free_i64(fp1);
6943
            gen_store_fpr64(ctx, fp0, fd);
6944
            tcg_temp_free_i64(fp0);
6945
        }
6946
        opn = "mul.ps";
6947
        break;
6948
    case FOP(5, 22):
6949
        check_cp1_64bitmode(ctx);
6950
        {
6951
            TCGv_i64 fp0 = tcg_temp_new_i64();
6952

    
6953
            gen_load_fpr64(ctx, fp0, fs);
6954
            gen_helper_float_abs_ps(fp0, fp0);
6955
            gen_store_fpr64(ctx, fp0, fd);
6956
            tcg_temp_free_i64(fp0);
6957
        }
6958
        opn = "abs.ps";
6959
        break;
6960
    case FOP(6, 22):
6961
        check_cp1_64bitmode(ctx);
6962
        {
6963
            TCGv_i64 fp0 = tcg_temp_new_i64();
6964

    
6965
            gen_load_fpr64(ctx, fp0, fs);
6966
            gen_store_fpr64(ctx, fp0, fd);
6967
            tcg_temp_free_i64(fp0);
6968
        }
6969
        opn = "mov.ps";
6970
        break;
6971
    case FOP(7, 22):
6972
        check_cp1_64bitmode(ctx);
6973
        {
6974
            TCGv_i64 fp0 = tcg_temp_new_i64();
6975

    
6976
            gen_load_fpr64(ctx, fp0, fs);
6977
            gen_helper_float_chs_ps(fp0, fp0);
6978
            gen_store_fpr64(ctx, fp0, fd);
6979
            tcg_temp_free_i64(fp0);
6980
        }
6981
        opn = "neg.ps";
6982
        break;
6983
    case FOP(17, 22):
6984
        check_cp1_64bitmode(ctx);
6985
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6986
        opn = "movcf.ps";
6987
        break;
6988
    case FOP(18, 22):
6989
        check_cp1_64bitmode(ctx);
6990
        {
6991
            int l1 = gen_new_label();
6992
            TCGv_i64 fp0;
6993

    
6994
            if (ft != 0)
6995
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6996
            fp0 = tcg_temp_new_i64();
6997
            gen_load_fpr64(ctx, fp0, fs);
6998
            gen_store_fpr64(ctx, fp0, fd);
6999
            tcg_temp_free_i64(fp0);
7000
            gen_set_label(l1);
7001
        }
7002
        opn = "movz.ps";
7003
        break;
7004
    case FOP(19, 22):
7005
        check_cp1_64bitmode(ctx);
7006
        {
7007
            int l1 = gen_new_label();
7008
            TCGv_i64 fp0;
7009

    
7010
            if (ft != 0) {
7011
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7012
                fp0 = tcg_temp_new_i64();
7013
                gen_load_fpr64(ctx, fp0, fs);
7014
                gen_store_fpr64(ctx, fp0, fd);
7015
                tcg_temp_free_i64(fp0);
7016
                gen_set_label(l1);
7017
            }
7018
        }
7019
        opn = "movn.ps";
7020
        break;
7021
    case FOP(24, 22):
7022
        check_cp1_64bitmode(ctx);
7023
        {
7024
            TCGv_i64 fp0 = tcg_temp_new_i64();
7025
            TCGv_i64 fp1 = tcg_temp_new_i64();
7026

    
7027
            gen_load_fpr64(ctx, fp0, ft);
7028
            gen_load_fpr64(ctx, fp1, fs);
7029
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7030
            tcg_temp_free_i64(fp1);
7031
            gen_store_fpr64(ctx, fp0, fd);
7032
            tcg_temp_free_i64(fp0);
7033
        }
7034
        opn = "addr.ps";
7035
        break;
7036
    case FOP(26, 22):
7037
        check_cp1_64bitmode(ctx);
7038
        {
7039
            TCGv_i64 fp0 = tcg_temp_new_i64();
7040
            TCGv_i64 fp1 = tcg_temp_new_i64();
7041

    
7042
            gen_load_fpr64(ctx, fp0, ft);
7043
            gen_load_fpr64(ctx, fp1, fs);
7044
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7045
            tcg_temp_free_i64(fp1);
7046
            gen_store_fpr64(ctx, fp0, fd);
7047
            tcg_temp_free_i64(fp0);
7048
        }
7049
        opn = "mulr.ps";
7050
        break;
7051
    case FOP(28, 22):
7052
        check_cp1_64bitmode(ctx);
7053
        {
7054
            TCGv_i64 fp0 = tcg_temp_new_i64();
7055
            TCGv_i64 fp1 = tcg_temp_new_i64();
7056

    
7057
            gen_load_fpr64(ctx, fp0, fs);
7058
            gen_load_fpr64(ctx, fp1, fd);
7059
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7060
            tcg_temp_free_i64(fp1);
7061
            gen_store_fpr64(ctx, fp0, fd);
7062
            tcg_temp_free_i64(fp0);
7063
        }
7064
        opn = "recip2.ps";
7065
        break;
7066
    case FOP(29, 22):
7067
        check_cp1_64bitmode(ctx);
7068
        {
7069
            TCGv_i64 fp0 = tcg_temp_new_i64();
7070

    
7071
            gen_load_fpr64(ctx, fp0, fs);
7072
            gen_helper_float_recip1_ps(fp0, fp0);
7073
            gen_store_fpr64(ctx, fp0, fd);
7074
            tcg_temp_free_i64(fp0);
7075
        }
7076
        opn = "recip1.ps";
7077
        break;
7078
    case FOP(30, 22):
7079
        check_cp1_64bitmode(ctx);
7080
        {
7081
            TCGv_i64 fp0 = tcg_temp_new_i64();
7082

    
7083
            gen_load_fpr64(ctx, fp0, fs);
7084
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7085
            gen_store_fpr64(ctx, fp0, fd);
7086
            tcg_temp_free_i64(fp0);
7087
        }
7088
        opn = "rsqrt1.ps";
7089
        break;
7090
    case FOP(31, 22):
7091
        check_cp1_64bitmode(ctx);
7092
        {
7093
            TCGv_i64 fp0 = tcg_temp_new_i64();
7094
            TCGv_i64 fp1 = tcg_temp_new_i64();
7095

    
7096
            gen_load_fpr64(ctx, fp0, fs);
7097
            gen_load_fpr64(ctx, fp1, ft);
7098
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7099
            tcg_temp_free_i64(fp1);
7100
            gen_store_fpr64(ctx, fp0, fd);
7101
            tcg_temp_free_i64(fp0);
7102
        }
7103
        opn = "rsqrt2.ps";
7104
        break;
7105
    case FOP(32, 22):
7106
        check_cp1_64bitmode(ctx);
7107
        {
7108
            TCGv_i32 fp0 = tcg_temp_new_i32();
7109

    
7110
            gen_load_fpr32h(fp0, fs);
7111
            gen_helper_float_cvts_pu(fp0, fp0);
7112
            gen_store_fpr32(fp0, fd);
7113
            tcg_temp_free_i32(fp0);
7114
        }
7115
        opn = "cvt.s.pu";
7116
        break;
7117
    case FOP(36, 22):
7118
        check_cp1_64bitmode(ctx);
7119
        {
7120
            TCGv_i64 fp0 = tcg_temp_new_i64();
7121

    
7122
            gen_load_fpr64(ctx, fp0, fs);
7123
            gen_helper_float_cvtpw_ps(fp0, fp0);
7124
            gen_store_fpr64(ctx, fp0, fd);
7125
            tcg_temp_free_i64(fp0);
7126
        }
7127
        opn = "cvt.pw.ps";
7128
        break;
7129
    case FOP(40, 22):
7130
        check_cp1_64bitmode(ctx);
7131
        {
7132
            TCGv_i32 fp0 = tcg_temp_new_i32();
7133

    
7134
            gen_load_fpr32(fp0, fs);
7135
            gen_helper_float_cvts_pl(fp0, fp0);
7136
            gen_store_fpr32(fp0, fd);
7137
            tcg_temp_free_i32(fp0);
7138
        }
7139
        opn = "cvt.s.pl";
7140
        break;
7141
    case FOP(44, 22):
7142
        check_cp1_64bitmode(ctx);
7143
        {
7144
            TCGv_i32 fp0 = tcg_temp_new_i32();
7145
            TCGv_i32 fp1 = tcg_temp_new_i32();
7146

    
7147
            gen_load_fpr32(fp0, fs);
7148
            gen_load_fpr32(fp1, ft);
7149
            gen_store_fpr32h(fp0, fd);
7150
            gen_store_fpr32(fp1, fd);
7151
            tcg_temp_free_i32(fp0);
7152
            tcg_temp_free_i32(fp1);
7153
        }
7154
        opn = "pll.ps";
7155
        break;
7156
    case FOP(45, 22):
7157
        check_cp1_64bitmode(ctx);
7158
        {
7159
            TCGv_i32 fp0 = tcg_temp_new_i32();
7160
            TCGv_i32 fp1 = tcg_temp_new_i32();
7161

    
7162
            gen_load_fpr32(fp0, fs);
7163
            gen_load_fpr32h(fp1, ft);
7164
            gen_store_fpr32(fp1, fd);
7165
            gen_store_fpr32h(fp0, fd);
7166
            tcg_temp_free_i32(fp0);
7167
            tcg_temp_free_i32(fp1);
7168
        }
7169
        opn = "plu.ps";
7170
        break;
7171
    case FOP(46, 22):
7172
        check_cp1_64bitmode(ctx);
7173
        {
7174
            TCGv_i32 fp0 = tcg_temp_new_i32();
7175
            TCGv_i32 fp1 = tcg_temp_new_i32();
7176

    
7177
            gen_load_fpr32h(fp0, fs);
7178
            gen_load_fpr32(fp1, ft);
7179
            gen_store_fpr32(fp1, fd);
7180
            gen_store_fpr32h(fp0, fd);
7181
            tcg_temp_free_i32(fp0);
7182
            tcg_temp_free_i32(fp1);
7183
        }
7184
        opn = "pul.ps";
7185
        break;
7186
    case FOP(47, 22):
7187
        check_cp1_64bitmode(ctx);
7188
        {
7189
            TCGv_i32 fp0 = tcg_temp_new_i32();
7190
            TCGv_i32 fp1 = tcg_temp_new_i32();
7191

    
7192
            gen_load_fpr32h(fp0, fs);
7193
            gen_load_fpr32h(fp1, ft);
7194
            gen_store_fpr32(fp1, fd);
7195
            gen_store_fpr32h(fp0, fd);
7196
            tcg_temp_free_i32(fp0);
7197
            tcg_temp_free_i32(fp1);
7198
        }
7199
        opn = "puu.ps";
7200
        break;
7201
    case FOP(48, 22):
7202
    case FOP(49, 22):
7203
    case FOP(50, 22):
7204
    case FOP(51, 22):
7205
    case FOP(52, 22):
7206
    case FOP(53, 22):
7207
    case FOP(54, 22):
7208
    case FOP(55, 22):
7209
    case FOP(56, 22):
7210
    case FOP(57, 22):
7211
    case FOP(58, 22):
7212
    case FOP(59, 22):
7213
    case FOP(60, 22):
7214
    case FOP(61, 22):
7215
    case FOP(62, 22):
7216
    case FOP(63, 22):
7217
        check_cp1_64bitmode(ctx);
7218
        {
7219
            TCGv_i64 fp0 = tcg_temp_new_i64();
7220
            TCGv_i64 fp1 = tcg_temp_new_i64();
7221

    
7222
            gen_load_fpr64(ctx, fp0, fs);
7223
            gen_load_fpr64(ctx, fp1, ft);
7224
            if (ctx->opcode & (1 << 6)) {
7225
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7226
                opn = condnames_abs[func-48];
7227
            } else {
7228
                gen_cmp_ps(func-48, fp0, fp1, cc);
7229
                opn = condnames[func-48];
7230
            }
7231
            tcg_temp_free_i64(fp0);
7232
            tcg_temp_free_i64(fp1);
7233
        }
7234
        break;
7235
    default:
7236
        MIPS_INVAL(opn);
7237
        generate_exception (ctx, EXCP_RI);
7238
        return;
7239
    }
7240
    switch (optype) {
7241
    case BINOP:
7242
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7243
        break;
7244
    case CMPOP:
7245
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7246
        break;
7247
    default:
7248
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7249
        break;
7250
    }
7251
}
7252

    
7253
/* Coprocessor 3 (FPU) */
7254
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7255
                           int fd, int fs, int base, int index)
7256
{
7257
    const char *opn = "extended float load/store";
7258
    int store = 0;
7259
    TCGv t0 = tcg_temp_new();
7260

    
7261
    if (base == 0) {
7262
        gen_load_gpr(t0, index);
7263
    } else if (index == 0) {
7264
        gen_load_gpr(t0, base);
7265
    } else {
7266
        gen_load_gpr(t0, index);
7267
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7268
    }
7269
    /* Don't do NOP if destination is zero: we must perform the actual
7270
       memory access. */
7271
    save_cpu_state(ctx, 0);
7272
    switch (opc) {
7273
    case OPC_LWXC1:
7274
        check_cop1x(ctx);
7275
        {
7276
            TCGv_i32 fp0 = tcg_temp_new_i32();
7277

    
7278
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7279
            tcg_gen_trunc_tl_i32(fp0, t0);
7280
            gen_store_fpr32(fp0, fd);
7281
            tcg_temp_free_i32(fp0);
7282
        }
7283
        opn = "lwxc1";
7284
        break;
7285
    case OPC_LDXC1:
7286
        check_cop1x(ctx);
7287
        check_cp1_registers(ctx, fd);
7288
        {
7289
            TCGv_i64 fp0 = tcg_temp_new_i64();
7290

    
7291
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7292
            gen_store_fpr64(ctx, fp0, fd);
7293
            tcg_temp_free_i64(fp0);
7294
        }
7295
        opn = "ldxc1";
7296
        break;
7297
    case OPC_LUXC1:
7298
        check_cp1_64bitmode(ctx);
7299
        tcg_gen_andi_tl(t0, t0, ~0x7);
7300
        {
7301
            TCGv_i64 fp0 = tcg_temp_new_i64();
7302

    
7303
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7304
            gen_store_fpr64(ctx, fp0, fd);
7305
            tcg_temp_free_i64(fp0);
7306
        }
7307
        opn = "luxc1";
7308
        break;
7309
    case OPC_SWXC1:
7310
        check_cop1x(ctx);
7311
        {
7312
            TCGv_i32 fp0 = tcg_temp_new_i32();
7313
            TCGv t1 = tcg_temp_new();
7314

    
7315
            gen_load_fpr32(fp0, fs);
7316
            tcg_gen_extu_i32_tl(t1, fp0);
7317
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7318
            tcg_temp_free_i32(fp0);
7319
            tcg_temp_free(t1);
7320
        }
7321
        opn = "swxc1";
7322
        store = 1;
7323
        break;
7324
    case OPC_SDXC1:
7325
        check_cop1x(ctx);
7326
        check_cp1_registers(ctx, fs);
7327
        {
7328
            TCGv_i64 fp0 = tcg_temp_new_i64();
7329

    
7330
            gen_load_fpr64(ctx, fp0, fs);
7331
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7332
            tcg_temp_free_i64(fp0);
7333
        }
7334
        opn = "sdxc1";
7335
        store = 1;
7336
        break;
7337
    case OPC_SUXC1:
7338
        check_cp1_64bitmode(ctx);
7339
        tcg_gen_andi_tl(t0, t0, ~0x7);
7340
        {
7341
            TCGv_i64 fp0 = tcg_temp_new_i64();
7342

    
7343
            gen_load_fpr64(ctx, fp0, fs);
7344
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7345
            tcg_temp_free_i64(fp0);
7346
        }
7347
        opn = "suxc1";
7348
        store = 1;
7349
        break;
7350
    }
7351
    tcg_temp_free(t0);
7352
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7353
               regnames[index], regnames[base]);
7354
}
7355

    
7356
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7357
                            int fd, int fr, int fs, int ft)
7358
{
7359
    const char *opn = "flt3_arith";
7360

    
7361
    switch (opc) {
7362
    case OPC_ALNV_PS:
7363
        check_cp1_64bitmode(ctx);
7364
        {
7365
            TCGv t0 = tcg_temp_local_new();
7366
            TCGv_i32 fp = tcg_temp_new_i32();
7367
            TCGv_i32 fph = tcg_temp_new_i32();
7368
            int l1 = gen_new_label();
7369
            int l2 = gen_new_label();
7370

    
7371
            gen_load_gpr(t0, fr);
7372
            tcg_gen_andi_tl(t0, t0, 0x7);
7373

    
7374
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7375
            gen_load_fpr32(fp, fs);
7376
            gen_load_fpr32h(fph, fs);
7377
            gen_store_fpr32(fp, fd);
7378
            gen_store_fpr32h(fph, fd);
7379
            tcg_gen_br(l2);
7380
            gen_set_label(l1);
7381
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7382
            tcg_temp_free(t0);
7383
#ifdef TARGET_WORDS_BIGENDIAN
7384
            gen_load_fpr32(fp, fs);
7385
            gen_load_fpr32h(fph, ft);
7386
            gen_store_fpr32h(fp, fd);
7387
            gen_store_fpr32(fph, fd);
7388
#else
7389
            gen_load_fpr32h(fph, fs);
7390
            gen_load_fpr32(fp, ft);
7391
            gen_store_fpr32(fph, fd);
7392
            gen_store_fpr32h(fp, fd);
7393
#endif
7394
            gen_set_label(l2);
7395
            tcg_temp_free_i32(fp);
7396
            tcg_temp_free_i32(fph);
7397
        }
7398
        opn = "alnv.ps";
7399
        break;
7400
    case OPC_MADD_S:
7401
        check_cop1x(ctx);
7402
        {
7403
            TCGv_i32 fp0 = tcg_temp_new_i32();
7404
            TCGv_i32 fp1 = tcg_temp_new_i32();
7405
            TCGv_i32 fp2 = tcg_temp_new_i32();
7406

    
7407
            gen_load_fpr32(fp0, fs);
7408
            gen_load_fpr32(fp1, ft);
7409
            gen_load_fpr32(fp2, fr);
7410
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7411
            tcg_temp_free_i32(fp0);
7412
            tcg_temp_free_i32(fp1);
7413
            gen_store_fpr32(fp2, fd);
7414
            tcg_temp_free_i32(fp2);
7415
        }
7416
        opn = "madd.s";
7417
        break;
7418
    case OPC_MADD_D:
7419
        check_cop1x(ctx);
7420
        check_cp1_registers(ctx, fd | fs | ft | fr);
7421
        {
7422
            TCGv_i64 fp0 = tcg_temp_new_i64();
7423
            TCGv_i64 fp1 = tcg_temp_new_i64();
7424
            TCGv_i64 fp2 = tcg_temp_new_i64();
7425

    
7426
            gen_load_fpr64(ctx, fp0, fs);
7427
            gen_load_fpr64(ctx, fp1, ft);
7428
            gen_load_fpr64(ctx, fp2, fr);
7429
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7430
            tcg_temp_free_i64(fp0);
7431
            tcg_temp_free_i64(fp1);
7432
            gen_store_fpr64(ctx, fp2, fd);
7433
            tcg_temp_free_i64(fp2);
7434
        }
7435
        opn = "madd.d";
7436
        break;
7437
    case OPC_MADD_PS:
7438
        check_cp1_64bitmode(ctx);
7439
        {
7440
            TCGv_i64 fp0 = tcg_temp_new_i64();
7441
            TCGv_i64 fp1 = tcg_temp_new_i64();
7442
            TCGv_i64 fp2 = tcg_temp_new_i64();
7443

    
7444
            gen_load_fpr64(ctx, fp0, fs);
7445
            gen_load_fpr64(ctx, fp1, ft);
7446
            gen_load_fpr64(ctx, fp2, fr);
7447
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7448
            tcg_temp_free_i64(fp0);
7449
            tcg_temp_free_i64(fp1);
7450
            gen_store_fpr64(ctx, fp2, fd);
7451
            tcg_temp_free_i64(fp2);
7452
        }
7453
        opn = "madd.ps";
7454
        break;
7455
    case OPC_MSUB_S:
7456
        check_cop1x(ctx);
7457
        {
7458
            TCGv_i32 fp0 = tcg_temp_new_i32();
7459
            TCGv_i32 fp1 = tcg_temp_new_i32();
7460
            TCGv_i32 fp2 = tcg_temp_new_i32();
7461

    
7462
            gen_load_fpr32(fp0, fs);
7463
            gen_load_fpr32(fp1, ft);
7464
            gen_load_fpr32(fp2, fr);
7465
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7466
            tcg_temp_free_i32(fp0);
7467
            tcg_temp_free_i32(fp1);
7468
            gen_store_fpr32(fp2, fd);
7469
            tcg_temp_free_i32(fp2);
7470
        }
7471
        opn = "msub.s";
7472
        break;
7473
    case OPC_MSUB_D:
7474
        check_cop1x(ctx);
7475
        check_cp1_registers(ctx, fd | fs | ft | fr);
7476
        {
7477
            TCGv_i64 fp0 = tcg_temp_new_i64();
7478
            TCGv_i64 fp1 = tcg_temp_new_i64();
7479
            TCGv_i64 fp2 = tcg_temp_new_i64();
7480

    
7481
            gen_load_fpr64(ctx, fp0, fs);
7482
            gen_load_fpr64(ctx, fp1, ft);
7483
            gen_load_fpr64(ctx, fp2, fr);
7484
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7485
            tcg_temp_free_i64(fp0);
7486
            tcg_temp_free_i64(fp1);
7487
            gen_store_fpr64(ctx, fp2, fd);
7488
            tcg_temp_free_i64(fp2);
7489
        }
7490
        opn = "msub.d";
7491
        break;
7492
    case OPC_MSUB_PS:
7493
        check_cp1_64bitmode(ctx);
7494
        {
7495
            TCGv_i64 fp0 = tcg_temp_new_i64();
7496
            TCGv_i64 fp1 = tcg_temp_new_i64();
7497
            TCGv_i64 fp2 = tcg_temp_new_i64();
7498

    
7499
            gen_load_fpr64(ctx, fp0, fs);
7500
            gen_load_fpr64(ctx, fp1, ft);
7501
            gen_load_fpr64(ctx, fp2, fr);
7502
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7503
            tcg_temp_free_i64(fp0);
7504
            tcg_temp_free_i64(fp1);
7505
            gen_store_fpr64(ctx, fp2, fd);
7506
            tcg_temp_free_i64(fp2);
7507
        }
7508
        opn = "msub.ps";
7509
        break;
7510
    case OPC_NMADD_S:
7511
        check_cop1x(ctx);
7512
        {
7513
            TCGv_i32 fp0 = tcg_temp_new_i32();
7514
            TCGv_i32 fp1 = tcg_temp_new_i32();
7515
            TCGv_i32 fp2 = tcg_temp_new_i32();
7516

    
7517
            gen_load_fpr32(fp0, fs);
7518
            gen_load_fpr32(fp1, ft);
7519
            gen_load_fpr32(fp2, fr);
7520
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7521
            tcg_temp_free_i32(fp0);
7522
            tcg_temp_free_i32(fp1);
7523
            gen_store_fpr32(fp2, fd);
7524
            tcg_temp_free_i32(fp2);
7525
        }
7526
        opn = "nmadd.s";
7527
        break;
7528
    case OPC_NMADD_D:
7529
        check_cop1x(ctx);
7530
        check_cp1_registers(ctx, fd | fs | ft | fr);
7531
        {
7532
            TCGv_i64 fp0 = tcg_temp_new_i64();
7533
            TCGv_i64 fp1 = tcg_temp_new_i64();
7534
            TCGv_i64 fp2 = tcg_temp_new_i64();
7535

    
7536
            gen_load_fpr64(ctx, fp0, fs);
7537
            gen_load_fpr64(ctx, fp1, ft);
7538
            gen_load_fpr64(ctx, fp2, fr);
7539
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7540
            tcg_temp_free_i64(fp0);
7541
            tcg_temp_free_i64(fp1);
7542
            gen_store_fpr64(ctx, fp2, fd);
7543
            tcg_temp_free_i64(fp2);
7544
        }
7545
        opn = "nmadd.d";
7546
        break;
7547
    case OPC_NMADD_PS:
7548
        check_cp1_64bitmode(ctx);
7549
        {
7550
            TCGv_i64 fp0 = tcg_temp_new_i64();
7551
            TCGv_i64 fp1 = tcg_temp_new_i64();
7552
            TCGv_i64 fp2 = tcg_temp_new_i64();
7553

    
7554
            gen_load_fpr64(ctx, fp0, fs);
7555
            gen_load_fpr64(ctx, fp1, ft);
7556
            gen_load_fpr64(ctx, fp2, fr);
7557
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7558
            tcg_temp_free_i64(fp0);
7559
            tcg_temp_free_i64(fp1);
7560
            gen_store_fpr64(ctx, fp2, fd);
7561
            tcg_temp_free_i64(fp2);
7562
        }
7563
        opn = "nmadd.ps";
7564
        break;
7565
    case OPC_NMSUB_S:
7566
        check_cop1x(ctx);
7567
        {
7568
            TCGv_i32 fp0 = tcg_temp_new_i32();
7569
            TCGv_i32 fp1 = tcg_temp_new_i32();
7570
            TCGv_i32 fp2 = tcg_temp_new_i32();
7571

    
7572
            gen_load_fpr32(fp0, fs);
7573
            gen_load_fpr32(fp1, ft);
7574
            gen_load_fpr32(fp2, fr);
7575
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7576
            tcg_temp_free_i32(fp0);
7577
            tcg_temp_free_i32(fp1);
7578
            gen_store_fpr32(fp2, fd);
7579
            tcg_temp_free_i32(fp2);
7580
        }
7581
        opn = "nmsub.s";
7582
        break;
7583
    case OPC_NMSUB_D:
7584
        check_cop1x(ctx);
7585
        check_cp1_registers(ctx, fd | fs | ft | fr);
7586
        {
7587
            TCGv_i64 fp0 = tcg_temp_new_i64();
7588
            TCGv_i64 fp1 = tcg_temp_new_i64();
7589
            TCGv_i64 fp2 = tcg_temp_new_i64();
7590

    
7591
            gen_load_fpr64(ctx, fp0, fs);
7592
            gen_load_fpr64(ctx, fp1, ft);
7593
            gen_load_fpr64(ctx, fp2, fr);
7594
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7595
            tcg_temp_free_i64(fp0);
7596
            tcg_temp_free_i64(fp1);
7597
            gen_store_fpr64(ctx, fp2, fd);
7598
            tcg_temp_free_i64(fp2);
7599
        }
7600
        opn = "nmsub.d";
7601
        break;
7602
    case OPC_NMSUB_PS:
7603
        check_cp1_64bitmode(ctx);
7604
        {
7605
            TCGv_i64 fp0 = tcg_temp_new_i64();
7606
            TCGv_i64 fp1 = tcg_temp_new_i64();
7607
            TCGv_i64 fp2 = tcg_temp_new_i64();
7608

    
7609
            gen_load_fpr64(ctx, fp0, fs);
7610
            gen_load_fpr64(ctx, fp1, ft);
7611
            gen_load_fpr64(ctx, fp2, fr);
7612
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7613
            tcg_temp_free_i64(fp0);
7614
            tcg_temp_free_i64(fp1);
7615
            gen_store_fpr64(ctx, fp2, fd);
7616
            tcg_temp_free_i64(fp2);
7617
        }
7618
        opn = "nmsub.ps";
7619
        break;
7620
    default:
7621
        MIPS_INVAL(opn);
7622
        generate_exception (ctx, EXCP_RI);
7623
        return;
7624
    }
7625
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7626
               fregnames[fs], fregnames[ft]);
7627
}
7628

    
7629
/* ISA extensions (ASEs) */
7630
/* MIPS16 extension to MIPS32 */
7631
/* SmartMIPS extension to MIPS32 */
7632

    
7633
#if defined(TARGET_MIPS64)
7634

    
7635
/* MDMX extension to MIPS64 */
7636

    
7637
#endif
7638

    
7639
static void decode_opc (CPUState *env, DisasContext *ctx)
7640
{
7641
    int32_t offset;
7642
    int rs, rt, rd, sa;
7643
    uint32_t op, op1, op2;
7644
    int16_t imm;
7645

    
7646
    /* make sure instructions are on a word boundary */
7647
    if (ctx->pc & 0x3) {
7648
        env->CP0_BadVAddr = ctx->pc;
7649
        generate_exception(ctx, EXCP_AdEL);
7650
        return;
7651
    }
7652

    
7653
    /* Handle blikely not taken case */
7654
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7655
        int l1 = gen_new_label();
7656

    
7657
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7658
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7659
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7660
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7661
        gen_set_label(l1);
7662
    }
7663

    
7664
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
7665
        tcg_gen_debug_insn_start(ctx->pc);
7666

    
7667
    op = MASK_OP_MAJOR(ctx->opcode);
7668
    rs = (ctx->opcode >> 21) & 0x1f;
7669
    rt = (ctx->opcode >> 16) & 0x1f;
7670
    rd = (ctx->opcode >> 11) & 0x1f;
7671
    sa = (ctx->opcode >> 6) & 0x1f;
7672
    imm = (int16_t)ctx->opcode;
7673
    switch (op) {
7674
    case OPC_SPECIAL:
7675
        op1 = MASK_SPECIAL(ctx->opcode);
7676
        switch (op1) {
7677
        case OPC_SLL:          /* Shift with immediate */
7678
        case OPC_SRA:
7679
        case OPC_SRL:
7680
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7681
            break;
7682
        case OPC_MOVN:         /* Conditional move */
7683
        case OPC_MOVZ:
7684
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7685
            gen_cond_move(env, op1, rd, rs, rt);
7686
            break;
7687
        case OPC_ADD ... OPC_SUBU:
7688
            gen_arith(env, ctx, op1, rd, rs, rt);
7689
            break;
7690
        case OPC_SLLV:         /* Shifts */
7691
        case OPC_SRLV:
7692
        case OPC_SRAV:
7693
            gen_shift(env, ctx, op1, rd, rs, rt);
7694
            break;
7695
        case OPC_SLT:          /* Set on less than */
7696
        case OPC_SLTU:
7697
            gen_slt(env, op1, rd, rs, rt);
7698
            break;
7699
        case OPC_AND:          /* Logic*/
7700
        case OPC_OR:
7701
        case OPC_NOR:
7702
        case OPC_XOR:
7703
            gen_logic(env, op1, rd, rs, rt);
7704
            break;
7705
        case OPC_MULT ... OPC_DIVU:
7706
            if (sa) {
7707
                check_insn(env, ctx, INSN_VR54XX);
7708
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7709
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7710
            } else
7711
                gen_muldiv(ctx, op1, rs, rt);
7712
            break;
7713
        case OPC_JR ... OPC_JALR:
7714
            gen_compute_branch(ctx, op1, rs, rd, sa);
7715
            return;
7716
        case OPC_TGE ... OPC_TEQ: /* Traps */
7717
        case OPC_TNE:
7718
            gen_trap(ctx, op1, rs, rt, -1);
7719
            break;
7720
        case OPC_MFHI:          /* Move from HI/LO */
7721
        case OPC_MFLO:
7722
            gen_HILO(ctx, op1, rd);
7723
            break;
7724
        case OPC_MTHI:
7725
        case OPC_MTLO:          /* Move to HI/LO */
7726
            gen_HILO(ctx, op1, rs);
7727
            break;
7728
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7729
#ifdef MIPS_STRICT_STANDARD
7730
            MIPS_INVAL("PMON / selsl");
7731
            generate_exception(ctx, EXCP_RI);
7732
#else
7733
            gen_helper_0i(pmon, sa);
7734
#endif
7735
            break;
7736
        case OPC_SYSCALL:
7737
            generate_exception(ctx, EXCP_SYSCALL);
7738
            ctx->bstate = BS_STOP;
7739
            break;
7740
        case OPC_BREAK:
7741
            generate_exception(ctx, EXCP_BREAK);
7742
            break;
7743
        case OPC_SPIM:
7744
#ifdef MIPS_STRICT_STANDARD
7745
            MIPS_INVAL("SPIM");
7746
            generate_exception(ctx, EXCP_RI);
7747
#else
7748
           /* Implemented as RI exception for now. */
7749
            MIPS_INVAL("spim (unofficial)");
7750
            generate_exception(ctx, EXCP_RI);
7751
#endif
7752
            break;
7753
        case OPC_SYNC:
7754
            /* Treat as NOP. */
7755
            break;
7756

    
7757
        case OPC_MOVCI:
7758
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7759
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7760
                check_cp1_enabled(ctx);
7761
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7762
                          (ctx->opcode >> 16) & 1);
7763
            } else {
7764
                generate_exception_err(ctx, EXCP_CpU, 1);
7765
            }
7766
            break;
7767

    
7768
#if defined(TARGET_MIPS64)
7769
       /* MIPS64 specific opcodes */
7770
        case OPC_DSLL:
7771
        case OPC_DSRA:
7772
        case OPC_DSRL:
7773
        case OPC_DSLL32:
7774
        case OPC_DSRA32:
7775
        case OPC_DSRL32:
7776
            check_insn(env, ctx, ISA_MIPS3);
7777
            check_mips_64(ctx);
7778
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7779
            break;
7780
        case OPC_DADD ... OPC_DSUBU:
7781
            check_insn(env, ctx, ISA_MIPS3);
7782
            check_mips_64(ctx);
7783
            gen_arith(env, ctx, op1, rd, rs, rt);
7784
            break;
7785
        case OPC_DSLLV:
7786
        case OPC_DSRAV:
7787
        case OPC_DSRLV:
7788
            check_insn(env, ctx, ISA_MIPS3);
7789
            check_mips_64(ctx);
7790
            gen_shift(env, ctx, op1, rd, rs, rt);
7791
            break;
7792
        case OPC_DMULT ... OPC_DDIVU:
7793
            check_insn(env, ctx, ISA_MIPS3);
7794
            check_mips_64(ctx);
7795
            gen_muldiv(ctx, op1, rs, rt);
7796
            break;
7797
#endif
7798
        default:            /* Invalid */
7799
            MIPS_INVAL("special");
7800
            generate_exception(ctx, EXCP_RI);
7801
            break;
7802
        }
7803
        break;
7804
    case OPC_SPECIAL2:
7805
        op1 = MASK_SPECIAL2(ctx->opcode);
7806
        switch (op1) {
7807
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7808
        case OPC_MSUB ... OPC_MSUBU:
7809
            check_insn(env, ctx, ISA_MIPS32);
7810
            gen_muldiv(ctx, op1, rs, rt);
7811
            break;
7812
        case OPC_MUL:
7813
            gen_arith(env, ctx, op1, rd, rs, rt);
7814
            break;
7815
        case OPC_CLO:
7816
        case OPC_CLZ:
7817
            check_insn(env, ctx, ISA_MIPS32);
7818
            gen_cl(ctx, op1, rd, rs);
7819
            break;
7820
        case OPC_SDBBP:
7821
            /* XXX: not clear which exception should be raised
7822
             *      when in debug mode...
7823
             */
7824
            check_insn(env, ctx, ISA_MIPS32);
7825
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7826
                generate_exception(ctx, EXCP_DBp);
7827
            } else {
7828
                generate_exception(ctx, EXCP_DBp);
7829
            }
7830
            /* Treat as NOP. */
7831
            break;
7832
#if defined(TARGET_MIPS64)
7833
        case OPC_DCLO:
7834
        case OPC_DCLZ:
7835
            check_insn(env, ctx, ISA_MIPS64);
7836
            check_mips_64(ctx);
7837
            gen_cl(ctx, op1, rd, rs);
7838
            break;
7839
#endif
7840
        default:            /* Invalid */
7841
            MIPS_INVAL("special2");
7842
            generate_exception(ctx, EXCP_RI);
7843
            break;
7844
        }
7845
        break;
7846
    case OPC_SPECIAL3:
7847
        op1 = MASK_SPECIAL3(ctx->opcode);
7848
        switch (op1) {
7849
        case OPC_EXT:
7850
        case OPC_INS:
7851
            check_insn(env, ctx, ISA_MIPS32R2);
7852
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7853
            break;
7854
        case OPC_BSHFL:
7855
            check_insn(env, ctx, ISA_MIPS32R2);
7856
            op2 = MASK_BSHFL(ctx->opcode);
7857
            gen_bshfl(ctx, op2, rt, rd);
7858
            break;
7859
        case OPC_RDHWR:
7860
            check_insn(env, ctx, ISA_MIPS32R2);
7861
            {
7862
                TCGv t0 = tcg_temp_new();
7863

    
7864
                switch (rd) {
7865
                case 0:
7866
                    save_cpu_state(ctx, 1);
7867
                    gen_helper_rdhwr_cpunum(t0);
7868
                    gen_store_gpr(t0, rt);
7869
                    break;
7870
                case 1:
7871
                    save_cpu_state(ctx, 1);
7872
                    gen_helper_rdhwr_synci_step(t0);
7873
                    gen_store_gpr(t0, rt);
7874
                    break;
7875
                case 2:
7876
                    save_cpu_state(ctx, 1);
7877
                    gen_helper_rdhwr_cc(t0);
7878
                    gen_store_gpr(t0, rt);
7879
                    break;
7880
                case 3:
7881
                    save_cpu_state(ctx, 1);
7882
                    gen_helper_rdhwr_ccres(t0);
7883
                    gen_store_gpr(t0, rt);
7884
                    break;
7885
                case 29:
7886
#if defined(CONFIG_USER_ONLY)
7887
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7888
                    gen_store_gpr(t0, rt);
7889
                    break;
7890
#else
7891
                    /* XXX: Some CPUs implement this in hardware.
7892
                       Not supported yet. */
7893
#endif
7894
                default:            /* Invalid */
7895
                    MIPS_INVAL("rdhwr");
7896
                    generate_exception(ctx, EXCP_RI);
7897
                    break;
7898
                }
7899
                tcg_temp_free(t0);
7900
            }
7901
            break;
7902
        case OPC_FORK:
7903
            check_insn(env, ctx, ASE_MT);
7904
            {
7905
                TCGv t0 = tcg_temp_new();
7906
                TCGv t1 = tcg_temp_new();
7907

    
7908
                gen_load_gpr(t0, rt);
7909
                gen_load_gpr(t1, rs);
7910
                gen_helper_fork(t0, t1);
7911
                tcg_temp_free(t0);
7912
                tcg_temp_free(t1);
7913
            }
7914
            break;
7915
        case OPC_YIELD:
7916
            check_insn(env, ctx, ASE_MT);
7917
            {
7918
                TCGv t0 = tcg_temp_new();
7919

    
7920
                save_cpu_state(ctx, 1);
7921
                gen_load_gpr(t0, rs);
7922
                gen_helper_yield(t0, t0);
7923
                gen_store_gpr(t0, rd);
7924
                tcg_temp_free(t0);
7925
            }
7926
            break;
7927
#if defined(TARGET_MIPS64)
7928
        case OPC_DEXTM ... OPC_DEXT:
7929
        case OPC_DINSM ... OPC_DINS:
7930
            check_insn(env, ctx, ISA_MIPS64R2);
7931
            check_mips_64(ctx);
7932
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7933
            break;
7934
        case OPC_DBSHFL:
7935
            check_insn(env, ctx, ISA_MIPS64R2);
7936
            check_mips_64(ctx);
7937
            op2 = MASK_DBSHFL(ctx->opcode);
7938
            gen_bshfl(ctx, op2, rt, rd);
7939
            break;
7940
#endif
7941
        default:            /* Invalid */
7942
            MIPS_INVAL("special3");
7943
            generate_exception(ctx, EXCP_RI);
7944
            break;
7945
        }
7946
        break;
7947
    case OPC_REGIMM:
7948
        op1 = MASK_REGIMM(ctx->opcode);
7949
        switch (op1) {
7950
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7951
        case OPC_BLTZAL ... OPC_BGEZALL:
7952
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7953
            return;
7954
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7955
        case OPC_TNEI:
7956
            gen_trap(ctx, op1, rs, -1, imm);
7957
            break;
7958
        case OPC_SYNCI:
7959
            check_insn(env, ctx, ISA_MIPS32R2);
7960
            /* Treat as NOP. */
7961
            break;
7962
        default:            /* Invalid */
7963
            MIPS_INVAL("regimm");
7964
            generate_exception(ctx, EXCP_RI);
7965
            break;
7966
        }
7967
        break;
7968
    case OPC_CP0:
7969
        check_cp0_enabled(ctx);
7970
        op1 = MASK_CP0(ctx->opcode);
7971
        switch (op1) {
7972
        case OPC_MFC0:
7973
        case OPC_MTC0:
7974
        case OPC_MFTR:
7975
        case OPC_MTTR:
7976
#if defined(TARGET_MIPS64)
7977
        case OPC_DMFC0:
7978
        case OPC_DMTC0:
7979
#endif
7980
#ifndef CONFIG_USER_ONLY
7981
            gen_cp0(env, ctx, op1, rt, rd);
7982
#endif /* !CONFIG_USER_ONLY */
7983
            break;
7984
        case OPC_C0_FIRST ... OPC_C0_LAST:
7985
#ifndef CONFIG_USER_ONLY
7986
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7987
#endif /* !CONFIG_USER_ONLY */
7988
            break;
7989
        case OPC_MFMC0:
7990
#ifndef CONFIG_USER_ONLY
7991
            {
7992
                TCGv t0 = tcg_temp_new();
7993

    
7994
                op2 = MASK_MFMC0(ctx->opcode);
7995
                switch (op2) {
7996
                case OPC_DMT:
7997
                    check_insn(env, ctx, ASE_MT);
7998
                    gen_helper_dmt(t0, t0);
7999
                    gen_store_gpr(t0, rt);
8000
                    break;
8001
                case OPC_EMT:
8002
                    check_insn(env, ctx, ASE_MT);
8003
                    gen_helper_emt(t0, t0);
8004
                    gen_store_gpr(t0, rt);
8005
                    break;
8006
                case OPC_DVPE:
8007
                    check_insn(env, ctx, ASE_MT);
8008
                    gen_helper_dvpe(t0, t0);
8009
                    gen_store_gpr(t0, rt);
8010
                    break;
8011
                case OPC_EVPE:
8012
                    check_insn(env, ctx, ASE_MT);
8013
                    gen_helper_evpe(t0, t0);
8014
                    gen_store_gpr(t0, rt);
8015
                    break;
8016
                case OPC_DI:
8017
                    check_insn(env, ctx, ISA_MIPS32R2);
8018
                    save_cpu_state(ctx, 1);
8019
                    gen_helper_di(t0);
8020
                    gen_store_gpr(t0, rt);
8021
                    /* Stop translation as we may have switched the execution mode */
8022
                    ctx->bstate = BS_STOP;
8023
                    break;
8024
                case OPC_EI:
8025
                    check_insn(env, ctx, ISA_MIPS32R2);
8026
                    save_cpu_state(ctx, 1);
8027
                    gen_helper_ei(t0);
8028
                    gen_store_gpr(t0, rt);
8029
                    /* Stop translation as we may have switched the execution mode */
8030
                    ctx->bstate = BS_STOP;
8031
                    break;
8032
                default:            /* Invalid */
8033
                    MIPS_INVAL("mfmc0");
8034
                    generate_exception(ctx, EXCP_RI);
8035
                    break;
8036
                }
8037
                tcg_temp_free(t0);
8038
            }
8039
#endif /* !CONFIG_USER_ONLY */
8040
            break;
8041
        case OPC_RDPGPR:
8042
            check_insn(env, ctx, ISA_MIPS32R2);
8043
            gen_load_srsgpr(rt, rd);
8044
            break;
8045
        case OPC_WRPGPR:
8046
            check_insn(env, ctx, ISA_MIPS32R2);
8047
            gen_store_srsgpr(rt, rd);
8048
            break;
8049
        default:
8050
            MIPS_INVAL("cp0");
8051
            generate_exception(ctx, EXCP_RI);
8052
            break;
8053
        }
8054
        break;
8055
    case OPC_ADDI: /* Arithmetic with immediate opcode */
8056
    case OPC_ADDIU:
8057
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8058
         break;
8059
    case OPC_SLTI: /* Set on less than with immediate opcode */
8060
    case OPC_SLTIU:
8061
         gen_slt_imm(env, op, rt, rs, imm);
8062
         break;
8063
    case OPC_ANDI: /* Arithmetic with immediate opcode */
8064
    case OPC_LUI:
8065
    case OPC_ORI:
8066
    case OPC_XORI:
8067
         gen_logic_imm(env, op, rt, rs, imm);
8068
         break;
8069
    case OPC_J ... OPC_JAL: /* Jump */
8070
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8071
         gen_compute_branch(ctx, op, rs, rt, offset);
8072
         return;
8073
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8074
    case OPC_BEQL ... OPC_BGTZL:
8075
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8076
         return;
8077
    case OPC_LB ... OPC_LWR: /* Load and stores */
8078
    case OPC_SB ... OPC_SW:
8079
    case OPC_SWR:
8080
    case OPC_LL:
8081
         gen_ldst(ctx, op, rt, rs, imm);
8082
         break;
8083
    case OPC_SC:
8084
         gen_st_cond(ctx, op, rt, rs, imm);
8085
         break;
8086
    case OPC_CACHE:
8087
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8088
        /* Treat as NOP. */
8089
        break;
8090
    case OPC_PREF:
8091
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8092
        /* Treat as NOP. */
8093
        break;
8094

    
8095
    /* Floating point (COP1). */
8096
    case OPC_LWC1:
8097
    case OPC_LDC1:
8098
    case OPC_SWC1:
8099
    case OPC_SDC1:
8100
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8101
            check_cp1_enabled(ctx);
8102
            gen_flt_ldst(ctx, op, rt, rs, imm);
8103
        } else {
8104
            generate_exception_err(ctx, EXCP_CpU, 1);
8105
        }
8106
        break;
8107

    
8108
    case OPC_CP1:
8109
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8110
            check_cp1_enabled(ctx);
8111
            op1 = MASK_CP1(ctx->opcode);
8112
            switch (op1) {
8113
            case OPC_MFHC1:
8114
            case OPC_MTHC1:
8115
                check_insn(env, ctx, ISA_MIPS32R2);
8116
            case OPC_MFC1:
8117
            case OPC_CFC1:
8118
            case OPC_MTC1:
8119
            case OPC_CTC1:
8120
                gen_cp1(ctx, op1, rt, rd);
8121
                break;
8122
#if defined(TARGET_MIPS64)
8123
            case OPC_DMFC1:
8124
            case OPC_DMTC1:
8125
                check_insn(env, ctx, ISA_MIPS3);
8126
                gen_cp1(ctx, op1, rt, rd);
8127
                break;
8128
#endif
8129
            case OPC_BC1ANY2:
8130
            case OPC_BC1ANY4:
8131
                check_cop1x(ctx);
8132
                check_insn(env, ctx, ASE_MIPS3D);
8133
                /* fall through */
8134
            case OPC_BC1:
8135
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8136
                                    (rt >> 2) & 0x7, imm << 2);
8137
                return;
8138
            case OPC_S_FMT:
8139
            case OPC_D_FMT:
8140
            case OPC_W_FMT:
8141
            case OPC_L_FMT:
8142
            case OPC_PS_FMT:
8143
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8144
                           (imm >> 8) & 0x7);
8145
                break;
8146
            default:
8147
                MIPS_INVAL("cp1");
8148
                generate_exception (ctx, EXCP_RI);
8149
                break;
8150
            }
8151
        } else {
8152
            generate_exception_err(ctx, EXCP_CpU, 1);
8153
        }
8154
        break;
8155

    
8156
    /* COP2.  */
8157
    case OPC_LWC2:
8158
    case OPC_LDC2:
8159
    case OPC_SWC2:
8160
    case OPC_SDC2:
8161
    case OPC_CP2:
8162
        /* COP2: Not implemented. */
8163
        generate_exception_err(ctx, EXCP_CpU, 2);
8164
        break;
8165

    
8166
    case OPC_CP3:
8167
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8168
            check_cp1_enabled(ctx);
8169
            op1 = MASK_CP3(ctx->opcode);
8170
            switch (op1) {
8171
            case OPC_LWXC1:
8172
            case OPC_LDXC1:
8173
            case OPC_LUXC1:
8174
            case OPC_SWXC1:
8175
            case OPC_SDXC1:
8176
            case OPC_SUXC1:
8177
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8178
                break;
8179
            case OPC_PREFX:
8180
                /* Treat as NOP. */
8181
                break;
8182
            case OPC_ALNV_PS:
8183
            case OPC_MADD_S:
8184
            case OPC_MADD_D:
8185
            case OPC_MADD_PS:
8186
            case OPC_MSUB_S:
8187
            case OPC_MSUB_D:
8188
            case OPC_MSUB_PS:
8189
            case OPC_NMADD_S:
8190
            case OPC_NMADD_D:
8191
            case OPC_NMADD_PS:
8192
            case OPC_NMSUB_S:
8193
            case OPC_NMSUB_D:
8194
            case OPC_NMSUB_PS:
8195
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8196
                break;
8197
            default:
8198
                MIPS_INVAL("cp3");
8199
                generate_exception (ctx, EXCP_RI);
8200
                break;
8201
            }
8202
        } else {
8203
            generate_exception_err(ctx, EXCP_CpU, 1);
8204
        }
8205
        break;
8206

    
8207
#if defined(TARGET_MIPS64)
8208
    /* MIPS64 opcodes */
8209
    case OPC_LWU:
8210
    case OPC_LDL ... OPC_LDR:
8211
    case OPC_SDL ... OPC_SDR:
8212
    case OPC_LLD:
8213
    case OPC_LD:
8214
    case OPC_SD:
8215
        check_insn(env, ctx, ISA_MIPS3);
8216
        check_mips_64(ctx);
8217
        gen_ldst(ctx, op, rt, rs, imm);
8218
        break;
8219
    case OPC_SCD:
8220
        check_insn(env, ctx, ISA_MIPS3);
8221
        check_mips_64(ctx);
8222
        gen_st_cond(ctx, op, rt, rs, imm);
8223
        break;
8224
    case OPC_DADDI:
8225
    case OPC_DADDIU:
8226
        check_insn(env, ctx, ISA_MIPS3);
8227
        check_mips_64(ctx);
8228
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8229
        break;
8230
#endif
8231
    case OPC_JALX:
8232
        check_insn(env, ctx, ASE_MIPS16);
8233
        /* MIPS16: Not implemented. */
8234
    case OPC_MDMX:
8235
        check_insn(env, ctx, ASE_MDMX);
8236
        /* MDMX: Not implemented. */
8237
    default:            /* Invalid */
8238
        MIPS_INVAL("major opcode");
8239
        generate_exception(ctx, EXCP_RI);
8240
        break;
8241
    }
8242
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8243
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8244
        /* Branches completion */
8245
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8246
        ctx->bstate = BS_BRANCH;
8247
        save_cpu_state(ctx, 0);
8248
        /* FIXME: Need to clear can_do_io.  */
8249
        switch (hflags) {
8250
        case MIPS_HFLAG_B:
8251
            /* unconditional branch */
8252
            MIPS_DEBUG("unconditional branch");
8253
            gen_goto_tb(ctx, 0, ctx->btarget);
8254
            break;
8255
        case MIPS_HFLAG_BL:
8256
            /* blikely taken case */
8257
            MIPS_DEBUG("blikely branch taken");
8258
            gen_goto_tb(ctx, 0, ctx->btarget);
8259
            break;
8260
        case MIPS_HFLAG_BC:
8261
            /* Conditional branch */
8262
            MIPS_DEBUG("conditional branch");
8263
            {
8264
                int l1 = gen_new_label();
8265

    
8266
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8267
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8268
                gen_set_label(l1);
8269
                gen_goto_tb(ctx, 0, ctx->btarget);
8270
            }
8271
            break;
8272
        case MIPS_HFLAG_BR:
8273
            /* unconditional branch to register */
8274
            MIPS_DEBUG("branch to register");
8275
            tcg_gen_mov_tl(cpu_PC, btarget);
8276
            if (ctx->singlestep_enabled) {
8277
                save_cpu_state(ctx, 0);
8278
                gen_helper_0i(raise_exception, EXCP_DEBUG);
8279
            }
8280
            tcg_gen_exit_tb(0);
8281
            break;
8282
        default:
8283
            MIPS_DEBUG("unknown branch");
8284
            break;
8285
        }
8286
    }
8287
}
8288

    
8289
static inline void
8290
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8291
                                int search_pc)
8292
{
8293
    DisasContext ctx;
8294
    target_ulong pc_start;
8295
    uint16_t *gen_opc_end;
8296
    CPUBreakpoint *bp;
8297
    int j, lj = -1;
8298
    int num_insns;
8299
    int max_insns;
8300

    
8301
    if (search_pc)
8302
        qemu_log("search pc %d\n", search_pc);
8303

    
8304
    pc_start = tb->pc;
8305
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8306
    ctx.pc = pc_start;
8307
    ctx.saved_pc = -1;
8308
    ctx.singlestep_enabled = env->singlestep_enabled;
8309
    ctx.tb = tb;
8310
    ctx.bstate = BS_NONE;
8311
    /* Restore delay slot state from the tb context.  */
8312
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8313
    restore_cpu_state(env, &ctx);
8314
#ifdef CONFIG_USER_ONLY
8315
        ctx.mem_idx = MIPS_HFLAG_UM;
8316
#else
8317
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8318
#endif
8319
    num_insns = 0;
8320
    max_insns = tb->cflags & CF_COUNT_MASK;
8321
    if (max_insns == 0)
8322
        max_insns = CF_COUNT_MASK;
8323
#ifdef DEBUG_DISAS
8324
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8325
    /* FIXME: This may print out stale hflags from env... */
8326
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8327
#endif
8328
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8329
    gen_icount_start();
8330
    while (ctx.bstate == BS_NONE) {
8331
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8332
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8333
                if (bp->pc == ctx.pc) {
8334
                    save_cpu_state(&ctx, 1);
8335
                    ctx.bstate = BS_BRANCH;
8336
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8337
                    /* Include the breakpoint location or the tb won't
8338
                     * be flushed when it must be.  */
8339
                    ctx.pc += 4;
8340
                    goto done_generating;
8341
                }
8342
            }
8343
        }
8344

    
8345
        if (search_pc) {
8346
            j = gen_opc_ptr - gen_opc_buf;
8347
            if (lj < j) {
8348
                lj++;
8349
                while (lj < j)
8350
                    gen_opc_instr_start[lj++] = 0;
8351
            }
8352
            gen_opc_pc[lj] = ctx.pc;
8353
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8354
            gen_opc_instr_start[lj] = 1;
8355
            gen_opc_icount[lj] = num_insns;
8356
        }
8357
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8358
            gen_io_start();
8359
        ctx.opcode = ldl_code(ctx.pc);
8360
        decode_opc(env, &ctx);
8361
        ctx.pc += 4;
8362
        num_insns++;
8363

    
8364
        /* Execute a branch and its delay slot as a single instruction.
8365
           This is what GDB expects and is consistent with what the
8366
           hardware does (e.g. if a delay slot instruction faults, the
8367
           reported PC is the PC of the branch).  */
8368
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
8369
            break;
8370

    
8371
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8372
            break;
8373

    
8374
        if (gen_opc_ptr >= gen_opc_end)
8375
            break;
8376

    
8377
        if (num_insns >= max_insns)
8378
            break;
8379

    
8380
        if (singlestep)
8381
            break;
8382
    }
8383
    if (tb->cflags & CF_LAST_IO)
8384
        gen_io_end();
8385
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
8386
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8387
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8388
    } else {
8389
        switch (ctx.bstate) {
8390
        case BS_STOP:
8391
            gen_helper_interrupt_restart();
8392
            gen_goto_tb(&ctx, 0, ctx.pc);
8393
            break;
8394
        case BS_NONE:
8395
            save_cpu_state(&ctx, 0);
8396
            gen_goto_tb(&ctx, 0, ctx.pc);
8397
            break;
8398
        case BS_EXCP:
8399
            gen_helper_interrupt_restart();
8400
            tcg_gen_exit_tb(0);
8401
            break;
8402
        case BS_BRANCH:
8403
        default:
8404
            break;
8405
        }
8406
    }
8407
done_generating:
8408
    gen_icount_end(tb, num_insns);
8409
    *gen_opc_ptr = INDEX_op_end;
8410
    if (search_pc) {
8411
        j = gen_opc_ptr - gen_opc_buf;
8412
        lj++;
8413
        while (lj <= j)
8414
            gen_opc_instr_start[lj++] = 0;
8415
    } else {
8416
        tb->size = ctx.pc - pc_start;
8417
        tb->icount = num_insns;
8418
    }
8419
#ifdef DEBUG_DISAS
8420
    LOG_DISAS("\n");
8421
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8422
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8423
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8424
        qemu_log("\n");
8425
    }
8426
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8427
#endif
8428
}
8429

    
8430
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8431
{
8432
    gen_intermediate_code_internal(env, tb, 0);
8433
}
8434

    
8435
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8436
{
8437
    gen_intermediate_code_internal(env, tb, 1);
8438
}
8439

    
8440
static void fpu_dump_state(CPUState *env, FILE *f,
8441
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8442
                           int flags)
8443
{
8444
    int i;
8445
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8446

    
8447
#define printfpr(fp)                                                        \
8448
    do {                                                                    \
8449
        if (is_fpu64)                                                       \
8450
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8451
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8452
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8453
        else {                                                              \
8454
            fpr_t tmp;                                                      \
8455
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8456
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8457
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8458
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8459
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8460
        }                                                                   \
8461
    } while(0)
8462

    
8463

    
8464
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8465
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8466
                get_float_exception_flags(&env->active_fpu.fp_status));
8467
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8468
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8469
        printfpr(&env->active_fpu.fpr[i]);
8470
    }
8471

    
8472
#undef printfpr
8473
}
8474

    
8475
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8476
/* Debug help: The architecture requires 32bit code to maintain proper
8477
   sign-extended values on 64bit machines.  */
8478

    
8479
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8480

    
8481
static void
8482
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8483
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8484
                                int flags)
8485
{
8486
    int i;
8487

    
8488
    if (!SIGN_EXT_P(env->active_tc.PC))
8489
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8490
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8491
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8492
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8493
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8494
    if (!SIGN_EXT_P(env->btarget))
8495
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8496

    
8497
    for (i = 0; i < 32; i++) {
8498
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8499
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8500
    }
8501

    
8502
    if (!SIGN_EXT_P(env->CP0_EPC))
8503
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8504
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8505
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8506
}
8507
#endif
8508

    
8509
void cpu_dump_state (CPUState *env, FILE *f,
8510
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8511
                     int flags)
8512
{
8513
    int i;
8514

    
8515
    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",
8516
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8517
                env->hflags, env->btarget, env->bcond);
8518
    for (i = 0; i < 32; i++) {
8519
        if ((i & 3) == 0)
8520
            cpu_fprintf(f, "GPR%02d:", i);
8521
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8522
        if ((i & 3) == 3)
8523
            cpu_fprintf(f, "\n");
8524
    }
8525

    
8526
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8527
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8528
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8529
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8530
    if (env->hflags & MIPS_HFLAG_FPU)
8531
        fpu_dump_state(env, f, cpu_fprintf, flags);
8532
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8533
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8534
#endif
8535
}
8536

    
8537
static void mips_tcg_init(void)
8538
{
8539
    int i;
8540
    static int inited;
8541

    
8542
    /* Initialize various static tables. */
8543
    if (inited)
8544
        return;
8545

    
8546
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8547
    TCGV_UNUSED(cpu_gpr[0]);
8548
    for (i = 1; i < 32; i++)
8549
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8550
                                        offsetof(CPUState, active_tc.gpr[i]),
8551
                                        regnames[i]);
8552
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8553
                                offsetof(CPUState, active_tc.PC), "PC");
8554
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8555
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8556
                                       offsetof(CPUState, active_tc.HI[i]),
8557
                                       regnames_HI[i]);
8558
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8559
                                       offsetof(CPUState, active_tc.LO[i]),
8560
                                       regnames_LO[i]);
8561
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8562
                                        offsetof(CPUState, active_tc.ACX[i]),
8563
                                        regnames_ACX[i]);
8564
    }
8565
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8566
                                     offsetof(CPUState, active_tc.DSPControl),
8567
                                     "DSPControl");
8568
    bcond = tcg_global_mem_new(TCG_AREG0,
8569
                               offsetof(CPUState, bcond), "bcond");
8570
    btarget = tcg_global_mem_new(TCG_AREG0,
8571
                                 offsetof(CPUState, btarget), "btarget");
8572
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8573
                                    offsetof(CPUState, hflags), "hflags");
8574

    
8575
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8576
                                      offsetof(CPUState, active_fpu.fcr0),
8577
                                      "fcr0");
8578
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8579
                                       offsetof(CPUState, active_fpu.fcr31),
8580
                                       "fcr31");
8581

    
8582
    /* register helpers */
8583
#define GEN_HELPER 2
8584
#include "helper.h"
8585

    
8586
    inited = 1;
8587
}
8588

    
8589
#include "translate_init.c"
8590

    
8591
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8592
{
8593
    CPUMIPSState *env;
8594
    const mips_def_t *def;
8595

    
8596
    def = cpu_mips_find_by_name(cpu_model);
8597
    if (!def)
8598
        return NULL;
8599
    env = qemu_mallocz(sizeof(CPUMIPSState));
8600
    env->cpu_model = def;
8601

    
8602
    cpu_exec_init(env);
8603
    env->cpu_model_str = cpu_model;
8604
    mips_tcg_init();
8605
    cpu_reset(env);
8606
    qemu_init_vcpu(env);
8607
    return env;
8608
}
8609

    
8610
void cpu_reset (CPUMIPSState *env)
8611
{
8612
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8613
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8614
        log_cpu_state(env, 0);
8615
    }
8616

    
8617
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8618

    
8619
    tlb_flush(env, 1);
8620

    
8621
    /* Minimal init */
8622
#if defined(CONFIG_USER_ONLY)
8623
    env->hflags = MIPS_HFLAG_UM;
8624
    /* Enable access to the SYNCI_Step register.  */
8625
    env->CP0_HWREna |= (1 << 1);
8626
#else
8627
    if (env->hflags & MIPS_HFLAG_BMASK) {
8628
        /* If the exception was raised from a delay slot,
8629
           come back to the jump.  */
8630
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8631
    } else {
8632
        env->CP0_ErrorEPC = env->active_tc.PC;
8633
    }
8634
    env->active_tc.PC = (int32_t)0xBFC00000;
8635
    env->CP0_Wired = 0;
8636
    /* SMP not implemented */
8637
    env->CP0_EBase = 0x80000000;
8638
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8639
    /* vectored interrupts not implemented, timer on int 7,
8640
       no performance counters. */
8641
    env->CP0_IntCtl = 0xe0000000;
8642
    {
8643
        int i;
8644

    
8645
        for (i = 0; i < 7; i++) {
8646
            env->CP0_WatchLo[i] = 0;
8647
            env->CP0_WatchHi[i] = 0x80000000;
8648
        }
8649
        env->CP0_WatchLo[7] = 0;
8650
        env->CP0_WatchHi[7] = 0;
8651
    }
8652
    /* Count register increments in debug mode, EJTAG version 1 */
8653
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8654
    env->hflags = MIPS_HFLAG_CP0;
8655
#endif
8656
    env->exception_index = EXCP_NONE;
8657
    cpu_mips_register(env, env->cpu_model);
8658
}
8659

    
8660
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8661
                unsigned long searched_pc, int pc_pos, void *puc)
8662
{
8663
    env->active_tc.PC = gen_opc_pc[pc_pos];
8664
    env->hflags &= ~MIPS_HFLAG_BMASK;
8665
    env->hflags |= gen_opc_hflags[pc_pos];
8666
}