Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 1fc7bf6e

History | View | Annotate | Download (241.2 kB)

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

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

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

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

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

    
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
    OPC_ANDI     = (0x0C << 26),
61
    OPC_ORI      = (0x0D << 26),
62
    OPC_XORI     = (0x0E << 26),
63
    OPC_LUI      = (0x0F << 26),
64
    OPC_DADDI    = (0x18 << 26),
65
    OPC_DADDIU   = (0x19 << 26),
66
    /* Jump and branches */
67
    OPC_J        = (0x02 << 26),
68
    OPC_JAL      = (0x03 << 26),
69
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
70
    OPC_BEQL     = (0x14 << 26),
71
    OPC_BNE      = (0x05 << 26),
72
    OPC_BNEL     = (0x15 << 26),
73
    OPC_BLEZ     = (0x06 << 26),
74
    OPC_BLEZL    = (0x16 << 26),
75
    OPC_BGTZ     = (0x07 << 26),
76
    OPC_BGTZL    = (0x17 << 26),
77
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
78
    /* Load and stores */
79
    OPC_LDL      = (0x1A << 26),
80
    OPC_LDR      = (0x1B << 26),
81
    OPC_LB       = (0x20 << 26),
82
    OPC_LH       = (0x21 << 26),
83
    OPC_LWL      = (0x22 << 26),
84
    OPC_LW       = (0x23 << 26),
85
    OPC_LBU      = (0x24 << 26),
86
    OPC_LHU      = (0x25 << 26),
87
    OPC_LWR      = (0x26 << 26),
88
    OPC_LWU      = (0x27 << 26),
89
    OPC_SB       = (0x28 << 26),
90
    OPC_SH       = (0x29 << 26),
91
    OPC_SWL      = (0x2A << 26),
92
    OPC_SW       = (0x2B << 26),
93
    OPC_SDL      = (0x2C << 26),
94
    OPC_SDR      = (0x2D << 26),
95
    OPC_SWR      = (0x2E << 26),
96
    OPC_LL       = (0x30 << 26),
97
    OPC_LLD      = (0x34 << 26),
98
    OPC_LD       = (0x37 << 26),
99
    OPC_SC       = (0x38 << 26),
100
    OPC_SCD      = (0x3C << 26),
101
    OPC_SD       = (0x3F << 26),
102
    /* Floating point load/store */
103
    OPC_LWC1     = (0x31 << 26),
104
    OPC_LWC2     = (0x32 << 26),
105
    OPC_LDC1     = (0x35 << 26),
106
    OPC_LDC2     = (0x36 << 26),
107
    OPC_SWC1     = (0x39 << 26),
108
    OPC_SWC2     = (0x3A << 26),
109
    OPC_SDC1     = (0x3D << 26),
110
    OPC_SDC2     = (0x3E << 26),
111
    /* MDMX ASE specific */
112
    OPC_MDMX     = (0x1E << 26),
113
    /* Cache and prefetch */
114
    OPC_CACHE    = (0x2F << 26),
115
    OPC_PREF     = (0x33 << 26),
116
    /* Reserved major opcode */
117
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
118
};
119

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

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

    
186
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
435
#include "gen-icount.h"
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
549
    if (from == 0)
550
        tcg_gen_movi_tl(r_tmp1, 0);
551
    else {
552
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
553
        TCGv_ptr addr = tcg_temp_new_ptr();
554

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

    
562
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
563
        tcg_temp_free_ptr(addr);
564
        tcg_temp_free_i32(r_tmp2);
565
    }
566
    gen_store_gpr(r_tmp1, to);
567
    tcg_temp_free(r_tmp1);
568
}
569

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

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

    
585
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
586
        tcg_temp_free_ptr(addr);
587
        tcg_temp_free_i32(r_tmp2);
588
        tcg_temp_free(r_tmp1);
589
    }
590
}
591

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
959
/* Load and store */
960
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
961
                      int base, int16_t offset)
962
{
963
    const char *opn = "ldst";
964
    TCGv t0 = tcg_temp_local_new();
965
    TCGv t1 = tcg_temp_local_new();
966

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

    
1122
/* Load and store */
1123
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1124
                          int base, int16_t offset)
1125
{
1126
    const char *opn = "flt_ldst";
1127
    TCGv 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
    switch (opc) {
1140
    case OPC_LWC1:
1141
        {
1142
            TCGv_i32 fp0 = tcg_temp_new_i32();
1143
            TCGv t1 = tcg_temp_new();
1144

    
1145
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1146
            tcg_gen_trunc_tl_i32(fp0, t1);
1147
            gen_store_fpr32(fp0, ft);
1148
            tcg_temp_free(t1);
1149
            tcg_temp_free_i32(fp0);
1150
        }
1151
        opn = "lwc1";
1152
        break;
1153
    case OPC_SWC1:
1154
        {
1155
            TCGv_i32 fp0 = tcg_temp_new_i32();
1156
            TCGv t1 = tcg_temp_new();
1157

    
1158
            gen_load_fpr32(fp0, ft);
1159
            tcg_gen_extu_i32_tl(t1, fp0);
1160
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1161
            tcg_temp_free(t1);
1162
            tcg_temp_free_i32(fp0);
1163
        }
1164
        opn = "swc1";
1165
        break;
1166
    case OPC_LDC1:
1167
        {
1168
            TCGv_i64 fp0 = tcg_temp_new_i64();
1169

    
1170
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1171
            gen_store_fpr64(ctx, fp0, ft);
1172
            tcg_temp_free_i64(fp0);
1173
        }
1174
        opn = "ldc1";
1175
        break;
1176
    case OPC_SDC1:
1177
        {
1178
            TCGv_i64 fp0 = tcg_temp_new_i64();
1179

    
1180
            gen_load_fpr64(ctx, fp0, ft);
1181
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1182
            tcg_temp_free_i64(fp0);
1183
        }
1184
        opn = "sdc1";
1185
        break;
1186
    default:
1187
        MIPS_INVAL(opn);
1188
        generate_exception(ctx, EXCP_RI);
1189
        goto out;
1190
    }
1191
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1192
 out:
1193
    tcg_temp_free(t0);
1194
}
1195

    
1196
/* Arithmetic with immediate operand */
1197
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1198
                           int rt, int rs, int16_t imm)
1199
{
1200
    target_ulong uimm;
1201
    const char *opn = "imm arith";
1202
    TCGv t0 = tcg_temp_local_new();
1203

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

    
1252
            save_cpu_state(ctx, 1);
1253
            tcg_gen_ext32s_tl(r_tmp1, t0);
1254
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1255

    
1256
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1257
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1258
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1259
            tcg_temp_free(r_tmp2);
1260
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1261
            /* operands of same sign, result different sign */
1262
            generate_exception(ctx, EXCP_OVERFLOW);
1263
            gen_set_label(l1);
1264
            tcg_temp_free(r_tmp1);
1265

    
1266
            tcg_gen_ext32s_tl(t0, t0);
1267
        }
1268
        opn = "addi";
1269
        break;
1270
    case OPC_ADDIU:
1271
        tcg_gen_addi_tl(t0, t0, uimm);
1272
        tcg_gen_ext32s_tl(t0, t0);
1273
        opn = "addiu";
1274
        break;
1275
#if defined(TARGET_MIPS64)
1276
    case OPC_DADDI:
1277
        {
1278
            TCGv r_tmp1 = tcg_temp_new();
1279
            TCGv r_tmp2 = tcg_temp_new();
1280
            int l1 = gen_new_label();
1281

    
1282
            save_cpu_state(ctx, 1);
1283
            tcg_gen_mov_tl(r_tmp1, t0);
1284
            tcg_gen_addi_tl(t0, t0, uimm);
1285

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

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

    
1450
/* Arithmetic */
1451
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1452
                       int rd, int rs, int rt)
1453
{
1454
    const char *opn = "arith";
1455
    TCGv t0 = tcg_temp_local_new();
1456
    TCGv t1 = tcg_temp_local_new();
1457

    
1458
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1459
       && opc != OPC_DADD && opc != OPC_DSUB) {
1460
        /* If no destination, treat it as a NOP.
1461
           For add & sub, we must generate the overflow exception when needed. */
1462
        MIPS_DEBUG("NOP");
1463
        goto out;
1464
    }
1465
    gen_load_gpr(t0, rs);
1466
    /* Specialcase the conventional move operation. */
1467
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1468
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1469
        gen_store_gpr(t0, rd);
1470
        goto out;
1471
    }
1472
    gen_load_gpr(t1, rt);
1473
    switch (opc) {
1474
    case OPC_ADD:
1475
        {
1476
            TCGv r_tmp1 = tcg_temp_new();
1477
            TCGv r_tmp2 = tcg_temp_new();
1478
            int l1 = gen_new_label();
1479

    
1480
            save_cpu_state(ctx, 1);
1481
            tcg_gen_ext32s_tl(r_tmp1, t0);
1482
            tcg_gen_ext32s_tl(r_tmp2, t1);
1483
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1484

    
1485
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1486
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1487
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1488
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1489
            tcg_temp_free(r_tmp2);
1490
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1491
            /* operands of same sign, result different sign */
1492
            generate_exception(ctx, EXCP_OVERFLOW);
1493
            gen_set_label(l1);
1494
            tcg_temp_free(r_tmp1);
1495

    
1496
            tcg_gen_ext32s_tl(t0, t0);
1497
        }
1498
        opn = "add";
1499
        break;
1500
    case OPC_ADDU:
1501
        tcg_gen_add_tl(t0, t0, t1);
1502
        tcg_gen_ext32s_tl(t0, t0);
1503
        opn = "addu";
1504
        break;
1505
    case OPC_SUB:
1506
        {
1507
            TCGv r_tmp1 = tcg_temp_new();
1508
            TCGv r_tmp2 = tcg_temp_new();
1509
            int l1 = gen_new_label();
1510

    
1511
            save_cpu_state(ctx, 1);
1512
            tcg_gen_ext32s_tl(r_tmp1, t0);
1513
            tcg_gen_ext32s_tl(r_tmp2, t1);
1514
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1515

    
1516
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1517
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1518
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1519
            tcg_temp_free(r_tmp2);
1520
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1521
            /* operands of different sign, first operand and result different sign */
1522
            generate_exception(ctx, EXCP_OVERFLOW);
1523
            gen_set_label(l1);
1524
            tcg_temp_free(r_tmp1);
1525

    
1526
            tcg_gen_ext32s_tl(t0, t0);
1527
        }
1528
        opn = "sub";
1529
        break;
1530
    case OPC_SUBU:
1531
        tcg_gen_sub_tl(t0, t0, t1);
1532
        tcg_gen_ext32s_tl(t0, t0);
1533
        opn = "subu";
1534
        break;
1535
#if defined(TARGET_MIPS64)
1536
    case OPC_DADD:
1537
        {
1538
            TCGv r_tmp1 = tcg_temp_new();
1539
            TCGv r_tmp2 = tcg_temp_new();
1540
            int l1 = gen_new_label();
1541

    
1542
            save_cpu_state(ctx, 1);
1543
            tcg_gen_mov_tl(r_tmp1, t0);
1544
            tcg_gen_add_tl(t0, t0, t1);
1545

    
1546
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1547
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1548
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1549
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1550
            tcg_temp_free(r_tmp2);
1551
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1552
            /* operands of same sign, result different sign */
1553
            generate_exception(ctx, EXCP_OVERFLOW);
1554
            gen_set_label(l1);
1555
            tcg_temp_free(r_tmp1);
1556
        }
1557
        opn = "dadd";
1558
        break;
1559
    case OPC_DADDU:
1560
        tcg_gen_add_tl(t0, t0, t1);
1561
        opn = "daddu";
1562
        break;
1563
    case OPC_DSUB:
1564
        {
1565
            TCGv r_tmp1 = tcg_temp_new();
1566
            TCGv r_tmp2 = tcg_temp_new();
1567
            int l1 = gen_new_label();
1568

    
1569
            save_cpu_state(ctx, 1);
1570
            tcg_gen_mov_tl(r_tmp1, t0);
1571
            tcg_gen_sub_tl(t0, t0, t1);
1572

    
1573
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1574
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1575
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1576
            tcg_temp_free(r_tmp2);
1577
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1578
            /* operands of different sign, first operand and result different sign */
1579
            generate_exception(ctx, EXCP_OVERFLOW);
1580
            gen_set_label(l1);
1581
            tcg_temp_free(r_tmp1);
1582
        }
1583
        opn = "dsub";
1584
        break;
1585
    case OPC_DSUBU:
1586
        tcg_gen_sub_tl(t0, t0, t1);
1587
        opn = "dsubu";
1588
        break;
1589
#endif
1590
    case OPC_SLT:
1591
        gen_op_lt(t0, t0, t1);
1592
        opn = "slt";
1593
        break;
1594
    case OPC_SLTU:
1595
        gen_op_ltu(t0, t0, t1);
1596
        opn = "sltu";
1597
        break;
1598
    case OPC_AND:
1599
        tcg_gen_and_tl(t0, t0, t1);
1600
        opn = "and";
1601
        break;
1602
    case OPC_NOR:
1603
        tcg_gen_nor_tl(t0, t0, t1);
1604
        opn = "nor";
1605
        break;
1606
    case OPC_OR:
1607
        tcg_gen_or_tl(t0, t0, t1);
1608
        opn = "or";
1609
        break;
1610
    case OPC_XOR:
1611
        tcg_gen_xor_tl(t0, t0, t1);
1612
        opn = "xor";
1613
        break;
1614
    case OPC_MUL:
1615
        tcg_gen_mul_tl(t0, t0, t1);
1616
        tcg_gen_ext32s_tl(t0, t0);
1617
        opn = "mul";
1618
        break;
1619
    case OPC_MOVN:
1620
        {
1621
            int l1 = gen_new_label();
1622

    
1623
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1624
            gen_store_gpr(t0, rd);
1625
            gen_set_label(l1);
1626
        }
1627
        opn = "movn";
1628
        goto print;
1629
    case OPC_MOVZ:
1630
        {
1631
            int l1 = gen_new_label();
1632

    
1633
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1634
            gen_store_gpr(t0, rd);
1635
            gen_set_label(l1);
1636
        }
1637
        opn = "movz";
1638
        goto print;
1639
    case OPC_SLLV:
1640
        tcg_gen_andi_tl(t0, t0, 0x1f);
1641
        tcg_gen_shl_tl(t0, t1, t0);
1642
        tcg_gen_ext32s_tl(t0, t0);
1643
        opn = "sllv";
1644
        break;
1645
    case OPC_SRAV:
1646
        tcg_gen_ext32s_tl(t1, t1);
1647
        tcg_gen_andi_tl(t0, t0, 0x1f);
1648
        tcg_gen_sar_tl(t0, t1, t0);
1649
        opn = "srav";
1650
        break;
1651
    case OPC_SRLV:
1652
        switch ((ctx->opcode >> 6) & 0x1f) {
1653
        case 0:
1654
            tcg_gen_ext32u_tl(t1, t1);
1655
            tcg_gen_andi_tl(t0, t0, 0x1f);
1656
            tcg_gen_shr_tl(t0, t1, t0);
1657
            tcg_gen_ext32s_tl(t0, t0);
1658
            opn = "srlv";
1659
            break;
1660
        case 1:
1661
            /* rotrv is decoded as srlv on non-R2 CPUs */
1662
            if (env->insn_flags & ISA_MIPS32R2) {
1663
                int l1 = gen_new_label();
1664
                int l2 = gen_new_label();
1665

    
1666
                tcg_gen_andi_tl(t0, t0, 0x1f);
1667
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1668
                {
1669
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1670
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1671

    
1672
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1673
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1674
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1675
                    tcg_temp_free_i32(r_tmp1);
1676
                    tcg_temp_free_i32(r_tmp2);
1677
                    tcg_gen_br(l2);
1678
                }
1679
                gen_set_label(l1);
1680
                tcg_gen_mov_tl(t0, t1);
1681
                gen_set_label(l2);
1682
                opn = "rotrv";
1683
            } else {
1684
                tcg_gen_ext32u_tl(t1, t1);
1685
                tcg_gen_andi_tl(t0, t0, 0x1f);
1686
                tcg_gen_shr_tl(t0, t1, t0);
1687
                tcg_gen_ext32s_tl(t0, t0);
1688
                opn = "srlv";
1689
            }
1690
            break;
1691
        default:
1692
            MIPS_INVAL("invalid srlv flag");
1693
            generate_exception(ctx, EXCP_RI);
1694
            break;
1695
        }
1696
        break;
1697
#if defined(TARGET_MIPS64)
1698
    case OPC_DSLLV:
1699
        tcg_gen_andi_tl(t0, t0, 0x3f);
1700
        tcg_gen_shl_tl(t0, t1, t0);
1701
        opn = "dsllv";
1702
        break;
1703
    case OPC_DSRAV:
1704
        tcg_gen_andi_tl(t0, t0, 0x3f);
1705
        tcg_gen_sar_tl(t0, t1, t0);
1706
        opn = "dsrav";
1707
        break;
1708
    case OPC_DSRLV:
1709
        switch ((ctx->opcode >> 6) & 0x1f) {
1710
        case 0:
1711
            tcg_gen_andi_tl(t0, t0, 0x3f);
1712
            tcg_gen_shr_tl(t0, t1, t0);
1713
            opn = "dsrlv";
1714
            break;
1715
        case 1:
1716
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1717
            if (env->insn_flags & ISA_MIPS32R2) {
1718
                int l1 = gen_new_label();
1719
                int l2 = gen_new_label();
1720

    
1721
                tcg_gen_andi_tl(t0, t0, 0x3f);
1722
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1723
                {
1724
                    tcg_gen_rotr_tl(t0, t1, t0);
1725
                    tcg_gen_br(l2);
1726
                }
1727
                gen_set_label(l1);
1728
                tcg_gen_mov_tl(t0, t1);
1729
                gen_set_label(l2);
1730
                opn = "drotrv";
1731
            } else {
1732
                tcg_gen_andi_tl(t0, t0, 0x3f);
1733
                tcg_gen_shr_tl(t0, t1, t0);
1734
                opn = "dsrlv";
1735
            }
1736
            break;
1737
        default:
1738
            MIPS_INVAL("invalid dsrlv flag");
1739
            generate_exception(ctx, EXCP_RI);
1740
            break;
1741
        }
1742
        break;
1743
#endif
1744
    default:
1745
        MIPS_INVAL(opn);
1746
        generate_exception(ctx, EXCP_RI);
1747
        goto out;
1748
    }
1749
    gen_store_gpr(t0, rd);
1750
 print:
1751
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1752
 out:
1753
    tcg_temp_free(t0);
1754
    tcg_temp_free(t1);
1755
}
1756

    
1757
/* Arithmetic on HI/LO registers */
1758
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1759
{
1760
    const char *opn = "hilo";
1761

    
1762
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1763
        /* Treat as NOP. */
1764
        MIPS_DEBUG("NOP");
1765
        return;
1766
    }
1767
    switch (opc) {
1768
    case OPC_MFHI:
1769
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1770
        opn = "mfhi";
1771
        break;
1772
    case OPC_MFLO:
1773
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1774
        opn = "mflo";
1775
        break;
1776
    case OPC_MTHI:
1777
        if (reg != 0)
1778
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1779
        else
1780
            tcg_gen_movi_tl(cpu_HI[0], 0);
1781
        opn = "mthi";
1782
        break;
1783
    case OPC_MTLO:
1784
        if (reg != 0)
1785
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1786
        else
1787
            tcg_gen_movi_tl(cpu_LO[0], 0);
1788
        opn = "mtlo";
1789
        break;
1790
    }
1791
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1792
}
1793

    
1794
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1795
                        int rs, int rt)
1796
{
1797
    const char *opn = "mul/div";
1798
    TCGv t0, t1;
1799

    
1800
    switch (opc) {
1801
    case OPC_DIV:
1802
    case OPC_DIVU:
1803
#if defined(TARGET_MIPS64)
1804
    case OPC_DDIV:
1805
    case OPC_DDIVU:
1806
#endif
1807
        t0 = tcg_temp_local_new();
1808
        t1 = tcg_temp_local_new();
1809
        break;
1810
    default:
1811
        t0 = tcg_temp_new();
1812
        t1 = tcg_temp_new();
1813
        break;
1814
    }
1815

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

    
1824
            tcg_gen_ext32s_tl(t0, t0);
1825
            tcg_gen_ext32s_tl(t1, t1);
1826
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1827
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1828
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1829

    
1830
            tcg_gen_mov_tl(cpu_LO[0], t0);
1831
            tcg_gen_movi_tl(cpu_HI[0], 0);
1832
            tcg_gen_br(l1);
1833
            gen_set_label(l2);
1834
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1835
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1836
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1837
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1838
            gen_set_label(l1);
1839
        }
1840
        opn = "div";
1841
        break;
1842
    case OPC_DIVU:
1843
        {
1844
            int l1 = gen_new_label();
1845

    
1846
            tcg_gen_ext32u_tl(t0, t0);
1847
            tcg_gen_ext32u_tl(t1, t1);
1848
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1849
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1850
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1851
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1852
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1853
            gen_set_label(l1);
1854
        }
1855
        opn = "divu";
1856
        break;
1857
    case OPC_MULT:
1858
        {
1859
            TCGv_i64 t2 = tcg_temp_new_i64();
1860
            TCGv_i64 t3 = tcg_temp_new_i64();
1861

    
1862
            tcg_gen_ext_tl_i64(t2, t0);
1863
            tcg_gen_ext_tl_i64(t3, t1);
1864
            tcg_gen_mul_i64(t2, t2, t3);
1865
            tcg_temp_free_i64(t3);
1866
            tcg_gen_trunc_i64_tl(t0, t2);
1867
            tcg_gen_shri_i64(t2, t2, 32);
1868
            tcg_gen_trunc_i64_tl(t1, t2);
1869
            tcg_temp_free_i64(t2);
1870
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1871
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1872
        }
