Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 344b983d

History | View | Annotate | Download (250.6 kB)

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

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

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

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

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

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

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

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

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

    
188
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
189

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
437
#include "gen-icount.h"
438

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

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

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

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

    
463
typedef struct DisasContext {
464
    struct TranslationBlock *tb;
465
    target_ulong pc, saved_pc;
466
    uint32_t opcode;
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 t0, TCGv t1)
807
{
808
    tcg_gen_add_tl(t0, t0, t1);
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(t0, t0);
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]);
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]);
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]);
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
        tcg_gen_goto_tb(n);
2465
        gen_save_pc(dest);
2466
        tcg_gen_exit_tb((long)tb + n);
2467
    } else {
2468
        gen_save_pc(dest);
2469
        tcg_gen_exit_tb(0);
2470
    }
2471
}
2472

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

    
2483
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2484
#ifdef MIPS_DEBUG_DISAS
2485
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2486
#endif
2487
        generate_exception(ctx, EXCP_RI);
2488
        goto out;
2489
    }
2490

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

    
2699
    ctx->btarget = btgt;
2700
    if (blink > 0) {
2701
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2702
    }
2703

    
2704
 out:
2705
    tcg_temp_free(t0);
2706
    tcg_temp_free(t1);
2707
}
2708

    
2709
/* special3 bitfield operations */
2710
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2711
                        int rs, int lsb, int msb)
