Statistics
| Branch: | Revision:

root / target-mips / translate.c @ af58f9ca

History | View | Annotate | Download (242.5 kB)

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

    
436
#include "gen-icount.h"
437

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1123
/* Load and store */
1124
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1125
                          int base, int16_t offset)
1126
{
1127
    const char *opn = "flt_ldst";
1128
    TCGv t0 = tcg_temp_local_new();
1129

    
1130
    if (base == 0) {
1131
        tcg_gen_movi_tl(t0, offset);
1132
    } else if (offset == 0) {
1133
        gen_load_gpr(t0, base);
1134
    } else {
1135
        tcg_gen_movi_tl(t0, offset);
1136
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1137
    }
1138
    /* Don't do NOP if destination is zero: we must perform the actual
1139
       memory access. */
1140
    switch (opc) {
1141
    case OPC_LWC1:
1142
        {
1143
            TCGv_i32 fp0 = tcg_temp_new_i32();
1144
            TCGv t1 = tcg_temp_new();
1145

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3270
    if (use_icount)
3271
        gen_io_start();
3272

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

    
3857
die:
3858
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3859
    generate_exception(ctx, EXCP_RI);
3860
}
3861

    
3862
#if defined(TARGET_MIPS64)
3863
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3864
{
3865
    const char *rn = "invalid";
3866

    
3867
    if (sel != 0)
3868
        check_insn(env, ctx, ISA_MIPS64);
3869

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

    
4424
die:
4425
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4426
    generate_exception(ctx, EXCP_RI);
4427
}
4428

    
4429
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4430
{
4431
    const char *rn = "invalid";
4432

    
4433
    if (sel != 0)
4434
        check_insn(env, ctx, ISA_MIPS64);
4435

    
4436
    if (use_icount)
4437
        gen_io_start();
4438

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

    
5010
die:
5011
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5012
    generate_exception(ctx, EXCP_RI);
5013
}
5014
#endif /* TARGET_MIPS64 */
5015

    
5016
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5017
                     int u, int sel, int h)
5018
{
5019
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5020
    TCGv t0 = tcg_temp_local_new();
5021

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

    
5147
            gen_load_fpr32(fp0, rt);
5148
            tcg_gen_ext_i32_tl(t0, fp0);
5149
            tcg_temp_free_i32(fp0);
5150
        } else {
5151
            TCGv_i32 fp0 = tcg_temp_new_i32();
5152

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

    
5174
die:
5175
    tcg_temp_free(t0);
5176
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5177
    generate_exception(ctx, EXCP_RI);
5178
}
5179

    
5180
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5181
                     int u, int sel, int h)
