Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 8167ee88

History | View | Annotate | Download (250.5 kB)

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

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

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

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

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

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

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

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

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
436
#include "gen-icount.h"
437

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
804
/* Addresses computation */
805
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
806
{
807
    tcg_gen_add_tl(t0, t0, t1);
808

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1157
    t0 = tcg_temp_local_new();
1158

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2458
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2459
{
2460
    TranslationBlock *tb;
2461
    tb = ctx->tb;
2462
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2463
        tcg_gen_goto_tb(n);
2464
        gen_save_pc(dest);
2465
        tcg_gen_exit_tb((long)tb + n);
2466
    } else {
2467
        gen_save_pc(dest);
2468
        tcg_gen_exit_tb(0);
2469
    }
2470
}
2471

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3487
    if (use_icount)
3488
        gen_io_start();
3489

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

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

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

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

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

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

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

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

    
4649
    if (use_icount)
4650
        gen_io_start();
4651

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5794
/* Coprocessor 1 (FPU) */
5795

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5977

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7627
#if defined(TARGET_MIPS64)
7628

    
7629
/* MDMX extension to MIPS64 */
7630

    
7631
#endif
7632

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8445

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

    
8454
#undef printfpr
8455
}
8456

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8568
    inited = 1;
8569
}
8570

    
8571
#include "translate_init.c"
8572

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

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

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

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

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

    
8601
    tlb_flush(env, 1);
8602

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

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

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