Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c01fccd2

History | View | Annotate | Download (245.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
//#define MIPS_SINGLE_STEP
42

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

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

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

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
438
#include "gen-icount.h"
439

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

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

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

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

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

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

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

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

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

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

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

    
504
static const char *fregnames_64[] =
505
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
506
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
507
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
508
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
509

    
510
static const char *fregnames_h[] =
511
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
512
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
513
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
514
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
515

    
516
#ifdef MIPS_DEBUG_DISAS
517
#define MIPS_DEBUG(fmt, args...)                         \
518
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
519
                       TARGET_FMT_lx ": %08x " fmt "\n", \
520
                       ctx->pc, ctx->opcode , ##args)
521
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
522
#else
523
#define MIPS_DEBUG(fmt, args...) do { } while(0)
524
#define LOG_DISAS(...) do { } while (0)
525
#endif
526

    
527
#define MIPS_INVAL(op)                                                        \
528
do {                                                                          \
529
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
530
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
531
} while (0)
532

    
533
/* General purpose registers moves. */
534
static inline void gen_load_gpr (TCGv t, int reg)
535
{
536
    if (reg == 0)
537
        tcg_gen_movi_tl(t, 0);
538
    else
539
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
540
}
541

    
542
static inline void gen_store_gpr (TCGv t, int reg)
543
{
544
    if (reg != 0)
545
        tcg_gen_mov_tl(cpu_gpr[reg], t);
546
}
547

    
548
/* Moves to/from ACX register.  */
549
static inline void gen_load_ACX (TCGv t, int reg)
550
{
551
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
552
}
553

    
554
static inline void gen_store_ACX (TCGv t, int reg)
555
{
556
    tcg_gen_mov_tl(cpu_ACX[reg], t);
557
}
558

    
559
/* Moves to/from shadow registers. */
560
static inline void gen_load_srsgpr (int from, int to)
561
{
562
    TCGv r_tmp1 = tcg_temp_new();
563

    
564
    if (from == 0)
565
        tcg_gen_movi_tl(r_tmp1, 0);
566
    else {
567
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
568
        TCGv_ptr addr = tcg_temp_new_ptr();
569

    
570
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
571
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
572
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
573
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
574
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
575
        tcg_gen_add_ptr(addr, cpu_env, addr);
576

    
577
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
578
        tcg_temp_free_ptr(addr);
579
        tcg_temp_free_i32(r_tmp2);
580
    }
581
    gen_store_gpr(r_tmp1, to);
582
    tcg_temp_free(r_tmp1);
583
}
584

    
585
static inline void gen_store_srsgpr (int from, int to)
586
{
587
    if (to != 0) {
588
        TCGv r_tmp1 = tcg_temp_new();
589
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
590
        TCGv_ptr addr = tcg_temp_new_ptr();
591

    
592
        gen_load_gpr(r_tmp1, from);
593
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
594
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
595
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
596
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
597
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
598
        tcg_gen_add_ptr(addr, cpu_env, addr);
599

    
600
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
601
        tcg_temp_free_ptr(addr);
602
        tcg_temp_free_i32(r_tmp2);
603
        tcg_temp_free(r_tmp1);
604
    }
605
}
606

    
607
/* Floating point register moves. */
608
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
609
{
610
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
611
}
612

    
613
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
614
{
615
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
616
}
617

    
618
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
619
{
620
    if (ctx->hflags & MIPS_HFLAG_F64)
621
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
622
    else {
623
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
624
    }
625
}
626

    
627
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
628
{
629
    if (ctx->hflags & MIPS_HFLAG_F64)
630
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
631
    else {
632
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
633
        tcg_gen_shri_i64(t, t, 32);
634
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
635
    }
636
}
637

    
638
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
639
{
640
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
641
}
642

    
643
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
644
{
645
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
646
}
647

    
648
static inline void get_fp_cond (TCGv_i32 t)
649
{
650
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
651
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
652

    
653
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
654
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
655
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
656
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
657
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
658
    tcg_temp_free_i32(r_tmp1);
659
    tcg_temp_free_i32(r_tmp2);
660
}
661

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

    
687
FOP_CONDS(, d, 64)
688
FOP_CONDS(abs, d, 64)
689
FOP_CONDS(, s, 32)
690
FOP_CONDS(abs, s, 32)
691
FOP_CONDS(, ps, 64)
692
FOP_CONDS(abs, ps, 64)
693
#undef FOP_CONDS
694

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

    
717
#define OP_CONDI(name, cond)                                  \
718
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
719
{                                                             \
720
    int l1 = gen_new_label();                                 \
721
    int l2 = gen_new_label();                                 \
722
                                                              \
723
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
724
    tcg_gen_movi_tl(t, 0);                                    \
725
    tcg_gen_br(l2);                                           \
726
    gen_set_label(l1);                                        \
727
    tcg_gen_movi_tl(t, 1);                                    \
728
    gen_set_label(l2);                                        \
729
}
730
OP_CONDI(lti, TCG_COND_LT);
731
OP_CONDI(ltiu, TCG_COND_LTU);
732
#undef OP_CONDI
733

    
734
#define OP_CONDZ(name, cond)                                  \
735
static inline void glue(gen_op_, name) (TCGv t)               \
736
{                                                             \
737
    int l1 = gen_new_label();                                 \
738
    int l2 = gen_new_label();                                 \
739
                                                              \
740
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
741
    tcg_gen_movi_tl(t, 0);                                    \
742
    tcg_gen_br(l2);                                           \
743
    gen_set_label(l1);                                        \
744
    tcg_gen_movi_tl(t, 1);                                    \
745
    gen_set_label(l2);                                        \
746
}
747
OP_CONDZ(gez, TCG_COND_GE);
748
OP_CONDZ(gtz, TCG_COND_GT);
749
OP_CONDZ(lez, TCG_COND_LE);
750
OP_CONDZ(ltz, TCG_COND_LT);
751
#undef OP_CONDZ
752

    
753
static inline void gen_save_pc(target_ulong pc)
754
{
755
    tcg_gen_movi_tl(cpu_PC, pc);
756
}
757

    
758
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
759
{
760
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
761
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
762
        gen_save_pc(ctx->pc);
763
        ctx->saved_pc = ctx->pc;
764
    }
765
    if (ctx->hflags != ctx->saved_hflags) {
766
        TCGv_i32 r_tmp = tcg_temp_new_i32();
767

    
768
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
769
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
770
        tcg_temp_free_i32(r_tmp);
771
        ctx->saved_hflags = ctx->hflags;
772
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
773
        case MIPS_HFLAG_BR:
774
            break;
775
        case MIPS_HFLAG_BC:
776
        case MIPS_HFLAG_BL:
777
        case MIPS_HFLAG_B:
778
            tcg_gen_movi_tl(btarget, ctx->btarget);
779
            break;
780
        }
781
    }
782
}
783

    
784
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
785
{
786
    ctx->saved_hflags = ctx->hflags;
787
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
788
    case MIPS_HFLAG_BR:
789
        break;
790
    case MIPS_HFLAG_BC:
791
    case MIPS_HFLAG_BL:
792
    case MIPS_HFLAG_B:
793
        ctx->btarget = env->btarget;
794
        break;
795
    }
796
}
797

    
798
static inline void
799
generate_exception_err (DisasContext *ctx, int excp, int err)
800
{
801
    TCGv_i32 texcp = tcg_const_i32(excp);
802
    TCGv_i32 terr = tcg_const_i32(err);
803
    save_cpu_state(ctx, 1);
804
    gen_helper_raise_exception_err(texcp, terr);
805
    tcg_temp_free_i32(terr);
806
    tcg_temp_free_i32(texcp);
807
    gen_helper_interrupt_restart();
808
    tcg_gen_exit_tb(0);
809
}
810

    
811
static inline void
812
generate_exception (DisasContext *ctx, int excp)
813
{
814
    save_cpu_state(ctx, 1);
815
    gen_helper_0i(raise_exception, excp);
816
    gen_helper_interrupt_restart();
817
    tcg_gen_exit_tb(0);
818
}
819

    
820
/* Addresses computation */
821
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
822
{
823
    tcg_gen_add_tl(t0, t0, t1);
824

    
825
#if defined(TARGET_MIPS64)
826
    /* For compatibility with 32-bit code, data reference in user mode
827
       with Status_UX = 0 should be casted to 32-bit and sign extended.
828
       See the MIPS64 PRA manual, section 4.10. */
829
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
830
        !(ctx->hflags & MIPS_HFLAG_UX)) {
831
        tcg_gen_ext32s_i64(t0, t0);
832
    }
833
#endif
834
}
835

    
836
static inline void check_cp0_enabled(DisasContext *ctx)
837
{
838
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
839
        generate_exception_err(ctx, EXCP_CpU, 1);
840
}
841

    
842
static inline void check_cp1_enabled(DisasContext *ctx)
843
{
844
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
845
        generate_exception_err(ctx, EXCP_CpU, 1);
846
}
847

    
848
/* Verify that the processor is running with COP1X instructions enabled.
849
   This is associated with the nabla symbol in the MIPS32 and MIPS64
850
   opcode tables.  */
851

    
852
static inline void check_cop1x(DisasContext *ctx)
853
{
854
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
855
        generate_exception(ctx, EXCP_RI);
856
}
857

    
858
/* Verify that the processor is running with 64-bit floating-point
859
   operations enabled.  */
860

    
861
static inline void check_cp1_64bitmode(DisasContext *ctx)
862
{
863
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
864
        generate_exception(ctx, EXCP_RI);
865
}
866

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

    
884
/* This code generates a "reserved instruction" exception if the
885
   CPU does not support the instruction set corresponding to flags. */
886
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
887
{
888
    if (unlikely(!(env->insn_flags & flags)))
889
        generate_exception(ctx, EXCP_RI);
890
}
891

    
892
/* This code generates a "reserved instruction" exception if 64-bit
893
   instructions are not enabled. */
894
static inline void check_mips_64(DisasContext *ctx)
895
{
896
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
897
        generate_exception(ctx, EXCP_RI);
898
}
899

    
900
/* load/store instructions. */
901
#define OP_LD(insn,fname)                                        \
902
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
903
{                                                                \
904
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
905
}
906
OP_LD(lb,ld8s);
907
OP_LD(lbu,ld8u);
908
OP_LD(lh,ld16s);
909
OP_LD(lhu,ld16u);
910
OP_LD(lw,ld32s);
911
#if defined(TARGET_MIPS64)
912
OP_LD(lwu,ld32u);
913
OP_LD(ld,ld64);
914
#endif
915
#undef OP_LD
916

    
917
#define OP_ST(insn,fname)                                        \
918
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
919
{                                                                \
920
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
921
}
922
OP_ST(sb,st8);
923
OP_ST(sh,st16);
924
OP_ST(sw,st32);
925
#if defined(TARGET_MIPS64)
926
OP_ST(sd,st64);
927
#endif
928
#undef OP_ST
929

    
930
#define OP_LD_ATOMIC(insn,fname)                                        \
931
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
932
{                                                                       \
933
    tcg_gen_mov_tl(t1, t0);                                             \
934
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
935
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
936
}
937
OP_LD_ATOMIC(ll,ld32s);
938
#if defined(TARGET_MIPS64)
939
OP_LD_ATOMIC(lld,ld64);
940
#endif
941
#undef OP_LD_ATOMIC
942

    
943
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
944
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
945
{                                                                       \
946
    TCGv r_tmp = tcg_temp_local_new();                       \
947
    int l1 = gen_new_label();                                           \
948
    int l2 = gen_new_label();                                           \
949
    int l3 = gen_new_label();                                           \
950
                                                                        \
951
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
952
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
953
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
954
    generate_exception(ctx, EXCP_AdES);                                 \
955
    gen_set_label(l1);                                                  \
956
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
957
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
958
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
959
    tcg_gen_movi_tl(t0, 1);                                             \
960
    tcg_gen_br(l3);                                                     \
961
    gen_set_label(l2);                                                  \
962
    tcg_gen_movi_tl(t0, 0);                                             \
963
    gen_set_label(l3);                                                  \
964
    tcg_temp_free(r_tmp);                                               \
965
}
966
OP_ST_ATOMIC(sc,st32,0x3);
967
#if defined(TARGET_MIPS64)
968
OP_ST_ATOMIC(scd,st64,0x7);
969
#endif
970
#undef OP_ST_ATOMIC
971

    
972
/* Load and store */
973
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
974
                      int base, int16_t offset)
975
{
976
    const char *opn = "ldst";
977
    TCGv t0 = tcg_temp_local_new();
978
    TCGv t1 = tcg_temp_local_new();
979

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

    
1135
/* Load and store */
1136
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1137
                          int base, int16_t offset)
1138
{
1139
    const char *opn = "flt_ldst";
1140
    TCGv t0 = tcg_temp_local_new();
1141

    
1142
    if (base == 0) {
1143
        tcg_gen_movi_tl(t0, offset);
1144
    } else if (offset == 0) {
1145
        gen_load_gpr(t0, base);
1146
    } else {
1147
        tcg_gen_movi_tl(t0, offset);
1148
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1149
    }
1150
    /* Don't do NOP if destination is zero: we must perform the actual
1151
       memory access. */
1152
    switch (opc) {
1153
    case OPC_LWC1:
1154
        {
1155
            TCGv_i32 fp0 = tcg_temp_new_i32();
1156
            TCGv t1 = tcg_temp_new();
1157

    
1158
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1159
            tcg_gen_trunc_tl_i32(fp0, t1);
1160
            gen_store_fpr32(fp0, ft);
1161
            tcg_temp_free(t1);
1162
            tcg_temp_free_i32(fp0);
1163
        }
1164
        opn = "lwc1";
1165
        break;
1166
    case OPC_SWC1:
1167
        {
1168
            TCGv_i32 fp0 = tcg_temp_new_i32();
1169
            TCGv t1 = tcg_temp_new();
1170

    
1171
            gen_load_fpr32(fp0, ft);
1172
            tcg_gen_extu_i32_tl(t1, fp0);
1173
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1174
            tcg_temp_free(t1);
1175
            tcg_temp_free_i32(fp0);
1176
        }
1177
        opn = "swc1";
1178
        break;
1179
    case OPC_LDC1:
1180
        {
1181
            TCGv_i64 fp0 = tcg_temp_new_i64();
1182

    
1183
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1184
            gen_store_fpr64(ctx, fp0, ft);
1185
            tcg_temp_free_i64(fp0);
1186
        }
1187
        opn = "ldc1";
1188
        break;
1189
    case OPC_SDC1:
1190
        {
1191
            TCGv_i64 fp0 = tcg_temp_new_i64();
1192

    
1193
            gen_load_fpr64(ctx, fp0, ft);
1194
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1195
            tcg_temp_free_i64(fp0);
1196
        }
1197
        opn = "sdc1";
1198
        break;
1199
    default:
1200
        MIPS_INVAL(opn);
1201
        generate_exception(ctx, EXCP_RI);
1202
        goto out;
1203
    }
1204
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1205
 out:
1206
    tcg_temp_free(t0);
1207
}
1208

    
1209
/* Arithmetic with immediate operand */
1210
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1211
                           int rt, int rs, int16_t imm)
1212
{
1213
    target_ulong uimm;
1214
    const char *opn = "imm arith";
1215
    TCGv t0 = tcg_temp_local_new();
1216

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

    
1265
            save_cpu_state(ctx, 1);
1266
            tcg_gen_ext32s_tl(r_tmp1, t0);
1267
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1268

    
1269
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1270
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1271
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1272
            tcg_temp_free(r_tmp2);
1273
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1274
            /* operands of same sign, result different sign */
1275
            generate_exception(ctx, EXCP_OVERFLOW);
1276
            gen_set_label(l1);
1277
            tcg_temp_free(r_tmp1);
1278

    
1279
            tcg_gen_ext32s_tl(t0, t0);
1280
        }
1281
        opn = "addi";
1282
        break;
1283
    case OPC_ADDIU:
1284
        tcg_gen_addi_tl(t0, t0, uimm);
1285
        tcg_gen_ext32s_tl(t0, t0);
1286
        opn = "addiu";
1287
        break;
1288
#if defined(TARGET_MIPS64)
1289
    case OPC_DADDI:
1290
        {
1291
            TCGv r_tmp1 = tcg_temp_new();
1292
            TCGv r_tmp2 = tcg_temp_new();
1293
            int l1 = gen_new_label();
1294

    
1295
            save_cpu_state(ctx, 1);
1296
            tcg_gen_mov_tl(r_tmp1, t0);
1297
            tcg_gen_addi_tl(t0, t0, uimm);
1298

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

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

    
1463
/* Arithmetic */
1464
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1465
                       int rd, int rs, int rt)
1466
{
1467
    const char *opn = "arith";
1468
    TCGv t0 = tcg_temp_local_new();
1469
    TCGv t1 = tcg_temp_local_new();
1470

    
1471
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1472
       && opc != OPC_DADD && opc != OPC_DSUB) {
1473
        /* If no destination, treat it as a NOP.
1474
           For add & sub, we must generate the overflow exception when needed. */
1475
        MIPS_DEBUG("NOP");
1476
        goto out;
1477
    }
1478
    gen_load_gpr(t0, rs);
1479
    /* Specialcase the conventional move operation. */
1480
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1481
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1482
        gen_store_gpr(t0, rd);
1483
        goto out;
1484
    }
1485
    gen_load_gpr(t1, rt);
1486
    switch (opc) {
1487
    case OPC_ADD:
1488
        {
1489
            TCGv r_tmp1 = tcg_temp_new();
1490
            TCGv r_tmp2 = tcg_temp_new();
1491
            int l1 = gen_new_label();
1492

    
1493
            save_cpu_state(ctx, 1);
1494
            tcg_gen_ext32s_tl(r_tmp1, t0);
1495
            tcg_gen_ext32s_tl(r_tmp2, t1);
1496
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1497

    
1498
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1499
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1500
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1501
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1502
            tcg_temp_free(r_tmp2);
1503
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1504
            /* operands of same sign, result different sign */
1505
            generate_exception(ctx, EXCP_OVERFLOW);
1506
            gen_set_label(l1);
1507
            tcg_temp_free(r_tmp1);
1508

    
1509
            tcg_gen_ext32s_tl(t0, t0);
1510
        }
1511
        opn = "add";
1512
        break;
1513
    case OPC_ADDU:
1514
        tcg_gen_add_tl(t0, t0, t1);
1515
        tcg_gen_ext32s_tl(t0, t0);
1516
        opn = "addu";
1517
        break;
1518
    case OPC_SUB:
1519
        {
1520
            TCGv r_tmp1 = tcg_temp_new();
1521
            TCGv r_tmp2 = tcg_temp_new();
1522
            int l1 = gen_new_label();
1523

    
1524
            save_cpu_state(ctx, 1);
1525
            tcg_gen_ext32s_tl(r_tmp1, t0);
1526
            tcg_gen_ext32s_tl(r_tmp2, t1);
1527
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1528

    
1529
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1530
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1531
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1532
            tcg_temp_free(r_tmp2);
1533
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1534
            /* operands of different sign, first operand and result different sign */
1535
            generate_exception(ctx, EXCP_OVERFLOW);
1536
            gen_set_label(l1);
1537
            tcg_temp_free(r_tmp1);
1538

    
1539
            tcg_gen_ext32s_tl(t0, t0);
1540
        }
1541
        opn = "sub";
1542
        break;
1543
    case OPC_SUBU:
1544
        tcg_gen_sub_tl(t0, t0, t1);
1545
        tcg_gen_ext32s_tl(t0, t0);
1546
        opn = "subu";
1547
        break;
1548
#if defined(TARGET_MIPS64)
1549
    case OPC_DADD:
1550
        {
1551
            TCGv r_tmp1 = tcg_temp_new();
1552
            TCGv r_tmp2 = tcg_temp_new();
1553
            int l1 = gen_new_label();
1554

    
1555
            save_cpu_state(ctx, 1);
1556
            tcg_gen_mov_tl(r_tmp1, t0);
1557
            tcg_gen_add_tl(t0, t0, t1);
1558

    
1559
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1560
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1561
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1562
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1563
            tcg_temp_free(r_tmp2);
1564
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1565
            /* operands of same sign, result different sign */
1566
            generate_exception(ctx, EXCP_OVERFLOW);
1567
            gen_set_label(l1);
1568
            tcg_temp_free(r_tmp1);
1569
        }
1570
        opn = "dadd";
1571
        break;
1572
    case OPC_DADDU:
1573
        tcg_gen_add_tl(t0, t0, t1);
1574
        opn = "daddu";
1575
        break;
1576
    case OPC_DSUB:
1577
        {
1578
            TCGv r_tmp1 = tcg_temp_new();
1579
            TCGv r_tmp2 = tcg_temp_new();
1580
            int l1 = gen_new_label();
1581

    
1582
            save_cpu_state(ctx, 1);
1583
            tcg_gen_mov_tl(r_tmp1, t0);
1584
            tcg_gen_sub_tl(t0, t0, t1);
1585

    
1586
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1587
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1588
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1589
            tcg_temp_free(r_tmp2);
1590
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1591
            /* operands of different sign, first operand and result different sign */
1592
            generate_exception(ctx, EXCP_OVERFLOW);
1593
            gen_set_label(l1);
1594
            tcg_temp_free(r_tmp1);
1595
        }
1596
        opn = "dsub";
1597
        break;
1598
    case OPC_DSUBU:
1599
        tcg_gen_sub_tl(t0, t0, t1);
1600
        opn = "dsubu";
1601
        break;
1602
#endif
1603
    case OPC_SLT:
1604
        gen_op_lt(t0, t1);
1605
        opn = "slt";
1606
        break;
1607
    case OPC_SLTU:
1608
        gen_op_ltu(t0, t1);
1609
        opn = "sltu";
1610
        break;
1611
    case OPC_AND:
1612
        tcg_gen_and_tl(t0, t0, t1);
1613
        opn = "and";
1614
        break;
1615
    case OPC_NOR:
1616
        tcg_gen_or_tl(t0, t0, t1);
1617
        tcg_gen_not_tl(t0, t0);
1618
        opn = "nor";
1619
        break;
1620
    case OPC_OR:
1621
        tcg_gen_or_tl(t0, t0, t1);
1622
        opn = "or";
1623
        break;
1624
    case OPC_XOR:
1625
        tcg_gen_xor_tl(t0, t0, t1);
1626
        opn = "xor";
1627
        break;
1628
    case OPC_MUL:
1629
        tcg_gen_mul_tl(t0, t0, t1);
1630
        tcg_gen_ext32s_tl(t0, t0);
1631
        opn = "mul";
1632
        break;
1633
    case OPC_MOVN:
1634
        {
1635
            int l1 = gen_new_label();
1636

    
1637
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1638
            gen_store_gpr(t0, rd);
1639
            gen_set_label(l1);
1640
        }
1641
        opn = "movn";
1642
        goto print;
1643
    case OPC_MOVZ:
1644
        {
1645
            int l1 = gen_new_label();
1646

    
1647
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1648
            gen_store_gpr(t0, rd);
1649
            gen_set_label(l1);
1650
        }
1651
        opn = "movz";
1652
        goto print;
1653
    case OPC_SLLV:
1654
        tcg_gen_andi_tl(t0, t0, 0x1f);
1655
        tcg_gen_shl_tl(t0, t1, t0);
1656
        tcg_gen_ext32s_tl(t0, t0);
1657
        opn = "sllv";
1658
        break;
1659
    case OPC_SRAV:
1660
        tcg_gen_ext32s_tl(t1, t1);
1661
        tcg_gen_andi_tl(t0, t0, 0x1f);
1662
        tcg_gen_sar_tl(t0, t1, t0);
1663
        opn = "srav";
1664
        break;
1665
    case OPC_SRLV:
1666
        switch ((ctx->opcode >> 6) & 0x1f) {
1667
        case 0:
1668
            tcg_gen_ext32u_tl(t1, t1);
1669
            tcg_gen_andi_tl(t0, t0, 0x1f);
1670
            tcg_gen_shr_tl(t0, t1, t0);
1671
            tcg_gen_ext32s_tl(t0, t0);
1672
            opn = "srlv";
1673
            break;
1674
        case 1:
1675
            /* rotrv is decoded as srlv on non-R2 CPUs */
1676
            if (env->insn_flags & ISA_MIPS32R2) {
1677
                int l1 = gen_new_label();
1678
                int l2 = gen_new_label();
1679

    
1680
                tcg_gen_andi_tl(t0, t0, 0x1f);
1681
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1682
                {
1683
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1684
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1685

    
1686
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1687
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1688
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1689
                    tcg_temp_free_i32(r_tmp1);
1690
                    tcg_temp_free_i32(r_tmp2);
1691
                    tcg_gen_br(l2);
1692
                }
1693
                gen_set_label(l1);
1694
                tcg_gen_mov_tl(t0, t1);
1695
                gen_set_label(l2);
1696
                opn = "rotrv";
1697
            } else {
1698
                tcg_gen_ext32u_tl(t1, t1);
1699
                tcg_gen_andi_tl(t0, t0, 0x1f);
1700
                tcg_gen_shr_tl(t0, t1, t0);
1701
                tcg_gen_ext32s_tl(t0, t0);
1702
                opn = "srlv";
1703
            }
1704
            break;
1705
        default:
1706
            MIPS_INVAL("invalid srlv flag");
1707
            generate_exception(ctx, EXCP_RI);
1708
            break;
1709
        }
1710
        break;
1711
#if defined(TARGET_MIPS64)
1712
    case OPC_DSLLV:
1713
        tcg_gen_andi_tl(t0, t0, 0x3f);
1714
        tcg_gen_shl_tl(t0, t1, t0);
1715
        opn = "dsllv";
1716
        break;
1717
    case OPC_DSRAV:
1718
        tcg_gen_andi_tl(t0, t0, 0x3f);
1719
        tcg_gen_sar_tl(t0, t1, t0);
1720
        opn = "dsrav";
1721
        break;
1722
    case OPC_DSRLV:
1723
        switch ((ctx->opcode >> 6) & 0x1f) {
1724
        case 0:
1725
            tcg_gen_andi_tl(t0, t0, 0x3f);
1726
            tcg_gen_shr_tl(t0, t1, t0);
1727
            opn = "dsrlv";
1728
            break;
1729
        case 1:
1730
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1731
            if (env->insn_flags & ISA_MIPS32R2) {
1732
                int l1 = gen_new_label();
1733
                int l2 = gen_new_label();
1734

    
1735
                tcg_gen_andi_tl(t0, t0, 0x3f);
1736
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1737
                {
1738
                    tcg_gen_rotr_tl(t0, t1, t0);
1739
                    tcg_gen_br(l2);
1740
                }
1741
                gen_set_label(l1);
1742
                tcg_gen_mov_tl(t0, t1);
1743
                gen_set_label(l2);
1744
                opn = "drotrv";
1745
            } else {
1746
                tcg_gen_andi_tl(t0, t0, 0x3f);
1747
                tcg_gen_shr_tl(t0, t1, t0);
1748
                opn = "dsrlv";
1749
            }
1750
            break;
1751
        default:
1752
            MIPS_INVAL("invalid dsrlv flag");
1753
            generate_exception(ctx, EXCP_RI);
1754
            break;
1755
        }
1756
        break;
1757
#endif
1758
    default:
1759
        MIPS_INVAL(opn);
1760
        generate_exception(ctx, EXCP_RI);
1761
        goto out;
1762
    }