5182
{
5183
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5184
    TCGv t0 = tcg_temp_local_new();
5185

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

    
5312
            tcg_gen_trunc_tl_i32(fp0, t0);
5313
            gen_store_fpr32(fp0, rd);
5314
            tcg_temp_free_i32(fp0);
5315
        } else {
5316
            TCGv_i32 fp0 = tcg_temp_new_i32();
5317

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

    
5338
die:
5339
    tcg_temp_free(t0);
5340
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5341
    generate_exception(ctx, EXCP_RI);
5342
}
5343

    
5344
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5345
{
5346
    const char *opn = "ldst";
5347

    
5348
    switch (opc) {
5349
    case OPC_MFC0:
5350
        if (rt == 0) {
5351
            /* Treat as NOP. */
5352
            return;
5353
        }
5354
        {
5355
            TCGv t0 = tcg_temp_local_new();
5356

    
5357
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5358
            gen_store_gpr(t0, rt);
5359
            tcg_temp_free(t0);
5360
        }
5361
        opn = "mfc0";
5362
        break;
5363
    case OPC_MTC0:
5364
        {
5365
            TCGv t0 = tcg_temp_local_new();
5366

    
5367
            gen_load_gpr(t0, rt);
5368
            save_cpu_state(ctx, 1);
5369
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5370
            tcg_temp_free(t0);
5371
        }
5372
        opn = "mtc0";
5373
        break;
5374
#if defined(TARGET_MIPS64)
5375
    case OPC_DMFC0:
5376
        check_insn(env, ctx, ISA_MIPS3);
5377
        if (rt == 0) {
5378
            /* Treat as NOP. */
5379
            return;
5380
        }
5381
        {
5382
            TCGv t0 = tcg_temp_local_new();
5383

    
5384
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5385
            gen_store_gpr(t0, rt);
5386
            tcg_temp_free(t0);
5387
        }
5388
        opn = "dmfc0";
5389
        break;
5390
    case OPC_DMTC0:
5391
        check_insn(env, ctx, ISA_MIPS3);
5392
        {
5393
            TCGv t0 = tcg_temp_local_new();
5394

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

    
5482
/* CP1 Branches (before delay slot) */
5483
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5484
                                 int32_t cc, int32_t offset)
5485
{
5486
    target_ulong btarget;
5487
    const char *opn = "cp1 cond branch";
5488
    TCGv_i32 t0 = tcg_temp_new_i32();
5489

    
5490
    if (cc != 0)
5491
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5492

    
5493
    btarget = ctx->pc + 4 + offset;
5494

    
5495
    switch (op) {
5496
    case OPC_BC1F:
5497
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5498
        tcg_gen_not_i32(t0, t0);
5499
        tcg_gen_andi_i32(t0, t0, 1);
5500
        tcg_gen_extu_i32_tl(bcond, t0);
5501
        opn = "bc1f";
5502
        goto not_likely;
5503
    case OPC_BC1FL:
5504
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5505
        tcg_gen_not_i32(t0, t0);
5506
        tcg_gen_andi_i32(t0, t0, 1);
5507
        tcg_gen_extu_i32_tl(bcond, t0);
5508
        opn = "bc1fl";
5509
        goto likely;
5510
    case OPC_BC1T:
5511
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5512
        tcg_gen_andi_i32(t0, t0, 1);
5513
        tcg_gen_extu_i32_tl(bcond, t0);
5514
        opn = "bc1t";
5515
        goto not_likely;
5516
    case OPC_BC1TL:
5517
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5518
        tcg_gen_andi_i32(t0, t0, 1);
5519
        tcg_gen_extu_i32_tl(bcond, t0);
5520
        opn = "bc1tl";
5521
    likely:
5522
        ctx->hflags |= MIPS_HFLAG_BL;
5523
        break;
5524
    case OPC_BC1FANY2:
5525
        {
5526
            TCGv_i32 t1 = tcg_temp_new_i32();
5527
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5528
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5529
            tcg_gen_or_i32(t0, t0, t1);
5530
            tcg_temp_free_i32(t1);
5531
            tcg_gen_not_i32(t0, t0);
5532
            tcg_gen_andi_i32(t0, t0, 1);
5533
            tcg_gen_extu_i32_tl(bcond, t0);
5534
        }
5535
        opn = "bc1any2f";
5536
        goto not_likely;
5537
    case OPC_BC1TANY2:
5538
        {
5539
            TCGv_i32 t1 = tcg_temp_new_i32();
5540
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5541
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5542
            tcg_gen_or_i32(t0, t0, t1);
5543
            tcg_temp_free_i32(t1);
5544
            tcg_gen_andi_i32(t0, t0, 1);
5545
            tcg_gen_extu_i32_tl(bcond, t0);
5546
        }
5547
        opn = "bc1any2t";
5548
        goto not_likely;
5549
    case OPC_BC1FANY4:
5550
        {
5551
            TCGv_i32 t1 = tcg_temp_new_i32();
5552
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5553
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5554
            tcg_gen_or_i32(t0, t0, t1);
5555
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5556
            tcg_gen_or_i32(t0, t0, t1);
5557
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5558
            tcg_gen_or_i32(t0, t0, t1);
5559
            tcg_temp_free_i32(t1);
5560
            tcg_gen_not_i32(t0, t0);
5561
            tcg_gen_andi_i32(t0, t0, 1);
5562
            tcg_gen_extu_i32_tl(bcond, t0);
5563
        }
5564
        opn = "bc1any4f";
5565
        goto not_likely;
5566
    case OPC_BC1TANY4:
5567
        {
5568
            TCGv_i32 t1 = tcg_temp_new_i32();
5569
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5570
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5571
            tcg_gen_or_i32(t0, t0, t1);
5572
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5573
            tcg_gen_or_i32(t0, t0, t1);
5574
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5575
            tcg_gen_or_i32(t0, t0, t1);
5576
            tcg_temp_free_i32(t1);
5577
            tcg_gen_andi_i32(t0, t0, 1);
5578
            tcg_gen_extu_i32_tl(bcond, t0);
5579
        }
5580
        opn = "bc1any4t";
5581
    not_likely:
5582
        ctx->hflags |= MIPS_HFLAG_BC;
5583
        break;
5584
    default:
5585
        MIPS_INVAL(opn);
5586
        generate_exception (ctx, EXCP_RI);
5587
        goto out;
5588
    }
5589
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5590
               ctx->hflags, btarget);
5591
    ctx->btarget = btarget;
5592

    
5593
 out:
5594
    tcg_temp_free_i32(t0);
5595
}
5596

    
5597
/* Coprocessor 1 (FPU) */
5598

    
5599
#define FOP(func, fmt) (((fmt) << 21) | (func))
5600

    
5601
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5602
{
5603
    const char *opn = "cp1 move";
5604
    TCGv t0 = tcg_temp_local_new();
5605

    
5606
    switch (opc) {
5607
    case OPC_MFC1:
5608
        {
5609
            TCGv_i32 fp0 = tcg_temp_new_i32();
5610

    
5611
            gen_load_fpr32(fp0, fs);
5612
            tcg_gen_ext_i32_tl(t0, fp0);
5613
            tcg_temp_free_i32(fp0);
5614
        }
5615
        gen_store_gpr(t0, rt);
5616
        opn = "mfc1";
5617
        break;
5618
    case OPC_MTC1:
5619
        gen_load_gpr(t0, rt);
5620
        {
5621
            TCGv_i32 fp0 = tcg_temp_new_i32();
5622

    
5623
            tcg_gen_trunc_tl_i32(fp0, t0);
5624
            gen_store_fpr32(fp0, fs);
5625
            tcg_temp_free_i32(fp0);
5626
        }
5627
        opn = "mtc1";
5628
        break;
5629
    case OPC_CFC1:
5630
        gen_helper_1i(cfc1, t0, fs);
5631
        gen_store_gpr(t0, rt);
5632
        opn = "cfc1";
5633
        break;
5634
    case OPC_CTC1:
5635
        gen_load_gpr(t0, rt);
5636
        gen_helper_1i(ctc1, t0, fs);
5637
        opn = "ctc1";
5638
        break;
5639
    case OPC_DMFC1:
5640
        {
5641
            TCGv_i64 fp0 = tcg_temp_new_i64();
5642

    
5643
            gen_load_fpr64(ctx, fp0, fs);
5644
            tcg_gen_trunc_i64_tl(t0, fp0);
5645
            tcg_temp_free_i64(fp0);
5646
        }
5647
        gen_store_gpr(t0, rt);
5648
        opn = "dmfc1";
5649
        break;
5650
    case OPC_DMTC1:
5651
        gen_load_gpr(t0, rt);
5652
        {
5653
            TCGv_i64 fp0 = tcg_temp_new_i64();
5654

    
5655
            tcg_gen_extu_tl_i64(fp0, t0);
5656
            gen_store_fpr64(ctx, fp0, fs);
5657
            tcg_temp_free_i64(fp0);
5658
        }
5659
        opn = "dmtc1";
5660
        break;
5661
    case OPC_MFHC1:
5662
        {
5663
            TCGv_i32 fp0 = tcg_temp_new_i32();
5664

    
5665
            gen_load_fpr32h(fp0, fs);
5666
            tcg_gen_ext_i32_tl(t0, fp0);
5667
            tcg_temp_free_i32(fp0);
5668
        }
5669
        gen_store_gpr(t0, rt);
5670
        opn = "mfhc1";
5671
        break;
5672
    case OPC_MTHC1:
5673
        gen_load_gpr(t0, rt);
5674
        {
5675
            TCGv_i32 fp0 = tcg_temp_new_i32();
5676

    
5677
            tcg_gen_trunc_tl_i32(fp0, t0);
5678
            gen_store_fpr32h(fp0, fs);
5679
            tcg_temp_free_i32(fp0);
5680
        }
5681
        opn = "mthc1";
5682
        break;
5683
    default:
5684
        MIPS_INVAL(opn);
5685
        generate_exception (ctx, EXCP_RI);
5686
        goto out;
5687
    }
5688
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5689

    
5690
 out:
5691
    tcg_temp_free(t0);
5692
}
5693

    
5694
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5695
{
5696
    int l1;
5697
    TCGCond cond;
5698
    TCGv_i32 t0;
5699

    
5700
    if (rd == 0) {
5701
        /* Treat as NOP. */
5702
        return;
5703
    }
5704

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

    
5710
    l1 = gen_new_label();
5711
    t0 = tcg_temp_new_i32();
5712
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5713
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5714
    if (rs == 0) {
5715
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5716
    } else {
5717
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5718
    }
5719
    gen_set_label(l1);
5720
    tcg_temp_free_i32(t0);
5721
}
5722

    
5723
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5724
{
5725
    uint32_t ccbit;
5726
    int cond;
5727
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5728
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5729
    int l1 = gen_new_label();
5730

    
5731
    if (cc)
5732
        ccbit = 1 << (24 + cc);
5733
    else
5734
        ccbit = 1 << 23;
5735

    
5736
    if (tf)
5737
        cond = TCG_COND_EQ;
5738
    else
5739
        cond = TCG_COND_NE;
5740

    
5741
    gen_load_fpr32(fp0, fd);
5742
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5743
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5744
    tcg_temp_free_i32(r_tmp1);
5745
    gen_load_fpr32(fp0, fs);
5746
    gen_set_label(l1);
5747
    gen_store_fpr32(fp0, fd);
5748
    tcg_temp_free_i32(fp0);
5749
}
5750

    
5751
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5752
{
5753
    uint32_t ccbit;
5754
    int cond;
5755
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5756
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5757
    int l1 = gen_new_label();
5758

    
5759
    if (cc)
5760
        ccbit = 1 << (24 + cc);
5761
    else
5762
        ccbit = 1 << 23;
5763

    
5764
    if (tf)
5765
        cond = TCG_COND_EQ;
5766
    else
5767
        cond = TCG_COND_NE;
5768

    
5769
    gen_load_fpr64(ctx, fp0, fd);
5770
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5771
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5772
    tcg_temp_free_i32(r_tmp1);
5773
    gen_load_fpr64(ctx, fp0, fs);
5774
    gen_set_label(l1);
5775
    gen_store_fpr64(ctx, fp0, fd);
5776
    tcg_temp_free_i64(fp0);
5777
}
5778

    
5779
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5780
{
5781
    uint32_t ccbit1, ccbit2;
5782
    int cond;
5783
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5784
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5785
    int l1 = gen_new_label();
5786
    int l2 = gen_new_label();
5787

    
5788
    if (cc) {
5789
        ccbit1 = 1 << (24 + cc);
5790
        ccbit2 = 1 << (25 + cc);
5791
    } else {
5792
        ccbit1 = 1 << 23;
5793
        ccbit2 = 1 << 25;
5794
    }
5795

    
5796
    if (tf)
5797
        cond = TCG_COND_EQ;
5798
    else
5799
        cond = TCG_COND_NE;
5800

    
5801
    gen_load_fpr32(fp0, fd);
5802
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5803
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5804
    gen_load_fpr32(fp0, fs);
5805
    gen_set_label(l1);
5806
    gen_store_fpr32(fp0, fd);
5807

    
5808
    gen_load_fpr32h(fp0, fd);
5809
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5810
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5811
    gen_load_fpr32h(fp0, fs);
5812
    gen_set_label(l2);
5813
    gen_store_fpr32h(fp0, fd);
5814

    
5815
    tcg_temp_free_i32(r_tmp1);
5816
    tcg_temp_free_i32(fp0);
5817
}
5818

    
5819

    
5820
static void gen_farith (DisasContext *ctx, uint32_t op1,
5821
                        int ft, int fs, int fd, int cc)
5822
{
5823
    const char *opn = "farith";
5824
    const char *condnames[] = {
5825
            "c.f",
5826
            "c.un",
5827
            "c.eq",
5828
            "c.ueq",
5829
            "c.olt",
5830
            "c.ult",
5831
            "c.ole",
5832
            "c.ule",
5833
            "c.sf",
5834
            "c.ngle",
5835
            "c.seq",
5836
            "c.ngl",
5837
            "c.lt",
5838
            "c.nge",
5839
            "c.le",
5840
            "c.ngt",
5841
    };
5842
    const char *condnames_abs[] = {
5843
            "cabs.f",
5844
            "cabs.un",
5845
            "cabs.eq",
5846
            "cabs.ueq",
5847
            "cabs.olt",
5848
            "cabs.ult",
5849
            "cabs.ole",
5850
            "cabs.ule",
5851
            "cabs.sf",
5852
            "cabs.ngle",
5853
            "cabs.seq",
5854
            "cabs.ngl",
5855
            "cabs.lt",
5856
            "cabs.nge",
5857
            "cabs.le",
5858
            "cabs.ngt",
5859
    };
5860
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5861
    uint32_t func = ctx->opcode & 0x3f;
5862

    
5863
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5864
    case FOP(0, 16):
5865
        {
5866
            TCGv_i32 fp0 = tcg_temp_new_i32();
5867
            TCGv_i32 fp1 = tcg_temp_new_i32();
5868

    
5869
            gen_load_fpr32(fp0, fs);
5870
            gen_load_fpr32(fp1, ft);
5871
            gen_helper_float_add_s(fp0, fp0, fp1);
5872
            tcg_temp_free_i32(fp1);
5873
            gen_store_fpr32(fp0, fd);
5874
            tcg_temp_free_i32(fp0);
5875
        }
5876
        opn = "add.s";
5877
        optype = BINOP;
5878
        break;
5879
    case FOP(1, 16):
5880
        {
5881
            TCGv_i32 fp0 = tcg_temp_new_i32();
5882
            TCGv_i32 fp1 = tcg_temp_new_i32();
5883

    
5884
            gen_load_fpr32(fp0, fs);
5885
            gen_load_fpr32(fp1, ft);
5886
            gen_helper_float_sub_s(fp0, fp0, fp1);
5887
            tcg_temp_free_i32(fp1);
5888
            gen_store_fpr32(fp0, fd);
5889
            tcg_temp_free_i32(fp0);
5890
        }
5891
        opn = "sub.s";
5892
        optype = BINOP;
5893
        break;
5894
    case FOP(2, 16):
5895
        {
5896
            TCGv_i32 fp0 = tcg_temp_new_i32();
5897
            TCGv_i32 fp1 = tcg_temp_new_i32();
5898

    
5899
            gen_load_fpr32(fp0, fs);
5900
            gen_load_fpr32(fp1, ft);
5901
            gen_helper_float_mul_s(fp0, fp0, fp1);
5902
            tcg_temp_free_i32(fp1);
5903
            gen_store_fpr32(fp0, fd);
5904
            tcg_temp_free_i32(fp0);
5905
        }
5906
        opn = "mul.s";
5907
        optype = BINOP;
5908
        break;
5909
    case FOP(3, 16):
5910
        {
5911
            TCGv_i32 fp0 = tcg_temp_new_i32();
5912
            TCGv_i32 fp1 = tcg_temp_new_i32();
5913

    
5914
            gen_load_fpr32(fp0, fs);
5915
            gen_load_fpr32(fp1, ft);
5916
            gen_helper_float_div_s(fp0, fp0, fp1);
5917
            tcg_temp_free_i32(fp1);
5918
            gen_store_fpr32(fp0, fd);
5919
            tcg_temp_free_i32(fp0);
5920
        }
5921
        opn = "div.s";
5922
        optype = BINOP;
5923
        break;
5924
    case FOP(4, 16):
5925
        {
5926
            TCGv_i32 fp0 = tcg_temp_new_i32();
5927

    
5928
            gen_load_fpr32(fp0, fs);
5929
            gen_helper_float_sqrt_s(fp0, fp0);
5930
            gen_store_fpr32(fp0, fd);
5931
            tcg_temp_free_i32(fp0);
5932
        }
5933
        opn = "sqrt.s";
5934
        break;
5935
    case FOP(5, 16):
5936
        {
5937
            TCGv_i32 fp0 = tcg_temp_new_i32();
5938

    
5939
            gen_load_fpr32(fp0, fs);
5940
            gen_helper_float_abs_s(fp0, fp0);
5941
            gen_store_fpr32(fp0, fd);
5942
            tcg_temp_free_i32(fp0);
5943
        }
5944
        opn = "abs.s";
5945
        break;
5946
    case FOP(6, 16):
5947
        {
5948
            TCGv_i32 fp0 = tcg_temp_new_i32();
5949

    
5950
            gen_load_fpr32(fp0, fs);
5951
            gen_store_fpr32(fp0, fd);
5952
            tcg_temp_free_i32(fp0);
5953
        }
5954
        opn = "mov.s";
5955
        break;
5956
    case FOP(7, 16):
5957
        {
5958
            TCGv_i32 fp0 = tcg_temp_new_i32();
5959

    
5960
            gen_load_fpr32(fp0, fs);
5961
            gen_helper_float_chs_s(fp0, fp0);
5962
            gen_store_fpr32(fp0, fd);
5963
            tcg_temp_free_i32(fp0);
5964
        }
5965
        opn = "neg.s";
5966
        break;
5967
    case FOP(8, 16):
5968
        check_cp1_64bitmode(ctx);
5969
        {
5970
            TCGv_i32 fp32 = tcg_temp_new_i32();
5971
            TCGv_i64 fp64 = tcg_temp_new_i64();
5972

    
5973
            gen_load_fpr32(fp32, fs);
5974
            gen_helper_float_roundl_s(fp64, fp32);
5975
            tcg_temp_free_i32(fp32);
5976
            gen_store_fpr64(ctx, fp64, fd);
5977
            tcg_temp_free_i64(fp64);
5978
        }
5979
        opn = "round.l.s";
5980
        break;
5981
    case FOP(9, 16):
5982
        check_cp1_64bitmode(ctx);
5983
        {
5984
            TCGv_i32 fp32 = tcg_temp_new_i32();
5985
            TCGv_i64 fp64 = tcg_temp_new_i64();
5986

    
5987
            gen_load_fpr32(fp32, fs);
5988
            gen_helper_float_truncl_s(fp64, fp32);
5989
            tcg_temp_free_i32(fp32);
5990
            gen_store_fpr64(ctx, fp64, fd);
5991
            tcg_temp_free_i64(fp64);
5992
        }
5993
        opn = "trunc.l.s";
5994
        break;
5995
    case FOP(10, 16):
5996
        check_cp1_64bitmode(ctx);
5997
        {
5998
            TCGv_i32 fp32 = tcg_temp_new_i32();
5999
            TCGv_i64 fp64 = tcg_temp_new_i64();
6000

    
6001
            gen_load_fpr32(fp32, fs);
6002
            gen_helper_float_ceill_s(fp64, fp32);
6003
            tcg_temp_free_i32(fp32);
6004
            gen_store_fpr64(ctx, fp64, fd);
6005
            tcg_temp_free_i64(fp64);
6006
        }
6007
        opn = "ceil.l.s";
6008
        break;
6009
    case FOP(11, 16):
6010
        check_cp1_64bitmode(ctx);
6011
        {
6012
            TCGv_i32 fp32 = tcg_temp_new_i32();
6013
            TCGv_i64 fp64 = tcg_temp_new_i64();
6014

    
6015
            gen_load_fpr32(fp32, fs);
6016
            gen_helper_float_floorl_s(fp64, fp32);
6017
            tcg_temp_free_i32(fp32);
6018
            gen_store_fpr64(ctx, fp64, fd);
6019
            tcg_temp_free_i64(fp64);
6020
        }
6021
        opn = "floor.l.s";
6022
        break;
6023
    case FOP(12, 16):
6024
        {
6025
            TCGv_i32 fp0 = tcg_temp_new_i32();
6026

    
6027
            gen_load_fpr32(fp0, fs);
6028
            gen_helper_float_roundw_s(fp0, fp0);
6029
            gen_store_fpr32(fp0, fd);
6030
            tcg_temp_free_i32(fp0);
6031
        }
6032
        opn = "round.w.s";
6033
        break;
6034
    case FOP(13, 16):
6035
        {
6036
            TCGv_i32 fp0 = tcg_temp_new_i32();
6037

    
6038
            gen_load_fpr32(fp0, fs);
6039
            gen_helper_float_truncw_s(fp0, fp0);
6040
            gen_store_fpr32(fp0, fd);
6041
            tcg_temp_free_i32(fp0);
6042
        }
6043
        opn = "trunc.w.s";
6044
        break;
6045
    case FOP(14, 16):
6046
        {
6047
            TCGv_i32 fp0 = tcg_temp_new_i32();
6048

    
6049
            gen_load_fpr32(fp0, fs);
6050
            gen_helper_float_ceilw_s(fp0, fp0);
6051
            gen_store_fpr32(fp0, fd);
6052
            tcg_temp_free_i32(fp0);
6053
        }
6054
        opn = "ceil.w.s";
6055
        break;
6056
    case FOP(15, 16):
6057
        {
6058
            TCGv_i32 fp0 = tcg_temp_new_i32();
6059

    
6060
            gen_load_fpr32(fp0, fs);
6061
            gen_helper_float_floorw_s(fp0, fp0);
6062
            gen_store_fpr32(fp0, fd);
6063
            tcg_temp_free_i32(fp0);
6064
        }
6065
        opn = "floor.w.s";
6066
        break;
6067
    case FOP(17, 16):
6068
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6069
        opn = "movcf.s";
6070
        break;
6071
    case FOP(18, 16):
6072
        {
6073
            int l1 = gen_new_label();
6074
            TCGv t0 = tcg_temp_new();
6075
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6076

    
6077
            gen_load_gpr(t0, ft);
6078
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6079
            gen_load_fpr32(fp0, fs);
6080
            gen_store_fpr32(fp0, fd);
6081
            tcg_temp_free_i32(fp0);
6082
            gen_set_label(l1);
6083
            tcg_temp_free(t0);
6084
        }
6085
        opn = "movz.s";
6086
        break;
6087
    case FOP(19, 16):
6088
        {
6089
            int l1 = gen_new_label();
6090
            TCGv t0 = tcg_temp_new();
6091
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6092

    
6093
            gen_load_gpr(t0, ft);
6094
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6095
            gen_load_fpr32(fp0, fs);
6096
            gen_store_fpr32(fp0, fd);
6097
            tcg_temp_free_i32(fp0);
6098
            gen_set_label(l1);
6099
            tcg_temp_free(t0);
6100
        }
6101
        opn = "movn.s";
6102
        break;
6103
    case FOP(21, 16):
6104
        check_cop1x(ctx);
6105
        {
6106
            TCGv_i32 fp0 = tcg_temp_new_i32();
6107

    
6108
            gen_load_fpr32(fp0, fs);
6109
            gen_helper_float_recip_s(fp0, fp0);
6110
            gen_store_fpr32(fp0, fd);
6111
            tcg_temp_free_i32(fp0);
6112
        }
6113
        opn = "recip.s";
6114
        break;
6115
    case FOP(22, 16):
6116
        check_cop1x(ctx);
6117
        {
6118
            TCGv_i32 fp0 = tcg_temp_new_i32();
6119

    
6120
            gen_load_fpr32(fp0, fs);
6121
            gen_helper_float_rsqrt_s(fp0, fp0);
6122
            gen_store_fpr32(fp0, fd);
6123
            tcg_temp_free_i32(fp0);
6124
        }
6125
        opn = "rsqrt.s";
6126
        break;
6127
    case FOP(28, 16):
6128
        check_cp1_64bitmode(ctx);
6129
        {
6130
            TCGv_i32 fp0 = tcg_temp_new_i32();
6131
            TCGv_i32 fp1 = tcg_temp_new_i32();
6132

    
6133
            gen_load_fpr32(fp0, fs);
6134
            gen_load_fpr32(fp1, fd);
6135
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6136
            tcg_temp_free_i32(fp1);
6137
            gen_store_fpr32(fp0, fd);
6138
            tcg_temp_free_i32(fp0);
6139
        }
6140
        opn = "recip2.s";
6141
        break;
6142
    case FOP(29, 16):
6143
        check_cp1_64bitmode(ctx);
6144
        {
6145
            TCGv_i32 fp0 = tcg_temp_new_i32();
6146

    
6147
            gen_load_fpr32(fp0, fs);
6148
            gen_helper_float_recip1_s(fp0, fp0);
6149
            gen_store_fpr32(fp0, fd);
6150
            tcg_temp_free_i32(fp0);
6151
        }
6152
        opn = "recip1.s";
6153
        break;
6154
    case FOP(30, 16):
6155
        check_cp1_64bitmode(ctx);
6156
        {
6157
            TCGv_i32 fp0 = tcg_temp_new_i32();
6158

    
6159
            gen_load_fpr32(fp0, fs);
6160
            gen_helper_float_rsqrt1_s(fp0, fp0);
6161
            gen_store_fpr32(fp0, fd);
6162
            tcg_temp_free_i32(fp0);
6163
        }
6164
        opn = "rsqrt1.s";
6165
        break;
6166
    case FOP(31, 16):
6167
        check_cp1_64bitmode(ctx);
6168
        {
6169
            TCGv_i32 fp0 = tcg_temp_new_i32();
6170
            TCGv_i32 fp1 = tcg_temp_new_i32();
6171

    
6172
            gen_load_fpr32(fp0, fs);
6173
            gen_load_fpr32(fp1, ft);
6174
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6175
            tcg_temp_free_i32(fp1);
6176
            gen_store_fpr32(fp0, fd);
6177
            tcg_temp_free_i32(fp0);
6178
        }
6179
        opn = "rsqrt2.s";
6180
        break;
6181
    case FOP(33, 16):
6182
        check_cp1_registers(ctx, fd);
6183
        {
6184
            TCGv_i32 fp32 = tcg_temp_new_i32();
6185
            TCGv_i64 fp64 = tcg_temp_new_i64();
6186

    
6187
            gen_load_fpr32(fp32, fs);
6188
            gen_helper_float_cvtd_s(fp64, fp32);
6189
            tcg_temp_free_i32(fp32);
6190
            gen_store_fpr64(ctx, fp64, fd);
6191
            tcg_temp_free_i64(fp64);
6192
        }
6193
        opn = "cvt.d.s";
6194
        break;
6195
    case FOP(36, 16):
6196
        {
6197
            TCGv_i32 fp0 = tcg_temp_new_i32();
6198

    
6199
            gen_load_fpr32(fp0, fs);
6200
            gen_helper_float_cvtw_s(fp0, fp0);
6201
            gen_store_fpr32(fp0, fd);
6202
            tcg_temp_free_i32(fp0);
6203
        }
6204
        opn = "cvt.w.s";
6205
        break;
6206
    case FOP(37, 16):
6207
        check_cp1_64bitmode(ctx);
6208
        {
6209
            TCGv_i32 fp32 = tcg_temp_new_i32();
6210
            TCGv_i64 fp64 = tcg_temp_new_i64();
6211

    
6212
            gen_load_fpr32(fp32, fs);
6213
            gen_helper_float_cvtl_s(fp64, fp32);
6214
            tcg_temp_free_i32(fp32);
6215
            gen_store_fpr64(ctx, fp64, fd);
6216
            tcg_temp_free_i64(fp64);
6217
        }
6218
        opn = "cvt.l.s";
6219
        break;
6220
    case FOP(38, 16):
6221
        check_cp1_64bitmode(ctx);
6222
        {
6223
            TCGv_i64 fp64 = tcg_temp_new_i64();
6224
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6225
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6226

    
6227
            gen_load_fpr32(fp32_0, fs);
6228
            gen_load_fpr32(fp32_1, ft);
6229
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6230
            tcg_temp_free_i32(fp32_1);
6231
            tcg_temp_free_i32(fp32_0);
6232
            gen_store_fpr64(ctx, fp64, fd);
6233
            tcg_temp_free_i64(fp64);
6234
        }
6235
        opn = "cvt.ps.s";
6236
        break;
6237
    case FOP(48, 16):
6238
    case FOP(49, 16):
6239
    case FOP(50, 16):
6240
    case FOP(51, 16):
6241
    case FOP(52, 16):
6242
    case FOP(53, 16):
6243
    case FOP(54, 16):
6244
    case FOP(55, 16):
6245
    case FOP(56, 16):
6246
    case FOP(57, 16):
6247
    case FOP(58, 16):
6248
    case FOP(59, 16):
6249
    case FOP(60, 16):
6250
    case FOP(61, 16):
6251
    case FOP(62, 16):
6252
    case FOP(63, 16):
6253
        {
6254
            TCGv_i32 fp0 = tcg_temp_new_i32();
6255
            TCGv_i32 fp1 = tcg_temp_new_i32();
6256

    
6257
            gen_load_fpr32(fp0, fs);
6258
            gen_load_fpr32(fp1, ft);
6259
            if (ctx->opcode & (1 << 6)) {
6260
                check_cop1x(ctx);
6261
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6262
                opn = condnames_abs[func-48];
6263
            } else {
6264
                gen_cmp_s(func-48, fp0, fp1, cc);
6265
                opn = condnames[func-48];
6266
            }
6267
            tcg_temp_free_i32(fp0);
6268
            tcg_temp_free_i32(fp1);
6269
        }
6270
        break;
6271
    case FOP(0, 17):
6272
        check_cp1_registers(ctx, fs | ft | fd);
6273
        {
6274
            TCGv_i64 fp0 = tcg_temp_new_i64();
6275
            TCGv_i64 fp1 = tcg_temp_new_i64();
6276

    
6277
            gen_load_fpr64(ctx, fp0, fs);
6278
            gen_load_fpr64(ctx, fp1, ft);
6279
            gen_helper_float_add_d(fp0, fp0, fp1);
6280
            tcg_temp_free_i64(fp1);
6281
            gen_store_fpr64(ctx, fp0, fd);
6282
            tcg_temp_free_i64(fp0);
6283
        }
6284
        opn = "add.d";
6285
        optype = BINOP;
6286
        break;
6287
    case FOP(1, 17):
6288
        check_cp1_registers(ctx, fs | ft | fd);
6289
        {
6290
            TCGv_i64 fp0 = tcg_temp_new_i64();
6291
            TCGv_i64 fp1 = tcg_temp_new_i64();
6292

    
6293
            gen_load_fpr64(ctx, fp0, fs);
6294
            gen_load_fpr64(ctx, fp1, ft);
6295
            gen_helper_float_sub_d(fp0, fp0, fp1);
6296
            tcg_temp_free_i64(fp1);
6297
            gen_store_fpr64(ctx, fp0, fd);
6298
            tcg_temp_free_i64(fp0);
6299
        }
6300
        opn = "sub.d";
6301
        optype = BINOP;
6302
        break;
6303
    case FOP(2, 17):
6304
        check_cp1_registers(ctx, fs | ft | fd);
6305
        {
6306
            TCGv_i64 fp0 = tcg_temp_new_i64();
6307
            TCGv_i64 fp1 = tcg_temp_new_i64();
6308

    
6309
            gen_load_fpr64(ctx, fp0, fs);
6310
            gen_load_fpr64(ctx, fp1, ft);
6311
            gen_helper_float_mul_d(fp0, fp0, fp1);
6312
            tcg_temp_free_i64(fp1);
6313
            gen_store_fpr64(ctx, fp0, fd);
6314
            tcg_temp_free_i64(fp0);
6315
        }
6316
        opn = "mul.d";
6317
        optype = BINOP;
6318
        break;
6319
    case FOP(3, 17):
6320
        check_cp1_registers(ctx, fs | ft | fd);
6321
        {
6322
            TCGv_i64 fp0 = tcg_temp_new_i64();
6323
            TCGv_i64 fp1 = tcg_temp_new_i64();
6324

    
6325
            gen_load_fpr64(ctx, fp0, fs);
6326
            gen_load_fpr64(ctx, fp1, ft);
6327
            gen_helper_float_div_d(fp0, fp0, fp1);
6328
            tcg_temp_free_i64(fp1);
6329
            gen_store_fpr64(ctx, fp0, fd);
6330
            tcg_temp_free_i64(fp0);
6331
        }
6332
        opn = "div.d";
6333
        optype = BINOP;
6334
        break;
6335
    case FOP(4, 17):
6336
        check_cp1_registers(ctx, fs | fd);
6337
        {
6338
            TCGv_i64 fp0 = tcg_temp_new_i64();
6339

    
6340
            gen_load_fpr64(ctx, fp0, fs);
6341
            gen_helper_float_sqrt_d(fp0, fp0);
6342
            gen_store_fpr64(ctx, fp0, fd);
6343
            tcg_temp_free_i64(fp0);
6344
        }
6345
        opn = "sqrt.d";
6346
        break;
6347
    case FOP(5, 17):
6348
        check_cp1_registers(ctx, fs | fd);
6349
        {
6350
            TCGv_i64 fp0 = tcg_temp_new_i64();
6351

    
6352
            gen_load_fpr64(ctx, fp0, fs);
6353
            gen_helper_float_abs_d(fp0, fp0);
6354
            gen_store_fpr64(ctx, fp0, fd);
6355
            tcg_temp_free_i64(fp0);
6356
        }
6357
        opn = "abs.d";
6358
        break;
6359
    case FOP(6, 17):
6360
        check_cp1_registers(ctx, fs | fd);
6361
        {
6362
            TCGv_i64 fp0 = tcg_temp_new_i64();
6363

    
6364
            gen_load_fpr64(ctx, fp0, fs);
6365
            gen_store_fpr64(ctx, fp0, fd);
6366
            tcg_temp_free_i64(fp0);
6367
        }
6368
        opn = "mov.d";
6369
        break;
6370
    case FOP(7, 17):
6371
        check_cp1_registers(ctx, fs | fd);
6372
        {
6373
            TCGv_i64 fp0 = tcg_temp_new_i64();
6374

    
6375
            gen_load_fpr64(ctx, fp0, fs);
6376
            gen_helper_float_chs_d(fp0, fp0);
6377
            gen_store_fpr64(ctx, fp0, fd);
6378
            tcg_temp_free_i64(fp0);
6379
        }
6380
        opn = "neg.d";
6381
        break;
6382
    case FOP(8, 17):
6383
        check_cp1_64bitmode(ctx);
6384
        {
6385
            TCGv_i64 fp0 = tcg_temp_new_i64();
6386

    
6387
            gen_load_fpr64(ctx, fp0, fs);
6388
            gen_helper_float_roundl_d(fp0, fp0);
6389
            gen_store_fpr64(ctx, fp0, fd);
6390
            tcg_temp_free_i64(fp0);
6391
        }
6392
        opn = "round.l.d";
6393
        break;
6394
    case FOP(9, 17):
6395
        check_cp1_64bitmode(ctx);
6396
        {
6397
            TCGv_i64 fp0 = tcg_temp_new_i64();
6398

    
6399
            gen_load_fpr64(ctx, fp0, fs);
6400
            gen_helper_float_truncl_d(fp0, fp0);
6401
            gen_store_fpr64(ctx, fp0, fd);
6402
            tcg_temp_free_i64(fp0);
6403
        }
6404
        opn = "trunc.l.d";
6405
        break;
6406
    case FOP(10, 17):
6407
        check_cp1_64bitmode(ctx);
6408
        {
6409
            TCGv_i64 fp0 = tcg_temp_new_i64();
6410

    
6411
            gen_load_fpr64(ctx, fp0, fs);
6412
            gen_helper_float_ceill_d(fp0, fp0);
6413
            gen_store_fpr64(ctx, fp0, fd);
6414
            tcg_temp_free_i64(fp0);
6415
        }
6416
        opn = "ceil.l.d";
6417
        break;
6418
    case FOP(11, 17):
6419
        check_cp1_64bitmode(ctx);
6420
        {
6421
            TCGv_i64 fp0 = tcg_temp_new_i64();
6422

    
6423
            gen_load_fpr64(ctx, fp0, fs);
6424
            gen_helper_float_floorl_d(fp0, fp0);
6425
            gen_store_fpr64(ctx, fp0, fd);
6426
            tcg_temp_free_i64(fp0);
6427
        }
6428
        opn = "floor.l.d";
6429
        break;
6430
    case FOP(12, 17):
6431
        check_cp1_registers(ctx, fs);
6432
        {
6433
            TCGv_i32 fp32 = tcg_temp_new_i32();
6434
            TCGv_i64 fp64 = tcg_temp_new_i64();
6435

    
6436
            gen_load_fpr64(ctx, fp64, fs);
6437
            gen_helper_float_roundw_d(fp32, fp64);
6438
            tcg_temp_free_i64(fp64);
6439
            gen_store_fpr32(fp32, fd);
6440
            tcg_temp_free_i32(fp32);
6441
        }
6442
        opn = "round.w.d";
6443
        break;
6444
    case FOP(13, 17):
6445
        check_cp1_registers(ctx, fs);
6446
        {
6447
            TCGv_i32 fp32 = tcg_temp_new_i32();
6448
            TCGv_i64 fp64 = tcg_temp_new_i64();
6449

    
6450
            gen_load_fpr64(ctx, fp64, fs);
6451
            gen_helper_float_truncw_d(fp32, fp64);
6452
            tcg_temp_free_i64(fp64);
6453
            gen_store_fpr32(fp32, fd);
6454
            tcg_temp_free_i32(fp32);
6455
        }
6456
        opn = "trunc.w.d";
6457
        break;
6458
    case FOP(14, 17):
6459
        check_cp1_registers(ctx, fs);
6460
        {
6461
            TCGv_i32 fp32 = tcg_temp_new_i32();
6462
            TCGv_i64 fp64 = tcg_temp_new_i64();
6463

    
6464
            gen_load_fpr64(ctx, fp64, fs);
6465
            gen_helper_float_ceilw_d(fp32, fp64);
6466
            tcg_temp_free_i64(fp64);
6467
            gen_store_fpr32(fp32, fd);
6468
            tcg_temp_free_i32(fp32);
6469
        }
6470
        opn = "ceil.w.d";
6471
        break;
6472
    case FOP(15, 17):
6473
        check_cp1_registers(ctx, fs);
6474
        {
6475
            TCGv_i32 fp32 = tcg_temp_new_i32();
6476
            TCGv_i64 fp64 = tcg_temp_new_i64();
6477

    
6478
            gen_load_fpr64(ctx, fp64, fs);
6479
            gen_helper_float_floorw_d(fp32, fp64);
6480
            tcg_temp_free_i64(fp64);
6481
            gen_store_fpr32(fp32, fd);
6482
            tcg_temp_free_i32(fp32);
6483
        }
6484
        opn = "floor.w.d";
6485
        break;
6486
    case FOP(17, 17):
6487
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6488
        opn = "movcf.d";
6489
        break;
6490
    case FOP(18, 17):
6491
        {
6492
            int l1 = gen_new_label();
6493
            TCGv t0 = tcg_temp_new();
6494
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6495

    
6496
            gen_load_gpr(t0, ft);
6497
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6498
            gen_load_fpr64(ctx, fp0, fs);
6499
            gen_store_fpr64(ctx, fp0, fd);
6500
            tcg_temp_free_i64(fp0);
6501
            gen_set_label(l1);
6502
            tcg_temp_free(t0);
6503
        }
6504
        opn = "movz.d";
6505
        break;
6506
    case FOP(19, 17):
6507
        {
6508
            int l1 = gen_new_label();
6509
            TCGv t0 = tcg_temp_new();
6510
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6511

    
6512
            gen_load_gpr(t0, ft);
6513
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6514
            gen_load_fpr64(ctx, fp0, fs);
6515
            gen_store_fpr64(ctx, fp0, fd);
6516
            tcg_temp_free_i64(fp0);
6517
            gen_set_label(l1);
6518
            tcg_temp_free(t0);
6519
        }
6520
        opn = "movn.d";
6521
        break;
6522
    case FOP(21, 17):
6523
        check_cp1_64bitmode(ctx);
6524
        {
6525
            TCGv_i64 fp0 = tcg_temp_new_i64();
6526

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

    
6539
            gen_load_fpr64(ctx, fp0, fs);
6540
            gen_helper_float_rsqrt_d(fp0, fp0);
6541
            gen_store_fpr64(ctx, fp0, fd);
6542
            tcg_temp_free_i64(fp0);
6543
        }
6544
        opn = "rsqrt.d";
6545
        break;
6546
    case FOP(28, 17):
6547
        check_cp1_64bitmode(ctx);
6548
        {
6549
            TCGv_i64 fp0 = tcg_temp_new_i64();
6550
            TCGv_i64 fp1 = tcg_temp_new_i64();
6551

    
6552
            gen_load_fpr64(ctx, fp0, fs);
6553
            gen_load_fpr64(ctx, fp1, ft);
6554
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6555
            tcg_temp_free_i64(fp1);
6556
            gen_store_fpr64(ctx, fp0, fd);
6557
            tcg_temp_free_i64(fp0);
6558
        }
6559
        opn = "recip2.d";
6560
        break;
6561
    case FOP(29, 17):
6562
        check_cp1_64bitmode(ctx);
6563
        {
6564
            TCGv_i64 fp0 = tcg_temp_new_i64();
6565

    
6566
            gen_load_fpr64(ctx, fp0, fs);
6567
            gen_helper_float_recip1_d(fp0, fp0);
6568
            gen_store_fpr64(ctx, fp0, fd);
6569
            tcg_temp_free_i64(fp0);
6570
        }
6571
        opn = "recip1.d";
6572
        break;
6573
    case FOP(30, 17):
6574
        check_cp1_64bitmode(ctx);
6575
        {
6576
            TCGv_i64 fp0 = tcg_temp_new_i64();
6577

    
6578
            gen_load_fpr64(ctx, fp0, fs);
6579
            gen_helper_float_rsqrt1_d(fp0, fp0);
6580
            gen_store_fpr64(ctx, fp0, fd);
6581
            tcg_temp_free_i64(fp0);
6582
        }
6583
        opn = "rsqrt1.d";
6584
        break;
6585
    case FOP(31, 17):
6586
        check_cp1_64bitmode(ctx);
6587
        {
6588
            TCGv_i64 fp0 = tcg_temp_new_i64();
6589
            TCGv_i64 fp1 = tcg_temp_new_i64();
6590

    
6591
            gen_load_fpr64(ctx, fp0, fs);
6592
            gen_load_fpr64(ctx, fp1, ft);
6593
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6594
            tcg_temp_free_i64(fp1);
6595
            gen_store_fpr64(ctx, fp0, fd);
6596
            tcg_temp_free_i64(fp0);
6597
        }
6598
        opn = "rsqrt2.d";
6599
        break;
6600
    case FOP(48, 17):
6601
    case FOP(49, 17):
6602
    case FOP(50, 17):
6603
    case FOP(51, 17):
6604
    case FOP(52, 17):
6605
    case FOP(53, 17):
6606
    case FOP(54, 17):
6607
    case FOP(55, 17):
6608
    case FOP(56, 17):
6609
    case FOP(57, 17):
6610
    case FOP(58, 17):
6611
    case FOP(59, 17):
6612
    case FOP(60, 17):
6613
    case FOP(61, 17):
6614
    case FOP(62, 17):
6615
    case FOP(63, 17):
6616
        {
6617
            TCGv_i64 fp0 = tcg_temp_new_i64();
6618
            TCGv_i64 fp1 = tcg_temp_new_i64();
6619

    
6620
            gen_load_fpr64(ctx, fp0, fs);
6621
            gen_load_fpr64(ctx, fp1, ft);
6622
            if (ctx->opcode & (1 << 6)) {
6623
                check_cop1x(ctx);
6624
                check_cp1_registers(ctx, fs | ft);
6625
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6626
                opn = condnames_abs[func-48];
6627
            } else {
6628
                check_cp1_registers(ctx, fs | ft);
6629
                gen_cmp_d(func-48, fp0, fp1, cc);
6630
                opn = condnames[func-48];
6631
            }
6632
            tcg_temp_free_i64(fp0);
6633
            tcg_temp_free_i64(fp1);
6634
        }
6635
        break;
6636
    case FOP(32, 17):
6637
        check_cp1_registers(ctx, fs);
6638
        {
6639
            TCGv_i32 fp32 = tcg_temp_new_i32();
6640
            TCGv_i64 fp64 = tcg_temp_new_i64();
6641

    
6642
            gen_load_fpr64(ctx, fp64, fs);
6643
            gen_helper_float_cvts_d(fp32, fp64);
6644
            tcg_temp_free_i64(fp64);
6645
            gen_store_fpr32(fp32, fd);
6646
            tcg_temp_free_i32(fp32);
6647
        }
6648
        opn = "cvt.s.d";
6649
        break;
6650
    case FOP(36, 17):
6651
        check_cp1_registers(ctx, fs);
6652
        {
6653
            TCGv_i32 fp32 = tcg_temp_new_i32();
6654
            TCGv_i64 fp64 = tcg_temp_new_i64();
6655

    
6656
            gen_load_fpr64(ctx, fp64, fs);
6657
            gen_helper_float_cvtw_d(fp32, fp64);
6658
            tcg_temp_free_i64(fp64);
6659
            gen_store_fpr32(fp32, fd);
6660
            tcg_temp_free_i32(fp32);
6661
        }
6662
        opn = "cvt.w.d";
6663
        break;
6664
    case FOP(37, 17):
6665
        check_cp1_64bitmode(ctx);
6666
        {
6667
            TCGv_i64 fp0 = tcg_temp_new_i64();
6668

    
6669
            gen_load_fpr64(ctx, fp0, fs);
6670
            gen_helper_float_cvtl_d(fp0, fp0);
6671
            gen_store_fpr64(ctx, fp0, fd);
6672
            tcg_temp_free_i64(fp0);
6673
        }
6674
        opn = "cvt.l.d";
6675
        break;
6676
    case FOP(32, 20):
6677
        {
6678
            TCGv_i32 fp0 = tcg_temp_new_i32();
6679

    
6680
            gen_load_fpr32(fp0, fs);
6681
            gen_helper_float_cvts_w(fp0, fp0);
6682
            gen_store_fpr32(fp0, fd);
6683
            tcg_temp_free_i32(fp0);
6684
        }
6685
        opn = "cvt.s.w";
6686
        break;
6687
    case FOP(33, 20):
6688
        check_cp1_registers(ctx, fd);
6689
        {
6690
            TCGv_i32 fp32 = tcg_temp_new_i32();
6691
            TCGv_i64 fp64 = tcg_temp_new_i64();
6692

    
6693
            gen_load_fpr32(fp32, fs);
6694
            gen_helper_float_cvtd_w(fp64, fp32);
6695
            tcg_temp_free_i32(fp32);
6696
            gen_store_fpr64(ctx, fp64, fd);
6697
            tcg_temp_free_i64(fp64);
6698
        }
6699
        opn = "cvt.d.w";
6700
        break;
6701
    case FOP(32, 21):
6702
        check_cp1_64bitmode(ctx);
6703
        {
6704
            TCGv_i32 fp32 = tcg_temp_new_i32();
6705
            TCGv_i64 fp64 = tcg_temp_new_i64();
6706

    
6707
            gen_load_fpr64(ctx, fp64, fs);
6708
            gen_helper_float_cvts_l(fp32, fp64);
6709
            tcg_temp_free_i64(fp64);
6710
            gen_store_fpr32(fp32, fd);
6711
            tcg_temp_free_i32(fp32);
6712
        }
6713
        opn = "cvt.s.l";
6714
        break;
6715
    case FOP(33, 21):
6716
        check_cp1_64bitmode(ctx);
6717
        {
6718
            TCGv_i64 fp0 = tcg_temp_new_i64();
6719

    
6720
            gen_load_fpr64(ctx, fp0, fs);
6721
            gen_helper_float_cvtd_l(fp0, fp0);
6722
            gen_store_fpr64(ctx, fp0, fd);
6723
            tcg_temp_free_i64(fp0);
6724
        }
6725
        opn = "cvt.d.l";
6726
        break;
6727
    case FOP(38, 20):
6728
        check_cp1_64bitmode(ctx);
6729
        {
6730
            TCGv_i64 fp0 = tcg_temp_new_i64();
6731

    
6732
            gen_load_fpr64(ctx, fp0, fs);
6733
            gen_helper_float_cvtps_pw(fp0, fp0);
6734
            gen_store_fpr64(ctx, fp0, fd);
6735
            tcg_temp_free_i64(fp0);
6736
        }
6737
        opn = "cvt.ps.pw";
6738
        break;
6739
    case FOP(0, 22):
6740
        check_cp1_64bitmode(ctx);
6741
        {
6742
            TCGv_i64 fp0 = tcg_temp_new_i64();
6743
            TCGv_i64 fp1 = tcg_temp_new_i64();
6744

    
6745
            gen_load_fpr64(ctx, fp0, fs);
6746
            gen_load_fpr64(ctx, fp1, ft);
6747
            gen_helper_float_add_ps(fp0, fp0, fp1);
6748
            tcg_temp_free_i64(fp1);
6749
            gen_store_fpr64(ctx, fp0, fd);
6750
            tcg_temp_free_i64(fp0);
6751
        }
6752
        opn = "add.ps";
6753
        break;
6754
    case FOP(1, 22):
6755
        check_cp1_64bitmode(ctx);
6756
        {
6757
            TCGv_i64 fp0 = tcg_temp_new_i64();
6758
            TCGv_i64 fp1 = tcg_temp_new_i64();
6759

    
6760
            gen_load_fpr64(ctx, fp0, fs);
6761
            gen_load_fpr64(ctx, fp1, ft);
6762
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6763
            tcg_temp_free_i64(fp1);
6764
            gen_store_fpr64(ctx, fp0, fd);
6765
            tcg_temp_free_i64(fp0);
6766
        }
6767
        opn = "sub.ps";
6768
        break;
6769
    case FOP(2, 22):
6770
        check_cp1_64bitmode(ctx);
6771
        {
6772
            TCGv_i64 fp0 = tcg_temp_new_i64();
6773
            TCGv_i64 fp1 = tcg_temp_new_i64();
6774

    
6775
            gen_load_fpr64(ctx, fp0, fs);
6776
            gen_load_fpr64(ctx, fp1, ft);
6777
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6778
            tcg_temp_free_i64(fp1);
6779
            gen_store_fpr64(ctx, fp0, fd);
6780
            tcg_temp_free_i64(fp0);
6781
        }
6782
        opn = "mul.ps";
6783
        break;
6784
    case FOP(5, 22):
6785
        check_cp1_64bitmode(ctx);
6786
        {
6787
            TCGv_i64 fp0 = tcg_temp_new_i64();
6788

    
6789
            gen_load_fpr64(ctx, fp0, fs);
6790
            gen_helper_float_abs_ps(fp0, fp0);
6791
            gen_store_fpr64(ctx, fp0, fd);
6792
            tcg_temp_free_i64(fp0);
6793
        }
6794
        opn = "abs.ps";
6795
        break;
6796
    case FOP(6, 22):
6797
        check_cp1_64bitmode(ctx);
6798
        {
6799
            TCGv_i64 fp0 = tcg_temp_new_i64();
6800

    
6801
            gen_load_fpr64(ctx, fp0, fs);
6802
            gen_store_fpr64(ctx, fp0, fd);
6803
            tcg_temp_free_i64(fp0);
6804
        }
6805
        opn = "mov.ps";
6806
        break;
6807
    case FOP(7, 22):
6808
        check_cp1_64bitmode(ctx);
6809
        {
6810
            TCGv_i64 fp0 = tcg_temp_new_i64();
6811

    
6812
            gen_load_fpr64(ctx, fp0, fs);
6813
            gen_helper_float_chs_ps(fp0, fp0);
6814
            gen_store_fpr64(ctx, fp0, fd);
6815
            tcg_temp_free_i64(fp0);
6816
        }
6817
        opn = "neg.ps";
6818
        break;
6819
    case FOP(17, 22):
6820
        check_cp1_64bitmode(ctx);
6821
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6822
        opn = "movcf.ps";
6823
        break;
6824
    case FOP(18, 22):
6825
        check_cp1_64bitmode(ctx);
6826
        {
6827
            int l1 = gen_new_label();
6828
            TCGv t0 = tcg_temp_new();
6829
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6830
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6831

    
6832
            gen_load_gpr(t0, ft);
6833
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6834
            gen_load_fpr32(fp0, fs);
6835
            gen_load_fpr32h(fph0, fs);
6836
            gen_store_fpr32(fp0, fd);
6837
            gen_store_fpr32h(fph0, fd);
6838
            tcg_temp_free_i32(fp0);
6839
            tcg_temp_free_i32(fph0);
6840
            gen_set_label(l1);
6841
            tcg_temp_free(t0);
6842
        }
6843
        opn = "movz.ps";
6844
        break;
6845
    case FOP(19, 22):
6846
        check_cp1_64bitmode(ctx);
6847
        {
6848
            int l1 = gen_new_label();
6849
            TCGv t0 = tcg_temp_new();
6850
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6851
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6852

    
6853
            gen_load_gpr(t0, ft);
6854
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6855
            gen_load_fpr32(fp0, fs);
6856
            gen_load_fpr32h(fph0, fs);
6857
            gen_store_fpr32(fp0, fd);
6858
            gen_store_fpr32h(fph0, fd);
6859
            tcg_temp_free_i32(fp0);
6860
            tcg_temp_free_i32(fph0);
6861
            gen_set_label(l1);
6862
            tcg_temp_free(t0);
6863
        }
6864
        opn = "movn.ps";
6865
        break;
6866
    case FOP(24, 22):
6867
        check_cp1_64bitmode(ctx);
6868
        {
6869
            TCGv_i64 fp0 = tcg_temp_new_i64();
6870
            TCGv_i64 fp1 = tcg_temp_new_i64();
6871

    
6872
            gen_load_fpr64(ctx, fp0, ft);
6873
            gen_load_fpr64(ctx, fp1, fs);
6874
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6875
            tcg_temp_free_i64(fp1);
6876
            gen_store_fpr64(ctx, fp0, fd);
6877
            tcg_temp_free_i64(fp0);
6878
        }
6879
        opn = "addr.ps";
6880
        break;
6881
    case FOP(26, 22):
6882
        check_cp1_64bitmode(ctx);
6883
        {
6884
            TCGv_i64 fp0 = tcg_temp_new_i64();
6885
            TCGv_i64 fp1 = tcg_temp_new_i64();
6886

    
6887
            gen_load_fpr64(ctx, fp0, ft);
6888
            gen_load_fpr64(ctx, fp1, fs);
6889
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6890
            tcg_temp_free_i64(fp1);
6891
            gen_store_fpr64(ctx, fp0, fd);
6892
            tcg_temp_free_i64(fp0);
6893
        }
6894
        opn = "mulr.ps";
6895
        break;
6896
    case FOP(28, 22):
6897
        check_cp1_64bitmode(ctx);
6898
        {
6899
            TCGv_i64 fp0 = tcg_temp_new_i64();
6900
            TCGv_i64 fp1 = tcg_temp_new_i64();
6901

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

    
6916
            gen_load_fpr64(ctx, fp0, fs);
6917
            gen_helper_float_recip1_ps(fp0, fp0);
6918
            gen_store_fpr64(ctx, fp0, fd);
6919
            tcg_temp_free_i64(fp0);
6920
        }
6921
        opn = "recip1.ps";
6922
        break;
6923
    case FOP(30, 22):
6924
        check_cp1_64bitmode(ctx);
6925
        {
6926
            TCGv_i64 fp0 = tcg_temp_new_i64();
6927

    
6928
            gen_load_fpr64(ctx, fp0, fs);
6929
            gen_helper_float_rsqrt1_ps(fp0, fp0);
6930
            gen_store_fpr64(ctx, fp0, fd);
6931
            tcg_temp_free_i64(fp0);
6932
        }
6933
        opn = "rsqrt1.ps";
6934
        break;
6935
    case FOP(31, 22):
6936
        check_cp1_64bitmode(ctx);
6937
        {
6938
            TCGv_i64 fp0 = tcg_temp_new_i64();
6939
            TCGv_i64 fp1 = tcg_temp_new_i64();
6940

    
6941
            gen_load_fpr64(ctx, fp0, fs);
6942
            gen_load_fpr64(ctx, fp1, ft);
6943
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
6944
            tcg_temp_free_i64(fp1);
6945
            gen_store_fpr64(ctx, fp0, fd);
6946
            tcg_temp_free_i64(fp0);
6947
        }
6948
        opn = "rsqrt2.ps";
6949
        break;
6950
    case FOP(32, 22):
6951
        check_cp1_64bitmode(ctx);
6952
        {
6953
            TCGv_i32 fp0 = tcg_temp_new_i32();
6954

    
6955
            gen_load_fpr32h(fp0, fs);
6956
            gen_helper_float_cvts_pu(fp0, fp0);
6957
            gen_store_fpr32(fp0, fd);
6958
            tcg_temp_free_i32(fp0);
6959
        }
6960
        opn = "cvt.s.pu";
6961
        break;
6962
    case FOP(36, 22):
6963
        check_cp1_64bitmode(ctx);
6964
        {
6965
            TCGv_i64 fp0 = tcg_temp_new_i64();
6966

    
6967
            gen_load_fpr64(ctx, fp0, fs);
6968
            gen_helper_float_cvtpw_ps(fp0, fp0);
6969
            gen_store_fpr64(ctx, fp0, fd);
6970
            tcg_temp_free_i64(fp0);
6971
        }
6972
        opn = "cvt.pw.ps";
6973
        break;
6974
    case FOP(40, 22):
6975
        check_cp1_64bitmode(ctx);
6976
        {
6977
            TCGv_i32 fp0 = tcg_temp_new_i32();
6978

    
6979
            gen_load_fpr32(fp0, fs);
6980
            gen_helper_float_cvts_pl(fp0, fp0);
6981
            gen_store_fpr32(fp0, fd);
6982
            tcg_temp_free_i32(fp0);
6983
        }
6984
        opn = "cvt.s.pl";
6985
        break;
6986
    case FOP(44, 22):
6987
        check_cp1_64bitmode(ctx);
6988
        {
6989
            TCGv_i32 fp0 = tcg_temp_new_i32();
6990
            TCGv_i32 fp1 = tcg_temp_new_i32();
6991

    
6992
            gen_load_fpr32(fp0, fs);
6993
            gen_load_fpr32(fp1, ft);
6994
            gen_store_fpr32h(fp0, fd);
6995
            gen_store_fpr32(fp1, fd);
6996
            tcg_temp_free_i32(fp0);
6997
            tcg_temp_free_i32(fp1);
6998
        }
6999
        opn = "pll.ps";
7000
        break;
7001
    case FOP(45, 22):
7002
        check_cp1_64bitmode(ctx);
7003
        {
7004
            TCGv_i32 fp0 = tcg_temp_new_i32();
7005
            TCGv_i32 fp1 = tcg_temp_new_i32();
7006

    
7007
            gen_load_fpr32(fp0, fs);
7008
            gen_load_fpr32h(fp1, ft);
7009
            gen_store_fpr32(fp1, fd);
7010
            gen_store_fpr32h(fp0, fd);
7011
            tcg_temp_free_i32(fp0);
7012
            tcg_temp_free_i32(fp1);
7013
        }
7014
        opn = "plu.ps";
7015
        break;
7016
    case FOP(46, 22):
7017
        check_cp1_64bitmode(ctx);
7018
        {
7019
            TCGv_i32 fp0 = tcg_temp_new_i32();
7020
            TCGv_i32 fp1 = tcg_temp_new_i32();
7021

    
7022
            gen_load_fpr32h(fp0, fs);
7023
            gen_load_fpr32(fp1, ft);
7024
            gen_store_fpr32(fp1, fd);
7025
            gen_store_fpr32h(fp0, fd);
7026
            tcg_temp_free_i32(fp0);
7027
            tcg_temp_free_i32(fp1);
7028
        }
7029
        opn = "pul.ps";
7030
        break;
7031
    case FOP(47, 22):
7032
        check_cp1_64bitmode(ctx);
7033
        {
7034
            TCGv_i32 fp0 = tcg_temp_new_i32();
7035
            TCGv_i32 fp1 = tcg_temp_new_i32();
7036

    
7037
            gen_load_fpr32h(fp0, fs);
7038
            gen_load_fpr32h(fp1, ft);
7039
            gen_store_fpr32(fp1, fd);
7040
            gen_store_fpr32h(fp0, fd);
7041
            tcg_temp_free_i32(fp0);
7042
            tcg_temp_free_i32(fp1);
7043
        }
7044
        opn = "puu.ps";
7045
        break;
7046
    case FOP(48, 22):
7047
    case FOP(49, 22):
7048
    case FOP(50, 22):
7049
    case FOP(51, 22):
7050
    case FOP(52, 22):
7051
    case FOP(53, 22):
7052
    case FOP(54, 22):
7053
    case FOP(55, 22):
7054
    case FOP(56, 22):
7055
    case FOP(57, 22):
7056
    case FOP(58, 22):
7057
    case FOP(59, 22):
7058
    case FOP(60, 22):
7059
    case FOP(61, 22):
7060
    case FOP(62, 22):
7061
    case FOP(63, 22):
7062
        check_cp1_64bitmode(ctx);
7063
        {
7064
            TCGv_i64 fp0 = tcg_temp_new_i64();
7065
            TCGv_i64 fp1 = tcg_temp_new_i64();
7066

    
7067
            gen_load_fpr64(ctx, fp0, fs);
7068
            gen_load_fpr64(ctx, fp1, ft);
7069
            if (ctx->opcode & (1 << 6)) {
7070
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7071
                opn = condnames_abs[func-48];
7072
            } else {
7073
                gen_cmp_ps(func-48, fp0, fp1, cc);
7074
                opn = condnames[func-48];
7075
            }
7076
            tcg_temp_free_i64(fp0);
7077
            tcg_temp_free_i64(fp1);
7078
        }
7079
        break;
7080
    default:
7081
        MIPS_INVAL(opn);
7082
        generate_exception (ctx, EXCP_RI);
7083
        return;
7084
    }
7085
    switch (optype) {
7086
    case BINOP:
7087
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7088
        break;
7089
    case CMPOP:
7090
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7091
        break;
7092
    default:
7093
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7094
        break;
7095
    }
7096
}
7097

    
7098
/* Coprocessor 3 (FPU) */
7099
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7100
                           int fd, int fs, int base, int index)