2712
{
2713
    TCGv t0 = tcg_temp_new();
2714
    TCGv t1 = tcg_temp_new();
2715
    target_ulong mask;
2716

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

    
2802
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2803
{
2804
    TCGv t0;
2805

    
2806
    if (rd == 0) {
2807
        /* If no destination, treat it as a NOP. */
2808
        MIPS_DEBUG("NOP");
2809
        return;
2810
    }
2811

    
2812
    t0 = tcg_temp_new();
2813
    gen_load_gpr(t0, rt);
2814
    switch (op2) {
2815
    case OPC_WSBH:
2816
        {
2817
            TCGv t1 = tcg_temp_new();
2818

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

    
2839
            tcg_gen_shri_tl(t1, t0, 8);
2840
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2841
            tcg_gen_shli_tl(t0, t0, 8);
2842
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2843
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2844
            tcg_temp_free(t1);
2845
        }
2846
        break;
2847
    case OPC_DSHD:
2848
        {
2849
            TCGv t1 = tcg_temp_new();
2850

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

    
2872
#ifndef CONFIG_USER_ONLY
2873
/* CP0 (MMU and control) */
2874
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2875
{
2876
    TCGv_i32 t0 = tcg_temp_new_i32();
2877

    
2878
    tcg_gen_ld_i32(t0, cpu_env, off);
2879
    tcg_gen_ext_i32_tl(arg, t0);
2880
    tcg_temp_free_i32(t0);
2881
}
2882

    
2883
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2884
{
2885
    tcg_gen_ld_tl(arg, cpu_env, off);
2886
    tcg_gen_ext32s_tl(arg, arg);
2887
}
2888

    
2889
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2890
{
2891
    TCGv_i32 t0 = tcg_temp_new_i32();
2892

    
2893
    tcg_gen_trunc_tl_i32(t0, arg);
2894
    tcg_gen_st_i32(t0, cpu_env, off);
2895
    tcg_temp_free_i32(t0);
2896
}
2897

    
2898
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2899
{
2900
    tcg_gen_ext32s_tl(arg, arg);
2901
    tcg_gen_st_tl(arg, cpu_env, off);
2902
}
2903

    
2904
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2905
{
2906
    const char *rn = "invalid";
2907

    
2908
    if (sel != 0)
2909
        check_insn(env, ctx, ISA_MIPS32);
2910

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

    
3476
die:
3477
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3478
    generate_exception(ctx, EXCP_RI);
3479
}
3480

    
3481
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3482
{
3483
    const char *rn = "invalid";
3484

    
3485
    if (sel != 0)
3486
        check_insn(env, ctx, ISA_MIPS32);
3487

    
3488
    if (use_icount)
3489
        gen_io_start();
3490

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

    
4071
die:
4072
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4073
    generate_exception(ctx, EXCP_RI);
4074
}
4075

    
4076
#if defined(TARGET_MIPS64)
4077
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4078
{
4079
    const char *rn = "invalid";
4080

    
4081
    if (sel != 0)
4082
        check_insn(env, ctx, ISA_MIPS64);
4083

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

    
4638
die:
4639
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4640
    generate_exception(ctx, EXCP_RI);
4641
}
4642

    
4643
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4644
{
4645
    const char *rn = "invalid";
4646

    
4647
    if (sel != 0)
4648
        check_insn(env, ctx, ISA_MIPS64);
4649

    
4650
    if (use_icount)
4651
        gen_io_start();
4652

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

    
5224
die:
5225
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5226
    generate_exception(ctx, EXCP_RI);
5227
}
5228
#endif /* TARGET_MIPS64 */
5229

    
5230
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5231
                     int u, int sel, int h)
5232
{
5233
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5234
    TCGv t0 = tcg_temp_local_new();
5235

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

    
5361
            gen_load_fpr32(fp0, rt);
5362
            tcg_gen_ext_i32_tl(t0, fp0);
5363
            tcg_temp_free_i32(fp0);
5364
        } else {
5365
            TCGv_i32 fp0 = tcg_temp_new_i32();
5366

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

    
5388
die:
5389
    tcg_temp_free(t0);
5390
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5391
    generate_exception(ctx, EXCP_RI);
5392
}
5393

    
5394
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5395
                     int u, int sel, int h)
5396
{
5397
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5398
    TCGv t0 = tcg_temp_local_new();
5399

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

    
5526
            tcg_gen_trunc_tl_i32(fp0, t0);
5527
            gen_store_fpr32(fp0, rd);
5528
            tcg_temp_free_i32(fp0);
5529
        } else {
5530
            TCGv_i32 fp0 = tcg_temp_new_i32();
5531

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

    
5552
die:
5553
    tcg_temp_free(t0);
5554
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5555
    generate_exception(ctx, EXCP_RI);
5556
}
5557

    
5558
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5559
{
5560
    const char *opn = "ldst";
5561

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

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

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

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

    
5688
    if (cc != 0)
5689
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5690

    
5691
    btarget = ctx->pc + 4 + offset;
5692

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

    
5791
 out:
5792
    tcg_temp_free_i32(t0);
5793
}
5794

    
5795
/* Coprocessor 1 (FPU) */
5796

    
5797
#define FOP(func, fmt) (((fmt) << 21) | (func))
5798

    
5799
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5800
{
5801
    const char *opn = "cp1 move";
5802
    TCGv t0 = tcg_temp_new();
5803

    
5804
    switch (opc) {
5805
    case OPC_MFC1:
5806
        {
5807
            TCGv_i32 fp0 = tcg_temp_new_i32();
5808

    
5809
            gen_load_fpr32(fp0, fs);
5810
            tcg_gen_ext_i32_tl(t0, fp0);
5811
            tcg_temp_free_i32(fp0);
5812
        }
5813
        gen_store_gpr(t0, rt);
5814
        opn = "mfc1";
5815
        break;
5816
    case OPC_MTC1:
5817
        gen_load_gpr(t0, rt);
5818
        {
5819
            TCGv_i32 fp0 = tcg_temp_new_i32();
5820

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

    
5853
            gen_load_fpr32h(fp0, fs);
5854
            tcg_gen_ext_i32_tl(t0, fp0);
5855
            tcg_temp_free_i32(fp0);
5856
        }
5857
        gen_store_gpr(t0, rt);
5858
        opn = "mfhc1";
5859
        break;
5860
    case OPC_MTHC1:
5861
        gen_load_gpr(t0, rt);
5862
        {
5863
            TCGv_i32 fp0 = tcg_temp_new_i32();
5864

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

    
5878
 out:
5879
    tcg_temp_free(t0);
5880
}
5881

    
5882
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5883
{
5884
    int l1;
5885
    TCGCond cond;
5886
    TCGv_i32 t0;
5887

    
5888
    if (rd == 0) {
5889
        /* Treat as NOP. */
5890
        return;
5891
    }
5892

    
5893
    if (tf)
5894
        cond = TCG_COND_EQ;
5895
    else
5896
        cond = TCG_COND_NE;
5897

    
5898
    l1 = gen_new_label();
5899
    t0 = tcg_temp_new_i32();
5900
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5901
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5902
    tcg_temp_free_i32(t0);
5903
    if (rs == 0) {
5904
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5905
    } else {
5906
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5907
    }
5908
    gen_set_label(l1);
5909
}
5910

    
5911
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5912
{
5913
    int cond;
5914
    TCGv_i32 t0 = tcg_temp_new_i32();
5915
    int l1 = gen_new_label();
5916

    
5917
    if (tf)
5918
        cond = TCG_COND_EQ;
5919
    else
5920
        cond = TCG_COND_NE;
5921

    
5922
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5923
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5924
    gen_load_fpr32(t0, fs);
5925
    gen_store_fpr32(t0, fd);
5926
    gen_set_label(l1);
5927
    tcg_temp_free_i32(t0);
5928
}
5929

    
5930
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5931
{
5932
    int cond;
5933
    TCGv_i32 t0 = tcg_temp_new_i32();
5934
    TCGv_i64 fp0;
5935
    int l1 = gen_new_label();
5936

    
5937
    if (tf)
5938
        cond = TCG_COND_EQ;
5939
    else
5940
        cond = TCG_COND_NE;
5941

    
5942
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5943
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5944
    tcg_temp_free_i32(t0);
5945
    fp0 = tcg_temp_new_i64();
5946
    gen_load_fpr64(ctx, fp0, fs);
5947
    gen_store_fpr64(ctx, fp0, fd);
5948
    tcg_temp_free_i64(fp0);
5949
    gen_set_label(l1);
5950
}
5951

    
5952
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5953
{
5954
    int cond;
5955
    TCGv_i32 t0 = tcg_temp_new_i32();
5956
    int l1 = gen_new_label();
5957
    int l2 = gen_new_label();
5958

    
5959
    if (tf)
5960
        cond = TCG_COND_EQ;
5961
    else
5962
        cond = TCG_COND_NE;
5963

    
5964
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5965
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5966
    gen_load_fpr32(t0, fs);
5967
    gen_store_fpr32(t0, fd);
5968
    gen_set_label(l1);
5969

    
5970
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5971
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5972
    gen_load_fpr32h(t0, fs);
5973
    gen_store_fpr32h(t0, fd);
5974
    tcg_temp_free_i32(t0);
5975
    gen_set_label(l2);
5976
}
5977

    
5978

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

    
6022
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6023
    case FOP(0, 16):
6024
        {
6025
            TCGv_i32 fp0 = tcg_temp_new_i32();
6026
            TCGv_i32 fp1 = tcg_temp_new_i32();
6027

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

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

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

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

    
6087
            gen_load_fpr32(fp0, fs);
6088
            gen_helper_float_sqrt_s(fp0, fp0);
6089
            gen_store_fpr32(fp0, fd);
6090
            tcg_temp_free_i32(fp0);
6091
        }
6092
        opn = "sqrt.s";
6093
        break;
6094
    case FOP(5, 16):
6095
        {
6096
            TCGv_i32 fp0 = tcg_temp_new_i32();
6097

    
6098
            gen_load_fpr32(fp0, fs);
6099
            gen_helper_float_abs_s(fp0, fp0);
6100
            gen_store_fpr32(fp0, fd);
6101
            tcg_temp_free_i32(fp0);
6102
        }
6103
        opn = "abs.s";
6104
        break;
6105
    case FOP(6, 16):
6106
        {
6107
            TCGv_i32 fp0 = tcg_temp_new_i32();
6108

    
6109
            gen_load_fpr32(fp0, fs);
6110
            gen_store_fpr32(fp0, fd);
6111
            tcg_temp_free_i32(fp0);
6112
        }
6113
        opn = "mov.s";
6114
        break;
6115
    case FOP(7, 16):
6116
        {
6117
            TCGv_i32 fp0 = tcg_temp_new_i32();
6118

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

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

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

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

    
6174
            gen_load_fpr32(fp32, fs);
6175
            gen_helper_float_floorl_s(fp64, fp32);
6176
            tcg_temp_free_i32(fp32);
6177
            gen_store_fpr64(ctx, fp64, fd);
6178
            tcg_temp_free_i64(fp64);
6179
        }
6180
        opn = "floor.l.s";
6181
        break;
6182
    case FOP(12, 16):
6183
        {
6184
            TCGv_i32 fp0 = tcg_temp_new_i32();
6185

    
6186
            gen_load_fpr32(fp0, fs);
6187
            gen_helper_float_roundw_s(fp0, fp0);
6188
            gen_store_fpr32(fp0, fd);
6189
            tcg_temp_free_i32(fp0);
6190
        }
6191
        opn = "round.w.s";
6192
        break;
6193
    case FOP(13, 16):
6194
        {
6195
            TCGv_i32 fp0 = tcg_temp_new_i32();
6196

    
6197
            gen_load_fpr32(fp0, fs);
6198
            gen_helper_float_truncw_s(fp0, fp0);
6199
            gen_store_fpr32(fp0, fd);
6200
            tcg_temp_free_i32(fp0);
6201
        }
6202
        opn = "trunc.w.s";
6203
        break;
6204
    case FOP(14, 16):
6205
        {
6206
            TCGv_i32 fp0 = tcg_temp_new_i32();
6207

    
6208
            gen_load_fpr32(fp0, fs);
6209
            gen_helper_float_ceilw_s(fp0, fp0);
6210
            gen_store_fpr32(fp0, fd);
6211
            tcg_temp_free_i32(fp0);
6212
        }
6213
        opn = "ceil.w.s";
6214
        break;
6215
    case FOP(15, 16):
6216
        {
6217
            TCGv_i32 fp0 = tcg_temp_new_i32();
6218

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

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

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

    
6267
            gen_load_fpr32(fp0, fs);
6268
            gen_helper_float_recip_s(fp0, fp0);
6269
            gen_store_fpr32(fp0, fd);
6270
            tcg_temp_free_i32(fp0);
6271
        }
6272
        opn = "recip.s";
6273
        break;
6274
    case FOP(22, 16):
6275
        check_cop1x(ctx);
6276
        {
6277
            TCGv_i32 fp0 = tcg_temp_new_i32();
6278

    
6279
            gen_load_fpr32(fp0, fs);
6280
            gen_helper_float_rsqrt_s(fp0, fp0);
6281
            gen_store_fpr32(fp0, fd);
6282
            tcg_temp_free_i32(fp0);
6283
        }
6284
        opn = "rsqrt.s";
6285
        break;
6286
    case FOP(28, 16):
6287
        check_cp1_64bitmode(ctx);
6288
        {
6289
            TCGv_i32 fp0 = tcg_temp_new_i32();
6290
            TCGv_i32 fp1 = tcg_temp_new_i32();
6291

    
6292
            gen_load_fpr32(fp0, fs);
6293
            gen_load_fpr32(fp1, fd);
6294
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6295
            tcg_temp_free_i32(fp1);
6296
            gen_store_fpr32(fp0, fd);
6297
            tcg_temp_free_i32(fp0);
6298
        }
6299
        opn = "recip2.s";
6300
        break;
6301
    case FOP(29, 16):
6302
        check_cp1_64bitmode(ctx);
6303
        {
6304
            TCGv_i32 fp0 = tcg_temp_new_i32();
6305

    
6306
            gen_load_fpr32(fp0, fs);
6307
            gen_helper_float_recip1_s(fp0, fp0);
6308
            gen_store_fpr32(fp0, fd);
6309
            tcg_temp_free_i32(fp0);
6310
        }
6311
        opn = "recip1.s";
6312
        break;
6313
    case FOP(30, 16):
6314
        check_cp1_64bitmode(ctx);
6315
        {
6316
            TCGv_i32 fp0 = tcg_temp_new_i32();
6317

    
6318
            gen_load_fpr32(fp0, fs);
6319
            gen_helper_float_rsqrt1_s(fp0, fp0);
6320
            gen_store_fpr32(fp0, fd);
6321
            tcg_temp_free_i32(fp0);
6322
        }
6323
        opn = "rsqrt1.s";
6324
        break;
6325
    case FOP(31, 16):
6326
        check_cp1_64bitmode(ctx);
6327
        {
6328
            TCGv_i32 fp0 = tcg_temp_new_i32();
6329
            TCGv_i32 fp1 = tcg_temp_new_i32();
6330

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

    
6346
            gen_load_fpr32(fp32, fs);
6347
            gen_helper_float_cvtd_s(fp64, fp32);
6348
            tcg_temp_free_i32(fp32);
6349
            gen_store_fpr64(ctx, fp64, fd);
6350
            tcg_temp_free_i64(fp64);
6351
        }
6352
        opn = "cvt.d.s";
6353
        break;
6354
    case FOP(36, 16):
6355
        {
6356
            TCGv_i32 fp0 = tcg_temp_new_i32();
6357

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

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

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

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

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

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

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

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

    
6499
            gen_load_fpr64(ctx, fp0, fs);
6500
            gen_helper_float_sqrt_d(fp0, fp0);
6501
            gen_store_fpr64(ctx, fp0, fd);
6502
            tcg_temp_free_i64(fp0);
6503
        }
6504
        opn = "sqrt.d";
6505
        break;
6506
    case FOP(5, 17):
6507
        check_cp1_registers(ctx, fs | fd);
6508
        {
6509
            TCGv_i64 fp0 = tcg_temp_new_i64();
6510

    
6511
            gen_load_fpr64(ctx, fp0, fs);
6512
            gen_helper_float_abs_d(fp0, fp0);
6513
            gen_store_fpr64(ctx, fp0, fd);
6514
            tcg_temp_free_i64(fp0);
6515
        }
6516
        opn = "abs.d";
6517
        break;
6518
    case FOP(6, 17):
6519
        check_cp1_registers(ctx, fs | fd);
6520
        {
6521
            TCGv_i64 fp0 = tcg_temp_new_i64();
6522

    
6523
            gen_load_fpr64(ctx, fp0, fs);
6524
            gen_store_fpr64(ctx, fp0, fd);
6525
            tcg_temp_free_i64(fp0);
6526
        }
6527
        opn = "mov.d";
6528
        break;
6529
    case FOP(7, 17):
6530
        check_cp1_registers(ctx, fs | fd);
6531
        {
6532
            TCGv_i64 fp0 = tcg_temp_new_i64();
6533

    
6534
            gen_load_fpr64(ctx, fp0, fs);
6535
            gen_helper_float_chs_d(fp0, fp0);
6536
            gen_store_fpr64(ctx, fp0, fd);
6537
            tcg_temp_free_i64(fp0);
6538
        }
6539
        opn = "neg.d";
6540
        break;
6541
    case FOP(8, 17):
6542
        check_cp1_64bitmode(ctx);
6543
        {
6544
            TCGv_i64 fp0 = tcg_temp_new_i64();
6545

    
6546
            gen_load_fpr64(ctx, fp0, fs);
6547
            gen_helper_float_roundl_d(fp0, fp0);
6548
            gen_store_fpr64(ctx, fp0, fd);
6549
            tcg_temp_free_i64(fp0);
6550
        }
6551
        opn = "round.l.d";
6552
        break;
6553
    case FOP(9, 17):
6554
        check_cp1_64bitmode(ctx);
6555
        {
6556
            TCGv_i64 fp0 = tcg_temp_new_i64();
6557

    
6558
            gen_load_fpr64(ctx, fp0, fs);
6559
            gen_helper_float_truncl_d(fp0, fp0);
6560
            gen_store_fpr64(ctx, fp0, fd);
6561
            tcg_temp_free_i64(fp0);
6562
        }
6563
        opn = "trunc.l.d";
6564
        break;
6565
    case FOP(10, 17):
6566
        check_cp1_64bitmode(ctx);
6567
        {
6568
            TCGv_i64 fp0 = tcg_temp_new_i64();
6569

    
6570
            gen_load_fpr64(ctx, fp0, fs);
6571
            gen_helper_float_ceill_d(fp0, fp0);
6572
            gen_store_fpr64(ctx, fp0, fd);
6573
            tcg_temp_free_i64(fp0);
6574
        }
6575
        opn = "ceil.l.d";
6576
        break;
6577
    case FOP(11, 17):
6578
        check_cp1_64bitmode(ctx);
6579
        {
6580
            TCGv_i64 fp0 = tcg_temp_new_i64();
6581

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

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

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

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

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

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

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

    
6686
            gen_load_fpr64(ctx, fp0, fs);
6687
            gen_helper_float_recip_d(fp0, fp0);
6688
            gen_store_fpr64(ctx, fp0, fd);
6689
            tcg_temp_free_i64(fp0);
6690
        }
6691
        opn = "recip.d";
6692
        break;
6693
    case FOP(22, 17):
6694
        check_cp1_64bitmode(ctx);
6695
        {
6696
            TCGv_i64 fp0 = tcg_temp_new_i64();
6697

    
6698
            gen_load_fpr64(ctx, fp0, fs);
6699
            gen_helper_float_rsqrt_d(fp0, fp0);
6700
            gen_store_fpr64(ctx, fp0, fd);
6701
            tcg_temp_free_i64(fp0);
6702
        }
6703
        opn = "rsqrt.d";
6704
        break;
6705
    case FOP(28, 17):
6706
        check_cp1_64bitmode(ctx);
6707
        {
6708
            TCGv_i64 fp0 = tcg_temp_new_i64();
6709
            TCGv_i64 fp1 = tcg_temp_new_i64();
6710

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

    
6725
            gen_load_fpr64(ctx, fp0, fs);
6726
            gen_helper_float_recip1_d(fp0, fp0);
6727
            gen_store_fpr64(ctx, fp0, fd);
6728
            tcg_temp_free_i64(fp0);
6729
        }
6730
        opn = "recip1.d";
6731
        break;
6732
    case FOP(30, 17):
6733
        check_cp1_64bitmode(ctx);
6734
        {
6735
            TCGv_i64 fp0 = tcg_temp_new_i64();
6736

    
6737
            gen_load_fpr64(ctx, fp0, fs);
6738
            gen_helper_float_rsqrt1_d(fp0, fp0);
6739
            gen_store_fpr64(ctx, fp0, fd);
6740
            tcg_temp_free_i64(fp0);
6741
        }
6742
        opn = "rsqrt1.d";
6743
        break;
6744
    case FOP(31, 17):
6745
        check_cp1_64bitmode(ctx);
6746
        {
6747
            TCGv_i64 fp0 = tcg_temp_new_i64();
6748
            TCGv_i64 fp1 = tcg_temp_new_i64();
6749

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

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

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

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

    
6828
            gen_load_fpr64(ctx, fp0, fs);
6829
            gen_helper_float_cvtl_d(fp0, fp0);
6830
            gen_store_fpr64(ctx, fp0, fd);
6831
            tcg_temp_free_i64(fp0);
6832
        }
6833
        opn = "cvt.l.d";
6834
        break;
6835
    case FOP(32, 20):
6836
        {
6837
            TCGv_i32 fp0 = tcg_temp_new_i32();
6838

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

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

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

    
6879
            gen_load_fpr64(ctx, fp0, fs);
6880
            gen_helper_float_cvtd_l(fp0, fp0);
6881
            gen_store_fpr64(ctx, fp0, fd);
6882
            tcg_temp_free_i64(fp0);
6883
        }
6884
        opn = "cvt.d.l";
6885
        break;
6886
    case FOP(38, 20):
6887
        check_cp1_64bitmode(ctx);
6888
        {
6889
            TCGv_i64 fp0 = tcg_temp_new_i64();
6890

    
6891
            gen_load_fpr64(ctx, fp0, fs);
6892
            gen_helper_float_cvtps_pw(fp0, fp0);
6893
            gen_store_fpr64(ctx, fp0, fd);
6894
            tcg_temp_free_i64(fp0);
6895
        }
6896
        opn = "cvt.ps.pw";
6897
        break;
6898
    case FOP(0, 22):
6899
        check_cp1_64bitmode(ctx);
6900
        {
6901
            TCGv_i64 fp0 = tcg_temp_new_i64();
6902
            TCGv_i64 fp1 = tcg_temp_new_i64();
6903

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

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

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

    
6948
            gen_load_fpr64(ctx, fp0, fs);
6949
            gen_helper_float_abs_ps(fp0, fp0);
6950
            gen_store_fpr64(ctx, fp0, fd);
6951
            tcg_temp_free_i64(fp0);
6952
        }
6953
        opn = "abs.ps";
6954
        break;
6955
    case FOP(6, 22):
6956
        check_cp1_64bitmode(ctx);
6957
        {
6958
            TCGv_i64 fp0 = tcg_temp_new_i64();
6959

    
6960
            gen_load_fpr64(ctx, fp0, fs);
6961
            gen_store_fpr64(ctx, fp0, fd);
6962
            tcg_temp_free_i64(fp0);
6963
        }
6964
        opn = "mov.ps";
6965
        break;
6966
    case FOP(7, 22):
6967
        check_cp1_64bitmode(ctx);
6968
        {
6969
            TCGv_i64 fp0 = tcg_temp_new_i64();
6970

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

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

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

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

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

    
7052
            gen_load_fpr64(ctx, fp0, fs);
7053
            gen_load_fpr64(ctx, fp1, fd);
7054
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7055
            tcg_temp_free_i64(fp1);
7056
            gen_store_fpr64(ctx, fp0, fd);
7057
            tcg_temp_free_i64(fp0);
7058
        }
7059
        opn = "recip2.ps";
7060
        break;
7061
    case FOP(29, 22):
7062
        check_cp1_64bitmode(ctx);
7063
        {
7064
            TCGv_i64 fp0 = tcg_temp_new_i64();
7065

    
7066
            gen_load_fpr64(ctx, fp0, fs);
7067
            gen_helper_float_recip1_ps(fp0, fp0);
7068
            gen_store_fpr64(ctx, fp0, fd);
7069
            tcg_temp_free_i64(fp0);
7070
        }
7071
        opn = "recip1.ps";
7072
        break;
7073
    case FOP(30, 22):
7074
        check_cp1_64bitmode(ctx);
7075
        {
7076
            TCGv_i64 fp0 = tcg_temp_new_i64();
7077

    
7078
            gen_load_fpr64(ctx, fp0, fs);
7079
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7080
            gen_store_fpr64(ctx, fp0, fd);
7081
            tcg_temp_free_i64(fp0);
7082
        }
7083
        opn = "rsqrt1.ps";
7084
        break;
7085
    case FOP(31, 22):
7086
        check_cp1_64bitmode(ctx);
7087
        {
7088
            TCGv_i64 fp0 = tcg_temp_new_i64();
7089
            TCGv_i64 fp1 = tcg_temp_new_i64();
7090

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

    
7105
            gen_load_fpr32h(fp0, fs);
7106
            gen_helper_float_cvts_pu(fp0, fp0);
7107
            gen_store_fpr32(fp0, fd);
7108
            tcg_temp_free_i32(fp0);
7109
        }
7110
        opn = "cvt.s.pu";
7111
        break;
7112
    case FOP(36, 22):
7113
        check_cp1_64bitmode(ctx);
7114
        {
7115
            TCGv_i64 fp0 = tcg_temp_new_i64();
7116

    
7117
            gen_load_fpr64(ctx, fp0, fs);
7118
            gen_helper_float_cvtpw_ps(fp0, fp0);
7119
            gen_store_fpr64(ctx, fp0, fd);
7120
            tcg_temp_free_i64(fp0);
7121
        }
7122
        opn = "cvt.pw.ps";
7123
        break;
7124
    case FOP(40, 22):
7125
        check_cp1_64bitmode(ctx);
7126
        {
7127
            TCGv_i32 fp0 = tcg_temp_new_i32();
7128

    
7129
            gen_load_fpr32(fp0, fs);
7130
            gen_helper_float_cvts_pl(fp0, fp0);
7131
            gen_store_fpr32(fp0, fd);
7132
            tcg_temp_free_i32(fp0);
7133
        }
7134
        opn = "cvt.s.pl";
7135
        break;
7136
    case FOP(44, 22):
7137
        check_cp1_64bitmode(ctx);
7138
        {
7139
            TCGv_i32 fp0 = tcg_temp_new_i32();
7140
            TCGv_i32 fp1 = tcg_temp_new_i32();
7141

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

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

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

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

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

    
7248
/* Coprocessor 3 (FPU) */
7249
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7250
                           int fd, int fs, int base, int index)
7251
{
7252
    const char *opn = "extended float load/store";
7253
    int store = 0;
7254
    TCGv t0 = tcg_temp_new();
7255

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

    
7273
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7274
            tcg_gen_trunc_tl_i32(fp0, t0);
7275
            gen_store_fpr32(fp0, fd);
7276
            tcg_temp_free_i32(fp0);
7277
        }
7278
        opn = "lwxc1";
7279
        break;
7280
    case OPC_LDXC1:
7281
        check_cop1x(ctx);
7282
        check_cp1_registers(ctx, fd);
7283
        {
7284
            TCGv_i64 fp0 = tcg_temp_new_i64();
7285

    
7286
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7287
            gen_store_fpr64(ctx, fp0, fd);
7288
            tcg_temp_free_i64(fp0);
7289
        }
7290
        opn = "ldxc1";
7291
        break;
7292
    case OPC_LUXC1:
7293
        check_cp1_64bitmode(ctx);
7294
        tcg_gen_andi_tl(t0, t0, ~0x7);
7295
        {
7296
            TCGv_i64 fp0 = tcg_temp_new_i64();
7297

    
7298
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7299
            gen_store_fpr64(ctx, fp0, fd);
7300
            tcg_temp_free_i64(fp0);
7301
        }
7302
        opn = "luxc1";
7303
        break;
7304
    case OPC_SWXC1:
7305
        check_cop1x(ctx);
7306
        {
7307
            TCGv_i32 fp0 = tcg_temp_new_i32();
7308
            TCGv t1 = tcg_temp_new();
7309

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

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

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

    
7351
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7352
                            int fd, int fr, int fs, int ft)
7353
{
7354
    const char *opn = "flt3_arith";
7355

    
7356
    switch (opc) {
7357
    case OPC_ALNV_PS:
7358
        check_cp1_64bitmode(ctx);
7359
        {
7360
            TCGv t0 = tcg_temp_local_new();
7361
            TCGv_i32 fp = tcg_temp_new_i32();
7362
            TCGv_i32 fph = tcg_temp_new_i32();
7363
            int l1 = gen_new_label();
7364
            int l2 = gen_new_label();
7365

    
7366
            gen_load_gpr(t0, fr);
7367
            tcg_gen_andi_tl(t0, t0, 0x7);
7368

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7624
/* ISA extensions (ASEs) */
7625
/* MIPS16 extension to MIPS32 */
7626
/* SmartMIPS extension to MIPS32 */
7627

    
7628
#if defined(TARGET_MIPS64)
7629

    
7630
/* MDMX extension to MIPS64 */
7631

    
7632
#endif
7633

    
7634
static void decode_opc (CPUState *env, DisasContext *ctx)
7635
{
7636
    int32_t offset;
7637
    int rs, rt, rd, sa;
7638
    uint32_t op, op1, op2;
7639
    int16_t imm;
7640

    
7641
    /* make sure instructions are on a word boundary */
7642
    if (ctx->pc & 0x3) {
7643
        env->CP0_BadVAddr = ctx->pc;
7644
        generate_exception(ctx, EXCP_AdEL);
7645
        return;
7646
    }
7647

    
7648
    /* Handle blikely not taken case */
7649
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7650
        int l1 = gen_new_label();
7651

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

    
7748
        case OPC_MOVCI:
7749
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7750
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7751
                check_cp1_enabled(ctx);
7752
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7753
                          (ctx->opcode >> 16) & 1);
7754
            } else {
7755
                generate_exception_err(ctx, EXCP_CpU, 1);
7756
            }
7757
            break;
7758

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

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

    
7899
                gen_load_gpr(t0, rt);
7900
                gen_load_gpr(t1, rs);
7901
                gen_helper_fork(t0, t1);
7902
                tcg_temp_free(t0);
7903
                tcg_temp_free(t1);
7904
            }
7905
            break;
7906
        case OPC_YIELD:
7907
            check_insn(env, ctx, ASE_MT);
7908
            {
7909
                TCGv t0 = tcg_temp_new();
7910

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

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

    
8086
    /* Floating point (COP1). */
8087
    case OPC_LWC1:
8088
    case OPC_LDC1:
8089
    case OPC_SWC1:
8090
    case OPC_SDC1:
8091
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8092
            check_cp1_enabled(ctx);
8093
            gen_flt_ldst(ctx, op, rt, rs, imm);
8094
        } else {
8095
            generate_exception_err(ctx, EXCP_CpU, 1);
8096
        }
8097
        break;
8098

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

    
8147
    /* COP2.  */
8148
    case OPC_LWC2:
8149
    case OPC_LDC2:
8150
    case OPC_SWC2:
8151
    case OPC_SDC2:
8152
    case OPC_CP2:
8153
        /* COP2: Not implemented. */
8154
        generate_exception_err(ctx, EXCP_CpU, 2);
8155
        break;
8156

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

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

    
8257
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8258
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8259
                gen_set_label(l1);
8260
                gen_goto_tb(ctx, 0, ctx->btarget);
8261
            }
8262
            break;
8263
        case MIPS_HFLAG_BR:
8264
            /* unconditional branch to register */
8265
            MIPS_DEBUG("branch to register");
8266
            tcg_gen_mov_tl(cpu_PC, btarget);
8267
            tcg_gen_exit_tb(0);
8268
            break;
8269
        default:
8270
            MIPS_DEBUG("unknown branch");
8271
            break;
8272
        }
8273
    }
8274
}
8275

    
8276
static inline void
8277
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8278
                                int search_pc)