1873
        opn = "mult";
1874
        break;
1875
    case OPC_MULTU:
1876
        {
1877
            TCGv_i64 t2 = tcg_temp_new_i64();
1878
            TCGv_i64 t3 = tcg_temp_new_i64();
1879

    
1880
            tcg_gen_ext32u_tl(t0, t0);
1881
            tcg_gen_ext32u_tl(t1, t1);
1882
            tcg_gen_extu_tl_i64(t2, t0);
1883
            tcg_gen_extu_tl_i64(t3, t1);
1884
            tcg_gen_mul_i64(t2, t2, t3);
1885
            tcg_temp_free_i64(t3);
1886
            tcg_gen_trunc_i64_tl(t0, t2);
1887
            tcg_gen_shri_i64(t2, t2, 32);
1888
            tcg_gen_trunc_i64_tl(t1, t2);
1889
            tcg_temp_free_i64(t2);
1890
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1891
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1892
        }
1893
        opn = "multu";
1894
        break;
1895
#if defined(TARGET_MIPS64)
1896
    case OPC_DDIV:
1897
        {
1898
            int l1 = gen_new_label();
1899
            int l2 = gen_new_label();
1900

    
1901
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1902
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1903
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1904
            tcg_gen_mov_tl(cpu_LO[0], t0);
1905
            tcg_gen_movi_tl(cpu_HI[0], 0);
1906
            tcg_gen_br(l1);
1907
            gen_set_label(l2);
1908
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
1909
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1910
            gen_set_label(l1);
1911
        }
1912
        opn = "ddiv";
1913
        break;
1914
    case OPC_DDIVU:
1915
        {
1916
            int l1 = gen_new_label();
1917

    
1918
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1919
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1920
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1921
            gen_set_label(l1);
1922
        }
1923
        opn = "ddivu";
1924
        break;
1925
    case OPC_DMULT:
1926
        gen_helper_dmult(t0, t1);
1927
        opn = "dmult";
1928
        break;
1929
    case OPC_DMULTU:
1930
        gen_helper_dmultu(t0, t1);
1931
        opn = "dmultu";
1932
        break;
1933
#endif
1934
    case OPC_MADD:
1935
        {
1936
            TCGv_i64 t2 = tcg_temp_new_i64();
1937
            TCGv_i64 t3 = tcg_temp_new_i64();
1938

    
1939
            tcg_gen_ext_tl_i64(t2, t0);
1940
            tcg_gen_ext_tl_i64(t3, t1);
1941
            tcg_gen_mul_i64(t2, t2, t3);
1942
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1943
            tcg_gen_add_i64(t2, t2, t3);
1944
            tcg_temp_free_i64(t3);
1945
            tcg_gen_trunc_i64_tl(t0, t2);
1946
            tcg_gen_shri_i64(t2, t2, 32);
1947
            tcg_gen_trunc_i64_tl(t1, t2);
1948
            tcg_temp_free_i64(t2);
1949
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1950
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1951
        }
1952
        opn = "madd";
1953
        break;
1954
    case OPC_MADDU:
1955
       {
1956
            TCGv_i64 t2 = tcg_temp_new_i64();
1957
            TCGv_i64 t3 = tcg_temp_new_i64();
1958

    
1959
            tcg_gen_ext32u_tl(t0, t0);
1960
            tcg_gen_ext32u_tl(t1, t1);
1961
            tcg_gen_extu_tl_i64(t2, t0);
1962
            tcg_gen_extu_tl_i64(t3, t1);
1963
            tcg_gen_mul_i64(t2, t2, t3);
1964
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1965
            tcg_gen_add_i64(t2, t2, t3);
1966
            tcg_temp_free_i64(t3);
1967
            tcg_gen_trunc_i64_tl(t0, t2);
1968
            tcg_gen_shri_i64(t2, t2, 32);
1969
            tcg_gen_trunc_i64_tl(t1, t2);
1970
            tcg_temp_free_i64(t2);
1971
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1972
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1973
        }
1974
        opn = "maddu";
1975
        break;
1976
    case OPC_MSUB:
1977
        {
1978
            TCGv_i64 t2 = tcg_temp_new_i64();
1979
            TCGv_i64 t3 = tcg_temp_new_i64();
1980

    
1981
            tcg_gen_ext_tl_i64(t2, t0);
1982
            tcg_gen_ext_tl_i64(t3, t1);
1983
            tcg_gen_mul_i64(t2, t2, t3);
1984
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1985
            tcg_gen_sub_i64(t2, t2, t3);
1986
            tcg_temp_free_i64(t3);
1987
            tcg_gen_trunc_i64_tl(t0, t2);
1988
            tcg_gen_shri_i64(t2, t2, 32);
1989
            tcg_gen_trunc_i64_tl(t1, t2);
1990
            tcg_temp_free_i64(t2);
1991
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1992
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1993
        }
1994
        opn = "msub";
1995
        break;
1996
    case OPC_MSUBU:
1997
        {
1998
            TCGv_i64 t2 = tcg_temp_new_i64();
1999
            TCGv_i64 t3 = tcg_temp_new_i64();
2000

    
2001
            tcg_gen_ext32u_tl(t0, t0);
2002
            tcg_gen_ext32u_tl(t1, t1);
2003
            tcg_gen_extu_tl_i64(t2, t0);
2004
            tcg_gen_extu_tl_i64(t3, t1);
2005
            tcg_gen_mul_i64(t2, t2, t3);
2006
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2007
            tcg_gen_sub_i64(t2, t2, t3);
2008
            tcg_temp_free_i64(t3);
2009
            tcg_gen_trunc_i64_tl(t0, t2);
2010
            tcg_gen_shri_i64(t2, t2, 32);
2011
            tcg_gen_trunc_i64_tl(t1, t2);
2012
            tcg_temp_free_i64(t2);
2013
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2014
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2015
        }
2016
        opn = "msubu";
2017
        break;
2018
    default:
2019
        MIPS_INVAL(opn);
2020
        generate_exception(ctx, EXCP_RI);
2021
        goto out;
2022
    }
2023
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2024
 out:
2025
    tcg_temp_free(t0);
2026
    tcg_temp_free(t1);
2027
}
2028

    
2029
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2030
                            int rd, int rs, int rt)
2031
{
2032
    const char *opn = "mul vr54xx";
2033
    TCGv t0 = tcg_temp_new();
2034
    TCGv t1 = tcg_temp_new();
2035

    
2036
    gen_load_gpr(t0, rs);
2037
    gen_load_gpr(t1, rt);
2038

    
2039
    switch (opc) {
2040
    case OPC_VR54XX_MULS:
2041
        gen_helper_muls(t0, t0, t1);
2042
        opn = "muls";
2043
        break;
2044
    case OPC_VR54XX_MULSU:
2045
        gen_helper_mulsu(t0, t0, t1);
2046
        opn = "mulsu";
2047
        break;
2048
    case OPC_VR54XX_MACC:
2049
        gen_helper_macc(t0, t0, t1);
2050
        opn = "macc";
2051
        break;
2052
    case OPC_VR54XX_MACCU:
2053
        gen_helper_maccu(t0, t0, t1);
2054
        opn = "maccu";
2055
        break;
2056
    case OPC_VR54XX_MSAC:
2057
        gen_helper_msac(t0, t0, t1);
2058
        opn = "msac";
2059
        break;
2060
    case OPC_VR54XX_MSACU:
2061
        gen_helper_msacu(t0, t0, t1);
2062
        opn = "msacu";
2063
        break;
2064
    case OPC_VR54XX_MULHI:
2065
        gen_helper_mulhi(t0, t0, t1);
2066
        opn = "mulhi";
2067
        break;
2068
    case OPC_VR54XX_MULHIU:
2069
        gen_helper_mulhiu(t0, t0, t1);
2070
        opn = "mulhiu";
2071
        break;
2072
    case OPC_VR54XX_MULSHI:
2073
        gen_helper_mulshi(t0, t0, t1);
2074
        opn = "mulshi";
2075
        break;
2076
    case OPC_VR54XX_MULSHIU:
2077
        gen_helper_mulshiu(t0, t0, t1);
2078
        opn = "mulshiu";
2079
        break;
2080
    case OPC_VR54XX_MACCHI:
2081
        gen_helper_macchi(t0, t0, t1);
2082
        opn = "macchi";
2083
        break;
2084
    case OPC_VR54XX_MACCHIU:
2085
        gen_helper_macchiu(t0, t0, t1);
2086
        opn = "macchiu";
2087
        break;
2088
    case OPC_VR54XX_MSACHI:
2089
        gen_helper_msachi(t0, t0, t1);
2090
        opn = "msachi";
2091
        break;
2092
    case OPC_VR54XX_MSACHIU:
2093
        gen_helper_msachiu(t0, t0, t1);
2094
        opn = "msachiu";
2095
        break;
2096
    default:
2097
        MIPS_INVAL("mul vr54xx");
2098
        generate_exception(ctx, EXCP_RI);
2099
        goto out;
2100
    }
2101
    gen_store_gpr(t0, rd);
2102
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2103

    
2104
 out:
2105
    tcg_temp_free(t0);
2106
    tcg_temp_free(t1);
2107
}
2108

    
2109
static void gen_cl (DisasContext *ctx, uint32_t opc,
2110
                    int rd, int rs)
2111
{
2112
    const char *opn = "CLx";
2113
    TCGv t0;
2114

    
2115
    if (rd == 0) {
2116
        /* Treat as NOP. */
2117
        MIPS_DEBUG("NOP");
2118
        return;
2119
    }
2120
    t0 = tcg_temp_new();
2121
    gen_load_gpr(t0, rs);
2122
    switch (opc) {
2123
    case OPC_CLO:
2124
        gen_helper_clo(cpu_gpr[rd], t0);
2125
        opn = "clo";
2126
        break;
2127
    case OPC_CLZ:
2128
        gen_helper_clz(cpu_gpr[rd], t0);
2129
        opn = "clz";
2130
        break;
2131
#if defined(TARGET_MIPS64)
2132
    case OPC_DCLO:
2133
        gen_helper_dclo(cpu_gpr[rd], t0);
2134
        opn = "dclo";
2135
        break;
2136
    case OPC_DCLZ:
2137
        gen_helper_dclz(cpu_gpr[rd], t0);
2138
        opn = "dclz";
2139
        break;
2140
#endif
2141
    }
2142
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2143
    tcg_temp_free(t0);
2144
}
2145

    
2146
/* Traps */
2147
static void gen_trap (DisasContext *ctx, uint32_t opc,
2148
                      int rs, int rt, int16_t imm)
2149
{
2150
    int cond;
2151
    TCGv t0 = tcg_temp_new();
2152
    TCGv t1 = tcg_temp_new();
2153

    
2154
    cond = 0;
2155
    /* Load needed operands */
2156
    switch (opc) {
2157
    case OPC_TEQ:
2158
    case OPC_TGE:
2159
    case OPC_TGEU:
2160
    case OPC_TLT:
2161
    case OPC_TLTU:
2162
    case OPC_TNE:
2163
        /* Compare two registers */
2164
        if (rs != rt) {
2165
            gen_load_gpr(t0, rs);
2166
            gen_load_gpr(t1, rt);
2167
            cond = 1;
2168
        }
2169
        break;
2170
    case OPC_TEQI:
2171
    case OPC_TGEI:
2172
    case OPC_TGEIU:
2173
    case OPC_TLTI:
2174
    case OPC_TLTIU:
2175
    case OPC_TNEI:
2176
        /* Compare register to immediate */
2177
        if (rs != 0 || imm != 0) {
2178
            gen_load_gpr(t0, rs);
2179
            tcg_gen_movi_tl(t1, (int32_t)imm);
2180
            cond = 1;
2181
        }
2182
        break;
2183
    }
2184
    if (cond == 0) {
2185
        switch (opc) {
2186
        case OPC_TEQ:   /* rs == rs */
2187
        case OPC_TEQI:  /* r0 == 0  */
2188
        case OPC_TGE:   /* rs >= rs */
2189
        case OPC_TGEI:  /* r0 >= 0  */
2190
        case OPC_TGEU:  /* rs >= rs unsigned */
2191
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2192
            /* Always trap */
2193
            generate_exception(ctx, EXCP_TRAP);
2194
            break;
2195
        case OPC_TLT:   /* rs < rs           */
2196
        case OPC_TLTI:  /* r0 < 0            */
2197
        case OPC_TLTU:  /* rs < rs unsigned  */
2198
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2199
        case OPC_TNE:   /* rs != rs          */
2200
        case OPC_TNEI:  /* r0 != 0           */
2201
            /* Never trap: treat as NOP. */
2202
            break;
2203
        }
2204
    } else {
2205
        int l1 = gen_new_label();
2206

    
2207
        switch (opc) {
2208
        case OPC_TEQ:
2209
        case OPC_TEQI:
2210
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2211
            break;
2212
        case OPC_TGE:
2213
        case OPC_TGEI:
2214
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2215
            break;
2216
        case OPC_TGEU:
2217
        case OPC_TGEIU:
2218
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2219
            break;
2220
        case OPC_TLT:
2221
        case OPC_TLTI:
2222
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2223
            break;
2224
        case OPC_TLTU:
2225
        case OPC_TLTIU:
2226
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2227
            break;
2228
        case OPC_TNE:
2229
        case OPC_TNEI:
2230
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2231
            break;
2232
        }
2233
        generate_exception(ctx, EXCP_TRAP);
2234
        gen_set_label(l1);
2235
    }
2236
    tcg_temp_free(t0);
2237
    tcg_temp_free(t1);
2238
}
2239

    
2240
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2241
{
2242
    TranslationBlock *tb;
2243
    tb = ctx->tb;
2244
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2245
        tcg_gen_goto_tb(n);
2246
        gen_save_pc(dest);
2247
        tcg_gen_exit_tb((long)tb + n);
2248
    } else {
2249
        gen_save_pc(dest);
2250
        tcg_gen_exit_tb(0);
2251
    }
2252
}
2253

    
2254
/* Branches (before delay slot) */
2255
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2256
                                int rs, int rt, int32_t offset)
2257
{
2258
    target_ulong btgt = -1;
2259
    int blink = 0;
2260
    int bcond_compute = 0;
2261
    TCGv t0 = tcg_temp_new();
2262
    TCGv t1 = tcg_temp_new();
2263

    
2264
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2265
#ifdef MIPS_DEBUG_DISAS
2266
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2267
#endif
2268
        generate_exception(ctx, EXCP_RI);
2269
        goto out;
2270
    }
2271

    
2272
    /* Load needed operands */
2273
    switch (opc) {
2274
    case OPC_BEQ:
2275
    case OPC_BEQL:
2276
    case OPC_BNE:
2277
    case OPC_BNEL:
2278
        /* Compare two registers */
2279
        if (rs != rt) {
2280
            gen_load_gpr(t0, rs);
2281
            gen_load_gpr(t1, rt);
2282
            bcond_compute = 1;
2283
        }
2284
        btgt = ctx->pc + 4 + offset;
2285
        break;
2286
    case OPC_BGEZ:
2287
    case OPC_BGEZAL:
2288
    case OPC_BGEZALL:
2289
    case OPC_BGEZL:
2290
    case OPC_BGTZ:
2291
    case OPC_BGTZL:
2292
    case OPC_BLEZ:
2293
    case OPC_BLEZL:
2294
    case OPC_BLTZ:
2295
    case OPC_BLTZAL:
2296
    case OPC_BLTZALL:
2297
    case OPC_BLTZL:
2298
        /* Compare to zero */
2299
        if (rs != 0) {
2300
            gen_load_gpr(t0, rs);
2301
            bcond_compute = 1;
2302
        }
2303
        btgt = ctx->pc + 4 + offset;
2304
        break;
2305
    case OPC_J:
2306
    case OPC_JAL:
2307
        /* Jump to immediate */
2308
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2309
        break;
2310
    case OPC_JR:
2311
    case OPC_JALR:
2312
        /* Jump to register */
2313
        if (offset != 0 && offset != 16) {
2314
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2315
               others are reserved. */
2316
            MIPS_INVAL("jump hint");
2317
            generate_exception(ctx, EXCP_RI);
2318
            goto out;
2319
        }
2320
        gen_load_gpr(btarget, rs);
2321
        break;
2322
    default:
2323
        MIPS_INVAL("branch/jump");
2324
        generate_exception(ctx, EXCP_RI);
2325
        goto out;
2326
    }
2327
    if (bcond_compute == 0) {
2328
        /* No condition to be computed */
2329
        switch (opc) {
2330
        case OPC_BEQ:     /* rx == rx        */
2331
        case OPC_BEQL:    /* rx == rx likely */
2332
        case OPC_BGEZ:    /* 0 >= 0          */
2333
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2334
        case OPC_BLEZ:    /* 0 <= 0          */
2335
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2336
            /* Always take */
2337
            ctx->hflags |= MIPS_HFLAG_B;
2338
            MIPS_DEBUG("balways");
2339
            break;
2340
        case OPC_BGEZAL:  /* 0 >= 0          */
2341
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2342
            /* Always take and link */
2343
            blink = 31;
2344
            ctx->hflags |= MIPS_HFLAG_B;
2345
            MIPS_DEBUG("balways and link");
2346
            break;
2347
        case OPC_BNE:     /* rx != rx        */
2348
        case OPC_BGTZ:    /* 0 > 0           */
2349
        case OPC_BLTZ:    /* 0 < 0           */
2350
            /* Treat as NOP. */
2351
            MIPS_DEBUG("bnever (NOP)");
2352
            goto out;
2353
        case OPC_BLTZAL:  /* 0 < 0           */
2354
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2355
            MIPS_DEBUG("bnever and link");
2356
            goto out;
2357
        case OPC_BLTZALL: /* 0 < 0 likely */
2358
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2359
            /* Skip the instruction in the delay slot */
2360
            MIPS_DEBUG("bnever, link and skip");
2361
            ctx->pc += 4;
2362
            goto out;
2363
        case OPC_BNEL:    /* rx != rx likely */
2364
        case OPC_BGTZL:   /* 0 > 0 likely */
2365
        case OPC_BLTZL:   /* 0 < 0 likely */
2366
            /* Skip the instruction in the delay slot */
2367
            MIPS_DEBUG("bnever and skip");
2368
            ctx->pc += 4;
2369
            goto out;
2370
        case OPC_J:
2371
            ctx->hflags |= MIPS_HFLAG_B;
2372
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2373
            break;
2374
        case OPC_JAL:
2375
            blink = 31;
2376
            ctx->hflags |= MIPS_HFLAG_B;
2377
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2378
            break;
2379
        case OPC_JR:
2380
            ctx->hflags |= MIPS_HFLAG_BR;
2381
            MIPS_DEBUG("jr %s", regnames[rs]);
2382
            break;
2383
        case OPC_JALR:
2384
            blink = rt;
2385
            ctx->hflags |= MIPS_HFLAG_BR;
2386
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2387
            break;
2388
        default:
2389
            MIPS_INVAL("branch/jump");
2390
            generate_exception(ctx, EXCP_RI);
2391
            goto out;
2392
        }
2393
    } else {
2394
        switch (opc) {
2395
        case OPC_BEQ:
2396
            gen_op_eq(bcond, t0, t1);
2397
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2398
                       regnames[rs], regnames[rt], btgt);
2399
            goto not_likely;
2400
        case OPC_BEQL:
2401
            gen_op_eq(bcond, t0, t1);
2402
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2403
                       regnames[rs], regnames[rt], btgt);
2404
            goto likely;
2405
        case OPC_BNE:
2406
            gen_op_ne(bcond, t0, t1);
2407
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2408
                       regnames[rs], regnames[rt], btgt);
2409
            goto not_likely;
2410
        case OPC_BNEL:
2411
            gen_op_ne(bcond, t0, t1);
2412
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2413
                       regnames[rs], regnames[rt], btgt);
2414
            goto likely;
2415
        case OPC_BGEZ:
2416
            gen_op_gez(bcond, t0);
2417
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2418
            goto not_likely;
2419
        case OPC_BGEZL:
2420
            gen_op_gez(bcond, t0);
2421
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2422
            goto likely;
2423
        case OPC_BGEZAL:
2424
            gen_op_gez(bcond, t0);
2425
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2426
            blink = 31;
2427
            goto not_likely;
2428
        case OPC_BGEZALL:
2429
            gen_op_gez(bcond, t0);
2430
            blink = 31;
2431
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2432
            goto likely;
2433
        case OPC_BGTZ:
2434
            gen_op_gtz(bcond, t0);
2435
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2436
            goto not_likely;
2437
        case OPC_BGTZL:
2438
            gen_op_gtz(bcond, t0);
2439
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2440
            goto likely;
2441
        case OPC_BLEZ:
2442
            gen_op_lez(bcond, t0);
2443
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2444
            goto not_likely;
2445
        case OPC_BLEZL:
2446
            gen_op_lez(bcond, t0);
2447
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2448
            goto likely;
2449
        case OPC_BLTZ:
2450
            gen_op_ltz(bcond, t0);
2451
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2452
            goto not_likely;
2453
        case OPC_BLTZL:
2454
            gen_op_ltz(bcond, t0);
2455
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2456
            goto likely;
2457
        case OPC_BLTZAL:
2458
            gen_op_ltz(bcond, t0);
2459
            blink = 31;
2460
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2461
        not_likely:
2462
            ctx->hflags |= MIPS_HFLAG_BC;
2463
            break;
2464
        case OPC_BLTZALL:
2465
            gen_op_ltz(bcond, t0);
2466
            blink = 31;
2467
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2468
        likely:
2469
            ctx->hflags |= MIPS_HFLAG_BL;
2470
            break;
2471
        default:
2472
            MIPS_INVAL("conditional branch/jump");
2473
            generate_exception(ctx, EXCP_RI);
2474
            goto out;
2475
        }
2476
    }
2477
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2478
               blink, ctx->hflags, btgt);
2479

    
2480
    ctx->btarget = btgt;
2481
    if (blink > 0) {
2482
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2483
    }
2484

    
2485
 out:
2486
    tcg_temp_free(t0);
2487
    tcg_temp_free(t1);
2488
}
2489

    
2490
/* special3 bitfield operations */
2491
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2492
                        int rs, int lsb, int msb)
2493
{
2494
    TCGv t0 = tcg_temp_new();
2495
    TCGv t1 = tcg_temp_new();
2496
    target_ulong mask;
2497

    
2498
    gen_load_gpr(t1, rs);
2499
    switch (opc) {
2500
    case OPC_EXT:
2501
        if (lsb + msb > 31)
2502
            goto fail;
2503
        tcg_gen_shri_tl(t0, t1, lsb);
2504
        if (msb != 31) {
2505
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2506
        } else {
2507
            tcg_gen_ext32s_tl(t0, t0);
2508
        }
2509
        break;
2510
#if defined(TARGET_MIPS64)
2511
    case OPC_DEXTM:
2512
        tcg_gen_shri_tl(t0, t1, lsb);
2513
        if (msb != 31) {
2514
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2515
        }
2516
        break;
2517
    case OPC_DEXTU:
2518
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2519
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2520
        break;
2521
    case OPC_DEXT:
2522
        tcg_gen_shri_tl(t0, t1, lsb);
2523
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2524
        break;
2525
#endif
2526
    case OPC_INS:
2527
        if (lsb > msb)
2528
            goto fail;
2529
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2530
        gen_load_gpr(t0, rt);
2531
        tcg_gen_andi_tl(t0, t0, ~mask);
2532
        tcg_gen_shli_tl(t1, t1, lsb);
2533
        tcg_gen_andi_tl(t1, t1, mask);
2534
        tcg_gen_or_tl(t0, t0, t1);
2535
        tcg_gen_ext32s_tl(t0, t0);
2536
        break;
2537
#if defined(TARGET_MIPS64)
2538
    case OPC_DINSM:
2539
        if (lsb > msb)
2540
            goto fail;
2541
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2542
        gen_load_gpr(t0, rt);
2543
        tcg_gen_andi_tl(t0, t0, ~mask);
2544
        tcg_gen_shli_tl(t1, t1, lsb);
2545
        tcg_gen_andi_tl(t1, t1, mask);
2546
        tcg_gen_or_tl(t0, t0, t1);
2547
        break;
2548
    case OPC_DINSU:
2549
        if (lsb > msb)
2550
            goto fail;
2551
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2552
        gen_load_gpr(t0, rt);
2553
        tcg_gen_andi_tl(t0, t0, ~mask);
2554
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2555
        tcg_gen_andi_tl(t1, t1, mask);
2556
        tcg_gen_or_tl(t0, t0, t1);
2557
        break;
2558
    case OPC_DINS:
2559
        if (lsb > msb)
2560
            goto fail;
2561
        gen_load_gpr(t0, rt);
2562
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2563
        gen_load_gpr(t0, rt);
2564
        tcg_gen_andi_tl(t0, t0, ~mask);
2565
        tcg_gen_shli_tl(t1, t1, lsb);
2566
        tcg_gen_andi_tl(t1, t1, mask);
2567
        tcg_gen_or_tl(t0, t0, t1);
2568
        break;
2569
#endif
2570
    default:
2571
fail:
2572
        MIPS_INVAL("bitops");
2573
        generate_exception(ctx, EXCP_RI);
2574
        tcg_temp_free(t0);
2575
        tcg_temp_free(t1);
2576
        return;
2577
    }
2578
    gen_store_gpr(t0, rt);
2579
    tcg_temp_free(t0);
2580
    tcg_temp_free(t1);
2581
}
2582

    
2583
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2584
{
2585
    TCGv t0;
2586

    
2587
    if (rd == 0) {
2588
        /* If no destination, treat it as a NOP. */
2589
        MIPS_DEBUG("NOP");
2590
        return;
2591
    }
2592

    
2593
    t0 = tcg_temp_new();
2594
    gen_load_gpr(t0, rt);
2595
    switch (op2) {
2596
    case OPC_WSBH:
2597
        {
2598
            TCGv t1 = tcg_temp_new();
2599

    
2600
            tcg_gen_shri_tl(t1, t0, 8);
2601
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2602
            tcg_gen_shli_tl(t0, t0, 8);
2603
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2604
            tcg_gen_or_tl(t0, t0, t1);
2605
            tcg_temp_free(t1);
2606
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2607
        }
2608
        break;
2609
    case OPC_SEB:
2610
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2611
        break;
2612
    case OPC_SEH:
2613
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2614
        break;
2615
#if defined(TARGET_MIPS64)
2616
    case OPC_DSBH:
2617
        {
2618
            TCGv t1 = tcg_temp_new();
2619

    
2620
            tcg_gen_shri_tl(t1, t0, 8);
2621
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2622
            tcg_gen_shli_tl(t0, t0, 8);
2623
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2624
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2625
            tcg_temp_free(t1);
2626
        }
2627
        break;
2628
    case OPC_DSHD:
2629
        {
2630
            TCGv t1 = tcg_temp_new();
2631

    
2632
            tcg_gen_shri_tl(t1, t0, 16);
2633
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2634
            tcg_gen_shli_tl(t0, t0, 16);
2635
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2636
            tcg_gen_or_tl(t0, t0, t1);
2637
            tcg_gen_shri_tl(t1, t0, 32);
2638
            tcg_gen_shli_tl(t0, t0, 32);
2639
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2640
            tcg_temp_free(t1);
2641
        }
2642
        break;
2643
#endif
2644
    default:
2645
        MIPS_INVAL("bsfhl");
2646
        generate_exception(ctx, EXCP_RI);
2647
        tcg_temp_free(t0);
2648
        return;
2649
    }
2650
    tcg_temp_free(t0);
2651
}
2652

    
2653
#ifndef CONFIG_USER_ONLY
2654
/* CP0 (MMU and control) */
2655
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2656
{
2657
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2658

    
2659
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2660
    tcg_gen_ext_i32_tl(t, r_tmp);
2661
    tcg_temp_free_i32(r_tmp);
2662
}
2663

    
2664
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2665
{
2666
    tcg_gen_ld_tl(t, cpu_env, off);
2667
    tcg_gen_ext32s_tl(t, t);
2668
}
2669

    
2670
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2671
{
2672
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2673

    
2674
    tcg_gen_trunc_tl_i32(r_tmp, t);
2675
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2676
    tcg_temp_free_i32(r_tmp);
2677
}
2678

    
2679
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2680
{
2681
    tcg_gen_ext32s_tl(t, t);
2682
    tcg_gen_st_tl(t, cpu_env, off);
2683
}
2684

    
2685
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2686
{
2687
    const char *rn = "invalid";
2688

    
2689
    if (sel != 0)
2690
        check_insn(env, ctx, ISA_MIPS32);
2691

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

    
3257
die:
3258
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3259
    generate_exception(ctx, EXCP_RI);
3260
}
3261

    
3262
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3263
{
3264
    const char *rn = "invalid";
3265

    
3266
    if (sel != 0)
3267
        check_insn(env, ctx, ISA_MIPS32);
3268

    
3269
    if (use_icount)
3270
        gen_io_start();
3271

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

    
3850
die:
3851
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3852
    generate_exception(ctx, EXCP_RI);
3853
}
3854

    
3855
#if defined(TARGET_MIPS64)
3856
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3857
{
3858
    const char *rn = "invalid";
3859

    
3860
    if (sel != 0)
3861
        check_insn(env, ctx, ISA_MIPS64);
3862

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

    
4417
die:
4418
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4419
    generate_exception(ctx, EXCP_RI);
4420
}
4421

    
4422
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4423
{
4424
    const char *rn = "invalid";
4425

    
4426
    if (sel != 0)
4427
        check_insn(env, ctx, ISA_MIPS64);
4428

    
4429
    if (use_icount)
4430
        gen_io_start();
4431

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

    
5003
die:
5004
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5005
    generate_exception(ctx, EXCP_RI);
5006
}
5007
#endif /* TARGET_MIPS64 */
5008

    
5009
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5010
                     int u, int sel, int h)
5011
{
5012
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5013
    TCGv t0 = tcg_temp_local_new();
5014

    
5015
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5016
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5017
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5018
        tcg_gen_movi_tl(t0, -1);
5019
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5020
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5021
        tcg_gen_movi_tl(t0, -1);
5022
    else if (u == 0) {
5023
        switch (rt) {
5024
        case 2:
5025
            switch (sel) {
5026
            case 1:
5027
                gen_helper_mftc0_tcstatus(t0);
5028
                break;
5029
            case 2:
5030
                gen_helper_mftc0_tcbind(t0);
5031
                break;
5032
            case 3:
5033
                gen_helper_mftc0_tcrestart(t0);
5034
                break;
5035
            case 4:
5036
                gen_helper_mftc0_tchalt(t0);
5037
                break;
5038
            case 5:
5039
                gen_helper_mftc0_tccontext(t0);
5040
                break;
5041
            case 6:
5042
                gen_helper_mftc0_tcschedule(t0);
5043
                break;
5044
            case 7:
5045
                gen_helper_mftc0_tcschefback(t0);
5046
                break;
5047
            default:
5048
                gen_mfc0(env, ctx, t0, rt, sel);
5049
                break;
5050
            }
5051
            break;
5052
        case 10:
5053
            switch (sel) {
5054
            case 0:
5055
                gen_helper_mftc0_entryhi(t0);
5056
                break;
5057
            default:
5058
                gen_mfc0(env, ctx, t0, rt, sel);
5059
                break;
5060
            }
5061
        case 12:
5062
            switch (sel) {
5063
            case 0:
5064
                gen_helper_mftc0_status(t0);
5065
                break;
5066
            default:
5067
                gen_mfc0(env, ctx, t0, rt, sel);
5068
                break;
5069
            }
5070
        case 23:
5071
            switch (sel) {
5072
            case 0:
5073
                gen_helper_mftc0_debug(t0);
5074
                break;
5075
            default:
5076
                gen_mfc0(env, ctx, t0, rt, sel);
5077
                break;
5078
            }
5079
            break;
5080
        default:
5081
            gen_mfc0(env, ctx, t0, rt, sel);
5082
        }
5083
    } else switch (sel) {
5084
    /* GPR registers. */
5085
    case 0:
5086
        gen_helper_1i(mftgpr, t0, rt);
5087
        break;
5088
    /* Auxiliary CPU registers */
5089
    case 1:
5090
        switch (rt) {
5091
        case 0:
5092
            gen_helper_1i(mftlo, t0, 0);
5093
            break;
5094
        case 1:
5095
            gen_helper_1i(mfthi, t0, 0);
5096
            break;
5097
        case 2:
5098
            gen_helper_1i(mftacx, t0, 0);
5099
            break;
5100
        case 4:
5101
            gen_helper_1i(mftlo, t0, 1);
5102
            break;
5103
        case 5:
5104
            gen_helper_1i(mfthi, t0, 1);
5105
            break;
5106
        case 6:
5107
            gen_helper_1i(mftacx, t0, 1);
5108
            break;
5109
        case 8:
5110
            gen_helper_1i(mftlo, t0, 2);
5111
            break;
5112
        case 9:
5113
            gen_helper_1i(mfthi, t0, 2);
5114
            break;
5115
        case 10:
5116
            gen_helper_1i(mftacx, t0, 2);
5117
            break;
5118
        case 12:
5119
            gen_helper_1i(mftlo, t0, 3);
5120
            break;
5121
        case 13:
5122
            gen_helper_1i(mfthi, t0, 3);
5123
            break;
5124
        case 14:
5125
            gen_helper_1i(mftacx, t0, 3);
5126
            break;
5127
        case 16:
5128
            gen_helper_mftdsp(t0);
5129
            break;
5130
        default:
5131
            goto die;
5132
        }
5133
        break;
5134
    /* Floating point (COP1). */
5135
    case 2:
5136
        /* XXX: For now we support only a single FPU context. */
5137
        if (h == 0) {
5138
            TCGv_i32 fp0 = tcg_temp_new_i32();
5139

    
5140
            gen_load_fpr32(fp0, rt);
5141
            tcg_gen_ext_i32_tl(t0, fp0);
5142
            tcg_temp_free_i32(fp0);
5143
        } else {
5144
            TCGv_i32 fp0 = tcg_temp_new_i32();
5145

    
5146
            gen_load_fpr32h(fp0, rt);
5147
            tcg_gen_ext_i32_tl(t0, fp0);
5148
            tcg_temp_free_i32(fp0);
5149
        }
5150
        break;
5151
    case 3:
5152
        /* XXX: For now we support only a single FPU context. */
5153
        gen_helper_1i(cfc1, t0, rt);
5154
        break;
5155
    /* COP2: Not implemented. */
5156
    case 4:
5157
    case 5:
5158
        /* fall through */
5159
    default:
5160
        goto die;
5161
    }
5162
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5163
    gen_store_gpr(t0, rd);
5164
    tcg_temp_free(t0);
5165
    return;
5166

    
5167
die:
5168
    tcg_temp_free(t0);
5169
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5170
    generate_exception(ctx, EXCP_RI);
5171
}
5172

    
5173
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5174
                     int u, int sel, int h)
5175
{
5176
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5177
    TCGv t0 = tcg_temp_local_new();
5178

    
5179
    gen_load_gpr(t0, rt);
5180
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5181
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5182
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5183
        /* NOP */ ;
5184
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5185
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5186
        /* NOP */ ;
5187
    else if (u == 0) {
5188
        switch (rd) {
5189
        case 2:
5190
            switch (sel) {
5191
            case 1:
5192
                gen_helper_mttc0_tcstatus(t0);
5193
                break;
5194
            case 2:
5195
                gen_helper_mttc0_tcbind(t0);
5196
                break;
5197
            case 3:
5198
                gen_helper_mttc0_tcrestart(t0);
5199
                break;
5200
            case 4:
5201
                gen_helper_mttc0_tchalt(t0);
5202
                break;
5203
            case 5:
5204
                gen_helper_mttc0_tccontext(t0);
5205
                break;
5206
            case 6:
5207
                gen_helper_mttc0_tcschedule(t0);
5208
                break;
5209
            case 7:
5210
                gen_helper_mttc0_tcschefback(t0);
5211
                break;
5212
            default:
5213
                gen_mtc0(env, ctx, t0, rd, sel);
5214
                break;
5215
            }
5216
            break;
5217
        case 10:
5218
            switch (sel) {
5219
            case 0:
5220
                gen_helper_mttc0_entryhi(t0);
5221
                break;
5222
            default:
5223
                gen_mtc0(env, ctx, t0, rd, sel);
5224
                break;
5225
            }
5226
        case 12:
5227
            switch (sel) {
5228
            case 0:
5229
                gen_helper_mttc0_status(t0);
5230
                break;
5231
            default:
5232
                gen_mtc0(env, ctx, t0, rd, sel);
5233
                break;
5234
            }
5235
        case 23:
5236
            switch (sel) {
5237
            case 0:
5238
                gen_helper_mttc0_debug(t0);
5239
                break;
5240
            default:
5241
                gen_mtc0(env, ctx, t0, rd, sel);
5242
                break;
5243
            }
5244
            break;
5245
        default:
5246
            gen_mtc0(env, ctx, t0, rd, sel);
5247
        }
5248
    } else switch (sel) {
5249
    /* GPR registers. */
5250
    case 0:
5251
        gen_helper_1i(mttgpr, t0, rd);
5252
        break;
5253
    /* Auxiliary CPU registers */
5254
    case 1:
5255
        switch (rd) {
5256
        case 0:
5257
            gen_helper_1i(mttlo, t0, 0);
5258
            break;
5259
        case 1:
5260
            gen_helper_1i(mtthi, t0, 0);
5261
            break;
5262
        case 2:
5263
            gen_helper_1i(mttacx, t0, 0);
5264
            break;
5265
        case 4:
5266
            gen_helper_1i(mttlo, t0, 1);
5267
            break;
5268
        case 5:
5269
            gen_helper_1i(mtthi, t0, 1);
5270
            break;
5271
        case 6:
5272
            gen_helper_1i(mttacx, t0, 1);
5273
            break;
5274
        case 8:
5275
            gen_helper_1i(mttlo, t0, 2);
5276
            break;
5277
        case 9:
5278
            gen_helper_1i(mtthi, t0, 2);
5279
            break;
5280
        case 10:
5281
            gen_helper_1i(mttacx, t0, 2);
5282
            break;
5283
        case 12:
5284
            gen_helper_1i(mttlo, t0, 3);
5285
            break;
5286
        case 13:
5287
            gen_helper_1i(mtthi, t0, 3);
5288
            break;
5289
        case 14:
5290
            gen_helper_1i(mttacx, t0, 3);
5291
            break;
5292
        case 16:
5293
            gen_helper_mttdsp(t0);
5294
            break;
5295
        default:
5296
            goto die;
5297
        }
5298
        break;
5299
    /* Floating point (COP1). */
5300
    case 2:
5301
        /* XXX: For now we support only a single FPU context. */
5302
        if (h == 0) {
5303
            TCGv_i32 fp0 = tcg_temp_new_i32();
5304

    
5305
            tcg_gen_trunc_tl_i32(fp0, t0);
5306
            gen_store_fpr32(fp0, rd);
5307
            tcg_temp_free_i32(fp0);
5308
        } else {
5309
            TCGv_i32 fp0 = tcg_temp_new_i32();
5310

    
5311
            tcg_gen_trunc_tl_i32(fp0, t0);
5312
            gen_store_fpr32h(fp0, rd);
5313
            tcg_temp_free_i32(fp0);
5314
        }
5315
        break;
5316
    case 3:
5317
        /* XXX: For now we support only a single FPU context. */
5318
        gen_helper_1i(ctc1, t0, rd);
5319
        break;
5320
    /* COP2: Not implemented. */
5321
    case 4:
5322
    case 5:
5323
        /* fall through */
5324
    default:
5325
        goto die;
5326
    }
5327
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5328
    tcg_temp_free(t0);
5329
    return;
5330

    
5331
die:
5332
    tcg_temp_free(t0);
5333
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5334
    generate_exception(ctx, EXCP_RI);
5335
}
5336

    
5337
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5338
{
5339
    const char *opn = "ldst";
5340

    
5341
    switch (opc) {
5342
    case OPC_MFC0:
5343
        if (rt == 0) {
5344
            /* Treat as NOP. */
5345
            return;
5346
        }
5347
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5348
        opn = "mfc0";
5349
        break;
5350
    case OPC_MTC0:
5351
        {
5352
            TCGv t0 = tcg_temp_new();
5353

    
5354
            gen_load_gpr(t0, rt);
5355
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5356
            tcg_temp_free(t0);
5357
        }
5358
        opn = "mtc0";
5359
        break;
5360
#if defined(TARGET_MIPS64)
5361
    case OPC_DMFC0:
5362
        check_insn(env, ctx, ISA_MIPS3);
5363
        if (rt == 0) {
5364
            /* Treat as NOP. */
5365
            return;
5366
        }
5367
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5368
        opn = "dmfc0";
5369
        break;
5370
    case OPC_DMTC0:
5371
        check_insn(env, ctx, ISA_MIPS3);
5372
        {
5373
            TCGv t0 = tcg_temp_new();
5374

    
5375
            gen_load_gpr(t0, rt);
5376
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5377
            tcg_temp_free(t0);
5378
        }
5379
        opn = "dmtc0";
5380
        break;
5381
#endif
5382
    case OPC_MFTR:
5383
        check_insn(env, ctx, ASE_MT);
5384
        if (rd == 0) {
5385
            /* Treat as NOP. */
5386
            return;
5387
        }
5388
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5389
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5390
        opn = "mftr";
5391
        break;
5392
    case OPC_MTTR:
5393
        check_insn(env, ctx, ASE_MT);
5394
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5395
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5396
        opn = "mttr";
5397
        break;
5398
    case OPC_TLBWI:
5399
        opn = "tlbwi";
5400
        if (!env->tlb->helper_tlbwi)
5401
            goto die;
5402
        gen_helper_tlbwi();
5403
        break;
5404
    case OPC_TLBWR:
5405
        opn = "tlbwr";
5406
        if (!env->tlb->helper_tlbwr)
5407
            goto die;
5408
        gen_helper_tlbwr();
5409
        break;
5410
    case OPC_TLBP:
5411
        opn = "tlbp";
5412
        if (!env->tlb->helper_tlbp)
5413
            goto die;
5414
        gen_helper_tlbp();
5415
        break;
5416
    case OPC_TLBR:
5417
        opn = "tlbr";
5418
        if (!env->tlb->helper_tlbr)
5419
            goto die;
5420
        gen_helper_tlbr();
5421
        break;
5422
    case OPC_ERET:
5423
        opn = "eret";
5424
        check_insn(env, ctx, ISA_MIPS2);
5425
        gen_helper_eret();
5426
        ctx->bstate = BS_EXCP;
5427
        break;
5428
    case OPC_DERET:
5429
        opn = "deret";
5430
        check_insn(env, ctx, ISA_MIPS32);
5431
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5432
            MIPS_INVAL(opn);
5433
            generate_exception(ctx, EXCP_RI);
5434
        } else {
5435
            gen_helper_deret();
5436
            ctx->bstate = BS_EXCP;
5437
        }
5438
        break;
5439
    case OPC_WAIT:
5440
        opn = "wait";
5441
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5442
        /* If we get an exception, we want to restart at next instruction */
5443
        ctx->pc += 4;
5444
        save_cpu_state(ctx, 1);
5445
        ctx->pc -= 4;
5446
        gen_helper_wait();
5447
        ctx->bstate = BS_EXCP;
5448
        break;
5449
    default:
5450
 die:
5451
        MIPS_INVAL(opn);
5452
        generate_exception(ctx, EXCP_RI);
5453
        return;
5454
    }