7101
{
7102
    const char *opn = "extended float load/store";
7103
    int store = 0;
7104
    TCGv t0 = tcg_temp_local_new();
7105
    TCGv t1 = tcg_temp_local_new();
7106

    
7107
    if (base == 0) {
7108
        gen_load_gpr(t0, index);
7109
    } else if (index == 0) {
7110
        gen_load_gpr(t0, base);
7111
    } else {
7112
        gen_load_gpr(t0, index);
7113
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7114
    }
7115
    /* Don't do NOP if destination is zero: we must perform the actual
7116
       memory access. */
7117
    switch (opc) {
7118
    case OPC_LWXC1:
7119
        check_cop1x(ctx);
7120
        {
7121
            TCGv_i32 fp0 = tcg_temp_new_i32();
7122

    
7123
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7124
            tcg_gen_trunc_tl_i32(fp0, t1);
7125
            gen_store_fpr32(fp0, fd);
7126
            tcg_temp_free_i32(fp0);
7127
        }
7128
        opn = "lwxc1";
7129
        break;
7130
    case OPC_LDXC1:
7131
        check_cop1x(ctx);
7132
        check_cp1_registers(ctx, fd);
7133
        {
7134
            TCGv_i64 fp0 = tcg_temp_new_i64();
7135

    
7136
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7137
            gen_store_fpr64(ctx, fp0, fd);
7138
            tcg_temp_free_i64(fp0);
7139
        }
7140
        opn = "ldxc1";
7141
        break;
7142
    case OPC_LUXC1:
7143
        check_cp1_64bitmode(ctx);
7144
        tcg_gen_andi_tl(t0, t0, ~0x7);
7145
        {
7146
            TCGv_i64 fp0 = tcg_temp_new_i64();
7147

    
7148
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7149
            gen_store_fpr64(ctx, fp0, fd);
7150
            tcg_temp_free_i64(fp0);
7151
        }
7152
        opn = "luxc1";
7153
        break;
7154
    case OPC_SWXC1:
7155
        check_cop1x(ctx);
7156
        {
7157
            TCGv_i32 fp0 = tcg_temp_new_i32();
7158

    
7159
            gen_load_fpr32(fp0, fs);
7160
            tcg_gen_extu_i32_tl(t1, fp0);
7161
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7162
            tcg_temp_free_i32(fp0);
7163
        }
7164
        opn = "swxc1";
7165
        store = 1;
7166
        break;
7167
    case OPC_SDXC1:
7168
        check_cop1x(ctx);
7169
        check_cp1_registers(ctx, fs);
7170
        {
7171
            TCGv_i64 fp0 = tcg_temp_new_i64();
7172

    
7173
            gen_load_fpr64(ctx, fp0, fs);
7174
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7175
            tcg_temp_free_i64(fp0);
7176
        }
7177
        opn = "sdxc1";
7178
        store = 1;
7179
        break;
7180
    case OPC_SUXC1:
7181
        check_cp1_64bitmode(ctx);
7182
        tcg_gen_andi_tl(t0, t0, ~0x7);
7183
        {
7184
            TCGv_i64 fp0 = tcg_temp_new_i64();
7185

    
7186
            gen_load_fpr64(ctx, fp0, fs);
7187
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7188
            tcg_temp_free_i64(fp0);
7189
        }
7190
        opn = "suxc1";
7191
        store = 1;
7192
        break;
7193
    default:
7194
        MIPS_INVAL(opn);
7195
        generate_exception(ctx, EXCP_RI);
7196
        tcg_temp_free(t0);
7197
        tcg_temp_free(t1);
7198
        return;
7199
    }
7200
    tcg_temp_free(t0);
7201
    tcg_temp_free(t1);
7202
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7203
               regnames[index], regnames[base]);