8279
{
8280
    DisasContext ctx;
8281
    target_ulong pc_start;
8282
    uint16_t *gen_opc_end;
8283
    CPUBreakpoint *bp;
8284
    int j, lj = -1;
8285
    int num_insns;
8286
    int max_insns;
8287

    
8288
    if (search_pc)
8289
        qemu_log("search pc %d\n", search_pc);
8290

    
8291
    pc_start = tb->pc;
8292
    /* Leave some spare opc slots for branch handling. */
8293
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8294
    ctx.pc = pc_start;
8295
    ctx.saved_pc = -1;
8296
    ctx.tb = tb;
8297
    ctx.bstate = BS_NONE;
8298
    /* Restore delay slot state from the tb context.  */
8299
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8300
    restore_cpu_state(env, &ctx);
8301
#ifdef CONFIG_USER_ONLY
8302
        ctx.mem_idx = MIPS_HFLAG_UM;
8303
#else
8304
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8305
#endif
8306
    num_insns = 0;
8307
    max_insns = tb->cflags & CF_COUNT_MASK;
8308
    if (max_insns == 0)
8309
        max_insns = CF_COUNT_MASK;
8310
#ifdef DEBUG_DISAS
8311
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8312
    /* FIXME: This may print out stale hflags from env... */
8313
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8314
#endif
8315
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8316
    gen_icount_start();
8317
    while (ctx.bstate == BS_NONE) {
8318
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8319
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8320
                if (bp->pc == ctx.pc) {
8321
                    save_cpu_state(&ctx, 1);
8322
                    ctx.bstate = BS_BRANCH;
8323
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8324
                    /* Include the breakpoint location or the tb won't
8325
                     * be flushed when it must be.  */
8326
                    ctx.pc += 4;
8327
                    goto done_generating;
8328
                }
8329
            }
8330
        }
