Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d9bea114

History | View | Annotate | Download (248.4 kB)

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

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

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

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

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

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

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

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

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

    
188
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
189

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
437
#include "gen-icount.h"
438

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
800
static inline void
801
generate_exception (DisasContext *ctx, int excp)
802
{
803
    save_cpu_state(ctx, 1);
804
    gen_helper_0i(raise_exception, excp);
805
    gen_helper_interrupt_restart();
806
    tcg_gen_exit_tb(0);
807
}
808

    
809
/* Addresses computation */
810
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
811
{
812
    tcg_gen_add_tl(t0, t0, t1);
813

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

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

    
831
static inline void check_cp1_enabled(DisasContext *ctx)
832
{
833
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
834
        generate_exception_err(ctx, EXCP_CpU, 1);
835
}
836

    
837
/* Verify that the processor is running with COP1X instructions enabled.
838
   This is associated with the nabla symbol in the MIPS32 and MIPS64
839
   opcode tables.  */
840

    
841
static inline void check_cop1x(DisasContext *ctx)
842
{
843
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
844
        generate_exception(ctx, EXCP_RI);
845
}
846

    
847
/* Verify that the processor is running with 64-bit floating-point
848
   operations enabled.  */
849

    
850
static inline void check_cp1_64bitmode(DisasContext *ctx)
851
{
852
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
853
        generate_exception(ctx, EXCP_RI);
854
}
855

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

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

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

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

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

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

    
934
#define OP_ST_ATOMIC(insn,fname,almask)                                              \
935
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, TCGv arg2, DisasContext *ctx) \
936
{                                                                                    \
937
    TCGv t0 = tcg_temp_new();                                                        \
938
    int l1 = gen_new_label();                                                        \
939
    int l2 = gen_new_label();                                                        \
940
    int l3 = gen_new_label();                                                        \
941
                                                                                     \
942
    tcg_gen_andi_tl(t0, arg2, almask);                                               \
943
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                                      \
944
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));                  \
945
    generate_exception(ctx, EXCP_AdES);                                              \
946
    gen_set_label(l1);                                                               \
947
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));                      \
948
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                                    \
949
    tcg_temp_free(t0);                                                               \
950
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                                  \
951
    tcg_gen_movi_tl(ret, 1);                                                         \
952
    tcg_gen_br(l3);                                                                  \
953
    gen_set_label(l2);                                                               \
954
    tcg_gen_movi_tl(ret, 0);                                                         \
955
    gen_set_label(l3);                                                               \
956
}
957
OP_ST_ATOMIC(sc,st32,0x3);
958
#if defined(TARGET_MIPS64)
959
OP_ST_ATOMIC(scd,st64,0x7);
960
#endif
961
#undef OP_ST_ATOMIC
962

    
963
/* Load and store */
964
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
965
                      int base, int16_t offset)
966
{
967
    const char *opn = "ldst";
968
    TCGv t0 = tcg_temp_new();
969
    TCGv t1 = tcg_temp_new();
970

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

    
1120
/* Store conditional */
1121
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1122
                         int base, int16_t offset)
1123
{
1124
    const char *opn = "st_cond";
1125
    TCGv t0, t1;
1126

    
1127
    t0 = tcg_temp_local_new();
1128

    
1129
    if (base == 0) {
1130
        tcg_gen_movi_tl(t0, offset);
1131
    } else if (offset == 0) {
1132
        gen_load_gpr(t0, base);
1133
    } else {
1134
        tcg_gen_movi_tl(t0, offset);
1135
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1136
    }
1137
    /* Don't do NOP if destination is zero: we must perform the actual
1138
       memory access. */
1139

    
1140
    t1 = tcg_temp_local_new();
1141
    gen_load_gpr(t1, rt);
1142
    switch (opc) {
1143
#if defined(TARGET_MIPS64)
1144
    case OPC_SCD:
1145
        save_cpu_state(ctx, 0);
1146
        op_ldst_scd(t0, t1, t0, ctx);
1147
        opn = "scd";
1148
        break;
1149
#endif
1150
    case OPC_SC:
1151
        save_cpu_state(ctx, 0);
1152
        op_ldst_sc(t0, t1, t0, ctx);
1153
        opn = "sc";
1154
        break;
1155
    }
1156
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1157
    tcg_temp_free(t1);
1158
    gen_store_gpr(t0, rt);
1159
    tcg_temp_free(t0);
1160
}
1161

    
1162
/* Load and store */
1163
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1164
                          int base, int16_t offset)
1165
{
1166
    const char *opn = "flt_ldst";
1167
    TCGv t0 = tcg_temp_new();
1168

    
1169
    if (base == 0) {
1170
        tcg_gen_movi_tl(t0, offset);
1171
    } else if (offset == 0) {
1172
        gen_load_gpr(t0, base);
1173
    } else {
1174
        tcg_gen_movi_tl(t0, offset);
1175
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1176
    }
1177
    /* Don't do NOP if destination is zero: we must perform the actual
1178
       memory access. */
1179
    switch (opc) {
1180
    case OPC_LWC1:
1181
        {
1182
            TCGv_i32 fp0 = tcg_temp_new_i32();
1183
            TCGv t1 = tcg_temp_new();
1184

    
1185
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1186
            tcg_gen_trunc_tl_i32(fp0, t1);
1187
            gen_store_fpr32(fp0, ft);
1188
            tcg_temp_free(t1);
1189
            tcg_temp_free_i32(fp0);
1190
        }
1191
        opn = "lwc1";
1192
        break;
1193
    case OPC_SWC1:
1194
        {
1195
            TCGv_i32 fp0 = tcg_temp_new_i32();
1196
            TCGv t1 = tcg_temp_new();
1197

    
1198
            gen_load_fpr32(fp0, ft);
1199
            tcg_gen_extu_i32_tl(t1, fp0);
1200
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1201
            tcg_temp_free(t1);
1202
            tcg_temp_free_i32(fp0);
1203
        }
1204
        opn = "swc1";
1205
        break;
1206
    case OPC_LDC1:
1207
        {
1208
            TCGv_i64 fp0 = tcg_temp_new_i64();
1209

    
1210
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1211
            gen_store_fpr64(ctx, fp0, ft);
1212
            tcg_temp_free_i64(fp0);
1213
        }
1214
        opn = "ldc1";
1215
        break;
1216
    case OPC_SDC1:
1217
        {
1218
            TCGv_i64 fp0 = tcg_temp_new_i64();
1219

    
1220
            gen_load_fpr64(ctx, fp0, ft);
1221
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1222
            tcg_temp_free_i64(fp0);
1223
        }
1224
        opn = "sdc1";
1225
        break;
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        goto out;
1230
    }
1231
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1232
 out:
1233
    tcg_temp_free(t0);
1234
}
1235

    
1236
/* Arithmetic with immediate operand */
1237
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1238
                           int rt, int rs, int16_t imm)
1239
{
1240
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1241
    const char *opn = "imm arith";
1242

    
1243
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1244
        /* If no destination, treat it as a NOP.
1245
           For addi, we must generate the overflow exception when needed. */
1246
        MIPS_DEBUG("NOP");
1247
        return;
1248
    }
1249
    switch (opc) {
1250
    case OPC_ADDI:
1251
        {
1252
            TCGv t0 = tcg_temp_local_new();
1253
            TCGv t1 = tcg_temp_new();
1254
            TCGv t2 = tcg_temp_new();
1255
            int l1 = gen_new_label();
1256

    
1257
            gen_load_gpr(t1, rs);
1258
            tcg_gen_addi_tl(t0, t1, uimm);
1259
            tcg_gen_ext32s_tl(t0, t0);
1260

    
1261
            tcg_gen_xori_tl(t1, t1, ~uimm);
1262
            tcg_gen_xori_tl(t2, t0, uimm);
1263
            tcg_gen_and_tl(t1, t1, t2);
1264
            tcg_temp_free(t2);
1265
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1266
            tcg_temp_free(t1);
1267
            /* operands of same sign, result different sign */
1268
            generate_exception(ctx, EXCP_OVERFLOW);
1269
            gen_set_label(l1);
1270
            tcg_gen_ext32s_tl(t0, t0);
1271
            gen_store_gpr(t0, rt);
1272
            tcg_temp_free(t0);
1273
        }
1274
        opn = "addi";
1275
        break;
1276
    case OPC_ADDIU:
1277
        if (rs != 0) {
1278
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1279
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1280
        } else {
1281
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1282
        }
1283
        opn = "addiu";
1284
        break;
1285
#if defined(TARGET_MIPS64)
1286
    case OPC_DADDI:
1287
        {
1288
            TCGv t0 = tcg_temp_local_new();
1289
            TCGv t1 = tcg_temp_new();
1290
            TCGv t2 = tcg_temp_new();
1291
            int l1 = gen_new_label();
1292

    
1293
            gen_load_gpr(t1, rs);
1294
            tcg_gen_addi_tl(t0, t1, uimm);
1295

    
1296
            tcg_gen_xori_tl(t1, t1, ~uimm);
1297
            tcg_gen_xori_tl(t2, t0, uimm);
1298
            tcg_gen_and_tl(t1, t1, t2);
1299
            tcg_temp_free(t2);
1300
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1301
            tcg_temp_free(t1);
1302
            /* operands of same sign, result different sign */
1303
            generate_exception(ctx, EXCP_OVERFLOW);
1304
            gen_set_label(l1);
1305
            gen_store_gpr(t0, rt);
1306
            tcg_temp_free(t0);
1307
        }
1308
        opn = "daddi";
1309
        break;
1310
    case OPC_DADDIU:
1311
        if (rs != 0) {
1312
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1313
        } else {
1314
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1315
        }
1316
        opn = "daddiu";
1317
        break;
1318
#endif
1319
    }
1320
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1321
}
1322

    
1323
/* Logic with immediate operand */
1324
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1325
{
1326
    target_ulong uimm;
1327
    const char *opn = "imm logic";
1328

    
1329
    if (rt == 0) {
1330
        /* If no destination, treat it as a NOP. */
1331
        MIPS_DEBUG("NOP");
1332
        return;
1333
    }
1334
    uimm = (uint16_t)imm;
1335
    switch (opc) {
1336
    case OPC_ANDI:
1337
        if (likely(rs != 0))
1338
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1339
        else
1340
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1341
        opn = "andi";
1342
        break;
1343
    case OPC_ORI:
1344
        if (rs != 0)
1345
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1346
        else
1347
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1348
        opn = "ori";
1349
        break;
1350
    case OPC_XORI:
1351
        if (likely(rs != 0))
1352
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1353
        else
1354
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1355
        opn = "xori";
1356
        break;
1357
    case OPC_LUI:
1358
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1359
        opn = "lui";
1360
        break;
1361
    }
1362
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1363
}
1364

    
1365
/* Set on less than with immediate operand */
1366
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1367
{
1368
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1369
    const char *opn = "imm arith";
1370
    TCGv t0;
1371

    
1372
    if (rt == 0) {
1373
        /* If no destination, treat it as a NOP. */
1374
        MIPS_DEBUG("NOP");
1375
        return;
1376
    }
1377
    t0 = tcg_temp_new();
1378
    gen_load_gpr(t0, rs);
1379
    switch (opc) {
1380
    case OPC_SLTI:
1381
        gen_op_lti(cpu_gpr[rt], t0, uimm);
1382
        opn = "slti";
1383
        break;
1384
    case OPC_SLTIU:
1385
        gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1386
        opn = "sltiu";
1387
        break;
1388
    }
1389
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1390
    tcg_temp_free(t0);
1391
}
1392

    
1393
/* Shifts with immediate operand */
1394
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1395
                          int rt, int rs, int16_t imm)
1396
{
1397
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1398
    const char *opn = "imm shift";
1399
    TCGv t0;
1400

    
1401
    if (rt == 0) {
1402
        /* If no destination, treat it as a NOP. */
1403
        MIPS_DEBUG("NOP");
1404
        return;
1405
    }
1406

    
1407
    t0 = tcg_temp_new();
1408
    gen_load_gpr(t0, rs);
1409
    switch (opc) {
1410
    case OPC_SLL:
1411
        tcg_gen_shli_tl(t0, t0, uimm);
1412
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1413
        opn = "sll";
1414
        break;
1415
    case OPC_SRA:
1416
        tcg_gen_ext32s_tl(t0, t0);
1417
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1418
        opn = "sra";
1419
        break;
1420
    case OPC_SRL:
1421
        switch ((ctx->opcode >> 21) & 0x1f) {
1422
        case 0:
1423
            if (uimm != 0) {
1424
                tcg_gen_ext32u_tl(t0, t0);
1425
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1426
            } else {
1427
                tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1428
            }
1429
            opn = "srl";
1430
            break;
1431
        case 1:
1432
            /* rotr is decoded as srl on non-R2 CPUs */
1433
            if (env->insn_flags & ISA_MIPS32R2) {
1434
                if (uimm != 0) {
1435
                    TCGv_i32 t1 = tcg_temp_new_i32();
1436

    
1437
                    tcg_gen_trunc_tl_i32(t1, t0);
1438
                    tcg_gen_rotri_i32(t1, t1, uimm);
1439
                    tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1440
                    tcg_temp_free_i32(t1);
1441
                }
1442
                opn = "rotr";
1443
            } else {
1444
                if (uimm != 0) {
1445
                    tcg_gen_ext32u_tl(t0, t0);
1446
                    tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1447
                } else {
1448
                    tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1449
                }
1450
                opn = "srl";
1451
            }
1452
            break;
1453
        default:
1454
            MIPS_INVAL("invalid srl flag");
1455
            generate_exception(ctx, EXCP_RI);
1456
            break;
1457
        }
1458
        break;
1459
#if defined(TARGET_MIPS64)
1460
    case OPC_DSLL:
1461
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1462
        opn = "dsll";
1463
        break;
1464
    case OPC_DSRA:
1465
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1466
        opn = "dsra";
1467
        break;
1468
    case OPC_DSRL:
1469
        switch ((ctx->opcode >> 21) & 0x1f) {
1470
        case 0:
1471
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1472
            opn = "dsrl";
1473
            break;
1474
        case 1:
1475
            /* drotr is decoded as dsrl on non-R2 CPUs */
1476
            if (env->insn_flags & ISA_MIPS32R2) {
1477
                if (uimm != 0) {
1478
                    tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1479
                }
1480
                opn = "drotr";
1481
            } else {
1482
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1483
                opn = "dsrl";
1484
            }
1485
            break;
1486
        default:
1487
            MIPS_INVAL("invalid dsrl flag");
1488
            generate_exception(ctx, EXCP_RI);
1489
            break;
1490
        }
1491
        break;
1492
    case OPC_DSLL32:
1493
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1494
        opn = "dsll32";
1495
        break;
1496
    case OPC_DSRA32:
1497
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1498
        opn = "dsra32";
1499
        break;
1500
    case OPC_DSRL32:
1501
        switch ((ctx->opcode >> 21) & 0x1f) {
1502
        case 0:
1503
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1504
            opn = "dsrl32";
1505
            break;
1506
        case 1:
1507
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1508
            if (env->insn_flags & ISA_MIPS32R2) {
1509
                tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1510
                opn = "drotr32";
1511
            } else {
1512
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1513
                opn = "dsrl32";
1514
            }
1515
            break;
1516
        default:
1517
            MIPS_INVAL("invalid dsrl32 flag");
1518
            generate_exception(ctx, EXCP_RI);
1519
            break;
1520
        }
1521
        break;
1522
#endif
1523
    }
1524
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1525
    tcg_temp_free(t0);
1526
}
1527

    
1528
/* Arithmetic */
1529
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1530
                       int rd, int rs, int rt)
1531
{
1532
    const char *opn = "arith";
1533

    
1534
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1535
       && opc != OPC_DADD && opc != OPC_DSUB) {
1536
        /* If no destination, treat it as a NOP.
1537
           For add & sub, we must generate the overflow exception when needed. */
1538
        MIPS_DEBUG("NOP");
1539
        return;
1540
    }
1541

    
1542
    switch (opc) {
1543
    case OPC_ADD:
1544
        {
1545
            TCGv t0 = tcg_temp_local_new();
1546
            TCGv t1 = tcg_temp_new();
1547
            TCGv t2 = tcg_temp_new();
1548
            int l1 = gen_new_label();
1549

    
1550
            gen_load_gpr(t1, rs);
1551
            gen_load_gpr(t2, rt);
1552
            tcg_gen_add_tl(t0, t1, t2);
1553
            tcg_gen_ext32s_tl(t0, t0);
1554
            tcg_gen_xor_tl(t1, t1, t2);
1555
            tcg_gen_not_tl(t1, t1);
1556
            tcg_gen_xor_tl(t2, t0, t2);
1557
            tcg_gen_and_tl(t1, t1, t2);
1558
            tcg_temp_free(t2);
1559
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1560
            tcg_temp_free(t1);
1561
            /* operands of same sign, result different sign */
1562
            generate_exception(ctx, EXCP_OVERFLOW);
1563
            gen_set_label(l1);
1564
            gen_store_gpr(t0, rd);
1565
            tcg_temp_free(t0);
1566
        }
1567
        opn = "add";
1568
        break;
1569
    case OPC_ADDU:
1570
        if (rs != 0 && rt != 0) {
1571
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1572
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1573
        } else if (rs == 0 && rt != 0) {
1574
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1575
        } else if (rs != 0 && rt == 0) {
1576
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1577
        } else {
1578
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1579
        }
1580
        opn = "addu";
1581
        break;
1582
    case OPC_SUB:
1583
        {
1584
            TCGv t0 = tcg_temp_local_new();
1585
            TCGv t1 = tcg_temp_new();
1586
            TCGv t2 = tcg_temp_new();
1587
            int l1 = gen_new_label();
1588

    
1589
            gen_load_gpr(t1, rs);
1590
            gen_load_gpr(t2, rt);
1591
            tcg_gen_sub_tl(t0, t1, t2);
1592
            tcg_gen_ext32s_tl(t0, t0);
1593
            tcg_gen_xor_tl(t2, t1, t2);
1594
            tcg_gen_xor_tl(t1, t0, t1);
1595
            tcg_gen_and_tl(t1, t1, t2);
1596
            tcg_temp_free(t2);
1597
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1598
            tcg_temp_free(t1);
1599
            /* operands of same sign, result different sign */
1600
            generate_exception(ctx, EXCP_OVERFLOW);
1601
            gen_set_label(l1);
1602
            gen_store_gpr(t0, rd);
1603
            tcg_temp_free(t0);
1604
        }
1605
        opn = "sub";
1606
        break;
1607
    case OPC_SUBU:
1608
        if (rs != 0 && rt != 0) {
1609
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1610
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1611
        } else if (rs == 0 && rt != 0) {
1612
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1613
        } else if (rs != 0 && rt == 0) {
1614
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1615
        } else {
1616
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1617
        }
1618
        opn = "subu";
1619
        break;
1620
#if defined(TARGET_MIPS64)
1621
    case OPC_DADD:
1622
        {
1623
            TCGv t0 = tcg_temp_local_new();
1624
            TCGv t1 = tcg_temp_new();
1625
            TCGv t2 = tcg_temp_new();
1626
            int l1 = gen_new_label();
1627

    
1628
            gen_load_gpr(t1, rs);
1629
            gen_load_gpr(t2, rt);
1630
            tcg_gen_add_tl(t0, t1, t2);
1631
            tcg_gen_xor_tl(t1, t1, t2);
1632
            tcg_gen_not_tl(t1, t1);
1633
            tcg_gen_xor_tl(t2, t0, t2);
1634
            tcg_gen_and_tl(t1, t1, t2);
1635
            tcg_temp_free(t2);
1636
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1637
            tcg_temp_free(t1);
1638
            /* operands of same sign, result different sign */
1639
            generate_exception(ctx, EXCP_OVERFLOW);
1640
            gen_set_label(l1);
1641
            gen_store_gpr(t0, rd);
1642
            tcg_temp_free(t0);
1643
        }
1644
        opn = "dadd";
1645
        break;
1646
    case OPC_DADDU:
1647
        if (rs != 0 && rt != 0) {
1648
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1649
        } else if (rs == 0 && rt != 0) {
1650
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1651
        } else if (rs != 0 && rt == 0) {
1652
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1653
        } else {
1654
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1655
        }
1656
        opn = "daddu";
1657
        break;
1658
    case OPC_DSUB:
1659
        {
1660
            TCGv t0 = tcg_temp_local_new();
1661
            TCGv t1 = tcg_temp_new();
1662
            TCGv t2 = tcg_temp_new();
1663
            int l1 = gen_new_label();
1664

    
1665
            gen_load_gpr(t1, rs);
1666
            gen_load_gpr(t2, rt);
1667
            tcg_gen_sub_tl(t0, t1, t2);
1668
            tcg_gen_xor_tl(t2, t1, t2);
1669
            tcg_gen_xor_tl(t1, t0, t1);
1670
            tcg_gen_and_tl(t1, t1, t2);
1671
            tcg_temp_free(t2);
1672
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1673
            tcg_temp_free(t1);
1674
            /* operands of same sign, result different sign */
1675
            generate_exception(ctx, EXCP_OVERFLOW);
1676
            gen_set_label(l1);
1677
            gen_store_gpr(t0, rd);
1678
            tcg_temp_free(t0);
1679
        }
1680
        opn = "dsub";
1681
        break;
1682
    case OPC_DSUBU:
1683
        if (rs != 0 && rt != 0) {
1684
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1685
        } else if (rs == 0 && rt != 0) {
1686
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1687
        } else if (rs != 0 && rt == 0) {
1688
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1689
        } else {
1690
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1691
        }
1692
        opn = "dsubu";
1693
        break;
1694
#endif
1695
    case OPC_MUL:
1696
        if (likely(rs != 0 && rt != 0)) {
1697
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1698
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1699
        } else {
1700
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1701
        }
1702
        opn = "mul";
1703
        break;
1704
    }