1763
    gen_store_gpr(t0, rd);
1764
 print:
1765
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1766
 out:
1767
    tcg_temp_free(t0);
1768
    tcg_temp_free(t1);
1769
}
1770

    
1771
/* Arithmetic on HI/LO registers */
1772
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1773
{
1774
    const char *opn = "hilo";
1775
    TCGv t0 = tcg_temp_local_new();
1776

    
1777
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1778
        /* Treat as NOP. */
1779
        MIPS_DEBUG("NOP");
1780
        goto out;
1781
    }
1782
    switch (opc) {
1783
    case OPC_MFHI:
1784
        tcg_gen_mov_tl(t0, cpu_HI[0]);
1785
        gen_store_gpr(t0, reg);
1786
        opn = "mfhi";
1787
        break;
1788
    case OPC_MFLO:
1789
        tcg_gen_mov_tl(t0, cpu_LO[0]);
1790
        gen_store_gpr(t0, reg);
1791
        opn = "mflo";
1792
        break;
1793
    case OPC_MTHI:
1794
        gen_load_gpr(t0, reg);
1795
        tcg_gen_mov_tl(cpu_HI[0], t0);
1796
        opn = "mthi";
1797
        break;
1798
    case OPC_MTLO:
1799
        gen_load_gpr(t0, reg);
1800
        tcg_gen_mov_tl(cpu_LO[0], t0);
1801
        opn = "mtlo";
1802
        break;
1803
    default:
1804
        MIPS_INVAL(opn);
1805
        generate_exception(ctx, EXCP_RI);
1806
        goto out;
1807
    }
1808
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1809
 out:
1810
    tcg_temp_free(t0);
1811
}
1812

    
1813
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1814
                        int rs, int rt)
1815
{
1816
    const char *opn = "mul/div";
1817
    TCGv t0 = tcg_temp_local_new();
1818
    TCGv t1 = tcg_temp_local_new();
1819

    
1820
    gen_load_gpr(t0, rs);
1821
    gen_load_gpr(t1, rt);
1822
    switch (opc) {
1823
    case OPC_DIV:
1824
        {
1825
            int l1 = gen_new_label();
1826

    
1827
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1828
            {
1829
                int l2 = gen_new_label();
1830
                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1831
                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1832
                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1833

    
1834
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1835
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1836
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1837
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1838
                tcg_gen_ext32s_tl(cpu_LO[0], t0);
1839
                tcg_gen_movi_tl(cpu_HI[0], 0);
1840
                tcg_gen_br(l1);
1841
                gen_set_label(l2);
1842
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1843
                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1844
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1845
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1846
                tcg_temp_free_i32(r_tmp1);
1847
                tcg_temp_free_i32(r_tmp2);
1848
                tcg_temp_free_i32(r_tmp3);
1849
            }
1850
            gen_set_label(l1);
1851
        }
1852
        opn = "div";
1853
        break;
1854
    case OPC_DIVU:
1855
        {
1856
            int l1 = gen_new_label();
1857

    
1858
            tcg_gen_ext32s_tl(t1, t1);
1859
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1860
            {
1861
                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1862
                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1863
                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1864

    
1865
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1866
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1867
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1868
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1869
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1870
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1871
                tcg_temp_free_i32(r_tmp1);
1872
                tcg_temp_free_i32(r_tmp2);
1873
                tcg_temp_free_i32(r_tmp3);
1874
            }
1875
            gen_set_label(l1);
1876
        }
1877
        opn = "divu";
1878
        break;
1879
    case OPC_MULT:
1880
        {
1881
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1882
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1883

    
1884
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1885
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1886
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1887
            tcg_temp_free_i64(r_tmp2);
1888
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1889
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1890
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1891
            tcg_temp_free_i64(r_tmp1);
1892
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1893
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1894
        }
1895
        opn = "mult";
1896
        break;
1897
    case OPC_MULTU:
1898
        {
1899
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1900
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1901

    
1902
            tcg_gen_ext32u_tl(t0, t0);
1903
            tcg_gen_ext32u_tl(t1, t1);
1904
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1905
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1906
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1907
            tcg_temp_free_i64(r_tmp2);
1908
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1909
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1910
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1911
            tcg_temp_free_i64(r_tmp1);
1912
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1913
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1914
        }
1915
        opn = "multu";
1916
        break;
1917
#if defined(TARGET_MIPS64)
1918
    case OPC_DDIV:
1919
        {
1920
            int l1 = gen_new_label();
1921

    
1922
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1923
            {
1924
                int l2 = gen_new_label();
1925

    
1926
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1927
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1928
                tcg_gen_mov_tl(cpu_LO[0], t0);
1929
                tcg_gen_movi_tl(cpu_HI[0], 0);
1930
                tcg_gen_br(l1);
1931
                gen_set_label(l2);
1932
                tcg_gen_div_i64(cpu_LO[0], t0, t1);
1933
                tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1934
            }
1935
            gen_set_label(l1);
1936
        }
1937
        opn = "ddiv";
1938
        break;
1939
    case OPC_DDIVU:
1940
        {
1941
            int l1 = gen_new_label();
1942

    
1943
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1944
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1945
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1946
            gen_set_label(l1);
1947
        }
1948
        opn = "ddivu";
1949
        break;
1950
    case OPC_DMULT:
1951
        gen_helper_dmult(t0, t1);
1952
        opn = "dmult";
1953
        break;
1954
    case OPC_DMULTU:
1955
        gen_helper_dmultu(t0, t1);
1956
        opn = "dmultu";
1957
        break;
1958
#endif
1959
    case OPC_MADD:
1960
        {
1961
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1962
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1963

    
1964
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1965
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1966
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1967
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1968
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1969
            tcg_temp_free_i64(r_tmp2);
1970
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1971
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1972
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1973
            tcg_temp_free_i64(r_tmp1);
1974
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1975
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1976
        }
1977
        opn = "madd";
1978
        break;
1979
    case OPC_MADDU:
1980
       {
1981
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1982
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1983

    
1984
            tcg_gen_ext32u_tl(t0, t0);
1985
            tcg_gen_ext32u_tl(t1, t1);
1986
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1987
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1988
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1989
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1990
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1991
            tcg_temp_free_i64(r_tmp2);
1992
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1993
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1994
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1995
            tcg_temp_free_i64(r_tmp1);
1996
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1997
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1998
        }
1999
        opn = "maddu";
2000
        break;
2001
    case OPC_MSUB:
2002
        {
2003
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2004
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2005

    
2006
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2007
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2008
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2009
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2010
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2011
            tcg_temp_free_i64(r_tmp2);
2012
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2013
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2014
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2015
            tcg_temp_free_i64(r_tmp1);
2016
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2017
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2018
        }
2019
        opn = "msub";
2020
        break;
2021
    case OPC_MSUBU:
2022
        {
2023
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2024
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2025

    
2026
            tcg_gen_ext32u_tl(t0, t0);
2027
            tcg_gen_ext32u_tl(t1, t1);
2028
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2029
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2030
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2031
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2032
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2033
            tcg_temp_free_i64(r_tmp2);
2034
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2035
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2036
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2037
            tcg_temp_free_i64(r_tmp1);
2038
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2039
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2040
        }
2041
        opn = "msubu";
2042
        break;
2043
    default:
2044
        MIPS_INVAL(opn);
2045
        generate_exception(ctx, EXCP_RI);
2046
        goto out;
2047
    }
2048
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2049
 out:
2050
    tcg_temp_free(t0);
2051
    tcg_temp_free(t1);
2052
}
2053

    
2054
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2055
                            int rd, int rs, int rt)
2056
{
2057
    const char *opn = "mul vr54xx";
2058
    TCGv t0 = tcg_temp_local_new();
2059
    TCGv t1 = tcg_temp_local_new();
2060

    
2061
    gen_load_gpr(t0, rs);
2062
    gen_load_gpr(t1, rt);
2063

    
2064
    switch (opc) {
2065
    case OPC_VR54XX_MULS:
2066
        gen_helper_muls(t0, t0, t1);
2067
        opn = "muls";
2068
        break;
2069
    case OPC_VR54XX_MULSU:
2070
        gen_helper_mulsu(t0, t0, t1);
2071
        opn = "mulsu";
2072
        break;
2073
    case OPC_VR54XX_MACC:
2074
        gen_helper_macc(t0, t0, t1);
2075
        opn = "macc";
2076
        break;
2077
    case OPC_VR54XX_MACCU:
2078
        gen_helper_maccu(t0, t0, t1);
2079
        opn = "maccu";
2080
        break;
2081
    case OPC_VR54XX_MSAC:
2082
        gen_helper_msac(t0, t0, t1);
2083
        opn = "msac";
2084
        break;
2085
    case OPC_VR54XX_MSACU:
2086
        gen_helper_msacu(t0, t0, t1);
2087
        opn = "msacu";
2088
        break;
2089
    case OPC_VR54XX_MULHI:
2090
        gen_helper_mulhi(t0, t0, t1);
2091
        opn = "mulhi";
2092
        break;
2093
    case OPC_VR54XX_MULHIU:
2094
        gen_helper_mulhiu(t0, t0, t1);
2095
        opn = "mulhiu";
2096
        break;
2097
    case OPC_VR54XX_MULSHI:
2098
        gen_helper_mulshi(t0, t0, t1);
2099
        opn = "mulshi";
2100
        break;
2101
    case OPC_VR54XX_MULSHIU:
2102
        gen_helper_mulshiu(t0, t0, t1);
2103
        opn = "mulshiu";
2104
        break;
2105
    case OPC_VR54XX_MACCHI:
2106
        gen_helper_macchi(t0, t0, t1);
2107
        opn = "macchi";
2108
        break;
2109
    case OPC_VR54XX_MACCHIU:
2110
        gen_helper_macchiu(t0, t0, t1);
2111
        opn = "macchiu";
2112
        break;
2113
    case OPC_VR54XX_MSACHI:
2114
        gen_helper_msachi(t0, t0, t1);
2115
        opn = "msachi";
2116
        break;
2117
    case OPC_VR54XX_MSACHIU:
2118
        gen_helper_msachiu(t0, t0, t1);
2119
        opn = "msachiu";
2120
        break;
2121
    default:
2122
        MIPS_INVAL("mul vr54xx");
2123
        generate_exception(ctx, EXCP_RI);
2124
        goto out;
2125
    }
2126
    gen_store_gpr(t0, rd);
2127
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2128

    
2129
 out:
2130
    tcg_temp_free(t0);
2131
    tcg_temp_free(t1);
2132
}
2133

    
2134
static void gen_cl (DisasContext *ctx, uint32_t opc,
2135
                    int rd, int rs)
2136
{
2137
    const char *opn = "CLx";
2138
    TCGv t0 = tcg_temp_local_new();
2139

    
2140
    if (rd == 0) {
2141
        /* Treat as NOP. */
2142
        MIPS_DEBUG("NOP");
2143
        goto out;
2144
    }
2145
    gen_load_gpr(t0, rs);
2146
    switch (opc) {
2147
    case OPC_CLO:
2148
        gen_helper_clo(t0, t0);
2149
        opn = "clo";
2150
        break;
2151
    case OPC_CLZ:
2152
        gen_helper_clz(t0, t0);
2153
        opn = "clz";
2154
        break;
2155
#if defined(TARGET_MIPS64)
2156
    case OPC_DCLO:
2157
        gen_helper_dclo(t0, t0);
2158
        opn = "dclo";
2159
        break;
2160
    case OPC_DCLZ:
2161
        gen_helper_dclz(t0, t0);
2162
        opn = "dclz";
2163
        break;
2164
#endif
2165
    default:
2166
        MIPS_INVAL(opn);
2167
        generate_exception(ctx, EXCP_RI);
2168
        goto out;
2169
    }
2170
    gen_store_gpr(t0, rd);
2171
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2172

    
2173
 out:
2174
    tcg_temp_free(t0);
2175
}
2176

    
2177
/* Traps */
2178
static void gen_trap (DisasContext *ctx, uint32_t opc,
2179
                      int rs, int rt, int16_t imm)
2180
{
2181
    int cond;
2182
    TCGv t0 = tcg_temp_local_new();
2183
    TCGv t1 = tcg_temp_local_new();
2184

    
2185
    cond = 0;
2186
    /* Load needed operands */
2187
    switch (opc) {
2188
    case OPC_TEQ:
2189
    case OPC_TGE:
2190
    case OPC_TGEU:
2191
    case OPC_TLT:
2192
    case OPC_TLTU:
2193
    case OPC_TNE:
2194
        /* Compare two registers */
2195
        if (rs != rt) {
2196
            gen_load_gpr(t0, rs);
2197
            gen_load_gpr(t1, rt);
2198
            cond = 1;
2199
        }
2200
        break;
2201
    case OPC_TEQI:
2202
    case OPC_TGEI:
2203
    case OPC_TGEIU:
2204
    case OPC_TLTI:
2205
    case OPC_TLTIU:
2206
    case OPC_TNEI:
2207
        /* Compare register to immediate */
2208
        if (rs != 0 || imm != 0) {
2209
            gen_load_gpr(t0, rs);
2210
            tcg_gen_movi_tl(t1, (int32_t)imm);
2211
            cond = 1;
2212
        }
2213
        break;
2214
    }
2215
    if (cond == 0) {
2216
        switch (opc) {
2217
        case OPC_TEQ:   /* rs == rs */
2218
        case OPC_TEQI:  /* r0 == 0  */
2219
        case OPC_TGE:   /* rs >= rs */
2220
        case OPC_TGEI:  /* r0 >= 0  */
2221
        case OPC_TGEU:  /* rs >= rs unsigned */
2222
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2223
            /* Always trap */
2224
            tcg_gen_movi_tl(t0, 1);
2225
            break;
2226
        case OPC_TLT:   /* rs < rs           */
2227
        case OPC_TLTI:  /* r0 < 0            */
2228
        case OPC_TLTU:  /* rs < rs unsigned  */
2229
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2230
        case OPC_TNE:   /* rs != rs          */
2231
        case OPC_TNEI:  /* r0 != 0           */
2232
            /* Never trap: treat as NOP. */
2233
            goto out;
2234
        default:
2235
            MIPS_INVAL("trap");
2236
            generate_exception(ctx, EXCP_RI);
2237
            goto out;
2238
        }
2239
    } else {
2240
        switch (opc) {
2241
        case OPC_TEQ:
2242
        case OPC_TEQI:
2243
            gen_op_eq(t0, t1);
2244
            break;
2245
        case OPC_TGE:
2246
        case OPC_TGEI:
2247
            gen_op_ge(t0, t1);
2248
            break;
2249
        case OPC_TGEU:
2250
        case OPC_TGEIU:
2251
            gen_op_geu(t0, t1);
2252
            break;
2253
        case OPC_TLT:
2254
        case OPC_TLTI:
2255
            gen_op_lt(t0, t1);
2256
            break;
2257
        case OPC_TLTU:
2258
        case OPC_TLTIU:
2259
            gen_op_ltu(t0, t1);
2260
            break;
2261
        case OPC_TNE:
2262
        case OPC_TNEI:
2263
            gen_op_ne(t0, t1);
2264
            break;
2265
        default:
2266
            MIPS_INVAL("trap");
2267
            generate_exception(ctx, EXCP_RI);
2268
            goto out;
2269
        }
2270
    }
2271
    save_cpu_state(ctx, 1);
2272
    {
2273
        int l1 = gen_new_label();
2274

    
2275
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2276
        gen_helper_0i(raise_exception, EXCP_TRAP);
2277
        gen_set_label(l1);
2278
    }
2279
    ctx->bstate = BS_STOP;
2280
 out:
2281
    tcg_temp_free(t0);
2282
    tcg_temp_free(t1);
2283
}
2284

    
2285
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2286
{
2287
    TranslationBlock *tb;
2288
    tb = ctx->tb;
2289
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2290
        tcg_gen_goto_tb(n);
2291
        gen_save_pc(dest);
2292
        tcg_gen_exit_tb((long)tb + n);
2293
    } else {
2294
        gen_save_pc(dest);
2295
        tcg_gen_exit_tb(0);
2296
    }
2297
}
2298

    
2299
/* Branches (before delay slot) */
2300
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2301
                                int rs, int rt, int32_t offset)
2302
{
2303
    target_ulong btgt = -1;
2304
    int blink = 0;
2305
    int bcond_compute = 0;
2306
    TCGv t0 = tcg_temp_local_new();
2307
    TCGv t1 = tcg_temp_local_new();
2308

    
2309
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2310
#ifdef MIPS_DEBUG_DISAS
2311
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2312
#endif
2313
        generate_exception(ctx, EXCP_RI);
2314
        goto out;
2315
    }
2316

    
2317
    /* Load needed operands */
2318
    switch (opc) {
2319
    case OPC_BEQ:
2320
    case OPC_BEQL:
2321
    case OPC_BNE:
2322
    case OPC_BNEL:
2323
        /* Compare two registers */
2324
        if (rs != rt) {
2325
            gen_load_gpr(t0, rs);
2326
            gen_load_gpr(t1, rt);
2327
            bcond_compute = 1;
2328
        }
2329
        btgt = ctx->pc + 4 + offset;
2330
        break;
2331
    case OPC_BGEZ:
2332
    case OPC_BGEZAL:
2333
    case OPC_BGEZALL:
2334
    case OPC_BGEZL:
2335
    case OPC_BGTZ:
2336
    case OPC_BGTZL:
2337
    case OPC_BLEZ:
2338
    case OPC_BLEZL:
2339
    case OPC_BLTZ:
2340
    case OPC_BLTZAL:
2341
    case OPC_BLTZALL:
2342
    case OPC_BLTZL:
2343
        /* Compare to zero */
2344
        if (rs != 0) {
2345
            gen_load_gpr(t0, rs);
2346
            bcond_compute = 1;
2347
        }
2348
        btgt = ctx->pc + 4 + offset;
2349
        break;
2350
    case OPC_J:
2351
    case OPC_JAL:
2352
        /* Jump to immediate */
2353
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2354
        break;
2355
    case OPC_JR:
2356
    case OPC_JALR:
2357
        /* Jump to register */
2358
        if (offset != 0 && offset != 16) {
2359
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2360
               others are reserved. */
2361
            MIPS_INVAL("jump hint");
2362
            generate_exception(ctx, EXCP_RI);
2363
            goto out;
2364
        }
2365
        gen_load_gpr(btarget, rs);
2366
        break;
2367
    default:
2368
        MIPS_INVAL("branch/jump");
2369
        generate_exception(ctx, EXCP_RI);
2370
        goto out;
2371
    }