8331

    
8332
        if (search_pc) {
8333
            j = gen_opc_ptr - gen_opc_buf;
8334
            if (lj < j) {
8335
                lj++;
8336
                while (lj < j)
8337
                    gen_opc_instr_start[lj++] = 0;
8338
            }
8339
            gen_opc_pc[lj] = ctx.pc;
8340
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8341
            gen_opc_instr_start[lj] = 1;
8342
            gen_opc_icount[lj] = num_insns;
8343
        }
8344
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8345
            gen_io_start();
8346
        ctx.opcode = ldl_code(ctx.pc);
8347
        decode_opc(env, &ctx);
8348
        ctx.pc += 4;
8349
        num_insns++;
8350

    
8351
        if (env->singlestep_enabled)
8352
            break;
8353

    
8354
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8355
            break;
8356

    
8357
        if (gen_opc_ptr >= gen_opc_end)
8358
            break;
8359

    
8360
        if (num_insns >= max_insns)
8361
            break;
8362

    
8363
        if (singlestep)
8364
            break;
8365
    }
8366
    if (tb->cflags & CF_LAST_IO)
8367
        gen_io_end();
8368
    if (env->singlestep_enabled) {
8369
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8370
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8371
    } else {
8372
        switch (ctx.bstate) {
8373
        case BS_STOP:
8374
            gen_helper_interrupt_restart();
8375
            gen_goto_tb(&ctx, 0, ctx.pc);
8376
            break;
8377
        case BS_NONE:
8378
            save_cpu_state(&ctx, 0);
8379
            gen_goto_tb(&ctx, 0, ctx.pc);
8380
            break;
8381
        case BS_EXCP:
8382
            gen_helper_interrupt_restart();
8383
            tcg_gen_exit_tb(0);
8384
            break;
8385
        case BS_BRANCH:
8386
        default:
8387
            break;
8388
        }
8389
    }