1705
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1706
}
1707

    
1708
/* Conditional move */
1709
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1710
{
1711
    const char *opn = "cond move";
1712
    int l1;
1713

    
1714
    if (rd == 0) {
1715
        /* If no destination, treat it as a NOP.
1716
           For add & sub, we must generate the overflow exception when needed. */
1717
        MIPS_DEBUG("NOP");
1718
        return;
1719
    }
1720

    
1721
    l1 = gen_new_label();
1722
    switch (opc) {
1723
    case OPC_MOVN:
1724
        if (likely(rt != 0))
1725
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1726
        else
1727
            tcg_gen_br(l1);
1728
        opn = "movn";
1729
        break;
1730
    case OPC_MOVZ:
1731
        if (likely(rt != 0))
1732
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1733
        opn = "movz";
1734
        break;
1735
    }
1736
    if (rs != 0)
1737
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1738
    else
1739
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1740
    gen_set_label(l1);
1741

    
1742
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1743
}
1744

    
1745
/* Logic */
1746
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1747
{
1748
    const char *opn = "logic";
1749

    
1750
    if (rd == 0) {
1751
        /* If no destination, treat it as a NOP. */
1752
        MIPS_DEBUG("NOP");
1753
        return;
1754
    }
1755

    
1756
    switch (opc) {
1757
    case OPC_AND:
1758
        if (likely(rs != 0 && rt != 0)) {
1759
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1760
        } else {
1761
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1762
        }
1763
        opn = "and";
1764
        break;
1765
    case OPC_NOR:
1766
        if (rs != 0 && rt != 0) {
1767
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1768
        } else if (rs == 0 && rt != 0) {
1769
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1770
        } else if (rs != 0 && rt == 0) {
1771
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1772
        } else {
1773
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1774
        }
1775
        opn = "nor";
1776
        break;
1777
    case OPC_OR:
1778
        if (likely(rs != 0 && rt != 0)) {
1779
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1780
        } else if (rs == 0 && rt != 0) {
1781
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1782
        } else if (rs != 0 && rt == 0) {
1783
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1784
        } else {
1785
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1786
        }
1787
        opn = "or";
1788
        break;
1789
    case OPC_XOR:
1790
        if (likely(rs != 0 && rt != 0)) {
1791
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1792
        } else if (rs == 0 && rt != 0) {
1793
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1794
        } else if (rs != 0 && rt == 0) {
1795
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1796
        } else {
1797
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1798
        }
1799
        opn = "xor";
1800
        break;
1801
    }
1802
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1803
}
1804

    
1805
/* Set on lower than */
1806
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1807
{
1808
    const char *opn = "slt";
1809
    TCGv t0, t1;
1810

    
1811
    if (rd == 0) {
1812
        /* If no destination, treat it as a NOP. */
1813
        MIPS_DEBUG("NOP");
1814
        return;
1815
    }
1816

    
1817
    t0 = tcg_temp_new();
1818
    t1 = tcg_temp_new();
1819
    gen_load_gpr(t0, rs);
1820
    gen_load_gpr(t1, rt);
1821
    switch (opc) {
1822
    case OPC_SLT:
1823
        gen_op_lt(cpu_gpr[rd], t0, t1);
1824
        opn = "slt";
1825
        break;
1826
    case OPC_SLTU:
1827
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1828
        opn = "sltu";
1829
        break;
1830
    }
1831
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1832
    tcg_temp_free(t0);
1833
    tcg_temp_free(t1);
1834
}
1835

    
1836
/* Shifts */
1837
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1838
                       int rd, int rs, int rt)
1839
{
1840
    const char *opn = "shifts";
1841
    TCGv t0, t1;
1842

    
1843
    if (rd == 0) {
1844
        /* If no destination, treat it as a NOP.
1845
           For add & sub, we must generate the overflow exception when needed. */
1846
        MIPS_DEBUG("NOP");
1847
        return;
1848
    }
1849

    
1850
    t0 = tcg_temp_new();
1851
    t1 = tcg_temp_new();
1852
    gen_load_gpr(t0, rs);
1853
    gen_load_gpr(t1, rt);
1854
    switch (opc) {
1855
    case OPC_SLLV:
1856
        tcg_gen_andi_tl(t0, t0, 0x1f);
1857
        tcg_gen_shl_tl(t0, t1, t0);
1858
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1859
        opn = "sllv";
1860
        break;
1861
    case OPC_SRAV:
1862
        tcg_gen_ext32s_tl(t1, t1);
1863
        tcg_gen_andi_tl(t0, t0, 0x1f);
1864
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1865
        opn = "srav";
1866
        break;
1867
    case OPC_SRLV:
1868
        switch ((ctx->opcode >> 6) & 0x1f) {
1869
        case 0:
1870
            tcg_gen_ext32u_tl(t1, t1);
1871
            tcg_gen_andi_tl(t0, t0, 0x1f);
1872
            tcg_gen_shr_tl(t0, t1, t0);
1873
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1874
            opn = "srlv";
1875
            break;
1876
        case 1:
1877
            /* rotrv is decoded as srlv on non-R2 CPUs */
1878
            if (env->insn_flags & ISA_MIPS32R2) {
1879
                TCGv_i32 t2 = tcg_temp_new_i32();
1880
                TCGv_i32 t3 = tcg_temp_new_i32();
1881

    
1882
                tcg_gen_trunc_tl_i32(t2, t0);
1883
                tcg_gen_trunc_tl_i32(t3, t1);
1884
                tcg_gen_andi_i32(t2, t2, 0x1f);
1885
                tcg_gen_rotr_i32(t2, t3, t2);
1886
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1887
                tcg_temp_free_i32(t2);
1888
                tcg_temp_free_i32(t3);
1889
                opn = "rotrv";
1890
            } else {
1891
                tcg_gen_ext32u_tl(t1, t1);
1892
                tcg_gen_andi_tl(t0, t0, 0x1f);
1893
                tcg_gen_shr_tl(t0, t1, t0);
1894
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1895
                opn = "srlv";
1896
            }
1897
            break;
1898
        default:
1899
            MIPS_INVAL("invalid srlv flag");
1900
            generate_exception(ctx, EXCP_RI);
1901
            break;
1902
        }
1903
        break;
1904
#if defined(TARGET_MIPS64)
1905
    case OPC_DSLLV:
1906
        tcg_gen_andi_tl(t0, t0, 0x3f);
1907
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1908
        opn = "dsllv";
1909
        break;
1910
    case OPC_DSRAV:
1911
        tcg_gen_andi_tl(t0, t0, 0x3f);
1912
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1913
        opn = "dsrav";
1914
        break;
1915
    case OPC_DSRLV:
1916
        switch ((ctx->opcode >> 6) & 0x1f) {
1917
        case 0:
1918
            tcg_gen_andi_tl(t0, t0, 0x3f);
1919
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1920
            opn = "dsrlv";
1921
            break;
1922
        case 1:
1923
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1924
            if (env->insn_flags & ISA_MIPS32R2) {
1925
                tcg_gen_andi_tl(t0, t0, 0x3f);
1926
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1927
                opn = "drotrv";
1928
            } else {
1929
                tcg_gen_andi_tl(t0, t0, 0x3f);
1930
                tcg_gen_shr_tl(t0, t1, t0);
1931
                opn = "dsrlv";
1932
            }
1933
            break;
1934
        default:
1935
            MIPS_INVAL("invalid dsrlv flag");
1936
            generate_exception(ctx, EXCP_RI);
1937
            break;
1938
        }
1939
        break;
1940
#endif
1941
    }
1942
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1943
    tcg_temp_free(t0);
1944
    tcg_temp_free(t1);
1945
}
1946

    
1947
/* Arithmetic on HI/LO registers */
1948
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1949
{
1950
    const char *opn = "hilo";
1951

    
1952
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1953
        /* Treat as NOP. */
1954
        MIPS_DEBUG("NOP");
1955
        return;
1956
    }
1957
    switch (opc) {
1958
    case OPC_MFHI:
1959
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1960
        opn = "mfhi";
1961
        break;
1962
    case OPC_MFLO:
1963
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1964
        opn = "mflo";
1965
        break;
1966
    case OPC_MTHI:
1967
        if (reg != 0)
1968
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1969
        else
1970
            tcg_gen_movi_tl(cpu_HI[0], 0);
1971
        opn = "mthi";
1972
        break;
1973
    case OPC_MTLO:
1974
        if (reg != 0)
1975
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1976
        else
1977
            tcg_gen_movi_tl(cpu_LO[0], 0);
1978
        opn = "mtlo";
1979
        break;
1980
    }
1981
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1982
}
1983

    
1984
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1985
                        int rs, int rt)
1986
{
1987
    const char *opn = "mul/div";
1988
    TCGv t0, t1;
1989

    
1990
    switch (opc) {
1991
    case OPC_DIV:
1992
    case OPC_DIVU:
1993
#if defined(TARGET_MIPS64)
1994
    case OPC_DDIV:
1995
    case OPC_DDIVU:
1996
#endif
1997
        t0 = tcg_temp_local_new();
1998
        t1 = tcg_temp_local_new();
1999
        break;
2000
    default:
2001
        t0 = tcg_temp_new();
2002
        t1 = tcg_temp_new();
2003
        break;
2004
    }
2005

    
2006
    gen_load_gpr(t0, rs);
2007
    gen_load_gpr(t1, rt);
2008
    switch (opc) {
2009
    case OPC_DIV:
2010
        {
2011
            int l1 = gen_new_label();
2012
            int l2 = gen_new_label();
2013

    
2014
            tcg_gen_ext32s_tl(t0, t0);
2015
            tcg_gen_ext32s_tl(t1, t1);
2016
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2017
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2018
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2019

    
2020
            tcg_gen_mov_tl(cpu_LO[0], t0);
2021
            tcg_gen_movi_tl(cpu_HI[0], 0);
2022
            tcg_gen_br(l1);
2023
            gen_set_label(l2);
2024
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2025
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2026
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2027
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2028
            gen_set_label(l1);
2029
        }
2030
        opn = "div";
2031
        break;
2032
    case OPC_DIVU:
2033
        {
2034
            int l1 = gen_new_label();
2035

    
2036
            tcg_gen_ext32u_tl(t0, t0);
2037
            tcg_gen_ext32u_tl(t1, t1);
2038
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2039
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2040
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2041
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2042
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2043
            gen_set_label(l1);
2044
        }
2045
        opn = "divu";
2046
        break;
2047
    case OPC_MULT:
2048
        {
2049
            TCGv_i64 t2 = tcg_temp_new_i64();
2050
            TCGv_i64 t3 = tcg_temp_new_i64();
2051

    
2052
            tcg_gen_ext_tl_i64(t2, t0);
2053
            tcg_gen_ext_tl_i64(t3, t1);
2054
            tcg_gen_mul_i64(t2, t2, t3);
2055
            tcg_temp_free_i64(t3);
2056
            tcg_gen_trunc_i64_tl(t0, t2);
2057
            tcg_gen_shri_i64(t2, t2, 32);
2058
            tcg_gen_trunc_i64_tl(t1, t2);
2059
            tcg_temp_free_i64(t2);
2060
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2061
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2062
        }
2063
        opn = "mult";
2064
        break;
2065
    case OPC_MULTU:
2066
        {
2067
            TCGv_i64 t2 = tcg_temp_new_i64();
2068
            TCGv_i64 t3 = tcg_temp_new_i64();
2069

    
2070
            tcg_gen_ext32u_tl(t0, t0);
2071
            tcg_gen_ext32u_tl(t1, t1);
2072
            tcg_gen_extu_tl_i64(t2, t0);
2073
            tcg_gen_extu_tl_i64(t3, t1);
2074
            tcg_gen_mul_i64(t2, t2, t3);
2075
            tcg_temp_free_i64(t3);
2076
            tcg_gen_trunc_i64_tl(t0, t2);
2077
            tcg_gen_shri_i64(t2, t2, 32);
2078
            tcg_gen_trunc_i64_tl(t1, t2);
2079
            tcg_temp_free_i64(t2);
2080
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2081
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2082
        }
2083
        opn = "multu";
2084
        break;
2085
#if defined(TARGET_MIPS64)
2086
    case OPC_DDIV:
2087
        {
2088
            int l1 = gen_new_label();
2089
            int l2 = gen_new_label();
2090

    
2091
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2092
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2093
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2094
            tcg_gen_mov_tl(cpu_LO[0], t0);
2095
            tcg_gen_movi_tl(cpu_HI[0], 0);
2096
            tcg_gen_br(l1);
2097
            gen_set_label(l2);
2098
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2099
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2100
            gen_set_label(l1);
2101
        }
2102
        opn = "ddiv";
2103
        break;
2104
    case OPC_DDIVU:
2105
        {
2106
            int l1 = gen_new_label();
2107

    
2108
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2109
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2110
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2111
            gen_set_label(l1);
2112
        }
2113
        opn = "ddivu";
2114
        break;
2115
    case OPC_DMULT:
2116
        gen_helper_dmult(t0, t1);
2117
        opn = "dmult";
2118
        break;
2119
    case OPC_DMULTU:
2120
        gen_helper_dmultu(t0, t1);
2121
        opn = "dmultu";
2122
        break;
2123
#endif
2124
    case OPC_MADD:
2125
        {
2126
            TCGv_i64 t2 = tcg_temp_new_i64();
2127
            TCGv_i64 t3 = tcg_temp_new_i64();
2128

    
2129
            tcg_gen_ext_tl_i64(t2, t0);
2130
            tcg_gen_ext_tl_i64(t3, t1);
2131
            tcg_gen_mul_i64(t2, t2, t3);
2132
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2133
            tcg_gen_add_i64(t2, t2, t3);
2134
            tcg_temp_free_i64(t3);
2135
            tcg_gen_trunc_i64_tl(t0, t2);
2136
            tcg_gen_shri_i64(t2, t2, 32);
2137
            tcg_gen_trunc_i64_tl(t1, t2);
2138
            tcg_temp_free_i64(t2);
2139
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2140
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
2141
        }
2142
        opn = "madd";
2143
        break;
2144
    case OPC_MADDU:
2145
       {
2146
            TCGv_i64 t2 = tcg_temp_new_i64();
2147
            TCGv_i64 t3 = tcg_temp_new_i64();
2148

    
2149
            tcg_gen_ext32u_tl(t0, t0);
2150
            tcg_gen_ext32u_tl(t1, t1);
2151
            tcg_gen_extu_tl_i64(t2, t0);
2152
            tcg_gen_extu_tl_i64(t3, t1);
2153
            tcg_gen_mul_i64(t2, t2, t3);
2154
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2155
            tcg_gen_add_i64(t2, t2, t3);
2156
            tcg_temp_free_i64(t3);
2157
            tcg_gen_trunc_i64_tl(t0, t2);
2158
            tcg_gen_shri_i64(t2, t2, 32);
2159
            tcg_gen_trunc_i64_tl(t1, t2);
2160
            tcg_temp_free_i64(t2);
2161
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2162
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2163
        }
2164
        opn = "maddu";
2165
        break;
2166
    case OPC_MSUB:
2167
        {
2168
            TCGv_i64 t2 = tcg_temp_new_i64();
2169
            TCGv_i64 t3 = tcg_temp_new_i64();
2170

    
2171
            tcg_gen_ext_tl_i64(t2, t0);
2172
            tcg_gen_ext_tl_i64(t3, t1);
2173
            tcg_gen_mul_i64(t2, t2, t3);
2174
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2175
            tcg_gen_sub_i64(t2, t2, t3);
2176
            tcg_temp_free_i64(t3);
2177
            tcg_gen_trunc_i64_tl(t0, t2);
2178
            tcg_gen_shri_i64(t2, t2, 32);
2179
            tcg_gen_trunc_i64_tl(t1, t2);
2180
            tcg_temp_free_i64(t2);
2181
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2182
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2183
        }
2184
        opn = "msub";
2185
        break;
2186
    case OPC_MSUBU:
2187
        {
2188
            TCGv_i64 t2 = tcg_temp_new_i64();
2189
            TCGv_i64 t3 = tcg_temp_new_i64();
2190

    
2191
            tcg_gen_ext32u_tl(t0, t0);
2192
            tcg_gen_ext32u_tl(t1, t1);
2193
            tcg_gen_extu_tl_i64(t2, t0);
2194
            tcg_gen_extu_tl_i64(t3, t1);
2195
            tcg_gen_mul_i64(t2, t2, t3);
2196
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2197
            tcg_gen_sub_i64(t2, t2, t3);
2198
            tcg_temp_free_i64(t3);
2199
            tcg_gen_trunc_i64_tl(t0, t2);
2200
            tcg_gen_shri_i64(t2, t2, 32);
2201
            tcg_gen_trunc_i64_tl(t1, t2);
2202
            tcg_temp_free_i64(t2);
2203
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2204
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2205
        }
2206
        opn = "msubu";
2207
        break;
2208
    default:
2209
        MIPS_INVAL(opn);
2210
        generate_exception(ctx, EXCP_RI);
2211
        goto out;
2212
    }
2213
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2214
 out:
2215
    tcg_temp_free(t0);
2216
    tcg_temp_free(t1);
2217
}
2218

    
2219
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2220
                            int rd, int rs, int rt)
2221
{
2222
    const char *opn = "mul vr54xx";
2223
    TCGv t0 = tcg_temp_new();
2224
    TCGv t1 = tcg_temp_new();
2225

    
2226
    gen_load_gpr(t0, rs);
2227
    gen_load_gpr(t1, rt);
2228

    
2229
    switch (opc) {
2230
    case OPC_VR54XX_MULS:
2231
        gen_helper_muls(t0, t0, t1);
2232
        opn = "muls";
2233
        break;
2234
    case OPC_VR54XX_MULSU:
2235
        gen_helper_mulsu(t0, t0, t1);
2236
        opn = "mulsu";
2237
        break;
2238
    case OPC_VR54XX_MACC:
2239
        gen_helper_macc(t0, t0, t1);
2240
        opn = "macc";
2241
        break;
2242
    case OPC_VR54XX_MACCU:
2243
        gen_helper_maccu(t0, t0, t1);
2244
        opn = "maccu";
2245
        break;
2246
    case OPC_VR54XX_MSAC:
2247
        gen_helper_msac(t0, t0, t1);
2248
        opn = "msac";
2249
        break;
2250
    case OPC_VR54XX_MSACU:
2251
        gen_helper_msacu(t0, t0, t1);
2252
        opn = "msacu";
2253
        break;
2254
    case OPC_VR54XX_MULHI:
2255
        gen_helper_mulhi(t0, t0, t1);
2256
        opn = "mulhi";
2257
        break;
2258
    case OPC_VR54XX_MULHIU:
2259
        gen_helper_mulhiu(t0, t0, t1);
2260
        opn = "mulhiu";
2261
        break;
2262
    case OPC_VR54XX_MULSHI:
2263
        gen_helper_mulshi(t0, t0, t1);
2264
        opn = "mulshi";
2265
        break;
2266
    case OPC_VR54XX_MULSHIU:
2267
        gen_helper_mulshiu(t0, t0, t1);
2268
        opn = "mulshiu";
2269
        break;
2270
    case OPC_VR54XX_MACCHI:
2271
        gen_helper_macchi(t0, t0, t1);
2272
        opn = "macchi";
2273
        break;
2274
    case OPC_VR54XX_MACCHIU:
2275
        gen_helper_macchiu(t0, t0, t1);
2276
        opn = "macchiu";
2277
        break;
2278
    case OPC_VR54XX_MSACHI:
2279
        gen_helper_msachi(t0, t0, t1);
2280
        opn = "msachi";
2281
        break;
2282
    case OPC_VR54XX_MSACHIU:
2283
        gen_helper_msachiu(t0, t0, t1);
2284
        opn = "msachiu";
2285
        break;
2286
    default:
2287
        MIPS_INVAL("mul vr54xx");
2288
        generate_exception(ctx, EXCP_RI);
2289
        goto out;
2290
    }
2291
    gen_store_gpr(t0, rd);
2292
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2293

    
2294
 out:
2295
    tcg_temp_free(t0);
2296
    tcg_temp_free(t1);
2297
}
2298

    
2299
static void gen_cl (DisasContext *ctx, uint32_t opc,
2300
                    int rd, int rs)
2301
{
2302
    const char *opn = "CLx";
2303
    TCGv t0;
2304

    
2305
    if (rd == 0) {
2306
        /* Treat as NOP. */
2307
        MIPS_DEBUG("NOP");
2308
        return;
2309
    }
2310
    t0 = tcg_temp_new();
2311
    gen_load_gpr(t0, rs);
2312
    switch (opc) {
2313
    case OPC_CLO:
2314
        gen_helper_clo(cpu_gpr[rd], t0);
2315
        opn = "clo";
2316
        break;
2317
    case OPC_CLZ:
2318
        gen_helper_clz(cpu_gpr[rd], t0);
2319
        opn = "clz";
2320
        break;
2321
#if defined(TARGET_MIPS64)
2322
    case OPC_DCLO:
2323
        gen_helper_dclo(cpu_gpr[rd], t0);
2324
        opn = "dclo";
2325
        break;
2326
    case OPC_DCLZ:
2327
        gen_helper_dclz(cpu_gpr[rd], t0);
2328
        opn = "dclz";
2329
        break;
2330
#endif
2331
    }
2332
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2333
    tcg_temp_free(t0);
2334
}
2335

    
2336
/* Traps */
2337
static void gen_trap (DisasContext *ctx, uint32_t opc,
2338
                      int rs, int rt, int16_t imm)