5455
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5456
}
5457
#endif /* !CONFIG_USER_ONLY */
5458

    
5459
/* CP1 Branches (before delay slot) */
5460
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5461
                                 int32_t cc, int32_t offset)
5462
{
5463
    target_ulong btarget;
5464
    const char *opn = "cp1 cond branch";
5465
    TCGv_i32 t0 = tcg_temp_new_i32();
5466

    
5467
    if (cc != 0)
5468
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5469

    
5470
    btarget = ctx->pc + 4 + offset;
5471

    
5472
    switch (op) {
5473
    case OPC_BC1F:
5474
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5475
        tcg_gen_not_i32(t0, t0);
5476
        tcg_gen_andi_i32(t0, t0, 1);
5477
        tcg_gen_extu_i32_tl(bcond, t0);
5478
        opn = "bc1f";
5479
        goto not_likely;
5480
    case OPC_BC1FL:
5481
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5482
        tcg_gen_not_i32(t0, t0);
5483
        tcg_gen_andi_i32(t0, t0, 1);
5484
        tcg_gen_extu_i32_tl(bcond, t0);
5485
        opn = "bc1fl";
5486
        goto likely;
5487
    case OPC_BC1T:
5488
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5489
        tcg_gen_andi_i32(t0, t0, 1);
5490
        tcg_gen_extu_i32_tl(bcond, t0);
5491
        opn = "bc1t";
5492
        goto not_likely;
5493
    case OPC_BC1TL:
5494
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5495
        tcg_gen_andi_i32(t0, t0, 1);
5496
        tcg_gen_extu_i32_tl(bcond, t0);
5497
        opn = "bc1tl";
5498
    likely:
5499
        ctx->hflags |= MIPS_HFLAG_BL;
5500
        break;
5501
    case OPC_BC1FANY2:
5502
        {
5503
            TCGv_i32 t1 = tcg_temp_new_i32();
5504
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5505
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5506
            tcg_gen_or_i32(t0, t0, t1);
5507
            tcg_temp_free_i32(t1);
5508
            tcg_gen_not_i32(t0, t0);
5509
            tcg_gen_andi_i32(t0, t0, 1);
5510
            tcg_gen_extu_i32_tl(bcond, t0);
5511
        }
5512
        opn = "bc1any2f";
5513
        goto not_likely;
5514
    case OPC_BC1TANY2:
5515
        {
5516
            TCGv_i32 t1 = tcg_temp_new_i32();
5517
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5518
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5519
            tcg_gen_or_i32(t0, t0, t1);
5520
            tcg_temp_free_i32(t1);
5521
            tcg_gen_andi_i32(t0, t0, 1);
5522
            tcg_gen_extu_i32_tl(bcond, t0);
5523
        }
5524
        opn = "bc1any2t";
5525
        goto not_likely;
5526
    case OPC_BC1FANY4:
5527
        {
5528
            TCGv_i32 t1 = tcg_temp_new_i32();
5529
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5530
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5531
            tcg_gen_or_i32(t0, t0, t1);
5532
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5533
            tcg_gen_or_i32(t0, t0, t1);
5534
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5535
            tcg_gen_or_i32(t0, t0, t1);
5536
            tcg_temp_free_i32(t1);
5537
            tcg_gen_not_i32(t0, t0);
5538
            tcg_gen_andi_i32(t0, t0, 1);
5539
            tcg_gen_extu_i32_tl(bcond, t0);
5540
        }
5541
        opn = "bc1any4f";
5542
        goto not_likely;
5543
    case OPC_BC1TANY4:
5544
        {
5545
            TCGv_i32 t1 = tcg_temp_new_i32();
5546
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5547
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5548
            tcg_gen_or_i32(t0, t0, t1);
5549
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5550
            tcg_gen_or_i32(t0, t0, t1);
5551
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5552
            tcg_gen_or_i32(t0, t0, t1);
5553
            tcg_temp_free_i32(t1);
5554
            tcg_gen_andi_i32(t0, t0, 1);
5555
            tcg_gen_extu_i32_tl(bcond, t0);
5556
        }
5557
        opn = "bc1any4t";
5558
    not_likely:
5559
        ctx->hflags |= MIPS_HFLAG_BC;
5560
        break;
5561
    default:
5562
        MIPS_INVAL(opn);
5563
        generate_exception (ctx, EXCP_RI);
5564
        goto out;
5565
    }
5566
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5567
               ctx->hflags, btarget);
5568
    ctx->btarget = btarget;
5569

    
5570
 out:
5571
    tcg_temp_free_i32(t0);
5572
}
5573

    
5574
/* Coprocessor 1 (FPU) */
5575

    
5576
#define FOP(func, fmt) (((fmt) << 21) | (func))
5577

    
5578
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5579
{
5580
    const char *opn = "cp1 move";
5581
    TCGv t0 = tcg_temp_local_new();
5582

    
5583
    switch (opc) {
5584
    case OPC_MFC1:
5585
        {
5586
            TCGv_i32 fp0 = tcg_temp_new_i32();
5587

    
5588
            gen_load_fpr32(fp0, fs);
5589
            tcg_gen_ext_i32_tl(t0, fp0);
5590
            tcg_temp_free_i32(fp0);
5591
        }
5592
        gen_store_gpr(t0, rt);
5593
        opn = "mfc1";
5594
        break;
5595
    case OPC_MTC1:
5596
        gen_load_gpr(t0, rt);
5597
        {
5598
            TCGv_i32 fp0 = tcg_temp_new_i32();
5599

    
5600
            tcg_gen_trunc_tl_i32(fp0, t0);
5601
            gen_store_fpr32(fp0, fs);
5602
            tcg_temp_free_i32(fp0);
5603
        }
5604
        opn = "mtc1";
5605
        break;
5606
    case OPC_CFC1:
5607
        gen_helper_1i(cfc1, t0, fs);
5608
        gen_store_gpr(t0, rt);
5609
        opn = "cfc1";
5610
        break;
5611
    case OPC_CTC1:
5612
        gen_load_gpr(t0, rt);
5613
        gen_helper_1i(ctc1, t0, fs);
5614
        opn = "ctc1";
5615
        break;
5616
    case OPC_DMFC1:
5617
        {
5618
            TCGv_i64 fp0 = tcg_temp_new_i64();
5619

    
5620
            gen_load_fpr64(ctx, fp0, fs);
5621
            tcg_gen_trunc_i64_tl(t0, fp0);
5622
            tcg_temp_free_i64(fp0);
5623
        }
5624
        gen_store_gpr(t0, rt);
5625
        opn = "dmfc1";
5626
        break;
5627
    case OPC_DMTC1:
5628
        gen_load_gpr(t0, rt);
5629
        {
5630
            TCGv_i64 fp0 = tcg_temp_new_i64();
5631

    
5632
            tcg_gen_extu_tl_i64(fp0, t0);
5633
            gen_store_fpr64(ctx, fp0, fs);
5634
            tcg_temp_free_i64(fp0);
5635
        }
5636
        opn = "dmtc1";
5637
        break;
5638
    case OPC_MFHC1:
5639
        {
5640
            TCGv_i32 fp0 = tcg_temp_new_i32();
5641

    
5642
            gen_load_fpr32h(fp0, fs);
5643
            tcg_gen_ext_i32_tl(t0, fp0);
5644
            tcg_temp_free_i32(fp0);
5645
        }
5646
        gen_store_gpr(t0, rt);
5647
        opn = "mfhc1";
5648
        break;
5649
    case OPC_MTHC1:
5650
        gen_load_gpr(t0, rt);
5651
        {
5652
            TCGv_i32 fp0 = tcg_temp_new_i32();
5653

    
5654
            tcg_gen_trunc_tl_i32(fp0, t0);
5655
            gen_store_fpr32h(fp0, fs);
5656
            tcg_temp_free_i32(fp0);
5657
        }
5658
        opn = "mthc1";
5659
        break;
5660
    default:
5661
        MIPS_INVAL(opn);
5662
        generate_exception (ctx, EXCP_RI);
5663
        goto out;
5664
    }
5665
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5666

    
5667
 out:
5668
    tcg_temp_free(t0);
5669
}
5670

    
5671
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5672
{
5673
    int l1;
5674
    TCGCond cond;
5675
    TCGv_i32 t0;
5676

    
5677
    if (rd == 0) {
5678
        /* Treat as NOP. */
5679
        return;
5680
    }
5681

    
5682
    if (tf)
5683
        cond = TCG_COND_EQ;
5684
    else
5685
        cond = TCG_COND_NE;
5686

    
5687
    l1 = gen_new_label();
5688
    t0 = tcg_temp_new_i32();
5689
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5690
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5691
    if (rs == 0) {
5692
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5693
    } else {
5694
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5695
    }
5696
    gen_set_label(l1);
5697
    tcg_temp_free_i32(t0);
5698
}
5699

    
5700
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5701
{
5702
    int cond;
5703
    TCGv_i32 t0 = tcg_temp_new_i32();
5704
    int l1 = gen_new_label();
5705

    
5706
    if (tf)
5707
        cond = TCG_COND_EQ;
5708
    else
5709
        cond = TCG_COND_NE;
5710

    
5711
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5712
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5713
    gen_load_fpr32(t0, fs);
5714
    gen_store_fpr32(t0, fd);
5715
    gen_set_label(l1);
5716
    tcg_temp_free_i32(t0);
5717
}
5718

    
5719
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5720
{
5721
    int cond;
5722
    TCGv_i32 t0 = tcg_temp_new_i32();
5723
    TCGv_i64 fp0;
5724
    int l1 = gen_new_label();
5725

    
5726
    if (tf)
5727
        cond = TCG_COND_EQ;
5728
    else
5729
        cond = TCG_COND_NE;
5730

    
5731
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5732
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5733
    fp0 = tcg_temp_local_new_i64();
5734
    gen_load_fpr64(ctx, fp0, fs);
5735
    gen_store_fpr64(ctx, fp0, fd);
5736
    tcg_temp_free_i64(fp0);
5737
    gen_set_label(l1);
5738
    tcg_temp_free_i32(t0);
5739
}
5740

    
5741
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5742
{
5743
    int cond;
5744
    TCGv_i32 t0 = tcg_temp_new_i32();
5745
    int l1 = gen_new_label();
5746
    int l2 = gen_new_label();
5747

    
5748
    if (tf)
5749
        cond = TCG_COND_EQ;
5750
    else
5751
        cond = TCG_COND_NE;
5752

    
5753
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5754
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5755
    gen_load_fpr32(t0, fs);
5756
    gen_store_fpr32(t0, fd);
5757
    gen_set_label(l1);
5758

    
5759
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5760
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5761
    gen_load_fpr32h(t0, fs);
5762
    gen_store_fpr32h(t0, fd);
5763
    gen_set_label(l2);
5764

    
5765
    tcg_temp_free_i32(t0);
5766
}
5767

    
5768

    
5769
static void gen_farith (DisasContext *ctx, uint32_t op1,
5770
                        int ft, int fs, int fd, int cc)