7204
}
7205

    
7206
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7207
                            int fd, int fr, int fs, int ft)
7208
{
7209
    const char *opn = "flt3_arith";
7210

    
7211
    switch (opc) {
7212
    case OPC_ALNV_PS:
7213
        check_cp1_64bitmode(ctx);
7214
        {
7215
            TCGv t0 = tcg_temp_local_new();
7216
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7217
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7218
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7219
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7220
            int l1 = gen_new_label();
7221
            int l2 = gen_new_label();
7222

    
7223
            gen_load_gpr(t0, fr);
7224
            tcg_gen_andi_tl(t0, t0, 0x7);
7225
            gen_load_fpr32(fp0, fs);
7226
            gen_load_fpr32h(fph0, fs);
7227
            gen_load_fpr32(fp1, ft);
7228
            gen_load_fpr32h(fph1, ft);
7229

    
7230
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7231
            gen_store_fpr32(fp0, fd);
7232
            gen_store_fpr32h(fph0, fd);
7233
            tcg_gen_br(l2);
7234
            gen_set_label(l1);
7235
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7236
            tcg_temp_free(t0);
7237
#ifdef TARGET_WORDS_BIGENDIAN
7238
            gen_store_fpr32(fph1, fd);
7239
            gen_store_fpr32h(fp0, fd);
7240
#else
7241
            gen_store_fpr32(fph0, fd);
7242
            gen_store_fpr32h(fp1, fd);
7243
#endif
7244
            gen_set_label(l2);
7245
            tcg_temp_free_i32(fp0);
7246
            tcg_temp_free_i32(fph0);
7247
            tcg_temp_free_i32(fp1);
7248
            tcg_temp_free_i32(fph1);
7249
        }
7250
        opn = "alnv.ps";
7251
        break;
7252
    case OPC_MADD_S:
7253
        check_cop1x(ctx);
7254
        {
7255
            TCGv_i32 fp0 = tcg_temp_new_i32();
7256
            TCGv_i32 fp1 = tcg_temp_new_i32();
7257
            TCGv_i32 fp2 = tcg_temp_new_i32();
7258

    
7259
            gen_load_fpr32(fp0, fs);
7260
            gen_load_fpr32(fp1, ft);
7261
            gen_load_fpr32(fp2, fr);
7262
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7263
            tcg_temp_free_i32(fp0);
7264
            tcg_temp_free_i32(fp1);
7265
            gen_store_fpr32(fp2, fd);
7266
            tcg_temp_free_i32(fp2);
7267
        }
7268
        opn = "madd.s";
7269
        break;
7270
    case OPC_MADD_D:
7271
        check_cop1x(ctx);
7272
        check_cp1_registers(ctx, fd | fs | ft | fr);
7273
        {
7274
            TCGv_i64 fp0 = tcg_temp_new_i64();
7275
            TCGv_i64 fp1 = tcg_temp_new_i64();
7276
            TCGv_i64 fp2 = tcg_temp_new_i64();
7277

    
7278
            gen_load_fpr64(ctx, fp0, fs);
7279
            gen_load_fpr64(ctx, fp1, ft);
7280
            gen_load_fpr64(ctx, fp2, fr);
7281
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7282
            tcg_temp_free_i64(fp0);
7283
            tcg_temp_free_i64(fp1);
7284
            gen_store_fpr64(ctx, fp2, fd);
7285
            tcg_temp_free_i64(fp2);
7286
        }
7287
        opn = "madd.d";
7288
        break;
7289
    case OPC_MADD_PS:
7290
        check_cp1_64bitmode(ctx);
7291
        {
7292
            TCGv_i64 fp0 = tcg_temp_new_i64();
7293
            TCGv_i64 fp1 = tcg_temp_new_i64();
7294
            TCGv_i64 fp2 = tcg_temp_new_i64();
7295

    
7296
            gen_load_fpr64(ctx, fp0, fs);
7297
            gen_load_fpr64(ctx, fp1, ft);
7298
            gen_load_fpr64(ctx, fp2, fr);
7299
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7300
            tcg_temp_free_i64(fp0);
7301
            tcg_temp_free_i64(fp1);
7302
            gen_store_fpr64(ctx, fp2, fd);
7303
            tcg_temp_free_i64(fp2);
7304
        }
7305
        opn = "madd.ps";
7306
        break;
7307
    case OPC_MSUB_S:
7308
        check_cop1x(ctx);
7309
        {
7310
            TCGv_i32 fp0 = tcg_temp_new_i32();
7311
            TCGv_i32 fp1 = tcg_temp_new_i32();
7312
            TCGv_i32 fp2 = tcg_temp_new_i32();
7313

    
7314
            gen_load_fpr32(fp0, fs);
7315
            gen_load_fpr32(fp1, ft);
7316
            gen_load_fpr32(fp2, fr);
7317
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7318
            tcg_temp_free_i32(fp0);
7319
            tcg_temp_free_i32(fp1);
7320
            gen_store_fpr32(fp2, fd);
7321
            tcg_temp_free_i32(fp2);
7322
        }
7323
        opn = "msub.s";
7324
        break;
7325
    case OPC_MSUB_D:
7326
        check_cop1x(ctx);
7327
        check_cp1_registers(ctx, fd | fs | ft | fr);
7328
        {
7329
            TCGv_i64 fp0 = tcg_temp_new_i64();
7330
            TCGv_i64 fp1 = tcg_temp_new_i64();
7331
            TCGv_i64 fp2 = tcg_temp_new_i64();
7332

    
7333
            gen_load_fpr64(ctx, fp0, fs);
7334
            gen_load_fpr64(ctx, fp1, ft);
7335
            gen_load_fpr64(ctx, fp2, fr);
7336
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7337
            tcg_temp_free_i64(fp0);
7338
            tcg_temp_free_i64(fp1);
7339
            gen_store_fpr64(ctx, fp2, fd);
7340
            tcg_temp_free_i64(fp2);
7341
        }
7342
        opn = "msub.d";
7343
        break;
7344
    case OPC_MSUB_PS:
7345
        check_cp1_64bitmode(ctx);
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_mulsub_ps(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 = "msub.ps";
7361
        break;
7362
    case OPC_NMADD_S:
7363
        check_cop1x(ctx);
7364
        {
7365
            TCGv_i32 fp0 = tcg_temp_new_i32();
7366
            TCGv_i32 fp1 = tcg_temp_new_i32();
7367
            TCGv_i32 fp2 = tcg_temp_new_i32();
7368

    
7369
            gen_load_fpr32(fp0, fs);
7370
            gen_load_fpr32(fp1, ft);
7371
            gen_load_fpr32(fp2, fr);
7372
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7373
            tcg_temp_free_i32(fp0);
7374
            tcg_temp_free_i32(fp1);
7375
            gen_store_fpr32(fp2, fd);
7376
            tcg_temp_free_i32(fp2);
7377
        }
7378
        opn = "nmadd.s";
7379
        break;
7380
    case OPC_NMADD_D:
7381
        check_cop1x(ctx);
7382
        check_cp1_registers(ctx, fd | fs | ft | fr);
7383
        {
7384
            TCGv_i64 fp0 = tcg_temp_new_i64();
7385
            TCGv_i64 fp1 = tcg_temp_new_i64();
7386
            TCGv_i64 fp2 = tcg_temp_new_i64();
7387

    
7388
            gen_load_fpr64(ctx, fp0, fs);
7389
            gen_load_fpr64(ctx, fp1, ft);
7390
            gen_load_fpr64(ctx, fp2, fr);
7391
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7392
            tcg_temp_free_i64(fp0);
7393
            tcg_temp_free_i64(fp1);
7394
            gen_store_fpr64(ctx, fp2, fd);
7395
            tcg_temp_free_i64(fp2);
7396
        }
7397
        opn = "nmadd.d";
7398
        break;
7399
    case OPC_NMADD_PS:
7400
        check_cp1_64bitmode(ctx);
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_nmuladd_ps(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 = "nmadd.ps";
7416
        break;
7417
    case OPC_NMSUB_S:
7418
        check_cop1x(ctx);
7419
        {
7420
            TCGv_i32 fp0 = tcg_temp_new_i32();
7421
            TCGv_i32 fp1 = tcg_temp_new_i32();
7422
            TCGv_i32 fp2 = tcg_temp_new_i32();
7423

    
7424
            gen_load_fpr32(fp0, fs);
7425
            gen_load_fpr32(fp1, ft);
7426
            gen_load_fpr32(fp2, fr);
7427
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7428
            tcg_temp_free_i32(fp0);
7429
            tcg_temp_free_i32(fp1);
7430
            gen_store_fpr32(fp2, fd);
7431
            tcg_temp_free_i32(fp2);
7432
        }
7433
        opn = "nmsub.s";
7434
        break;
7435
    case OPC_NMSUB_D:
7436
        check_cop1x(ctx);
7437
        check_cp1_registers(ctx, fd | fs | ft | fr);
7438
        {
7439
            TCGv_i64 fp0 = tcg_temp_new_i64();
7440
            TCGv_i64 fp1 = tcg_temp_new_i64();
7441
            TCGv_i64 fp2 = tcg_temp_new_i64();
7442

    
7443
            gen_load_fpr64(ctx, fp0, fs);
7444
            gen_load_fpr64(ctx, fp1, ft);
7445
            gen_load_fpr64(ctx, fp2, fr);
7446
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7447
            tcg_temp_free_i64(fp0);
7448
            tcg_temp_free_i64(fp1);
7449
            gen_store_fpr64(ctx, fp2, fd);
7450
            tcg_temp_free_i64(fp2);
7451
        }
7452
        opn = "nmsub.d";
7453
        break;
7454
    case OPC_NMSUB_PS:
7455
        check_cp1_64bitmode(ctx);
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_nmulsub_ps(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 = "nmsub.ps";
7471
        break;
7472
    default:
7473
        MIPS_INVAL(opn);
7474
        generate_exception (ctx, EXCP_RI);
7475
        return;
7476
    }
7477
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7478
               fregnames[fs], fregnames[ft]);
7479
}
7480

    
7481
/* ISA extensions (ASEs) */
7482
/* MIPS16 extension to MIPS32 */
7483
/* SmartMIPS extension to MIPS32 */
7484

    
7485
#if defined(TARGET_MIPS64)
7486

    
7487
/* MDMX extension to MIPS64 */
7488

    
7489
#endif
7490

    
7491
static void decode_opc (CPUState *env, DisasContext *ctx)
7492
{
7493
    int32_t offset;
7494
    int rs, rt, rd, sa;
7495
    uint32_t op, op1, op2;
7496
    int16_t imm;
7497

    
7498
    /* make sure instructions are on a word boundary */
7499
    if (ctx->pc & 0x3) {
7500
        env->CP0_BadVAddr = ctx->pc;
7501
        generate_exception(ctx, EXCP_AdEL);
7502
        return;
7503
    }
7504

    
7505
    /* Handle blikely not taken case */
7506
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7507
        int l1 = gen_new_label();
7508

    
7509
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7510
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7511
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7512
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7513
        gen_set_label(l1);
7514
    }
7515
    op = MASK_OP_MAJOR(ctx->opcode);
7516
    rs = (ctx->opcode >> 21) & 0x1f;
7517
    rt = (ctx->opcode >> 16) & 0x1f;
7518
    rd = (ctx->opcode >> 11) & 0x1f;
7519
    sa = (ctx->opcode >> 6) & 0x1f;
7520
    imm = (int16_t)ctx->opcode;
7521
    switch (op) {
7522
    case OPC_SPECIAL:
7523
        op1 = MASK_SPECIAL(ctx->opcode);
7524
        switch (op1) {
7525
        case OPC_SLL:          /* Arithmetic with immediate */
7526
        case OPC_SRL ... OPC_SRA:
7527
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7528
            break;
7529
        case OPC_MOVZ ... OPC_MOVN:
7530
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7531
        case OPC_SLLV:         /* Arithmetic */
7532
        case OPC_SRLV ... OPC_SRAV:
7533
        case OPC_ADD ... OPC_NOR:
7534
        case OPC_SLT ... OPC_SLTU:
7535
            gen_arith(env, ctx, op1, rd, rs, rt);
7536
            break;
7537
        case OPC_MULT ... OPC_DIVU:
7538
            if (sa) {
7539
                check_insn(env, ctx, INSN_VR54XX);
7540
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7541
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7542
            } else
7543
                gen_muldiv(ctx, op1, rs, rt);
7544
            break;
7545
        case OPC_JR ... OPC_JALR:
7546
            gen_compute_branch(ctx, op1, rs, rd, sa);
7547
            return;
7548
        case OPC_TGE ... OPC_TEQ: /* Traps */
7549
        case OPC_TNE:
7550
            gen_trap(ctx, op1, rs, rt, -1);
7551
            break;
7552
        case OPC_MFHI:          /* Move from HI/LO */
7553
        case OPC_MFLO:
7554
            gen_HILO(ctx, op1, rd);
7555
            break;
7556
        case OPC_MTHI:
7557
        case OPC_MTLO:          /* Move to HI/LO */
7558
            gen_HILO(ctx, op1, rs);
7559
            break;
7560
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7561
#ifdef MIPS_STRICT_STANDARD
7562
            MIPS_INVAL("PMON / selsl");
7563
            generate_exception(ctx, EXCP_RI);
7564
#else
7565
            gen_helper_0i(pmon, sa);
7566
#endif
7567
            break;
7568
        case OPC_SYSCALL:
7569
            generate_exception(ctx, EXCP_SYSCALL);
7570
            break;
7571
        case OPC_BREAK:
7572
            generate_exception(ctx, EXCP_BREAK);
7573
            break;
7574
        case OPC_SPIM:
7575
#ifdef MIPS_STRICT_STANDARD
7576
            MIPS_INVAL("SPIM");
7577
            generate_exception(ctx, EXCP_RI);
7578
#else
7579
           /* Implemented as RI exception for now. */
7580
            MIPS_INVAL("spim (unofficial)");
7581
            generate_exception(ctx, EXCP_RI);
7582
#endif
7583
            break;
7584
        case OPC_SYNC:
7585
            /* Treat as NOP. */
7586
            break;
7587

    
7588
        case OPC_MOVCI:
7589
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7590
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7591
                save_cpu_state(ctx, 1);
7592
                check_cp1_enabled(ctx);
7593
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7594
                          (ctx->opcode >> 16) & 1);
7595
            } else {
7596
                generate_exception_err(ctx, EXCP_CpU, 1);
7597
            }
7598
            break;
7599

    
7600
#if defined(TARGET_MIPS64)
7601
       /* MIPS64 specific opcodes */
7602
        case OPC_DSLL:
7603
        case OPC_DSRL ... OPC_DSRA:
7604
        case OPC_DSLL32:
7605
        case OPC_DSRL32 ... OPC_DSRA32:
7606
            check_insn(env, ctx, ISA_MIPS3);
7607
            check_mips_64(ctx);
7608
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7609
            break;
7610
        case OPC_DSLLV:
7611
        case OPC_DSRLV ... OPC_DSRAV:
7612
        case OPC_DADD ... OPC_DSUBU:
7613
            check_insn(env, ctx, ISA_MIPS3);
7614
            check_mips_64(ctx);
7615
            gen_arith(env, ctx, op1, rd, rs, rt);
7616
            break;
7617
        case OPC_DMULT ... OPC_DDIVU:
7618
            check_insn(env, ctx, ISA_MIPS3);
7619
            check_mips_64(ctx);
7620
            gen_muldiv(ctx, op1, rs, rt);
7621
            break;
7622
#endif
7623
        default:            /* Invalid */
7624
            MIPS_INVAL("special");
7625
            generate_exception(ctx, EXCP_RI);
7626
            break;
7627
        }
7628
        break;
7629
    case OPC_SPECIAL2:
7630
        op1 = MASK_SPECIAL2(ctx->opcode);
7631
        switch (op1) {
7632
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7633
        case OPC_MSUB ... OPC_MSUBU:
7634
            check_insn(env, ctx, ISA_MIPS32);
7635
            gen_muldiv(ctx, op1, rs, rt);
7636
            break;
7637
        case OPC_MUL:
7638
            gen_arith(env, ctx, op1, rd, rs, rt);
7639
            break;
7640
        case OPC_CLO:
7641
        case OPC_CLZ:
7642
            check_insn(env, ctx, ISA_MIPS32);
7643
            gen_cl(ctx, op1, rd, rs);
7644
            break;
7645
        case OPC_SDBBP:
7646
            /* XXX: not clear which exception should be raised
7647
             *      when in debug mode...
7648
             */
7649
            check_insn(env, ctx, ISA_MIPS32);
7650
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7651
                generate_exception(ctx, EXCP_DBp);
7652
            } else {
7653
                generate_exception(ctx, EXCP_DBp);
7654
            }
7655
            /* Treat as NOP. */
7656
            break;
7657
#if defined(TARGET_MIPS64)
7658
        case OPC_DCLO:
7659
        case OPC_DCLZ:
7660
            check_insn(env, ctx, ISA_MIPS64);
7661
            check_mips_64(ctx);
7662
            gen_cl(ctx, op1, rd, rs);
7663
            break;
7664
#endif
7665
        default:            /* Invalid */
7666
            MIPS_INVAL("special2");
7667
            generate_exception(ctx, EXCP_RI);
7668
            break;
7669
        }