2339
{
2340
    int cond;
2341
    TCGv t0 = tcg_temp_new();
2342
    TCGv t1 = tcg_temp_new();
2343

    
2344
    cond = 0;
2345
    /* Load needed operands */
2346
    switch (opc) {
2347
    case OPC_TEQ:
2348
    case OPC_TGE:
2349
    case OPC_TGEU:
2350
    case OPC_TLT:
2351
    case OPC_TLTU:
2352
    case OPC_TNE:
2353
        /* Compare two registers */
2354
        if (rs != rt) {
2355
            gen_load_gpr(t0, rs);
2356
            gen_load_gpr(t1, rt);
2357
            cond = 1;
2358
        }
2359
        break;
2360
    case OPC_TEQI:
2361
    case OPC_TGEI:
2362
    case OPC_TGEIU:
2363
    case OPC_TLTI:
2364
    case OPC_TLTIU:
2365
    case OPC_TNEI:
2366
        /* Compare register to immediate */
2367
        if (rs != 0 || imm != 0) {
2368
            gen_load_gpr(t0, rs);
2369
            tcg_gen_movi_tl(t1, (int32_t)imm);
2370
            cond = 1;
2371
        }
2372
        break;
2373
    }
2374
    if (cond == 0) {
2375
        switch (opc) {
2376
        case OPC_TEQ:   /* rs == rs */
2377
        case OPC_TEQI:  /* r0 == 0  */
2378
        case OPC_TGE:   /* rs >= rs */
2379
        case OPC_TGEI:  /* r0 >= 0  */
2380
        case OPC_TGEU:  /* rs >= rs unsigned */
2381
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2382
            /* Always trap */
2383
            generate_exception(ctx, EXCP_TRAP);
2384
            break;
2385
        case OPC_TLT:   /* rs < rs           */
2386
        case OPC_TLTI:  /* r0 < 0            */
2387
        case OPC_TLTU:  /* rs < rs unsigned  */
2388
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2389
        case OPC_TNE:   /* rs != rs          */
2390
        case OPC_TNEI:  /* r0 != 0           */
2391
            /* Never trap: treat as NOP. */
2392
            break;
2393
        }
2394
    } else {
2395
        int l1 = gen_new_label();
2396

    
2397
        switch (opc) {
2398
        case OPC_TEQ:
2399
        case OPC_TEQI:
2400
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2401
            break;
2402
        case OPC_TGE:
2403
        case OPC_TGEI:
2404
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2405
            break;
2406
        case OPC_TGEU:
2407
        case OPC_TGEIU:
2408
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2409
            break;
2410
        case OPC_TLT:
2411
        case OPC_TLTI:
2412
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2413
            break;
2414
        case OPC_TLTU:
2415
        case OPC_TLTIU:
2416
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2417
            break;
2418
        case OPC_TNE:
2419
        case OPC_TNEI:
2420
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2421
            break;
2422
        }
2423
        generate_exception(ctx, EXCP_TRAP);
2424
        gen_set_label(l1);
2425
    }
2426
    tcg_temp_free(t0);
2427
    tcg_temp_free(t1);
2428
}
2429

    
2430
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2431
{
2432
    TranslationBlock *tb;
2433
    tb = ctx->tb;
2434
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2435
        tcg_gen_goto_tb(n);
2436
        gen_save_pc(dest);
2437
        tcg_gen_exit_tb((long)tb + n);
2438
    } else {
2439
        gen_save_pc(dest);
2440
        tcg_gen_exit_tb(0);
2441
    }
2442
}
2443

    
2444
/* Branches (before delay slot) */
2445
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2446
                                int rs, int rt, int32_t offset)
2447
{
2448
    target_ulong btgt = -1;
2449
    int blink = 0;
2450
    int bcond_compute = 0;
2451
    TCGv t0 = tcg_temp_new();
2452
    TCGv t1 = tcg_temp_new();
2453

    
2454
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2455
#ifdef MIPS_DEBUG_DISAS
2456
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2457
#endif
2458
        generate_exception(ctx, EXCP_RI);
2459
        goto out;
2460
    }
2461

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

    
2670
    ctx->btarget = btgt;
2671
    if (blink > 0) {
2672
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2673
    }
2674

    
2675
 out:
2676
    tcg_temp_free(t0);
2677
    tcg_temp_free(t1);
2678
}
2679

    
2680
/* special3 bitfield operations */
2681
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2682
                        int rs, int lsb, int msb)
2683
{
2684
    TCGv t0 = tcg_temp_new();
2685
    TCGv t1 = tcg_temp_new();
2686
    target_ulong mask;
2687

    
2688
    gen_load_gpr(t1, rs);
2689
    switch (opc) {
2690
    case OPC_EXT:
2691
        if (lsb + msb > 31)
2692
            goto fail;
2693
        tcg_gen_shri_tl(t0, t1, lsb);
2694
        if (msb != 31) {
2695
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2696
        } else {
2697
            tcg_gen_ext32s_tl(t0, t0);
2698
        }
2699
        break;
2700
#if defined(TARGET_MIPS64)
2701
    case OPC_DEXTM:
2702
        tcg_gen_shri_tl(t0, t1, lsb);
2703
        if (msb != 31) {
2704
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2705
        }
2706
        break;
2707
    case OPC_DEXTU:
2708
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2709
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2710
        break;
2711
    case OPC_DEXT:
2712
        tcg_gen_shri_tl(t0, t1, lsb);
2713
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2714
        break;
2715
#endif
2716
    case OPC_INS:
2717
        if (lsb > msb)
2718
            goto fail;
2719
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2720
        gen_load_gpr(t0, rt);
2721
        tcg_gen_andi_tl(t0, t0, ~mask);
2722
        tcg_gen_shli_tl(t1, t1, lsb);
2723
        tcg_gen_andi_tl(t1, t1, mask);
2724
        tcg_gen_or_tl(t0, t0, t1);
2725
        tcg_gen_ext32s_tl(t0, t0);
2726
        break;
2727
#if defined(TARGET_MIPS64)
2728
    case OPC_DINSM:
2729
        if (lsb > msb)
2730
            goto fail;
2731
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2732
        gen_load_gpr(t0, rt);
2733
        tcg_gen_andi_tl(t0, t0, ~mask);
2734
        tcg_gen_shli_tl(t1, t1, lsb);
2735
        tcg_gen_andi_tl(t1, t1, mask);
2736
        tcg_gen_or_tl(t0, t0, t1);
2737
        break;
2738
    case OPC_DINSU:
2739
        if (lsb > msb)
2740
            goto fail;
2741
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2742
        gen_load_gpr(t0, rt);
2743
        tcg_gen_andi_tl(t0, t0, ~mask);
2744
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2745
        tcg_gen_andi_tl(t1, t1, mask);
2746
        tcg_gen_or_tl(t0, t0, t1);
2747
        break;
2748
    case OPC_DINS:
2749
        if (lsb > msb)
2750
            goto fail;
2751
        gen_load_gpr(t0, rt);
2752
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2753
        gen_load_gpr(t0, rt);
2754
        tcg_gen_andi_tl(t0, t0, ~mask);
2755
        tcg_gen_shli_tl(t1, t1, lsb);
2756
        tcg_gen_andi_tl(t1, t1, mask);
2757
        tcg_gen_or_tl(t0, t0, t1);
2758
        break;
2759
#endif
2760
    default:
2761
fail:
2762
        MIPS_INVAL("bitops");
2763
        generate_exception(ctx, EXCP_RI);
2764
        tcg_temp_free(t0);
2765
        tcg_temp_free(t1);
2766
        return;
2767
    }
2768
    gen_store_gpr(t0, rt);
2769
    tcg_temp_free(t0);
2770
    tcg_temp_free(t1);
2771
}
2772

    
2773
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2774
{
2775
    TCGv t0;
2776

    
2777
    if (rd == 0) {
2778
        /* If no destination, treat it as a NOP. */
2779
        MIPS_DEBUG("NOP");
2780
        return;
2781
    }
2782

    
2783
    t0 = tcg_temp_new();
2784
    gen_load_gpr(t0, rt);
2785
    switch (op2) {
2786
    case OPC_WSBH:
2787
        {
2788
            TCGv t1 = tcg_temp_new();
2789

    
2790
            tcg_gen_shri_tl(t1, t0, 8);
2791
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2792
            tcg_gen_shli_tl(t0, t0, 8);
2793
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2794
            tcg_gen_or_tl(t0, t0, t1);
2795
            tcg_temp_free(t1);
2796
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2797
        }
2798
        break;
2799
    case OPC_SEB:
2800
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2801
        break;
2802
    case OPC_SEH:
2803
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2804
        break;
2805
#if defined(TARGET_MIPS64)
2806
    case OPC_DSBH:
2807
        {
2808
            TCGv t1 = tcg_temp_new();
2809

    
2810
            tcg_gen_shri_tl(t1, t0, 8);
2811
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2812
            tcg_gen_shli_tl(t0, t0, 8);
2813
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2814
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2815
            tcg_temp_free(t1);
2816
        }
2817
        break;
2818
    case OPC_DSHD:
2819
        {
2820
            TCGv t1 = tcg_temp_new();
2821

    
2822
            tcg_gen_shri_tl(t1, t0, 16);
2823
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2824
            tcg_gen_shli_tl(t0, t0, 16);
2825
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2826
            tcg_gen_or_tl(t0, t0, t1);
2827
            tcg_gen_shri_tl(t1, t0, 32);
2828
            tcg_gen_shli_tl(t0, t0, 32);
2829
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2830
            tcg_temp_free(t1);
2831
        }
2832
        break;
2833
#endif
2834
    default:
2835
        MIPS_INVAL("bsfhl");
2836
        generate_exception(ctx, EXCP_RI);
2837
        tcg_temp_free(t0);
2838
        return;
2839
    }
2840
    tcg_temp_free(t0);
2841
}
2842

    
2843
#ifndef CONFIG_USER_ONLY
2844
/* CP0 (MMU and control) */
2845
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2846
{
2847
    TCGv_i32 t0 = tcg_temp_new_i32();
2848

    
2849
    tcg_gen_ld_i32(t0, cpu_env, off);
2850
    tcg_gen_ext_i32_tl(arg, t0);
2851
    tcg_temp_free_i32(t0);
2852
}
2853

    
2854
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2855
{
2856
    tcg_gen_ld_tl(arg, cpu_env, off);
2857
    tcg_gen_ext32s_tl(arg, arg);
2858
}
2859

    
2860
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2861
{
2862
    TCGv_i32 t0 = tcg_temp_new_i32();
2863

    
2864
    tcg_gen_trunc_tl_i32(t0, arg);
2865
    tcg_gen_st_i32(t0, cpu_env, off);
2866
    tcg_temp_free_i32(t0);
2867
}
2868

    
2869
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2870
{
2871
    tcg_gen_ext32s_tl(arg, arg);
2872
    tcg_gen_st_tl(arg, cpu_env, off);
2873
}
2874

    
2875
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2876
{
2877
    const char *rn = "invalid";
2878

    
2879
    if (sel != 0)
2880
        check_insn(env, ctx, ISA_MIPS32);
2881

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

    
3447
die:
3448
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3449
    generate_exception(ctx, EXCP_RI);
3450
}
3451

    
3452
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3453
{
3454
    const char *rn = "invalid";
3455

    
3456
    if (sel != 0)
3457
        check_insn(env, ctx, ISA_MIPS32);
3458

    
3459
    if (use_icount)
3460
        gen_io_start();
3461

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

    
4042
die:
4043
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4044
    generate_exception(ctx, EXCP_RI);
4045
}
4046

    
4047
#if defined(TARGET_MIPS64)
4048
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4049
{
4050
    const char *rn = "invalid";
4051

    
4052
    if (sel != 0)
4053
        check_insn(env, ctx, ISA_MIPS64);
4054

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

    
4609
die:
4610
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4611
    generate_exception(ctx, EXCP_RI);
4612
}
4613

    
4614
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4615
{
4616
    const char *rn = "invalid";
4617

    
4618
    if (sel != 0)
4619
        check_insn(env, ctx, ISA_MIPS64);
4620

    
4621
    if (use_icount)
4622
        gen_io_start();
4623

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

    
5195
die:
5196
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5197
    generate_exception(ctx, EXCP_RI);
5198
}
5199
#endif /* TARGET_MIPS64 */
5200

    
5201
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5202
                     int u, int sel, int h)
5203
{
5204
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5205
    TCGv t0 = tcg_temp_local_new();
5206

    
5207
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5208
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5209
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5210
        tcg_gen_movi_tl(t0, -1);
5211
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5212
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5213
        tcg_gen_movi_tl(t0, -1);
5214
    else if (u == 0) {
5215
        switch (rt) {
5216
        case 2:
5217
            switch (sel) {
5218
            case 1:
5219
                gen_helper_mftc0_tcstatus(t0);
5220
                break;
5221
            case 2:
5222
                gen_helper_mftc0_tcbind(t0);
5223
                break;
5224
            case 3:
5225
                gen_helper_mftc0_tcrestart(t0);
5226
                break;
5227
            case 4:
5228
                gen_helper_mftc0_tchalt(t0);
5229
                break;
5230
            case 5:
5231
                gen_helper_mftc0_tccontext(t0);
5232
                break;
5233
            case 6:
5234
                gen_helper_mftc0_tcschedule(t0);
5235
                break;
5236
            case 7:
5237
                gen_helper_mftc0_tcschefback(t0);
5238
                break;
5239
            default:
5240
                gen_mfc0(env, ctx, t0, rt, sel);
5241
                break;
5242
            }
5243
            break;
5244
        case 10:
5245
            switch (sel) {
5246
            case 0:
5247
                gen_helper_mftc0_entryhi(t0);
5248
                break;
5249
            default:
5250
                gen_mfc0(env, ctx, t0, rt, sel);
5251
                break;
5252
            }
5253
        case 12:
5254
            switch (sel) {
5255
            case 0:
5256
                gen_helper_mftc0_status(t0);
5257
                break;
5258
            default:
5259
                gen_mfc0(env, ctx, t0, rt, sel);
5260
                break;
5261
            }
5262
        case 23:
5263
            switch (sel) {
5264
            case 0:
5265
                gen_helper_mftc0_debug(t0);
5266
                break;
5267
            default:
5268
                gen_mfc0(env, ctx, t0, rt, sel);
5269
                break;
5270
            }
5271
            break;
5272
        default:
5273
            gen_mfc0(env, ctx, t0, rt, sel);
5274
        }
5275
    } else switch (sel) {
5276
    /* GPR registers. */
5277
    case 0:
5278
        gen_helper_1i(mftgpr, t0, rt);
5279
        break;
5280
    /* Auxiliary CPU registers */
5281
    case 1:
5282
        switch (rt) {
5283
        case 0:
5284
            gen_helper_1i(mftlo, t0, 0);
5285
            break;
5286
        case 1:
5287
            gen_helper_1i(mfthi, t0, 0);
5288
            break;
5289
        case 2:
5290
            gen_helper_1i(mftacx, t0, 0);
5291
            break;
5292
        case 4:
5293
            gen_helper_1i(mftlo, t0, 1);
5294
            break;
5295
        case 5:
5296
            gen_helper_1i(mfthi, t0, 1);
5297
            break;
5298
        case 6:
5299
            gen_helper_1i(mftacx, t0, 1);
5300
            break;
5301
        case 8:
5302
            gen_helper_1i(mftlo, t0, 2);
5303
            break;
5304
        case 9:
5305
            gen_helper_1i(mfthi, t0, 2);
5306
            break;
5307
        case 10:
5308
            gen_helper_1i(mftacx, t0, 2);
5309
            break;
5310
        case 12:
5311
            gen_helper_1i(mftlo, t0, 3);
5312
            break;
5313
        case 13:
5314
            gen_helper_1i(mfthi, t0, 3);
5315
            break;
5316
        case 14:
5317
            gen_helper_1i(mftacx, t0, 3);
5318
            break;
5319
        case 16:
5320
            gen_helper_mftdsp(t0);
5321
            break;
5322
        default:
5323
            goto die;
5324
        }
5325
        break;
5326
    /* Floating point (COP1). */
5327
    case 2:
5328
        /* XXX: For now we support only a single FPU context. */
5329
        if (h == 0) {
5330
            TCGv_i32 fp0 = tcg_temp_new_i32();
5331

    
5332
            gen_load_fpr32(fp0, rt);
5333
            tcg_gen_ext_i32_tl(t0, fp0);
5334
            tcg_temp_free_i32(fp0);
5335
        } else {
5336
            TCGv_i32 fp0 = tcg_temp_new_i32();
5337

    
5338
            gen_load_fpr32h(fp0, rt);
5339
            tcg_gen_ext_i32_tl(t0, fp0);
5340
            tcg_temp_free_i32(fp0);
5341
        }
5342
        break;
5343
    case 3:
5344
        /* XXX: For now we support only a single FPU context. */
5345
        gen_helper_1i(cfc1, t0, rt);
5346
        break;
5347
    /* COP2: Not implemented. */
5348
    case 4:
5349
    case 5:
5350
        /* fall through */
5351
    default:
5352
        goto die;
5353
    }
5354
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5355
    gen_store_gpr(t0, rd);
5356
    tcg_temp_free(t0);
5357
    return;
5358

    
5359
die:
5360
    tcg_temp_free(t0);
5361
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5362
    generate_exception(ctx, EXCP_RI);
5363
}
5364

    
5365
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5366
                     int u, int sel, int h)
5367
{
5368
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5369
    TCGv t0 = tcg_temp_local_new();
5370

    
5371
    gen_load_gpr(t0, rt);
5372
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5373
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5374
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5375
        /* NOP */ ;
5376
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5377
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5378
        /* NOP */ ;
5379
    else if (u == 0) {
5380
        switch (rd) {
5381
        case 2:
5382
            switch (sel) {
5383
            case 1:
5384
                gen_helper_mttc0_tcstatus(t0);
5385
                break;
5386
            case 2:
5387
                gen_helper_mttc0_tcbind(t0);
5388
                break;
5389
            case 3:
5390
                gen_helper_mttc0_tcrestart(t0);
5391
                break;
5392
            case 4:
5393
                gen_helper_mttc0_tchalt(t0);
5394
                break;
5395
            case 5:
5396
                gen_helper_mttc0_tccontext(t0);
5397
                break;
5398
            case 6:
5399
                gen_helper_mttc0_tcschedule(t0);
5400
                break;
5401
            case 7:
5402
                gen_helper_mttc0_tcschefback(t0);
5403
                break;
5404
            default:
5405
                gen_mtc0(env, ctx, t0, rd, sel);
5406
                break;
5407
            }
5408
            break;
5409
        case 10:
5410
            switch (sel) {
5411
            case 0:
5412
                gen_helper_mttc0_entryhi(t0);
5413
                break;
5414
            default:
5415
                gen_mtc0(env, ctx, t0, rd, sel);
5416
                break;
5417
            }
5418
        case 12:
5419
            switch (sel) {
5420
            case 0:
5421
                gen_helper_mttc0_status(t0);
5422
                break;
5423
            default:
5424
                gen_mtc0(env, ctx, t0, rd, sel);
5425
                break;
5426
            }
5427
        case 23:
5428
            switch (sel) {
5429
            case 0:
5430
                gen_helper_mttc0_debug(t0);
5431
                break;
5432
            default:
5433
                gen_mtc0(env, ctx, t0, rd, sel);
5434
                break;
5435
            }
5436
            break;
5437
        default:
5438
            gen_mtc0(env, ctx, t0, rd, sel);
5439
        }
5440
    } else switch (sel) {
5441
    /* GPR registers. */
5442
    case 0:
5443
        gen_helper_1i(mttgpr, t0, rd);
5444
        break;
5445
    /* Auxiliary CPU registers */
5446
    case 1:
5447
        switch (rd) {
5448
        case 0:
5449
            gen_helper_1i(mttlo, t0, 0);
5450
            break;
5451
        case 1:
5452
            gen_helper_1i(mtthi, t0, 0);
5453
            break;
5454
        case 2:
5455
            gen_helper_1i(mttacx, t0, 0);
5456
            break;
5457
        case 4:
5458
            gen_helper_1i(mttlo, t0, 1);
5459
            break;
5460
        case 5:
5461
            gen_helper_1i(mtthi, t0, 1);
5462
            break;
5463
        case 6:
5464
            gen_helper_1i(mttacx, t0, 1);
5465
            break;
5466
        case 8:
5467
            gen_helper_1i(mttlo, t0, 2);
5468
            break;
5469
        case 9:
5470
            gen_helper_1i(mtthi, t0, 2);
5471
            break;
5472
        case 10:
5473
            gen_helper_1i(mttacx, t0, 2);
5474
            break;
5475
        case 12:
5476
            gen_helper_1i(mttlo, t0, 3);
5477
            break;
5478
        case 13:
5479
            gen_helper_1i(mtthi, t0, 3);
5480
            break;
5481
        case 14:
5482
            gen_helper_1i(mttacx, t0, 3);
5483
            break;
5484
        case 16:
5485
            gen_helper_mttdsp(t0);
5486
            break;
5487
        default:
5488
            goto die;
5489
        }
5490
        break;
5491
    /* Floating point (COP1). */
5492
    case 2:
5493
        /* XXX: For now we support only a single FPU context. */
5494
        if (h == 0) {
5495
            TCGv_i32 fp0 = tcg_temp_new_i32();
5496

    
5497
            tcg_gen_trunc_tl_i32(fp0, t0);
5498
            gen_store_fpr32(fp0, rd);
5499
            tcg_temp_free_i32(fp0);
5500
        } else {
5501
            TCGv_i32 fp0 = tcg_temp_new_i32();
5502

    
5503
            tcg_gen_trunc_tl_i32(fp0, t0);
5504
            gen_store_fpr32h(fp0, rd);
5505
            tcg_temp_free_i32(fp0);
5506
        }
5507
        break;
5508
    case 3:
5509
        /* XXX: For now we support only a single FPU context. */
5510
        gen_helper_1i(ctc1, t0, rd);
5511
        break;
5512
    /* COP2: Not implemented. */
5513
    case 4:
5514
    case 5:
5515
        /* fall through */
5516
    default:
5517
        goto die;
5518
    }
5519
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5520
    tcg_temp_free(t0);
5521
    return;
5522

    
5523
die:
5524
    tcg_temp_free(t0);
5525
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5526
    generate_exception(ctx, EXCP_RI);
5527
}
5528

    
5529
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5530
{
5531
    const char *opn = "ldst";
5532

    
5533
    switch (opc) {
5534
    case OPC_MFC0:
5535
        if (rt == 0) {
5536
            /* Treat as NOP. */
5537
            return;
5538
        }
5539
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5540
        opn = "mfc0";
5541
        break;
5542
    case OPC_MTC0:
5543
        {
5544
            TCGv t0 = tcg_temp_new();
5545

    
5546
            gen_load_gpr(t0, rt);
5547
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5548
            tcg_temp_free(t0);
5549
        }
5550
        opn = "mtc0";
5551
        break;
5552
#if defined(TARGET_MIPS64)
5553
    case OPC_DMFC0:
5554
        check_insn(env, ctx, ISA_MIPS3);
5555
        if (rt == 0) {
5556
            /* Treat as NOP. */
5557
            return;
5558
        }
5559
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5560
        opn = "dmfc0";
5561
        break;
5562
    case OPC_DMTC0:
5563
        check_insn(env, ctx, ISA_MIPS3);
5564
        {
5565
            TCGv t0 = tcg_temp_new();
5566

    
5567
            gen_load_gpr(t0, rt);
5568
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5569
            tcg_temp_free(t0);
5570
        }
5571
        opn = "dmtc0";
5572
        break;
5573
#endif
5574
    case OPC_MFTR:
5575
        check_insn(env, ctx, ASE_MT);
5576
        if (rd == 0) {
5577
            /* Treat as NOP. */
5578
            return;
5579
        }
5580
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5581
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5582
        opn = "mftr";
5583
        break;
5584
    case OPC_MTTR:
5585
        check_insn(env, ctx, ASE_MT);
5586
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5587
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5588
        opn = "mttr";
5589
        break;
5590
    case OPC_TLBWI:
5591
        opn = "tlbwi";
5592
        if (!env->tlb->helper_tlbwi)
5593
            goto die;
5594
        gen_helper_tlbwi();
5595
        break;
5596
    case OPC_TLBWR:
5597
        opn = "tlbwr";
5598
        if (!env->tlb->helper_tlbwr)
5599
            goto die;
5600
        gen_helper_tlbwr();
5601
        break;
5602
    case OPC_TLBP:
5603
        opn = "tlbp";
5604
        if (!env->tlb->helper_tlbp)
5605
            goto die;
5606
        gen_helper_tlbp();
5607
        break;
5608
    case OPC_TLBR:
5609
        opn = "tlbr";
5610
        if (!env->tlb->helper_tlbr)
5611
            goto die;
5612
        gen_helper_tlbr();
5613
        break;
5614
    case OPC_ERET:
5615
        opn = "eret";
5616
        check_insn(env, ctx, ISA_MIPS2);
5617
        gen_helper_eret();
5618
        ctx->bstate = BS_EXCP;
5619
        break;
5620
    case OPC_DERET:
5621
        opn = "deret";
5622
        check_insn(env, ctx, ISA_MIPS32);
5623
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5624
            MIPS_INVAL(opn);
5625
            generate_exception(ctx, EXCP_RI);
5626
        } else {
5627
            gen_helper_deret();
5628
            ctx->bstate = BS_EXCP;
5629
        }
5630
        break;
5631
    case OPC_WAIT:
5632
        opn = "wait";
5633
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5634
        /* If we get an exception, we want to restart at next instruction */
5635
        ctx->pc += 4;
5636
        save_cpu_state(ctx, 1);
5637
        ctx->pc -= 4;
5638
        gen_helper_wait();
5639
        ctx->bstate = BS_EXCP;
5640
        break;
5641
    default:
5642
 die:
5643
        MIPS_INVAL(opn);
5644
        generate_exception(ctx, EXCP_RI);
5645
        return;
5646
    }