8390
done_generating:
8391
    gen_icount_end(tb, num_insns);
8392
    *gen_opc_ptr = INDEX_op_end;
8393
    if (search_pc) {
8394
        j = gen_opc_ptr - gen_opc_buf;
8395
        lj++;
8396
        while (lj <= j)
8397
            gen_opc_instr_start[lj++] = 0;
8398
    } else {
8399
        tb->size = ctx.pc - pc_start;
8400
        tb->icount = num_insns;
8401
    }
8402
#ifdef DEBUG_DISAS
8403
    LOG_DISAS("\n");
8404
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8405
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8406
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8407
        qemu_log("\n");
8408
    }
8409
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8410
#endif
8411
}
8412

    
8413
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8414
{
8415
    gen_intermediate_code_internal(env, tb, 0);
8416
}
8417

    
8418
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8419
{
8420
    gen_intermediate_code_internal(env, tb, 1);
8421
}
8422

    
8423
static void fpu_dump_state(CPUState *env, FILE *f,
8424
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8425
                           int flags)
8426
{
8427
    int i;
8428
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8429

    
8430
#define printfpr(fp)                                                        \
8431
    do {                                                                    \
8432
        if (is_fpu64)                                                       \
8433
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8434
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8435
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8436
        else {                                                              \
8437
            fpr_t tmp;                                                      \
8438
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8439
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8440
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8441
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8442
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8443
        }                                                                   \
8444
    } while(0)
8445

    
8446

    
8447
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8448
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8449
                get_float_exception_flags(&env->active_fpu.fp_status));