7670
        break;
7671
    case OPC_SPECIAL3:
7672
        op1 = MASK_SPECIAL3(ctx->opcode);
7673
        switch (op1) {
7674
        case OPC_EXT:
7675
        case OPC_INS:
7676
            check_insn(env, ctx, ISA_MIPS32R2);
7677
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7678
            break;
7679
        case OPC_BSHFL:
7680
            check_insn(env, ctx, ISA_MIPS32R2);
7681
            op2 = MASK_BSHFL(ctx->opcode);
7682
            gen_bshfl(ctx, op2, rt, rd);
7683
            break;
7684
        case OPC_RDHWR:
7685
            check_insn(env, ctx, ISA_MIPS32R2);
7686
            {
7687
                TCGv t0 = tcg_temp_local_new();
7688

    
7689
                switch (rd) {
7690
                case 0:
7691
                    save_cpu_state(ctx, 1);
7692
                    gen_helper_rdhwr_cpunum(t0);
7693
                    break;
7694
                case 1:
7695
                    save_cpu_state(ctx, 1);
7696
                    gen_helper_rdhwr_synci_step(t0);
7697
                    break;
7698
                case 2:
7699
                    save_cpu_state(ctx, 1);
7700
                    gen_helper_rdhwr_cc(t0);
7701
                    break;
7702
                case 3:
7703
                    save_cpu_state(ctx, 1);
7704
                    gen_helper_rdhwr_ccres(t0);
7705
                    break;
7706
                case 29:
7707
#if defined(CONFIG_USER_ONLY)
7708
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7709
                    break;
7710
#else
7711
                    /* XXX: Some CPUs implement this in hardware.
7712
                       Not supported yet. */
7713
#endif
7714
                default:            /* Invalid */
7715
                    MIPS_INVAL("rdhwr");
7716
                    generate_exception(ctx, EXCP_RI);
7717
                    break;
7718
                }
7719
                gen_store_gpr(t0, rt);
7720
                tcg_temp_free(t0);
7721
            }
7722
            break;
7723
        case OPC_FORK:
7724
            check_insn(env, ctx, ASE_MT);
7725
            {
7726
                TCGv t0 = tcg_temp_local_new();
7727
                TCGv t1 = tcg_temp_local_new();
7728

    
7729
                gen_load_gpr(t0, rt);
7730
                gen_load_gpr(t1, rs);
7731
                gen_helper_fork(t0, t1);
7732
                tcg_temp_free(t0);
7733
                tcg_temp_free(t1);
7734
            }
7735
            break;
7736
        case OPC_YIELD:
7737
            check_insn(env, ctx, ASE_MT);
7738
            {
7739
                TCGv t0 = tcg_temp_local_new();
7740

    
7741
                gen_load_gpr(t0, rs);
7742
                gen_helper_yield(t0, t0);
7743
                gen_store_gpr(t0, rd);
7744
                tcg_temp_free(t0);
7745
            }
7746
            break;
7747
#if defined(TARGET_MIPS64)
7748
        case OPC_DEXTM ... OPC_DEXT:
7749
        case OPC_DINSM ... OPC_DINS:
7750
            check_insn(env, ctx, ISA_MIPS64R2);
7751
            check_mips_64(ctx);
7752
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7753
            break;
7754
        case OPC_DBSHFL:
7755
            check_insn(env, ctx, ISA_MIPS64R2);
7756
            check_mips_64(ctx);
7757
            op2 = MASK_DBSHFL(ctx->opcode);
7758
            gen_bshfl(ctx, op2, rt, rd);
7759
            break;
7760
#endif
7761
        default:            /* Invalid */
7762
            MIPS_INVAL("special3");
7763
            generate_exception(ctx, EXCP_RI);
7764
            break;
7765
        }