5647
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5648
}
5649
#endif /* !CONFIG_USER_ONLY */
5650

    
5651
/* CP1 Branches (before delay slot) */
5652
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5653
                                 int32_t cc, int32_t offset)
5654
{
5655
    target_ulong btarget;
5656
    const char *opn = "cp1 cond branch";
5657
    TCGv_i32 t0 = tcg_temp_new_i32();
5658

    
5659
    if (cc != 0)
5660
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5661

    
5662
    btarget = ctx->pc + 4 + offset;
5663

    
5664
    switch (op) {
5665
    case OPC_BC1F:
5666
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5667
        tcg_gen_not_i32(t0, t0);
5668
        tcg_gen_andi_i32(t0, t0, 1);
5669
        tcg_gen_extu_i32_tl(bcond, t0);
5670
        opn = "bc1f";
5671
        goto not_likely;
5672
    case OPC_BC1FL:
5673
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5674
        tcg_gen_not_i32(t0, t0);
5675
        tcg_gen_andi_i32(t0, t0, 1);
5676
        tcg_gen_extu_i32_tl(bcond, t0);
5677
        opn = "bc1fl";
5678
        goto likely;
5679
    case OPC_BC1T:
5680
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5681
        tcg_gen_andi_i32(t0, t0, 1);
5682
        tcg_gen_extu_i32_tl(bcond, t0);
5683
        opn = "bc1t";
5684
        goto not_likely;
5685
    case OPC_BC1TL:
5686
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5687
        tcg_gen_andi_i32(t0, t0, 1);
5688
        tcg_gen_extu_i32_tl(bcond, t0);
5689
        opn = "bc1tl";
5690
    likely:
5691
        ctx->hflags |= MIPS_HFLAG_BL;
5692
        break;
5693
    case OPC_BC1FANY2:
5694
        {
5695
            TCGv_i32 t1 = tcg_temp_new_i32();
5696
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5697
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5698
            tcg_gen_or_i32(t0, t0, t1);
5699
            tcg_temp_free_i32(t1);
5700
            tcg_gen_not_i32(t0, t0);
5701
            tcg_gen_andi_i32(t0, t0, 1);
5702
            tcg_gen_extu_i32_tl(bcond, t0);
5703
        }
5704
        opn = "bc1any2f";
5705
        goto not_likely;
5706
    case OPC_BC1TANY2:
5707
        {
5708
            TCGv_i32 t1 = tcg_temp_new_i32();
5709
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5710
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5711
            tcg_gen_or_i32(t0, t0, t1);
5712
            tcg_temp_free_i32(t1);
5713
            tcg_gen_andi_i32(t0, t0, 1);
5714
            tcg_gen_extu_i32_tl(bcond, t0);
5715
        }
5716
        opn = "bc1any2t";
5717
        goto not_likely;
5718
    case OPC_BC1FANY4:
5719
        {
5720
            TCGv_i32 t1 = tcg_temp_new_i32();
5721
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5722
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5723
            tcg_gen_or_i32(t0, t0, t1);
5724
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5725
            tcg_gen_or_i32(t0, t0, t1);
5726
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5727
            tcg_gen_or_i32(t0, t0, t1);
5728
            tcg_temp_free_i32(t1);
5729
            tcg_gen_not_i32(t0, t0);
5730
            tcg_gen_andi_i32(t0, t0, 1);
5731
            tcg_gen_extu_i32_tl(bcond, t0);
5732
        }
5733
        opn = "bc1any4f";
5734
        goto not_likely;
5735
    case OPC_BC1TANY4:
5736
        {
5737
            TCGv_i32 t1 = tcg_temp_new_i32();
5738
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5739
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5740
            tcg_gen_or_i32(t0, t0, t1);
5741
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5742
            tcg_gen_or_i32(t0, t0, t1);
5743
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5744
            tcg_gen_or_i32(t0, t0, t1);
5745
            tcg_temp_free_i32(t1);
5746
            tcg_gen_andi_i32(t0, t0, 1);
5747
            tcg_gen_extu_i32_tl(bcond, t0);
5748
        }
5749
        opn = "bc1any4t";
5750
    not_likely:
5751
        ctx->hflags |= MIPS_HFLAG_BC;
5752
        break;
5753
    default:
5754
        MIPS_INVAL(opn);
5755
        generate_exception (ctx, EXCP_RI);
5756
        goto out;
5757
    }
5758
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5759
               ctx->hflags, btarget);
5760
    ctx->btarget = btarget;
5761

    
5762
 out:
5763
    tcg_temp_free_i32(t0);
5764
}
5765

    
5766
/* Coprocessor 1 (FPU) */
5767

    
5768
#define FOP(func, fmt) (((fmt) << 21) | (func))
5769

    
5770
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5771
{
5772
    const char *opn = "cp1 move";
5773
    TCGv t0 = tcg_temp_new();
5774

    
5775
    switch (opc) {
5776
    case OPC_MFC1:
5777
        {
5778
            TCGv_i32 fp0 = tcg_temp_new_i32();
5779

    
5780
            gen_load_fpr32(fp0, fs);
5781
            tcg_gen_ext_i32_tl(t0, fp0);
5782
            tcg_temp_free_i32(fp0);
5783
        }
5784
        gen_store_gpr(t0, rt);
5785
        opn = "mfc1";
5786
        break;
5787
    case OPC_MTC1:
5788
        gen_load_gpr(t0, rt);
5789
        {
5790
            TCGv_i32 fp0 = tcg_temp_new_i32();
5791

    
5792
            tcg_gen_trunc_tl_i32(fp0, t0);
5793
            gen_store_fpr32(fp0, fs);
5794
            tcg_temp_free_i32(fp0);
5795
        }
5796
        opn = "mtc1";
5797
        break;
5798
    case OPC_CFC1:
5799
        gen_helper_1i(cfc1, t0, fs);
5800
        gen_store_gpr(t0, rt);
5801
        opn = "cfc1";
5802
        break;
5803
    case OPC_CTC1:
5804
        gen_load_gpr(t0, rt);
5805
        gen_helper_1i(ctc1, t0, fs);
5806
        opn = "ctc1";
5807
        break;
5808
#if defined(TARGET_MIPS64)
5809
    case OPC_DMFC1:
5810
        gen_load_fpr64(ctx, t0, fs);
5811
        gen_store_gpr(t0, rt);
5812
        opn = "dmfc1";
5813
        break;
5814
    case OPC_DMTC1:
5815
        gen_load_gpr(t0, rt);
5816
        gen_store_fpr64(ctx, t0, fs);
5817
        opn = "dmtc1";
5818
        break;
5819
#endif
5820
    case OPC_MFHC1:
5821
        {
5822
            TCGv_i32 fp0 = tcg_temp_new_i32();
5823

    
5824
            gen_load_fpr32h(fp0, fs);
5825
            tcg_gen_ext_i32_tl(t0, fp0);
5826
            tcg_temp_free_i32(fp0);
5827
        }
5828
        gen_store_gpr(t0, rt);
5829
        opn = "mfhc1";
5830
        break;
5831
    case OPC_MTHC1:
5832
        gen_load_gpr(t0, rt);
5833
        {
5834
            TCGv_i32 fp0 = tcg_temp_new_i32();
5835

    
5836
            tcg_gen_trunc_tl_i32(fp0, t0);
5837
            gen_store_fpr32h(fp0, fs);
5838
            tcg_temp_free_i32(fp0);
5839
        }
5840
        opn = "mthc1";
5841
        break;
5842
    default:
5843
        MIPS_INVAL(opn);
5844
        generate_exception (ctx, EXCP_RI);
5845
        goto out;
5846
    }
5847
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5848

    
5849
 out:
5850
    tcg_temp_free(t0);
5851
}
5852

    
5853
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5854
{
5855
    int l1;
5856
    TCGCond cond;
5857
    TCGv_i32 t0;
5858

    
5859
    if (rd == 0) {
5860
        /* Treat as NOP. */
5861
        return;
5862
    }
5863

    
5864
    if (tf)
5865
        cond = TCG_COND_EQ;
5866
    else
5867
        cond = TCG_COND_NE;
5868

    
5869
    l1 = gen_new_label();
5870
    t0 = tcg_temp_new_i32();
5871
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5872
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5873
    tcg_temp_free_i32(t0);
5874
    if (rs == 0) {
5875
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5876
    } else {
5877
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5878
    }
5879
    gen_set_label(l1);
5880
}
5881

    
5882
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5883
{
5884
    int cond;
5885
    TCGv_i32 t0 = tcg_temp_new_i32();
5886
    int l1 = gen_new_label();
5887

    
5888
    if (tf)
5889
        cond = TCG_COND_EQ;
5890
    else
5891
        cond = TCG_COND_NE;
5892

    
5893
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5894
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5895
    gen_load_fpr32(t0, fs);
5896
    gen_store_fpr32(t0, fd);
5897
    gen_set_label(l1);
5898
    tcg_temp_free_i32(t0);
5899
}
5900

    
5901
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5902
{
5903
    int cond;
5904
    TCGv_i32 t0 = tcg_temp_new_i32();
5905
    TCGv_i64 fp0;
5906
    int l1 = gen_new_label();
5907

    
5908
    if (tf)
5909
        cond = TCG_COND_EQ;
5910
    else
5911
        cond = TCG_COND_NE;
5912

    
5913
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5914
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5915
    tcg_temp_free_i32(t0);
5916
    fp0 = tcg_temp_new_i64();
5917
    gen_load_fpr64(ctx, fp0, fs);
5918
    gen_store_fpr64(ctx, fp0, fd);
5919
    tcg_temp_free_i64(fp0);
5920
    gen_set_label(l1);
5921
}
5922

    
5923
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5924
{
5925
    int cond;
5926
    TCGv_i32 t0 = tcg_temp_new_i32();
5927
    int l1 = gen_new_label();
5928
    int l2 = gen_new_label();
5929

    
5930
    if (tf)
5931
        cond = TCG_COND_EQ;
5932
    else
5933
        cond = TCG_COND_NE;
5934

    
5935
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5936
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5937
    gen_load_fpr32(t0, fs);
5938
    gen_store_fpr32(t0, fd);
5939
    gen_set_label(l1);
5940

    
5941
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5942
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5943
    gen_load_fpr32h(t0, fs);
5944
    gen_store_fpr32h(t0, fd);
5945
    tcg_temp_free_i32(t0);
5946
    gen_set_label(l2);
5947
}
5948

    
5949

    
5950
static void gen_farith (DisasContext *ctx, uint32_t op1,
5951
                        int ft, int fs, int fd, int cc)