2372
    if (bcond_compute == 0) {
2373
        /* No condition to be computed */
2374
        switch (opc) {
2375
        case OPC_BEQ:     /* rx == rx        */
2376
        case OPC_BEQL:    /* rx == rx likely */
2377
        case OPC_BGEZ:    /* 0 >= 0          */
2378
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2379
        case OPC_BLEZ:    /* 0 <= 0          */
2380
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2381
            /* Always take */
2382
            ctx->hflags |= MIPS_HFLAG_B;
2383
            MIPS_DEBUG("balways");
2384
            break;
2385
        case OPC_BGEZAL:  /* 0 >= 0          */
2386
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2387
            /* Always take and link */
2388
            blink = 31;
2389
            ctx->hflags |= MIPS_HFLAG_B;
2390
            MIPS_DEBUG("balways and link");
2391
            break;
2392
        case OPC_BNE:     /* rx != rx        */
2393
        case OPC_BGTZ:    /* 0 > 0           */
2394
        case OPC_BLTZ:    /* 0 < 0           */
2395
            /* Treat as NOP. */
2396
            MIPS_DEBUG("bnever (NOP)");
2397
            goto out;
2398
        case OPC_BLTZAL:  /* 0 < 0           */
2399
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2400
            gen_store_gpr(t0, 31);
2401
            MIPS_DEBUG("bnever and link");
2402
            goto out;
2403
        case OPC_BLTZALL: /* 0 < 0 likely */
2404
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2405
            gen_store_gpr(t0, 31);
2406
            /* Skip the instruction in the delay slot */
2407
            MIPS_DEBUG("bnever, link and skip");
2408
            ctx->pc += 4;
2409
            goto out;
2410
        case OPC_BNEL:    /* rx != rx likely */
2411
        case OPC_BGTZL:   /* 0 > 0 likely */
2412
        case OPC_BLTZL:   /* 0 < 0 likely */
2413
            /* Skip the instruction in the delay slot */
2414
            MIPS_DEBUG("bnever and skip");
2415
            ctx->pc += 4;
2416
            goto out;
2417
        case OPC_J:
2418
            ctx->hflags |= MIPS_HFLAG_B;
2419
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2420
            break;
2421
        case OPC_JAL:
2422
            blink = 31;
2423
            ctx->hflags |= MIPS_HFLAG_B;
2424
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2425
            break;
2426
        case OPC_JR:
2427
            ctx->hflags |= MIPS_HFLAG_BR;
2428
            MIPS_DEBUG("jr %s", regnames[rs]);
2429
            break;
2430
        case OPC_JALR:
2431
            blink = rt;
2432
            ctx->hflags |= MIPS_HFLAG_BR;
2433
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2434
            break;
2435
        default:
2436
            MIPS_INVAL("branch/jump");
2437
            generate_exception(ctx, EXCP_RI);
2438
            goto out;
2439
        }
2440
    } else {
2441
        switch (opc) {
2442
        case OPC_BEQ:
2443
            gen_op_eq(t0, t1);
2444
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2445
                       regnames[rs], regnames[rt], btgt);
2446
            goto not_likely;
2447
        case OPC_BEQL:
2448
            gen_op_eq(t0, t1);
2449
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2450
                       regnames[rs], regnames[rt], btgt);
2451
            goto likely;
2452
        case OPC_BNE:
2453
            gen_op_ne(t0, t1);
2454
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2455
                       regnames[rs], regnames[rt], btgt);
2456
            goto not_likely;
2457
        case OPC_BNEL:
2458
            gen_op_ne(t0, t1);
2459
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2460
                       regnames[rs], regnames[rt], btgt);
2461
            goto likely;
2462
        case OPC_BGEZ:
2463
            gen_op_gez(t0);
2464
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2465
            goto not_likely;
2466
        case OPC_BGEZL:
2467
            gen_op_gez(t0);
2468
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2469
            goto likely;
2470
        case OPC_BGEZAL:
2471
            gen_op_gez(t0);
2472
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2473
            blink = 31;
2474
            goto not_likely;
2475
        case OPC_BGEZALL:
2476
            gen_op_gez(t0);
2477
            blink = 31;
2478
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2479
            goto likely;
2480
        case OPC_BGTZ:
2481
            gen_op_gtz(t0);
2482
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2483
            goto not_likely;
2484
        case OPC_BGTZL:
2485
            gen_op_gtz(t0);
2486
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2487
            goto likely;
2488
        case OPC_BLEZ:
2489
            gen_op_lez(t0);
2490
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2491
            goto not_likely;
2492
        case OPC_BLEZL:
2493
            gen_op_lez(t0);
2494
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2495
            goto likely;
2496
        case OPC_BLTZ:
2497
            gen_op_ltz(t0);
2498
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2499
            goto not_likely;
2500
        case OPC_BLTZL:
2501
            gen_op_ltz(t0);
2502
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2503
            goto likely;
2504
        case OPC_BLTZAL:
2505
            gen_op_ltz(t0);
2506
            blink = 31;
2507
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2508
        not_likely:
2509
            ctx->hflags |= MIPS_HFLAG_BC;
2510
            tcg_gen_trunc_tl_i32(bcond, t0);
2511
            break;
2512
        case OPC_BLTZALL:
2513
            gen_op_ltz(t0);
2514
            blink = 31;
2515
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2516
        likely:
2517
            ctx->hflags |= MIPS_HFLAG_BL;
2518
            tcg_gen_trunc_tl_i32(bcond, t0);
2519
            break;
2520
        default:
2521
            MIPS_INVAL("conditional branch/jump");
2522
            generate_exception(ctx, EXCP_RI);
2523
            goto out;
2524
        }
2525
    }
2526
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2527
               blink, ctx->hflags, btgt);
2528

    
2529
    ctx->btarget = btgt;
2530
    if (blink > 0) {
2531
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2532
        gen_store_gpr(t0, blink);
2533
    }
2534

    
2535
 out:
2536
    tcg_temp_free(t0);
2537
    tcg_temp_free(t1);
2538
}
2539

    
2540
/* special3 bitfield operations */
2541
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2542
                        int rs, int lsb, int msb)
2543
{
2544
    TCGv t0 = tcg_temp_new();
2545
    TCGv t1 = tcg_temp_new();
2546
    target_ulong mask;
2547

    
2548
    gen_load_gpr(t1, rs);
2549
    switch (opc) {
2550
    case OPC_EXT:
2551
        if (lsb + msb > 31)
2552
            goto fail;
2553
        tcg_gen_shri_tl(t0, t1, lsb);
2554
        if (msb != 31) {
2555
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2556
        } else {
2557
            tcg_gen_ext32s_tl(t0, t0);
2558
        }
2559
        break;
2560
#if defined(TARGET_MIPS64)
2561
    case OPC_DEXTM:
2562
        tcg_gen_shri_tl(t0, t1, lsb);
2563
        if (msb != 31) {
2564
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2565
        }
2566
        break;
2567
    case OPC_DEXTU:
2568
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2569
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2570
        break;
2571
    case OPC_DEXT:
2572
        tcg_gen_shri_tl(t0, t1, lsb);
2573
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2574
        break;
2575
#endif
2576
    case OPC_INS:
2577
        if (lsb > msb)
2578
            goto fail;
2579
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2580
        gen_load_gpr(t0, rt);
2581
        tcg_gen_andi_tl(t0, t0, ~mask);
2582
        tcg_gen_shli_tl(t1, t1, lsb);
2583
        tcg_gen_andi_tl(t1, t1, mask);
2584
        tcg_gen_or_tl(t0, t0, t1);
2585
        tcg_gen_ext32s_tl(t0, t0);
2586
        break;
2587
#if defined(TARGET_MIPS64)
2588
    case OPC_DINSM:
2589
        if (lsb > msb)
2590
            goto fail;
2591
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2592
        gen_load_gpr(t0, rt);
2593
        tcg_gen_andi_tl(t0, t0, ~mask);
2594
        tcg_gen_shli_tl(t1, t1, lsb);
2595
        tcg_gen_andi_tl(t1, t1, mask);
2596
        tcg_gen_or_tl(t0, t0, t1);
2597
        break;
2598
    case OPC_DINSU:
2599
        if (lsb > msb)
2600
            goto fail;
2601
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2602
        gen_load_gpr(t0, rt);
2603
        tcg_gen_andi_tl(t0, t0, ~mask);
2604
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2605
        tcg_gen_andi_tl(t1, t1, mask);
2606
        tcg_gen_or_tl(t0, t0, t1);
2607
        break;
2608
    case OPC_DINS:
2609
        if (lsb > msb)
2610
            goto fail;
2611
        gen_load_gpr(t0, rt);
2612
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2613
        gen_load_gpr(t0, rt);
2614
        tcg_gen_andi_tl(t0, t0, ~mask);
2615
        tcg_gen_shli_tl(t1, t1, lsb);
2616
        tcg_gen_andi_tl(t1, t1, mask);
2617
        tcg_gen_or_tl(t0, t0, t1);
2618
        break;
2619
#endif
2620
    default:
2621
fail:
2622
        MIPS_INVAL("bitops");
2623
        generate_exception(ctx, EXCP_RI);
2624
        tcg_temp_free(t0);
2625
        tcg_temp_free(t1);
2626
        return;
2627
    }
2628
    gen_store_gpr(t0, rt);
2629
    tcg_temp_free(t0);
2630
    tcg_temp_free(t1);
2631
}
2632

    
2633
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2634
{
2635
    TCGv t0 = tcg_temp_new();
2636
    TCGv t1 = tcg_temp_new();
2637

    
2638
    gen_load_gpr(t1, rt);
2639
    switch (op2) {
2640
    case OPC_WSBH:
2641
        tcg_gen_shri_tl(t0, t1, 8);
2642
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
2643
        tcg_gen_shli_tl(t1, t1, 8);
2644
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
2645
        tcg_gen_or_tl(t0, t0, t1);
2646
        tcg_gen_ext32s_tl(t0, t0);
2647
        break;
2648
    case OPC_SEB:
2649
        tcg_gen_ext8s_tl(t0, t1);
2650
        break;
2651
    case OPC_SEH:
2652
        tcg_gen_ext16s_tl(t0, t1);
2653
        break;
2654
#if defined(TARGET_MIPS64)
2655
    case OPC_DSBH:
2656
        gen_load_gpr(t1, rt);
2657
        tcg_gen_shri_tl(t0, t1, 8);
2658
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
2659
        tcg_gen_shli_tl(t1, t1, 8);
2660
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
2661
        tcg_gen_or_tl(t0, t0, t1);
2662
        break;
2663
    case OPC_DSHD:
2664
        gen_load_gpr(t1, rt);
2665
        tcg_gen_shri_tl(t0, t1, 16);
2666
        tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
2667
        tcg_gen_shli_tl(t1, t1, 16);
2668
        tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
2669
        tcg_gen_or_tl(t1, t0, t1);
2670
        tcg_gen_shri_tl(t0, t1, 32);
2671
        tcg_gen_shli_tl(t1, t1, 32);
2672
        tcg_gen_or_tl(t0, t0, t1);
2673
        break;
2674
#endif
2675
    default:
2676
        MIPS_INVAL("bsfhl");
2677
        generate_exception(ctx, EXCP_RI);
2678
        tcg_temp_free(t0);
2679
        tcg_temp_free(t1);
2680
        return;
2681
    }
2682
    gen_store_gpr(t0, rd);
2683
    tcg_temp_free(t0);
2684
    tcg_temp_free(t1);
2685
}
2686

    
2687
#ifndef CONFIG_USER_ONLY
2688
/* CP0 (MMU and control) */
2689
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2690
{
2691
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2692

    
2693
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2694
    tcg_gen_ext_i32_tl(t, r_tmp);
2695
    tcg_temp_free_i32(r_tmp);
2696
}
2697

    
2698
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2699
{
2700
    tcg_gen_ld_tl(t, cpu_env, off);
2701
    tcg_gen_ext32s_tl(t, t);
2702
}
2703

    
2704
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2705
{
2706
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2707

    
2708
    tcg_gen_trunc_tl_i32(r_tmp, t);
2709
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2710
    tcg_temp_free_i32(r_tmp);
2711
}
2712

    
2713
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2714
{
2715
    tcg_gen_ext32s_tl(t, t);
2716
    tcg_gen_st_tl(t, cpu_env, off);
2717
}
2718

    
2719
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2720
{
2721
    const char *rn = "invalid";
2722

    
2723
    if (sel != 0)
2724
        check_insn(env, ctx, ISA_MIPS32);
2725

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

    
3291
die:
3292
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3293
    generate_exception(ctx, EXCP_RI);
3294
}
3295

    
3296
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3297
{
3298
    const char *rn = "invalid";
3299

    
3300
    if (sel != 0)
3301
        check_insn(env, ctx, ISA_MIPS32);
3302

    
3303
    if (use_icount)
3304
        gen_io_start();
3305

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

    
3890
die:
3891
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3892
    generate_exception(ctx, EXCP_RI);
3893
}
3894

    
3895
#if defined(TARGET_MIPS64)
3896
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3897
{
3898
    const char *rn = "invalid";
3899

    
3900
    if (sel != 0)
3901
        check_insn(env, ctx, ISA_MIPS64);
3902

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

    
4457
die:
4458
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4459
    generate_exception(ctx, EXCP_RI);
4460
}
4461

    
4462
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4463
{
4464
    const char *rn = "invalid";
4465

    
4466
    if (sel != 0)
4467
        check_insn(env, ctx, ISA_MIPS64);
4468

    
4469
    if (use_icount)
4470
        gen_io_start();
4471

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

    
5043
die:
5044
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5045
    generate_exception(ctx, EXCP_RI);
5046
}
5047
#endif /* TARGET_MIPS64 */
5048

    
5049
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5050
                     int u, int sel, int h)
5051
{
5052
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5053
    TCGv t0 = tcg_temp_local_new();
5054

    
5055
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5056
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5057
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5058
        tcg_gen_movi_tl(t0, -1);
5059
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5060
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5061
        tcg_gen_movi_tl(t0, -1);
5062
    else if (u == 0) {
5063
        switch (rt) {
5064
        case 2:
5065
            switch (sel) {
5066
            case 1:
5067
                gen_helper_mftc0_tcstatus(t0);
5068
                break;
5069
            case 2:
5070
                gen_helper_mftc0_tcbind(t0);
5071
                break;
5072
            case 3:
5073
                gen_helper_mftc0_tcrestart(t0);
5074
                break;
5075
            case 4:
5076
                gen_helper_mftc0_tchalt(t0);
5077
                break;
5078
            case 5:
5079
                gen_helper_mftc0_tccontext(t0);
5080
                break;
5081
            case 6:
5082
                gen_helper_mftc0_tcschedule(t0);
5083
                break;
5084
            case 7:
5085
                gen_helper_mftc0_tcschefback(t0);
5086
                break;
5087
            default:
5088
                gen_mfc0(env, ctx, t0, rt, sel);
5089
                break;
5090
            }
5091
            break;
5092
        case 10:
5093
            switch (sel) {
5094
            case 0:
5095
                gen_helper_mftc0_entryhi(t0);
5096
                break;
5097
            default:
5098
                gen_mfc0(env, ctx, t0, rt, sel);
5099
                break;
5100
            }
5101
        case 12:
5102
            switch (sel) {
5103
            case 0:
5104
                gen_helper_mftc0_status(t0);
5105
                break;
5106
            default:
5107
                gen_mfc0(env, ctx, t0, rt, sel);
5108
                break;
5109
            }
5110
        case 23:
5111
            switch (sel) {
5112
            case 0:
5113
                gen_helper_mftc0_debug(t0);
5114
                break;
5115
            default:
5116
                gen_mfc0(env, ctx, t0, rt, sel);
5117
                break;
5118
            }
5119
            break;
5120
        default:
5121
            gen_mfc0(env, ctx, t0, rt, sel);
5122
        }
5123
    } else switch (sel) {
5124
    /* GPR registers. */
5125
    case 0:
5126
        gen_helper_1i(mftgpr, t0, rt);
5127
        break;
5128
    /* Auxiliary CPU registers */
5129
    case 1:
5130
        switch (rt) {
5131
        case 0:
5132
            gen_helper_1i(mftlo, t0, 0);
5133
            break;
5134
        case 1:
5135
            gen_helper_1i(mfthi, t0, 0);
5136
            break;
5137
        case 2:
5138
            gen_helper_1i(mftacx, t0, 0);
5139
            break;
5140
        case 4:
5141
            gen_helper_1i(mftlo, t0, 1);
5142
            break;
5143
        case 5:
5144
            gen_helper_1i(mfthi, t0, 1);
5145
            break;
5146
        case 6:
5147
            gen_helper_1i(mftacx, t0, 1);
5148
            break;
5149
        case 8:
5150
            gen_helper_1i(mftlo, t0, 2);
5151
            break;
5152
        case 9:
5153
            gen_helper_1i(mfthi, t0, 2);
5154
            break;
5155
        case 10:
5156
            gen_helper_1i(mftacx, t0, 2);
5157
            break;
5158
        case 12:
5159
            gen_helper_1i(mftlo, t0, 3);
5160
            break;
5161
        case 13:
5162
            gen_helper_1i(mfthi, t0, 3);
5163
            break;
5164
        case 14:
5165
            gen_helper_1i(mftacx, t0, 3);
5166
            break;
5167
        case 16:
5168
            gen_helper_mftdsp(t0);
5169
            break;
5170
        default:
5171
            goto die;
5172
        }
5173
        break;
5174
    /* Floating point (COP1). */
5175
    case 2:
5176
        /* XXX: For now we support only a single FPU context. */
5177
        if (h == 0) {
5178
            TCGv_i32 fp0 = tcg_temp_new_i32();
5179

    
5180
            gen_load_fpr32(fp0, rt);
5181
            tcg_gen_ext_i32_tl(t0, fp0);
5182
            tcg_temp_free_i32(fp0);
5183
        } else {
5184
            TCGv_i32 fp0 = tcg_temp_new_i32();
5185

    
5186
            gen_load_fpr32h(fp0, rt);
5187
            tcg_gen_ext_i32_tl(t0, fp0);
5188
            tcg_temp_free_i32(fp0);
5189
        }
5190
        break;
5191
    case 3:
5192
        /* XXX: For now we support only a single FPU context. */
5193
        gen_helper_1i(cfc1, t0, rt);
5194
        break;
5195
    /* COP2: Not implemented. */
5196
    case 4:
5197
    case 5:
5198
        /* fall through */
5199
    default:
5200
        goto die;
5201
    }
5202
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5203
    gen_store_gpr(t0, rd);
5204
    tcg_temp_free(t0);
5205
    return;
5206

    
5207
die:
5208
    tcg_temp_free(t0);
5209
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5210
    generate_exception(ctx, EXCP_RI);
5211
}
5212

    
5213
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5214
                     int u, int sel, int h)
5215
{
5216
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5217
    TCGv t0 = tcg_temp_local_new();
5218

    
5219
    gen_load_gpr(t0, rt);
5220
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5221
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5222
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5223
        /* NOP */ ;
5224
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5225
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5226
        /* NOP */ ;
5227
    else if (u == 0) {
5228
        switch (rd) {
5229
        case 2:
5230
            switch (sel) {
5231
            case 1:
5232
                gen_helper_mttc0_tcstatus(t0);
5233
                break;
5234
            case 2:
5235
                gen_helper_mttc0_tcbind(t0);
5236
                break;
5237
            case 3:
5238
                gen_helper_mttc0_tcrestart(t0);
5239
                break;
5240
            case 4:
5241
                gen_helper_mttc0_tchalt(t0);
5242
                break;
5243
            case 5:
5244
                gen_helper_mttc0_tccontext(t0);
5245
                break;
5246
            case 6:
5247
                gen_helper_mttc0_tcschedule(t0);
5248
                break;
5249
            case 7:
5250
                gen_helper_mttc0_tcschefback(t0);
5251
                break;
5252
            default:
5253
                gen_mtc0(env, ctx, t0, rd, sel);
5254
                break;
5255
            }
5256
            break;
5257
        case 10:
5258
            switch (sel) {
5259
            case 0:
5260
                gen_helper_mttc0_entryhi(t0);
5261
                break;
5262
            default:
5263
                gen_mtc0(env, ctx, t0, rd, sel);
5264
                break;
5265
            }
5266
        case 12:
5267
            switch (sel) {
5268
            case 0:
5269
                gen_helper_mttc0_status(t0);
5270
                break;
5271
            default:
5272
                gen_mtc0(env, ctx, t0, rd, sel);
5273
                break;
5274
            }
5275
        case 23:
5276
            switch (sel) {
5277
            case 0:
5278
                gen_helper_mttc0_debug(t0);
5279
                break;
5280
            default:
5281
                gen_mtc0(env, ctx, t0, rd, sel);
5282
                break;
5283
            }
5284
            break;
5285
        default:
5286
            gen_mtc0(env, ctx, t0, rd, sel);
5287
        }
5288
    } else switch (sel) {
5289
    /* GPR registers. */
5290
    case 0:
5291
        gen_helper_1i(mttgpr, t0, rd);
5292
        break;
5293
    /* Auxiliary CPU registers */
5294
    case 1:
5295
        switch (rd) {
5296
        case 0:
5297
            gen_helper_1i(mttlo, t0, 0);
5298
            break;
5299
        case 1:
5300
            gen_helper_1i(mtthi, t0, 0);
5301
            break;
5302
        case 2:
5303
            gen_helper_1i(mttacx, t0, 0);
5304
            break;
5305
        case 4:
5306
            gen_helper_1i(mttlo, t0, 1);
5307
            break;
5308
        case 5:
5309
            gen_helper_1i(mtthi, t0, 1);
5310
            break;
5311
        case 6:
5312
            gen_helper_1i(mttacx, t0, 1);
5313
            break;
5314
        case 8:
5315
            gen_helper_1i(mttlo, t0, 2);
5316
            break;
5317
        case 9:
5318
            gen_helper_1i(mtthi, t0, 2);
5319
            break;
5320
        case 10:
5321
            gen_helper_1i(mttacx, t0, 2);
5322
            break;
5323
        case 12:
5324
            gen_helper_1i(mttlo, t0, 3);
5325
            break;
5326
        case 13:
5327
            gen_helper_1i(mtthi, t0, 3);
5328
            break;
5329
        case 14:
5330
            gen_helper_1i(mttacx, t0, 3);
5331
            break;
5332
        case 16:
5333
            gen_helper_mttdsp(t0);
5334
            break;
5335
        default:
5336
            goto die;
5337
        }
5338
        break;
5339
    /* Floating point (COP1). */
5340
    case 2:
5341
        /* XXX: For now we support only a single FPU context. */
5342
        if (h == 0) {
5343
            TCGv_i32 fp0 = tcg_temp_new_i32();
5344

    
5345
            tcg_gen_trunc_tl_i32(fp0, t0);
5346
            gen_store_fpr32(fp0, rd);
5347
            tcg_temp_free_i32(fp0);
5348
        } else {
5349
            TCGv_i32 fp0 = tcg_temp_new_i32();
5350

    
5351
            tcg_gen_trunc_tl_i32(fp0, t0);
5352
            gen_store_fpr32h(fp0, rd);
5353
            tcg_temp_free_i32(fp0);
5354
        }
5355
        break;
5356
    case 3:
5357
        /* XXX: For now we support only a single FPU context. */
5358
        gen_helper_1i(ctc1, t0, rd);
5359
        break;
5360
    /* COP2: Not implemented. */
5361
    case 4:
5362
    case 5:
5363
        /* fall through */
5364
    default:
5365
        goto die;
5366
    }
5367
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5368
    tcg_temp_free(t0);
5369
    return;
5370

    
5371
die:
5372
    tcg_temp_free(t0);
5373
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5374
    generate_exception(ctx, EXCP_RI);
5375
}
5376

    
5377
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5378
{
5379
    const char *opn = "ldst";
5380

    
5381
    switch (opc) {
5382
    case OPC_MFC0:
5383
        if (rt == 0) {
5384
            /* Treat as NOP. */
5385
            return;
5386
        }
5387
        {
5388
            TCGv t0 = tcg_temp_local_new();
5389

    
5390
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5391
            gen_store_gpr(t0, rt);
5392
            tcg_temp_free(t0);
5393
        }
5394
        opn = "mfc0";
5395
        break;
5396
    case OPC_MTC0:
5397
        {
5398
            TCGv t0 = tcg_temp_local_new();
5399

    
5400
            gen_load_gpr(t0, rt);
5401
            save_cpu_state(ctx, 1);
5402
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5403
            tcg_temp_free(t0);
5404
        }
5405
        opn = "mtc0";
5406
        break;
5407
#if defined(TARGET_MIPS64)
5408
    case OPC_DMFC0:
5409
        check_insn(env, ctx, ISA_MIPS3);
5410
        if (rt == 0) {
5411
            /* Treat as NOP. */
5412
            return;
5413
        }
5414
        {
5415
            TCGv t0 = tcg_temp_local_new();
5416

    
5417
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5418
            gen_store_gpr(t0, rt);
5419
            tcg_temp_free(t0);
5420
        }
5421
        opn = "dmfc0";
5422
        break;
5423
    case OPC_DMTC0:
5424
        check_insn(env, ctx, ISA_MIPS3);
5425
        {
5426
            TCGv t0 = tcg_temp_local_new();
5427

    
5428
            gen_load_gpr(t0, rt);
5429
            save_cpu_state(ctx, 1);
5430
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5431
            tcg_temp_free(t0);
5432
        }
5433
        opn = "dmtc0";
5434
        break;
5435
#endif
5436
    case OPC_MFTR:
5437
        check_insn(env, ctx, ASE_MT);
5438
        if (rd == 0) {
5439
            /* Treat as NOP. */
5440
            return;
5441
        }
5442
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5443
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5444
        opn = "mftr";
5445
        break;
5446
    case OPC_MTTR:
5447
        check_insn(env, ctx, ASE_MT);
5448
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5449
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5450
        opn = "mttr";
5451
        break;
5452
    case OPC_TLBWI:
5453
        opn = "tlbwi";
5454
        if (!env->tlb->helper_tlbwi)
5455
            goto die;
5456
        gen_helper_tlbwi();
5457
        break;
5458
    case OPC_TLBWR:
5459
        opn = "tlbwr";
5460
        if (!env->tlb->helper_tlbwr)
5461
            goto die;
5462
        gen_helper_tlbwr();
5463
        break;
5464
    case OPC_TLBP:
5465
        opn = "tlbp";
5466
        if (!env->tlb->helper_tlbp)
5467
            goto die;
5468
        gen_helper_tlbp();
5469
        break;
5470
    case OPC_TLBR:
5471
        opn = "tlbr";
5472
        if (!env->tlb->helper_tlbr)
5473
            goto die;
5474
        gen_helper_tlbr();
5475
        break;
5476
    case OPC_ERET:
5477
        opn = "eret";
5478
        check_insn(env, ctx, ISA_MIPS2);
5479
        save_cpu_state(ctx, 1);
5480
        gen_helper_eret();
5481
        ctx->bstate = BS_EXCP;
5482
        break;
5483
    case OPC_DERET:
5484
        opn = "deret";
5485
        check_insn(env, ctx, ISA_MIPS32);
5486
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5487
            MIPS_INVAL(opn);
5488
            generate_exception(ctx, EXCP_RI);
5489
        } else {
5490
            save_cpu_state(ctx, 1);
5491
            gen_helper_deret();
5492
            ctx->bstate = BS_EXCP;
5493
        }
5494
        break;
5495
    case OPC_WAIT:
5496
        opn = "wait";
5497
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5498
        /* If we get an exception, we want to restart at next instruction */
5499
        ctx->pc += 4;
5500
        save_cpu_state(ctx, 1);
5501
        ctx->pc -= 4;
5502
        gen_helper_wait();
5503
        ctx->bstate = BS_EXCP;
5504
        break;
5505
    default:
5506
 die:
5507
        MIPS_INVAL(opn);
5508
        generate_exception(ctx, EXCP_RI);
5509
        return;
5510
    }