7766
        break;
7767
    case OPC_REGIMM:
7768
        op1 = MASK_REGIMM(ctx->opcode);
7769
        switch (op1) {
7770
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7771
        case OPC_BLTZAL ... OPC_BGEZALL:
7772
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7773
            return;
7774
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7775
        case OPC_TNEI:
7776
            gen_trap(ctx, op1, rs, -1, imm);
7777
            break;
7778
        case OPC_SYNCI:
7779
            check_insn(env, ctx, ISA_MIPS32R2);
7780
            /* Treat as NOP. */
7781
            break;
7782
        default:            /* Invalid */
7783
            MIPS_INVAL("regimm");
7784
            generate_exception(ctx, EXCP_RI);
7785
            break;
7786
        }
7787
        break;
7788
    case OPC_CP0:
7789
        check_cp0_enabled(ctx);
7790
        op1 = MASK_CP0(ctx->opcode);
7791
        switch (op1) {
7792
        case OPC_MFC0:
7793
        case OPC_MTC0:
7794
        case OPC_MFTR:
7795
        case OPC_MTTR:
7796
#if defined(TARGET_MIPS64)
7797
        case OPC_DMFC0:
7798
        case OPC_DMTC0:
7799
#endif
7800
#ifndef CONFIG_USER_ONLY
7801
            gen_cp0(env, ctx, op1, rt, rd);
7802
#endif /* !CONFIG_USER_ONLY */
7803
            break;
7804
        case OPC_C0_FIRST ... OPC_C0_LAST:
7805
#ifndef CONFIG_USER_ONLY
7806
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7807
#endif /* !CONFIG_USER_ONLY */
7808
            break;
7809
        case OPC_MFMC0:
7810
#ifndef CONFIG_USER_ONLY
7811
            {
7812
                TCGv t0 = tcg_temp_local_new();
7813

    
7814
                op2 = MASK_MFMC0(ctx->opcode);
7815
                switch (op2) {
7816
                case OPC_DMT:
7817
                    check_insn(env, ctx, ASE_MT);
7818
                    gen_helper_dmt(t0, t0);
7819
                    break;
7820
                case OPC_EMT:
7821
                    check_insn(env, ctx, ASE_MT);
7822
                    gen_helper_emt(t0, t0);
7823
                    break;
7824
                case OPC_DVPE:
7825
                    check_insn(env, ctx, ASE_MT);
7826
                    gen_helper_dvpe(t0, t0);
7827
                    break;
7828
                case OPC_EVPE:
7829
                    check_insn(env, ctx, ASE_MT);
7830
                    gen_helper_evpe(t0, t0);
7831
                    break;
7832
                case OPC_DI:
7833
                    check_insn(env, ctx, ISA_MIPS32R2);
7834
                    save_cpu_state(ctx, 1);
7835
                    gen_helper_di(t0);
7836
                    /* Stop translation as we may have switched the execution mode */
7837
                    ctx->bstate = BS_STOP;
7838
                    break;
7839
                case OPC_EI:
7840
                    check_insn(env, ctx, ISA_MIPS32R2);
7841
                    save_cpu_state(ctx, 1);
7842
                    gen_helper_ei(t0);
7843
                    /* Stop translation as we may have switched the execution mode */
7844
                    ctx->bstate = BS_STOP;
7845
                    break;
7846
                default:            /* Invalid */
7847
                    MIPS_INVAL("mfmc0");
7848
                    generate_exception(ctx, EXCP_RI);
7849
                    break;
7850
                }
7851
                gen_store_gpr(t0, rt);
7852
                tcg_temp_free(t0);
7853
            }
7854
#endif /* !CONFIG_USER_ONLY */
7855
            break;
7856
        case OPC_RDPGPR:
7857
            check_insn(env, ctx, ISA_MIPS32R2);
7858
            gen_load_srsgpr(rt, rd);
7859
            break;
7860
        case OPC_WRPGPR:
7861
            check_insn(env, ctx, ISA_MIPS32R2);
7862
            gen_store_srsgpr(rt, rd);
7863
            break;
7864
        default:
7865
            MIPS_INVAL("cp0");
7866
            generate_exception(ctx, EXCP_RI);
7867
            break;
7868
        }