5952
{
5953
    const char *opn = "farith";
5954
    const char *condnames[] = {
5955
            "c.f",
5956
            "c.un",
5957
            "c.eq",
5958
            "c.ueq",
5959
            "c.olt",
5960
            "c.ult",
5961
            "c.ole",
5962
            "c.ule",
5963
            "c.sf",
5964
            "c.ngle",
5965
            "c.seq",
5966
            "c.ngl",
5967
            "c.lt",
5968
            "c.nge",
5969
            "c.le",
5970
            "c.ngt",
5971
    };
5972
    const char *condnames_abs[] = {
5973
            "cabs.f",
5974
            "cabs.un",
5975
            "cabs.eq",
5976
            "cabs.ueq",
5977
            "cabs.olt",
5978
            "cabs.ult",
5979
            "cabs.ole",
5980
            "cabs.ule",
5981
            "cabs.sf",
5982
            "cabs.ngle",
5983
            "cabs.seq",
5984
            "cabs.ngl",
5985
            "cabs.lt",
5986
            "cabs.nge",
5987
            "cabs.le",
5988
            "cabs.ngt",
5989
    };
5990
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5991
    uint32_t func = ctx->opcode & 0x3f;
5992

    
5993
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5994
    case FOP(0, 16):
5995
        {
5996
            TCGv_i32 fp0 = tcg_temp_new_i32();
5997
            TCGv_i32 fp1 = tcg_temp_new_i32();
5998

    
5999
            gen_load_fpr32(fp0, fs);
6000
            gen_load_fpr32(fp1, ft);
6001
            gen_helper_float_add_s(fp0, fp0, fp1);
6002
            tcg_temp_free_i32(fp1);
6003
            gen_store_fpr32(fp0, fd);
6004
            tcg_temp_free_i32(fp0);
6005
        }
6006
        opn = "add.s";
6007
        optype = BINOP;
6008
        break;
6009
    case FOP(1, 16):
6010
        {
6011
            TCGv_i32 fp0 = tcg_temp_new_i32();
6012
            TCGv_i32 fp1 = tcg_temp_new_i32();
6013

    
6014
            gen_load_fpr32(fp0, fs);
6015
            gen_load_fpr32(fp1, ft);
6016
            gen_helper_float_sub_s(fp0, fp0, fp1);
6017
            tcg_temp_free_i32(fp1);
6018
            gen_store_fpr32(fp0, fd);
6019
            tcg_temp_free_i32(fp0);
6020
        }
6021
        opn = "sub.s";
6022
        optype = BINOP;
6023
        break;
6024
    case FOP(2, 16):
6025
        {
6026
            TCGv_i32 fp0 = tcg_temp_new_i32();
6027
            TCGv_i32 fp1 = tcg_temp_new_i32();
6028

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

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

    
6058
            gen_load_fpr32(fp0, fs);
6059
            gen_helper_float_sqrt_s(fp0, fp0);
6060
            gen_store_fpr32(fp0, fd);
6061
            tcg_temp_free_i32(fp0);
6062
        }
6063
        opn = "sqrt.s";
6064
        break;
6065
    case FOP(5, 16):
6066
        {
6067
            TCGv_i32 fp0 = tcg_temp_new_i32();
6068

    
6069
            gen_load_fpr32(fp0, fs);
6070
            gen_helper_float_abs_s(fp0, fp0);
6071
            gen_store_fpr32(fp0, fd);
6072
            tcg_temp_free_i32(fp0);
6073
        }
6074
        opn = "abs.s";
6075
        break;
6076
    case FOP(6, 16):
6077
        {
6078
            TCGv_i32 fp0 = tcg_temp_new_i32();
6079

    
6080
            gen_load_fpr32(fp0, fs);
6081
            gen_store_fpr32(fp0, fd);
6082
            tcg_temp_free_i32(fp0);
6083
        }
6084
        opn = "mov.s";
6085
        break;
6086
    case FOP(7, 16):
6087
        {
6088
            TCGv_i32 fp0 = tcg_temp_new_i32();
6089

    
6090
            gen_load_fpr32(fp0, fs);
6091
            gen_helper_float_chs_s(fp0, fp0);
6092
            gen_store_fpr32(fp0, fd);
6093
            tcg_temp_free_i32(fp0);
6094
        }
6095
        opn = "neg.s";
6096
        break;
6097
    case FOP(8, 16):
6098
        check_cp1_64bitmode(ctx);
6099
        {
6100
            TCGv_i32 fp32 = tcg_temp_new_i32();
6101
            TCGv_i64 fp64 = tcg_temp_new_i64();
6102

    
6103
            gen_load_fpr32(fp32, fs);
6104
            gen_helper_float_roundl_s(fp64, fp32);
6105
            tcg_temp_free_i32(fp32);
6106
            gen_store_fpr64(ctx, fp64, fd);
6107
            tcg_temp_free_i64(fp64);
6108
        }
6109
        opn = "round.l.s";
6110
        break;
6111
    case FOP(9, 16):
6112
        check_cp1_64bitmode(ctx);
6113
        {
6114
            TCGv_i32 fp32 = tcg_temp_new_i32();
6115
            TCGv_i64 fp64 = tcg_temp_new_i64();
6116

    
6117
            gen_load_fpr32(fp32, fs);
6118
            gen_helper_float_truncl_s(fp64, fp32);
6119
            tcg_temp_free_i32(fp32);
6120
            gen_store_fpr64(ctx, fp64, fd);
6121
            tcg_temp_free_i64(fp64);
6122
        }
6123
        opn = "trunc.l.s";
6124
        break;
6125
    case FOP(10, 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_ceill_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 = "ceil.l.s";
6138
        break;
6139
    case FOP(11, 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_floorl_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 = "floor.l.s";
6152
        break;
6153
    case FOP(12, 16):
6154
        {
6155
            TCGv_i32 fp0 = tcg_temp_new_i32();
6156

    
6157
            gen_load_fpr32(fp0, fs);
6158
            gen_helper_float_roundw_s(fp0, fp0);
6159
            gen_store_fpr32(fp0, fd);
6160
            tcg_temp_free_i32(fp0);
6161
        }
6162
        opn = "round.w.s";
6163
        break;
6164
    case FOP(13, 16):
6165
        {
6166
            TCGv_i32 fp0 = tcg_temp_new_i32();
6167

    
6168
            gen_load_fpr32(fp0, fs);
6169
            gen_helper_float_truncw_s(fp0, fp0);
6170
            gen_store_fpr32(fp0, fd);
6171
            tcg_temp_free_i32(fp0);
6172
        }
6173
        opn = "trunc.w.s";
6174
        break;
6175
    case FOP(14, 16):
6176
        {
6177
            TCGv_i32 fp0 = tcg_temp_new_i32();
6178

    
6179
            gen_load_fpr32(fp0, fs);
6180
            gen_helper_float_ceilw_s(fp0, fp0);
6181
            gen_store_fpr32(fp0, fd);
6182
            tcg_temp_free_i32(fp0);
6183
        }
6184
        opn = "ceil.w.s";
6185
        break;
6186
    case FOP(15, 16):
6187
        {
6188
            TCGv_i32 fp0 = tcg_temp_new_i32();
6189

    
6190
            gen_load_fpr32(fp0, fs);
6191
            gen_helper_float_floorw_s(fp0, fp0);
6192
            gen_store_fpr32(fp0, fd);
6193
            tcg_temp_free_i32(fp0);
6194
        }
6195
        opn = "floor.w.s";
6196
        break;
6197
    case FOP(17, 16):
6198
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6199
        opn = "movcf.s";
6200
        break;
6201
    case FOP(18, 16):
6202
        {
6203
            int l1 = gen_new_label();
6204
            TCGv_i32 fp0;
6205

    
6206
            if (ft != 0) {
6207
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6208
            }
6209
            fp0 = tcg_temp_new_i32();
6210
            gen_load_fpr32(fp0, fs);
6211
            gen_store_fpr32(fp0, fd);
6212
            tcg_temp_free_i32(fp0);
6213
            gen_set_label(l1);
6214
        }
6215
        opn = "movz.s";
6216
        break;
6217
    case FOP(19, 16):
6218
        {
6219
            int l1 = gen_new_label();
6220
            TCGv_i32 fp0;
6221

    
6222
            if (ft != 0) {
6223
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6224
                fp0 = tcg_temp_new_i32();
6225
                gen_load_fpr32(fp0, fs);
6226
                gen_store_fpr32(fp0, fd);
6227
                tcg_temp_free_i32(fp0);
6228
                gen_set_label(l1);
6229
            }
6230
        }
6231
        opn = "movn.s";
6232
        break;
6233
    case FOP(21, 16):
6234
        check_cop1x(ctx);
6235
        {
6236
            TCGv_i32 fp0 = tcg_temp_new_i32();
6237

    
6238
            gen_load_fpr32(fp0, fs);
6239
            gen_helper_float_recip_s(fp0, fp0);
6240
            gen_store_fpr32(fp0, fd);
6241
            tcg_temp_free_i32(fp0);
6242
        }
6243
        opn = "recip.s";
6244
        break;
6245
    case FOP(22, 16):
6246
        check_cop1x(ctx);
6247
        {
6248
            TCGv_i32 fp0 = tcg_temp_new_i32();
6249

    
6250
            gen_load_fpr32(fp0, fs);
6251
            gen_helper_float_rsqrt_s(fp0, fp0);
6252
            gen_store_fpr32(fp0, fd);
6253
            tcg_temp_free_i32(fp0);
6254
        }
6255
        opn = "rsqrt.s";
6256
        break;
6257
    case FOP(28, 16):
6258
        check_cp1_64bitmode(ctx);
6259
        {
6260
            TCGv_i32 fp0 = tcg_temp_new_i32();
6261
            TCGv_i32 fp1 = tcg_temp_new_i32();
6262

    
6263
            gen_load_fpr32(fp0, fs);
6264
            gen_load_fpr32(fp1, fd);
6265
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6266
            tcg_temp_free_i32(fp1);
6267
            gen_store_fpr32(fp0, fd);
6268
            tcg_temp_free_i32(fp0);
6269
        }
6270
        opn = "recip2.s";
6271
        break;
6272
    case FOP(29, 16):
6273
        check_cp1_64bitmode(ctx);
6274
        {
6275
            TCGv_i32 fp0 = tcg_temp_new_i32();
6276

    
6277
            gen_load_fpr32(fp0, fs);
6278
            gen_helper_float_recip1_s(fp0, fp0);
6279
            gen_store_fpr32(fp0, fd);
6280
            tcg_temp_free_i32(fp0);
6281
        }
6282
        opn = "recip1.s";
6283
        break;
6284
    case FOP(30, 16):
6285
        check_cp1_64bitmode(ctx);
6286
        {
6287
            TCGv_i32 fp0 = tcg_temp_new_i32();
6288

    
6289
            gen_load_fpr32(fp0, fs);
6290
            gen_helper_float_rsqrt1_s(fp0, fp0);
6291
            gen_store_fpr32(fp0, fd);
6292
            tcg_temp_free_i32(fp0);
6293
        }
6294
        opn = "rsqrt1.s";
6295
        break;
6296
    case FOP(31, 16):
6297
        check_cp1_64bitmode(ctx);
6298
        {
6299
            TCGv_i32 fp0 = tcg_temp_new_i32();
6300
            TCGv_i32 fp1 = tcg_temp_new_i32();
6301

    
6302
            gen_load_fpr32(fp0, fs);
6303
            gen_load_fpr32(fp1, ft);
6304
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6305
            tcg_temp_free_i32(fp1);
6306
            gen_store_fpr32(fp0, fd);
6307
            tcg_temp_free_i32(fp0);
6308
        }
6309
        opn = "rsqrt2.s";
6310
        break;
6311
    case FOP(33, 16):
6312
        check_cp1_registers(ctx, fd);
6313
        {
6314
            TCGv_i32 fp32 = tcg_temp_new_i32();
6315
            TCGv_i64 fp64 = tcg_temp_new_i64();
6316

    
6317
            gen_load_fpr32(fp32, fs);
6318
            gen_helper_float_cvtd_s(fp64, fp32);
6319
            tcg_temp_free_i32(fp32);
6320
            gen_store_fpr64(ctx, fp64, fd);
6321
            tcg_temp_free_i64(fp64);
6322
        }
6323
        opn = "cvt.d.s";
6324
        break;
6325
    case FOP(36, 16):
6326
        {
6327
            TCGv_i32 fp0 = tcg_temp_new_i32();
6328

    
6329
            gen_load_fpr32(fp0, fs);
6330
            gen_helper_float_cvtw_s(fp0, fp0);
6331
            gen_store_fpr32(fp0, fd);
6332
            tcg_temp_free_i32(fp0);
6333
        }
6334
        opn = "cvt.w.s";
6335
        break;
6336
    case FOP(37, 16):
6337
        check_cp1_64bitmode(ctx);
6338
        {
6339
            TCGv_i32 fp32 = tcg_temp_new_i32();
6340
            TCGv_i64 fp64 = tcg_temp_new_i64();
6341

    
6342
            gen_load_fpr32(fp32, fs);
6343
            gen_helper_float_cvtl_s(fp64, fp32);
6344
            tcg_temp_free_i32(fp32);
6345
            gen_store_fpr64(ctx, fp64, fd);
6346
            tcg_temp_free_i64(fp64);
6347
        }
6348
        opn = "cvt.l.s";
6349
        break;
6350
    case FOP(38, 16):
6351
        check_cp1_64bitmode(ctx);
6352
        {
6353
            TCGv_i64 fp64 = tcg_temp_new_i64();
6354
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6355
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6356

    
6357
            gen_load_fpr32(fp32_0, fs);
6358
            gen_load_fpr32(fp32_1, ft);
6359
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6360
            tcg_temp_free_i32(fp32_1);
6361
            tcg_temp_free_i32(fp32_0);
6362
            gen_store_fpr64(ctx, fp64, fd);
6363
            tcg_temp_free_i64(fp64);
6364
        }
6365
        opn = "cvt.ps.s";
6366
        break;
6367
    case FOP(48, 16):
6368
    case FOP(49, 16):
6369
    case FOP(50, 16):
6370
    case FOP(51, 16):
6371
    case FOP(52, 16):
6372
    case FOP(53, 16):
6373
    case FOP(54, 16):
6374
    case FOP(55, 16):
6375
    case FOP(56, 16):
6376
    case FOP(57, 16):
6377
    case FOP(58, 16):
6378
    case FOP(59, 16):
6379
    case FOP(60, 16):
6380
    case FOP(61, 16):
6381
    case FOP(62, 16):
6382
    case FOP(63, 16):
6383
        {
6384
            TCGv_i32 fp0 = tcg_temp_new_i32();
6385
            TCGv_i32 fp1 = tcg_temp_new_i32();
6386

    
6387
            gen_load_fpr32(fp0, fs);
6388
            gen_load_fpr32(fp1, ft);
6389
            if (ctx->opcode & (1 << 6)) {
6390
                check_cop1x(ctx);
6391
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6392
                opn = condnames_abs[func-48];
6393
            } else {
6394
                gen_cmp_s(func-48, fp0, fp1, cc);
6395
                opn = condnames[func-48];
6396
            }
6397
            tcg_temp_free_i32(fp0);
6398
            tcg_temp_free_i32(fp1);
6399
        }
6400
        break;
6401
    case FOP(0, 17):
6402
        check_cp1_registers(ctx, fs | ft | fd);
6403
        {
6404
            TCGv_i64 fp0 = tcg_temp_new_i64();
6405
            TCGv_i64 fp1 = tcg_temp_new_i64();
6406

    
6407
            gen_load_fpr64(ctx, fp0, fs);
6408
            gen_load_fpr64(ctx, fp1, ft);
6409
            gen_helper_float_add_d(fp0, fp0, fp1);
6410
            tcg_temp_free_i64(fp1);
6411
            gen_store_fpr64(ctx, fp0, fd);
6412
            tcg_temp_free_i64(fp0);
6413
        }
6414
        opn = "add.d";
6415
        optype = BINOP;
6416
        break;
6417
    case FOP(1, 17):
6418
        check_cp1_registers(ctx, fs | ft | fd);
6419
        {
6420
            TCGv_i64 fp0 = tcg_temp_new_i64();
6421
            TCGv_i64 fp1 = tcg_temp_new_i64();
6422

    
6423
            gen_load_fpr64(ctx, fp0, fs);
6424
            gen_load_fpr64(ctx, fp1, ft);
6425
            gen_helper_float_sub_d(fp0, fp0, fp1);
6426
            tcg_temp_free_i64(fp1);
6427
            gen_store_fpr64(ctx, fp0, fd);
6428
            tcg_temp_free_i64(fp0);
6429
        }
6430
        opn = "sub.d";
6431
        optype = BINOP;
6432
        break;
6433
    case FOP(2, 17):
6434
        check_cp1_registers(ctx, fs | ft | fd);
6435
        {
6436
            TCGv_i64 fp0 = tcg_temp_new_i64();
6437
            TCGv_i64 fp1 = tcg_temp_new_i64();
6438

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

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

    
6470
            gen_load_fpr64(ctx, fp0, fs);
6471
            gen_helper_float_sqrt_d(fp0, fp0);
6472
            gen_store_fpr64(ctx, fp0, fd);
6473
            tcg_temp_free_i64(fp0);
6474
        }
6475
        opn = "sqrt.d";
6476
        break;
6477
    case FOP(5, 17):
6478
        check_cp1_registers(ctx, fs | fd);
6479
        {
6480
            TCGv_i64 fp0 = tcg_temp_new_i64();
6481

    
6482
            gen_load_fpr64(ctx, fp0, fs);
6483
            gen_helper_float_abs_d(fp0, fp0);
6484
            gen_store_fpr64(ctx, fp0, fd);
6485
            tcg_temp_free_i64(fp0);
6486
        }
6487
        opn = "abs.d";
6488
        break;
6489
    case FOP(6, 17):
6490
        check_cp1_registers(ctx, fs | fd);
6491
        {
6492
            TCGv_i64 fp0 = tcg_temp_new_i64();
6493

    
6494
            gen_load_fpr64(ctx, fp0, fs);
6495
            gen_store_fpr64(ctx, fp0, fd);
6496
            tcg_temp_free_i64(fp0);
6497
        }
6498
        opn = "mov.d";
6499
        break;
6500
    case FOP(7, 17):
6501
        check_cp1_registers(ctx, fs | fd);
6502
        {
6503
            TCGv_i64 fp0 = tcg_temp_new_i64();
6504

    
6505
            gen_load_fpr64(ctx, fp0, fs);
6506
            gen_helper_float_chs_d(fp0, fp0);
6507
            gen_store_fpr64(ctx, fp0, fd);
6508
            tcg_temp_free_i64(fp0);
6509
        }
6510
        opn = "neg.d";
6511
        break;
6512
    case FOP(8, 17):
6513
        check_cp1_64bitmode(ctx);
6514
        {
6515
            TCGv_i64 fp0 = tcg_temp_new_i64();
6516

    
6517
            gen_load_fpr64(ctx, fp0, fs);
6518
            gen_helper_float_roundl_d(fp0, fp0);
6519
            gen_store_fpr64(ctx, fp0, fd);
6520
            tcg_temp_free_i64(fp0);
6521
        }
6522
        opn = "round.l.d";
6523
        break;
6524
    case FOP(9, 17):
6525
        check_cp1_64bitmode(ctx);
6526
        {
6527
            TCGv_i64 fp0 = tcg_temp_new_i64();
6528

    
6529
            gen_load_fpr64(ctx, fp0, fs);
6530
            gen_helper_float_truncl_d(fp0, fp0);
6531
            gen_store_fpr64(ctx, fp0, fd);
6532
            tcg_temp_free_i64(fp0);
6533
        }
6534
        opn = "trunc.l.d";
6535
        break;
6536
    case FOP(10, 17):
6537
        check_cp1_64bitmode(ctx);
6538
        {
6539
            TCGv_i64 fp0 = tcg_temp_new_i64();
6540

    
6541
            gen_load_fpr64(ctx, fp0, fs);
6542
            gen_helper_float_ceill_d(fp0, fp0);
6543
            gen_store_fpr64(ctx, fp0, fd);
6544
            tcg_temp_free_i64(fp0);
6545
        }
6546
        opn = "ceil.l.d";
6547
        break;
6548
    case FOP(11, 17):
6549
        check_cp1_64bitmode(ctx);
6550
        {
6551
            TCGv_i64 fp0 = tcg_temp_new_i64();
6552

    
6553
            gen_load_fpr64(ctx, fp0, fs);
6554
            gen_helper_float_floorl_d(fp0, fp0);
6555
            gen_store_fpr64(ctx, fp0, fd);
6556
            tcg_temp_free_i64(fp0);
6557
        }
6558
        opn = "floor.l.d";
6559
        break;
6560
    case FOP(12, 17):
6561
        check_cp1_registers(ctx, fs);
6562
        {
6563
            TCGv_i32 fp32 = tcg_temp_new_i32();
6564
            TCGv_i64 fp64 = tcg_temp_new_i64();
6565

    
6566
            gen_load_fpr64(ctx, fp64, fs);
6567
            gen_helper_float_roundw_d(fp32, fp64);
6568
            tcg_temp_free_i64(fp64);
6569
            gen_store_fpr32(fp32, fd);
6570
            tcg_temp_free_i32(fp32);
6571
        }
6572
        opn = "round.w.d";
6573
        break;
6574
    case FOP(13, 17):
6575
        check_cp1_registers(ctx, fs);
6576
        {
6577
            TCGv_i32 fp32 = tcg_temp_new_i32();
6578
            TCGv_i64 fp64 = tcg_temp_new_i64();
6579

    
6580
            gen_load_fpr64(ctx, fp64, fs);
6581
            gen_helper_float_truncw_d(fp32, fp64);
6582
            tcg_temp_free_i64(fp64);
6583
            gen_store_fpr32(fp32, fd);
6584
            tcg_temp_free_i32(fp32);
6585
        }
6586
        opn = "trunc.w.d";
6587
        break;
6588
    case FOP(14, 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_ceilw_d(fp32, fp64);
6596
            tcg_temp_free_i64(fp64);
6597
            gen_store_fpr32(fp32, fd);
6598
            tcg_temp_free_i32(fp32);
6599
        }
6600
        opn = "ceil.w.d";
6601
        break;
6602
    case FOP(15, 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_floorw_d(fp32, fp64);
6610
            tcg_temp_free_i64(fp64);
6611
            gen_store_fpr32(fp32, fd);
6612
            tcg_temp_free_i32(fp32);
6613
        }
6614
        opn = "floor.w.d";
6615
        break;
6616
    case FOP(17, 17):
6617
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6618
        opn = "movcf.d";
6619
        break;
6620
    case FOP(18, 17):
6621
        {
6622
            int l1 = gen_new_label();
6623
            TCGv_i64 fp0;
6624

    
6625
            if (ft != 0) {
6626
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6627
            }
6628
            fp0 = tcg_temp_new_i64();
6629
            gen_load_fpr64(ctx, fp0, fs);
6630
            gen_store_fpr64(ctx, fp0, fd);
6631
            tcg_temp_free_i64(fp0);
6632
            gen_set_label(l1);
6633
        }
6634
        opn = "movz.d";
6635
        break;
6636
    case FOP(19, 17):
6637
        {
6638
            int l1 = gen_new_label();
6639
            TCGv_i64 fp0;
6640

    
6641
            if (ft != 0) {
6642
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6643
                fp0 = tcg_temp_new_i64();
6644
                gen_load_fpr64(ctx, fp0, fs);
6645
                gen_store_fpr64(ctx, fp0, fd);
6646
                tcg_temp_free_i64(fp0);
6647
                gen_set_label(l1);
6648
            }
6649
        }
6650
        opn = "movn.d";
6651
        break;
6652
    case FOP(21, 17):
6653
        check_cp1_64bitmode(ctx);
6654
        {
6655
            TCGv_i64 fp0 = tcg_temp_new_i64();
6656

    
6657
            gen_load_fpr64(ctx, fp0, fs);
6658
            gen_helper_float_recip_d(fp0, fp0);
6659
            gen_store_fpr64(ctx, fp0, fd);
6660
            tcg_temp_free_i64(fp0);
6661
        }
6662
        opn = "recip.d";
6663
        break;
6664
    case FOP(22, 17):
6665
        check_cp1_64bitmode(ctx);
6666
        {
6667
            TCGv_i64 fp0 = tcg_temp_new_i64();
6668

    
6669
            gen_load_fpr64(ctx, fp0, fs);
6670
            gen_helper_float_rsqrt_d(fp0, fp0);
6671
            gen_store_fpr64(ctx, fp0, fd);
6672
            tcg_temp_free_i64(fp0);
6673
        }
6674
        opn = "rsqrt.d";
6675
        break;
6676
    case FOP(28, 17):
6677
        check_cp1_64bitmode(ctx);
6678
        {
6679
            TCGv_i64 fp0 = tcg_temp_new_i64();
6680
            TCGv_i64 fp1 = tcg_temp_new_i64();
6681

    
6682
            gen_load_fpr64(ctx, fp0, fs);
6683
            gen_load_fpr64(ctx, fp1, ft);
6684
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6685
            tcg_temp_free_i64(fp1);
6686
            gen_store_fpr64(ctx, fp0, fd);
6687
            tcg_temp_free_i64(fp0);
6688
        }
6689
        opn = "recip2.d";
6690
        break;
6691
    case FOP(29, 17):
6692
        check_cp1_64bitmode(ctx);
6693
        {
6694
            TCGv_i64 fp0 = tcg_temp_new_i64();
6695

    
6696
            gen_load_fpr64(ctx, fp0, fs);
6697
            gen_helper_float_recip1_d(fp0, fp0);
6698
            gen_store_fpr64(ctx, fp0, fd);
6699
            tcg_temp_free_i64(fp0);
6700
        }
6701
        opn = "recip1.d";
6702
        break;
6703
    case FOP(30, 17):
6704
        check_cp1_64bitmode(ctx);
6705
        {
6706
            TCGv_i64 fp0 = tcg_temp_new_i64();
6707

    
6708
            gen_load_fpr64(ctx, fp0, fs);
6709
            gen_helper_float_rsqrt1_d(fp0, fp0);
6710
            gen_store_fpr64(ctx, fp0, fd);
6711
            tcg_temp_free_i64(fp0);
6712
        }
6713
        opn = "rsqrt1.d";
6714
        break;
6715
    case FOP(31, 17):
6716
        check_cp1_64bitmode(ctx);
6717
        {
6718
            TCGv_i64 fp0 = tcg_temp_new_i64();
6719
            TCGv_i64 fp1 = tcg_temp_new_i64();
6720

    
6721
            gen_load_fpr64(ctx, fp0, fs);
6722
            gen_load_fpr64(ctx, fp1, ft);
6723
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6724
            tcg_temp_free_i64(fp1);
6725
            gen_store_fpr64(ctx, fp0, fd);
6726
            tcg_temp_free_i64(fp0);
6727
        }
6728
        opn = "rsqrt2.d";
6729
        break;
6730
    case FOP(48, 17):
6731
    case FOP(49, 17):
6732
    case FOP(50, 17):
6733
    case FOP(51, 17):
6734
    case FOP(52, 17):
6735
    case FOP(53, 17):
6736
    case FOP(54, 17):
6737
    case FOP(55, 17):
6738
    case FOP(56, 17):
6739
    case FOP(57, 17):
6740
    case FOP(58, 17):
6741
    case FOP(59, 17):
6742
    case FOP(60, 17):
6743
    case FOP(61, 17):
6744
    case FOP(62, 17):
6745
    case FOP(63, 17):
6746
        {
6747
            TCGv_i64 fp0 = tcg_temp_new_i64();
6748
            TCGv_i64 fp1 = tcg_temp_new_i64();
6749

    
6750
            gen_load_fpr64(ctx, fp0, fs);
6751
            gen_load_fpr64(ctx, fp1, ft);
6752
            if (ctx->opcode & (1 << 6)) {
6753
                check_cop1x(ctx);
6754
                check_cp1_registers(ctx, fs | ft);
6755
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6756
                opn = condnames_abs[func-48];
6757
            } else {
6758
                check_cp1_registers(ctx, fs | ft);
6759
                gen_cmp_d(func-48, fp0, fp1, cc);
6760
                opn = condnames[func-48];
6761
            }
6762
            tcg_temp_free_i64(fp0);
6763
            tcg_temp_free_i64(fp1);
6764
        }
6765
        break;
6766
    case FOP(32, 17):
6767
        check_cp1_registers(ctx, fs);
6768
        {
6769
            TCGv_i32 fp32 = tcg_temp_new_i32();
6770
            TCGv_i64 fp64 = tcg_temp_new_i64();
6771

    
6772
            gen_load_fpr64(ctx, fp64, fs);
6773
            gen_helper_float_cvts_d(fp32, fp64);
6774
            tcg_temp_free_i64(fp64);
6775
            gen_store_fpr32(fp32, fd);
6776
            tcg_temp_free_i32(fp32);
6777
        }
6778
        opn = "cvt.s.d";
6779
        break;
6780
    case FOP(36, 17):
6781
        check_cp1_registers(ctx, fs);
6782
        {
6783
            TCGv_i32 fp32 = tcg_temp_new_i32();
6784
            TCGv_i64 fp64 = tcg_temp_new_i64();
6785

    
6786
            gen_load_fpr64(ctx, fp64, fs);
6787
            gen_helper_float_cvtw_d(fp32, fp64);
6788
            tcg_temp_free_i64(fp64);
6789
            gen_store_fpr32(fp32, fd);
6790
            tcg_temp_free_i32(fp32);
6791
        }
6792
        opn = "cvt.w.d";
6793
        break;
6794
    case FOP(37, 17):
6795
        check_cp1_64bitmode(ctx);
6796
        {
6797
            TCGv_i64 fp0 = tcg_temp_new_i64();
6798

    
6799
            gen_load_fpr64(ctx, fp0, fs);
6800
            gen_helper_float_cvtl_d(fp0, fp0);
6801
            gen_store_fpr64(ctx, fp0, fd);
6802
            tcg_temp_free_i64(fp0);
6803
        }
6804
        opn = "cvt.l.d";
6805
        break;
6806
    case FOP(32, 20):
6807
        {
6808
            TCGv_i32 fp0 = tcg_temp_new_i32();
6809

    
6810
            gen_load_fpr32(fp0, fs);
6811
            gen_helper_float_cvts_w(fp0, fp0);
6812
            gen_store_fpr32(fp0, fd);
6813
            tcg_temp_free_i32(fp0);
6814
        }
6815
        opn = "cvt.s.w";
6816
        break;
6817
    case FOP(33, 20):
6818
        check_cp1_registers(ctx, fd);
6819
        {
6820
            TCGv_i32 fp32 = tcg_temp_new_i32();
6821
            TCGv_i64 fp64 = tcg_temp_new_i64();
6822

    
6823
            gen_load_fpr32(fp32, fs);
6824
            gen_helper_float_cvtd_w(fp64, fp32);
6825
            tcg_temp_free_i32(fp32);
6826
            gen_store_fpr64(ctx, fp64, fd);
6827
            tcg_temp_free_i64(fp64);
6828
        }
6829
        opn = "cvt.d.w";
6830
        break;
6831
    case FOP(32, 21):
6832
        check_cp1_64bitmode(ctx);
6833
        {
6834
            TCGv_i32 fp32 = tcg_temp_new_i32();
6835
            TCGv_i64 fp64 = tcg_temp_new_i64();
6836

    
6837
            gen_load_fpr64(ctx, fp64, fs);
6838
            gen_helper_float_cvts_l(fp32, fp64);
6839
            tcg_temp_free_i64(fp64);
6840
            gen_store_fpr32(fp32, fd);
6841
            tcg_temp_free_i32(fp32);
6842
        }
6843
        opn = "cvt.s.l";
6844
        break;
6845
    case FOP(33, 21):
6846
        check_cp1_64bitmode(ctx);
6847
        {
6848
            TCGv_i64 fp0 = tcg_temp_new_i64();
6849

    
6850
            gen_load_fpr64(ctx, fp0, fs);
6851
            gen_helper_float_cvtd_l(fp0, fp0);
6852
            gen_store_fpr64(ctx, fp0, fd);
6853
            tcg_temp_free_i64(fp0);
6854
        }
6855
        opn = "cvt.d.l";
6856
        break;
6857
    case FOP(38, 20):
6858
        check_cp1_64bitmode(ctx);
6859
        {
6860
            TCGv_i64 fp0 = tcg_temp_new_i64();
6861

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

    
6875
            gen_load_fpr64(ctx, fp0, fs);
6876
            gen_load_fpr64(ctx, fp1, ft);
6877
            gen_helper_float_add_ps(fp0, fp0, fp1);
6878
            tcg_temp_free_i64(fp1);
6879
            gen_store_fpr64(ctx, fp0, fd);
6880
            tcg_temp_free_i64(fp0);
6881
        }
6882
        opn = "add.ps";
6883
        break;
6884
    case FOP(1, 22):
6885
        check_cp1_64bitmode(ctx);
6886
        {
6887
            TCGv_i64 fp0 = tcg_temp_new_i64();
6888
            TCGv_i64 fp1 = tcg_temp_new_i64();
6889

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

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

    
6919
            gen_load_fpr64(ctx, fp0, fs);
6920
            gen_helper_float_abs_ps(fp0, fp0);
6921
            gen_store_fpr64(ctx, fp0, fd);
6922
            tcg_temp_free_i64(fp0);
6923
        }
6924
        opn = "abs.ps";
6925
        break;
6926
    case FOP(6, 22):
6927
        check_cp1_64bitmode(ctx);
6928
        {
6929
            TCGv_i64 fp0 = tcg_temp_new_i64();
6930

    
6931
            gen_load_fpr64(ctx, fp0, fs);
6932
            gen_store_fpr64(ctx, fp0, fd);
6933
            tcg_temp_free_i64(fp0);
6934
        }
6935
        opn = "mov.ps";
6936
        break;
6937
    case FOP(7, 22):
6938
        check_cp1_64bitmode(ctx);
6939
        {
6940
            TCGv_i64 fp0 = tcg_temp_new_i64();
6941

    
6942
            gen_load_fpr64(ctx, fp0, fs);
6943
            gen_helper_float_chs_ps(fp0, fp0);
6944
            gen_store_fpr64(ctx, fp0, fd);
6945
            tcg_temp_free_i64(fp0);
6946
        }
6947
        opn = "neg.ps";
6948
        break;
6949
    case FOP(17, 22):
6950
        check_cp1_64bitmode(ctx);
6951
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6952
        opn = "movcf.ps";
6953
        break;
6954
    case FOP(18, 22):
6955
        check_cp1_64bitmode(ctx);
6956
        {
6957
            int l1 = gen_new_label();
6958
            TCGv_i64 fp0;
6959

    
6960
            if (ft != 0)
6961
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6962
            fp0 = tcg_temp_new_i64();
6963
            gen_load_fpr64(ctx, fp0, fs);
6964
            gen_store_fpr64(ctx, fp0, fd);
6965
            tcg_temp_free_i64(fp0);
6966
            gen_set_label(l1);
6967
        }
6968
        opn = "movz.ps";
6969
        break;
6970
    case FOP(19, 22):
6971
        check_cp1_64bitmode(ctx);
6972
        {
6973
            int l1 = gen_new_label();
6974
            TCGv_i64 fp0;
6975

    
6976
            if (ft != 0) {
6977
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6978
                fp0 = tcg_temp_new_i64();
6979
                gen_load_fpr64(ctx, fp0, fs);
6980
                gen_store_fpr64(ctx, fp0, fd);
6981
                tcg_temp_free_i64(fp0);
6982
                gen_set_label(l1);
6983
            }
6984
        }
6985
        opn = "movn.ps";
6986
        break;
6987
    case FOP(24, 22):
6988
        check_cp1_64bitmode(ctx);
6989
        {
6990
            TCGv_i64 fp0 = tcg_temp_new_i64();
6991
            TCGv_i64 fp1 = tcg_temp_new_i64();
6992

    
6993
            gen_load_fpr64(ctx, fp0, ft);
6994
            gen_load_fpr64(ctx, fp1, fs);
6995
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6996
            tcg_temp_free_i64(fp1);
6997
            gen_store_fpr64(ctx, fp0, fd);
6998
            tcg_temp_free_i64(fp0);
6999
        }
7000
        opn = "addr.ps";
7001
        break;
7002
    case FOP(26, 22):
7003
        check_cp1_64bitmode(ctx);
7004
        {
7005
            TCGv_i64 fp0 = tcg_temp_new_i64();
7006
            TCGv_i64 fp1 = tcg_temp_new_i64();
7007

    
7008
            gen_load_fpr64(ctx, fp0, ft);
7009
            gen_load_fpr64(ctx, fp1, fs);
7010
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7011
            tcg_temp_free_i64(fp1);
7012
            gen_store_fpr64(ctx, fp0, fd);
7013
            tcg_temp_free_i64(fp0);
7014
        }
7015
        opn = "mulr.ps";
7016
        break;
7017
    case FOP(28, 22):
7018
        check_cp1_64bitmode(ctx);
7019
        {
7020
            TCGv_i64 fp0 = tcg_temp_new_i64();
7021
            TCGv_i64 fp1 = tcg_temp_new_i64();
7022

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

    
7037
            gen_load_fpr64(ctx, fp0, fs);
7038
            gen_helper_float_recip1_ps(fp0, fp0);
7039
            gen_store_fpr64(ctx, fp0, fd);
7040
            tcg_temp_free_i64(fp0);
7041
        }
7042
        opn = "recip1.ps";
7043
        break;
7044
    case FOP(30, 22):
7045
        check_cp1_64bitmode(ctx);
7046
        {
7047
            TCGv_i64 fp0 = tcg_temp_new_i64();
7048

    
7049
            gen_load_fpr64(ctx, fp0, fs);
7050
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7051
            gen_store_fpr64(ctx, fp0, fd);
7052
            tcg_temp_free_i64(fp0);
7053
        }
7054
        opn = "rsqrt1.ps";
7055
        break;
7056
    case FOP(31, 22):
7057
        check_cp1_64bitmode(ctx);
7058
        {
7059
            TCGv_i64 fp0 = tcg_temp_new_i64();
7060
            TCGv_i64 fp1 = tcg_temp_new_i64();
7061

    
7062
            gen_load_fpr64(ctx, fp0, fs);
7063
            gen_load_fpr64(ctx, fp1, ft);
7064
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7065
            tcg_temp_free_i64(fp1);
7066
            gen_store_fpr64(ctx, fp0, fd);
7067
            tcg_temp_free_i64(fp0);
7068
        }
7069
        opn = "rsqrt2.ps";
7070
        break;
7071
    case FOP(32, 22):
7072
        check_cp1_64bitmode(ctx);
7073
        {
7074
            TCGv_i32 fp0 = tcg_temp_new_i32();
7075

    
7076
            gen_load_fpr32h(fp0, fs);
7077
            gen_helper_float_cvts_pu(fp0, fp0);
7078
            gen_store_fpr32(fp0, fd);
7079
            tcg_temp_free_i32(fp0);
7080
        }
7081
        opn = "cvt.s.pu";
7082
        break;
7083
    case FOP(36, 22):
7084
        check_cp1_64bitmode(ctx);
7085
        {
7086
            TCGv_i64 fp0 = tcg_temp_new_i64();
7087

    
7088
            gen_load_fpr64(ctx, fp0, fs);
7089
            gen_helper_float_cvtpw_ps(fp0, fp0);
7090
            gen_store_fpr64(ctx, fp0, fd);
7091
            tcg_temp_free_i64(fp0);
7092
        }
7093
        opn = "cvt.pw.ps";
7094
        break;
7095
    case FOP(40, 22):
7096
        check_cp1_64bitmode(ctx);
7097
        {
7098
            TCGv_i32 fp0 = tcg_temp_new_i32();
7099

    
7100
            gen_load_fpr32(fp0, fs);
7101
            gen_helper_float_cvts_pl(fp0, fp0);
7102
            gen_store_fpr32(fp0, fd);
7103
            tcg_temp_free_i32(fp0);
7104
        }
7105
        opn = "cvt.s.pl";
7106
        break;
7107
    case FOP(44, 22):
7108
        check_cp1_64bitmode(ctx);
7109
        {
7110
            TCGv_i32 fp0 = tcg_temp_new_i32();
7111
            TCGv_i32 fp1 = tcg_temp_new_i32();
7112

    
7113
            gen_load_fpr32(fp0, fs);
7114
            gen_load_fpr32(fp1, ft);
7115
            gen_store_fpr32h(fp0, fd);
7116
            gen_store_fpr32(fp1, fd);
7117
            tcg_temp_free_i32(fp0);
7118
            tcg_temp_free_i32(fp1);
7119
        }
7120
        opn = "pll.ps";
7121
        break;
7122
    case FOP(45, 22):
7123
        check_cp1_64bitmode(ctx);
7124
        {
7125
            TCGv_i32 fp0 = tcg_temp_new_i32();
7126
            TCGv_i32 fp1 = tcg_temp_new_i32();
7127

    
7128
            gen_load_fpr32(fp0, fs);
7129
            gen_load_fpr32h(fp1, ft);
7130
            gen_store_fpr32(fp1, fd);
7131
            gen_store_fpr32h(fp0, fd);
7132
            tcg_temp_free_i32(fp0);
7133
            tcg_temp_free_i32(fp1);
7134
        }
7135
        opn = "plu.ps";
7136
        break;
7137
    case FOP(46, 22):
7138
        check_cp1_64bitmode(ctx);
7139
        {
7140
            TCGv_i32 fp0 = tcg_temp_new_i32();
7141
            TCGv_i32 fp1 = tcg_temp_new_i32();
7142

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

    
7158
            gen_load_fpr32h(fp0, fs);
7159
            gen_load_fpr32h(fp1, ft);
7160
            gen_store_fpr32(fp1, fd);
7161
            gen_store_fpr32h(fp0, fd);
7162
            tcg_temp_free_i32(fp0);
7163
            tcg_temp_free_i32(fp1);
7164
        }
7165
        opn = "puu.ps";
7166
        break;
7167
    case FOP(48, 22):
7168
    case FOP(49, 22):
7169
    case FOP(50, 22):
7170
    case FOP(51, 22):
7171
    case FOP(52, 22):
7172
    case FOP(53, 22):
7173
    case FOP(54, 22):
7174
    case FOP(55, 22):
7175
    case FOP(56, 22):
7176
    case FOP(57, 22):
7177
    case FOP(58, 22):
7178
    case FOP(59, 22):
7179
    case FOP(60, 22):
7180
    case FOP(61, 22):
7181
    case FOP(62, 22):
7182
    case FOP(63, 22):
7183
        check_cp1_64bitmode(ctx);
7184
        {
7185
            TCGv_i64 fp0 = tcg_temp_new_i64();
7186
            TCGv_i64 fp1 = tcg_temp_new_i64();
7187

    
7188
            gen_load_fpr64(ctx, fp0, fs);
7189
            gen_load_fpr64(ctx, fp1, ft);
7190
            if (ctx->opcode & (1 << 6)) {
7191
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7192
                opn = condnames_abs[func-48];
7193
            } else {
7194
                gen_cmp_ps(func-48, fp0, fp1, cc);
7195
                opn = condnames[func-48];
7196
            }
7197
            tcg_temp_free_i64(fp0);
7198
            tcg_temp_free_i64(fp1);
7199
        }
7200
        break;
7201
    default:
7202
        MIPS_INVAL(opn);
7203
        generate_exception (ctx, EXCP_RI);
7204
        return;
7205
    }
7206
    switch (optype) {
7207
    case BINOP:
7208
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7209
        break;
7210
    case CMPOP:
7211
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7212
        break;
7213
    default:
7214
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7215
        break;
7216
    }
7217
}
7218

    
7219
/* Coprocessor 3 (FPU) */
7220
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7221
                           int fd, int fs, int base, int index)