5511
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5512
}
5513
#endif /* !CONFIG_USER_ONLY */
5514

    
5515
/* CP1 Branches (before delay slot) */
5516
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5517
                                 int32_t cc, int32_t offset)
5518
{
5519
    target_ulong btarget;
5520
    const char *opn = "cp1 cond branch";
5521
    TCGv_i32 t0 = tcg_temp_new_i32();
5522

    
5523
    if (cc != 0)
5524
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5525

    
5526
    btarget = ctx->pc + 4 + offset;
5527

    
5528
    switch (op) {
5529
    case OPC_BC1F:
5530
        {
5531
            int l1 = gen_new_label();
5532
            int l2 = gen_new_label();
5533

    
5534
            get_fp_cond(t0);
5535
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5536
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5537
            tcg_gen_movi_i32(bcond, 0);
5538
            tcg_gen_br(l2);
5539
            gen_set_label(l1);
5540
            tcg_gen_movi_i32(bcond, 1);
5541
            gen_set_label(l2);
5542
        }
5543
        opn = "bc1f";
5544
        goto not_likely;
5545
    case OPC_BC1FL:
5546
        {
5547
            int l1 = gen_new_label();
5548
            int l2 = gen_new_label();
5549

    
5550
            get_fp_cond(t0);
5551
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5552
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5553
            tcg_gen_movi_i32(bcond, 0);
5554
            tcg_gen_br(l2);
5555
            gen_set_label(l1);
5556
            tcg_gen_movi_i32(bcond, 1);
5557
            gen_set_label(l2);
5558
        }
5559
        opn = "bc1fl";
5560
        goto likely;
5561
    case OPC_BC1T:
5562
        {
5563
            int l1 = gen_new_label();
5564
            int l2 = gen_new_label();
5565

    
5566
            get_fp_cond(t0);
5567
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5568
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5569
            tcg_gen_movi_i32(bcond, 0);
5570
            tcg_gen_br(l2);
5571
            gen_set_label(l1);
5572
            tcg_gen_movi_i32(bcond, 1);
5573
            gen_set_label(l2);
5574
        }
5575
        opn = "bc1t";
5576
        goto not_likely;
5577
    case OPC_BC1TL:
5578
        {
5579
            int l1 = gen_new_label();
5580
            int l2 = gen_new_label();
5581

    
5582
            get_fp_cond(t0);
5583
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5584
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5585
            tcg_gen_movi_i32(bcond, 0);
5586
            tcg_gen_br(l2);
5587
            gen_set_label(l1);
5588
            tcg_gen_movi_i32(bcond, 1);
5589
            gen_set_label(l2);
5590
        }
5591
        opn = "bc1tl";
5592
    likely:
5593
        ctx->hflags |= MIPS_HFLAG_BL;
5594
        break;
5595
    case OPC_BC1FANY2:
5596
        {
5597
            int l1 = gen_new_label();
5598
            int l2 = gen_new_label();
5599

    
5600
            get_fp_cond(t0);
5601
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5602
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5603
            tcg_gen_movi_i32(bcond, 0);
5604
            tcg_gen_br(l2);
5605
            gen_set_label(l1);
5606
            tcg_gen_movi_i32(bcond, 1);
5607
            gen_set_label(l2);
5608
        }
5609
        opn = "bc1any2f";
5610
        goto not_likely;
5611
    case OPC_BC1TANY2:
5612
        {
5613
            int l1 = gen_new_label();
5614
            int l2 = gen_new_label();
5615

    
5616
            get_fp_cond(t0);
5617
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5618
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5619
            tcg_gen_movi_i32(bcond, 0);
5620
            tcg_gen_br(l2);
5621
            gen_set_label(l1);
5622
            tcg_gen_movi_i32(bcond, 1);
5623
            gen_set_label(l2);
5624
        }
5625
        opn = "bc1any2t";
5626
        goto not_likely;
5627
    case OPC_BC1FANY4:
5628
        {
5629
            int l1 = gen_new_label();
5630
            int l2 = gen_new_label();
5631

    
5632
            get_fp_cond(t0);
5633
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5634
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5635
            tcg_gen_movi_i32(bcond, 0);
5636
            tcg_gen_br(l2);
5637
            gen_set_label(l1);
5638
            tcg_gen_movi_i32(bcond, 1);
5639
            gen_set_label(l2);
5640
        }
5641
        opn = "bc1any4f";
5642
        goto not_likely;
5643
    case OPC_BC1TANY4:
5644
        {
5645
            int l1 = gen_new_label();
5646
            int l2 = gen_new_label();
5647

    
5648
            get_fp_cond(t0);
5649
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5650
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5651
            tcg_gen_movi_i32(bcond, 0);
5652
            tcg_gen_br(l2);
5653
            gen_set_label(l1);
5654
            tcg_gen_movi_i32(bcond, 1);
5655
            gen_set_label(l2);
5656
        }
5657
        opn = "bc1any4t";
5658
    not_likely:
5659
        ctx->hflags |= MIPS_HFLAG_BC;
5660
        break;
5661
    default:
5662
        MIPS_INVAL(opn);
5663
        generate_exception (ctx, EXCP_RI);
5664
        goto out;
5665
    }
5666
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5667
               ctx->hflags, btarget);
5668
    ctx->btarget = btarget;
5669

    
5670
 out:
5671
    tcg_temp_free_i32(t0);
5672
}
5673

    
5674
/* Coprocessor 1 (FPU) */
5675

    
5676
#define FOP(func, fmt) (((fmt) << 21) | (func))
5677

    
5678
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5679
{
5680
    const char *opn = "cp1 move";
5681
    TCGv t0 = tcg_temp_local_new();
5682

    
5683
    switch (opc) {
5684
    case OPC_MFC1:
5685
        {
5686
            TCGv_i32 fp0 = tcg_temp_new_i32();
5687

    
5688
            gen_load_fpr32(fp0, fs);
5689
            tcg_gen_ext_i32_tl(t0, fp0);
5690
            tcg_temp_free_i32(fp0);
5691
        }
5692
        gen_store_gpr(t0, rt);
5693
        opn = "mfc1";
5694
        break;
5695
    case OPC_MTC1:
5696
        gen_load_gpr(t0, rt);
5697
        {
5698
            TCGv_i32 fp0 = tcg_temp_new_i32();
5699

    
5700
            tcg_gen_trunc_tl_i32(fp0, t0);
5701
            gen_store_fpr32(fp0, fs);
5702
            tcg_temp_free_i32(fp0);
5703
        }
5704
        opn = "mtc1";
5705
        break;
5706
    case OPC_CFC1:
5707
        gen_helper_1i(cfc1, t0, fs);
5708
        gen_store_gpr(t0, rt);
5709
        opn = "cfc1";
5710
        break;
5711
    case OPC_CTC1:
5712
        gen_load_gpr(t0, rt);
5713
        gen_helper_1i(ctc1, t0, fs);
5714
        opn = "ctc1";
5715
        break;
5716
    case OPC_DMFC1:
5717
        {
5718
            TCGv_i64 fp0 = tcg_temp_new_i64();
5719

    
5720
            gen_load_fpr64(ctx, fp0, fs);
5721
            tcg_gen_trunc_i64_tl(t0, fp0);
5722
            tcg_temp_free_i64(fp0);
5723
        }
5724
        gen_store_gpr(t0, rt);
5725
        opn = "dmfc1";
5726
        break;
5727
    case OPC_DMTC1:
5728
        gen_load_gpr(t0, rt);
5729
        {
5730
            TCGv_i64 fp0 = tcg_temp_new_i64();
5731

    
5732
            tcg_gen_extu_tl_i64(fp0, t0);
5733
            gen_store_fpr64(ctx, fp0, fs);
5734
            tcg_temp_free_i64(fp0);
5735
        }
5736
        opn = "dmtc1";
5737
        break;
5738
    case OPC_MFHC1:
5739
        {
5740
            TCGv_i32 fp0 = tcg_temp_new_i32();
5741

    
5742
            gen_load_fpr32h(fp0, fs);
5743
            tcg_gen_ext_i32_tl(t0, fp0);
5744
            tcg_temp_free_i32(fp0);
5745
        }
5746
        gen_store_gpr(t0, rt);
5747
        opn = "mfhc1";
5748
        break;
5749
    case OPC_MTHC1:
5750
        gen_load_gpr(t0, rt);
5751
        {
5752
            TCGv_i32 fp0 = tcg_temp_new_i32();
5753

    
5754
            tcg_gen_trunc_tl_i32(fp0, t0);
5755
            gen_store_fpr32h(fp0, fs);
5756
            tcg_temp_free_i32(fp0);
5757
        }
5758
        opn = "mthc1";
5759
        break;
5760
    default:
5761
        MIPS_INVAL(opn);
5762
        generate_exception (ctx, EXCP_RI);
5763
        goto out;
5764
    }
5765
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5766

    
5767
 out:
5768
    tcg_temp_free(t0);
5769
}
5770

    
5771
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5772
{
5773
    int l1 = gen_new_label();
5774
    uint32_t ccbit;
5775
    TCGCond cond;
5776
    TCGv t0 = tcg_temp_local_new();
5777
    TCGv_i32 r_tmp = tcg_temp_new_i32();
5778

    
5779
    if (cc)
5780
        ccbit = 1 << (24 + cc);
5781
    else
5782
        ccbit = 1 << 23;
5783
    if (tf)
5784
        cond = TCG_COND_EQ;
5785
    else
5786
        cond = TCG_COND_NE;
5787

    
5788
    gen_load_gpr(t0, rd);
5789
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5790
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5791
    tcg_temp_free_i32(r_tmp);
5792
    gen_load_gpr(t0, rs);
5793
    gen_set_label(l1);
5794
    gen_store_gpr(t0, rd);
5795
    tcg_temp_free(t0);
5796
}
5797

    
5798
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5799
{
5800
    uint32_t ccbit;
5801
    int cond;
5802
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5803
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5804
    int l1 = gen_new_label();
5805

    
5806
    if (cc)
5807
        ccbit = 1 << (24 + cc);
5808
    else
5809
        ccbit = 1 << 23;
5810

    
5811
    if (tf)
5812
        cond = TCG_COND_EQ;
5813
    else
5814
        cond = TCG_COND_NE;
5815

    
5816
    gen_load_fpr32(fp0, fd);
5817
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5818
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5819
    tcg_temp_free_i32(r_tmp1);
5820
    gen_load_fpr32(fp0, fs);
5821
    gen_set_label(l1);
5822
    gen_store_fpr32(fp0, fd);
5823
    tcg_temp_free_i32(fp0);
5824
}
5825

    
5826
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5827
{
5828
    uint32_t ccbit;
5829
    int cond;
5830
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5831
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5832
    int l1 = gen_new_label();
5833

    
5834
    if (cc)
5835
        ccbit = 1 << (24 + cc);
5836
    else
5837
        ccbit = 1 << 23;
5838

    
5839
    if (tf)
5840
        cond = TCG_COND_EQ;
5841
    else
5842
        cond = TCG_COND_NE;
5843

    
5844
    gen_load_fpr64(ctx, fp0, fd);
5845
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5846
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5847
    tcg_temp_free_i32(r_tmp1);
5848
    gen_load_fpr64(ctx, fp0, fs);
5849
    gen_set_label(l1);
5850
    gen_store_fpr64(ctx, fp0, fd);
5851
    tcg_temp_free_i64(fp0);
5852
}
5853

    
5854
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5855
{
5856
    uint32_t ccbit1, ccbit2;
5857
    int cond;
5858
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5859
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5860
    int l1 = gen_new_label();
5861
    int l2 = gen_new_label();
5862

    
5863
    if (cc) {
5864
        ccbit1 = 1 << (24 + cc);
5865
        ccbit2 = 1 << (25 + cc);
5866
    } else {
5867
        ccbit1 = 1 << 23;
5868
        ccbit2 = 1 << 25;
5869
    }
5870

    
5871
    if (tf)
5872
        cond = TCG_COND_EQ;
5873
    else
5874
        cond = TCG_COND_NE;
5875

    
5876
    gen_load_fpr32(fp0, fd);
5877
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5878
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5879
    gen_load_fpr32(fp0, fs);
5880
    gen_set_label(l1);
5881
    gen_store_fpr32(fp0, fd);
5882

    
5883
    gen_load_fpr32h(fp0, fd);
5884
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5885
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5886
    gen_load_fpr32h(fp0, fs);
5887
    gen_set_label(l2);
5888
    gen_store_fpr32h(fp0, fd);
5889

    
5890
    tcg_temp_free_i32(r_tmp1);
5891
    tcg_temp_free_i32(fp0);
5892
}
5893

    
5894

    
5895
static void gen_farith (DisasContext *ctx, uint32_t op1,
5896
                        int ft, int fs, int fd, int cc)