5771
{
5772
    const char *opn = "farith";
5773
    const char *condnames[] = {
5774
            "c.f",
5775
            "c.un",
5776
            "c.eq",
5777
            "c.ueq",
5778
            "c.olt",
5779
            "c.ult",
5780
            "c.ole",
5781
            "c.ule",
5782
            "c.sf",
5783
            "c.ngle",
5784
            "c.seq",
5785
            "c.ngl",
5786
            "c.lt",
5787
            "c.nge",
5788
            "c.le",
5789
            "c.ngt",
5790
    };
5791
    const char *condnames_abs[] = {
5792
            "cabs.f",
5793
            "cabs.un",
5794
            "cabs.eq",
5795
            "cabs.ueq",
5796
            "cabs.olt",
5797
            "cabs.ult",
5798
            "cabs.ole",
5799
            "cabs.ule",
5800
            "cabs.sf",
5801
            "cabs.ngle",
5802
            "cabs.seq",
5803
            "cabs.ngl",
5804
            "cabs.lt",
5805
            "cabs.nge",
5806
            "cabs.le",
5807
            "cabs.ngt",
5808
    };
5809
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5810
    uint32_t func = ctx->opcode & 0x3f;
5811

    
5812
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5813
    case FOP(0, 16):
5814
        {
5815
            TCGv_i32 fp0 = tcg_temp_new_i32();
5816
            TCGv_i32 fp1 = tcg_temp_new_i32();
5817

    
5818
            gen_load_fpr32(fp0, fs);
5819
            gen_load_fpr32(fp1, ft);
5820
            gen_helper_float_add_s(fp0, fp0, fp1);
5821
            tcg_temp_free_i32(fp1);
5822
            gen_store_fpr32(fp0, fd);
5823
            tcg_temp_free_i32(fp0);
5824
        }
5825
        opn = "add.s";
5826
        optype = BINOP;
5827
        break;
5828
    case FOP(1, 16):
5829
        {
5830
            TCGv_i32 fp0 = tcg_temp_new_i32();
5831
            TCGv_i32 fp1 = tcg_temp_new_i32();
5832

    
5833
            gen_load_fpr32(fp0, fs);
5834
            gen_load_fpr32(fp1, ft);
5835
            gen_helper_float_sub_s(fp0, fp0, fp1);
5836
            tcg_temp_free_i32(fp1);
5837
            gen_store_fpr32(fp0, fd);
5838
            tcg_temp_free_i32(fp0);
5839
        }
5840
        opn = "sub.s";
5841
        optype = BINOP;
5842
        break;
5843
    case FOP(2, 16):
5844
        {
5845
            TCGv_i32 fp0 = tcg_temp_new_i32();
5846
            TCGv_i32 fp1 = tcg_temp_new_i32();
5847

    
5848
            gen_load_fpr32(fp0, fs);
5849
            gen_load_fpr32(fp1, ft);
5850
            gen_helper_float_mul_s(fp0, fp0, fp1);
5851
            tcg_temp_free_i32(fp1);
5852
            gen_store_fpr32(fp0, fd);
5853
            tcg_temp_free_i32(fp0);
5854
        }
5855
        opn = "mul.s";
5856
        optype = BINOP;
5857
        break;
5858
    case FOP(3, 16):
5859
        {
5860
            TCGv_i32 fp0 = tcg_temp_new_i32();
5861
            TCGv_i32 fp1 = tcg_temp_new_i32();
5862

    
5863
            gen_load_fpr32(fp0, fs);
5864
            gen_load_fpr32(fp1, ft);
5865
            gen_helper_float_div_s(fp0, fp0, fp1);
5866
            tcg_temp_free_i32(fp1);
5867
            gen_store_fpr32(fp0, fd);
5868
            tcg_temp_free_i32(fp0);
5869
        }
5870
        opn = "div.s";
5871
        optype = BINOP;
5872
        break;
5873
    case FOP(4, 16):
5874
        {
5875
            TCGv_i32 fp0 = tcg_temp_new_i32();
5876

    
5877
            gen_load_fpr32(fp0, fs);
5878
            gen_helper_float_sqrt_s(fp0, fp0);
5879
            gen_store_fpr32(fp0, fd);
5880
            tcg_temp_free_i32(fp0);
5881
        }
5882
        opn = "sqrt.s";
5883
        break;
5884
    case FOP(5, 16):
5885
        {
5886
            TCGv_i32 fp0 = tcg_temp_new_i32();
5887

    
5888
            gen_load_fpr32(fp0, fs);
5889
            gen_helper_float_abs_s(fp0, fp0);
5890
            gen_store_fpr32(fp0, fd);
5891
            tcg_temp_free_i32(fp0);
5892
        }
5893
        opn = "abs.s";
5894
        break;
5895
    case FOP(6, 16):
5896
        {
5897
            TCGv_i32 fp0 = tcg_temp_new_i32();
5898

    
5899
            gen_load_fpr32(fp0, fs);
5900
            gen_store_fpr32(fp0, fd);
5901
            tcg_temp_free_i32(fp0);
5902
        }
5903
        opn = "mov.s";
5904
        break;
5905
    case FOP(7, 16):
5906
        {
5907
            TCGv_i32 fp0 = tcg_temp_new_i32();
5908

    
5909
            gen_load_fpr32(fp0, fs);
5910
            gen_helper_float_chs_s(fp0, fp0);
5911
            gen_store_fpr32(fp0, fd);
5912
            tcg_temp_free_i32(fp0);
5913
        }
5914
        opn = "neg.s";
5915
        break;
5916
    case FOP(8, 16):
5917
        check_cp1_64bitmode(ctx);
5918
        {
5919
            TCGv_i32 fp32 = tcg_temp_new_i32();
5920
            TCGv_i64 fp64 = tcg_temp_new_i64();
5921

    
5922
            gen_load_fpr32(fp32, fs);
5923
            gen_helper_float_roundl_s(fp64, fp32);
5924
            tcg_temp_free_i32(fp32);
5925
            gen_store_fpr64(ctx, fp64, fd);
5926
            tcg_temp_free_i64(fp64);
5927
        }
5928
        opn = "round.l.s";
5929
        break;
5930
    case FOP(9, 16):
5931
        check_cp1_64bitmode(ctx);
5932
        {
5933
            TCGv_i32 fp32 = tcg_temp_new_i32();
5934
            TCGv_i64 fp64 = tcg_temp_new_i64();
5935

    
5936
            gen_load_fpr32(fp32, fs);
5937
            gen_helper_float_truncl_s(fp64, fp32);
5938
            tcg_temp_free_i32(fp32);
5939
            gen_store_fpr64(ctx, fp64, fd);
5940
            tcg_temp_free_i64(fp64);
5941
        }
5942
        opn = "trunc.l.s";
5943
        break;
5944
    case FOP(10, 16):
5945
        check_cp1_64bitmode(ctx);
5946
        {
5947
            TCGv_i32 fp32 = tcg_temp_new_i32();
5948
            TCGv_i64 fp64 = tcg_temp_new_i64();
5949

    
5950
            gen_load_fpr32(fp32, fs);
5951
            gen_helper_float_ceill_s(fp64, fp32);
5952
            tcg_temp_free_i32(fp32);
5953
            gen_store_fpr64(ctx, fp64, fd);
5954
            tcg_temp_free_i64(fp64);
5955
        }
5956
        opn = "ceil.l.s";
5957
        break;
5958
    case FOP(11, 16):
5959
        check_cp1_64bitmode(ctx);
5960
        {
5961
            TCGv_i32 fp32 = tcg_temp_new_i32();
5962
            TCGv_i64 fp64 = tcg_temp_new_i64();
5963

    
5964
            gen_load_fpr32(fp32, fs);
5965
            gen_helper_float_floorl_s(fp64, fp32);
5966
            tcg_temp_free_i32(fp32);
5967
            gen_store_fpr64(ctx, fp64, fd);
5968
            tcg_temp_free_i64(fp64);
5969
        }
5970
        opn = "floor.l.s";
5971
        break;
5972
    case FOP(12, 16):
5973
        {
5974
            TCGv_i32 fp0 = tcg_temp_new_i32();
5975

    
5976
            gen_load_fpr32(fp0, fs);
5977
            gen_helper_float_roundw_s(fp0, fp0);
5978
            gen_store_fpr32(fp0, fd);
5979
            tcg_temp_free_i32(fp0);
5980
        }
5981
        opn = "round.w.s";
5982
        break;
5983
    case FOP(13, 16):
5984
        {
5985
            TCGv_i32 fp0 = tcg_temp_new_i32();
5986

    
5987
            gen_load_fpr32(fp0, fs);
5988
            gen_helper_float_truncw_s(fp0, fp0);
5989
            gen_store_fpr32(fp0, fd);
5990
            tcg_temp_free_i32(fp0);
5991
        }
5992
        opn = "trunc.w.s";
5993
        break;
5994
    case FOP(14, 16):
5995
        {
5996
            TCGv_i32 fp0 = tcg_temp_new_i32();
5997

    
5998
            gen_load_fpr32(fp0, fs);
5999
            gen_helper_float_ceilw_s(fp0, fp0);
6000
            gen_store_fpr32(fp0, fd);
6001
            tcg_temp_free_i32(fp0);
6002
        }
6003
        opn = "ceil.w.s";
6004
        break;
6005
    case FOP(15, 16):
6006
        {
6007
            TCGv_i32 fp0 = tcg_temp_new_i32();
6008

    
6009
            gen_load_fpr32(fp0, fs);
6010
            gen_helper_float_floorw_s(fp0, fp0);
6011
            gen_store_fpr32(fp0, fd);
6012
            tcg_temp_free_i32(fp0);
6013
        }
6014
        opn = "floor.w.s";
6015
        break;
6016
    case FOP(17, 16):
6017
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6018
        opn = "movcf.s";
6019
        break;
6020
    case FOP(18, 16):
6021
        {
6022
            int l1 = gen_new_label();
6023
            TCGv t0 = tcg_temp_new();
6024
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6025

    
6026
            gen_load_gpr(t0, ft);
6027
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6028
            gen_load_fpr32(fp0, fs);
6029
            gen_store_fpr32(fp0, fd);
6030
            tcg_temp_free_i32(fp0);
6031
            gen_set_label(l1);
6032
            tcg_temp_free(t0);
6033
        }
6034
        opn = "movz.s";
6035
        break;
6036
    case FOP(19, 16):
6037
        {
6038
            int l1 = gen_new_label();
6039
            TCGv t0 = tcg_temp_new();
6040
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6041

    
6042
            gen_load_gpr(t0, ft);
6043
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6044
            gen_load_fpr32(fp0, fs);
6045
            gen_store_fpr32(fp0, fd);
6046
            tcg_temp_free_i32(fp0);
6047
            gen_set_label(l1);
6048
            tcg_temp_free(t0);
6049
        }
6050
        opn = "movn.s";
6051
        break;
6052
    case FOP(21, 16):
6053
        check_cop1x(ctx);
6054
        {
6055
            TCGv_i32 fp0 = tcg_temp_new_i32();
6056

    
6057
            gen_load_fpr32(fp0, fs);
6058
            gen_helper_float_recip_s(fp0, fp0);
6059
            gen_store_fpr32(fp0, fd);
6060
            tcg_temp_free_i32(fp0);
6061
        }
6062
        opn = "recip.s";
6063
        break;
6064
    case FOP(22, 16):
6065
        check_cop1x(ctx);
6066
        {
6067
            TCGv_i32 fp0 = tcg_temp_new_i32();
6068

    
6069
            gen_load_fpr32(fp0, fs);
6070
            gen_helper_float_rsqrt_s(fp0, fp0);
6071
            gen_store_fpr32(fp0, fd);
6072
            tcg_temp_free_i32(fp0);
6073
        }
6074
        opn = "rsqrt.s";
6075
        break;
6076
    case FOP(28, 16):
6077
        check_cp1_64bitmode(ctx);
6078
        {
6079
            TCGv_i32 fp0 = tcg_temp_new_i32();
6080
            TCGv_i32 fp1 = tcg_temp_new_i32();
6081

    
6082
            gen_load_fpr32(fp0, fs);
6083
            gen_load_fpr32(fp1, fd);
6084
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6085
            tcg_temp_free_i32(fp1);
6086
            gen_store_fpr32(fp0, fd);
6087
            tcg_temp_free_i32(fp0);
6088
        }
6089
        opn = "recip2.s";
6090
        break;
6091
    case FOP(29, 16):
6092
        check_cp1_64bitmode(ctx);
6093
        {
6094
            TCGv_i32 fp0 = tcg_temp_new_i32();
6095

    
6096
            gen_load_fpr32(fp0, fs);
6097
            gen_helper_float_recip1_s(fp0, fp0);
6098
            gen_store_fpr32(fp0, fd);
6099
            tcg_temp_free_i32(fp0);
6100
        }
6101
        opn = "recip1.s";
6102
        break;
6103
    case FOP(30, 16):
6104
        check_cp1_64bitmode(ctx);
6105
        {
6106
            TCGv_i32 fp0 = tcg_temp_new_i32();
6107

    
6108
            gen_load_fpr32(fp0, fs);
6109
            gen_helper_float_rsqrt1_s(fp0, fp0);
6110
            gen_store_fpr32(fp0, fd);
6111
            tcg_temp_free_i32(fp0);
6112
        }
6113
        opn = "rsqrt1.s";
6114
        break;
6115
    case FOP(31, 16):
6116
        check_cp1_64bitmode(ctx);
6117
        {
6118
            TCGv_i32 fp0 = tcg_temp_new_i32();
6119
            TCGv_i32 fp1 = tcg_temp_new_i32();
6120

    
6121
            gen_load_fpr32(fp0, fs);
6122
            gen_load_fpr32(fp1, ft);
6123
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6124
            tcg_temp_free_i32(fp1);
6125
            gen_store_fpr32(fp0, fd);
6126
            tcg_temp_free_i32(fp0);
6127
        }
6128
        opn = "rsqrt2.s";
6129
        break;
6130
    case FOP(33, 16):
6131
        check_cp1_registers(ctx, fd);
6132
        {
6133
            TCGv_i32 fp32 = tcg_temp_new_i32();
6134
            TCGv_i64 fp64 = tcg_temp_new_i64();
6135

    
6136
            gen_load_fpr32(fp32, fs);
6137
            gen_helper_float_cvtd_s(fp64, fp32);
6138
            tcg_temp_free_i32(fp32);
6139
            gen_store_fpr64(ctx, fp64, fd);
6140
            tcg_temp_free_i64(fp64);
6141
        }
6142
        opn = "cvt.d.s";
6143
        break;
6144
    case FOP(36, 16):
6145
        {
6146
            TCGv_i32 fp0 = tcg_temp_new_i32();
6147

    
6148
            gen_load_fpr32(fp0, fs);
6149
            gen_helper_float_cvtw_s(fp0, fp0);
6150
            gen_store_fpr32(fp0, fd);
6151
            tcg_temp_free_i32(fp0);
6152
        }
6153
        opn = "cvt.w.s";
6154
        break;
6155
    case FOP(37, 16):
6156
        check_cp1_64bitmode(ctx);
6157
        {
6158
            TCGv_i32 fp32 = tcg_temp_new_i32();
6159
            TCGv_i64 fp64 = tcg_temp_new_i64();
6160

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

    
6176
            gen_load_fpr32(fp32_0, fs);
6177
            gen_load_fpr32(fp32_1, ft);
6178
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6179
            tcg_temp_free_i32(fp32_1);
6180
            tcg_temp_free_i32(fp32_0);
6181
            gen_store_fpr64(ctx, fp64, fd);
6182
            tcg_temp_free_i64(fp64);
6183
        }
6184
        opn = "cvt.ps.s";
6185
        break;
6186
    case FOP(48, 16):
6187
    case FOP(49, 16):
6188
    case FOP(50, 16):
6189
    case FOP(51, 16):
6190
    case FOP(52, 16):
6191
    case FOP(53, 16):
6192
    case FOP(54, 16):
6193
    case FOP(55, 16):
6194
    case FOP(56, 16):
6195
    case FOP(57, 16):
6196
    case FOP(58, 16):
6197
    case FOP(59, 16):
6198
    case FOP(60, 16):
6199
    case FOP(61, 16):
6200
    case FOP(62, 16):
6201
    case FOP(63, 16):
6202
        {
6203
            TCGv_i32 fp0 = tcg_temp_new_i32();
6204
            TCGv_i32 fp1 = tcg_temp_new_i32();
6205

    
6206
            gen_load_fpr32(fp0, fs);
6207
            gen_load_fpr32(fp1, ft);
6208
            if (ctx->opcode & (1 << 6)) {
6209
                check_cop1x(ctx);
6210
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6211
                opn = condnames_abs[func-48];
6212
            } else {
6213
                gen_cmp_s(func-48, fp0, fp1, cc);
6214
                opn = condnames[func-48];
6215
            }
6216
            tcg_temp_free_i32(fp0);
6217
            tcg_temp_free_i32(fp1);
6218
        }
6219
        break;
6220
    case FOP(0, 17):
6221
        check_cp1_registers(ctx, fs | ft | fd);
6222
        {
6223
            TCGv_i64 fp0 = tcg_temp_new_i64();
6224
            TCGv_i64 fp1 = tcg_temp_new_i64();
6225

    
6226
            gen_load_fpr64(ctx, fp0, fs);
6227
            gen_load_fpr64(ctx, fp1, ft);
6228
            gen_helper_float_add_d(fp0, fp0, fp1);
6229
            tcg_temp_free_i64(fp1);
6230
            gen_store_fpr64(ctx, fp0, fd);
6231
            tcg_temp_free_i64(fp0);
6232
        }
6233
        opn = "add.d";
6234
        optype = BINOP;
6235
        break;
6236
    case FOP(1, 17):
6237
        check_cp1_registers(ctx, fs | ft | fd);
6238
        {
6239
            TCGv_i64 fp0 = tcg_temp_new_i64();
6240
            TCGv_i64 fp1 = tcg_temp_new_i64();
6241

    
6242
            gen_load_fpr64(ctx, fp0, fs);
6243
            gen_load_fpr64(ctx, fp1, ft);
6244
            gen_helper_float_sub_d(fp0, fp0, fp1);
6245
            tcg_temp_free_i64(fp1);
6246
            gen_store_fpr64(ctx, fp0, fd);
6247
            tcg_temp_free_i64(fp0);
6248
        }
6249
        opn = "sub.d";
6250
        optype = BINOP;
6251
        break;
6252
    case FOP(2, 17):
6253
        check_cp1_registers(ctx, fs | ft | fd);
6254
        {
6255
            TCGv_i64 fp0 = tcg_temp_new_i64();
6256
            TCGv_i64 fp1 = tcg_temp_new_i64();
6257

    
6258
            gen_load_fpr64(ctx, fp0, fs);
6259
            gen_load_fpr64(ctx, fp1, ft);
6260
            gen_helper_float_mul_d(fp0, fp0, fp1);
6261
            tcg_temp_free_i64(fp1);
6262
            gen_store_fpr64(ctx, fp0, fd);
6263
            tcg_temp_free_i64(fp0);
6264
        }
6265
        opn = "mul.d";
6266
        optype = BINOP;
6267
        break;
6268
    case FOP(3, 17):
6269
        check_cp1_registers(ctx, fs | ft | fd);
6270
        {
6271
            TCGv_i64 fp0 = tcg_temp_new_i64();
6272
            TCGv_i64 fp1 = tcg_temp_new_i64();
6273

    
6274
            gen_load_fpr64(ctx, fp0, fs);
6275
            gen_load_fpr64(ctx, fp1, ft);
6276
            gen_helper_float_div_d(fp0, fp0, fp1);
6277
            tcg_temp_free_i64(fp1);
6278
            gen_store_fpr64(ctx, fp0, fd);
6279
            tcg_temp_free_i64(fp0);
6280
        }
6281
        opn = "div.d";
6282
        optype = BINOP;
6283
        break;
6284
    case FOP(4, 17):
6285
        check_cp1_registers(ctx, fs | fd);
6286
        {
6287
            TCGv_i64 fp0 = tcg_temp_new_i64();
6288

    
6289
            gen_load_fpr64(ctx, fp0, fs);
6290
            gen_helper_float_sqrt_d(fp0, fp0);
6291
            gen_store_fpr64(ctx, fp0, fd);
6292
            tcg_temp_free_i64(fp0);
6293
        }
6294
        opn = "sqrt.d";
6295
        break;
6296
    case FOP(5, 17):
6297
        check_cp1_registers(ctx, fs | fd);
6298
        {
6299
            TCGv_i64 fp0 = tcg_temp_new_i64();
6300

    
6301
            gen_load_fpr64(ctx, fp0, fs);
6302
            gen_helper_float_abs_d(fp0, fp0);
6303
            gen_store_fpr64(ctx, fp0, fd);
6304
            tcg_temp_free_i64(fp0);
6305
        }
6306
        opn = "abs.d";
6307
        break;
6308
    case FOP(6, 17):
6309
        check_cp1_registers(ctx, fs | fd);
6310
        {
6311
            TCGv_i64 fp0 = tcg_temp_new_i64();
6312

    
6313
            gen_load_fpr64(ctx, fp0, fs);
6314
            gen_store_fpr64(ctx, fp0, fd);
6315
            tcg_temp_free_i64(fp0);
6316
        }
6317
        opn = "mov.d";
6318
        break;
6319
    case FOP(7, 17):
6320
        check_cp1_registers(ctx, fs | fd);
6321
        {
6322
            TCGv_i64 fp0 = tcg_temp_new_i64();
6323

    
6324
            gen_load_fpr64(ctx, fp0, fs);
6325
            gen_helper_float_chs_d(fp0, fp0);
6326
            gen_store_fpr64(ctx, fp0, fd);
6327
            tcg_temp_free_i64(fp0);
6328
        }
6329
        opn = "neg.d";
6330
        break;
6331
    case FOP(8, 17):
6332
        check_cp1_64bitmode(ctx);
6333
        {
6334
            TCGv_i64 fp0 = tcg_temp_new_i64();
6335

    
6336
            gen_load_fpr64(ctx, fp0, fs);
6337
            gen_helper_float_roundl_d(fp0, fp0);
6338
            gen_store_fpr64(ctx, fp0, fd);
6339
            tcg_temp_free_i64(fp0);
6340
        }
6341
        opn = "round.l.d";
6342
        break;
6343
    case FOP(9, 17):
6344
        check_cp1_64bitmode(ctx);
6345
        {
6346
            TCGv_i64 fp0 = tcg_temp_new_i64();
6347

    
6348
            gen_load_fpr64(ctx, fp0, fs);
6349
            gen_helper_float_truncl_d(fp0, fp0);
6350
            gen_store_fpr64(ctx, fp0, fd);
6351
            tcg_temp_free_i64(fp0);
6352
        }
6353
        opn = "trunc.l.d";
6354
        break;
6355
    case FOP(10, 17):
6356
        check_cp1_64bitmode(ctx);
6357
        {
6358
            TCGv_i64 fp0 = tcg_temp_new_i64();
6359

    
6360
            gen_load_fpr64(ctx, fp0, fs);
6361
            gen_helper_float_ceill_d(fp0, fp0);
6362
            gen_store_fpr64(ctx, fp0, fd);
6363
            tcg_temp_free_i64(fp0);
6364
        }
6365
        opn = "ceil.l.d";
6366
        break;
6367
    case FOP(11, 17):
6368
        check_cp1_64bitmode(ctx);
6369
        {
6370
            TCGv_i64 fp0 = tcg_temp_new_i64();
6371

    
6372
            gen_load_fpr64(ctx, fp0, fs);
6373
            gen_helper_float_floorl_d(fp0, fp0);
6374
            gen_store_fpr64(ctx, fp0, fd);
6375
            tcg_temp_free_i64(fp0);
6376
        }
6377
        opn = "floor.l.d";
6378
        break;
6379
    case FOP(12, 17):
6380
        check_cp1_registers(ctx, fs);
6381
        {
6382
            TCGv_i32 fp32 = tcg_temp_new_i32();
6383
            TCGv_i64 fp64 = tcg_temp_new_i64();
6384

    
6385
            gen_load_fpr64(ctx, fp64, fs);
6386
            gen_helper_float_roundw_d(fp32, fp64);
6387
            tcg_temp_free_i64(fp64);
6388
            gen_store_fpr32(fp32, fd);
6389
            tcg_temp_free_i32(fp32);
6390
        }
6391
        opn = "round.w.d";
6392
        break;
6393
    case FOP(13, 17):
6394
        check_cp1_registers(ctx, fs);
6395
        {
6396
            TCGv_i32 fp32 = tcg_temp_new_i32();
6397
            TCGv_i64 fp64 = tcg_temp_new_i64();
6398

    
6399
            gen_load_fpr64(ctx, fp64, fs);
6400
            gen_helper_float_truncw_d(fp32, fp64);
6401
            tcg_temp_free_i64(fp64);
6402
            gen_store_fpr32(fp32, fd);
6403
            tcg_temp_free_i32(fp32);
6404
        }
6405
        opn = "trunc.w.d";
6406
        break;
6407
    case FOP(14, 17):
6408
        check_cp1_registers(ctx, fs);
6409
        {
6410
            TCGv_i32 fp32 = tcg_temp_new_i32();
6411
            TCGv_i64 fp64 = tcg_temp_new_i64();
6412

    
6413
            gen_load_fpr64(ctx, fp64, fs);
6414
            gen_helper_float_ceilw_d(fp32, fp64);
6415
            tcg_temp_free_i64(fp64);
6416
            gen_store_fpr32(fp32, fd);
6417
            tcg_temp_free_i32(fp32);
6418
        }
6419
        opn = "ceil.w.d";
6420
        break;
6421
    case FOP(15, 17):
6422
        check_cp1_registers(ctx, fs);
6423
        {
6424
            TCGv_i32 fp32 = tcg_temp_new_i32();
6425
            TCGv_i64 fp64 = tcg_temp_new_i64();
6426

    
6427
            gen_load_fpr64(ctx, fp64, fs);
6428
            gen_helper_float_floorw_d(fp32, fp64);
6429
            tcg_temp_free_i64(fp64);
6430
            gen_store_fpr32(fp32, fd);
6431
            tcg_temp_free_i32(fp32);
6432
        }
6433
        opn = "floor.w.d";
6434
        break;
6435
    case FOP(17, 17):
6436
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6437
        opn = "movcf.d";
6438
        break;
6439
    case FOP(18, 17):
6440
        {
6441
            int l1 = gen_new_label();
6442
            TCGv t0 = tcg_temp_new();
6443
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6444

    
6445
            gen_load_gpr(t0, ft);
6446
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6447
            gen_load_fpr64(ctx, fp0, fs);
6448
            gen_store_fpr64(ctx, fp0, fd);
6449
            tcg_temp_free_i64(fp0);
6450
            gen_set_label(l1);
6451
            tcg_temp_free(t0);
6452
        }
6453
        opn = "movz.d";
6454
        break;
6455
    case FOP(19, 17):
6456
        {
6457
            int l1 = gen_new_label();
6458
            TCGv t0 = tcg_temp_new();
6459
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6460

    
6461
            gen_load_gpr(t0, ft);
6462
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6463
            gen_load_fpr64(ctx, fp0, fs);
6464
            gen_store_fpr64(ctx, fp0, fd);
6465
            tcg_temp_free_i64(fp0);
6466
            gen_set_label(l1);
6467
            tcg_temp_free(t0);
6468
        }
6469
        opn = "movn.d";
6470
        break;
6471
    case FOP(21, 17):
6472
        check_cp1_64bitmode(ctx);
6473
        {
6474
            TCGv_i64 fp0 = tcg_temp_new_i64();
6475

    
6476
            gen_load_fpr64(ctx, fp0, fs);
6477
            gen_helper_float_recip_d(fp0, fp0);
6478
            gen_store_fpr64(ctx, fp0, fd);
6479
            tcg_temp_free_i64(fp0);
6480
        }
6481
        opn = "recip.d";
6482
        break;
6483
    case FOP(22, 17):
6484
        check_cp1_64bitmode(ctx);
6485
        {
6486
            TCGv_i64 fp0 = tcg_temp_new_i64();
6487

    
6488
            gen_load_fpr64(ctx, fp0, fs);
6489
            gen_helper_float_rsqrt_d(fp0, fp0);
6490
            gen_store_fpr64(ctx, fp0, fd);
6491
            tcg_temp_free_i64(fp0);
6492
        }
6493
        opn = "rsqrt.d";
6494
        break;
6495
    case FOP(28, 17):
6496
        check_cp1_64bitmode(ctx);
6497
        {
6498
            TCGv_i64 fp0 = tcg_temp_new_i64();
6499
            TCGv_i64 fp1 = tcg_temp_new_i64();
6500

    
6501
            gen_load_fpr64(ctx, fp0, fs);
6502
            gen_load_fpr64(ctx, fp1, ft);
6503
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6504
            tcg_temp_free_i64(fp1);
6505
            gen_store_fpr64(ctx, fp0, fd);
6506
            tcg_temp_free_i64(fp0);
6507
        }
6508
        opn = "recip2.d";
6509
        break;
6510
    case FOP(29, 17):
6511
        check_cp1_64bitmode(ctx);
6512
        {
6513
            TCGv_i64 fp0 = tcg_temp_new_i64();
6514

    
6515
            gen_load_fpr64(ctx, fp0, fs);
6516
            gen_helper_float_recip1_d(fp0, fp0);
6517
            gen_store_fpr64(ctx, fp0, fd);
6518
            tcg_temp_free_i64(fp0);
6519
        }
6520
        opn = "recip1.d";
6521
        break;
6522
    case FOP(30, 17):
6523
        check_cp1_64bitmode(ctx);
6524
        {
6525
            TCGv_i64 fp0 = tcg_temp_new_i64();
6526

    
6527
            gen_load_fpr64(ctx, fp0, fs);
6528
            gen_helper_float_rsqrt1_d(fp0, fp0);
6529
            gen_store_fpr64(ctx, fp0, fd);
6530
            tcg_temp_free_i64(fp0);
6531
        }
6532
        opn = "rsqrt1.d";
6533
        break;
6534
    case FOP(31, 17):
6535
        check_cp1_64bitmode(ctx);
6536
        {
6537
            TCGv_i64 fp0 = tcg_temp_new_i64();
6538
            TCGv_i64 fp1 = tcg_temp_new_i64();
6539

    
6540
            gen_load_fpr64(ctx, fp0, fs);
6541
            gen_load_fpr64(ctx, fp1, ft);
6542
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6543
            tcg_temp_free_i64(fp1);
6544
            gen_store_fpr64(ctx, fp0, fd);
6545
            tcg_temp_free_i64(fp0);
6546
        }
6547
        opn = "rsqrt2.d";
6548
        break;
6549
    case FOP(48, 17):
6550
    case FOP(49, 17):
6551
    case FOP(50, 17):
6552
    case FOP(51, 17):
6553
    case FOP(52, 17):
6554
    case FOP(53, 17):
6555
    case FOP(54, 17):
6556
    case FOP(55, 17):
6557
    case FOP(56, 17):
6558
    case FOP(57, 17):
6559
    case FOP(58, 17):
6560
    case FOP(59, 17):
6561
    case FOP(60, 17):
6562
    case FOP(61, 17):
6563
    case FOP(62, 17):
6564
    case FOP(63, 17):
6565
        {
6566
            TCGv_i64 fp0 = tcg_temp_new_i64();
6567
            TCGv_i64 fp1 = tcg_temp_new_i64();
6568

    
6569
            gen_load_fpr64(ctx, fp0, fs);
6570
            gen_load_fpr64(ctx, fp1, ft);
6571
            if (ctx->opcode & (1 << 6)) {
6572
                check_cop1x(ctx);
6573
                check_cp1_registers(ctx, fs | ft);
6574
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6575
                opn = condnames_abs[func-48];
6576
            } else {
6577
                check_cp1_registers(ctx, fs | ft);
6578
                gen_cmp_d(func-48, fp0, fp1, cc);
6579
                opn = condnames[func-48];
6580
            }
6581
            tcg_temp_free_i64(fp0);
6582
            tcg_temp_free_i64(fp1);
6583
        }
6584
        break;
6585
    case FOP(32, 17):
6586
        check_cp1_registers(ctx, fs);
6587
        {
6588
            TCGv_i32 fp32 = tcg_temp_new_i32();
6589
            TCGv_i64 fp64 = tcg_temp_new_i64();
6590

    
6591
            gen_load_fpr64(ctx, fp64, fs);
6592
            gen_helper_float_cvts_d(fp32, fp64);
6593
            tcg_temp_free_i64(fp64);
6594
            gen_store_fpr32(fp32, fd);
6595
            tcg_temp_free_i32(fp32);
6596
        }
6597
        opn = "cvt.s.d";
6598
        break;
6599
    case FOP(36, 17):
6600
        check_cp1_registers(ctx, fs);
6601
        {
6602
            TCGv_i32 fp32 = tcg_temp_new_i32();
6603
            TCGv_i64 fp64 = tcg_temp_new_i64();
6604

    
6605
            gen_load_fpr64(ctx, fp64, fs);
6606
            gen_helper_float_cvtw_d(fp32, fp64);
6607
            tcg_temp_free_i64(fp64);
6608
            gen_store_fpr32(fp32, fd);
6609
            tcg_temp_free_i32(fp32);
6610
        }
6611
        opn = "cvt.w.d";
6612
        break;
6613
    case FOP(37, 17):
6614
        check_cp1_64bitmode(ctx);
6615
        {
6616
            TCGv_i64 fp0 = tcg_temp_new_i64();
6617

    
6618
            gen_load_fpr64(ctx, fp0, fs);
6619
            gen_helper_float_cvtl_d(fp0, fp0);
6620
            gen_store_fpr64(ctx, fp0, fd);
6621
            tcg_temp_free_i64(fp0);
6622
        }
6623
        opn = "cvt.l.d";
6624
        break;
6625
    case FOP(32, 20):
6626
        {
6627
            TCGv_i32 fp0 = tcg_temp_new_i32();
6628

    
6629
            gen_load_fpr32(fp0, fs);
6630
            gen_helper_float_cvts_w(fp0, fp0);
6631
            gen_store_fpr32(fp0, fd);
6632
            tcg_temp_free_i32(fp0);
6633
        }
6634
        opn = "cvt.s.w";
6635
        break;
6636
    case FOP(33, 20):
6637
        check_cp1_registers(ctx, fd);
6638
        {
6639
            TCGv_i32 fp32 = tcg_temp_new_i32();
6640
            TCGv_i64 fp64 = tcg_temp_new_i64();
6641

    
6642
            gen_load_fpr32(fp32, fs);
6643
            gen_helper_float_cvtd_w(fp64, fp32);
6644
            tcg_temp_free_i32(fp32);
6645
            gen_store_fpr64(ctx, fp64, fd);
6646
            tcg_temp_free_i64(fp64);
6647
        }
6648
        opn = "cvt.d.w";
6649
        break;
6650
    case FOP(32, 21):
6651
        check_cp1_64bitmode(ctx);
6652
        {
6653
            TCGv_i32 fp32 = tcg_temp_new_i32();
6654
            TCGv_i64 fp64 = tcg_temp_new_i64();
6655

    
6656
            gen_load_fpr64(ctx, fp64, fs);
6657
            gen_helper_float_cvts_l(fp32, fp64);
6658
            tcg_temp_free_i64(fp64);
6659
            gen_store_fpr32(fp32, fd);
6660
            tcg_temp_free_i32(fp32);
6661
        }
6662
        opn = "cvt.s.l";
6663
        break;
6664
    case FOP(33, 21):
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_cvtd_l(fp0, fp0);
6671
            gen_store_fpr64(ctx, fp0, fd);
6672
            tcg_temp_free_i64(fp0);
6673
        }