7222
{
7223
    const char *opn = "extended float load/store";
7224
    int store = 0;
7225
    TCGv t0 = tcg_temp_new();
7226
    TCGv t1 = tcg_temp_new();
7227

    
7228
    if (base == 0) {
7229
        gen_load_gpr(t0, index);
7230
    } else if (index == 0) {
7231
        gen_load_gpr(t0, base);
7232
    } else {
7233
        gen_load_gpr(t0, index);
7234
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7235
    }
7236
    /* Don't do NOP if destination is zero: we must perform the actual
7237
       memory access. */
7238
    save_cpu_state(ctx, 0);
7239
    switch (opc) {
7240
    case OPC_LWXC1:
7241
        check_cop1x(ctx);
7242
        {
7243
            TCGv_i32 fp0 = tcg_temp_new_i32();
7244

    
7245
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7246
            tcg_gen_trunc_tl_i32(fp0, t1);
7247
            gen_store_fpr32(fp0, fd);
7248
            tcg_temp_free_i32(fp0);
7249
        }
7250
        opn = "lwxc1";
7251
        break;
7252
    case OPC_LDXC1:
7253
        check_cop1x(ctx);
7254
        check_cp1_registers(ctx, fd);
7255
        {
7256
            TCGv_i64 fp0 = tcg_temp_new_i64();
7257

    
7258
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7259
            gen_store_fpr64(ctx, fp0, fd);
7260
            tcg_temp_free_i64(fp0);
7261
        }
7262
        opn = "ldxc1";
7263
        break;
7264
    case OPC_LUXC1:
7265
        check_cp1_64bitmode(ctx);
7266
        tcg_gen_andi_tl(t0, t0, ~0x7);
7267
        {
7268
            TCGv_i64 fp0 = tcg_temp_new_i64();
7269

    
7270
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7271
            gen_store_fpr64(ctx, fp0, fd);
7272
            tcg_temp_free_i64(fp0);
7273
        }
7274
        opn = "luxc1";
7275
        break;
7276
    case OPC_SWXC1:
7277
        check_cop1x(ctx);
7278
        {
7279
            TCGv_i32 fp0 = tcg_temp_new_i32();
7280

    
7281
            gen_load_fpr32(fp0, fs);
7282
            tcg_gen_extu_i32_tl(t1, fp0);
7283
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7284
            tcg_temp_free_i32(fp0);
7285
        }
7286
        opn = "swxc1";
7287
        store = 1;
7288
        break;
7289
    case OPC_SDXC1:
7290
        check_cop1x(ctx);
7291
        check_cp1_registers(ctx, fs);
7292
        {
7293
            TCGv_i64 fp0 = tcg_temp_new_i64();
7294

    
7295
            gen_load_fpr64(ctx, fp0, fs);
7296
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7297
            tcg_temp_free_i64(fp0);
7298
        }
7299
        opn = "sdxc1";
7300
        store = 1;
7301
        break;
7302
    case OPC_SUXC1:
7303
        check_cp1_64bitmode(ctx);
7304
        tcg_gen_andi_tl(t0, t0, ~0x7);
7305
        {
7306
            TCGv_i64 fp0 = tcg_temp_new_i64();
7307

    
7308
            gen_load_fpr64(ctx, fp0, fs);
7309
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7310
            tcg_temp_free_i64(fp0);
7311
        }
7312
        opn = "suxc1";
7313
        store = 1;
7314
        break;
7315
    }
7316
    tcg_temp_free(t0);
7317
    tcg_temp_free(t1);
7318
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7319
               regnames[index], regnames[base]);
7320
}
7321

    
7322
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7323
                            int fd, int fr, int fs, int ft)