5897
{
5898
    const char *opn = "farith";
5899
    const char *condnames[] = {
5900
            "c.f",
5901
            "c.un",
5902
            "c.eq",
5903
            "c.ueq",
5904
            "c.olt",
5905
            "c.ult",
5906
            "c.ole",
5907
            "c.ule",
5908
            "c.sf",
5909
            "c.ngle",
5910
            "c.seq",
5911
            "c.ngl",
5912
            "c.lt",
5913
            "c.nge",
5914
            "c.le",
5915
            "c.ngt",
5916
    };
5917
    const char *condnames_abs[] = {
5918
            "cabs.f",
5919
            "cabs.un",
5920
            "cabs.eq",
5921
            "cabs.ueq",
5922
            "cabs.olt",
5923
            "cabs.ult",
5924
            "cabs.ole",
5925
            "cabs.ule",
5926
            "cabs.sf",
5927
            "cabs.ngle",
5928
            "cabs.seq",
5929
            "cabs.ngl",
5930
            "cabs.lt",
5931
            "cabs.nge",
5932
            "cabs.le",
5933
            "cabs.ngt",
5934
    };
5935
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5936
    uint32_t func = ctx->opcode & 0x3f;
5937

    
5938
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5939
    case FOP(0, 16):
5940
        {
5941
            TCGv_i32 fp0 = tcg_temp_new_i32();
5942
            TCGv_i32 fp1 = tcg_temp_new_i32();
5943

    
5944
            gen_load_fpr32(fp0, fs);
5945
            gen_load_fpr32(fp1, ft);
5946
            gen_helper_float_add_s(fp0, fp0, fp1);
5947
            tcg_temp_free_i32(fp1);
5948
            gen_store_fpr32(fp0, fd);
5949
            tcg_temp_free_i32(fp0);
5950
        }
5951
        opn = "add.s";
5952
        optype = BINOP;
5953
        break;
5954
    case FOP(1, 16):
5955
        {
5956
            TCGv_i32 fp0 = tcg_temp_new_i32();
5957
            TCGv_i32 fp1 = tcg_temp_new_i32();
5958

    
5959
            gen_load_fpr32(fp0, fs);
5960
            gen_load_fpr32(fp1, ft);
5961
            gen_helper_float_sub_s(fp0, fp0, fp1);
5962
            tcg_temp_free_i32(fp1);
5963
            gen_store_fpr32(fp0, fd);
5964
            tcg_temp_free_i32(fp0);
5965
        }
5966
        opn = "sub.s";
5967
        optype = BINOP;
5968
        break;
5969
    case FOP(2, 16):
5970
        {
5971
            TCGv_i32 fp0 = tcg_temp_new_i32();
5972
            TCGv_i32 fp1 = tcg_temp_new_i32();
5973

    
5974
            gen_load_fpr32(fp0, fs);
5975
            gen_load_fpr32(fp1, ft);
5976
            gen_helper_float_mul_s(fp0, fp0, fp1);
5977
            tcg_temp_free_i32(fp1);
5978
            gen_store_fpr32(fp0, fd);
5979
            tcg_temp_free_i32(fp0);
5980
        }
5981
        opn = "mul.s";
5982
        optype = BINOP;
5983
        break;
5984
    case FOP(3, 16):
5985
        {
5986
            TCGv_i32 fp0 = tcg_temp_new_i32();
5987
            TCGv_i32 fp1 = tcg_temp_new_i32();
5988

    
5989
            gen_load_fpr32(fp0, fs);
5990
            gen_load_fpr32(fp1, ft);
5991
            gen_helper_float_div_s(fp0, fp0, fp1);
5992
            tcg_temp_free_i32(fp1);
5993
            gen_store_fpr32(fp0, fd);
5994
            tcg_temp_free_i32(fp0);
5995
        }
5996
        opn = "div.s";
5997
        optype = BINOP;
5998
        break;
5999
    case FOP(4, 16):
6000
        {
6001
            TCGv_i32 fp0 = tcg_temp_new_i32();
6002

    
6003
            gen_load_fpr32(fp0, fs);
6004
            gen_helper_float_sqrt_s(fp0, fp0);
6005
            gen_store_fpr32(fp0, fd);
6006
            tcg_temp_free_i32(fp0);
6007
        }
6008
        opn = "sqrt.s";
6009
        break;
6010
    case FOP(5, 16):
6011
        {
6012
            TCGv_i32 fp0 = tcg_temp_new_i32();
6013

    
6014
            gen_load_fpr32(fp0, fs);
6015
            gen_helper_float_abs_s(fp0, fp0);
6016
            gen_store_fpr32(fp0, fd);
6017
            tcg_temp_free_i32(fp0);
6018
        }
6019
        opn = "abs.s";
6020
        break;
6021
    case FOP(6, 16):
6022
        {
6023
            TCGv_i32 fp0 = tcg_temp_new_i32();
6024

    
6025
            gen_load_fpr32(fp0, fs);
6026
            gen_store_fpr32(fp0, fd);
6027
            tcg_temp_free_i32(fp0);
6028
        }
6029
        opn = "mov.s";
6030
        break;
6031
    case FOP(7, 16):
6032
        {
6033
            TCGv_i32 fp0 = tcg_temp_new_i32();
6034

    
6035
            gen_load_fpr32(fp0, fs);
6036
            gen_helper_float_chs_s(fp0, fp0);
6037
            gen_store_fpr32(fp0, fd);
6038
            tcg_temp_free_i32(fp0);
6039
        }
6040
        opn = "neg.s";
6041
        break;
6042
    case FOP(8, 16):
6043
        check_cp1_64bitmode(ctx);
6044
        {
6045
            TCGv_i32 fp32 = tcg_temp_new_i32();
6046
            TCGv_i64 fp64 = tcg_temp_new_i64();
6047

    
6048
            gen_load_fpr32(fp32, fs);
6049
            gen_helper_float_roundl_s(fp64, fp32);
6050
            tcg_temp_free_i32(fp32);
6051
            gen_store_fpr64(ctx, fp64, fd);
6052
            tcg_temp_free_i64(fp64);
6053
        }
6054
        opn = "round.l.s";
6055
        break;
6056
    case FOP(9, 16):
6057
        check_cp1_64bitmode(ctx);
6058
        {
6059
            TCGv_i32 fp32 = tcg_temp_new_i32();
6060
            TCGv_i64 fp64 = tcg_temp_new_i64();
6061

    
6062
            gen_load_fpr32(fp32, fs);
6063
            gen_helper_float_truncl_s(fp64, fp32);
6064
            tcg_temp_free_i32(fp32);
6065
            gen_store_fpr64(ctx, fp64, fd);
6066
            tcg_temp_free_i64(fp64);
6067
        }
6068
        opn = "trunc.l.s";
6069
        break;
6070
    case FOP(10, 16):
6071
        check_cp1_64bitmode(ctx);
6072
        {
6073
            TCGv_i32 fp32 = tcg_temp_new_i32();
6074
            TCGv_i64 fp64 = tcg_temp_new_i64();
6075

    
6076
            gen_load_fpr32(fp32, fs);
6077
            gen_helper_float_ceill_s(fp64, fp32);
6078
            tcg_temp_free_i32(fp32);
6079
            gen_store_fpr64(ctx, fp64, fd);
6080
            tcg_temp_free_i64(fp64);
6081
        }
6082
        opn = "ceil.l.s";
6083
        break;
6084
    case FOP(11, 16):
6085
        check_cp1_64bitmode(ctx);
6086
        {
6087
            TCGv_i32 fp32 = tcg_temp_new_i32();
6088
            TCGv_i64 fp64 = tcg_temp_new_i64();
6089

    
6090
            gen_load_fpr32(fp32, fs);
6091
            gen_helper_float_floorl_s(fp64, fp32);
6092
            tcg_temp_free_i32(fp32);
6093
            gen_store_fpr64(ctx, fp64, fd);
6094
            tcg_temp_free_i64(fp64);
6095
        }
6096
        opn = "floor.l.s";
6097
        break;
6098
    case FOP(12, 16):
6099
        {
6100
            TCGv_i32 fp0 = tcg_temp_new_i32();
6101

    
6102
            gen_load_fpr32(fp0, fs);
6103
            gen_helper_float_roundw_s(fp0, fp0);
6104
            gen_store_fpr32(fp0, fd);
6105
            tcg_temp_free_i32(fp0);
6106
        }
6107
        opn = "round.w.s";
6108
        break;
6109
    case FOP(13, 16):
6110
        {
6111
            TCGv_i32 fp0 = tcg_temp_new_i32();
6112

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

    
6124
            gen_load_fpr32(fp0, fs);
6125
            gen_helper_float_ceilw_s(fp0, fp0);
6126
            gen_store_fpr32(fp0, fd);
6127
            tcg_temp_free_i32(fp0);
6128
        }
6129
        opn = "ceil.w.s";
6130
        break;
6131
    case FOP(15, 16):
6132
        {
6133
            TCGv_i32 fp0 = tcg_temp_new_i32();
6134

    
6135
            gen_load_fpr32(fp0, fs);
6136
            gen_helper_float_floorw_s(fp0, fp0);
6137
            gen_store_fpr32(fp0, fd);
6138
            tcg_temp_free_i32(fp0);
6139
        }
6140
        opn = "floor.w.s";
6141
        break;
6142
    case FOP(17, 16):
6143
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6144
        opn = "movcf.s";
6145
        break;
6146
    case FOP(18, 16):
6147
        {
6148
            int l1 = gen_new_label();
6149
            TCGv t0 = tcg_temp_new();
6150
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6151

    
6152
            gen_load_gpr(t0, ft);
6153
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6154
            gen_load_fpr32(fp0, fs);
6155
            gen_store_fpr32(fp0, fd);
6156
            tcg_temp_free_i32(fp0);
6157
            gen_set_label(l1);
6158
            tcg_temp_free(t0);
6159
        }
6160
        opn = "movz.s";
6161
        break;
6162
    case FOP(19, 16):
6163
        {
6164
            int l1 = gen_new_label();
6165
            TCGv t0 = tcg_temp_new();
6166
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6167

    
6168
            gen_load_gpr(t0, ft);
6169
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6170
            gen_load_fpr32(fp0, fs);
6171
            gen_store_fpr32(fp0, fd);
6172
            tcg_temp_free_i32(fp0);
6173
            gen_set_label(l1);
6174
            tcg_temp_free(t0);
6175
        }
6176
        opn = "movn.s";
6177
        break;
6178
    case FOP(21, 16):
6179
        check_cop1x(ctx);
6180
        {
6181
            TCGv_i32 fp0 = tcg_temp_new_i32();
6182

    
6183
            gen_load_fpr32(fp0, fs);
6184
            gen_helper_float_recip_s(fp0, fp0);
6185
            gen_store_fpr32(fp0, fd);
6186
            tcg_temp_free_i32(fp0);
6187
        }
6188
        opn = "recip.s";
6189
        break;
6190
    case FOP(22, 16):
6191
        check_cop1x(ctx);
6192
        {
6193
            TCGv_i32 fp0 = tcg_temp_new_i32();
6194

    
6195
            gen_load_fpr32(fp0, fs);
6196
            gen_helper_float_rsqrt_s(fp0, fp0);
6197
            gen_store_fpr32(fp0, fd);
6198
            tcg_temp_free_i32(fp0);
6199
        }
6200
        opn = "rsqrt.s";
6201
        break;
6202
    case FOP(28, 16):
6203
        check_cp1_64bitmode(ctx);
6204
        {
6205
            TCGv_i32 fp0 = tcg_temp_new_i32();
6206
            TCGv_i32 fp1 = tcg_temp_new_i32();
6207

    
6208
            gen_load_fpr32(fp0, fs);
6209
            gen_load_fpr32(fp1, fd);
6210
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6211
            tcg_temp_free_i32(fp1);
6212
            gen_store_fpr32(fp0, fd);
6213
            tcg_temp_free_i32(fp0);
6214
        }
6215
        opn = "recip2.s";
6216
        break;
6217
    case FOP(29, 16):
6218
        check_cp1_64bitmode(ctx);
6219
        {
6220
            TCGv_i32 fp0 = tcg_temp_new_i32();
6221

    
6222
            gen_load_fpr32(fp0, fs);
6223
            gen_helper_float_recip1_s(fp0, fp0);
6224
            gen_store_fpr32(fp0, fd);
6225
            tcg_temp_free_i32(fp0);
6226
        }
6227
        opn = "recip1.s";
6228
        break;
6229
    case FOP(30, 16):
6230
        check_cp1_64bitmode(ctx);
6231
        {
6232
            TCGv_i32 fp0 = tcg_temp_new_i32();
6233

    
6234
            gen_load_fpr32(fp0, fs);
6235
            gen_helper_float_rsqrt1_s(fp0, fp0);
6236
            gen_store_fpr32(fp0, fd);
6237
            tcg_temp_free_i32(fp0);
6238
        }
6239
        opn = "rsqrt1.s";
6240
        break;
6241
    case FOP(31, 16):
6242
        check_cp1_64bitmode(ctx);
6243
        {
6244
            TCGv_i32 fp0 = tcg_temp_new_i32();
6245
            TCGv_i32 fp1 = tcg_temp_new_i32();
6246

    
6247
            gen_load_fpr32(fp0, fs);
6248
            gen_load_fpr32(fp1, ft);
6249
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6250
            tcg_temp_free_i32(fp1);
6251
            gen_store_fpr32(fp0, fd);
6252
            tcg_temp_free_i32(fp0);
6253
        }
6254
        opn = "rsqrt2.s";
6255
        break;
6256
    case FOP(33, 16):
6257
        check_cp1_registers(ctx, fd);
6258
        {
6259
            TCGv_i32 fp32 = tcg_temp_new_i32();
6260
            TCGv_i64 fp64 = tcg_temp_new_i64();
6261

    
6262
            gen_load_fpr32(fp32, fs);
6263
            gen_helper_float_cvtd_s(fp64, fp32);
6264
            tcg_temp_free_i32(fp32);
6265
            gen_store_fpr64(ctx, fp64, fd);
6266
            tcg_temp_free_i64(fp64);
6267
        }
6268
        opn = "cvt.d.s";
6269
        break;
6270
    case FOP(36, 16):
6271
        {
6272
            TCGv_i32 fp0 = tcg_temp_new_i32();
6273

    
6274
            gen_load_fpr32(fp0, fs);
6275
            gen_helper_float_cvtw_s(fp0, fp0);
6276
            gen_store_fpr32(fp0, fd);
6277
            tcg_temp_free_i32(fp0);
6278
        }
6279
        opn = "cvt.w.s";
6280
        break;
6281
    case FOP(37, 16):
6282
        check_cp1_64bitmode(ctx);
6283
        {
6284
            TCGv_i32 fp32 = tcg_temp_new_i32();
6285
            TCGv_i64 fp64 = tcg_temp_new_i64();
6286

    
6287
            gen_load_fpr32(fp32, fs);
6288
            gen_helper_float_cvtl_s(fp64, fp32);
6289
            tcg_temp_free_i32(fp32);
6290
            gen_store_fpr64(ctx, fp64, fd);
6291
            tcg_temp_free_i64(fp64);
6292
        }
6293
        opn = "cvt.l.s";
6294
        break;
6295
    case FOP(38, 16):
6296
        check_cp1_64bitmode(ctx);
6297
        {
6298
            TCGv_i64 fp64 = tcg_temp_new_i64();
6299
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6300
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6301

    
6302
            gen_load_fpr32(fp32_0, fs);
6303
            gen_load_fpr32(fp32_1, ft);
6304
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6305
            tcg_temp_free_i32(fp32_1);
6306
            tcg_temp_free_i32(fp32_0);
6307
            gen_store_fpr64(ctx, fp64, fd);
6308
            tcg_temp_free_i64(fp64);
6309
        }
6310
        opn = "cvt.ps.s";
6311
        break;
6312
    case FOP(48, 16):
6313
    case FOP(49, 16):
6314
    case FOP(50, 16):
6315
    case FOP(51, 16):
6316
    case FOP(52, 16):
6317
    case FOP(53, 16):
6318
    case FOP(54, 16):
6319
    case FOP(55, 16):
6320
    case FOP(56, 16):
6321
    case FOP(57, 16):
6322
    case FOP(58, 16):
6323
    case FOP(59, 16):
6324
    case FOP(60, 16):
6325
    case FOP(61, 16):
6326
    case FOP(62, 16):
6327
    case FOP(63, 16):
6328
        {
6329
            TCGv_i32 fp0 = tcg_temp_new_i32();
6330
            TCGv_i32 fp1 = tcg_temp_new_i32();
6331

    
6332
            gen_load_fpr32(fp0, fs);
6333
            gen_load_fpr32(fp1, ft);
6334
            if (ctx->opcode & (1 << 6)) {
6335
                check_cop1x(ctx);
6336
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6337
                opn = condnames_abs[func-48];
6338
            } else {
6339
                gen_cmp_s(func-48, fp0, fp1, cc);
6340
                opn = condnames[func-48];
6341
            }
6342
            tcg_temp_free_i32(fp0);
6343
            tcg_temp_free_i32(fp1);
6344
        }
6345
        break;
6346
    case FOP(0, 17):
6347
        check_cp1_registers(ctx, fs | ft | fd);
6348
        {
6349
            TCGv_i64 fp0 = tcg_temp_new_i64();
6350
            TCGv_i64 fp1 = tcg_temp_new_i64();
6351

    
6352
            gen_load_fpr64(ctx, fp0, fs);
6353
            gen_load_fpr64(ctx, fp1, ft);
6354
            gen_helper_float_add_d(fp0, fp0, fp1);
6355
            tcg_temp_free_i64(fp1);
6356
            gen_store_fpr64(ctx, fp0, fd);
6357
            tcg_temp_free_i64(fp0);
6358
        }
6359
        opn = "add.d";
6360
        optype = BINOP;
6361
        break;
6362
    case FOP(1, 17):
6363
        check_cp1_registers(ctx, fs | ft | fd);
6364
        {
6365
            TCGv_i64 fp0 = tcg_temp_new_i64();
6366
            TCGv_i64 fp1 = tcg_temp_new_i64();
6367

    
6368
            gen_load_fpr64(ctx, fp0, fs);
6369
            gen_load_fpr64(ctx, fp1, ft);
6370
            gen_helper_float_sub_d(fp0, fp0, fp1);
6371
            tcg_temp_free_i64(fp1);
6372
            gen_store_fpr64(ctx, fp0, fd);
6373
            tcg_temp_free_i64(fp0);
6374
        }
6375
        opn = "sub.d";
6376
        optype = BINOP;
6377
        break;
6378
    case FOP(2, 17):
6379
        check_cp1_registers(ctx, fs | ft | fd);
6380
        {
6381
            TCGv_i64 fp0 = tcg_temp_new_i64();
6382
            TCGv_i64 fp1 = tcg_temp_new_i64();
6383

    
6384
            gen_load_fpr64(ctx, fp0, fs);
6385
            gen_load_fpr64(ctx, fp1, ft);
6386
            gen_helper_float_mul_d(fp0, fp0, fp1);
6387
            tcg_temp_free_i64(fp1);
6388
            gen_store_fpr64(ctx, fp0, fd);
6389
            tcg_temp_free_i64(fp0);
6390
        }
6391
        opn = "mul.d";
6392
        optype = BINOP;
6393
        break;
6394
    case FOP(3, 17):
6395
        check_cp1_registers(ctx, fs | ft | fd);
6396
        {
6397
            TCGv_i64 fp0 = tcg_temp_new_i64();
6398
            TCGv_i64 fp1 = tcg_temp_new_i64();
6399

    
6400
            gen_load_fpr64(ctx, fp0, fs);
6401
            gen_load_fpr64(ctx, fp1, ft);
6402
            gen_helper_float_div_d(fp0, fp0, fp1);
6403
            tcg_temp_free_i64(fp1);
6404
            gen_store_fpr64(ctx, fp0, fd);
6405
            tcg_temp_free_i64(fp0);
6406
        }
6407
        opn = "div.d";
6408
        optype = BINOP;
6409
        break;
6410
    case FOP(4, 17):
6411
        check_cp1_registers(ctx, fs | fd);
6412
        {
6413
            TCGv_i64 fp0 = tcg_temp_new_i64();
6414

    
6415
            gen_load_fpr64(ctx, fp0, fs);
6416
            gen_helper_float_sqrt_d(fp0, fp0);
6417
            gen_store_fpr64(ctx, fp0, fd);
6418
            tcg_temp_free_i64(fp0);
6419
        }
6420
        opn = "sqrt.d";
6421
        break;
6422
    case FOP(5, 17):
6423
        check_cp1_registers(ctx, fs | fd);
6424
        {
6425
            TCGv_i64 fp0 = tcg_temp_new_i64();
6426

    
6427
            gen_load_fpr64(ctx, fp0, fs);
6428
            gen_helper_float_abs_d(fp0, fp0);
6429
            gen_store_fpr64(ctx, fp0, fd);
6430
            tcg_temp_free_i64(fp0);
6431
        }
6432
        opn = "abs.d";
6433
        break;
6434
    case FOP(6, 17):
6435
        check_cp1_registers(ctx, fs | fd);
6436
        {
6437
            TCGv_i64 fp0 = tcg_temp_new_i64();
6438

    
6439
            gen_load_fpr64(ctx, fp0, fs);
6440
            gen_store_fpr64(ctx, fp0, fd);
6441
            tcg_temp_free_i64(fp0);
6442
        }
6443
        opn = "mov.d";
6444
        break;
6445
    case FOP(7, 17):
6446
        check_cp1_registers(ctx, fs | fd);
6447
        {
6448
            TCGv_i64 fp0 = tcg_temp_new_i64();
6449

    
6450
            gen_load_fpr64(ctx, fp0, fs);
6451
            gen_helper_float_chs_d(fp0, fp0);
6452
            gen_store_fpr64(ctx, fp0, fd);
6453
            tcg_temp_free_i64(fp0);
6454
        }
6455
        opn = "neg.d";
6456
        break;
6457
    case FOP(8, 17):
6458
        check_cp1_64bitmode(ctx);
6459
        {
6460
            TCGv_i64 fp0 = tcg_temp_new_i64();
6461

    
6462
            gen_load_fpr64(ctx, fp0, fs);
6463
            gen_helper_float_roundl_d(fp0, fp0);
6464
            gen_store_fpr64(ctx, fp0, fd);
6465
            tcg_temp_free_i64(fp0);
6466
        }
6467
        opn = "round.l.d";
6468
        break;
6469
    case FOP(9, 17):
6470
        check_cp1_64bitmode(ctx);
6471
        {
6472
            TCGv_i64 fp0 = tcg_temp_new_i64();
6473

    
6474
            gen_load_fpr64(ctx, fp0, fs);
6475
            gen_helper_float_truncl_d(fp0, fp0);
6476
            gen_store_fpr64(ctx, fp0, fd);
6477
            tcg_temp_free_i64(fp0);
6478
        }
6479
        opn = "trunc.l.d";
6480
        break;
6481
    case FOP(10, 17):
6482
        check_cp1_64bitmode(ctx);
6483
        {
6484
            TCGv_i64 fp0 = tcg_temp_new_i64();
6485

    
6486
            gen_load_fpr64(ctx, fp0, fs);
6487
            gen_helper_float_ceill_d(fp0, fp0);
6488
            gen_store_fpr64(ctx, fp0, fd);
6489
            tcg_temp_free_i64(fp0);
6490
        }
6491
        opn = "ceil.l.d";
6492
        break;
6493
    case FOP(11, 17):
6494
        check_cp1_64bitmode(ctx);
6495
        {
6496
            TCGv_i64 fp0 = tcg_temp_new_i64();
6497

    
6498
            gen_load_fpr64(ctx, fp0, fs);
6499
            gen_helper_float_floorl_d(fp0, fp0);
6500
            gen_store_fpr64(ctx, fp0, fd);
6501
            tcg_temp_free_i64(fp0);
6502
        }
6503
        opn = "floor.l.d";
6504
        break;
6505
    case FOP(12, 17):
6506
        check_cp1_registers(ctx, fs);
6507
        {
6508
            TCGv_i32 fp32 = tcg_temp_new_i32();
6509
            TCGv_i64 fp64 = tcg_temp_new_i64();
6510

    
6511
            gen_load_fpr64(ctx, fp64, fs);
6512
            gen_helper_float_roundw_d(fp32, fp64);
6513
            tcg_temp_free_i64(fp64);
6514
            gen_store_fpr32(fp32, fd);
6515
            tcg_temp_free_i32(fp32);
6516
        }
6517
        opn = "round.w.d";
6518
        break;
6519
    case FOP(13, 17):
6520
        check_cp1_registers(ctx, fs);
6521
        {
6522
            TCGv_i32 fp32 = tcg_temp_new_i32();
6523
            TCGv_i64 fp64 = tcg_temp_new_i64();
6524

    
6525
            gen_load_fpr64(ctx, fp64, fs);
6526
            gen_helper_float_truncw_d(fp32, fp64);
6527
            tcg_temp_free_i64(fp64);
6528
            gen_store_fpr32(fp32, fd);
6529
            tcg_temp_free_i32(fp32);
6530
        }
6531
        opn = "trunc.w.d";
6532
        break;
6533
    case FOP(14, 17):
6534
        check_cp1_registers(ctx, fs);
6535
        {
6536
            TCGv_i32 fp32 = tcg_temp_new_i32();
6537
            TCGv_i64 fp64 = tcg_temp_new_i64();
6538

    
6539
            gen_load_fpr64(ctx, fp64, fs);
6540
            gen_helper_float_ceilw_d(fp32, fp64);
6541
            tcg_temp_free_i64(fp64);
6542
            gen_store_fpr32(fp32, fd);
6543
            tcg_temp_free_i32(fp32);
6544
        }
6545
        opn = "ceil.w.d";
6546
        break;
6547
    case FOP(15, 17):
6548
        check_cp1_registers(ctx, fs);
6549
        {
6550
            TCGv_i32 fp32 = tcg_temp_new_i32();
6551
            TCGv_i64 fp64 = tcg_temp_new_i64();
6552

    
6553
            gen_load_fpr64(ctx, fp64, fs);
6554
            gen_helper_float_floorw_d(fp32, fp64);
6555
            tcg_temp_free_i64(fp64);
6556
            gen_store_fpr32(fp32, fd);
6557
            tcg_temp_free_i32(fp32);
6558
        }
6559
        opn = "floor.w.d";
6560
        break;
6561
    case FOP(17, 17):
6562
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6563
        opn = "movcf.d";
6564
        break;
6565
    case FOP(18, 17):
6566
        {
6567
            int l1 = gen_new_label();
6568
            TCGv t0 = tcg_temp_new();
6569
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6570

    
6571
            gen_load_gpr(t0, ft);
6572
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6573
            gen_load_fpr64(ctx, fp0, fs);
6574
            gen_store_fpr64(ctx, fp0, fd);
6575
            tcg_temp_free_i64(fp0);
6576
            gen_set_label(l1);
6577
            tcg_temp_free(t0);
6578
        }
6579
        opn = "movz.d";
6580
        break;
6581
    case FOP(19, 17):
6582
        {
6583
            int l1 = gen_new_label();
6584
            TCGv t0 = tcg_temp_new();
6585
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6586

    
6587
            gen_load_gpr(t0, ft);
6588
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6589
            gen_load_fpr64(ctx, fp0, fs);
6590
            gen_store_fpr64(ctx, fp0, fd);
6591
            tcg_temp_free_i64(fp0);
6592
            gen_set_label(l1);
6593
            tcg_temp_free(t0);
6594
        }
6595
        opn = "movn.d";
6596
        break;
6597
    case FOP(21, 17):
6598
        check_cp1_64bitmode(ctx);
6599
        {
6600
            TCGv_i64 fp0 = tcg_temp_new_i64();
6601

    
6602
            gen_load_fpr64(ctx, fp0, fs);
6603
            gen_helper_float_recip_d(fp0, fp0);
6604
            gen_store_fpr64(ctx, fp0, fd);
6605
            tcg_temp_free_i64(fp0);
6606
        }
6607
        opn = "recip.d";
6608
        break;
6609
    case FOP(22, 17):
6610
        check_cp1_64bitmode(ctx);
6611
        {
6612
            TCGv_i64 fp0 = tcg_temp_new_i64();
6613

    
6614
            gen_load_fpr64(ctx, fp0, fs);
6615
            gen_helper_float_rsqrt_d(fp0, fp0);
6616
            gen_store_fpr64(ctx, fp0, fd);
6617
            tcg_temp_free_i64(fp0);
6618
        }
6619
        opn = "rsqrt.d";
6620
        break;
6621
    case FOP(28, 17):
6622
        check_cp1_64bitmode(ctx);
6623
        {
6624
            TCGv_i64 fp0 = tcg_temp_new_i64();
6625
            TCGv_i64 fp1 = tcg_temp_new_i64();
6626

    
6627
            gen_load_fpr64(ctx, fp0, fs);
6628
            gen_load_fpr64(ctx, fp1, ft);
6629
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6630
            tcg_temp_free_i64(fp1);
6631
            gen_store_fpr64(ctx, fp0, fd);
6632
            tcg_temp_free_i64(fp0);
6633
        }
6634
        opn = "recip2.d";
6635
        break;
6636
    case FOP(29, 17):
6637
        check_cp1_64bitmode(ctx);
6638
        {
6639
            TCGv_i64 fp0 = tcg_temp_new_i64();
6640

    
6641
            gen_load_fpr64(ctx, fp0, fs);
6642
            gen_helper_float_recip1_d(fp0, fp0);
6643
            gen_store_fpr64(ctx, fp0, fd);
6644
            tcg_temp_free_i64(fp0);
6645
        }
6646
        opn = "recip1.d";
6647
        break;
6648
    case FOP(30, 17):
6649
        check_cp1_64bitmode(ctx);
6650
        {
6651
            TCGv_i64 fp0 = tcg_temp_new_i64();
6652

    
6653
            gen_load_fpr64(ctx, fp0, fs);
6654
            gen_helper_float_rsqrt1_d(fp0, fp0);
6655
            gen_store_fpr64(ctx, fp0, fd);
6656
            tcg_temp_free_i64(fp0);
6657
        }
6658
        opn = "rsqrt1.d";
6659
        break;
6660
    case FOP(31, 17):
6661
        check_cp1_64bitmode(ctx);
6662
        {
6663
            TCGv_i64 fp0 = tcg_temp_new_i64();
6664
            TCGv_i64 fp1 = tcg_temp_new_i64();
6665

    
6666
            gen_load_fpr64(ctx, fp0, fs);
6667
            gen_load_fpr64(ctx, fp1, ft);
6668
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6669
            tcg_temp_free_i64(fp1);
6670
            gen_store_fpr64(ctx, fp0, fd);
6671
            tcg_temp_free_i64(fp0);
6672
        }
6673
        opn = "rsqrt2.d";
6674
        break;
6675
    case FOP(48, 17):
6676
    case FOP(49, 17):
6677
    case FOP(50, 17):
6678
    case FOP(51, 17):
6679
    case FOP(52, 17):
6680
    case FOP(53, 17):
6681
    case FOP(54, 17):
6682
    case FOP(55, 17):
6683
    case FOP(56, 17):
6684
    case FOP(57, 17):
6685
    case FOP(58, 17):
6686
    case FOP(59, 17):
6687
    case FOP(60, 17):
6688
    case FOP(61, 17):
6689
    case FOP(62, 17):
6690
    case FOP(63, 17):
6691
        {
6692
            TCGv_i64 fp0 = tcg_temp_new_i64();
6693
            TCGv_i64 fp1 = tcg_temp_new_i64();
6694

    
6695
            gen_load_fpr64(ctx, fp0, fs);
6696
            gen_load_fpr64(ctx, fp1, ft);
6697
            if (ctx->opcode & (1 << 6)) {
6698
                check_cop1x(ctx);
6699
                check_cp1_registers(ctx, fs | ft);
6700
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6701
                opn = condnames_abs[func-48];
6702
            } else {
6703
                check_cp1_registers(ctx, fs | ft);
6704
                gen_cmp_d(func-48, fp0, fp1, cc);
6705
                opn = condnames[func-48];
6706
            }
6707
            tcg_temp_free_i64(fp0);
6708
            tcg_temp_free_i64(fp1);
6709
        }
6710
        break;
6711
    case FOP(32, 17):
6712
        check_cp1_registers(ctx, fs);
6713
        {
6714
            TCGv_i32 fp32 = tcg_temp_new_i32();
6715
            TCGv_i64 fp64 = tcg_temp_new_i64();
6716

    
6717
            gen_load_fpr64(ctx, fp64, fs);
6718
            gen_helper_float_cvts_d(fp32, fp64);
6719
            tcg_temp_free_i64(fp64);
6720
            gen_store_fpr32(fp32, fd);
6721
            tcg_temp_free_i32(fp32);
6722
        }
6723
        opn = "cvt.s.d";
6724
        break;
6725
    case FOP(36, 17):
6726
        check_cp1_registers(ctx, fs);
6727
        {
6728
            TCGv_i32 fp32 = tcg_temp_new_i32();
6729
            TCGv_i64 fp64 = tcg_temp_new_i64();
6730

    
6731
            gen_load_fpr64(ctx, fp64, fs);
6732
            gen_helper_float_cvtw_d(fp32, fp64);
6733
            tcg_temp_free_i64(fp64);
6734
            gen_store_fpr32(fp32, fd);
6735
            tcg_temp_free_i32(fp32);
6736
        }
6737
        opn = "cvt.w.d";
6738
        break;
6739
    case FOP(37, 17):
6740
        check_cp1_64bitmode(ctx);
6741
        {
6742
            TCGv_i64 fp0 = tcg_temp_new_i64();
6743

    
6744
            gen_load_fpr64(ctx, fp0, fs);
6745
            gen_helper_float_cvtl_d(fp0, fp0);
6746
            gen_store_fpr64(ctx, fp0, fd);
6747
            tcg_temp_free_i64(fp0);
6748
        }
6749
        opn = "cvt.l.d";
6750
        break;
6751
    case FOP(32, 20):
6752
        {
6753
            TCGv_i32 fp0 = tcg_temp_new_i32();
6754

    
6755
            gen_load_fpr32(fp0, fs);
6756
            gen_helper_float_cvts_w(fp0, fp0);
6757
            gen_store_fpr32(fp0, fd);
6758
            tcg_temp_free_i32(fp0);
6759
        }
6760
        opn = "cvt.s.w";
6761
        break;
6762
    case FOP(33, 20):
6763
        check_cp1_registers(ctx, fd);
6764
        {
6765
            TCGv_i32 fp32 = tcg_temp_new_i32();
6766
            TCGv_i64 fp64 = tcg_temp_new_i64();
6767

    
6768
            gen_load_fpr32(fp32, fs);
6769
            gen_helper_float_cvtd_w(fp64, fp32);
6770
            tcg_temp_free_i32(fp32);
6771
            gen_store_fpr64(ctx, fp64, fd);
6772
            tcg_temp_free_i64(fp64);
6773
        }
6774
        opn = "cvt.d.w";
6775
        break;
6776
    case FOP(32, 21):
6777
        check_cp1_64bitmode(ctx);
6778
        {
6779
            TCGv_i32 fp32 = tcg_temp_new_i32();
6780
            TCGv_i64 fp64 = tcg_temp_new_i64();
6781

    
6782
            gen_load_fpr64(ctx, fp64, fs);
6783
            gen_helper_float_cvts_l(fp32, fp64);
6784
            tcg_temp_free_i64(fp64);
6785
            gen_store_fpr32(fp32, fd);
6786
            tcg_temp_free_i32(fp32);
6787
        }
6788
        opn = "cvt.s.l";
6789
        break;
6790
    case FOP(33, 21):
6791
        check_cp1_64bitmode(ctx);
6792
        {
6793
            TCGv_i64 fp0 = tcg_temp_new_i64();
6794

    
6795
            gen_load_fpr64(ctx, fp0, fs);
6796
            gen_helper_float_cvtd_l(fp0, fp0);
6797
            gen_store_fpr64(ctx, fp0, fd);
6798
            tcg_temp_free_i64(fp0);
6799
        }
6800
        opn = "cvt.d.l";
6801
        break;
6802
    case FOP(38, 20):
6803
        check_cp1_64bitmode(ctx);
6804
        {
6805
            TCGv_i64 fp0 = tcg_temp_new_i64();
6806

    
6807
            gen_load_fpr64(ctx, fp0, fs);
6808
            gen_helper_float_cvtps_pw(fp0, fp0);
6809
            gen_store_fpr64(ctx, fp0, fd);
6810
            tcg_temp_free_i64(fp0);
6811
        }
6812
        opn = "cvt.ps.pw";
6813
        break;
6814
    case FOP(0, 22):
6815
        check_cp1_64bitmode(ctx);
6816
        {
6817
            TCGv_i64 fp0 = tcg_temp_new_i64();
6818
            TCGv_i64 fp1 = tcg_temp_new_i64();
6819

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

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

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

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

    
6876
            gen_load_fpr64(ctx, fp0, fs);
6877
            gen_store_fpr64(ctx, fp0, fd);
6878
            tcg_temp_free_i64(fp0);
6879
        }
6880
        opn = "mov.ps";
6881
        break;
6882
    case FOP(7, 22):
6883
        check_cp1_64bitmode(ctx);
6884
        {
6885
            TCGv_i64 fp0 = tcg_temp_new_i64();
6886

    
6887
            gen_load_fpr64(ctx, fp0, fs);
6888
            gen_helper_float_chs_ps(fp0, fp0);
6889
            gen_store_fpr64(ctx, fp0, fd);
6890
            tcg_temp_free_i64(fp0);
6891
        }
6892
        opn = "neg.ps";
6893
        break;
6894
    case FOP(17, 22):
6895
        check_cp1_64bitmode(ctx);
6896
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6897
        opn = "movcf.ps";
6898
        break;
6899
    case FOP(18, 22):
6900
        check_cp1_64bitmode(ctx);
6901
        {
6902
            int l1 = gen_new_label();
6903
            TCGv t0 = tcg_temp_new();
6904
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6905
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6906

    
6907
            gen_load_gpr(t0, ft);
6908
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6909
            gen_load_fpr32(fp0, fs);
6910
            gen_load_fpr32h(fph0, fs);
6911
            gen_store_fpr32(fp0, fd);
6912
            gen_store_fpr32h(fph0, fd);
6913
            tcg_temp_free_i32(fp0);
6914
            tcg_temp_free_i32(fph0);
6915
            gen_set_label(l1);
6916
            tcg_temp_free(t0);
6917
        }
6918
        opn = "movz.ps";
6919
        break;
6920
    case FOP(19, 22):
6921
        check_cp1_64bitmode(ctx);
6922
        {
6923
            int l1 = gen_new_label();
6924
            TCGv t0 = tcg_temp_new();
6925
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6926
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6927

    
6928
            gen_load_gpr(t0, ft);
6929
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6930
            gen_load_fpr32(fp0, fs);
6931
            gen_load_fpr32h(fph0, fs);
6932
            gen_store_fpr32(fp0, fd);
6933
            gen_store_fpr32h(fph0, fd);
6934
            tcg_temp_free_i32(fp0);
6935
            tcg_temp_free_i32(fph0);
6936
            gen_set_label(l1);
6937
            tcg_temp_free(t0);
6938
        }
6939
        opn = "movn.ps";
6940
        break;
6941
    case FOP(24, 22):
6942
        check_cp1_64bitmode(ctx);
6943
        {
6944
            TCGv_i64 fp0 = tcg_temp_new_i64();
6945
            TCGv_i64 fp1 = tcg_temp_new_i64();
6946

    
6947
            gen_load_fpr64(ctx, fp0, ft);
6948
            gen_load_fpr64(ctx, fp1, fs);
6949
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6950
            tcg_temp_free_i64(fp1);
6951
            gen_store_fpr64(ctx, fp0, fd);
6952
            tcg_temp_free_i64(fp0);
6953
        }
6954
        opn = "addr.ps";
6955
        break;
6956
    case FOP(26, 22):
6957
        check_cp1_64bitmode(ctx);
6958
        {
6959
            TCGv_i64 fp0 = tcg_temp_new_i64();
6960
            TCGv_i64 fp1 = tcg_temp_new_i64();
6961

    
6962
            gen_load_fpr64(ctx, fp0, ft);
6963
            gen_load_fpr64(ctx, fp1, fs);
6964
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6965
            tcg_temp_free_i64(fp1);
6966
            gen_store_fpr64(ctx, fp0, fd);
6967
            tcg_temp_free_i64(fp0);
6968
        }
6969
        opn = "mulr.ps";
6970
        break;
6971
    case FOP(28, 22):
6972
        check_cp1_64bitmode(ctx);
6973
        {
6974
            TCGv_i64 fp0 = tcg_temp_new_i64();
6975
            TCGv_i64 fp1 = tcg_temp_new_i64();
6976

    
6977
            gen_load_fpr64(ctx, fp0, fs);
6978
            gen_load_fpr64(ctx, fp1, fd);
6979
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6980
            tcg_temp_free_i64(fp1);
6981
            gen_store_fpr64(ctx, fp0, fd);
6982
            tcg_temp_free_i64(fp0);
6983
        }
6984
        opn = "recip2.ps";
6985
        break;
6986
    case FOP(29, 22):
6987
        check_cp1_64bitmode(ctx);
6988
        {
6989
            TCGv_i64 fp0 = tcg_temp_new_i64();
6990

    
6991
            gen_load_fpr64(ctx, fp0, fs);
6992
            gen_helper_float_recip1_ps(fp0, fp0);
6993
            gen_store_fpr64(ctx, fp0, fd);
6994
            tcg_temp_free_i64(fp0);
6995
        }
6996
        opn = "recip1.ps";
6997
        break;
6998
    case FOP(30, 22):
6999
        check_cp1_64bitmode(ctx);
7000
        {
7001
            TCGv_i64 fp0 = tcg_temp_new_i64();
7002

    
7003
            gen_load_fpr64(ctx, fp0, fs);
7004
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7005
            gen_store_fpr64(ctx, fp0, fd);
7006
            tcg_temp_free_i64(fp0);
7007
        }
7008
        opn = "rsqrt1.ps";
7009
        break;
7010
    case FOP(31, 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
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7019
            tcg_temp_free_i64(fp1);
7020
            gen_store_fpr64(ctx, fp0, fd);
7021
            tcg_temp_free_i64(fp0);
7022
        }
7023
        opn = "rsqrt2.ps";
7024
        break;
7025
    case FOP(32, 22):
7026
        check_cp1_64bitmode(ctx);
7027
        {
7028
            TCGv_i32 fp0 = tcg_temp_new_i32();
7029

    
7030
            gen_load_fpr32h(fp0, fs);
7031
            gen_helper_float_cvts_pu(fp0, fp0);
7032
            gen_store_fpr32(fp0, fd);
7033
            tcg_temp_free_i32(fp0);
7034
        }
7035
        opn = "cvt.s.pu";
7036
        break;
7037
    case FOP(36, 22):
7038
        check_cp1_64bitmode(ctx);
7039
        {
7040
            TCGv_i64 fp0 = tcg_temp_new_i64();
7041

    
7042
            gen_load_fpr64(ctx, fp0, fs);
7043
            gen_helper_float_cvtpw_ps(fp0, fp0);
7044
            gen_store_fpr64(ctx, fp0, fd);
7045
            tcg_temp_free_i64(fp0);
7046
        }
7047
        opn = "cvt.pw.ps";
7048
        break;
7049
    case FOP(40, 22):
7050
        check_cp1_64bitmode(ctx);
7051
        {
7052
            TCGv_i32 fp0 = tcg_temp_new_i32();
7053

    
7054
            gen_load_fpr32(fp0, fs);
7055
            gen_helper_float_cvts_pl(fp0, fp0);
7056
            gen_store_fpr32(fp0, fd);
7057
            tcg_temp_free_i32(fp0);
7058
        }
7059
        opn = "cvt.s.pl";
7060
        break;
7061
    case FOP(44, 22):
7062
        check_cp1_64bitmode(ctx);
7063
        {
7064
            TCGv_i32 fp0 = tcg_temp_new_i32();
7065
            TCGv_i32 fp1 = tcg_temp_new_i32();
7066

    
7067
            gen_load_fpr32(fp0, fs);
7068
            gen_load_fpr32(fp1, ft);
7069
            gen_store_fpr32h(fp0, fd);
7070
            gen_store_fpr32(fp1, fd);
7071
            tcg_temp_free_i32(fp0);
7072
            tcg_temp_free_i32(fp1);
7073
        }
7074
        opn = "pll.ps";
7075
        break;
7076
    case FOP(45, 22):
7077
        check_cp1_64bitmode(ctx);
7078
        {
7079
            TCGv_i32 fp0 = tcg_temp_new_i32();
7080
            TCGv_i32 fp1 = tcg_temp_new_i32();
7081

    
7082
            gen_load_fpr32(fp0, fs);
7083
            gen_load_fpr32h(fp1, ft);
7084
            gen_store_fpr32(fp1, fd);
7085
            gen_store_fpr32h(fp0, fd);
7086
            tcg_temp_free_i32(fp0);
7087
            tcg_temp_free_i32(fp1);
7088
        }
7089
        opn = "plu.ps";
7090
        break;
7091
    case FOP(46, 22):
7092
        check_cp1_64bitmode(ctx);
7093
        {
7094
            TCGv_i32 fp0 = tcg_temp_new_i32();
7095
            TCGv_i32 fp1 = tcg_temp_new_i32();
7096

    
7097
            gen_load_fpr32h(fp0, fs);
7098
            gen_load_fpr32(fp1, ft);
7099
            gen_store_fpr32(fp1, fd);
7100
            gen_store_fpr32h(fp0, fd);
7101
            tcg_temp_free_i32(fp0);
7102
            tcg_temp_free_i32(fp1);
7103
        }
7104
        opn = "pul.ps";
7105
        break;
7106
    case FOP(47, 22):
7107
        check_cp1_64bitmode(ctx);
7108
        {
7109
            TCGv_i32 fp0 = tcg_temp_new_i32();
7110
            TCGv_i32 fp1 = tcg_temp_new_i32();
7111

    
7112
            gen_load_fpr32h(fp0, fs);
7113
            gen_load_fpr32h(fp1, ft);
7114
            gen_store_fpr32(fp1, fd);
7115
            gen_store_fpr32h(fp0, fd);
7116
            tcg_temp_free_i32(fp0);
7117
            tcg_temp_free_i32(fp1);
7118
        }
7119
        opn = "puu.ps";
7120
        break;
7121
    case FOP(48, 22):
7122
    case FOP(49, 22):
7123
    case FOP(50, 22):
7124
    case FOP(51, 22):
7125
    case FOP(52, 22):
7126
    case FOP(53, 22):
7127
    case FOP(54, 22):
7128
    case FOP(55, 22):
7129
    case FOP(56, 22):
7130
    case FOP(57, 22):
7131
    case FOP(58, 22):
7132
    case FOP(59, 22):
7133
    case FOP(60, 22):
7134
    case FOP(61, 22):
7135
    case FOP(62, 22):
7136
    case FOP(63, 22):
7137
        check_cp1_64bitmode(ctx);
7138
        {
7139
            TCGv_i64 fp0 = tcg_temp_new_i64();
7140
            TCGv_i64 fp1 = tcg_temp_new_i64();
7141

    
7142
            gen_load_fpr64(ctx, fp0, fs);
7143
            gen_load_fpr64(ctx, fp1, ft);
7144
            if (ctx->opcode & (1 << 6)) {
7145
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7146
                opn = condnames_abs[func-48];
7147
            } else {
7148
                gen_cmp_ps(func-48, fp0, fp1, cc);
7149
                opn = condnames[func-48];
7150
            }
7151
            tcg_temp_free_i64(fp0);
7152
            tcg_temp_free_i64(fp1);
7153
        }
7154
        break;
7155
    default:
7156
        MIPS_INVAL(opn);
7157
        generate_exception (ctx, EXCP_RI);
7158
        return;
7159
    }