6674
        opn = "cvt.d.l";
6675
        break;
6676
    case FOP(38, 20):
6677
        check_cp1_64bitmode(ctx);
6678
        {
6679
            TCGv_i64 fp0 = tcg_temp_new_i64();
6680

    
6681
            gen_load_fpr64(ctx, fp0, fs);
6682
            gen_helper_float_cvtps_pw(fp0, fp0);
6683
            gen_store_fpr64(ctx, fp0, fd);
6684
            tcg_temp_free_i64(fp0);
6685
        }
6686
        opn = "cvt.ps.pw";
6687
        break;
6688
    case FOP(0, 22):
6689
        check_cp1_64bitmode(ctx);
6690
        {
6691
            TCGv_i64 fp0 = tcg_temp_new_i64();
6692
            TCGv_i64 fp1 = tcg_temp_new_i64();
6693

    
6694
            gen_load_fpr64(ctx, fp0, fs);
6695
            gen_load_fpr64(ctx, fp1, ft);
6696
            gen_helper_float_add_ps(fp0, fp0, fp1);
6697
            tcg_temp_free_i64(fp1);
6698
            gen_store_fpr64(ctx, fp0, fd);
6699
            tcg_temp_free_i64(fp0);
6700
        }
6701
        opn = "add.ps";
6702
        break;
6703
    case FOP(1, 22):
6704
        check_cp1_64bitmode(ctx);
6705
        {
6706
            TCGv_i64 fp0 = tcg_temp_new_i64();
6707
            TCGv_i64 fp1 = tcg_temp_new_i64();
6708

    
6709
            gen_load_fpr64(ctx, fp0, fs);
6710
            gen_load_fpr64(ctx, fp1, ft);
6711
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6712
            tcg_temp_free_i64(fp1);
6713
            gen_store_fpr64(ctx, fp0, fd);
6714
            tcg_temp_free_i64(fp0);
6715
        }
6716
        opn = "sub.ps";
6717
        break;
6718
    case FOP(2, 22):
6719
        check_cp1_64bitmode(ctx);
6720
        {
6721
            TCGv_i64 fp0 = tcg_temp_new_i64();
6722
            TCGv_i64 fp1 = tcg_temp_new_i64();
6723

    
6724
            gen_load_fpr64(ctx, fp0, fs);
6725
            gen_load_fpr64(ctx, fp1, ft);
6726
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6727
            tcg_temp_free_i64(fp1);
6728
            gen_store_fpr64(ctx, fp0, fd);
6729
            tcg_temp_free_i64(fp0);
6730
        }
6731
        opn = "mul.ps";
6732
        break;
6733
    case FOP(5, 22):
6734
        check_cp1_64bitmode(ctx);
6735
        {
6736
            TCGv_i64 fp0 = tcg_temp_new_i64();
6737

    
6738
            gen_load_fpr64(ctx, fp0, fs);
6739
            gen_helper_float_abs_ps(fp0, fp0);
6740
            gen_store_fpr64(ctx, fp0, fd);
6741
            tcg_temp_free_i64(fp0);
6742
        }
6743
        opn = "abs.ps";
6744
        break;
6745
    case FOP(6, 22):
6746
        check_cp1_64bitmode(ctx);
6747
        {
6748
            TCGv_i64 fp0 = tcg_temp_new_i64();
6749

    
6750
            gen_load_fpr64(ctx, fp0, fs);
6751
            gen_store_fpr64(ctx, fp0, fd);
6752
            tcg_temp_free_i64(fp0);
6753
        }
6754
        opn = "mov.ps";
6755
        break;
6756
    case FOP(7, 22):
6757
        check_cp1_64bitmode(ctx);
6758
        {
6759
            TCGv_i64 fp0 = tcg_temp_new_i64();
6760

    
6761
            gen_load_fpr64(ctx, fp0, fs);
6762
            gen_helper_float_chs_ps(fp0, fp0);
6763
            gen_store_fpr64(ctx, fp0, fd);
6764
            tcg_temp_free_i64(fp0);
6765
        }
6766
        opn = "neg.ps";
6767
        break;
6768
    case FOP(17, 22):
6769
        check_cp1_64bitmode(ctx);
6770
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6771
        opn = "movcf.ps";
6772
        break;
6773
    case FOP(18, 22):
6774
        check_cp1_64bitmode(ctx);
6775
        {
6776
            int l1 = gen_new_label();
6777
            TCGv t0 = tcg_temp_new();
6778
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6779
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6780

    
6781
            gen_load_gpr(t0, ft);
6782
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6783
            gen_load_fpr32(fp0, fs);
6784
            gen_load_fpr32h(fph0, fs);
6785
            gen_store_fpr32(fp0, fd);
6786
            gen_store_fpr32h(fph0, fd);
6787
            tcg_temp_free_i32(fp0);
6788
            tcg_temp_free_i32(fph0);
6789
            gen_set_label(l1);
6790
            tcg_temp_free(t0);
6791
        }
6792
        opn = "movz.ps";
6793
        break;
6794
    case FOP(19, 22):
6795
        check_cp1_64bitmode(ctx);
6796
        {
6797
            int l1 = gen_new_label();
6798
            TCGv t0 = tcg_temp_new();
6799
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6800
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6801

    
6802
            gen_load_gpr(t0, ft);
6803
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6804
            gen_load_fpr32(fp0, fs);
6805
            gen_load_fpr32h(fph0, fs);
6806
            gen_store_fpr32(fp0, fd);
6807
            gen_store_fpr32h(fph0, fd);
6808
            tcg_temp_free_i32(fp0);
6809
            tcg_temp_free_i32(fph0);
6810
            gen_set_label(l1);
6811
            tcg_temp_free(t0);
6812
        }
6813
        opn = "movn.ps";
6814
        break;
6815
    case FOP(24, 22):
6816
        check_cp1_64bitmode(ctx);
6817
        {
6818
            TCGv_i64 fp0 = tcg_temp_new_i64();
6819
            TCGv_i64 fp1 = tcg_temp_new_i64();
6820

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

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

    
6851
            gen_load_fpr64(ctx, fp0, fs);
6852
            gen_load_fpr64(ctx, fp1, fd);
6853
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6854
            tcg_temp_free_i64(fp1);
6855
            gen_store_fpr64(ctx, fp0, fd);
6856
            tcg_temp_free_i64(fp0);
6857
        }
6858
        opn = "recip2.ps";
6859
        break;
6860
    case FOP(29, 22):
6861
        check_cp1_64bitmode(ctx);
6862
        {
6863
            TCGv_i64 fp0 = tcg_temp_new_i64();
6864

    
6865
            gen_load_fpr64(ctx, fp0, fs);
6866
            gen_helper_float_recip1_ps(fp0, fp0);
6867
            gen_store_fpr64(ctx, fp0, fd);
6868
            tcg_temp_free_i64(fp0);
6869
        }
6870
        opn = "recip1.ps";
6871
        break;
6872
    case FOP(30, 22):
6873
        check_cp1_64bitmode(ctx);
6874
        {
6875
            TCGv_i64 fp0 = tcg_temp_new_i64();
6876

    
6877
            gen_load_fpr64(ctx, fp0, fs);
6878
            gen_helper_float_rsqrt1_ps(fp0, fp0);
6879
            gen_store_fpr64(ctx, fp0, fd);
6880
            tcg_temp_free_i64(fp0);
6881
        }
6882
        opn = "rsqrt1.ps";
6883
        break;
6884
    case FOP(31, 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_rsqrt2_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 = "rsqrt2.ps";
6898
        break;
6899
    case FOP(32, 22):
6900
        check_cp1_64bitmode(ctx);
6901
        {
6902
            TCGv_i32 fp0 = tcg_temp_new_i32();
6903

    
6904
            gen_load_fpr32h(fp0, fs);
6905
            gen_helper_float_cvts_pu(fp0, fp0);
6906
            gen_store_fpr32(fp0, fd);
6907
            tcg_temp_free_i32(fp0);
6908
        }
6909
        opn = "cvt.s.pu";
6910
        break;
6911
    case FOP(36, 22):
6912
        check_cp1_64bitmode(ctx);
6913
        {
6914
            TCGv_i64 fp0 = tcg_temp_new_i64();
6915

    
6916
            gen_load_fpr64(ctx, fp0, fs);
6917
            gen_helper_float_cvtpw_ps(fp0, fp0);
6918
            gen_store_fpr64(ctx, fp0, fd);
6919
            tcg_temp_free_i64(fp0);
6920
        }
6921
        opn = "cvt.pw.ps";
6922
        break;
6923
    case FOP(40, 22):
6924
        check_cp1_64bitmode(ctx);
6925
        {
6926
            TCGv_i32 fp0 = tcg_temp_new_i32();
6927

    
6928
            gen_load_fpr32(fp0, fs);
6929
            gen_helper_float_cvts_pl(fp0, fp0);
6930
            gen_store_fpr32(fp0, fd);
6931
            tcg_temp_free_i32(fp0);
6932
        }
6933
        opn = "cvt.s.pl";
6934
        break;
6935
    case FOP(44, 22):
6936
        check_cp1_64bitmode(ctx);
6937
        {
6938
            TCGv_i32 fp0 = tcg_temp_new_i32();
6939
            TCGv_i32 fp1 = tcg_temp_new_i32();
6940

    
6941
            gen_load_fpr32(fp0, fs);
6942
            gen_load_fpr32(fp1, ft);
6943
            gen_store_fpr32h(fp0, fd);
6944
            gen_store_fpr32(fp1, fd);
6945
            tcg_temp_free_i32(fp0);
6946
            tcg_temp_free_i32(fp1);
6947
        }
6948
        opn = "pll.ps";
6949
        break;
6950
    case FOP(45, 22):
6951
        check_cp1_64bitmode(ctx);
6952
        {
6953
            TCGv_i32 fp0 = tcg_temp_new_i32();
6954
            TCGv_i32 fp1 = tcg_temp_new_i32();
6955

    
6956
            gen_load_fpr32(fp0, fs);
6957
            gen_load_fpr32h(fp1, ft);
6958
            gen_store_fpr32(fp1, fd);
6959
            gen_store_fpr32h(fp0, fd);
6960
            tcg_temp_free_i32(fp0);
6961
            tcg_temp_free_i32(fp1);
6962
        }
6963
        opn = "plu.ps";
6964
        break;
6965
    case FOP(46, 22):
6966
        check_cp1_64bitmode(ctx);
6967
        {
6968
            TCGv_i32 fp0 = tcg_temp_new_i32();
6969
            TCGv_i32 fp1 = tcg_temp_new_i32();
6970

    
6971
            gen_load_fpr32h(fp0, fs);
6972
            gen_load_fpr32(fp1, ft);
6973
            gen_store_fpr32(fp1, fd);
6974
            gen_store_fpr32h(fp0, fd);
6975
            tcg_temp_free_i32(fp0);
6976
            tcg_temp_free_i32(fp1);
6977
        }
6978
        opn = "pul.ps";
6979
        break;
6980
    case FOP(47, 22):
6981
        check_cp1_64bitmode(ctx);
6982
        {
6983
            TCGv_i32 fp0 = tcg_temp_new_i32();
6984
            TCGv_i32 fp1 = tcg_temp_new_i32();
6985

    
6986
            gen_load_fpr32h(fp0, fs);
6987
            gen_load_fpr32h(fp1, ft);
6988
            gen_store_fpr32(fp1, fd);
6989
            gen_store_fpr32h(fp0, fd);
6990
            tcg_temp_free_i32(fp0);
6991
            tcg_temp_free_i32(fp1);
6992
        }
6993
        opn = "puu.ps";
6994
        break;
6995
    case FOP(48, 22):
6996
    case FOP(49, 22):
6997
    case FOP(50, 22):
6998
    case FOP(51, 22):
6999
    case FOP(52, 22):
7000
    case FOP(53, 22):
7001
    case FOP(54, 22):
7002
    case FOP(55, 22):
7003
    case FOP(56, 22):
7004
    case FOP(57, 22):
7005
    case FOP(58, 22):
7006
    case FOP(59, 22):
7007
    case FOP(60, 22):
7008
    case FOP(61, 22):
7009
    case FOP(62, 22):
7010
    case FOP(63, 22):
7011
        check_cp1_64bitmode(ctx);
7012
        {
7013
            TCGv_i64 fp0 = tcg_temp_new_i64();
7014
            TCGv_i64 fp1 = tcg_temp_new_i64();
7015

    
7016
            gen_load_fpr64(ctx, fp0, fs);
7017
            gen_load_fpr64(ctx, fp1, ft);
7018
            if (ctx->opcode & (1 << 6)) {
7019
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7020
                opn = condnames_abs[func-48];
7021
            } else {
7022
                gen_cmp_ps(func-48, fp0, fp1, cc);
7023
                opn = condnames[func-48];
7024
            }
7025
            tcg_temp_free_i64(fp0);
7026
            tcg_temp_free_i64(fp1);
7027
        }
7028
        break;
7029
    default:
7030
        MIPS_INVAL(opn);
7031
        generate_exception (ctx, EXCP_RI);
7032
        return;
7033
    }
7034
    switch (optype) {
7035
    case BINOP:
7036
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7037
        break;
7038
    case CMPOP:
7039
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7040
        break;
7041
    default:
7042
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7043
        break;
7044
    }
7045
}
7046

    
7047
/* Coprocessor 3 (FPU) */
7048
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7049
                           int fd, int fs, int base, int index)
7050
{
7051
    const char *opn = "extended float load/store";
7052
    int store = 0;
7053
    TCGv t0 = tcg_temp_local_new();
7054
    TCGv t1 = tcg_temp_local_new();
7055

    
7056
    if (base == 0) {
7057
        gen_load_gpr(t0, index);
7058
    } else if (index == 0) {
7059
        gen_load_gpr(t0, base);
7060
    } else {
7061
        gen_load_gpr(t0, index);
7062
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7063
    }
7064
    /* Don't do NOP if destination is zero: we must perform the actual
7065
       memory access. */
7066
    switch (opc) {
7067
    case OPC_LWXC1:
7068
        check_cop1x(ctx);
7069
        {
7070
            TCGv_i32 fp0 = tcg_temp_new_i32();
7071

    
7072
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7073
            tcg_gen_trunc_tl_i32(fp0, t1);
7074
            gen_store_fpr32(fp0, fd);
7075
            tcg_temp_free_i32(fp0);
7076
        }
7077
        opn = "lwxc1";
7078
        break;
7079
    case OPC_LDXC1:
7080
        check_cop1x(ctx);
7081
        check_cp1_registers(ctx, fd);
7082
        {
7083
            TCGv_i64 fp0 = tcg_temp_new_i64();
7084

    
7085
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7086
            gen_store_fpr64(ctx, fp0, fd);
7087
            tcg_temp_free_i64(fp0);
7088
        }
7089
        opn = "ldxc1";
7090
        break;
7091
    case OPC_LUXC1:
7092
        check_cp1_64bitmode(ctx);
7093
        tcg_gen_andi_tl(t0, t0, ~0x7);
7094
        {
7095
            TCGv_i64 fp0 = tcg_temp_new_i64();
7096

    
7097
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7098
            gen_store_fpr64(ctx, fp0, fd);
7099
            tcg_temp_free_i64(fp0);
7100
        }
7101
        opn = "luxc1";
7102
        break;
7103
    case OPC_SWXC1:
7104
        check_cop1x(ctx);
7105
        {
7106
            TCGv_i32 fp0 = tcg_temp_new_i32();
7107

    
7108
            gen_load_fpr32(fp0, fs);
7109
            tcg_gen_extu_i32_tl(t1, fp0);
7110
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7111
            tcg_temp_free_i32(fp0);
7112
        }
7113
        opn = "swxc1";
7114
        store = 1;
7115
        break;
7116
    case OPC_SDXC1:
7117
        check_cop1x(ctx);
7118
        check_cp1_registers(ctx, fs);
7119
        {
7120
            TCGv_i64 fp0 = tcg_temp_new_i64();
7121

    
7122
            gen_load_fpr64(ctx, fp0, fs);
7123
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7124
            tcg_temp_free_i64(fp0);
7125
        }
7126
        opn = "sdxc1";
7127
        store = 1;
7128
        break;
7129
    case OPC_SUXC1:
7130
        check_cp1_64bitmode(ctx);
7131
        tcg_gen_andi_tl(t0, t0, ~0x7);
7132
        {
7133
            TCGv_i64 fp0 = tcg_temp_new_i64();
7134

    
7135
            gen_load_fpr64(ctx, fp0, fs);
7136
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7137
            tcg_temp_free_i64(fp0);
7138
        }
7139
        opn = "suxc1";
7140
        store = 1;
7141
        break;
7142
    default:
7143
        MIPS_INVAL(opn);
7144
        generate_exception(ctx, EXCP_RI);
7145
        tcg_temp_free(t0);
7146
        tcg_temp_free(t1);
7147
        return;
7148
    }
7149
    tcg_temp_free(t0);
7150
    tcg_temp_free(t1);
7151
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7152
               regnames[index], regnames[base]);
7153
}
7154

    
7155
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7156
                            int fd, int fr, int fs, int ft)