7324
{
7325
    const char *opn = "flt3_arith";
7326

    
7327
    switch (opc) {
7328
    case OPC_ALNV_PS:
7329
        check_cp1_64bitmode(ctx);
7330
        {
7331
            TCGv t0 = tcg_temp_local_new();
7332
            TCGv_i32 fp = tcg_temp_new_i32();
7333
            TCGv_i32 fph = tcg_temp_new_i32();
7334
            int l1 = gen_new_label();
7335
            int l2 = gen_new_label();
7336

    
7337
            gen_load_gpr(t0, fr);
7338
            tcg_gen_andi_tl(t0, t0, 0x7);
7339

    
7340
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7341
            gen_load_fpr32(fp, fs);
7342
            gen_load_fpr32h(fph, fs);
7343
            gen_store_fpr32(fp, fd);
7344
            gen_store_fpr32h(fph, fd);
7345
            tcg_gen_br(l2);
7346
            gen_set_label(l1);
7347
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7348
            tcg_temp_free(t0);
7349
#ifdef TARGET_WORDS_BIGENDIAN
7350
            gen_load_fpr32(fp, fs);
7351
            gen_load_fpr32h(fph, ft);
7352
            gen_store_fpr32h(fp, fd);
7353
            gen_store_fpr32(fph, fd);
7354
#else
7355
            gen_load_fpr32h(fph, fs);
7356
            gen_load_fpr32(fp, ft);
7357
            gen_store_fpr32(fph, fd);
7358
            gen_store_fpr32h(fp, fd);
7359
#endif
7360
            gen_set_label(l2);
7361
            tcg_temp_free_i32(fp);
7362
            tcg_temp_free_i32(fph);
7363
        }
7364
        opn = "alnv.ps";
7365
        break;
7366
    case OPC_MADD_S:
7367
        check_cop1x(ctx);
7368
        {
7369
            TCGv_i32 fp0 = tcg_temp_new_i32();
7370
            TCGv_i32 fp1 = tcg_temp_new_i32();
7371
            TCGv_i32 fp2 = tcg_temp_new_i32();
7372

    
7373
            gen_load_fpr32(fp0, fs);
7374
            gen_load_fpr32(fp1, ft);
7375
            gen_load_fpr32(fp2, fr);
7376
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7377
            tcg_temp_free_i32(fp0);
7378
            tcg_temp_free_i32(fp1);
7379
            gen_store_fpr32(fp2, fd);
7380
            tcg_temp_free_i32(fp2);
7381
        }
7382
        opn = "madd.s";
7383
        break;
7384
    case OPC_MADD_D:
7385
        check_cop1x(ctx);
7386
        check_cp1_registers(ctx, fd | fs | ft | fr);
7387
        {
7388
            TCGv_i64 fp0 = tcg_temp_new_i64();
7389
            TCGv_i64 fp1 = tcg_temp_new_i64();
7390
            TCGv_i64 fp2 = tcg_temp_new_i64();
7391

    
7392
            gen_load_fpr64(ctx, fp0, fs);
7393
            gen_load_fpr64(ctx, fp1, ft);
7394
            gen_load_fpr64(ctx, fp2, fr);
7395
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7396
            tcg_temp_free_i64(fp0);
7397
            tcg_temp_free_i64(fp1);
7398
            gen_store_fpr64(ctx, fp2, fd);
7399
            tcg_temp_free_i64(fp2);
7400
        }
7401
        opn = "madd.d";
7402
        break;
7403
    case OPC_MADD_PS:
7404
        check_cp1_64bitmode(ctx);
7405
        {
7406
            TCGv_i64 fp0 = tcg_temp_new_i64();
7407
            TCGv_i64 fp1 = tcg_temp_new_i64();
7408
            TCGv_i64 fp2 = tcg_temp_new_i64();
7409

    
7410
            gen_load_fpr64(ctx, fp0, fs);
7411
            gen_load_fpr64(ctx, fp1, ft);
7412
            gen_load_fpr64(ctx, fp2, fr);
7413
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7414
            tcg_temp_free_i64(fp0);
7415
            tcg_temp_free_i64(fp1);
7416
            gen_store_fpr64(ctx, fp2, fd);
7417
            tcg_temp_free_i64(fp2);
7418
        }
7419
        opn = "madd.ps";
7420
        break;
7421
    case OPC_MSUB_S:
7422
        check_cop1x(ctx);
7423
        {
7424
            TCGv_i32 fp0 = tcg_temp_new_i32();
7425
            TCGv_i32 fp1 = tcg_temp_new_i32();
7426
            TCGv_i32 fp2 = tcg_temp_new_i32();
7427

    
7428
            gen_load_fpr32(fp0, fs);
7429
            gen_load_fpr32(fp1, ft);
7430
            gen_load_fpr32(fp2, fr);
7431
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7432
            tcg_temp_free_i32(fp0);
7433
            tcg_temp_free_i32(fp1);
7434
            gen_store_fpr32(fp2, fd);
7435
            tcg_temp_free_i32(fp2);
7436
        }
7437
        opn = "msub.s";
7438
        break;
7439
    case OPC_MSUB_D:
7440
        check_cop1x(ctx);
7441
        check_cp1_registers(ctx, fd | fs | ft | fr);
7442
        {
7443
            TCGv_i64 fp0 = tcg_temp_new_i64();
7444
            TCGv_i64 fp1 = tcg_temp_new_i64();
7445
            TCGv_i64 fp2 = tcg_temp_new_i64();
7446

    
7447
            gen_load_fpr64(ctx, fp0, fs);
7448
            gen_load_fpr64(ctx, fp1, ft);
7449
            gen_load_fpr64(ctx, fp2, fr);
7450
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7451
            tcg_temp_free_i64(fp0);
7452
            tcg_temp_free_i64(fp1);
7453
            gen_store_fpr64(ctx, fp2, fd);
7454
            tcg_temp_free_i64(fp2);
7455
        }
7456
        opn = "msub.d";
7457
        break;
7458
    case OPC_MSUB_PS:
7459
        check_cp1_64bitmode(ctx);
7460
        {
7461
            TCGv_i64 fp0 = tcg_temp_new_i64();
7462
            TCGv_i64 fp1 = tcg_temp_new_i64();
7463
            TCGv_i64 fp2 = tcg_temp_new_i64();
7464

    
7465
            gen_load_fpr64(ctx, fp0, fs);
7466
            gen_load_fpr64(ctx, fp1, ft);
7467
            gen_load_fpr64(ctx, fp2, fr);
7468
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7469
            tcg_temp_free_i64(fp0);
7470
            tcg_temp_free_i64(fp1);
7471
            gen_store_fpr64(ctx, fp2, fd);
7472
            tcg_temp_free_i64(fp2);
7473
        }
7474
        opn = "msub.ps";
7475
        break;
7476
    case OPC_NMADD_S:
7477
        check_cop1x(ctx);
7478
        {
7479
            TCGv_i32 fp0 = tcg_temp_new_i32();
7480
            TCGv_i32 fp1 = tcg_temp_new_i32();
7481
            TCGv_i32 fp2 = tcg_temp_new_i32();
7482

    
7483
            gen_load_fpr32(fp0, fs);
7484
            gen_load_fpr32(fp1, ft);
7485
            gen_load_fpr32(fp2, fr);
7486
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7487
            tcg_temp_free_i32(fp0);
7488
            tcg_temp_free_i32(fp1);
7489
            gen_store_fpr32(fp2, fd);
7490
            tcg_temp_free_i32(fp2);
7491
        }
7492
        opn = "nmadd.s";
7493
        break;
7494
    case OPC_NMADD_D:
7495
        check_cop1x(ctx);
7496
        check_cp1_registers(ctx, fd | fs | ft | fr);
7497
        {
7498
            TCGv_i64 fp0 = tcg_temp_new_i64();
7499
            TCGv_i64 fp1 = tcg_temp_new_i64();
7500
            TCGv_i64 fp2 = tcg_temp_new_i64();
7501

    
7502
            gen_load_fpr64(ctx, fp0, fs);
7503
            gen_load_fpr64(ctx, fp1, ft);
7504
            gen_load_fpr64(ctx, fp2, fr);
7505
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7506
            tcg_temp_free_i64(fp0);
7507
            tcg_temp_free_i64(fp1);
7508
            gen_store_fpr64(ctx, fp2, fd);
7509
            tcg_temp_free_i64(fp2);
7510
        }
7511
        opn = "nmadd.d";
7512
        break;
7513
    case OPC_NMADD_PS:
7514
        check_cp1_64bitmode(ctx);
7515
        {
7516
            TCGv_i64 fp0 = tcg_temp_new_i64();
7517
            TCGv_i64 fp1 = tcg_temp_new_i64();
7518
            TCGv_i64 fp2 = tcg_temp_new_i64();
7519

    
7520
            gen_load_fpr64(ctx, fp0, fs);
7521
            gen_load_fpr64(ctx, fp1, ft);
7522
            gen_load_fpr64(ctx, fp2, fr);
7523
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7524
            tcg_temp_free_i64(fp0);
7525
            tcg_temp_free_i64(fp1);
7526
            gen_store_fpr64(ctx, fp2, fd);
7527
            tcg_temp_free_i64(fp2);
7528
        }
7529
        opn = "nmadd.ps";
7530
        break;
7531
    case OPC_NMSUB_S:
7532
        check_cop1x(ctx);
7533
        {
7534
            TCGv_i32 fp0 = tcg_temp_new_i32();
7535
            TCGv_i32 fp1 = tcg_temp_new_i32();
7536
            TCGv_i32 fp2 = tcg_temp_new_i32();
7537

    
7538
            gen_load_fpr32(fp0, fs);
7539
            gen_load_fpr32(fp1, ft);
7540
            gen_load_fpr32(fp2, fr);
7541
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7542
            tcg_temp_free_i32(fp0);
7543
            tcg_temp_free_i32(fp1);
7544
            gen_store_fpr32(fp2, fd);
7545
            tcg_temp_free_i32(fp2);
7546
        }
7547
        opn = "nmsub.s";
7548
        break;
7549
    case OPC_NMSUB_D:
7550
        check_cop1x(ctx);
7551
        check_cp1_registers(ctx, fd | fs | ft | fr);
7552
        {
7553
            TCGv_i64 fp0 = tcg_temp_new_i64();
7554
            TCGv_i64 fp1 = tcg_temp_new_i64();
7555
            TCGv_i64 fp2 = tcg_temp_new_i64();
7556

    
7557
            gen_load_fpr64(ctx, fp0, fs);
7558
            gen_load_fpr64(ctx, fp1, ft);
7559
            gen_load_fpr64(ctx, fp2, fr);
7560
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7561
            tcg_temp_free_i64(fp0);
7562
            tcg_temp_free_i64(fp1);
7563
            gen_store_fpr64(ctx, fp2, fd);
7564
            tcg_temp_free_i64(fp2);
7565
        }
7566
        opn = "nmsub.d";
7567
        break;
7568
    case OPC_NMSUB_PS:
7569
        check_cp1_64bitmode(ctx);
7570
        {
7571
            TCGv_i64 fp0 = tcg_temp_new_i64();
7572
            TCGv_i64 fp1 = tcg_temp_new_i64();
7573
            TCGv_i64 fp2 = tcg_temp_new_i64();
7574

    
7575
            gen_load_fpr64(ctx, fp0, fs);
7576
            gen_load_fpr64(ctx, fp1, ft);
7577
            gen_load_fpr64(ctx, fp2, fr);
7578
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7579
            tcg_temp_free_i64(fp0);
7580
            tcg_temp_free_i64(fp1);
7581
            gen_store_fpr64(ctx, fp2, fd);
7582
            tcg_temp_free_i64(fp2);
7583
        }
7584
        opn = "nmsub.ps";
7585
        break;
7586
    default:
7587
        MIPS_INVAL(opn);
7588
        generate_exception (ctx, EXCP_RI);
7589
        return;
7590
    }
7591
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7592
               fregnames[fs], fregnames[ft]);
7593
}
7594

    
7595
/* ISA extensions (ASEs) */
7596
/* MIPS16 extension to MIPS32 */
7597
/* SmartMIPS extension to MIPS32 */
7598

    
7599
#if defined(TARGET_MIPS64)
7600

    
7601
/* MDMX extension to MIPS64 */
7602

    
7603
#endif
7604

    
7605
static void decode_opc (CPUState *env, DisasContext *ctx)
7606
{
7607
    int32_t offset;
7608
    int rs, rt, rd, sa;
7609
    uint32_t op, op1, op2;
7610
    int16_t imm;
7611

    
7612
    /* make sure instructions are on a word boundary */
7613
    if (ctx->pc & 0x3) {
7614
        env->CP0_BadVAddr = ctx->pc;
7615
        generate_exception(ctx, EXCP_AdEL);
7616
        return;
7617
    }
7618

    
7619
    /* Handle blikely not taken case */
7620
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7621
        int l1 = gen_new_label();
7622

    
7623
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7624
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7625
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7626
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7627
        gen_set_label(l1);
7628
    }
7629
    op = MASK_OP_MAJOR(ctx->opcode);
7630
    rs = (ctx->opcode >> 21) & 0x1f;
7631
    rt = (ctx->opcode >> 16) & 0x1f;
7632
    rd = (ctx->opcode >> 11) & 0x1f;
7633
    sa = (ctx->opcode >> 6) & 0x1f;
7634
    imm = (int16_t)ctx->opcode;
7635
    switch (op) {
7636
    case OPC_SPECIAL:
7637
        op1 = MASK_SPECIAL(ctx->opcode);
7638
        switch (op1) {
7639
        case OPC_SLL:          /* Shift with immediate */
7640
        case OPC_SRA:
7641
        case OPC_SRL:
7642
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7643
            break;
7644
        case OPC_MOVN:         /* Conditional move */
7645
        case OPC_MOVZ:
7646
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7647
            gen_cond_move(env, op1, rd, rs, rt);
7648
            break;
7649
        case OPC_ADD ... OPC_SUBU:
7650
            gen_arith(env, ctx, op1, rd, rs, rt);
7651
            break;
7652
        case OPC_SLLV:         /* Shifts */
7653
        case OPC_SRLV:
7654
        case OPC_SRAV:
7655
            gen_shift(env, ctx, op1, rd, rs, rt);
7656
            break;
7657
        case OPC_SLT:          /* Set on less than */
7658
        case OPC_SLTU:
7659
            gen_slt(env, op1, rd, rs, rt);
7660
            break;
7661
        case OPC_AND:          /* Logic*/
7662
        case OPC_OR:
7663
        case OPC_NOR:
7664
        case OPC_XOR:
7665
            gen_logic(env, op1, rd, rs, rt);
7666
            break;
7667
        case OPC_MULT ... OPC_DIVU:
7668
            if (sa) {
7669
                check_insn(env, ctx, INSN_VR54XX);
7670
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7671
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7672
            } else
7673
                gen_muldiv(ctx, op1, rs, rt);
7674
            break;
7675
        case OPC_JR ... OPC_JALR:
7676
            gen_compute_branch(ctx, op1, rs, rd, sa);
7677
            return;
7678
        case OPC_TGE ... OPC_TEQ: /* Traps */
7679
        case OPC_TNE:
7680
            gen_trap(ctx, op1, rs, rt, -1);
7681
            break;
7682
        case OPC_MFHI:          /* Move from HI/LO */
7683
        case OPC_MFLO:
7684
            gen_HILO(ctx, op1, rd);
7685
            break;
7686
        case OPC_MTHI:
7687
        case OPC_MTLO:          /* Move to HI/LO */
7688
            gen_HILO(ctx, op1, rs);
7689
            break;
7690
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7691
#ifdef MIPS_STRICT_STANDARD
7692
            MIPS_INVAL("PMON / selsl");
7693
            generate_exception(ctx, EXCP_RI);
7694
#else
7695
            gen_helper_0i(pmon, sa);
7696
#endif
7697
            break;
7698
        case OPC_SYSCALL:
7699
            generate_exception(ctx, EXCP_SYSCALL);
7700
            break;
7701
        case OPC_BREAK:
7702
            generate_exception(ctx, EXCP_BREAK);
7703
            break;
7704
        case OPC_SPIM:
7705
#ifdef MIPS_STRICT_STANDARD
7706
            MIPS_INVAL("SPIM");
7707
            generate_exception(ctx, EXCP_RI);
7708
#else
7709
           /* Implemented as RI exception for now. */
7710
            MIPS_INVAL("spim (unofficial)");
7711
            generate_exception(ctx, EXCP_RI);
7712
#endif
7713
            break;
7714
        case OPC_SYNC:
7715
            /* Treat as NOP. */
7716
            break;
7717

    
7718
        case OPC_MOVCI:
7719
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7720
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7721
                check_cp1_enabled(ctx);
7722
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7723
                          (ctx->opcode >> 16) & 1);
7724
            } else {
7725
                generate_exception_err(ctx, EXCP_CpU, 1);
7726
            }
7727
            break;
7728

    
7729
#if defined(TARGET_MIPS64)
7730
       /* MIPS64 specific opcodes */
7731
        case OPC_DSLL:
7732
        case OPC_DSRA:
7733
        case OPC_DSRL:
7734
        case OPC_DSLL32:
7735
        case OPC_DSRA32:
7736
        case OPC_DSRL32:
7737
            check_insn(env, ctx, ISA_MIPS3);
7738
            check_mips_64(ctx);
7739
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7740
            break;
7741
        case OPC_DADD ... OPC_DSUBU:
7742
            check_insn(env, ctx, ISA_MIPS3);
7743
            check_mips_64(ctx);
7744
            gen_arith(env, ctx, op1, rd, rs, rt);
7745
            break;
7746
        case OPC_DSLLV:
7747
        case OPC_DSRAV:
7748
        case OPC_DSRLV:
7749
            check_insn(env, ctx, ISA_MIPS3);
7750
            check_mips_64(ctx);
7751
            gen_shift(env, ctx, op1, rd, rs, rt);
7752
            break;
7753
        case OPC_DMULT ... OPC_DDIVU:
7754
            check_insn(env, ctx, ISA_MIPS3);
7755
            check_mips_64(ctx);
7756
            gen_muldiv(ctx, op1, rs, rt);
7757
            break;
7758
#endif
7759
        default:            /* Invalid */
7760
            MIPS_INVAL("special");
7761
            generate_exception(ctx, EXCP_RI);
7762
            break;
7763
        }
7764
        break;
7765
    case OPC_SPECIAL2:
7766
        op1 = MASK_SPECIAL2(ctx->opcode);
7767
        switch (op1) {
7768
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7769
        case OPC_MSUB ... OPC_MSUBU:
7770
            check_insn(env, ctx, ISA_MIPS32);
7771
            gen_muldiv(ctx, op1, rs, rt);
7772
            break;
7773
        case OPC_MUL:
7774
            gen_arith(env, ctx, op1, rd, rs, rt);
7775
            break;
7776
        case OPC_CLO:
7777
        case OPC_CLZ:
7778
            check_insn(env, ctx, ISA_MIPS32);
7779
            gen_cl(ctx, op1, rd, rs);
7780
            break;
7781
        case OPC_SDBBP:
7782
            /* XXX: not clear which exception should be raised
7783
             *      when in debug mode...
7784
             */
7785
            check_insn(env, ctx, ISA_MIPS32);
7786
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7787
                generate_exception(ctx, EXCP_DBp);
7788
            } else {
7789
                generate_exception(ctx, EXCP_DBp);
7790
            }
7791
            /* Treat as NOP. */
7792
            break;
7793
#if defined(TARGET_MIPS64)
7794
        case OPC_DCLO:
7795
        case OPC_DCLZ:
7796
            check_insn(env, ctx, ISA_MIPS64);
7797
            check_mips_64(ctx);
7798
            gen_cl(ctx, op1, rd, rs);
7799
            break;
7800
#endif
7801
        default:            /* Invalid */
7802
            MIPS_INVAL("special2");
7803
            generate_exception(ctx, EXCP_RI);
7804
            break;
7805
        }
7806
        break;
7807
    case OPC_SPECIAL3:
7808
        op1 = MASK_SPECIAL3(ctx->opcode);
7809
        switch (op1) {
7810
        case OPC_EXT:
7811
        case OPC_INS:
7812
            check_insn(env, ctx, ISA_MIPS32R2);
7813
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7814
            break;
7815
        case OPC_BSHFL:
7816
            check_insn(env, ctx, ISA_MIPS32R2);
7817
            op2 = MASK_BSHFL(ctx->opcode);
7818
            gen_bshfl(ctx, op2, rt, rd);
7819
            break;
7820
        case OPC_RDHWR:
7821
            check_insn(env, ctx, ISA_MIPS32R2);
7822
            {
7823
                TCGv t0 = tcg_temp_new();
7824

    
7825
                switch (rd) {
7826
                case 0:
7827
                    save_cpu_state(ctx, 1);
7828
                    gen_helper_rdhwr_cpunum(t0);
7829
                    gen_store_gpr(t0, rt);
7830
                    break;
7831
                case 1:
7832
                    save_cpu_state(ctx, 1);
7833
                    gen_helper_rdhwr_synci_step(t0);
7834
                    gen_store_gpr(t0, rt);
7835
                    break;
7836
                case 2:
7837
                    save_cpu_state(ctx, 1);
7838
                    gen_helper_rdhwr_cc(t0);
7839
                    gen_store_gpr(t0, rt);
7840
                    break;
7841
                case 3:
7842
                    save_cpu_state(ctx, 1);
7843
                    gen_helper_rdhwr_ccres(t0);
7844
                    gen_store_gpr(t0, rt);
7845
                    break;
7846
                case 29:
7847
#if defined(CONFIG_USER_ONLY)
7848
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7849
                    gen_store_gpr(t0, rt);
7850
                    break;
7851
#else
7852
                    /* XXX: Some CPUs implement this in hardware.
7853
                       Not supported yet. */
7854
#endif
7855
                default:            /* Invalid */
7856
                    MIPS_INVAL("rdhwr");
7857
                    generate_exception(ctx, EXCP_RI);
7858
                    break;
7859
                }
7860
                tcg_temp_free(t0);
7861
            }
7862
            break;
7863
        case OPC_FORK:
7864
            check_insn(env, ctx, ASE_MT);
7865
            {
7866
                TCGv t0 = tcg_temp_new();
7867
                TCGv t1 = tcg_temp_new();
7868

    
7869
                gen_load_gpr(t0, rt);
7870
                gen_load_gpr(t1, rs);
7871
                gen_helper_fork(t0, t1);
7872
                tcg_temp_free(t0);
7873
                tcg_temp_free(t1);
7874
            }
7875
            break;
7876
        case OPC_YIELD:
7877
            check_insn(env, ctx, ASE_MT);
7878
            {
7879
                TCGv t0 = tcg_temp_new();
7880

    
7881
                save_cpu_state(ctx, 1);
7882
                gen_load_gpr(t0, rs);
7883
                gen_helper_yield(t0, t0);
7884
                gen_store_gpr(t0, rd);
7885
                tcg_temp_free(t0);
7886
            }
7887
            break;
7888
#if defined(TARGET_MIPS64)
7889
        case OPC_DEXTM ... OPC_DEXT:
7890
        case OPC_DINSM ... OPC_DINS:
7891
            check_insn(env, ctx, ISA_MIPS64R2);
7892
            check_mips_64(ctx);
7893
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7894
            break;
7895
        case OPC_DBSHFL:
7896
            check_insn(env, ctx, ISA_MIPS64R2);
7897
            check_mips_64(ctx);
7898
            op2 = MASK_DBSHFL(ctx->opcode);
7899
            gen_bshfl(ctx, op2, rt, rd);
7900
            break;
7901
#endif
7902
        default:            /* Invalid */
7903
            MIPS_INVAL("special3");
7904
            generate_exception(ctx, EXCP_RI);
7905
            break;
7906
        }
7907
        break;
7908
    case OPC_REGIMM:
7909
        op1 = MASK_REGIMM(ctx->opcode);
7910
        switch (op1) {
7911
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7912
        case OPC_BLTZAL ... OPC_BGEZALL:
7913
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7914
            return;
7915
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7916
        case OPC_TNEI:
7917
            gen_trap(ctx, op1, rs, -1, imm);
7918
            break;
7919
        case OPC_SYNCI:
7920
            check_insn(env, ctx, ISA_MIPS32R2);
7921
            /* Treat as NOP. */
7922
            break;
7923
        default:            /* Invalid */
7924
            MIPS_INVAL("regimm");
7925
            generate_exception(ctx, EXCP_RI);
7926
            break;
7927
        }
7928
        break;
7929
    case OPC_CP0:
7930
        check_cp0_enabled(ctx);
7931
        op1 = MASK_CP0(ctx->opcode);