7160
    switch (optype) {
7161
    case BINOP:
7162
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7163
        break;
7164
    case CMPOP:
7165
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7166
        break;
7167
    default:
7168
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7169
        break;
7170
    }
7171
}
7172

    
7173
/* Coprocessor 3 (FPU) */
7174
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7175
                           int fd, int fs, int base, int index)
7176
{
7177
    const char *opn = "extended float load/store";
7178
    int store = 0;
7179
    TCGv t0 = tcg_temp_local_new();
7180
    TCGv t1 = tcg_temp_local_new();
7181

    
7182
    if (base == 0) {
7183
        gen_load_gpr(t0, index);
7184
    } else if (index == 0) {
7185
        gen_load_gpr(t0, base);
7186
    } else {
7187
        gen_load_gpr(t0, index);
7188
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7189
    }
7190
    /* Don't do NOP if destination is zero: we must perform the actual
7191
       memory access. */
7192
    switch (opc) {
7193
    case OPC_LWXC1:
7194
        check_cop1x(ctx);
7195
        {
7196
            TCGv_i32 fp0 = tcg_temp_new_i32();
7197

    
7198
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7199
            tcg_gen_trunc_tl_i32(fp0, t1);
7200
            gen_store_fpr32(fp0, fd);
7201
            tcg_temp_free_i32(fp0);
7202
        }
7203
        opn = "lwxc1";
7204
        break;
7205
    case OPC_LDXC1:
7206
        check_cop1x(ctx);
7207
        check_cp1_registers(ctx, fd);
7208
        {
7209
            TCGv_i64 fp0 = tcg_temp_new_i64();
7210

    
7211
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7212
            gen_store_fpr64(ctx, fp0, fd);
7213
            tcg_temp_free_i64(fp0);
7214
        }
7215
        opn = "ldxc1";
7216
        break;
7217
    case OPC_LUXC1:
7218
        check_cp1_64bitmode(ctx);
7219
        tcg_gen_andi_tl(t0, t0, ~0x7);
7220
        {
7221
            TCGv_i64 fp0 = tcg_temp_new_i64();
7222

    
7223
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7224
            gen_store_fpr64(ctx, fp0, fd);
7225
            tcg_temp_free_i64(fp0);
7226
        }
7227
        opn = "luxc1";
7228
        break;
7229
    case OPC_SWXC1:
7230
        check_cop1x(ctx);
7231
        {
7232
            TCGv_i32 fp0 = tcg_temp_new_i32();
7233

    
7234
            gen_load_fpr32(fp0, fs);
7235
            tcg_gen_extu_i32_tl(t1, fp0);
7236
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7237
            tcg_temp_free_i32(fp0);
7238
        }
7239
        opn = "swxc1";
7240
        store = 1;
7241
        break;
7242
    case OPC_SDXC1:
7243
        check_cop1x(ctx);
7244
        check_cp1_registers(ctx, fs);
7245
        {
7246
            TCGv_i64 fp0 = tcg_temp_new_i64();
7247

    
7248
            gen_load_fpr64(ctx, fp0, fs);
7249
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7250
            tcg_temp_free_i64(fp0);
7251
        }
7252
        opn = "sdxc1";
7253
        store = 1;
7254
        break;
7255
    case OPC_SUXC1:
7256
        check_cp1_64bitmode(ctx);
7257
        tcg_gen_andi_tl(t0, t0, ~0x7);
7258
        {
7259
            TCGv_i64 fp0 = tcg_temp_new_i64();
7260

    
7261
            gen_load_fpr64(ctx, fp0, fs);
7262
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7263
            tcg_temp_free_i64(fp0);
7264
        }
7265
        opn = "suxc1";
7266
        store = 1;
7267
        break;
7268
    default:
7269
        MIPS_INVAL(opn);
7270
        generate_exception(ctx, EXCP_RI);
7271
        tcg_temp_free(t0);
7272
        tcg_temp_free(t1);
7273
        return;
7274
    }
7275
    tcg_temp_free(t0);
7276
    tcg_temp_free(t1);
7277
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7278
               regnames[index], regnames[base]);