8450
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8451
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8452
        printfpr(&env->active_fpu.fpr[i]);
8453
    }
8454

    
8455
#undef printfpr
8456
}
8457

    
8458
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8459
/* Debug help: The architecture requires 32bit code to maintain proper
8460
   sign-extended values on 64bit machines.  */
8461

    
8462
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8463

    
8464
static void
8465
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8466
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8467
                                int flags)
8468
{
8469
    int i;
8470

    
8471
    if (!SIGN_EXT_P(env->active_tc.PC))
8472
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8473
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8474
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8475
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8476
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8477
    if (!SIGN_EXT_P(env->btarget))
8478
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8479

    
8480
    for (i = 0; i < 32; i++) {
8481
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8482
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8483
    }
8484

    
8485
    if (!SIGN_EXT_P(env->CP0_EPC))
8486
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8487
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8488
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8489
}
8490
#endif
8491

    
8492
void cpu_dump_state (CPUState *env, FILE *f,
8493
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8494
                     int flags)
8495
{
8496
    int i;
8497

    
8498
    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",
8499
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8500
                env->hflags, env->btarget, env->bcond);
8501
    for (i = 0; i < 32; i++) {
8502
        if ((i & 3) == 0)
8503
            cpu_fprintf(f, "GPR%02d:", i);
8504
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8505
        if ((i & 3) == 3)
8506
            cpu_fprintf(f, "\n");
8507
    }