7869
        break;
7870
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7871
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7872
         break;
7873
    case OPC_J ... OPC_JAL: /* Jump */
7874
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7875
         gen_compute_branch(ctx, op, rs, rt, offset);
7876
         return;
7877
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7878
    case OPC_BEQL ... OPC_BGTZL:
7879
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7880
         return;
7881
    case OPC_LB ... OPC_LWR: /* Load and stores */
7882
    case OPC_SB ... OPC_SW:
7883
    case OPC_SWR:
7884
    case OPC_LL:
7885
    case OPC_SC:
7886
         gen_ldst(ctx, op, rt, rs, imm);
7887
         break;
7888
    case OPC_CACHE:
7889
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7890
        /* Treat as NOP. */
7891
        break;
7892
    case OPC_PREF:
7893
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7894
        /* Treat as NOP. */
7895
        break;
7896

    
7897
    /* Floating point (COP1). */
7898
    case OPC_LWC1:
7899
    case OPC_LDC1:
7900
    case OPC_SWC1:
7901
    case OPC_SDC1:
7902
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7903
            save_cpu_state(ctx, 1);
7904
            check_cp1_enabled(ctx);
7905
            gen_flt_ldst(ctx, op, rt, rs, imm);
7906
        } else {
7907
            generate_exception_err(ctx, EXCP_CpU, 1);
7908
        }
7909
        break;
7910

    
7911
    case OPC_CP1:
7912
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7913
            save_cpu_state(ctx, 1);
7914
            check_cp1_enabled(ctx);
7915
            op1 = MASK_CP1(ctx->opcode);
7916
            switch (op1) {
7917
            case OPC_MFHC1:
7918
            case OPC_MTHC1:
7919
                check_insn(env, ctx, ISA_MIPS32R2);
7920
            case OPC_MFC1:
7921
            case OPC_CFC1:
7922
            case OPC_MTC1:
7923
            case OPC_CTC1:
7924
                gen_cp1(ctx, op1, rt, rd);
7925
                break;
7926
#if defined(TARGET_MIPS64)
7927
            case OPC_DMFC1:
7928
            case OPC_DMTC1:
7929
                check_insn(env, ctx, ISA_MIPS3);
7930
                gen_cp1(ctx, op1, rt, rd);
7931
                break;
7932
#endif
7933
            case OPC_BC1ANY2:
7934
            case OPC_BC1ANY4:
7935
                check_cop1x(ctx);
7936
                check_insn(env, ctx, ASE_MIPS3D);
7937
                /* fall through */
7938
            case OPC_BC1:
7939
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7940
                                    (rt >> 2) & 0x7, imm << 2);
7941
                return;
7942
            case OPC_S_FMT:
7943
            case OPC_D_FMT:
7944
            case OPC_W_FMT:
7945
            case OPC_L_FMT:
7946
            case OPC_PS_FMT:
7947
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7948
                           (imm >> 8) & 0x7);
7949
                break;
7950
            default:
7951
                MIPS_INVAL("cp1");
7952
                generate_exception (ctx, EXCP_RI);
7953
                break;
7954
            }
7955
        } else {
7956
            generate_exception_err(ctx, EXCP_CpU, 1);
7957
        }
7958
        break;
7959

    
7960
    /* COP2.  */
7961
    case OPC_LWC2:
7962
    case OPC_LDC2:
7963
    case OPC_SWC2:
7964
    case OPC_SDC2:
7965
    case OPC_CP2:
7966
        /* COP2: Not implemented. */
7967
        generate_exception_err(ctx, EXCP_CpU, 2);
7968
        break;
7969

    
7970
    case OPC_CP3:
7971
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7972
            save_cpu_state(ctx, 1);
7973
            check_cp1_enabled(ctx);
7974
            op1 = MASK_CP3(ctx->opcode);
7975
            switch (op1) {
7976
            case OPC_LWXC1:
7977
            case OPC_LDXC1:
7978
            case OPC_LUXC1:
7979
            case OPC_SWXC1:
7980
            case OPC_SDXC1:
7981
            case OPC_SUXC1:
7982
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7983
                break;
7984
            case OPC_PREFX:
7985
                /* Treat as NOP. */
7986
                break;
7987
            case OPC_ALNV_PS:
7988
            case OPC_MADD_S:
7989
            case OPC_MADD_D:
7990
            case OPC_MADD_PS:
7991
            case OPC_MSUB_S:
7992
            case OPC_MSUB_D:
7993
            case OPC_MSUB_PS:
7994
            case OPC_NMADD_S:
7995
            case OPC_NMADD_D:
7996
            case OPC_NMADD_PS:
7997
            case OPC_NMSUB_S:
7998
            case OPC_NMSUB_D:
7999
            case OPC_NMSUB_PS:
8000
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8001
                break;
8002
            default:
8003
                MIPS_INVAL("cp3");
8004
                generate_exception (ctx, EXCP_RI);
8005
                break;
8006
            }