7932
        switch (op1) {
7933
        case OPC_MFC0:
7934
        case OPC_MTC0:
7935
        case OPC_MFTR:
7936
        case OPC_MTTR:
7937
#if defined(TARGET_MIPS64)
7938
        case OPC_DMFC0:
7939
        case OPC_DMTC0:
7940
#endif
7941
#ifndef CONFIG_USER_ONLY
7942
            gen_cp0(env, ctx, op1, rt, rd);
7943
#endif /* !CONFIG_USER_ONLY */
7944
            break;
7945
        case OPC_C0_FIRST ... OPC_C0_LAST:
7946
#ifndef CONFIG_USER_ONLY
7947
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7948
#endif /* !CONFIG_USER_ONLY */
7949
            break;
7950
        case OPC_MFMC0:
7951
#ifndef CONFIG_USER_ONLY
7952
            {
7953
                TCGv t0 = tcg_temp_new();
7954

    
7955
                op2 = MASK_MFMC0(ctx->opcode);
7956
                switch (op2) {
7957
                case OPC_DMT:
7958
                    check_insn(env, ctx, ASE_MT);
7959
                    gen_helper_dmt(t0, t0);
7960
                    gen_store_gpr(t0, rt);
7961
                    break;
7962
                case OPC_EMT:
7963
                    check_insn(env, ctx, ASE_MT);
7964
                    gen_helper_emt(t0, t0);
7965
                    gen_store_gpr(t0, rt);
7966
                    break;
7967
                case OPC_DVPE:
7968
                    check_insn(env, ctx, ASE_MT);
7969
                    gen_helper_dvpe(t0, t0);
7970
                    gen_store_gpr(t0, rt);
7971
                    break;
7972
                case OPC_EVPE:
7973
                    check_insn(env, ctx, ASE_MT);
7974
                    gen_helper_evpe(t0, t0);
7975
                    gen_store_gpr(t0, rt);
7976
                    break;
7977
                case OPC_DI:
7978
                    check_insn(env, ctx, ISA_MIPS32R2);
7979
                    save_cpu_state(ctx, 1);
7980
                    gen_helper_di(t0);
7981
                    gen_store_gpr(t0, rt);
7982
                    /* Stop translation as we may have switched the execution mode */
7983
                    ctx->bstate = BS_STOP;
7984
                    break;
7985
                case OPC_EI:
7986
                    check_insn(env, ctx, ISA_MIPS32R2);
7987
                    save_cpu_state(ctx, 1);
7988
                    gen_helper_ei(t0);
7989
                    gen_store_gpr(t0, rt);
7990
                    /* Stop translation as we may have switched the execution mode */
7991
                    ctx->bstate = BS_STOP;
7992
                    break;
7993
                default:            /* Invalid */
7994
                    MIPS_INVAL("mfmc0");
7995
                    generate_exception(ctx, EXCP_RI);
7996
                    break;
7997
                }
7998
                tcg_temp_free(t0);
7999
            }
8000
#endif /* !CONFIG_USER_ONLY */
8001
            break;
8002
        case OPC_RDPGPR:
8003
            check_insn(env, ctx, ISA_MIPS32R2);
8004
            gen_load_srsgpr(rt, rd);
8005
            break;
8006
        case OPC_WRPGPR:
8007
            check_insn(env, ctx, ISA_MIPS32R2);
8008
            gen_store_srsgpr(rt, rd);
8009
            break;
8010
        default:
8011
            MIPS_INVAL("cp0");
8012
            generate_exception(ctx, EXCP_RI);
8013
            break;
8014
        }
8015
        break;
8016
    case OPC_ADDI: /* Arithmetic with immediate opcode */
8017
    case OPC_ADDIU:
8018
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8019
         break;
8020
    case OPC_SLTI: /* Set on less than with immediate opcode */
8021
    case OPC_SLTIU:
8022
         gen_slt_imm(env, op, rt, rs, imm);
8023
         break;
8024
    case OPC_ANDI: /* Arithmetic with immediate opcode */
8025
    case OPC_LUI:
8026
    case OPC_ORI:
8027
    case OPC_XORI:
8028
         gen_logic_imm(env, op, rt, rs, imm);
8029
         break;
8030
    case OPC_J ... OPC_JAL: /* Jump */
8031
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8032
         gen_compute_branch(ctx, op, rs, rt, offset);
8033
         return;
8034
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8035
    case OPC_BEQL ... OPC_BGTZL:
8036
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8037
         return;
8038
    case OPC_LB ... OPC_LWR: /* Load and stores */
8039
    case OPC_SB ... OPC_SW:
8040
    case OPC_SWR:
8041
    case OPC_LL:
8042
         gen_ldst(ctx, op, rt, rs, imm);
8043
         break;
8044
    case OPC_SC:
8045
         gen_st_cond(ctx, op, rt, rs, imm);
8046
         break;
8047
    case OPC_CACHE:
8048
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8049
        /* Treat as NOP. */
8050
        break;
8051
    case OPC_PREF:
8052
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8053
        /* Treat as NOP. */
8054
        break;
8055

    
8056
    /* Floating point (COP1). */
8057
    case OPC_LWC1:
8058
    case OPC_LDC1:
8059
    case OPC_SWC1:
8060
    case OPC_SDC1:
8061
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8062
            check_cp1_enabled(ctx);
8063
            gen_flt_ldst(ctx, op, rt, rs, imm);
8064
        } else {
8065
            generate_exception_err(ctx, EXCP_CpU, 1);
8066
        }
8067
        break;
8068

    
8069
    case OPC_CP1:
8070
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8071
            check_cp1_enabled(ctx);
8072
            op1 = MASK_CP1(ctx->opcode);
8073
            switch (op1) {
8074
            case OPC_MFHC1:
8075
            case OPC_MTHC1:
8076
                check_insn(env, ctx, ISA_MIPS32R2);
8077
            case OPC_MFC1:
8078
            case OPC_CFC1:
8079
            case OPC_MTC1:
8080
            case OPC_CTC1:
8081
                gen_cp1(ctx, op1, rt, rd);
8082
                break;
8083
#if defined(TARGET_MIPS64)
8084
            case OPC_DMFC1:
8085
            case OPC_DMTC1:
8086
                check_insn(env, ctx, ISA_MIPS3);
8087
                gen_cp1(ctx, op1, rt, rd);
8088
                break;
8089
#endif
8090
            case OPC_BC1ANY2:
8091
            case OPC_BC1ANY4:
8092
                check_cop1x(ctx);
8093
                check_insn(env, ctx, ASE_MIPS3D);
8094
                /* fall through */
8095
            case OPC_BC1:
8096
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8097
                                    (rt >> 2) & 0x7, imm << 2);
8098
                return;
8099
            case OPC_S_FMT:
8100
            case OPC_D_FMT:
8101
            case OPC_W_FMT:
8102
            case OPC_L_FMT:
8103
            case OPC_PS_FMT:
8104
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8105
                           (imm >> 8) & 0x7);
8106
                break;
8107
            default:
8108
                MIPS_INVAL("cp1");
8109
                generate_exception (ctx, EXCP_RI);
8110
                break;
8111
            }
8112
        } else {
8113
            generate_exception_err(ctx, EXCP_CpU, 1);
8114
        }
8115
        break;
8116

    
8117
    /* COP2.  */
8118
    case OPC_LWC2:
8119
    case OPC_LDC2:
8120
    case OPC_SWC2:
8121
    case OPC_SDC2:
8122
    case OPC_CP2:
8123
        /* COP2: Not implemented. */
8124
        generate_exception_err(ctx, EXCP_CpU, 2);
8125
        break;
8126

    
8127
    case OPC_CP3:
8128
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8129
            check_cp1_enabled(ctx);
8130
            op1 = MASK_CP3(ctx->opcode);
8131
            switch (op1) {
8132
            case OPC_LWXC1:
8133
            case OPC_LDXC1:
8134
            case OPC_LUXC1:
8135
            case OPC_SWXC1:
8136
            case OPC_SDXC1:
8137
            case OPC_SUXC1:
8138
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8139
                break;
8140
            case OPC_PREFX:
8141
                /* Treat as NOP. */
8142
                break;
8143
            case OPC_ALNV_PS:
8144
            case OPC_MADD_S:
8145
            case OPC_MADD_D:
8146
            case OPC_MADD_PS:
8147
            case OPC_MSUB_S:
8148
            case OPC_MSUB_D:
8149
            case OPC_MSUB_PS:
8150
            case OPC_NMADD_S:
8151
            case OPC_NMADD_D:
8152
            case OPC_NMADD_PS:
8153
            case OPC_NMSUB_S:
8154
            case OPC_NMSUB_D:
8155
            case OPC_NMSUB_PS:
8156
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8157
                break;
8158
            default:
8159
                MIPS_INVAL("cp3");
8160
                generate_exception (ctx, EXCP_RI);
8161
                break;
8162
            }
8163
        } else {
8164
            generate_exception_err(ctx, EXCP_CpU, 1);
8165
        }
8166
        break;
8167

    
8168
#if defined(TARGET_MIPS64)
8169
    /* MIPS64 opcodes */
8170
    case OPC_LWU:
8171
    case OPC_LDL ... OPC_LDR:
8172
    case OPC_SDL ... OPC_SDR:
8173
    case OPC_LLD:
8174
    case OPC_LD:
8175
    case OPC_SD:
8176
        check_insn(env, ctx, ISA_MIPS3);
8177
        check_mips_64(ctx);
8178
        gen_ldst(ctx, op, rt, rs, imm);
8179
        break;
8180
    case OPC_SCD:
8181
        check_insn(env, ctx, ISA_MIPS3);
8182
        check_mips_64(ctx);
8183
        gen_st_cond(ctx, op, rt, rs, imm);
8184
        break;
8185
    case OPC_DADDI:
8186
    case OPC_DADDIU:
8187
        check_insn(env, ctx, ISA_MIPS3);
8188
        check_mips_64(ctx);
8189
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8190
        break;
8191
#endif
8192
    case OPC_JALX:
8193
        check_insn(env, ctx, ASE_MIPS16);
8194
        /* MIPS16: Not implemented. */
8195
    case OPC_MDMX:
8196
        check_insn(env, ctx, ASE_MDMX);
8197
        /* MDMX: Not implemented. */
8198
    default:            /* Invalid */
8199
        MIPS_INVAL("major opcode");
8200
        generate_exception(ctx, EXCP_RI);
8201
        break;
8202
    }
8203
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8204
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8205
        /* Branches completion */
8206
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8207
        ctx->bstate = BS_BRANCH;
8208
        save_cpu_state(ctx, 0);
8209
        /* FIXME: Need to clear can_do_io.  */
8210
        switch (hflags) {
8211
        case MIPS_HFLAG_B:
8212
            /* unconditional branch */
8213
            MIPS_DEBUG("unconditional branch");
8214
            gen_goto_tb(ctx, 0, ctx->btarget);
8215
            break;
8216
        case MIPS_HFLAG_BL:
8217
            /* blikely taken case */
8218
            MIPS_DEBUG("blikely branch taken");
8219
            gen_goto_tb(ctx, 0, ctx->btarget);
8220
            break;
8221
        case MIPS_HFLAG_BC:
8222
            /* Conditional branch */
8223
            MIPS_DEBUG("conditional branch");
8224
            {
8225
                int l1 = gen_new_label();
8226

    
8227
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8228
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8229
                gen_set_label(l1);
8230
                gen_goto_tb(ctx, 0, ctx->btarget);
8231
            }
8232
            break;
8233
        case MIPS_HFLAG_BR:
8234
            /* unconditional branch to register */
8235
            MIPS_DEBUG("branch to register");
8236
            tcg_gen_mov_tl(cpu_PC, btarget);
8237
            tcg_gen_exit_tb(0);
8238
            break;
8239
        default:
8240
            MIPS_DEBUG("unknown branch");
8241
            break;
8242
        }
8243
    }
8244
}
8245

    
8246
static inline void
8247
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8248
                                int search_pc)
8249
{
8250
    DisasContext ctx;
8251
    target_ulong pc_start;
8252
    uint16_t *gen_opc_end;
8253
    CPUBreakpoint *bp;
8254
    int j, lj = -1;
8255
    int num_insns;
8256
    int max_insns;
8257

    
8258
    if (search_pc)
8259
        qemu_log("search pc %d\n", search_pc);
8260

    
8261
    pc_start = tb->pc;
8262
    /* Leave some spare opc slots for branch handling. */
8263
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8264
    ctx.pc = pc_start;
8265
    ctx.saved_pc = -1;
8266
    ctx.tb = tb;
8267
    ctx.bstate = BS_NONE;
8268
    /* Restore delay slot state from the tb context.  */
8269
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8270
    restore_cpu_state(env, &ctx);
8271
#ifdef CONFIG_USER_ONLY
8272
        ctx.mem_idx = MIPS_HFLAG_UM;
8273
#else
8274
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8275
#endif
8276
    num_insns = 0;
8277
    max_insns = tb->cflags & CF_COUNT_MASK;
8278
    if (max_insns == 0)
8279
        max_insns = CF_COUNT_MASK;
8280
#ifdef DEBUG_DISAS
8281
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8282
    /* FIXME: This may print out stale hflags from env... */
8283
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8284
#endif
8285
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8286
    gen_icount_start();
8287
    while (ctx.bstate == BS_NONE) {
8288
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8289
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8290
                if (bp->pc == ctx.pc) {
8291
                    save_cpu_state(&ctx, 1);
8292
                    ctx.bstate = BS_BRANCH;
8293
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8294
                    /* Include the breakpoint location or the tb won't
8295
                     * be flushed when it must be.  */
8296
                    ctx.pc += 4;
8297
                    goto done_generating;
8298
                }
8299
            }
8300
        }
8301

    
8302
        if (search_pc) {
8303
            j = gen_opc_ptr - gen_opc_buf;
8304
            if (lj < j) {
8305
                lj++;
8306
                while (lj < j)
8307
                    gen_opc_instr_start[lj++] = 0;
8308
            }
8309
            gen_opc_pc[lj] = ctx.pc;
8310
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8311
            gen_opc_instr_start[lj] = 1;
8312
            gen_opc_icount[lj] = num_insns;
8313
        }
8314
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8315
            gen_io_start();
8316
        ctx.opcode = ldl_code(ctx.pc);
8317
        decode_opc(env, &ctx);
8318
        ctx.pc += 4;
8319
        num_insns++;
8320

    
8321
        if (env->singlestep_enabled)
8322
            break;
8323

    
8324
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8325
            break;
8326

    
8327
        if (gen_opc_ptr >= gen_opc_end)
8328
            break;
8329

    
8330
        if (num_insns >= max_insns)
8331
            break;
8332

    
8333
        if (singlestep)
8334
            break;
8335
    }
8336
    if (tb->cflags & CF_LAST_IO)
8337
        gen_io_end();
8338
    if (env->singlestep_enabled) {
8339
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8340
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8341
    } else {
8342
        switch (ctx.bstate) {
8343
        case BS_STOP:
8344
            gen_helper_interrupt_restart();
8345
            gen_goto_tb(&ctx, 0, ctx.pc);
8346
            break;
8347
        case BS_NONE:
8348
            save_cpu_state(&ctx, 0);
8349
            gen_goto_tb(&ctx, 0, ctx.pc);
8350
            break;
8351
        case BS_EXCP:
8352
            gen_helper_interrupt_restart();
8353
            tcg_gen_exit_tb(0);
8354
            break;
8355
        case BS_BRANCH:
8356
        default:
8357
            break;
8358
        }
8359
    }
8360
done_generating:
8361
    gen_icount_end(tb, num_insns);
8362
    *gen_opc_ptr = INDEX_op_end;
8363
    if (search_pc) {
8364
        j = gen_opc_ptr - gen_opc_buf;
8365
        lj++;
8366
        while (lj <= j)
8367
            gen_opc_instr_start[lj++] = 0;
8368
    } else {
8369
        tb->size = ctx.pc - pc_start;
8370
        tb->icount = num_insns;
8371
    }
8372
#ifdef DEBUG_DISAS
8373
    LOG_DISAS("\n");
8374
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8375
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8376
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8377
        qemu_log("\n");
8378
    }
8379
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8380
#endif
8381
}
8382

    
8383
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8384
{
8385
    gen_intermediate_code_internal(env, tb, 0);
8386
}
8387

    
8388
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8389
{
8390
    gen_intermediate_code_internal(env, tb, 1);
8391
}
8392

    
8393
static void fpu_dump_state(CPUState *env, FILE *f,
8394
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8395
                           int flags)
8396
{
8397
    int i;
8398
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8399

    
8400
#define printfpr(fp)                                                        \
8401
    do {                                                                    \
8402
        if (is_fpu64)                                                       \
8403
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8404
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8405
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8406
        else {                                                              \
8407
            fpr_t tmp;                                                      \
8408
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8409
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8410
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8411
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8412
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8413
        }                                                                   \
8414
    } while(0)
8415

    
8416

    
8417
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8418
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8419
                get_float_exception_flags(&env->active_fpu.fp_status));
8420
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8421
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8422
        printfpr(&env->active_fpu.fpr[i]);
8423
    }
8424

    
8425
#undef printfpr
8426
}
8427

    
8428
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8429
/* Debug help: The architecture requires 32bit code to maintain proper
8430
   sign-extended values on 64bit machines.  */
8431

    
8432
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8433

    
8434
static void
8435
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8436
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8437
                                int flags)
8438
{
8439
    int i;
8440

    
8441
    if (!SIGN_EXT_P(env->active_tc.PC))
8442
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8443
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8444
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8445
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8446
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8447
    if (!SIGN_EXT_P(env->btarget))
8448
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8449

    
8450
    for (i = 0; i < 32; i++) {
8451
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8452
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8453
    }
8454

    
8455
    if (!SIGN_EXT_P(env->CP0_EPC))
8456
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8457
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8458
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8459
}
8460
#endif
8461

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

    
8468
    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",
8469
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8470
                env->hflags, env->btarget, env->bcond);
8471
    for (i = 0; i < 32; i++) {
8472
        if ((i & 3) == 0)
8473
            cpu_fprintf(f, "GPR%02d:", i);
8474
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8475
        if ((i & 3) == 3)
8476
            cpu_fprintf(f, "\n");
8477
    }
8478

    
8479
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8480
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8481
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8482
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8483
    if (env->hflags & MIPS_HFLAG_FPU)
8484
        fpu_dump_state(env, f, cpu_fprintf, flags);
8485
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8486
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8487
#endif
8488
}
8489

    
8490
static void mips_tcg_init(void)
8491
{
8492
    int i;
8493
    static int inited;
8494

    
8495
    /* Initialize various static tables. */
8496
    if (inited)
8497
        return;
8498

    
8499
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8500
    for (i = 1; i < 32; i++)
8501
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8502
                                        offsetof(CPUState, active_tc.gpr[i]),
8503
                                        regnames[i]);
8504
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8505
                                offsetof(CPUState, active_tc.PC), "PC");
8506
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8507
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8508
                                       offsetof(CPUState, active_tc.HI[i]),
8509
                                       regnames_HI[i]);
8510
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8511
                                       offsetof(CPUState, active_tc.LO[i]),
8512
                                       regnames_LO[i]);
8513
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8514
                                        offsetof(CPUState, active_tc.ACX[i]),
8515
                                        regnames_ACX[i]);
8516
    }
8517
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8518
                                     offsetof(CPUState, active_tc.DSPControl),
8519
                                     "DSPControl");
8520
    bcond = tcg_global_mem_new(TCG_AREG0,
8521
                               offsetof(CPUState, bcond), "bcond");
8522
    btarget = tcg_global_mem_new(TCG_AREG0,
8523
                                 offsetof(CPUState, btarget), "btarget");
8524
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8525
                                    offsetof(CPUState, hflags), "hflags");
8526

    
8527
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8528
                                      offsetof(CPUState, active_fpu.fcr0),
8529
                                      "fcr0");
8530
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8531
                                       offsetof(CPUState, active_fpu.fcr31),
8532
                                       "fcr31");
8533

    
8534
    /* register helpers */
8535
#define GEN_HELPER 2
8536
#include "helper.h"
8537

    
8538
    inited = 1;
8539
}
8540

    
8541
#include "translate_init.c"
8542

    
8543
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8544
{
8545
    CPUMIPSState *env;
8546
    const mips_def_t *def;
8547

    
8548
    def = cpu_mips_find_by_name(cpu_model);
8549
    if (!def)
8550
        return NULL;
8551
    env = qemu_mallocz(sizeof(CPUMIPSState));
8552
    env->cpu_model = def;
8553

    
8554
    cpu_exec_init(env);
8555
    env->cpu_model_str = cpu_model;
8556
    mips_tcg_init();
8557
    cpu_reset(env);
8558
    return env;
8559
}
8560

    
8561
void cpu_reset (CPUMIPSState *env)
8562
{
8563
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8564
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8565
        log_cpu_state(env, 0);
8566
    }
8567

    
8568
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8569

    
8570
    tlb_flush(env, 1);
8571

    
8572
    /* Minimal init */
8573
#if defined(CONFIG_USER_ONLY)
8574
    env->hflags = MIPS_HFLAG_UM;
8575
#else
8576
    if (env->hflags & MIPS_HFLAG_BMASK) {
8577
        /* If the exception was raised from a delay slot,
8578
           come back to the jump.  */
8579
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8580
    } else {
8581
        env->CP0_ErrorEPC = env->active_tc.PC;
8582
    }
8583
    env->active_tc.PC = (int32_t)0xBFC00000;
8584
    env->CP0_Wired = 0;
8585
    /* SMP not implemented */
8586
    env->CP0_EBase = 0x80000000;
8587
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8588
    /* vectored interrupts not implemented, timer on int 7,
8589
       no performance counters. */
8590
    env->CP0_IntCtl = 0xe0000000;
8591
    {
8592
        int i;
8593

    
8594
        for (i = 0; i < 7; i++) {
8595
            env->CP0_WatchLo[i] = 0;
8596
            env->CP0_WatchHi[i] = 0x80000000;
8597
        }
8598
        env->CP0_WatchLo[7] = 0;
8599
        env->CP0_WatchHi[7] = 0;
8600
    }
8601
    /* Count register increments in debug mode, EJTAG version 1 */
8602
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8603
    env->hflags = MIPS_HFLAG_CP0;
8604
#endif
8605
    env->exception_index = EXCP_NONE;
8606
    cpu_mips_register(env, env->cpu_model);
8607
}
8608

    
8609
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8610
                unsigned long searched_pc, int pc_pos, void *puc)
8611
{
8612
    env->active_tc.PC = gen_opc_pc[pc_pos];
8613
    env->hflags &= ~MIPS_HFLAG_BMASK;
8614
    env->hflags |= gen_opc_hflags[pc_pos];
8615
}