8508

    
8509
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8510
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8511
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8512
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8513
    if (env->hflags & MIPS_HFLAG_FPU)
8514
        fpu_dump_state(env, f, cpu_fprintf, flags);
8515
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8516
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8517
#endif
8518
}
8519

    
8520
static void mips_tcg_init(void)
8521
{
8522
    int i;
8523
    static int inited;
8524

    
8525
    /* Initialize various static tables. */
8526
    if (inited)
8527
        return;
8528

    
8529
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8530
    TCGV_UNUSED(cpu_gpr[0]);
8531
    for (i = 1; i < 32; i++)
8532
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8533
                                        offsetof(CPUState, active_tc.gpr[i]),
8534
                                        regnames[i]);
8535
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8536
                                offsetof(CPUState, active_tc.PC), "PC");
8537
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8538
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8539
                                       offsetof(CPUState, active_tc.HI[i]),
8540
                                       regnames_HI[i]);
8541
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8542
                                       offsetof(CPUState, active_tc.LO[i]),
8543
                                       regnames_LO[i]);
8544
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8545
                                        offsetof(CPUState, active_tc.ACX[i]),
8546
                                        regnames_ACX[i]);
8547
    }
8548
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8549
                                     offsetof(CPUState, active_tc.DSPControl),
8550
                                     "DSPControl");
