Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a3fe9013

History | View | Annotate | Download (245.1 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_nor_tl(t0, t0, t1);
1617
        opn = "nor";
1618
        break;
1619
    case OPC_OR:
1620
        tcg_gen_or_tl(t0, t0, t1);
1621
        opn = "or";
1622
        break;
1623
    case OPC_XOR:
1624
        tcg_gen_xor_tl(t0, t0, t1);
1625
        opn = "xor";
1626
        break;
1627
    case OPC_MUL:
1628
        tcg_gen_mul_tl(t0, t0, t1);
1629
        tcg_gen_ext32s_tl(t0, t0);
1630
        opn = "mul";
1631
        break;
1632
    case OPC_MOVN:
1633
        {
1634
            int l1 = gen_new_label();
1635

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2059
    gen_load_gpr(t0, rs);
2060
    gen_load_gpr(t1, rt);
2061

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

    
2127
 out:
2128
    tcg_temp_free(t0);
2129
    tcg_temp_free(t1);
2130
}
2131

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

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

    
2171
 out:
2172
    tcg_temp_free(t0);
2173
}
2174

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

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

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

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

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

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

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

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

    
2533
 out:
2534
    tcg_temp_free(t0);
2535
    tcg_temp_free(t1);
2536
}
2537

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

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

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

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

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

    
2691
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2692
    tcg_gen_ext_i32_tl(t, r_tmp);
2693
    tcg_temp_free_i32(r_tmp);
2694
}
2695

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

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

    
2706
    tcg_gen_trunc_tl_i32(r_tmp, t);
2707
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2708
    tcg_temp_free_i32(r_tmp);
2709
}
2710

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

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

    
2721
    if (sel != 0)
2722
        check_insn(env, ctx, ISA_MIPS32);
2723

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

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

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

    
3298
    if (sel != 0)
3299
        check_insn(env, ctx, ISA_MIPS32);
3300

    
3301
    if (use_icount)
3302
        gen_io_start();
3303

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

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

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

    
3898
    if (sel != 0)
3899
        check_insn(env, ctx, ISA_MIPS64);
3900

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

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

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

    
4464
    if (sel != 0)
4465
        check_insn(env, ctx, ISA_MIPS64);
4466

    
4467
    if (use_icount)
4468
        gen_io_start();
4469

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5524
    btarget = ctx->pc + 4 + offset;
5525

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

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

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

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

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

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

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

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

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

    
5668
 out:
5669
    tcg_temp_free_i32(t0);
5670
}
5671

    
5672
/* Coprocessor 1 (FPU) */
5673

    
5674
#define FOP(func, fmt) (((fmt) << 21) | (func))
5675

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

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

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

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

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

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

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

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

    
5765
 out:
5766
    tcg_temp_free(t0);
5767
}
5768

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

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

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

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

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

    
5809
    if (tf)
5810
        cond = TCG_COND_EQ;
5811
    else
5812
        cond = TCG_COND_NE;
5813

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

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

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

    
5837
    if (tf)
5838
        cond = TCG_COND_EQ;
5839
    else
5840
        cond = TCG_COND_NE;
5841

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

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

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

    
5869
    if (tf)
5870
        cond = TCG_COND_EQ;
5871
    else
5872
        cond = TCG_COND_NE;
5873

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

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

    
5888
    tcg_temp_free_i32(r_tmp1);
5889
    tcg_temp_free_i32(fp0);
5890
}
5891

    
5892

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7001
            gen_load_fpr64(ctx, fp0, fs);
7002
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7003
            gen_store_fpr64(ctx, fp0, fd);
7004
            tcg_temp_free_i64(fp0);
7005
        }
7006
        opn = "rsqrt1.ps";
7007
        break;
7008
    case FOP(31, 22):
7009
        check_cp1_64bitmode(ctx);
7010
        {
7011
            TCGv_i64 fp0 = tcg_temp_new_i64();
7012
            TCGv_i64 fp1 = tcg_temp_new_i64();
7013

    
7014
            gen_load_fpr64(ctx, fp0, fs);
7015
            gen_load_fpr64(ctx, fp1, ft);
7016
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7017
            tcg_temp_free_i64(fp1);
7018
            gen_store_fpr64(ctx, fp0, fd);
7019
            tcg_temp_free_i64(fp0);
7020
        }
7021
        opn = "rsqrt2.ps";
7022
        break;
7023
    case FOP(32, 22):
7024
        check_cp1_64bitmode(ctx);
7025
        {
7026
            TCGv_i32 fp0 = tcg_temp_new_i32();
7027

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7554
/* ISA extensions (ASEs) */
7555
/* MIPS16 extension to MIPS32 */
7556
/* SmartMIPS extension to MIPS32 */
7557

    
7558
#if defined(TARGET_MIPS64)
7559

    
7560
/* MDMX extension to MIPS64 */
7561

    
7562
#endif
7563

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8174
    if (search_pc)
8175
        qemu_log("search pc %d\n", search_pc);
8176

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

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

    
8237
        if (env->singlestep_enabled)
8238
            break;
8239

    
8240
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8241
            break;
8242

    
8243
        if (gen_opc_ptr >= gen_opc_end)
8244
            break;
8245

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

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

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

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

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

    
8332

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

    
8341
#undef printfpr
8342
}
8343

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

    
8348
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8349

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

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

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

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

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

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

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

    
8406
static void mips_tcg_init(void)
8407
{
8408
    int i;
8409
    static int inited;
8410

    
8411
    /* Initialize various static tables. */
8412
    if (inited)
8413
        return;
8414

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

    
8459
    /* register helpers */
8460
#define GEN_HELPER 2
8461
#include "helper.h"
8462

    
8463
    inited = 1;
8464
}
8465

    
8466
#include "translate_init.c"
8467

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

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

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

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

    
8493
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8494

    
8495
    tlb_flush(env, 1);
8496

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

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

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