8007
        } else {
8008
            generate_exception_err(ctx, EXCP_CpU, 1);
8009
        }
8010
        break;
8011

    
8012
#if defined(TARGET_MIPS64)
8013
    /* MIPS64 opcodes */
8014
    case OPC_LWU:
8015
    case OPC_LDL ... OPC_LDR:
8016
    case OPC_SDL ... OPC_SDR:
8017
    case OPC_LLD:
8018
    case OPC_LD:
8019
    case OPC_SCD:
8020
    case OPC_SD:
8021
        check_insn(env, ctx, ISA_MIPS3);
8022
        check_mips_64(ctx);
8023
        gen_ldst(ctx, op, rt, rs, imm);
8024
        break;
8025
    case OPC_DADDI ... OPC_DADDIU:
8026
        check_insn(env, ctx, ISA_MIPS3);
8027
        check_mips_64(ctx);
8028
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8029
        break;
8030
#endif
8031
    case OPC_JALX:
8032
        check_insn(env, ctx, ASE_MIPS16);
8033
        /* MIPS16: Not implemented. */
8034
    case OPC_MDMX:
8035
        check_insn(env, ctx, ASE_MDMX);
8036
        /* MDMX: Not implemented. */
8037
    default:            /* Invalid */
8038
        MIPS_INVAL("major opcode");
8039
        generate_exception(ctx, EXCP_RI);
8040
        break;
8041
    }
8042
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8043
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8044
        /* Branches completion */
8045
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8046
        ctx->bstate = BS_BRANCH;
8047
        save_cpu_state(ctx, 0);
8048
        /* FIXME: Need to clear can_do_io.  */
8049
        switch (hflags) {
8050
        case MIPS_HFLAG_B:
8051
            /* unconditional branch */
8052
            MIPS_DEBUG("unconditional branch");
8053
            gen_goto_tb(ctx, 0, ctx->btarget);
8054
            break;
8055
        case MIPS_HFLAG_BL:
8056
            /* blikely taken case */
8057
            MIPS_DEBUG("blikely branch taken");
8058
            gen_goto_tb(ctx, 0, ctx->btarget);
8059
            break;
8060
        case MIPS_HFLAG_BC:
8061
            /* Conditional branch */
8062
            MIPS_DEBUG("conditional branch");
8063
            {
8064
                int l1 = gen_new_label();
8065

    
8066
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8067
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8068
                gen_set_label(l1);
8069
                gen_goto_tb(ctx, 0, ctx->btarget);
8070
            }
8071
            break;
8072
        case MIPS_HFLAG_BR:
8073
            /* unconditional branch to register */
8074
            MIPS_DEBUG("branch to register");
8075
            tcg_gen_mov_tl(cpu_PC, btarget);
8076
            tcg_gen_exit_tb(0);
8077
            break;
8078
        default:
8079
            MIPS_DEBUG("unknown branch");
8080
            break;
8081
        }
8082
    }
8083
}
8084

    
8085
static inline void
8086
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8087
                                int search_pc)
8088
{
8089
    DisasContext ctx;
8090
    target_ulong pc_start;
8091
    uint16_t *gen_opc_end;
8092
    CPUBreakpoint *bp;
8093
    int j, lj = -1;
8094
    int num_insns;
8095
    int max_insns;
8096

    
8097
    if (search_pc)
8098
        qemu_log("search pc %d\n", search_pc);
8099

    
8100
    pc_start = tb->pc;
8101
    /* Leave some spare opc slots for branch handling. */
8102
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8103
    ctx.pc = pc_start;
8104
    ctx.saved_pc = -1;
8105
    ctx.tb = tb;
8106
    ctx.bstate = BS_NONE;
8107
    /* Restore delay slot state from the tb context.  */
8108
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8109
    restore_cpu_state(env, &ctx);
8110
#ifdef CONFIG_USER_ONLY
8111
        ctx.mem_idx = MIPS_HFLAG_UM;
8112
#else
8113
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8114
#endif
8115
    num_insns = 0;
8116
    max_insns = tb->cflags & CF_COUNT_MASK;
8117
    if (max_insns == 0)
8118
        max_insns = CF_COUNT_MASK;
8119
#ifdef DEBUG_DISAS
8120
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8121
    /* FIXME: This may print out stale hflags from env... */
8122
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8123
#endif
8124
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8125
    gen_icount_start();
8126
    while (ctx.bstate == BS_NONE) {
8127
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8128
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8129
                if (bp->pc == ctx.pc) {
8130
                    save_cpu_state(&ctx, 1);
8131
                    ctx.bstate = BS_BRANCH;
8132
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8133
                    /* Include the breakpoint location or the tb won't
8134
                     * be flushed when it must be.  */
8135
                    ctx.pc += 4;
8136
                    goto done_generating;
8137
                }
8138
            }
8139
        }
8140

    
8141
        if (search_pc) {
8142
            j = gen_opc_ptr - gen_opc_buf;
8143
            if (lj < j) {
8144
                lj++;
8145
                while (lj < j)
8146
                    gen_opc_instr_start[lj++] = 0;
8147
            }
8148
            gen_opc_pc[lj] = ctx.pc;
8149
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8150
            gen_opc_instr_start[lj] = 1;
8151
            gen_opc_icount[lj] = num_insns;
8152
        }
8153
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8154
            gen_io_start();
8155
        ctx.opcode = ldl_code(ctx.pc);
8156
        decode_opc(env, &ctx);
8157
        ctx.pc += 4;
8158
        num_insns++;
8159

    
8160
        if (env->singlestep_enabled)
8161
            break;
8162

    
8163
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8164
            break;
8165

    
8166
        if (gen_opc_ptr >= gen_opc_end)
8167
            break;
8168

    
8169
        if (num_insns >= max_insns)
8170
            break;
8171
#if defined (MIPS_SINGLE_STEP)
8172
        break;
8173
#endif
8174
    }
8175
    if (tb->cflags & CF_LAST_IO)
8176
        gen_io_end();
8177
    if (env->singlestep_enabled) {
8178
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8179
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8180
    } else {
8181
        switch (ctx.bstate) {
8182
        case BS_STOP:
8183
            gen_helper_interrupt_restart();
8184
            gen_goto_tb(&ctx, 0, ctx.pc);
8185
            break;
8186
        case BS_NONE:
8187
            save_cpu_state(&ctx, 0);
8188
            gen_goto_tb(&ctx, 0, ctx.pc);
8189
            break;
8190
        case BS_EXCP:
8191
            gen_helper_interrupt_restart();
8192
            tcg_gen_exit_tb(0);
8193
            break;
8194
        case BS_BRANCH:
8195
        default:
8196
            break;
8197
        }
8198
    }
8199
done_generating:
8200
    gen_icount_end(tb, num_insns);
8201
    *gen_opc_ptr = INDEX_op_end;
8202
    if (search_pc) {
8203
        j = gen_opc_ptr - gen_opc_buf;
8204
        lj++;
8205
        while (lj <= j)
8206
            gen_opc_instr_start[lj++] = 0;
8207
    } else {
8208
        tb->size = ctx.pc - pc_start;
8209
        tb->icount = num_insns;
8210
    }
8211
#ifdef DEBUG_DISAS
8212
    LOG_DISAS("\n");
8213
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8214
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8215
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8216
        qemu_log("\n");
8217
    }
8218
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8219
#endif
8220
}
8221

    
8222
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8223
{
8224
    gen_intermediate_code_internal(env, tb, 0);
8225
}
8226

    
8227
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8228
{
8229
    gen_intermediate_code_internal(env, tb, 1);
8230
}
8231

    
8232
static void fpu_dump_state(CPUState *env, FILE *f,
8233
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8234
                           int flags)
8235
{
8236
    int i;
8237
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8238

    
8239
#define printfpr(fp)                                                        \
8240
    do {                                                                    \
8241
        if (is_fpu64)                                                       \
8242
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8243
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8244
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8245
        else {                                                              \
8246
            fpr_t tmp;                                                      \
8247
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8248
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8249
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8250
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8251
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8252
        }                                                                   \
8253
    } while(0)
8254

    
8255

    
8256
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8257
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8258
                get_float_exception_flags(&env->active_fpu.fp_status));
8259
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8260
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8261
        printfpr(&env->active_fpu.fpr[i]);
8262
    }
8263

    
8264
#undef printfpr
8265
}
8266

    
8267
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8268
/* Debug help: The architecture requires 32bit code to maintain proper
8269
   sign-extended values on 64bit machines.  */
8270

    
8271
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8272

    
8273
static void
8274
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8275
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8276
                                int flags)
8277
{
8278
    int i;
8279

    
8280
    if (!SIGN_EXT_P(env->active_tc.PC))
8281
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8282
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8283
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8284
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8285
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8286
    if (!SIGN_EXT_P(env->btarget))
8287
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8288

    
8289
    for (i = 0; i < 32; i++) {
8290
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8291
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8292
    }
8293

    
8294
    if (!SIGN_EXT_P(env->CP0_EPC))
8295
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8296
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8297
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8298
}
8299
#endif
8300

    
8301
void cpu_dump_state (CPUState *env, FILE *f,
8302
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8303
                     int flags)
8304
{
8305
    int i;
8306

    
8307
    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",
8308
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8309
                env->hflags, env->btarget, env->bcond);
8310
    for (i = 0; i < 32; i++) {
8311
        if ((i & 3) == 0)
8312
            cpu_fprintf(f, "GPR%02d:", i);
8313
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8314
        if ((i & 3) == 3)
8315
            cpu_fprintf(f, "\n");
8316
    }
8317

    
8318
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8319
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8320
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8321
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8322
    if (env->hflags & MIPS_HFLAG_FPU)
8323
        fpu_dump_state(env, f, cpu_fprintf, flags);
8324
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8325
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8326
#endif
8327
}
8328

    
8329
static void mips_tcg_init(void)
8330
{
8331
    int i;
8332
    static int inited;
8333

    
8334
    /* Initialize various static tables. */
8335
    if (inited)
8336
        return;
8337

    
8338
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8339
    for (i = 0; i < 32; i++)
8340
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8341
                                        offsetof(CPUState, active_tc.gpr[i]),
8342
                                        regnames[i]);
8343
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8344
                                offsetof(CPUState, active_tc.PC), "PC");
8345
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8346
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8347
                                       offsetof(CPUState, active_tc.HI[i]),
8348
                                       regnames_HI[i]);
8349
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8350
                                       offsetof(CPUState, active_tc.LO[i]),
8351
                                       regnames_LO[i]);
8352
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8353
                                        offsetof(CPUState, active_tc.ACX[i]),
8354
                                        regnames_ACX[i]);
8355
    }
8356
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8357
                                     offsetof(CPUState, active_tc.DSPControl),
8358
                                     "DSPControl");
8359
    bcond = tcg_global_mem_new(TCG_AREG0,
8360
                               offsetof(CPUState, bcond), "bcond");
8361
    btarget = tcg_global_mem_new(TCG_AREG0,
8362
                                 offsetof(CPUState, btarget), "btarget");
8363
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8364
                                    offsetof(CPUState, hflags), "hflags");
8365

    
8366
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8367
                                      offsetof(CPUState, active_fpu.fcr0),
8368
                                      "fcr0");
8369
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8370
                                       offsetof(CPUState, active_fpu.fcr31),
8371
                                       "fcr31");
8372

    
8373
    /* register helpers */
8374
#define GEN_HELPER 2
8375
#include "helper.h"
8376

    
8377
    inited = 1;
8378
}
8379

    
8380
#include "translate_init.c"
8381

    
8382
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8383
{
8384
    CPUMIPSState *env;
8385
    const mips_def_t *def;
8386

    
8387
    def = cpu_mips_find_by_name(cpu_model);
8388
    if (!def)
8389
        return NULL;
8390
    env = qemu_mallocz(sizeof(CPUMIPSState));
8391
    env->cpu_model = def;
8392

    
8393
    cpu_exec_init(env);
8394
    env->cpu_model_str = cpu_model;
8395
    mips_tcg_init();
8396
    cpu_reset(env);
8397
    return env;
8398
}
8399

    
8400
void cpu_reset (CPUMIPSState *env)
8401
{
8402
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8403
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8404
        log_cpu_state(env, 0);
8405
    }
8406

    
8407
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8408

    
8409
    tlb_flush(env, 1);
8410

    
8411
    /* Minimal init */
8412
#if defined(CONFIG_USER_ONLY)
8413
    env->hflags = MIPS_HFLAG_UM;
8414
#else
8415
    if (env->hflags & MIPS_HFLAG_BMASK) {
8416
        /* If the exception was raised from a delay slot,
8417
           come back to the jump.  */
8418
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8419
    } else {
8420
        env->CP0_ErrorEPC = env->active_tc.PC;
8421
    }
8422
    env->active_tc.PC = (int32_t)0xBFC00000;
8423
    env->CP0_Wired = 0;
8424
    /* SMP not implemented */
8425
    env->CP0_EBase = 0x80000000;
8426
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8427
    /* vectored interrupts not implemented, timer on int 7,
8428
       no performance counters. */
8429
    env->CP0_IntCtl = 0xe0000000;
8430
    {
8431
        int i;
8432

    
8433
        for (i = 0; i < 7; i++) {
8434
            env->CP0_WatchLo[i] = 0;
8435
            env->CP0_WatchHi[i] = 0x80000000;
8436
        }
8437
        env->CP0_WatchLo[7] = 0;
8438
        env->CP0_WatchHi[7] = 0;
8439
    }
8440
    /* Count register increments in debug mode, EJTAG version 1 */
8441
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8442
    env->hflags = MIPS_HFLAG_CP0;
8443
#endif
8444
    env->exception_index = EXCP_NONE;
8445
    cpu_mips_register(env, env->cpu_model);
8446
}
8447

    
8448
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8449
                unsigned long searched_pc, int pc_pos, void *puc)
8450
{
8451
    env->active_tc.PC = gen_opc_pc[pc_pos];
8452
    env->hflags &= ~MIPS_HFLAG_BMASK;
8453
    env->hflags |= gen_opc_hflags[pc_pos];
8454
}