8551
    bcond = tcg_global_mem_new(TCG_AREG0,
8552
                               offsetof(CPUState, bcond), "bcond");
8553
    btarget = tcg_global_mem_new(TCG_AREG0,
8554
                                 offsetof(CPUState, btarget), "btarget");
8555
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8556
                                    offsetof(CPUState, hflags), "hflags");
8557

    
8558
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8559
                                      offsetof(CPUState, active_fpu.fcr0),
8560
                                      "fcr0");
8561
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8562
                                       offsetof(CPUState, active_fpu.fcr31),
8563
                                       "fcr31");
8564

    
8565
    /* register helpers */
8566
#define GEN_HELPER 2
8567
#include "helper.h"
8568

    
8569
    inited = 1;
8570
}
8571

    
8572
#include "translate_init.c"
8573

    
8574
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8575
{
8576
    CPUMIPSState *env;
8577
    const mips_def_t *def;
8578

    
8579
    def = cpu_mips_find_by_name(cpu_model);
8580
    if (!def)
8581
        return NULL;
8582
    env = qemu_mallocz(sizeof(CPUMIPSState));
8583
    env->cpu_model = def;
8584

    
8585
    cpu_exec_init(env);
8586
    env->cpu_model_str = cpu_model;
8587
    mips_tcg_init();
8588
    cpu_reset(env);
8589
    qemu_init_vcpu(env);
8590
    return env;
8591
}
8592

    
8593
void cpu_reset (CPUMIPSState *env)
8594
{
8595
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8596
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8597
        log_cpu_state(env, 0);
8598
    }
8599

    
8600
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8601

    
8602
    tlb_flush(env, 1);
8603

    
8604
    /* Minimal init */
8605
#if defined(CONFIG_USER_ONLY)
8606
    env->hflags = MIPS_HFLAG_UM;
8607
    /* Enable access to the SYNCI_Step register.  */
8608
    env->CP0_HWREna |= (1 << 1);
8609
#else
8610
    if (env->hflags & MIPS_HFLAG_BMASK) {
8611
        /* If the exception was raised from a delay slot,
8612
           come back to the jump.  */
8613
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8614
    } else {
8615
        env->CP0_ErrorEPC = env->active_tc.PC;
8616
    }
8617
    env->active_tc.PC = (int32_t)0xBFC00000;
8618
    env->CP0_Wired = 0;
8619
    /* SMP not implemented */
8620
    env->CP0_EBase = 0x80000000;
8621
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8622
    /* vectored interrupts not implemented, timer on int 7,
8623
       no performance counters. */
8624
    env->CP0_IntCtl = 0xe0000000;
8625
    {
8626
        int i;
8627

    
8628
        for (i = 0; i < 7; i++) {
8629
            env->CP0_WatchLo[i] = 0;
8630
            env->CP0_WatchHi[i] = 0x80000000;
8631
        }
8632
        env->CP0_WatchLo[7] = 0;
8633
        env->CP0_WatchHi[7] = 0;
8634
    }
8635
    /* Count register increments in debug mode, EJTAG version 1 */
8636
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8637
    env->hflags = MIPS_HFLAG_CP0;
8638
#endif
8639
    env->exception_index = EXCP_NONE;
8640
    cpu_mips_register(env, env->cpu_model);
8641
}
8642

    
8643
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8644
                unsigned long searched_pc, int pc_pos, void *puc)
8645
{
8646
    env->active_tc.PC = gen_opc_pc[pc_pos];
8647
    env->hflags &= ~MIPS_HFLAG_BMASK;
8648
    env->hflags |= gen_opc_hflags[pc_pos];
8649
}