7279
}
7280

    
7281
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7282
                            int fd, int fr, int fs, int ft)
7283
{
7284
    const char *opn = "flt3_arith";
7285

    
7286
    switch (opc) {
7287
    case OPC_ALNV_PS:
7288
        check_cp1_64bitmode(ctx);
7289
        {
7290
            TCGv t0 = tcg_temp_local_new();
7291
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7292
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7293
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7294
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7295
            int l1 = gen_new_label();
7296
            int l2 = gen_new_label();
7297

    
7298
            gen_load_gpr(t0, fr);
7299
            tcg_gen_andi_tl(t0, t0, 0x7);
7300
            gen_load_fpr32(fp0, fs);
7301
            gen_load_fpr32h(fph0, fs);
7302
            gen_load_fpr32(fp1, ft);
7303
            gen_load_fpr32h(fph1, ft);
7304

    
7305
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7306
            gen_store_fpr32(fp0, fd);
7307
            gen_store_fpr32h(fph0, fd);
7308
            tcg_gen_br(l2);
7309
            gen_set_label(l1);
7310
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7311
            tcg_temp_free(t0);
7312
#ifdef TARGET_WORDS_BIGENDIAN
7313
            gen_store_fpr32(fph1, fd);
7314
            gen_store_fpr32h(fp0, fd);
7315
#else
7316
            gen_store_fpr32(fph0, fd);
7317
            gen_store_fpr32h(fp1, fd);
7318
#endif
7319
            gen_set_label(l2);
7320
            tcg_temp_free_i32(fp0);
7321
            tcg_temp_free_i32(fph0);
7322
            tcg_temp_free_i32(fp1);
7323
            tcg_temp_free_i32(fph1);
7324
        }
7325
        opn = "alnv.ps";
7326
        break;
7327
    case OPC_MADD_S:
7328
        check_cop1x(ctx);
7329
        {
7330
            TCGv_i32 fp0 = tcg_temp_new_i32();
7331
            TCGv_i32 fp1 = tcg_temp_new_i32();
7332
            TCGv_i32 fp2 = tcg_temp_new_i32();
7333

    
7334
            gen_load_fpr32(fp0, fs);
7335
            gen_load_fpr32(fp1, ft);
7336
            gen_load_fpr32(fp2, fr);
7337
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7338
            tcg_temp_free_i32(fp0);
7339
            tcg_temp_free_i32(fp1);
7340
            gen_store_fpr32(fp2, fd);
7341
            tcg_temp_free_i32(fp2);
7342
        }
7343
        opn = "madd.s";
7344
        break;
7345
    case OPC_MADD_D:
7346
        check_cop1x(ctx);
7347
        check_cp1_registers(ctx, fd | fs | ft | fr);
7348
        {
7349
            TCGv_i64 fp0 = tcg_temp_new_i64();
7350
            TCGv_i64 fp1 = tcg_temp_new_i64();
7351
            TCGv_i64 fp2 = tcg_temp_new_i64();
7352

    
7353
            gen_load_fpr64(ctx, fp0, fs);
7354
            gen_load_fpr64(ctx, fp1, ft);
7355
            gen_load_fpr64(ctx, fp2, fr);
7356
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7357
            tcg_temp_free_i64(fp0);
7358
            tcg_temp_free_i64(fp1);
7359
            gen_store_fpr64(ctx, fp2, fd);
7360
            tcg_temp_free_i64(fp2);
7361
        }
7362
        opn = "madd.d";
7363
        break;
7364
    case OPC_MADD_PS:
7365
        check_cp1_64bitmode(ctx);
7366
        {
7367
            TCGv_i64 fp0 = tcg_temp_new_i64();
7368
            TCGv_i64 fp1 = tcg_temp_new_i64();
7369
            TCGv_i64 fp2 = tcg_temp_new_i64();
7370

    
7371
            gen_load_fpr64(ctx, fp0, fs);
7372
            gen_load_fpr64(ctx, fp1, ft);
7373
            gen_load_fpr64(ctx, fp2, fr);
7374
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7375
            tcg_temp_free_i64(fp0);
7376
            tcg_temp_free_i64(fp1);
7377
            gen_store_fpr64(ctx, fp2, fd);
7378
            tcg_temp_free_i64(fp2);
7379
        }
7380
        opn = "madd.ps";
7381
        break;
7382
    case OPC_MSUB_S:
7383
        check_cop1x(ctx);
7384
        {
7385
            TCGv_i32 fp0 = tcg_temp_new_i32();
7386
            TCGv_i32 fp1 = tcg_temp_new_i32();
7387
            TCGv_i32 fp2 = tcg_temp_new_i32();
7388

    
7389
            gen_load_fpr32(fp0, fs);
7390
            gen_load_fpr32(fp1, ft);
7391
            gen_load_fpr32(fp2, fr);
7392
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7393
            tcg_temp_free_i32(fp0);
7394
            tcg_temp_free_i32(fp1);
7395
            gen_store_fpr32(fp2, fd);
7396
            tcg_temp_free_i32(fp2);
7397
        }
7398
        opn = "msub.s";
7399
        break;
7400
    case OPC_MSUB_D:
7401
        check_cop1x(ctx);
7402
        check_cp1_registers(ctx, fd | fs | ft | fr);
7403
        {
7404
            TCGv_i64 fp0 = tcg_temp_new_i64();
7405
            TCGv_i64 fp1 = tcg_temp_new_i64();
7406
            TCGv_i64 fp2 = tcg_temp_new_i64();
7407

    
7408
            gen_load_fpr64(ctx, fp0, fs);
7409
            gen_load_fpr64(ctx, fp1, ft);
7410
            gen_load_fpr64(ctx, fp2, fr);
7411
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7412
            tcg_temp_free_i64(fp0);
7413
            tcg_temp_free_i64(fp1);
7414
            gen_store_fpr64(ctx, fp2, fd);
7415
            tcg_temp_free_i64(fp2);
7416
        }
7417
        opn = "msub.d";
7418
        break;
7419
    case OPC_MSUB_PS:
7420
        check_cp1_64bitmode(ctx);
7421
        {
7422
            TCGv_i64 fp0 = tcg_temp_new_i64();
7423
            TCGv_i64 fp1 = tcg_temp_new_i64();
7424
            TCGv_i64 fp2 = tcg_temp_new_i64();
7425

    
7426
            gen_load_fpr64(ctx, fp0, fs);
7427
            gen_load_fpr64(ctx, fp1, ft);
7428
            gen_load_fpr64(ctx, fp2, fr);
7429
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7430
            tcg_temp_free_i64(fp0);
7431
            tcg_temp_free_i64(fp1);
7432
            gen_store_fpr64(ctx, fp2, fd);
7433
            tcg_temp_free_i64(fp2);
7434
        }
7435
        opn = "msub.ps";
7436
        break;
7437
    case OPC_NMADD_S:
7438
        check_cop1x(ctx);
7439
        {
7440
            TCGv_i32 fp0 = tcg_temp_new_i32();
7441
            TCGv_i32 fp1 = tcg_temp_new_i32();
7442
            TCGv_i32 fp2 = tcg_temp_new_i32();
7443

    
7444
            gen_load_fpr32(fp0, fs);
7445
            gen_load_fpr32(fp1, ft);
7446
            gen_load_fpr32(fp2, fr);
7447
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7448
            tcg_temp_free_i32(fp0);
7449
            tcg_temp_free_i32(fp1);
7450
            gen_store_fpr32(fp2, fd);
7451
            tcg_temp_free_i32(fp2);
7452
        }
7453
        opn = "nmadd.s";
7454
        break;
7455
    case OPC_NMADD_D:
7456
        check_cop1x(ctx);
7457
        check_cp1_registers(ctx, fd | fs | ft | fr);
7458
        {
7459
            TCGv_i64 fp0 = tcg_temp_new_i64();
7460
            TCGv_i64 fp1 = tcg_temp_new_i64();
7461
            TCGv_i64 fp2 = tcg_temp_new_i64();
7462

    
7463
            gen_load_fpr64(ctx, fp0, fs);
7464
            gen_load_fpr64(ctx, fp1, ft);
7465
            gen_load_fpr64(ctx, fp2, fr);
7466
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7467
            tcg_temp_free_i64(fp0);
7468
            tcg_temp_free_i64(fp1);
7469
            gen_store_fpr64(ctx, fp2, fd);
7470
            tcg_temp_free_i64(fp2);
7471
        }
7472
        opn = "nmadd.d";
7473
        break;
7474
    case OPC_NMADD_PS:
7475
        check_cp1_64bitmode(ctx);
7476
        {
7477
            TCGv_i64 fp0 = tcg_temp_new_i64();
7478
            TCGv_i64 fp1 = tcg_temp_new_i64();
7479
            TCGv_i64 fp2 = tcg_temp_new_i64();
7480

    
7481
            gen_load_fpr64(ctx, fp0, fs);
7482
            gen_load_fpr64(ctx, fp1, ft);
7483
            gen_load_fpr64(ctx, fp2, fr);
7484
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7485
            tcg_temp_free_i64(fp0);
7486
            tcg_temp_free_i64(fp1);
7487
            gen_store_fpr64(ctx, fp2, fd);
7488
            tcg_temp_free_i64(fp2);
7489
        }
7490
        opn = "nmadd.ps";
7491
        break;
7492
    case OPC_NMSUB_S:
7493
        check_cop1x(ctx);
7494
        {
7495
            TCGv_i32 fp0 = tcg_temp_new_i32();
7496
            TCGv_i32 fp1 = tcg_temp_new_i32();
7497
            TCGv_i32 fp2 = tcg_temp_new_i32();
7498

    
7499
            gen_load_fpr32(fp0, fs);
7500
            gen_load_fpr32(fp1, ft);
7501
            gen_load_fpr32(fp2, fr);
7502
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7503
            tcg_temp_free_i32(fp0);
7504
            tcg_temp_free_i32(fp1);
7505
            gen_store_fpr32(fp2, fd);
7506
            tcg_temp_free_i32(fp2);
7507
        }
7508
        opn = "nmsub.s";
7509
        break;
7510
    case OPC_NMSUB_D:
7511
        check_cop1x(ctx);
7512
        check_cp1_registers(ctx, fd | fs | ft | fr);
7513
        {
7514
            TCGv_i64 fp0 = tcg_temp_new_i64();
7515
            TCGv_i64 fp1 = tcg_temp_new_i64();
7516
            TCGv_i64 fp2 = tcg_temp_new_i64();
7517

    
7518
            gen_load_fpr64(ctx, fp0, fs);
7519
            gen_load_fpr64(ctx, fp1, ft);
7520
            gen_load_fpr64(ctx, fp2, fr);
7521
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7522
            tcg_temp_free_i64(fp0);
7523
            tcg_temp_free_i64(fp1);
7524
            gen_store_fpr64(ctx, fp2, fd);
7525
            tcg_temp_free_i64(fp2);
7526
        }
7527
        opn = "nmsub.d";
7528
        break;
7529
    case OPC_NMSUB_PS:
7530
        check_cp1_64bitmode(ctx);
7531
        {
7532
            TCGv_i64 fp0 = tcg_temp_new_i64();
7533
            TCGv_i64 fp1 = tcg_temp_new_i64();
7534
            TCGv_i64 fp2 = tcg_temp_new_i64();
7535

    
7536
            gen_load_fpr64(ctx, fp0, fs);
7537
            gen_load_fpr64(ctx, fp1, ft);
7538
            gen_load_fpr64(ctx, fp2, fr);
7539
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7540
            tcg_temp_free_i64(fp0);
7541
            tcg_temp_free_i64(fp1);
7542
            gen_store_fpr64(ctx, fp2, fd);
7543
            tcg_temp_free_i64(fp2);
7544
        }
7545
        opn = "nmsub.ps";
7546
        break;
7547
    default:
7548
        MIPS_INVAL(opn);
7549
        generate_exception (ctx, EXCP_RI);
7550
        return;
7551
    }
7552
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7553
               fregnames[fs], fregnames[ft]);
7554
}
7555

    
7556
/* ISA extensions (ASEs) */
7557
/* MIPS16 extension to MIPS32 */
7558
/* SmartMIPS extension to MIPS32 */
7559

    
7560
#if defined(TARGET_MIPS64)
7561

    
7562
/* MDMX extension to MIPS64 */
7563

    
7564
#endif
7565

    
7566
static void decode_opc (CPUState *env, DisasContext *ctx)
7567
{
7568
    int32_t offset;
7569
    int rs, rt, rd, sa;
7570
    uint32_t op, op1, op2;
7571
    int16_t imm;
7572

    
7573
    /* make sure instructions are on a word boundary */
7574
    if (ctx->pc & 0x3) {
7575
        env->CP0_BadVAddr = ctx->pc;
7576
        generate_exception(ctx, EXCP_AdEL);
7577
        return;
7578
    }
7579

    
7580
    /* Handle blikely not taken case */
7581
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7582
        int l1 = gen_new_label();
7583

    
7584
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7585
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7586
        {
7587
            TCGv_i32 r_tmp = tcg_temp_new_i32();
7588

    
7589
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7590
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7591
            tcg_temp_free_i32(r_tmp);
7592
        }
7593
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7594
        gen_set_label(l1);
7595
    }
7596
    op = MASK_OP_MAJOR(ctx->opcode);
7597
    rs = (ctx->opcode >> 21) & 0x1f;
7598
    rt = (ctx->opcode >> 16) & 0x1f;
7599
    rd = (ctx->opcode >> 11) & 0x1f;
7600
    sa = (ctx->opcode >> 6) & 0x1f;
7601
    imm = (int16_t)ctx->opcode;
7602
    switch (op) {
7603
    case OPC_SPECIAL:
7604
        op1 = MASK_SPECIAL(ctx->opcode);
7605
        switch (op1) {
7606
        case OPC_SLL:          /* Arithmetic with immediate */
7607
        case OPC_SRL ... OPC_SRA:
7608
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7609
            break;
7610
        case OPC_MOVZ ... OPC_MOVN:
7611
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7612
        case OPC_SLLV:         /* Arithmetic */
7613
        case OPC_SRLV ... OPC_SRAV:
7614
        case OPC_ADD ... OPC_NOR:
7615
        case OPC_SLT ... OPC_SLTU:
7616
            gen_arith(env, ctx, op1, rd, rs, rt);
7617
            break;
7618
        case OPC_MULT ... OPC_DIVU:
7619
            if (sa) {
7620
                check_insn(env, ctx, INSN_VR54XX);
7621
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7622
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7623
            } else
7624
                gen_muldiv(ctx, op1, rs, rt);
7625
            break;
7626
        case OPC_JR ... OPC_JALR:
7627
            gen_compute_branch(ctx, op1, rs, rd, sa);
7628
            return;
7629
        case OPC_TGE ... OPC_TEQ: /* Traps */
7630
        case OPC_TNE:
7631
            gen_trap(ctx, op1, rs, rt, -1);
7632
            break;
7633
        case OPC_MFHI:          /* Move from HI/LO */
7634
        case OPC_MFLO:
7635
            gen_HILO(ctx, op1, rd);
7636
            break;
7637
        case OPC_MTHI:
7638
        case OPC_MTLO:          /* Move to HI/LO */
7639
            gen_HILO(ctx, op1, rs);
7640
            break;
7641
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7642
#ifdef MIPS_STRICT_STANDARD
7643
            MIPS_INVAL("PMON / selsl");
7644
            generate_exception(ctx, EXCP_RI);
7645
#else
7646
            gen_helper_0i(pmon, sa);
7647
#endif
7648
            break;
7649
        case OPC_SYSCALL:
7650
            generate_exception(ctx, EXCP_SYSCALL);
7651
            break;
7652
        case OPC_BREAK:
7653
            generate_exception(ctx, EXCP_BREAK);
7654
            break;
7655
        case OPC_SPIM:
7656
#ifdef MIPS_STRICT_STANDARD
7657
            MIPS_INVAL("SPIM");
7658
            generate_exception(ctx, EXCP_RI);
7659
#else
7660
           /* Implemented as RI exception for now. */
7661
            MIPS_INVAL("spim (unofficial)");
7662
            generate_exception(ctx, EXCP_RI);
7663
#endif
7664
            break;
7665
        case OPC_SYNC:
7666
            /* Treat as NOP. */
7667
            break;
7668

    
7669
        case OPC_MOVCI:
7670
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7671
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7672
                save_cpu_state(ctx, 1);
7673
                check_cp1_enabled(ctx);
7674
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7675
                          (ctx->opcode >> 16) & 1);
7676
            } else {
7677
                generate_exception_err(ctx, EXCP_CpU, 1);
7678
            }
7679
            break;
7680

    
7681
#if defined(TARGET_MIPS64)
7682
       /* MIPS64 specific opcodes */
7683
        case OPC_DSLL:
7684
        case OPC_DSRL ... OPC_DSRA:
7685
        case OPC_DSLL32:
7686
        case OPC_DSRL32 ... OPC_DSRA32:
7687
            check_insn(env, ctx, ISA_MIPS3);
7688
            check_mips_64(ctx);
7689
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7690
            break;
7691
        case OPC_DSLLV:
7692
        case OPC_DSRLV ... OPC_DSRAV:
7693
        case OPC_DADD ... OPC_DSUBU:
7694
            check_insn(env, ctx, ISA_MIPS3);
7695
            check_mips_64(ctx);
7696
            gen_arith(env, ctx, op1, rd, rs, rt);
7697
            break;
7698
        case OPC_DMULT ... OPC_DDIVU:
7699
            check_insn(env, ctx, ISA_MIPS3);
7700
            check_mips_64(ctx);
7701
            gen_muldiv(ctx, op1, rs, rt);
7702
            break;
7703
#endif
7704
        default:            /* Invalid */
7705
            MIPS_INVAL("special");
7706
            generate_exception(ctx, EXCP_RI);
7707
            break;
7708
        }
7709
        break;
7710
    case OPC_SPECIAL2:
7711
        op1 = MASK_SPECIAL2(ctx->opcode);
7712
        switch (op1) {
7713
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7714
        case OPC_MSUB ... OPC_MSUBU:
7715
            check_insn(env, ctx, ISA_MIPS32);
7716
            gen_muldiv(ctx, op1, rs, rt);
7717
            break;
7718
        case OPC_MUL:
7719
            gen_arith(env, ctx, op1, rd, rs, rt);
7720
            break;
7721
        case OPC_CLZ ... OPC_CLO:
7722
            check_insn(env, ctx, ISA_MIPS32);
7723
            gen_cl(ctx, op1, rd, rs);
7724
            break;
7725
        case OPC_SDBBP:
7726
            /* XXX: not clear which exception should be raised
7727
             *      when in debug mode...
7728
             */
7729
            check_insn(env, ctx, ISA_MIPS32);
7730
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7731
                generate_exception(ctx, EXCP_DBp);
7732
            } else {
7733
                generate_exception(ctx, EXCP_DBp);
7734
            }
7735
            /* Treat as NOP. */
7736
            break;
7737
#if defined(TARGET_MIPS64)
7738
        case OPC_DCLZ ... OPC_DCLO:
7739
            check_insn(env, ctx, ISA_MIPS64);
7740
            check_mips_64(ctx);
7741
            gen_cl(ctx, op1, rd, rs);
7742
            break;
7743
#endif
7744
        default:            /* Invalid */
7745
            MIPS_INVAL("special2");
7746
            generate_exception(ctx, EXCP_RI);
7747
            break;
7748
        }
7749
        break;
7750
    case OPC_SPECIAL3:
7751
        op1 = MASK_SPECIAL3(ctx->opcode);
7752
        switch (op1) {
7753
        case OPC_EXT:
7754
        case OPC_INS:
7755
            check_insn(env, ctx, ISA_MIPS32R2);
7756
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7757
            break;
7758
        case OPC_BSHFL:
7759
            check_insn(env, ctx, ISA_MIPS32R2);
7760
            op2 = MASK_BSHFL(ctx->opcode);
7761
            gen_bshfl(ctx, op2, rt, rd);
7762
            break;
7763
        case OPC_RDHWR:
7764
            check_insn(env, ctx, ISA_MIPS32R2);
7765
            {
7766
                TCGv t0 = tcg_temp_local_new();
7767

    
7768
                switch (rd) {
7769
                case 0:
7770
                    save_cpu_state(ctx, 1);
7771
                    gen_helper_rdhwr_cpunum(t0);
7772
                    break;
7773
                case 1:
7774
                    save_cpu_state(ctx, 1);
7775
                    gen_helper_rdhwr_synci_step(t0);
7776
                    break;
7777
                case 2:
7778
                    save_cpu_state(ctx, 1);
7779
                    gen_helper_rdhwr_cc(t0);
7780
                    break;
7781
                case 3:
7782
                    save_cpu_state(ctx, 1);
7783
                    gen_helper_rdhwr_ccres(t0);
7784
                    break;
7785
                case 29:
7786
#if defined(CONFIG_USER_ONLY)
7787
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7788
                    break;
7789
#else
7790
                    /* XXX: Some CPUs implement this in hardware.
7791
                       Not supported yet. */
7792
#endif
7793
                default:            /* Invalid */
7794
                    MIPS_INVAL("rdhwr");
7795
                    generate_exception(ctx, EXCP_RI);
7796
                    break;
7797
                }
7798
                gen_store_gpr(t0, rt);
7799
                tcg_temp_free(t0);
7800
            }
7801
            break;
7802
        case OPC_FORK:
7803
            check_insn(env, ctx, ASE_MT);
7804
            {
7805
                TCGv t0 = tcg_temp_local_new();
7806
                TCGv t1 = tcg_temp_local_new();
7807

    
7808
                gen_load_gpr(t0, rt);
7809
                gen_load_gpr(t1, rs);
7810
                gen_helper_fork(t0, t1);
7811
                tcg_temp_free(t0);
7812
                tcg_temp_free(t1);
7813
            }
7814
            break;
7815
        case OPC_YIELD:
7816
            check_insn(env, ctx, ASE_MT);
7817
            {
7818
                TCGv t0 = tcg_temp_local_new();
7819

    
7820
                gen_load_gpr(t0, rs);
7821
                gen_helper_yield(t0, t0);
7822
                gen_store_gpr(t0, rd);
7823
                tcg_temp_free(t0);
7824
            }
7825
            break;
7826
#if defined(TARGET_MIPS64)
7827
        case OPC_DEXTM ... OPC_DEXT:
7828
        case OPC_DINSM ... OPC_DINS:
7829
            check_insn(env, ctx, ISA_MIPS64R2);
7830
            check_mips_64(ctx);
7831
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7832
            break;
7833
        case OPC_DBSHFL:
7834
            check_insn(env, ctx, ISA_MIPS64R2);
7835
            check_mips_64(ctx);
7836
            op2 = MASK_DBSHFL(ctx->opcode);
7837
            gen_bshfl(ctx, op2, rt, rd);
7838
            break;
7839
#endif
7840
        default:            /* Invalid */
7841
            MIPS_INVAL("special3");
7842
            generate_exception(ctx, EXCP_RI);
7843
            break;
7844
        }
7845
        break;