7157
{
7158
    const char *opn = "flt3_arith";
7159

    
7160
    switch (opc) {
7161
    case OPC_ALNV_PS:
7162
        check_cp1_64bitmode(ctx);
7163
        {
7164
            TCGv t0 = tcg_temp_local_new();
7165
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7166
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7167
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7168
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7169
            int l1 = gen_new_label();
7170
            int l2 = gen_new_label();
7171

    
7172
            gen_load_gpr(t0, fr);
7173
            tcg_gen_andi_tl(t0, t0, 0x7);
7174
            gen_load_fpr32(fp0, fs);
7175
            gen_load_fpr32h(fph0, fs);
7176
            gen_load_fpr32(fp1, ft);
7177
            gen_load_fpr32h(fph1, ft);
7178

    
7179
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7180
            gen_store_fpr32(fp0, fd);
7181
            gen_store_fpr32h(fph0, fd);
7182
            tcg_gen_br(l2);
7183
            gen_set_label(l1);
7184
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7185
            tcg_temp_free(t0);
7186
#ifdef TARGET_WORDS_BIGENDIAN
7187
            gen_store_fpr32(fph1, fd);
7188
            gen_store_fpr32h(fp0, fd);
7189
#else
7190
            gen_store_fpr32(fph0, fd);
7191
            gen_store_fpr32h(fp1, fd);
7192
#endif
7193
            gen_set_label(l2);
7194
            tcg_temp_free_i32(fp0);
7195
            tcg_temp_free_i32(fph0);
7196
            tcg_temp_free_i32(fp1);
7197
            tcg_temp_free_i32(fph1);
7198
        }
7199
        opn = "alnv.ps";
7200
        break;
7201
    case OPC_MADD_S:
7202
        check_cop1x(ctx);
7203
        {
7204
            TCGv_i32 fp0 = tcg_temp_new_i32();
7205
            TCGv_i32 fp1 = tcg_temp_new_i32();
7206
            TCGv_i32 fp2 = tcg_temp_new_i32();
7207

    
7208
            gen_load_fpr32(fp0, fs);
7209
            gen_load_fpr32(fp1, ft);
7210
            gen_load_fpr32(fp2, fr);
7211
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7212
            tcg_temp_free_i32(fp0);
7213
            tcg_temp_free_i32(fp1);
7214
            gen_store_fpr32(fp2, fd);
7215
            tcg_temp_free_i32(fp2);
7216
        }
7217
        opn = "madd.s";
7218
        break;
7219
    case OPC_MADD_D:
7220
        check_cop1x(ctx);
7221
        check_cp1_registers(ctx, fd | fs | ft | fr);
7222
        {
7223
            TCGv_i64 fp0 = tcg_temp_new_i64();
7224
            TCGv_i64 fp1 = tcg_temp_new_i64();
7225
            TCGv_i64 fp2 = tcg_temp_new_i64();
7226

    
7227
            gen_load_fpr64(ctx, fp0, fs);
7228
            gen_load_fpr64(ctx, fp1, ft);
7229
            gen_load_fpr64(ctx, fp2, fr);
7230
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7231
            tcg_temp_free_i64(fp0);
7232
            tcg_temp_free_i64(fp1);
7233
            gen_store_fpr64(ctx, fp2, fd);
7234
            tcg_temp_free_i64(fp2);
7235
        }
7236
        opn = "madd.d";
7237
        break;
7238
    case OPC_MADD_PS:
7239
        check_cp1_64bitmode(ctx);
7240
        {
7241
            TCGv_i64 fp0 = tcg_temp_new_i64();
7242
            TCGv_i64 fp1 = tcg_temp_new_i64();
7243
            TCGv_i64 fp2 = tcg_temp_new_i64();
7244

    
7245
            gen_load_fpr64(ctx, fp0, fs);
7246
            gen_load_fpr64(ctx, fp1, ft);
7247
            gen_load_fpr64(ctx, fp2, fr);
7248
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7249
            tcg_temp_free_i64(fp0);
7250
            tcg_temp_free_i64(fp1);
7251
            gen_store_fpr64(ctx, fp2, fd);
7252
            tcg_temp_free_i64(fp2);
7253
        }
7254
        opn = "madd.ps";
7255
        break;
7256
    case OPC_MSUB_S:
7257
        check_cop1x(ctx);
7258
        {
7259
            TCGv_i32 fp0 = tcg_temp_new_i32();
7260
            TCGv_i32 fp1 = tcg_temp_new_i32();
7261
            TCGv_i32 fp2 = tcg_temp_new_i32();
7262

    
7263
            gen_load_fpr32(fp0, fs);
7264
            gen_load_fpr32(fp1, ft);
7265
            gen_load_fpr32(fp2, fr);
7266
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7267
            tcg_temp_free_i32(fp0);
7268
            tcg_temp_free_i32(fp1);
7269
            gen_store_fpr32(fp2, fd);
7270
            tcg_temp_free_i32(fp2);
7271
        }
7272
        opn = "msub.s";
7273
        break;
7274
    case OPC_MSUB_D:
7275
        check_cop1x(ctx);
7276
        check_cp1_registers(ctx, fd | fs | ft | fr);
7277
        {
7278
            TCGv_i64 fp0 = tcg_temp_new_i64();
7279
            TCGv_i64 fp1 = tcg_temp_new_i64();
7280
            TCGv_i64 fp2 = tcg_temp_new_i64();
7281

    
7282
            gen_load_fpr64(ctx, fp0, fs);
7283
            gen_load_fpr64(ctx, fp1, ft);
7284
            gen_load_fpr64(ctx, fp2, fr);
7285
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7286
            tcg_temp_free_i64(fp0);
7287
            tcg_temp_free_i64(fp1);
7288
            gen_store_fpr64(ctx, fp2, fd);
7289
            tcg_temp_free_i64(fp2);
7290
        }
7291
        opn = "msub.d";
7292
        break;
7293
    case OPC_MSUB_PS:
7294
        check_cp1_64bitmode(ctx);
7295
        {
7296
            TCGv_i64 fp0 = tcg_temp_new_i64();
7297
            TCGv_i64 fp1 = tcg_temp_new_i64();
7298
            TCGv_i64 fp2 = tcg_temp_new_i64();
7299

    
7300
            gen_load_fpr64(ctx, fp0, fs);
7301
            gen_load_fpr64(ctx, fp1, ft);
7302
            gen_load_fpr64(ctx, fp2, fr);
7303
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7304
            tcg_temp_free_i64(fp0);
7305
            tcg_temp_free_i64(fp1);
7306
            gen_store_fpr64(ctx, fp2, fd);
7307
            tcg_temp_free_i64(fp2);
7308
        }
7309
        opn = "msub.ps";
7310
        break;
7311
    case OPC_NMADD_S:
7312
        check_cop1x(ctx);
7313
        {
7314
            TCGv_i32 fp0 = tcg_temp_new_i32();
7315
            TCGv_i32 fp1 = tcg_temp_new_i32();
7316
            TCGv_i32 fp2 = tcg_temp_new_i32();
7317

    
7318
            gen_load_fpr32(fp0, fs);
7319
            gen_load_fpr32(fp1, ft);
7320
            gen_load_fpr32(fp2, fr);
7321
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7322
            tcg_temp_free_i32(fp0);
7323
            tcg_temp_free_i32(fp1);
7324
            gen_store_fpr32(fp2, fd);
7325
            tcg_temp_free_i32(fp2);
7326
        }
7327
        opn = "nmadd.s";
7328
        break;
7329
    case OPC_NMADD_D:
7330
        check_cop1x(ctx);
7331
        check_cp1_registers(ctx, fd | fs | ft | fr);
7332
        {
7333
            TCGv_i64 fp0 = tcg_temp_new_i64();
7334
            TCGv_i64 fp1 = tcg_temp_new_i64();
7335
            TCGv_i64 fp2 = tcg_temp_new_i64();
7336

    
7337
            gen_load_fpr64(ctx, fp0, fs);
7338
            gen_load_fpr64(ctx, fp1, ft);
7339
            gen_load_fpr64(ctx, fp2, fr);
7340
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7341
            tcg_temp_free_i64(fp0);
7342
            tcg_temp_free_i64(fp1);
7343
            gen_store_fpr64(ctx, fp2, fd);
7344
            tcg_temp_free_i64(fp2);
7345
        }
7346
        opn = "nmadd.d";
7347
        break;
7348
    case OPC_NMADD_PS:
7349
        check_cp1_64bitmode(ctx);
7350
        {
7351
            TCGv_i64 fp0 = tcg_temp_new_i64();
7352
            TCGv_i64 fp1 = tcg_temp_new_i64();
7353
            TCGv_i64 fp2 = tcg_temp_new_i64();
7354

    
7355
            gen_load_fpr64(ctx, fp0, fs);
7356
            gen_load_fpr64(ctx, fp1, ft);
7357
            gen_load_fpr64(ctx, fp2, fr);
7358
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7359
            tcg_temp_free_i64(fp0);
7360
            tcg_temp_free_i64(fp1);
7361
            gen_store_fpr64(ctx, fp2, fd);
7362
            tcg_temp_free_i64(fp2);
7363
        }
7364
        opn = "nmadd.ps";
7365
        break;
7366
    case OPC_NMSUB_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_nmulsub_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 = "nmsub.s";
7383
        break;
7384
    case OPC_NMSUB_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_nmulsub_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 = "nmsub.d";
7402
        break;
7403
    case OPC_NMSUB_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_nmulsub_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 = "nmsub.ps";
7420
        break;
7421
    default:
7422
        MIPS_INVAL(opn);
7423
        generate_exception (ctx, EXCP_RI);
7424
        return;
7425
    }
7426
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7427
               fregnames[fs], fregnames[ft]);
7428
}
7429

    
7430
/* ISA extensions (ASEs) */
7431
/* MIPS16 extension to MIPS32 */
7432
/* SmartMIPS extension to MIPS32 */
7433

    
7434
#if defined(TARGET_MIPS64)
7435

    
7436
/* MDMX extension to MIPS64 */
7437

    
7438
#endif
7439

    
7440
static void decode_opc (CPUState *env, DisasContext *ctx)
7441
{
7442
    int32_t offset;
7443
    int rs, rt, rd, sa;
7444
    uint32_t op, op1, op2;
7445
    int16_t imm;
7446

    
7447
    /* make sure instructions are on a word boundary */
7448
    if (ctx->pc & 0x3) {
7449
        env->CP0_BadVAddr = ctx->pc;
7450
        generate_exception(ctx, EXCP_AdEL);
7451
        return;
7452
    }
7453

    
7454
    /* Handle blikely not taken case */
7455
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7456
        int l1 = gen_new_label();
7457

    
7458
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7459
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7460
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7461
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7462
        gen_set_label(l1);
7463
    }
7464
    op = MASK_OP_MAJOR(ctx->opcode);
7465
    rs = (ctx->opcode >> 21) & 0x1f;
7466
    rt = (ctx->opcode >> 16) & 0x1f;
7467
    rd = (ctx->opcode >> 11) & 0x1f;
7468
    sa = (ctx->opcode >> 6) & 0x1f;
7469
    imm = (int16_t)ctx->opcode;
7470
    switch (op) {
7471
    case OPC_SPECIAL:
7472
        op1 = MASK_SPECIAL(ctx->opcode);
7473
        switch (op1) {
7474
        case OPC_SLL:          /* Arithmetic with immediate */
7475
        case OPC_SRL ... OPC_SRA:
7476
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7477
            break;
7478
        case OPC_MOVZ ... OPC_MOVN:
7479
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7480
        case OPC_SLLV:         /* Arithmetic */
7481
        case OPC_SRLV ... OPC_SRAV:
7482
        case OPC_ADD ... OPC_NOR:
7483
        case OPC_SLT ... OPC_SLTU:
7484
            gen_arith(env, ctx, op1, rd, rs, rt);
7485
            break;
7486
        case OPC_MULT ... OPC_DIVU:
7487
            if (sa) {
7488
                check_insn(env, ctx, INSN_VR54XX);
7489
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7490
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7491
            } else
7492
                gen_muldiv(ctx, op1, rs, rt);
7493
            break;
7494
        case OPC_JR ... OPC_JALR:
7495
            gen_compute_branch(ctx, op1, rs, rd, sa);
7496
            return;
7497
        case OPC_TGE ... OPC_TEQ: /* Traps */
7498
        case OPC_TNE:
7499
            gen_trap(ctx, op1, rs, rt, -1);
7500
            break;
7501
        case OPC_MFHI:          /* Move from HI/LO */
7502
        case OPC_MFLO:
7503
            gen_HILO(ctx, op1, rd);
7504
            break;
7505
        case OPC_MTHI:
7506
        case OPC_MTLO:          /* Move to HI/LO */
7507
            gen_HILO(ctx, op1, rs);
7508
            break;
7509
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7510
#ifdef MIPS_STRICT_STANDARD
7511
            MIPS_INVAL("PMON / selsl");
7512
            generate_exception(ctx, EXCP_RI);
7513
#else
7514
            gen_helper_0i(pmon, sa);
7515
#endif
7516
            break;
7517
        case OPC_SYSCALL:
7518
            generate_exception(ctx, EXCP_SYSCALL);
7519
            break;
7520
        case OPC_BREAK:
7521
            generate_exception(ctx, EXCP_BREAK);
7522
            break;
7523
        case OPC_SPIM:
7524
#ifdef MIPS_STRICT_STANDARD
7525
            MIPS_INVAL("SPIM");
7526
            generate_exception(ctx, EXCP_RI);
7527
#else
7528
           /* Implemented as RI exception for now. */
7529
            MIPS_INVAL("spim (unofficial)");
7530
            generate_exception(ctx, EXCP_RI);
7531
#endif
7532
            break;
7533
        case OPC_SYNC:
7534
            /* Treat as NOP. */
7535
            break;
7536

    
7537
        case OPC_MOVCI:
7538
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7539
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7540
                save_cpu_state(ctx, 1);
7541
                check_cp1_enabled(ctx);
7542
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7543
                          (ctx->opcode >> 16) & 1);
7544
            } else {
7545
                generate_exception_err(ctx, EXCP_CpU, 1);
7546
            }
7547
            break;
7548

    
7549
#if defined(TARGET_MIPS64)
7550
       /* MIPS64 specific opcodes */
7551
        case OPC_DSLL:
7552
        case OPC_DSRL ... OPC_DSRA:
7553
        case OPC_DSLL32:
7554
        case OPC_DSRL32 ... OPC_DSRA32:
7555
            check_insn(env, ctx, ISA_MIPS3);
7556
            check_mips_64(ctx);
7557
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7558
            break;
7559
        case OPC_DSLLV:
7560
        case OPC_DSRLV ... OPC_DSRAV:
7561
        case OPC_DADD ... OPC_DSUBU:
7562
            check_insn(env, ctx, ISA_MIPS3);
7563
            check_mips_64(ctx);
7564
            gen_arith(env, ctx, op1, rd, rs, rt);
7565
            break;
7566
        case OPC_DMULT ... OPC_DDIVU:
7567
            check_insn(env, ctx, ISA_MIPS3);
7568
            check_mips_64(ctx);
7569
            gen_muldiv(ctx, op1, rs, rt);
7570
            break;
7571
#endif
7572
        default:            /* Invalid */
7573
            MIPS_INVAL("special");
7574
            generate_exception(ctx, EXCP_RI);
7575
            break;
7576
        }
7577
        break;
7578
    case OPC_SPECIAL2:
7579
        op1 = MASK_SPECIAL2(ctx->opcode);
7580
        switch (op1) {
7581
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7582
        case OPC_MSUB ... OPC_MSUBU:
7583
            check_insn(env, ctx, ISA_MIPS32);
7584
            gen_muldiv(ctx, op1, rs, rt);
7585
            break;
7586
        case OPC_MUL:
7587
            gen_arith(env, ctx, op1, rd, rs, rt);
7588
            break;
7589
        case OPC_CLO:
7590
        case OPC_CLZ:
7591
            check_insn(env, ctx, ISA_MIPS32);
7592
            gen_cl(ctx, op1, rd, rs);
7593
            break;
7594
        case OPC_SDBBP:
7595
            /* XXX: not clear which exception should be raised
7596
             *      when in debug mode...
7597
             */
7598
            check_insn(env, ctx, ISA_MIPS32);
7599
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7600
                generate_exception(ctx, EXCP_DBp);
7601
            } else {
7602
                generate_exception(ctx, EXCP_DBp);
7603
            }
7604
            /* Treat as NOP. */
7605
            break;
7606
#if defined(TARGET_MIPS64)
7607
        case OPC_DCLO:
7608
        case OPC_DCLZ:
7609
            check_insn(env, ctx, ISA_MIPS64);
7610
            check_mips_64(ctx);
7611
            gen_cl(ctx, op1, rd, rs);
7612
            break;
7613
#endif
7614
        default:            /* Invalid */
7615
            MIPS_INVAL("special2");
7616
            generate_exception(ctx, EXCP_RI);
7617
            break;
7618
        }
7619
        break;
7620
    case OPC_SPECIAL3:
7621
        op1 = MASK_SPECIAL3(ctx->opcode);
7622
        switch (op1) {
7623
        case OPC_EXT:
7624
        case OPC_INS:
7625
            check_insn(env, ctx, ISA_MIPS32R2);
7626
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7627
            break;
7628
        case OPC_BSHFL:
7629
            check_insn(env, ctx, ISA_MIPS32R2);
7630
            op2 = MASK_BSHFL(ctx->opcode);
7631
            gen_bshfl(ctx, op2, rt, rd);
7632
            break;
7633
        case OPC_RDHWR:
7634
            check_insn(env, ctx, ISA_MIPS32R2);
7635
            {
7636
                TCGv t0 = tcg_temp_local_new();
7637

    
7638
                switch (rd) {
7639
                case 0:
7640
                    save_cpu_state(ctx, 1);
7641
                    gen_helper_rdhwr_cpunum(t0);
7642
                    break;
7643
                case 1:
7644
                    save_cpu_state(ctx, 1);
7645
                    gen_helper_rdhwr_synci_step(t0);
7646
                    break;
7647
                case 2:
7648
                    save_cpu_state(ctx, 1);
7649
                    gen_helper_rdhwr_cc(t0);
7650
                    break;
7651
                case 3:
7652
                    save_cpu_state(ctx, 1);
7653
                    gen_helper_rdhwr_ccres(t0);
7654
                    break;
7655
                case 29:
7656
#if defined(CONFIG_USER_ONLY)
7657
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7658
                    break;
7659
#else
7660
                    /* XXX: Some CPUs implement this in hardware.
7661
                       Not supported yet. */
7662
#endif
7663
                default:            /* Invalid */
7664
                    MIPS_INVAL("rdhwr");
7665
                    generate_exception(ctx, EXCP_RI);
7666
                    break;
7667
                }
7668
                gen_store_gpr(t0, rt);
7669
                tcg_temp_free(t0);
7670
            }
7671
            break;
7672
        case OPC_FORK:
7673
            check_insn(env, ctx, ASE_MT);
7674
            {
7675
                TCGv t0 = tcg_temp_local_new();
7676
                TCGv t1 = tcg_temp_local_new();
7677

    
7678
                gen_load_gpr(t0, rt);
7679
                gen_load_gpr(t1, rs);
7680
                gen_helper_fork(t0, t1);
7681
                tcg_temp_free(t0);
7682
                tcg_temp_free(t1);
7683
            }
7684
            break;
7685
        case OPC_YIELD:
7686
            check_insn(env, ctx, ASE_MT);
7687
            {
7688
                TCGv t0 = tcg_temp_local_new();
7689

    
7690
                gen_load_gpr(t0, rs);
7691
                gen_helper_yield(t0, t0);
7692
                gen_store_gpr(t0, rd);
7693
                tcg_temp_free(t0);
7694
            }
7695
            break;
7696
#if defined(TARGET_MIPS64)
7697
        case OPC_DEXTM ... OPC_DEXT:
7698
        case OPC_DINSM ... OPC_DINS:
7699
            check_insn(env, ctx, ISA_MIPS64R2);
7700
            check_mips_64(ctx);
7701
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7702
            break;
7703
        case OPC_DBSHFL:
7704
            check_insn(env, ctx, ISA_MIPS64R2);
7705
            check_mips_64(ctx);
7706
            op2 = MASK_DBSHFL(ctx->opcode);
7707
            gen_bshfl(ctx, op2, rt, rd);
7708
            break;
7709
#endif
7710
        default:            /* Invalid */
7711
            MIPS_INVAL("special3");
7712
            generate_exception(ctx, EXCP_RI);
7713
            break;
7714
        }
7715
        break;
7716
    case OPC_REGIMM:
7717
        op1 = MASK_REGIMM(ctx->opcode);
7718
        switch (op1) {
7719
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7720
        case OPC_BLTZAL ... OPC_BGEZALL:
7721
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7722
            return;
7723
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7724
        case OPC_TNEI:
7725
            gen_trap(ctx, op1, rs, -1, imm);
7726
            break;
7727
        case OPC_SYNCI:
7728
            check_insn(env, ctx, ISA_MIPS32R2);
7729
            /* Treat as NOP. */
7730
            break;
7731
        default:            /* Invalid */
7732
            MIPS_INVAL("regimm");
7733
            generate_exception(ctx, EXCP_RI);
7734
            break;
7735
        }
7736
        break;
7737
    case OPC_CP0:
7738
        check_cp0_enabled(ctx);
7739
        op1 = MASK_CP0(ctx->opcode);