7846
    case OPC_REGIMM:
7847
        op1 = MASK_REGIMM(ctx->opcode);
7848
        switch (op1) {
7849
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7850
        case OPC_BLTZAL ... OPC_BGEZALL:
7851
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7852
            return;
7853
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7854
        case OPC_TNEI:
7855
            gen_trap(ctx, op1, rs, -1, imm);
7856
            break;
7857
        case OPC_SYNCI:
7858
            check_insn(env, ctx, ISA_MIPS32R2);
7859
            /* Treat as NOP. */
7860
            break;
7861
        default:            /* Invalid */
7862
            MIPS_INVAL("regimm");
7863
            generate_exception(ctx, EXCP_RI);
7864
            break;
7865
        }
7866
        break;
7867
    case OPC_CP0:
7868
        check_cp0_enabled(ctx);
7869
        op1 = MASK_CP0(ctx->opcode);
7870
        switch (op1) {
7871
        case OPC_MFC0:
7872
        case OPC_MTC0:
7873
        case OPC_MFTR:
7874
        case OPC_MTTR:
7875
#if defined(TARGET_MIPS64)
7876
        case OPC_DMFC0:
7877
        case OPC_DMTC0:
7878
#endif
7879
#ifndef CONFIG_USER_ONLY
7880
            gen_cp0(env, ctx, op1, rt, rd);
7881
#endif /* !CONFIG_USER_ONLY */
7882
            break;
7883
        case OPC_C0_FIRST ... OPC_C0_LAST:
7884
#ifndef CONFIG_USER_ONLY
7885
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7886
#endif /* !CONFIG_USER_ONLY */
7887
            break;
7888
        case OPC_MFMC0:
7889
#ifndef CONFIG_USER_ONLY
7890
            {
7891
                TCGv t0 = tcg_temp_local_new();
7892

    
7893
                op2 = MASK_MFMC0(ctx->opcode);
7894
                switch (op2) {
7895
                case OPC_DMT:
7896
                    check_insn(env, ctx, ASE_MT);
7897
                    gen_helper_dmt(t0, t0);
7898
                    break;
7899
                case OPC_EMT:
7900
                    check_insn(env, ctx, ASE_MT);
7901
                    gen_helper_emt(t0, t0);
7902
                    break;
7903
                case OPC_DVPE:
7904
                    check_insn(env, ctx, ASE_MT);
7905
                    gen_helper_dvpe(t0, t0);
7906
                    break;
7907
                case OPC_EVPE:
7908
                    check_insn(env, ctx, ASE_MT);
7909
                    gen_helper_evpe(t0, t0);
7910
                    break;
7911
                case OPC_DI:
7912
                    check_insn(env, ctx, ISA_MIPS32R2);
7913
                    save_cpu_state(ctx, 1);
7914
                    gen_helper_di(t0);
7915
                    /* Stop translation as we may have switched the execution mode */
7916
                    ctx->bstate = BS_STOP;
7917
                    break;
7918
                case OPC_EI:
7919
                    check_insn(env, ctx, ISA_MIPS32R2);
7920
                    save_cpu_state(ctx, 1);
7921
                    gen_helper_ei(t0);
7922
                    /* Stop translation as we may have switched the execution mode */
7923
                    ctx->bstate = BS_STOP;
7924
                    break;
7925
                default:            /* Invalid */
7926
                    MIPS_INVAL("mfmc0");
7927
                    generate_exception(ctx, EXCP_RI);
7928
                    break;
7929
                }
7930
                gen_store_gpr(t0, rt);
7931
                tcg_temp_free(t0);
7932
            }
7933
#endif /* !CONFIG_USER_ONLY */
7934
            break;
7935
        case OPC_RDPGPR:
7936
            check_insn(env, ctx, ISA_MIPS32R2);
7937
            gen_load_srsgpr(rt, rd);
7938
            break;
7939
        case OPC_WRPGPR:
7940
            check_insn(env, ctx, ISA_MIPS32R2);
7941
            gen_store_srsgpr(rt, rd);
7942
            break;
7943
        default:
7944
            MIPS_INVAL("cp0");
7945
            generate_exception(ctx, EXCP_RI);
7946
            break;
7947
        }
7948
        break;
7949
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7950
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7951
         break;
7952
    case OPC_J ... OPC_JAL: /* Jump */
7953
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7954
         gen_compute_branch(ctx, op, rs, rt, offset);
7955
         return;
7956
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7957
    case OPC_BEQL ... OPC_BGTZL:
7958
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7959
         return;
7960
    case OPC_LB ... OPC_LWR: /* Load and stores */
7961
    case OPC_SB ... OPC_SW:
7962
    case OPC_SWR:
7963
    case OPC_LL:
7964
    case OPC_SC:
7965
         gen_ldst(ctx, op, rt, rs, imm);
7966
         break;
7967
    case OPC_CACHE:
7968
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7969
        /* Treat as NOP. */
7970
        break;
7971
    case OPC_PREF:
7972
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7973
        /* Treat as NOP. */
7974
        break;
7975

    
7976
    /* Floating point (COP1). */
7977
    case OPC_LWC1:
7978
    case OPC_LDC1:
7979
    case OPC_SWC1:
7980
    case OPC_SDC1:
7981
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7982
            save_cpu_state(ctx, 1);
7983
            check_cp1_enabled(ctx);
7984
            gen_flt_ldst(ctx, op, rt, rs, imm);
7985
        } else {
7986
            generate_exception_err(ctx, EXCP_CpU, 1);
7987
        }
7988
        break;
7989

    
7990
    case OPC_CP1:
7991
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7992
            save_cpu_state(ctx, 1);
7993
            check_cp1_enabled(ctx);
7994
            op1 = MASK_CP1(ctx->opcode);
7995
            switch (op1) {
7996
            case OPC_MFHC1:
7997
            case OPC_MTHC1:
7998
                check_insn(env, ctx, ISA_MIPS32R2);
7999
            case OPC_MFC1:
8000
            case OPC_CFC1:
8001
            case OPC_MTC1:
8002
            case OPC_CTC1:
8003
                gen_cp1(ctx, op1, rt, rd);
8004
                break;
8005
#if defined(TARGET_MIPS64)
8006
            case OPC_DMFC1:
8007
            case OPC_DMTC1:
8008
                check_insn(env, ctx, ISA_MIPS3);
8009
                gen_cp1(ctx, op1, rt, rd);
8010
                break;
8011
#endif
8012
            case OPC_BC1ANY2:
8013
            case OPC_BC1ANY4:
8014
                check_cop1x(ctx);
8015
                check_insn(env, ctx, ASE_MIPS3D);
8016
                /* fall through */
8017
            case OPC_BC1:
8018
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8019
                                    (rt >> 2) & 0x7, imm << 2);
8020
                return;
8021
            case OPC_S_FMT:
8022
            case OPC_D_FMT:
8023
            case OPC_W_FMT:
8024
            case OPC_L_FMT:
8025
            case OPC_PS_FMT:
8026
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8027
                           (imm >> 8) & 0x7);
8028
                break;
8029
            default:
8030
                MIPS_INVAL("cp1");
8031
                generate_exception (ctx, EXCP_RI);
8032
                break;
8033
            }
8034
        } else {
8035
            generate_exception_err(ctx, EXCP_CpU, 1);
8036
        }
8037
        break;
8038

    
8039
    /* COP2.  */
8040
    case OPC_LWC2:
8041
    case OPC_LDC2:
8042
    case OPC_SWC2:
8043
    case OPC_SDC2:
8044
    case OPC_CP2:
8045
        /* COP2: Not implemented. */
8046
        generate_exception_err(ctx, EXCP_CpU, 2);
8047
        break;
8048

    
8049
    case OPC_CP3:
8050
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8051
            save_cpu_state(ctx, 1);
8052
            check_cp1_enabled(ctx);
8053
            op1 = MASK_CP3(ctx->opcode);
8054
            switch (op1) {
8055
            case OPC_LWXC1:
8056
            case OPC_LDXC1:
8057
            case OPC_LUXC1:
8058
            case OPC_SWXC1:
8059
            case OPC_SDXC1:
8060
            case OPC_SUXC1:
8061
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8062
                break;
8063
            case OPC_PREFX:
8064
                /* Treat as NOP. */
8065
                break;
8066
            case OPC_ALNV_PS:
8067
            case OPC_MADD_S:
8068
            case OPC_MADD_D:
8069
            case OPC_MADD_PS:
8070
            case OPC_MSUB_S:
8071
            case OPC_MSUB_D:
8072
            case OPC_MSUB_PS:
8073
            case OPC_NMADD_S:
8074
            case OPC_NMADD_D:
8075
            case OPC_NMADD_PS:
8076
            case OPC_NMSUB_S:
8077
            case OPC_NMSUB_D:
8078
            case OPC_NMSUB_PS:
8079
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8080
                break;
8081
            default:
8082
                MIPS_INVAL("cp3");
8083
                generate_exception (ctx, EXCP_RI);
8084
                break;
8085
            }
8086
        } else {
8087
            generate_exception_err(ctx, EXCP_CpU, 1);
8088
        }
8089
        break;
8090

    
8091
#if defined(TARGET_MIPS64)
8092
    /* MIPS64 opcodes */
8093
    case OPC_LWU:
8094
    case OPC_LDL ... OPC_LDR:
8095
    case OPC_SDL ... OPC_SDR:
8096
    case OPC_LLD:
8097
    case OPC_LD:
8098
    case OPC_SCD:
8099
    case OPC_SD:
8100
        check_insn(env, ctx, ISA_MIPS3);
8101
        check_mips_64(ctx);
8102
        gen_ldst(ctx, op, rt, rs, imm);
8103
        break;
8104
    case OPC_DADDI ... OPC_DADDIU:
8105
        check_insn(env, ctx, ISA_MIPS3);
8106
        check_mips_64(ctx);
8107
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8108
        break;
8109
#endif
8110
    case OPC_JALX:
8111
        check_insn(env, ctx, ASE_MIPS16);
8112
        /* MIPS16: Not implemented. */
8113
    case OPC_MDMX:
8114
        check_insn(env, ctx, ASE_MDMX);
8115
        /* MDMX: Not implemented. */
8116
    default:            /* Invalid */
8117
        MIPS_INVAL("major opcode");
8118
        generate_exception(ctx, EXCP_RI);
8119
        break;
8120
    }
8121
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8122
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8123
        /* Branches completion */
8124
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8125
        ctx->bstate = BS_BRANCH;
8126
        save_cpu_state(ctx, 0);
8127
        /* FIXME: Need to clear can_do_io.  */
8128
        switch (hflags) {
8129
        case MIPS_HFLAG_B:
8130
            /* unconditional branch */
8131
            MIPS_DEBUG("unconditional branch");
8132
            gen_goto_tb(ctx, 0, ctx->btarget);
8133
            break;
8134
        case MIPS_HFLAG_BL:
8135
            /* blikely taken case */
8136
            MIPS_DEBUG("blikely branch taken");
8137
            gen_goto_tb(ctx, 0, ctx->btarget);
8138
            break;
8139
        case MIPS_HFLAG_BC:
8140
            /* Conditional branch */
8141
            MIPS_DEBUG("conditional branch");
8142
            {
8143
                int l1 = gen_new_label();
8144

    
8145
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8146
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8147
                gen_set_label(l1);
8148
                gen_goto_tb(ctx, 0, ctx->btarget);
8149
            }
8150
            break;
8151
        case MIPS_HFLAG_BR:
8152
            /* unconditional branch to register */
8153
            MIPS_DEBUG("branch to register");
8154
            tcg_gen_mov_tl(cpu_PC, btarget);
8155
            tcg_gen_exit_tb(0);
8156
            break;
8157
        default:
8158
            MIPS_DEBUG("unknown branch");
8159
            break;
8160
        }
8161
    }
8162
}
8163

    
8164
static inline void
8165
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8166
                                int search_pc)
8167
{
8168
    DisasContext ctx;
8169
    target_ulong pc_start;
8170
    uint16_t *gen_opc_end;
8171
    CPUBreakpoint *bp;
8172
    int j, lj = -1;
8173
    int num_insns;
8174
    int max_insns;
8175

    
8176
    if (search_pc)
8177
        qemu_log("search pc %d\n", search_pc);
8178

    
8179
    pc_start = tb->pc;
8180
    /* Leave some spare opc slots for branch handling. */
8181
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8182
    ctx.pc = pc_start;
8183
    ctx.saved_pc = -1;
8184
    ctx.tb = tb;
8185
    ctx.bstate = BS_NONE;
8186
    /* Restore delay slot state from the tb context.  */
8187
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8188
    restore_cpu_state(env, &ctx);
8189
#ifdef CONFIG_USER_ONLY
8190
        ctx.mem_idx = MIPS_HFLAG_UM;
8191
#else
8192
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8193
#endif
8194
    num_insns = 0;
8195
    max_insns = tb->cflags & CF_COUNT_MASK;
8196
    if (max_insns == 0)
8197
        max_insns = CF_COUNT_MASK;
8198
#ifdef DEBUG_DISAS
8199
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8200
    /* FIXME: This may print out stale hflags from env... */
8201
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8202
#endif
8203
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8204
    gen_icount_start();
8205
    while (ctx.bstate == BS_NONE) {
8206
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8207
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8208
                if (bp->pc == ctx.pc) {
8209
                    save_cpu_state(&ctx, 1);
8210
                    ctx.bstate = BS_BRANCH;
8211
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8212
                    /* Include the breakpoint location or the tb won't
8213
                     * be flushed when it must be.  */
8214
                    ctx.pc += 4;
8215
                    goto done_generating;
8216
                }
8217
            }
8218
        }
8219

    
8220
        if (search_pc) {
8221
            j = gen_opc_ptr - gen_opc_buf;
8222
            if (lj < j) {
8223
                lj++;
8224
                while (lj < j)
8225
                    gen_opc_instr_start[lj++] = 0;
8226
            }
8227
            gen_opc_pc[lj] = ctx.pc;
8228
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8229
            gen_opc_instr_start[lj] = 1;
8230
            gen_opc_icount[lj] = num_insns;
8231
        }
8232
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8233
            gen_io_start();
8234
        ctx.opcode = ldl_code(ctx.pc);
8235
        decode_opc(env, &ctx);
8236
        ctx.pc += 4;
8237
        num_insns++;
8238

    
8239
        if (env->singlestep_enabled)
8240
            break;
8241

    
8242
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8243
            break;
8244

    
8245
        if (gen_opc_ptr >= gen_opc_end)
8246
            break;
8247

    
8248
        if (num_insns >= max_insns)
8249
            break;
8250
#if defined (MIPS_SINGLE_STEP)
8251
        break;
8252
#endif
8253
    }
8254
    if (tb->cflags & CF_LAST_IO)
8255
        gen_io_end();
8256
    if (env->singlestep_enabled) {
8257
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8258
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8259
    } else {
8260
        switch (ctx.bstate) {
8261
        case BS_STOP:
8262
            gen_helper_interrupt_restart();
8263
            gen_goto_tb(&ctx, 0, ctx.pc);
8264
            break;
8265
        case BS_NONE:
8266
            save_cpu_state(&ctx, 0);
8267
            gen_goto_tb(&ctx, 0, ctx.pc);
8268
            break;
8269
        case BS_EXCP:
8270
            gen_helper_interrupt_restart();
8271
            tcg_gen_exit_tb(0);
8272
            break;
8273
        case BS_BRANCH:
8274
        default:
8275
            break;
8276
        }
8277
    }
8278
done_generating:
8279
    gen_icount_end(tb, num_insns);
8280
    *gen_opc_ptr = INDEX_op_end;
8281
    if (search_pc) {
8282
        j = gen_opc_ptr - gen_opc_buf;
8283
        lj++;
8284
        while (lj <= j)
8285
            gen_opc_instr_start[lj++] = 0;
8286
    } else {
8287
        tb->size = ctx.pc - pc_start;
8288
        tb->icount = num_insns;
8289
    }
8290
#ifdef DEBUG_DISAS
8291
    LOG_DISAS("\n");
8292
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8293
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8294
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8295
        qemu_log("\n");
8296
    }
8297
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8298
#endif
8299
}
8300

    
8301
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8302
{
8303
    gen_intermediate_code_internal(env, tb, 0);
8304
}
8305

    
8306
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8307
{
8308
    gen_intermediate_code_internal(env, tb, 1);
8309
}
8310

    
8311
static void fpu_dump_state(CPUState *env, FILE *f,
8312
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8313
                           int flags)
8314
{
8315
    int i;
8316
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8317

    
8318
#define printfpr(fp)                                                        \
8319
    do {                                                                    \
8320
        if (is_fpu64)                                                       \
8321
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8322
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8323
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8324
        else {                                                              \
8325
            fpr_t tmp;                                                      \
8326
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8327
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8328
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8329
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8330
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8331
        }                                                                   \
8332
    } while(0)
8333

    
8334

    
8335
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8336
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8337
                get_float_exception_flags(&env->active_fpu.fp_status));
8338
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8339
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8340
        printfpr(&env->active_fpu.fpr[i]);
8341
    }
8342

    
8343
#undef printfpr
8344
}
8345

    
8346
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8347
/* Debug help: The architecture requires 32bit code to maintain proper
8348
   sign-extended values on 64bit machines.  */
8349

    
8350
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8351

    
8352
static void
8353
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8354
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8355
                                int flags)
8356
{
8357
    int i;
8358

    
8359
    if (!SIGN_EXT_P(env->active_tc.PC))
8360
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8361
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8362
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8363
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8364
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8365
    if (!SIGN_EXT_P(env->btarget))
8366
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8367

    
8368
    for (i = 0; i < 32; i++) {
8369
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8370
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8371
    }
8372

    
8373
    if (!SIGN_EXT_P(env->CP0_EPC))
8374
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8375
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8376
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8377
}
8378
#endif
8379

    
8380
void cpu_dump_state (CPUState *env, FILE *f,
8381
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8382
                     int flags)
8383
{
8384
    int i;
8385

    
8386
    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",
8387
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8388
                env->hflags, env->btarget, env->bcond);
8389
    for (i = 0; i < 32; i++) {
8390
        if ((i & 3) == 0)
8391
            cpu_fprintf(f, "GPR%02d:", i);
8392
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8393
        if ((i & 3) == 3)
8394
            cpu_fprintf(f, "\n");
8395
    }
8396

    
8397
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8398
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8399
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8400
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8401
    if (env->hflags & MIPS_HFLAG_FPU)
8402
        fpu_dump_state(env, f, cpu_fprintf, flags);
8403
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8404
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8405
#endif
8406
}
8407

    
8408
static void mips_tcg_init(void)
8409
{
8410
    int i;
8411
    static int inited;
8412

    
8413
    /* Initialize various static tables. */
8414
    if (inited)
8415
        return;
8416

    
8417
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8418
    for (i = 0; i < 32; i++)
8419
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8420
                                        offsetof(CPUState, active_tc.gpr[i]),
8421
                                        regnames[i]);
8422
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8423
                                offsetof(CPUState, active_tc.PC), "PC");
8424
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8425
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8426
                                       offsetof(CPUState, active_tc.HI[i]),
8427
                                       regnames_HI[i]);
8428
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8429
                                       offsetof(CPUState, active_tc.LO[i]),
8430
                                       regnames_LO[i]);
8431
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8432
                                        offsetof(CPUState, active_tc.ACX[i]),
8433
                                        regnames_ACX[i]);
8434
    }
8435
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8436
                                     offsetof(CPUState, active_tc.DSPControl),
8437
                                     "DSPControl");
8438
    bcond = tcg_global_mem_new_i32(TCG_AREG0,
8439
                                   offsetof(CPUState, bcond), "bcond");
8440
    btarget = tcg_global_mem_new(TCG_AREG0,
8441
                                 offsetof(CPUState, btarget), "btarget");
8442
    for (i = 0; i < 32; i++)
8443
        fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8444
            offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8445
            fregnames[i]);
8446
    for (i = 0; i < 32; i++)
8447
        fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
8448
            offsetof(CPUState, active_fpu.fpr[i]),
8449
            fregnames_64[i]);
8450
    for (i = 0; i < 32; i++)
8451
        fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8452
            offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8453
            fregnames_h[i]);
8454
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8455
                                      offsetof(CPUState, active_fpu.fcr0),
8456
                                      "fcr0");
8457
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8458
                                       offsetof(CPUState, active_fpu.fcr31),
8459
                                       "fcr31");
8460

    
8461
    /* register helpers */
8462
#define GEN_HELPER 2
8463
#include "helper.h"
8464

    
8465
    inited = 1;
8466
}
8467

    
8468
#include "translate_init.c"
8469

    
8470
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8471
{
8472
    CPUMIPSState *env;
8473
    const mips_def_t *def;
8474

    
8475
    def = cpu_mips_find_by_name(cpu_model);
8476
    if (!def)
8477
        return NULL;
8478
    env = qemu_mallocz(sizeof(CPUMIPSState));
8479
    env->cpu_model = def;
8480

    
8481
    cpu_exec_init(env);
8482
    env->cpu_model_str = cpu_model;
8483
    mips_tcg_init();
8484
    cpu_reset(env);
8485
    return env;
8486
}
8487

    
8488
void cpu_reset (CPUMIPSState *env)
8489
{
8490
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8491
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8492
        log_cpu_state(env, 0);
8493
    }
8494

    
8495
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8496

    
8497
    tlb_flush(env, 1);
8498

    
8499
    /* Minimal init */
8500
#if defined(CONFIG_USER_ONLY)
8501
    env->hflags = MIPS_HFLAG_UM;
8502
#else
8503
    if (env->hflags & MIPS_HFLAG_BMASK) {
8504
        /* If the exception was raised from a delay slot,
8505
           come back to the jump.  */
8506
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8507
    } else {
8508
        env->CP0_ErrorEPC = env->active_tc.PC;
8509
    }
8510
    env->active_tc.PC = (int32_t)0xBFC00000;
8511
    env->CP0_Wired = 0;
8512
    /* SMP not implemented */
8513
    env->CP0_EBase = 0x80000000;
8514
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8515
    /* vectored interrupts not implemented, timer on int 7,
8516
       no performance counters. */
8517
    env->CP0_IntCtl = 0xe0000000;
8518
    {
8519
        int i;
8520

    
8521
        for (i = 0; i < 7; i++) {
8522
            env->CP0_WatchLo[i] = 0;
8523
            env->CP0_WatchHi[i] = 0x80000000;
8524
        }
8525
        env->CP0_WatchLo[7] = 0;
8526
        env->CP0_WatchHi[7] = 0;
8527
    }
8528
    /* Count register increments in debug mode, EJTAG version 1 */
8529
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8530
    env->hflags = MIPS_HFLAG_CP0;
8531
#endif
8532
    env->exception_index = EXCP_NONE;
8533
    cpu_mips_register(env, env->cpu_model);
8534
}
8535

    
8536
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8537
                unsigned long searched_pc, int pc_pos, void *puc)
8538
{
8539
    env->active_tc.PC = gen_opc_pc[pc_pos];
8540
    env->hflags &= ~MIPS_HFLAG_BMASK;
8541
    env->hflags |= gen_opc_hflags[pc_pos];
8542
}