7740
        switch (op1) {
7741
        case OPC_MFC0:
7742
        case OPC_MTC0:
7743
        case OPC_MFTR:
7744
        case OPC_MTTR:
7745
#if defined(TARGET_MIPS64)
7746
        case OPC_DMFC0:
7747
        case OPC_DMTC0:
7748
#endif
7749
#ifndef CONFIG_USER_ONLY
7750
            gen_cp0(env, ctx, op1, rt, rd);
7751
#endif /* !CONFIG_USER_ONLY */
7752
            break;
7753
        case OPC_C0_FIRST ... OPC_C0_LAST:
7754
#ifndef CONFIG_USER_ONLY
7755
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7756
#endif /* !CONFIG_USER_ONLY */
7757
            break;
7758
        case OPC_MFMC0:
7759
#ifndef CONFIG_USER_ONLY
7760
            {
7761
                TCGv t0 = tcg_temp_local_new();
7762

    
7763
                op2 = MASK_MFMC0(ctx->opcode);
7764
                switch (op2) {
7765
                case OPC_DMT:
7766
                    check_insn(env, ctx, ASE_MT);
7767
                    gen_helper_dmt(t0, t0);
7768
                    break;
7769
                case OPC_EMT:
7770
                    check_insn(env, ctx, ASE_MT);
7771
                    gen_helper_emt(t0, t0);
7772
                    break;
7773
                case OPC_DVPE:
7774
                    check_insn(env, ctx, ASE_MT);
7775
                    gen_helper_dvpe(t0, t0);
7776
                    break;
7777
                case OPC_EVPE:
7778
                    check_insn(env, ctx, ASE_MT);
7779
                    gen_helper_evpe(t0, t0);
7780
                    break;
7781
                case OPC_DI:
7782
                    check_insn(env, ctx, ISA_MIPS32R2);
7783
                    save_cpu_state(ctx, 1);
7784
                    gen_helper_di(t0);
7785
                    /* Stop translation as we may have switched the execution mode */
7786
                    ctx->bstate = BS_STOP;
7787
                    break;
7788
                case OPC_EI:
7789
                    check_insn(env, ctx, ISA_MIPS32R2);
7790
                    save_cpu_state(ctx, 1);
7791
                    gen_helper_ei(t0);
7792
                    /* Stop translation as we may have switched the execution mode */
7793
                    ctx->bstate = BS_STOP;
7794
                    break;
7795
                default:            /* Invalid */
7796
                    MIPS_INVAL("mfmc0");
7797
                    generate_exception(ctx, EXCP_RI);
7798
                    break;
7799
                }
7800
                gen_store_gpr(t0, rt);
7801
                tcg_temp_free(t0);
7802
            }
7803
#endif /* !CONFIG_USER_ONLY */
7804
            break;
7805
        case OPC_RDPGPR:
7806
            check_insn(env, ctx, ISA_MIPS32R2);
7807
            gen_load_srsgpr(rt, rd);
7808
            break;
7809
        case OPC_WRPGPR:
7810
            check_insn(env, ctx, ISA_MIPS32R2);
7811
            gen_store_srsgpr(rt, rd);
7812
            break;
7813
        default:
7814
            MIPS_INVAL("cp0");
7815
            generate_exception(ctx, EXCP_RI);
7816
            break;
7817
        }
7818
        break;
7819
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7820
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7821
         break;
7822
    case OPC_J ... OPC_JAL: /* Jump */
7823
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7824
         gen_compute_branch(ctx, op, rs, rt, offset);
7825
         return;
7826
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7827
    case OPC_BEQL ... OPC_BGTZL:
7828
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7829
         return;
7830
    case OPC_LB ... OPC_LWR: /* Load and stores */
7831
    case OPC_SB ... OPC_SW:
7832
    case OPC_SWR:
7833
    case OPC_LL:
7834
    case OPC_SC:
7835
         gen_ldst(ctx, op, rt, rs, imm);
7836
         break;
7837
    case OPC_CACHE:
7838
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7839
        /* Treat as NOP. */
7840
        break;
7841
    case OPC_PREF:
7842
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7843
        /* Treat as NOP. */
7844
        break;
7845

    
7846
    /* Floating point (COP1). */
7847
    case OPC_LWC1:
7848
    case OPC_LDC1:
7849
    case OPC_SWC1:
7850
    case OPC_SDC1:
7851
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7852
            save_cpu_state(ctx, 1);
7853
            check_cp1_enabled(ctx);
7854
            gen_flt_ldst(ctx, op, rt, rs, imm);
7855
        } else {
7856
            generate_exception_err(ctx, EXCP_CpU, 1);
7857
        }
7858
        break;
7859

    
7860
    case OPC_CP1:
7861
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7862
            save_cpu_state(ctx, 1);
7863
            check_cp1_enabled(ctx);
7864
            op1 = MASK_CP1(ctx->opcode);
7865
            switch (op1) {
7866
            case OPC_MFHC1:
7867
            case OPC_MTHC1:
7868
                check_insn(env, ctx, ISA_MIPS32R2);
7869
            case OPC_MFC1:
7870
            case OPC_CFC1:
7871
            case OPC_MTC1:
7872
            case OPC_CTC1:
7873
                gen_cp1(ctx, op1, rt, rd);
7874
                break;
7875
#if defined(TARGET_MIPS64)
7876
            case OPC_DMFC1:
7877
            case OPC_DMTC1:
7878
                check_insn(env, ctx, ISA_MIPS3);
7879
                gen_cp1(ctx, op1, rt, rd);
7880
                break;
7881
#endif
7882
            case OPC_BC1ANY2:
7883
            case OPC_BC1ANY4:
7884
                check_cop1x(ctx);
7885
                check_insn(env, ctx, ASE_MIPS3D);
7886
                /* fall through */
7887
            case OPC_BC1:
7888
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7889
                                    (rt >> 2) & 0x7, imm << 2);
7890
                return;
7891
            case OPC_S_FMT:
7892
            case OPC_D_FMT:
7893
            case OPC_W_FMT:
7894
            case OPC_L_FMT:
7895
            case OPC_PS_FMT:
7896
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7897
                           (imm >> 8) & 0x7);
7898
                break;
7899
            default:
7900
                MIPS_INVAL("cp1");
7901
                generate_exception (ctx, EXCP_RI);
7902
                break;
7903
            }
7904
        } else {
7905
            generate_exception_err(ctx, EXCP_CpU, 1);
7906
        }
7907
        break;
7908

    
7909
    /* COP2.  */
7910
    case OPC_LWC2:
7911
    case OPC_LDC2:
7912
    case OPC_SWC2:
7913
    case OPC_SDC2:
7914
    case OPC_CP2:
7915
        /* COP2: Not implemented. */
7916
        generate_exception_err(ctx, EXCP_CpU, 2);
7917
        break;
7918

    
7919
    case OPC_CP3:
7920
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7921
            save_cpu_state(ctx, 1);
7922
            check_cp1_enabled(ctx);
7923
            op1 = MASK_CP3(ctx->opcode);
7924
            switch (op1) {
7925
            case OPC_LWXC1:
7926
            case OPC_LDXC1:
7927
            case OPC_LUXC1:
7928
            case OPC_SWXC1:
7929
            case OPC_SDXC1:
7930
            case OPC_SUXC1:
7931
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7932
                break;
7933
            case OPC_PREFX:
7934
                /* Treat as NOP. */
7935
                break;
7936
            case OPC_ALNV_PS:
7937
            case OPC_MADD_S:
7938
            case OPC_MADD_D:
7939
            case OPC_MADD_PS:
7940
            case OPC_MSUB_S:
7941
            case OPC_MSUB_D:
7942
            case OPC_MSUB_PS:
7943
            case OPC_NMADD_S:
7944
            case OPC_NMADD_D:
7945
            case OPC_NMADD_PS:
7946
            case OPC_NMSUB_S:
7947
            case OPC_NMSUB_D:
7948
            case OPC_NMSUB_PS:
7949
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7950
                break;
7951
            default:
7952
                MIPS_INVAL("cp3");
7953
                generate_exception (ctx, EXCP_RI);
7954
                break;
7955
            }
7956
        } else {
7957
            generate_exception_err(ctx, EXCP_CpU, 1);
7958
        }
7959
        break;
7960

    
7961
#if defined(TARGET_MIPS64)
7962
    /* MIPS64 opcodes */
7963
    case OPC_LWU:
7964
    case OPC_LDL ... OPC_LDR:
7965
    case OPC_SDL ... OPC_SDR:
7966
    case OPC_LLD:
7967
    case OPC_LD:
7968
    case OPC_SCD:
7969
    case OPC_SD:
7970
        check_insn(env, ctx, ISA_MIPS3);
7971
        check_mips_64(ctx);
7972
        gen_ldst(ctx, op, rt, rs, imm);
7973
        break;
7974
    case OPC_DADDI ... OPC_DADDIU:
7975
        check_insn(env, ctx, ISA_MIPS3);
7976
        check_mips_64(ctx);
7977
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7978
        break;
7979
#endif
7980
    case OPC_JALX:
7981
        check_insn(env, ctx, ASE_MIPS16);
7982
        /* MIPS16: Not implemented. */
7983
    case OPC_MDMX:
7984
        check_insn(env, ctx, ASE_MDMX);
7985
        /* MDMX: Not implemented. */
7986
    default:            /* Invalid */
7987
        MIPS_INVAL("major opcode");
7988
        generate_exception(ctx, EXCP_RI);
7989
        break;
7990
    }
7991
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7992
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7993
        /* Branches completion */
7994
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7995
        ctx->bstate = BS_BRANCH;
7996
        save_cpu_state(ctx, 0);
7997
        /* FIXME: Need to clear can_do_io.  */
7998
        switch (hflags) {
7999
        case MIPS_HFLAG_B:
8000
            /* unconditional branch */
8001
            MIPS_DEBUG("unconditional branch");
8002
            gen_goto_tb(ctx, 0, ctx->btarget);
8003
            break;
8004
        case MIPS_HFLAG_BL:
8005
            /* blikely taken case */
8006
            MIPS_DEBUG("blikely branch taken");
8007
            gen_goto_tb(ctx, 0, ctx->btarget);
8008
            break;
8009
        case MIPS_HFLAG_BC:
8010
            /* Conditional branch */
8011
            MIPS_DEBUG("conditional branch");
8012
            {
8013
                int l1 = gen_new_label();
8014

    
8015
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8016
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8017
                gen_set_label(l1);
8018
                gen_goto_tb(ctx, 0, ctx->btarget);
8019
            }
8020
            break;
8021
        case MIPS_HFLAG_BR:
8022
            /* unconditional branch to register */
8023
            MIPS_DEBUG("branch to register");
8024
            tcg_gen_mov_tl(cpu_PC, btarget);
8025
            tcg_gen_exit_tb(0);
8026
            break;
8027
        default:
8028
            MIPS_DEBUG("unknown branch");
8029
            break;
8030
        }
8031
    }
8032
}
8033

    
8034
static inline void
8035
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8036
                                int search_pc)
8037
{
8038
    DisasContext ctx;
8039
    target_ulong pc_start;
8040
    uint16_t *gen_opc_end;
8041
    CPUBreakpoint *bp;
8042
    int j, lj = -1;
8043
    int num_insns;
8044
    int max_insns;
8045

    
8046
    if (search_pc)
8047
        qemu_log("search pc %d\n", search_pc);
8048

    
8049
    pc_start = tb->pc;
8050
    /* Leave some spare opc slots for branch handling. */
8051
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8052
    ctx.pc = pc_start;
8053
    ctx.saved_pc = -1;
8054
    ctx.tb = tb;
8055
    ctx.bstate = BS_NONE;
8056
    /* Restore delay slot state from the tb context.  */
8057
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8058
    restore_cpu_state(env, &ctx);
8059
#ifdef CONFIG_USER_ONLY
8060
        ctx.mem_idx = MIPS_HFLAG_UM;
8061
#else
8062
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8063
#endif
8064
    num_insns = 0;
8065
    max_insns = tb->cflags & CF_COUNT_MASK;
8066
    if (max_insns == 0)
8067
        max_insns = CF_COUNT_MASK;
8068
#ifdef DEBUG_DISAS
8069
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8070
    /* FIXME: This may print out stale hflags from env... */
8071
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8072
#endif
8073
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8074
    gen_icount_start();
8075
    while (ctx.bstate == BS_NONE) {
8076
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8077
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8078
                if (bp->pc == ctx.pc) {
8079
                    save_cpu_state(&ctx, 1);
8080
                    ctx.bstate = BS_BRANCH;
8081
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8082
                    /* Include the breakpoint location or the tb won't
8083
                     * be flushed when it must be.  */
8084
                    ctx.pc += 4;
8085
                    goto done_generating;
8086
                }
8087
            }
8088
        }
8089

    
8090
        if (search_pc) {
8091
            j = gen_opc_ptr - gen_opc_buf;
8092
            if (lj < j) {
8093
                lj++;
8094
                while (lj < j)
8095
                    gen_opc_instr_start[lj++] = 0;
8096
            }
8097
            gen_opc_pc[lj] = ctx.pc;
8098
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8099
            gen_opc_instr_start[lj] = 1;
8100
            gen_opc_icount[lj] = num_insns;
8101
        }
8102
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8103
            gen_io_start();
8104
        ctx.opcode = ldl_code(ctx.pc);
8105
        decode_opc(env, &ctx);
8106
        ctx.pc += 4;
8107
        num_insns++;
8108

    
8109
        if (env->singlestep_enabled)
8110
            break;
8111

    
8112
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8113
            break;
8114

    
8115
        if (gen_opc_ptr >= gen_opc_end)
8116
            break;
8117

    
8118
        if (num_insns >= max_insns)
8119
            break;
8120

    
8121
        if (singlestep)
8122
            break;
8123
    }
8124
    if (tb->cflags & CF_LAST_IO)
8125
        gen_io_end();
8126
    if (env->singlestep_enabled) {
8127
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8128
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8129
    } else {
8130
        switch (ctx.bstate) {
8131
        case BS_STOP:
8132
            gen_helper_interrupt_restart();
8133
            gen_goto_tb(&ctx, 0, ctx.pc);
8134
            break;
8135
        case BS_NONE:
8136
            save_cpu_state(&ctx, 0);
8137
            gen_goto_tb(&ctx, 0, ctx.pc);
8138
            break;
8139
        case BS_EXCP:
8140
            gen_helper_interrupt_restart();
8141
            tcg_gen_exit_tb(0);
8142
            break;
8143
        case BS_BRANCH:
8144
        default:
8145
            break;
8146
        }
8147
    }
8148
done_generating:
8149
    gen_icount_end(tb, num_insns);
8150
    *gen_opc_ptr = INDEX_op_end;
8151
    if (search_pc) {
8152
        j = gen_opc_ptr - gen_opc_buf;
8153
        lj++;
8154
        while (lj <= j)
8155
            gen_opc_instr_start[lj++] = 0;
8156
    } else {
8157
        tb->size = ctx.pc - pc_start;
8158
        tb->icount = num_insns;
8159
    }
8160
#ifdef DEBUG_DISAS
8161
    LOG_DISAS("\n");
8162
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8163
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8164
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8165
        qemu_log("\n");
8166
    }
8167
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8168
#endif
8169
}
8170

    
8171
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8172
{
8173
    gen_intermediate_code_internal(env, tb, 0);
8174
}
8175

    
8176
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8177
{
8178
    gen_intermediate_code_internal(env, tb, 1);
8179
}
8180

    
8181
static void fpu_dump_state(CPUState *env, FILE *f,
8182
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8183
                           int flags)
8184
{
8185
    int i;
8186
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8187

    
8188
#define printfpr(fp)                                                        \
8189
    do {                                                                    \
8190
        if (is_fpu64)                                                       \
8191
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8192
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8193
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8194
        else {                                                              \
8195
            fpr_t tmp;                                                      \
8196
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8197
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8198
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8199
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8200
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8201
        }                                                                   \
8202
    } while(0)
8203

    
8204

    
8205
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8206
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8207
                get_float_exception_flags(&env->active_fpu.fp_status));
8208
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8209
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8210
        printfpr(&env->active_fpu.fpr[i]);
8211
    }
8212

    
8213
#undef printfpr
8214
}
8215

    
8216
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8217
/* Debug help: The architecture requires 32bit code to maintain proper
8218
   sign-extended values on 64bit machines.  */
8219

    
8220
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8221

    
8222
static void
8223
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8224
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8225
                                int flags)
8226
{
8227
    int i;
8228

    
8229
    if (!SIGN_EXT_P(env->active_tc.PC))
8230
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8231
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8232
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8233
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8234
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8235
    if (!SIGN_EXT_P(env->btarget))
8236
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8237

    
8238
    for (i = 0; i < 32; i++) {
8239
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8240
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8241
    }
8242

    
8243
    if (!SIGN_EXT_P(env->CP0_EPC))
8244
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8245
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8246
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8247
}
8248
#endif
8249

    
8250
void cpu_dump_state (CPUState *env, FILE *f,
8251
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8252
                     int flags)
8253
{
8254
    int i;
8255

    
8256
    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",
8257
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8258
                env->hflags, env->btarget, env->bcond);
8259
    for (i = 0; i < 32; i++) {
8260
        if ((i & 3) == 0)
8261
            cpu_fprintf(f, "GPR%02d:", i);
8262
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8263
        if ((i & 3) == 3)
8264
            cpu_fprintf(f, "\n");
8265
    }
8266

    
8267
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8268
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8269
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8270
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8271
    if (env->hflags & MIPS_HFLAG_FPU)
8272
        fpu_dump_state(env, f, cpu_fprintf, flags);
8273
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8274
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8275
#endif
8276
}
8277

    
8278
static void mips_tcg_init(void)
8279
{
8280
    int i;
8281
    static int inited;
8282

    
8283
    /* Initialize various static tables. */
8284
    if (inited)
8285
        return;
8286

    
8287
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8288
    for (i = 0; i < 32; i++)
8289
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8290
                                        offsetof(CPUState, active_tc.gpr[i]),
8291
                                        regnames[i]);
8292
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8293
                                offsetof(CPUState, active_tc.PC), "PC");
8294
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8295
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8296
                                       offsetof(CPUState, active_tc.HI[i]),
8297
                                       regnames_HI[i]);
8298
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8299
                                       offsetof(CPUState, active_tc.LO[i]),
8300
                                       regnames_LO[i]);
8301
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8302
                                        offsetof(CPUState, active_tc.ACX[i]),
8303
                                        regnames_ACX[i]);
8304
    }
8305
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8306
                                     offsetof(CPUState, active_tc.DSPControl),
8307
                                     "DSPControl");
8308
    bcond = tcg_global_mem_new(TCG_AREG0,
8309
                               offsetof(CPUState, bcond), "bcond");
8310
    btarget = tcg_global_mem_new(TCG_AREG0,
8311
                                 offsetof(CPUState, btarget), "btarget");
8312
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8313
                                    offsetof(CPUState, hflags), "hflags");
8314

    
8315
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8316
                                      offsetof(CPUState, active_fpu.fcr0),
8317
                                      "fcr0");
8318
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8319
                                       offsetof(CPUState, active_fpu.fcr31),
8320
                                       "fcr31");
8321

    
8322
    /* register helpers */
8323
#define GEN_HELPER 2
8324
#include "helper.h"
8325

    
8326
    inited = 1;
8327
}
8328

    
8329
#include "translate_init.c"
8330

    
8331
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8332
{
8333
    CPUMIPSState *env;
8334
    const mips_def_t *def;
8335

    
8336
    def = cpu_mips_find_by_name(cpu_model);
8337
    if (!def)
8338
        return NULL;
8339
    env = qemu_mallocz(sizeof(CPUMIPSState));
8340
    env->cpu_model = def;
8341

    
8342
    cpu_exec_init(env);
8343
    env->cpu_model_str = cpu_model;
8344
    mips_tcg_init();
8345
    cpu_reset(env);
8346
    return env;
8347
}
8348

    
8349
void cpu_reset (CPUMIPSState *env)
8350
{
8351
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8352
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8353
        log_cpu_state(env, 0);
8354
    }
8355

    
8356
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8357

    
8358
    tlb_flush(env, 1);
8359

    
8360
    /* Minimal init */
8361
#if defined(CONFIG_USER_ONLY)
8362
    env->hflags = MIPS_HFLAG_UM;
8363
#else
8364
    if (env->hflags & MIPS_HFLAG_BMASK) {
8365
        /* If the exception was raised from a delay slot,
8366
           come back to the jump.  */
8367
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8368
    } else {
8369
        env->CP0_ErrorEPC = env->active_tc.PC;
8370
    }
8371
    env->active_tc.PC = (int32_t)0xBFC00000;
8372
    env->CP0_Wired = 0;
8373
    /* SMP not implemented */
8374
    env->CP0_EBase = 0x80000000;
8375
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8376
    /* vectored interrupts not implemented, timer on int 7,
8377
       no performance counters. */
8378
    env->CP0_IntCtl = 0xe0000000;
8379
    {
8380
        int i;
8381

    
8382
        for (i = 0; i < 7; i++) {
8383
            env->CP0_WatchLo[i] = 0;
8384
            env->CP0_WatchHi[i] = 0x80000000;
8385
        }
8386
        env->CP0_WatchLo[7] = 0;
8387
        env->CP0_WatchHi[7] = 0;
8388
    }
8389
    /* Count register increments in debug mode, EJTAG version 1 */
8390
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8391
    env->hflags = MIPS_HFLAG_CP0;
8392
#endif
8393
    env->exception_index = EXCP_NONE;
8394
    cpu_mips_register(env, env->cpu_model);
8395
}
8396

    
8397
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8398
                unsigned long searched_pc, int pc_pos, void *puc)
8399
{
8400
    env->active_tc.PC = gen_opc_pc[pc_pos];
8401
    env->hflags &= ~MIPS_HFLAG_BMASK;
8402
    env->hflags |= gen_opc_hflags[pc_pos];
8403
}