Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 0fd70f8f

History | View | Annotate | Download (258.3 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

    
36
//#define MIPS_DEBUG_DISAS
37
//#define MIPS_DEBUG_SIGN_EXTENSIONS
38
//#define MIPS_SINGLE_STEP
39

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
386
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

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

    
400
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
401

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

    
425
/* global register indices */
426
static TCGv cpu_env, bcond, btarget, current_fpu;
427

    
428
#include "gen-icount.h"
429

    
430
static inline void tcg_gen_helper_0_i(void *func, TCGv arg)
431
{
432
    TCGv tmp = tcg_const_i32(arg);
433

    
434
    tcg_gen_helper_0_1(func, tmp);
435
    tcg_temp_free(tmp);
436
}
437

    
438
static inline void tcg_gen_helper_0_ii(void *func, TCGv arg1, TCGv arg2)
439
{
440
    TCGv tmp1 = tcg_const_i32(arg1);
441
    TCGv tmp2 = tcg_const_i32(arg2);
442

    
443
    tcg_gen_helper_0_2(func, tmp1, tmp2);
444
    tcg_temp_free(tmp1);
445
    tcg_temp_free(tmp2);
446
}
447

    
448
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, TCGv arg2)
449
{
450
    TCGv tmp = tcg_const_i32(arg2);
451

    
452
    tcg_gen_helper_0_2(func, arg1, tmp);
453
    tcg_temp_free(tmp);
454
}
455

    
456
static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
457
{
458
    TCGv tmp = tcg_const_i32(arg3);
459

    
460
    tcg_gen_helper_0_3(func, arg1, arg2, tmp);
461
    tcg_temp_free(tmp);
462
}
463

    
464
static inline void tcg_gen_helper_0_1ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
465
{
466
    TCGv tmp1 = tcg_const_i32(arg2);
467
    TCGv tmp2 = tcg_const_i32(arg3);
468

    
469
    tcg_gen_helper_0_3(func, arg1, tmp1, tmp2);
470
    tcg_temp_free(tmp1);
471
    tcg_temp_free(tmp2);
472
}
473

    
474
static inline void tcg_gen_helper_1_i(void *func, TCGv ret, TCGv arg)
475
{
476
    TCGv tmp = tcg_const_i32(arg);
477

    
478
    tcg_gen_helper_1_1(func, ret, tmp);
479
    tcg_temp_free(tmp);
480
}
481

    
482
static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2)
483
{
484
    TCGv tmp = tcg_const_i32(arg2);
485

    
486
    tcg_gen_helper_1_2(func, ret, arg1, tmp);
487
    tcg_temp_free(tmp);
488
}
489

    
490
static inline void tcg_gen_helper_1_1ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
491
{
492
    TCGv tmp1 = tcg_const_i32(arg2);
493
    TCGv tmp2 = tcg_const_i32(arg3);
494

    
495
    tcg_gen_helper_1_3(func, ret, arg1, tmp1, tmp2);
496
    tcg_temp_free(tmp1);
497
    tcg_temp_free(tmp2);
498
}
499

    
500
static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
501
{
502
    TCGv tmp = tcg_const_i32(arg3);
503

    
504
    tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp);
505
    tcg_temp_free(tmp);
506
}
507

    
508
static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4)
509
{
510
    TCGv tmp1 = tcg_const_i32(arg3);
511
    TCGv tmp2 = tcg_const_i32(arg4);
512

    
513
    tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2);
514
    tcg_temp_free(tmp1);
515
    tcg_temp_free(tmp2);
516
}
517

    
518
typedef struct DisasContext {
519
    struct TranslationBlock *tb;
520
    target_ulong pc, saved_pc;
521
    uint32_t opcode;
522
    /* Routine used to access memory */
523
    int mem_idx;
524
    uint32_t hflags, saved_hflags;
525
    int bstate;
526
    target_ulong btarget;
527
} DisasContext;
528

    
529
enum {
530
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
531
                      * exception condition */
532
    BS_STOP     = 1, /* We want to stop translation for any reason */
533
    BS_BRANCH   = 2, /* We reached a branch condition     */
534
    BS_EXCP     = 3, /* We reached an exception condition */
535
};
536

    
537
static const char *regnames[] =
538
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
539
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
540
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
541
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
542

    
543
static const char *fregnames[] =
544
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
545
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
546
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
547
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
548

    
549
#ifdef MIPS_DEBUG_DISAS
550
#define MIPS_DEBUG(fmt, args...)                                              \
551
do {                                                                          \
552
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
553
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
554
                ctx->pc, ctx->opcode , ##args);                               \
555
    }                                                                         \
556
} while (0)
557
#else
558
#define MIPS_DEBUG(fmt, args...) do { } while(0)
559
#endif
560

    
561
#define MIPS_INVAL(op)                                                        \
562
do {                                                                          \
563
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
564
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
565
} while (0)
566

    
567
/* General purpose registers moves. */
568
static inline void gen_load_gpr (TCGv t, int reg)
569
{
570
    if (reg == 0)
571
        tcg_gen_movi_tl(t, 0);
572
    else
573
        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
574
                                  sizeof(target_ulong) * reg);
575
}
576

    
577
static inline void gen_store_gpr (TCGv t, int reg)
578
{
579
    if (reg != 0)
580
        tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
581
                                  sizeof(target_ulong) * reg);
582
}
583

    
584
/* Moves to/from HI and LO registers.  */
585
static inline void gen_load_LO (TCGv t, int reg)
586
{
587
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
588
                              sizeof(target_ulong) * reg);
589
}
590

    
591
static inline void gen_store_LO (TCGv t, int reg)
592
{
593
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
594
                              sizeof(target_ulong) * reg);
595
}
596

    
597
static inline void gen_load_HI (TCGv t, int reg)
598
{
599
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
600
                              sizeof(target_ulong) * reg);
601
}
602

    
603
static inline void gen_store_HI (TCGv t, int reg)
604
{
605
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
606
                              sizeof(target_ulong) * reg);
607
}
608

    
609
/* Moves to/from shadow registers. */
610
static inline void gen_load_srsgpr (int from, int to)
611
{
612
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
613

    
614
    if (from == 0)
615
        tcg_gen_movi_tl(r_tmp1, 0);
616
    else {
617
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
618

    
619
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
620
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
621
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
622
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
623
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
624

    
625
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
626
        tcg_temp_free(r_tmp2);
627
    }
628
    gen_store_gpr(r_tmp1, to);
629
    tcg_temp_free(r_tmp1);
630
}
631

    
632
static inline void gen_store_srsgpr (int from, int to)
633
{
634
    if (to != 0) {
635
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
636
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
637

    
638
        gen_load_gpr(r_tmp1, from);
639
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
640
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
641
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
642
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
643
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
644

    
645
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
646
        tcg_temp_free(r_tmp1);
647
        tcg_temp_free(r_tmp2);
648
    }
649
}
650

    
651
/* Floating point register moves. */
652
static inline void gen_load_fpr32 (TCGv t, int reg)
653
{
654
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
655
}
656

    
657
static inline void gen_store_fpr32 (TCGv t, int reg)
658
{
659
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
660
}
661

    
662
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
663
{
664
    if (ctx->hflags & MIPS_HFLAG_F64) {
665
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
666
    } else {
667
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
668
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
669

    
670
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
671
        tcg_gen_extu_i32_i64(t, r_tmp1);
672
        tcg_gen_shli_i64(t, t, 32);
673
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
674
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
675
        tcg_gen_or_i64(t, t, r_tmp2);
676
        tcg_temp_free(r_tmp1);
677
        tcg_temp_free(r_tmp2);
678
    }
679
}
680

    
681
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
682
{
683
    if (ctx->hflags & MIPS_HFLAG_F64) {
684
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
685
    } else {
686
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
687

    
688
        tcg_gen_trunc_i64_i32(r_tmp, t);
689
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
690
        tcg_gen_shri_i64(t, t, 32);
691
        tcg_gen_trunc_i64_i32(r_tmp, t);
692
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
693
        tcg_temp_free(r_tmp);
694
    }
695
}
696

    
697
static inline void gen_load_fpr32h (TCGv t, int reg)
698
{
699
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
700
}
701

    
702
static inline void gen_store_fpr32h (TCGv t, int reg)
703
{
704
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
705
}
706

    
707
static inline void get_fp_cond (TCGv t)
708
{
709
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
710
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
711

    
712
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
713
    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
714
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
715
    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
716
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
717
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
718
    tcg_temp_free(r_tmp1);
719
    tcg_temp_free(r_tmp2);
720
}
721

    
722
typedef void (fcmp_fun32)(uint32_t, uint32_t, int);
723
typedef void (fcmp_fun64)(uint64_t, uint64_t, int);
724

    
725
#define FOP_CONDS(fcmp_fun, type, arg0, arg1, fmt)                            \
726
static fcmp_fun * fcmp ## type ## _ ## fmt ## _table[16] = {                  \
727
    do_cmp ## type ## _ ## fmt ## _f,                                         \
728
    do_cmp ## type ## _ ## fmt ## _un,                                        \
729
    do_cmp ## type ## _ ## fmt ## _eq,                                        \
730
    do_cmp ## type ## _ ## fmt ## _ueq,                                       \
731
    do_cmp ## type ## _ ## fmt ## _olt,                                       \
732
    do_cmp ## type ## _ ## fmt ## _ult,                                       \
733
    do_cmp ## type ## _ ## fmt ## _ole,                                       \
734
    do_cmp ## type ## _ ## fmt ## _ule,                                       \
735
    do_cmp ## type ## _ ## fmt ## _sf,                                        \
736
    do_cmp ## type ## _ ## fmt ## _ngle,                                      \
737
    do_cmp ## type ## _ ## fmt ## _seq,                                       \
738
    do_cmp ## type ## _ ## fmt ## _ngl,                                       \
739
    do_cmp ## type ## _ ## fmt ## _lt,                                        \
740
    do_cmp ## type ## _ ## fmt ## _nge,                                       \
741
    do_cmp ## type ## _ ## fmt ## _le,                                        \
742
    do_cmp ## type ## _ ## fmt ## _ngt,                                       \
743
};                                                                            \
744
static inline void gen_cmp ## type ## _ ## fmt(int n, arg0 a, arg1 b, int cc) \
745
{                                                                             \
746
    tcg_gen_helper_0_2i(fcmp ## type ## _ ## fmt ## _table[n], a, b, cc);     \
747
}
748

    
749
FOP_CONDS(fcmp_fun64, , uint64_t, uint64_t, d)
750
FOP_CONDS(fcmp_fun64, abs, uint64_t, uint64_t, d)
751
FOP_CONDS(fcmp_fun32, , uint32_t, uint32_t, s)
752
FOP_CONDS(fcmp_fun32, abs, uint32_t, uint32_t, s)
753
FOP_CONDS(fcmp_fun64, , uint64_t, uint64_t, ps)
754
FOP_CONDS(fcmp_fun64, abs, uint64_t, uint64_t, ps)
755
#undef FOP_CONDS
756

    
757
/* Tests */
758
#define OP_COND(name, cond)                                   \
759
static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
760
{                                                             \
761
    int l1 = gen_new_label();                                 \
762
    int l2 = gen_new_label();                                 \
763
                                                              \
764
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
765
    tcg_gen_movi_tl(t0, 0);                                   \
766
    tcg_gen_br(l2);                                           \
767
    gen_set_label(l1);                                        \
768
    tcg_gen_movi_tl(t0, 1);                                   \
769
    gen_set_label(l2);                                        \
770
}
771
OP_COND(eq, TCG_COND_EQ);
772
OP_COND(ne, TCG_COND_NE);
773
OP_COND(ge, TCG_COND_GE);
774
OP_COND(geu, TCG_COND_GEU);
775
OP_COND(lt, TCG_COND_LT);
776
OP_COND(ltu, TCG_COND_LTU);
777
#undef OP_COND
778

    
779
#define OP_CONDI(name, cond)                                  \
780
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
781
{                                                             \
782
    int l1 = gen_new_label();                                 \
783
    int l2 = gen_new_label();                                 \
784
                                                              \
785
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
786
    tcg_gen_movi_tl(t, 0);                                    \
787
    tcg_gen_br(l2);                                           \
788
    gen_set_label(l1);                                        \
789
    tcg_gen_movi_tl(t, 1);                                    \
790
    gen_set_label(l2);                                        \
791
}
792
OP_CONDI(lti, TCG_COND_LT);
793
OP_CONDI(ltiu, TCG_COND_LTU);
794
#undef OP_CONDI
795

    
796
#define OP_CONDZ(name, cond)                                  \
797
static inline void glue(gen_op_, name) (TCGv t)               \
798
{                                                             \
799
    int l1 = gen_new_label();                                 \
800
    int l2 = gen_new_label();                                 \
801
                                                              \
802
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
803
    tcg_gen_movi_tl(t, 0);                                    \
804
    tcg_gen_br(l2);                                           \
805
    gen_set_label(l1);                                        \
806
    tcg_gen_movi_tl(t, 1);                                    \
807
    gen_set_label(l2);                                        \
808
}
809
OP_CONDZ(gez, TCG_COND_GE);
810
OP_CONDZ(gtz, TCG_COND_GT);
811
OP_CONDZ(lez, TCG_COND_LE);
812
OP_CONDZ(ltz, TCG_COND_LT);
813
#undef OP_CONDZ
814

    
815
static inline void gen_save_pc(target_ulong pc)
816
{
817
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
818

    
819
    tcg_gen_movi_tl(r_tmp, pc);
820
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
821
    tcg_temp_free(r_tmp);
822
}
823

    
824
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
825
{
826
#if defined MIPS_DEBUG_DISAS
827
    if (loglevel & CPU_LOG_TB_IN_ASM) {
828
            fprintf(logfile, "hflags %08x saved %08x\n",
829
                    ctx->hflags, ctx->saved_hflags);
830
    }
831
#endif
832
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
833
        gen_save_pc(ctx->pc);
834
        ctx->saved_pc = ctx->pc;
835
    }
836
    if (ctx->hflags != ctx->saved_hflags) {
837
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
838

    
839
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
840
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
841
        tcg_temp_free(r_tmp);
842
        ctx->saved_hflags = ctx->hflags;
843
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
844
        case MIPS_HFLAG_BR:
845
            break;
846
        case MIPS_HFLAG_BC:
847
        case MIPS_HFLAG_BL:
848
        case MIPS_HFLAG_B:
849
            tcg_gen_movi_tl(btarget, ctx->btarget);
850
            break;
851
        }
852
    }
853
}
854

    
855
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
856
{
857
    ctx->saved_hflags = ctx->hflags;
858
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
859
    case MIPS_HFLAG_BR:
860
        break;
861
    case MIPS_HFLAG_BC:
862
    case MIPS_HFLAG_BL:
863
    case MIPS_HFLAG_B:
864
        ctx->btarget = env->btarget;
865
        break;
866
    }
867
}
868

    
869
static inline void
870
generate_exception_err (DisasContext *ctx, int excp, int err)
871
{
872
    save_cpu_state(ctx, 1);
873
    tcg_gen_helper_0_ii(do_raise_exception_err, excp, err);
874
    tcg_gen_helper_0_0(do_interrupt_restart);
875
    tcg_gen_exit_tb(0);
876
}
877

    
878
static inline void
879
generate_exception (DisasContext *ctx, int excp)
880
{
881
    save_cpu_state(ctx, 1);
882
    tcg_gen_helper_0_i(do_raise_exception, excp);
883
    tcg_gen_helper_0_0(do_interrupt_restart);
884
    tcg_gen_exit_tb(0);
885
}
886

    
887
/* Addresses computation */
888
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
889
{
890
    tcg_gen_add_tl(t0, t0, t1);
891

    
892
#if defined(TARGET_MIPS64)
893
    /* For compatibility with 32-bit code, data reference in user mode
894
       with Status_UX = 0 should be casted to 32-bit and sign extended.
895
       See the MIPS64 PRA manual, section 4.10. */
896
    {
897
        int l1 = gen_new_label();
898
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
899

    
900
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
901
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
902
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
903
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
904
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
905
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
906
        tcg_temp_free(r_tmp);
907
        tcg_gen_ext32s_i64(t0, t0);
908
        gen_set_label(l1);
909
    }
910
#endif
911
}
912

    
913
static inline void check_cp0_enabled(DisasContext *ctx)
914
{
915
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
916
        generate_exception_err(ctx, EXCP_CpU, 1);
917
}
918

    
919
static inline void check_cp1_enabled(DisasContext *ctx)
920
{
921
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
922
        generate_exception_err(ctx, EXCP_CpU, 1);
923
}
924

    
925
/* Verify that the processor is running with COP1X instructions enabled.
926
   This is associated with the nabla symbol in the MIPS32 and MIPS64
927
   opcode tables.  */
928

    
929
static inline void check_cop1x(DisasContext *ctx)
930
{
931
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
932
        generate_exception(ctx, EXCP_RI);
933
}
934

    
935
/* Verify that the processor is running with 64-bit floating-point
936
   operations enabled.  */
937

    
938
static inline void check_cp1_64bitmode(DisasContext *ctx)
939
{
940
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
941
        generate_exception(ctx, EXCP_RI);
942
}
943

    
944
/*
945
 * Verify if floating point register is valid; an operation is not defined
946
 * if bit 0 of any register specification is set and the FR bit in the
947
 * Status register equals zero, since the register numbers specify an
948
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
949
 * in the Status register equals one, both even and odd register numbers
950
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
951
 *
952
 * Multiple 64 bit wide registers can be checked by calling
953
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
954
 */
955
static inline void check_cp1_registers(DisasContext *ctx, int regs)
956
{
957
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
958
        generate_exception(ctx, EXCP_RI);
959
}
960

    
961
/* This code generates a "reserved instruction" exception if the
962
   CPU does not support the instruction set corresponding to flags. */
963
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
964
{
965
    if (unlikely(!(env->insn_flags & flags)))
966
        generate_exception(ctx, EXCP_RI);
967
}
968

    
969
/* This code generates a "reserved instruction" exception if 64-bit
970
   instructions are not enabled. */
971
static inline void check_mips_64(DisasContext *ctx)
972
{
973
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
974
        generate_exception(ctx, EXCP_RI);
975
}
976

    
977
/* load/store instructions. */
978
#define OP_LD(insn,fname)                                        \
979
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
980
{                                                                \
981
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
982
}
983
OP_LD(lb,ld8s);
984
OP_LD(lbu,ld8u);
985
OP_LD(lh,ld16s);
986
OP_LD(lhu,ld16u);
987
OP_LD(lw,ld32s);
988
#if defined(TARGET_MIPS64)
989
OP_LD(lwu,ld32u);
990
OP_LD(ld,ld64);
991
#endif
992
#undef OP_LD
993

    
994
#define OP_ST(insn,fname)                                        \
995
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
996
{                                                                \
997
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
998
}
999
OP_ST(sb,st8);
1000
OP_ST(sh,st16);
1001
OP_ST(sw,st32);
1002
#if defined(TARGET_MIPS64)
1003
OP_ST(sd,st64);
1004
#endif
1005
#undef OP_ST
1006

    
1007
#define OP_LD_ATOMIC(insn,fname)                                        \
1008
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1009
{                                                                       \
1010
    tcg_gen_mov_tl(t1, t0);                                             \
1011
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
1012
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
1013
}
1014
OP_LD_ATOMIC(ll,ld32s);
1015
#if defined(TARGET_MIPS64)
1016
OP_LD_ATOMIC(lld,ld64);
1017
#endif
1018
#undef OP_LD_ATOMIC
1019

    
1020
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1021
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1022
{                                                                       \
1023
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1024
    int l1 = gen_new_label();                                           \
1025
    int l2 = gen_new_label();                                           \
1026
    int l3 = gen_new_label();                                           \
1027
                                                                        \
1028
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
1029
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1030
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
1031
    generate_exception(ctx, EXCP_AdES);                                 \
1032
    gen_set_label(l1);                                                  \
1033
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1034
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
1035
    tcg_temp_free(r_tmp);                                               \
1036
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
1037
    tcg_gen_movi_tl(t0, 1);                                             \
1038
    tcg_gen_br(l3);                                                     \
1039
    gen_set_label(l2);                                                  \
1040
    tcg_gen_movi_tl(t0, 0);                                             \
1041
    gen_set_label(l3);                                                  \
1042
}
1043
OP_ST_ATOMIC(sc,st32,0x3);
1044
#if defined(TARGET_MIPS64)
1045
OP_ST_ATOMIC(scd,st64,0x7);
1046
#endif
1047
#undef OP_ST_ATOMIC
1048

    
1049
/* Load and store */
1050
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1051
                      int base, int16_t offset)
1052
{
1053
    const char *opn = "ldst";
1054
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1055
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1056

    
1057
    if (base == 0) {
1058
        tcg_gen_movi_tl(t0, offset);
1059
    } else if (offset == 0) {
1060
        gen_load_gpr(t0, base);
1061
    } else {
1062
        gen_load_gpr(t0, base);
1063
        tcg_gen_movi_tl(t1, offset);
1064
        gen_op_addr_add(t0, t1);
1065
    }
1066
    /* Don't do NOP if destination is zero: we must perform the actual
1067
       memory access. */
1068
    switch (opc) {
1069
#if defined(TARGET_MIPS64)
1070
    case OPC_LWU:
1071
        op_ldst_lwu(t0, ctx);
1072
        gen_store_gpr(t0, rt);
1073
        opn = "lwu";
1074
        break;
1075
    case OPC_LD:
1076
        op_ldst_ld(t0, ctx);
1077
        gen_store_gpr(t0, rt);
1078
        opn = "ld";
1079
        break;
1080
    case OPC_LLD:
1081
        op_ldst_lld(t0, t1, ctx);
1082
        gen_store_gpr(t0, rt);
1083
        opn = "lld";
1084
        break;
1085
    case OPC_SD:
1086
        gen_load_gpr(t1, rt);
1087
        op_ldst_sd(t0, t1, ctx);
1088
        opn = "sd";
1089
        break;
1090
    case OPC_SCD:
1091
        save_cpu_state(ctx, 1);
1092
        gen_load_gpr(t1, rt);
1093
        op_ldst_scd(t0, t1, ctx);
1094
        gen_store_gpr(t0, rt);
1095
        opn = "scd";
1096
        break;
1097
    case OPC_LDL:
1098
        save_cpu_state(ctx, 1);
1099
        gen_load_gpr(t1, rt);
1100
        tcg_gen_helper_1_2i(do_ldl, t1, t0, t1, ctx->mem_idx);
1101
        gen_store_gpr(t1, rt);
1102
        opn = "ldl";
1103
        break;
1104
    case OPC_SDL:
1105
        save_cpu_state(ctx, 1);
1106
        gen_load_gpr(t1, rt);
1107
        tcg_gen_helper_0_2i(do_sdl, t0, t1, ctx->mem_idx);
1108
        opn = "sdl";
1109
        break;
1110
    case OPC_LDR:
1111
        save_cpu_state(ctx, 1);
1112
        gen_load_gpr(t1, rt);
1113
        tcg_gen_helper_1_2i(do_ldr, t1, t0, t1, ctx->mem_idx);
1114
        gen_store_gpr(t1, rt);
1115
        opn = "ldr";
1116
        break;
1117
    case OPC_SDR:
1118
        save_cpu_state(ctx, 1);
1119
        gen_load_gpr(t1, rt);
1120
        tcg_gen_helper_0_2i(do_sdr, t0, t1, ctx->mem_idx);
1121
        opn = "sdr";
1122
        break;
1123
#endif
1124
    case OPC_LW:
1125
        op_ldst_lw(t0, ctx);
1126
        gen_store_gpr(t0, rt);
1127
        opn = "lw";
1128
        break;
1129
    case OPC_SW:
1130
        gen_load_gpr(t1, rt);
1131
        op_ldst_sw(t0, t1, ctx);
1132
        opn = "sw";
1133
        break;
1134
    case OPC_LH:
1135
        op_ldst_lh(t0, ctx);
1136
        gen_store_gpr(t0, rt);
1137
        opn = "lh";
1138
        break;
1139
    case OPC_SH:
1140
        gen_load_gpr(t1, rt);
1141
        op_ldst_sh(t0, t1, ctx);
1142
        opn = "sh";
1143
        break;
1144
    case OPC_LHU:
1145
        op_ldst_lhu(t0, ctx);
1146
        gen_store_gpr(t0, rt);
1147
        opn = "lhu";
1148
        break;
1149
    case OPC_LB:
1150
        op_ldst_lb(t0, ctx);
1151
        gen_store_gpr(t0, rt);
1152
        opn = "lb";
1153
        break;
1154
    case OPC_SB:
1155
        gen_load_gpr(t1, rt);
1156
        op_ldst_sb(t0, t1, ctx);
1157
        opn = "sb";
1158
        break;
1159
    case OPC_LBU:
1160
        op_ldst_lbu(t0, ctx);
1161
        gen_store_gpr(t0, rt);
1162
        opn = "lbu";
1163
        break;
1164
    case OPC_LWL:
1165
        save_cpu_state(ctx, 1);
1166
        gen_load_gpr(t1, rt);
1167
        tcg_gen_helper_1_2i(do_lwl, t1, t0, t1, ctx->mem_idx);
1168
        gen_store_gpr(t1, rt);
1169
        opn = "lwl";
1170
        break;
1171
    case OPC_SWL:
1172
        save_cpu_state(ctx, 1);
1173
        gen_load_gpr(t1, rt);
1174
        tcg_gen_helper_0_2i(do_swl, t0, t1, ctx->mem_idx);
1175
        opn = "swr";
1176
        break;
1177
    case OPC_LWR:
1178
        save_cpu_state(ctx, 1);
1179
        gen_load_gpr(t1, rt);
1180
        tcg_gen_helper_1_2i(do_lwr, t1, t0, t1, ctx->mem_idx);
1181
        gen_store_gpr(t1, rt);
1182
        opn = "lwr";
1183
        break;
1184
    case OPC_SWR:
1185
        save_cpu_state(ctx, 1);
1186
        gen_load_gpr(t1, rt);
1187
        tcg_gen_helper_0_2i(do_swr, t0, t1, ctx->mem_idx);
1188
        opn = "swr";
1189
        break;
1190
    case OPC_LL:
1191
        op_ldst_ll(t0, t1, ctx);
1192
        gen_store_gpr(t0, rt);
1193
        opn = "ll";
1194
        break;
1195
    case OPC_SC:
1196
        save_cpu_state(ctx, 1);
1197
        gen_load_gpr(t1, rt);
1198
        op_ldst_sc(t0, t1, ctx);
1199
        gen_store_gpr(t0, rt);
1200
        opn = "sc";
1201
        break;
1202
    default:
1203
        MIPS_INVAL(opn);
1204
        generate_exception(ctx, EXCP_RI);
1205
        goto out;
1206
    }
1207
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1208
 out:
1209
    tcg_temp_free(t0);
1210
    tcg_temp_free(t1);
1211
}
1212

    
1213
/* Load and store */
1214
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1215
                          int base, int16_t offset)
1216
{
1217
    const char *opn = "flt_ldst";
1218
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1219

    
1220
    if (base == 0) {
1221
        tcg_gen_movi_tl(t0, offset);
1222
    } else if (offset == 0) {
1223
        gen_load_gpr(t0, base);
1224
    } else {
1225
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1226

    
1227
        gen_load_gpr(t0, base);
1228
        tcg_gen_movi_tl(t1, offset);
1229
        gen_op_addr_add(t0, t1);
1230
        tcg_temp_free(t1);
1231
    }
1232
    /* Don't do NOP if destination is zero: we must perform the actual
1233
       memory access. */
1234
    switch (opc) {
1235
    case OPC_LWC1:
1236
        {
1237
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1238

    
1239
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
1240
            gen_store_fpr32(fp0, ft);
1241
            tcg_temp_free(fp0);
1242
        }
1243
        opn = "lwc1";
1244
        break;
1245
    case OPC_SWC1:
1246
        {
1247
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1248

    
1249
            gen_load_fpr32(fp0, ft);
1250
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
1251
            tcg_temp_free(fp0);
1252
        }
1253
        opn = "swc1";
1254
        break;
1255
    case OPC_LDC1:
1256
        {
1257
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1258

    
1259
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1260
            gen_store_fpr64(ctx, fp0, ft);
1261
            tcg_temp_free(fp0);
1262
        }
1263
        opn = "ldc1";
1264
        break;
1265
    case OPC_SDC1:
1266
        {
1267
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1268

    
1269
            gen_load_fpr64(ctx, fp0, ft);
1270
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1271
            tcg_temp_free(fp0);
1272
        }
1273
        opn = "sdc1";
1274
        break;
1275
    default:
1276
        MIPS_INVAL(opn);
1277
        generate_exception(ctx, EXCP_RI);
1278
        goto out;
1279
    }
1280
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1281
 out:
1282
    tcg_temp_free(t0);
1283
}
1284

    
1285
/* Arithmetic with immediate operand */
1286
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1287
                           int rt, int rs, int16_t imm)
1288
{
1289
    target_ulong uimm;
1290
    const char *opn = "imm arith";
1291
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1292

    
1293
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1294
        /* If no destination, treat it as a NOP.
1295
           For addi, we must generate the overflow exception when needed. */
1296
        MIPS_DEBUG("NOP");
1297
        goto out;
1298
    }
1299
    uimm = (uint16_t)imm;
1300
    switch (opc) {
1301
    case OPC_ADDI:
1302
    case OPC_ADDIU:
1303
#if defined(TARGET_MIPS64)
1304
    case OPC_DADDI:
1305
    case OPC_DADDIU:
1306
#endif
1307
    case OPC_SLTI:
1308
    case OPC_SLTIU:
1309
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1310
        /* Fall through. */
1311
    case OPC_ANDI:
1312
    case OPC_ORI:
1313
    case OPC_XORI:
1314
        gen_load_gpr(t0, rs);
1315
        break;
1316
    case OPC_LUI:
1317
        tcg_gen_movi_tl(t0, imm << 16);
1318
        break;
1319
    case OPC_SLL:
1320
    case OPC_SRA:
1321
    case OPC_SRL:
1322
#if defined(TARGET_MIPS64)
1323
    case OPC_DSLL:
1324
    case OPC_DSRA:
1325
    case OPC_DSRL:
1326
    case OPC_DSLL32:
1327
    case OPC_DSRA32:
1328
    case OPC_DSRL32:
1329
#endif
1330
        uimm &= 0x1f;
1331
        gen_load_gpr(t0, rs);
1332
        break;
1333
    }
1334
    switch (opc) {
1335
    case OPC_ADDI:
1336
        {
1337
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1338
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1339
            int l1 = gen_new_label();
1340

    
1341
            save_cpu_state(ctx, 1);
1342
            tcg_gen_ext32s_tl(r_tmp1, t0);
1343
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1344

    
1345
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1346
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1347
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1348
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1349
            tcg_temp_free(r_tmp2);
1350
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1351
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1352
            tcg_temp_free(r_tmp1);
1353
            /* operands of same sign, result different sign */
1354
            generate_exception(ctx, EXCP_OVERFLOW);
1355
            gen_set_label(l1);
1356

    
1357
            tcg_gen_ext32s_tl(t0, t0);
1358
        }
1359
        opn = "addi";
1360
        break;
1361
    case OPC_ADDIU:
1362
        tcg_gen_ext32s_tl(t0, t0);
1363
        tcg_gen_addi_tl(t0, t0, uimm);
1364
        tcg_gen_ext32s_tl(t0, t0);
1365
        opn = "addiu";
1366
        break;
1367
#if defined(TARGET_MIPS64)
1368
    case OPC_DADDI:
1369
        {
1370
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1371
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1372
            int l1 = gen_new_label();
1373

    
1374
            save_cpu_state(ctx, 1);
1375
            tcg_gen_mov_tl(r_tmp1, t0);
1376
            tcg_gen_addi_tl(t0, t0, uimm);
1377

    
1378
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1379
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1380
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1381
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1382
            tcg_temp_free(r_tmp2);
1383
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1384
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1385
            tcg_temp_free(r_tmp1);
1386
            /* operands of same sign, result different sign */
1387
            generate_exception(ctx, EXCP_OVERFLOW);
1388
            gen_set_label(l1);
1389
        }
1390
        opn = "daddi";
1391
        break;
1392
    case OPC_DADDIU:
1393
        tcg_gen_addi_tl(t0, t0, uimm);
1394
        opn = "daddiu";
1395
        break;
1396
#endif
1397
    case OPC_SLTI:
1398
        gen_op_lti(t0, uimm);
1399
        opn = "slti";
1400
        break;
1401
    case OPC_SLTIU:
1402
        gen_op_ltiu(t0, uimm);
1403
        opn = "sltiu";
1404
        break;
1405
    case OPC_ANDI:
1406
        tcg_gen_andi_tl(t0, t0, uimm);
1407
        opn = "andi";
1408
        break;
1409
    case OPC_ORI:
1410
        tcg_gen_ori_tl(t0, t0, uimm);
1411
        opn = "ori";
1412
        break;
1413
    case OPC_XORI:
1414
        tcg_gen_xori_tl(t0, t0, uimm);
1415
        opn = "xori";
1416
        break;
1417
    case OPC_LUI:
1418
        opn = "lui";
1419
        break;
1420
    case OPC_SLL:
1421
        tcg_gen_ext32u_tl(t0, t0);
1422
        tcg_gen_shli_tl(t0, t0, uimm);
1423
        tcg_gen_ext32s_tl(t0, t0);
1424
        opn = "sll";
1425
        break;
1426
    case OPC_SRA:
1427
        tcg_gen_ext32s_tl(t0, t0);
1428
        tcg_gen_sari_tl(t0, t0, uimm);
1429
        tcg_gen_ext32s_tl(t0, t0);
1430
        opn = "sra";
1431
        break;
1432
    case OPC_SRL:
1433
        switch ((ctx->opcode >> 21) & 0x1f) {
1434
        case 0:
1435
            tcg_gen_ext32u_tl(t0, t0);
1436
            tcg_gen_shri_tl(t0, t0, uimm);
1437
            tcg_gen_ext32s_tl(t0, t0);
1438
            opn = "srl";
1439
            break;
1440
        case 1:
1441
            /* rotr is decoded as srl on non-R2 CPUs */
1442
            if (env->insn_flags & ISA_MIPS32R2) {
1443
                if (uimm != 0) {
1444
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1445
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1446

    
1447
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1448
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1449
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1450
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1451
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1452
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1453
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1454
                    tcg_temp_free(r_tmp1);
1455
                    tcg_temp_free(r_tmp2);
1456
                }
1457
                opn = "rotr";
1458
            } else {
1459
                tcg_gen_ext32u_tl(t0, t0);
1460
                tcg_gen_shri_tl(t0, t0, uimm);
1461
                tcg_gen_ext32s_tl(t0, t0);
1462
                opn = "srl";
1463
            }
1464
            break;
1465
        default:
1466
            MIPS_INVAL("invalid srl flag");
1467
            generate_exception(ctx, EXCP_RI);
1468
            break;
1469
        }
1470
        break;
1471
#if defined(TARGET_MIPS64)
1472
    case OPC_DSLL:
1473
        tcg_gen_shli_tl(t0, t0, uimm);
1474
        opn = "dsll";
1475
        break;
1476
    case OPC_DSRA:
1477
        tcg_gen_sari_tl(t0, t0, uimm);
1478
        opn = "dsra";
1479
        break;
1480
    case OPC_DSRL:
1481
        switch ((ctx->opcode >> 21) & 0x1f) {
1482
        case 0:
1483
            tcg_gen_shri_tl(t0, t0, uimm);
1484
            opn = "dsrl";
1485
            break;
1486
        case 1:
1487
            /* drotr is decoded as dsrl on non-R2 CPUs */
1488
            if (env->insn_flags & ISA_MIPS32R2) {
1489
                if (uimm != 0) {
1490
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1491

    
1492
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1493
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1494
                    tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1495
                    tcg_gen_shri_tl(t0, t0, uimm);
1496
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1497
                    tcg_temp_free(r_tmp1);
1498
                }
1499
                opn = "drotr";
1500
            } else {
1501
                tcg_gen_shri_tl(t0, t0, uimm);
1502
                opn = "dsrl";
1503
            }
1504
            break;
1505
        default:
1506
            MIPS_INVAL("invalid dsrl flag");
1507
            generate_exception(ctx, EXCP_RI);
1508
            break;
1509
        }
1510
        break;
1511
    case OPC_DSLL32:
1512
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1513
        opn = "dsll32";
1514
        break;
1515
    case OPC_DSRA32:
1516
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1517
        opn = "dsra32";
1518
        break;
1519
    case OPC_DSRL32:
1520
        switch ((ctx->opcode >> 21) & 0x1f) {
1521
        case 0:
1522
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1523
            opn = "dsrl32";
1524
            break;
1525
        case 1:
1526
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1527
            if (env->insn_flags & ISA_MIPS32R2) {
1528
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1529
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1530

    
1531
                tcg_gen_movi_tl(r_tmp1, 0x40);
1532
                tcg_gen_movi_tl(r_tmp2, 32);
1533
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1534
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1535
                tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1536
                tcg_gen_shr_tl(t0, t0, r_tmp2);
1537
                tcg_gen_or_tl(t0, t0, r_tmp1);
1538
                tcg_temp_free(r_tmp1);
1539
                tcg_temp_free(r_tmp2);
1540
                opn = "drotr32";
1541
            } else {
1542
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1543
                opn = "dsrl32";
1544
            }
1545
            break;
1546
        default:
1547
            MIPS_INVAL("invalid dsrl32 flag");
1548
            generate_exception(ctx, EXCP_RI);
1549
            break;
1550
        }
1551
        break;
1552
#endif
1553
    default:
1554
        MIPS_INVAL(opn);
1555
        generate_exception(ctx, EXCP_RI);
1556
        goto out;
1557
    }
1558
    gen_store_gpr(t0, rt);
1559
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1560
 out:
1561
    tcg_temp_free(t0);
1562
}
1563

    
1564
/* Arithmetic */
1565
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1566
                       int rd, int rs, int rt)
1567
{
1568
    const char *opn = "arith";
1569
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1570
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1571

    
1572
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1573
       && opc != OPC_DADD && opc != OPC_DSUB) {
1574
        /* If no destination, treat it as a NOP.
1575
           For add & sub, we must generate the overflow exception when needed. */
1576
        MIPS_DEBUG("NOP");
1577
        goto out;
1578
    }
1579
    gen_load_gpr(t0, rs);
1580
    /* Specialcase the conventional move operation. */
1581
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1582
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1583
        gen_store_gpr(t0, rd);
1584
        goto out;
1585
    }
1586
    gen_load_gpr(t1, rt);
1587
    switch (opc) {
1588
    case OPC_ADD:
1589
        {
1590
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1591
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1592
            int l1 = gen_new_label();
1593

    
1594
            save_cpu_state(ctx, 1);
1595
            tcg_gen_ext32s_tl(r_tmp1, t0);
1596
            tcg_gen_ext32s_tl(r_tmp2, t1);
1597
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1598

    
1599
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1600
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1601
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1602
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1603
            tcg_temp_free(r_tmp2);
1604
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1605
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1606
            tcg_temp_free(r_tmp1);
1607
            /* operands of same sign, result different sign */
1608
            generate_exception(ctx, EXCP_OVERFLOW);
1609
            gen_set_label(l1);
1610

    
1611
            tcg_gen_ext32s_tl(t0, t0);
1612
        }
1613
        opn = "add";
1614
        break;
1615
    case OPC_ADDU:
1616
        tcg_gen_ext32s_tl(t0, t0);
1617
        tcg_gen_ext32s_tl(t1, t1);
1618
        tcg_gen_add_tl(t0, t0, t1);
1619
        tcg_gen_ext32s_tl(t0, t0);
1620
        opn = "addu";
1621
        break;
1622
    case OPC_SUB:
1623
        {
1624
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1625
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1626
            int l1 = gen_new_label();
1627

    
1628
            save_cpu_state(ctx, 1);
1629
            tcg_gen_ext32s_tl(r_tmp1, t0);
1630
            tcg_gen_ext32s_tl(r_tmp2, t1);
1631
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1632

    
1633
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1634
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1635
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1636
            tcg_temp_free(r_tmp2);
1637
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1638
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1639
            tcg_temp_free(r_tmp1);
1640
            /* operands of different sign, first operand and result different sign */
1641
            generate_exception(ctx, EXCP_OVERFLOW);
1642
            gen_set_label(l1);
1643

    
1644
            tcg_gen_ext32s_tl(t0, t0);
1645
        }
1646
        opn = "sub";
1647
        break;
1648
    case OPC_SUBU:
1649
        tcg_gen_ext32s_tl(t0, t0);
1650
        tcg_gen_ext32s_tl(t1, t1);
1651
        tcg_gen_sub_tl(t0, t0, t1);
1652
        tcg_gen_ext32s_tl(t0, t0);
1653
        opn = "subu";
1654
        break;
1655
#if defined(TARGET_MIPS64)
1656
    case OPC_DADD:
1657
        {
1658
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1659
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1660
            int l1 = gen_new_label();
1661

    
1662
            save_cpu_state(ctx, 1);
1663
            tcg_gen_mov_tl(r_tmp1, t0);
1664
            tcg_gen_add_tl(t0, t0, t1);
1665

    
1666
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1667
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1668
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1669
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1670
            tcg_temp_free(r_tmp2);
1671
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1672
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1673
            tcg_temp_free(r_tmp1);
1674
            /* operands of same sign, result different sign */
1675
            generate_exception(ctx, EXCP_OVERFLOW);
1676
            gen_set_label(l1);
1677
        }
1678
        opn = "dadd";
1679
        break;
1680
    case OPC_DADDU:
1681
        tcg_gen_add_tl(t0, t0, t1);
1682
        opn = "daddu";
1683
        break;
1684
    case OPC_DSUB:
1685
        {
1686
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1687
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1688
            int l1 = gen_new_label();
1689

    
1690
            save_cpu_state(ctx, 1);
1691
            tcg_gen_mov_tl(r_tmp1, t0);
1692
            tcg_gen_sub_tl(t0, t0, t1);
1693

    
1694
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1695
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1696
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1697
            tcg_temp_free(r_tmp2);
1698
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1699
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1700
            tcg_temp_free(r_tmp1);
1701
            /* operands of different sign, first operand and result different sign */
1702
            generate_exception(ctx, EXCP_OVERFLOW);
1703
            gen_set_label(l1);
1704
        }
1705
        opn = "dsub";
1706
        break;
1707
    case OPC_DSUBU:
1708
        tcg_gen_sub_tl(t0, t0, t1);
1709
        opn = "dsubu";
1710
        break;
1711
#endif
1712
    case OPC_SLT:
1713
        gen_op_lt(t0, t1);
1714
        opn = "slt";
1715
        break;
1716
    case OPC_SLTU:
1717
        gen_op_ltu(t0, t1);
1718
        opn = "sltu";
1719
        break;
1720
    case OPC_AND:
1721
        tcg_gen_and_tl(t0, t0, t1);
1722
        opn = "and";
1723
        break;
1724
    case OPC_NOR:
1725
        tcg_gen_or_tl(t0, t0, t1);
1726
        tcg_gen_not_tl(t0, t0);
1727
        opn = "nor";
1728
        break;
1729
    case OPC_OR:
1730
        tcg_gen_or_tl(t0, t0, t1);
1731
        opn = "or";
1732
        break;
1733
    case OPC_XOR:
1734
        tcg_gen_xor_tl(t0, t0, t1);
1735
        opn = "xor";
1736
        break;
1737
    case OPC_MUL:
1738
        tcg_gen_ext32s_tl(t0, t0);
1739
        tcg_gen_ext32s_tl(t1, t1);
1740
        tcg_gen_mul_tl(t0, t0, t1);
1741
        tcg_gen_ext32s_tl(t0, t0);
1742
        opn = "mul";
1743
        break;
1744
    case OPC_MOVN:
1745
        {
1746
            int l1 = gen_new_label();
1747

    
1748
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1749
            gen_store_gpr(t0, rd);
1750
            gen_set_label(l1);
1751
        }
1752
        opn = "movn";
1753
        goto print;
1754
    case OPC_MOVZ:
1755
        {
1756
            int l1 = gen_new_label();
1757

    
1758
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1759
            gen_store_gpr(t0, rd);
1760
            gen_set_label(l1);
1761
        }
1762
        opn = "movz";
1763
        goto print;
1764
    case OPC_SLLV:
1765
        tcg_gen_ext32u_tl(t0, t0);
1766
        tcg_gen_ext32u_tl(t1, t1);
1767
        tcg_gen_andi_tl(t0, t0, 0x1f);
1768
        tcg_gen_shl_tl(t0, t1, t0);
1769
        tcg_gen_ext32s_tl(t0, t0);
1770
        opn = "sllv";
1771
        break;
1772
    case OPC_SRAV:
1773
        tcg_gen_ext32s_tl(t1, t1);
1774
        tcg_gen_andi_tl(t0, t0, 0x1f);
1775
        tcg_gen_sar_tl(t0, t1, t0);
1776
        tcg_gen_ext32s_tl(t0, t0);
1777
        opn = "srav";
1778
        break;
1779
    case OPC_SRLV:
1780
        switch ((ctx->opcode >> 6) & 0x1f) {
1781
        case 0:
1782
            tcg_gen_ext32u_tl(t1, t1);
1783
            tcg_gen_andi_tl(t0, t0, 0x1f);
1784
            tcg_gen_shr_tl(t0, t1, t0);
1785
            tcg_gen_ext32s_tl(t0, t0);
1786
            opn = "srlv";
1787
            break;
1788
        case 1:
1789
            /* rotrv is decoded as srlv on non-R2 CPUs */
1790
            if (env->insn_flags & ISA_MIPS32R2) {
1791
                int l1 = gen_new_label();
1792
                int l2 = gen_new_label();
1793

    
1794
                tcg_gen_andi_tl(t0, t0, 0x1f);
1795
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1796
                {
1797
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1798
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1799
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1800

    
1801
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1802
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1803
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1804
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1805
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1806
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1807
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1808
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1809
                    tcg_temp_free(r_tmp1);
1810
                    tcg_temp_free(r_tmp2);
1811
                    tcg_temp_free(r_tmp3);
1812
                    tcg_gen_br(l2);
1813
                }
1814
                gen_set_label(l1);
1815
                tcg_gen_mov_tl(t0, t1);
1816
                gen_set_label(l2);
1817
                opn = "rotrv";
1818
            } else {
1819
                tcg_gen_ext32u_tl(t1, t1);
1820
                tcg_gen_andi_tl(t0, t0, 0x1f);
1821
                tcg_gen_shr_tl(t0, t1, t0);
1822
                tcg_gen_ext32s_tl(t0, t0);
1823
                opn = "srlv";
1824
            }
1825
            break;
1826
        default:
1827
            MIPS_INVAL("invalid srlv flag");
1828
            generate_exception(ctx, EXCP_RI);
1829
            break;
1830
        }
1831
        break;
1832
#if defined(TARGET_MIPS64)
1833
    case OPC_DSLLV:
1834
        tcg_gen_andi_tl(t0, t0, 0x3f);
1835
        tcg_gen_shl_tl(t0, t1, t0);
1836
        opn = "dsllv";
1837
        break;
1838
    case OPC_DSRAV:
1839
        tcg_gen_andi_tl(t0, t0, 0x3f);
1840
        tcg_gen_sar_tl(t0, t1, t0);
1841
        opn = "dsrav";
1842
        break;
1843
    case OPC_DSRLV:
1844
        switch ((ctx->opcode >> 6) & 0x1f) {
1845
        case 0:
1846
            tcg_gen_andi_tl(t0, t0, 0x3f);
1847
            tcg_gen_shr_tl(t0, t1, t0);
1848
            opn = "dsrlv";
1849
            break;
1850
        case 1:
1851
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1852
            if (env->insn_flags & ISA_MIPS32R2) {
1853
                int l1 = gen_new_label();
1854
                int l2 = gen_new_label();
1855

    
1856
                tcg_gen_andi_tl(t0, t0, 0x3f);
1857
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1858
                {
1859
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1860

    
1861
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1862
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, t0);
1863
                    tcg_gen_shl_tl(r_tmp1, t1, r_tmp1);
1864
                    tcg_gen_shr_tl(t0, t1, t0);
1865
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1866
                    tcg_temp_free(r_tmp1);
1867
                    tcg_gen_br(l2);
1868
                }
1869
                gen_set_label(l1);
1870
                tcg_gen_mov_tl(t0, t1);
1871
                gen_set_label(l2);
1872
                opn = "drotrv";
1873
            } else {
1874
                tcg_gen_andi_tl(t0, t0, 0x3f);
1875
                tcg_gen_shr_tl(t0, t1, t0);
1876
                opn = "dsrlv";
1877
            }
1878
            break;
1879
        default:
1880
            MIPS_INVAL("invalid dsrlv flag");
1881
            generate_exception(ctx, EXCP_RI);
1882
            break;
1883
        }
1884
        break;
1885
#endif
1886
    default:
1887
        MIPS_INVAL(opn);
1888
        generate_exception(ctx, EXCP_RI);
1889
        goto out;
1890
    }
1891
    gen_store_gpr(t0, rd);
1892
 print:
1893
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1894
 out:
1895
    tcg_temp_free(t0);
1896
    tcg_temp_free(t1);
1897
}
1898

    
1899
/* Arithmetic on HI/LO registers */
1900
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1901
{
1902
    const char *opn = "hilo";
1903
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1904

    
1905
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1906
        /* Treat as NOP. */
1907
        MIPS_DEBUG("NOP");
1908
        goto out;
1909
    }
1910
    switch (opc) {
1911
    case OPC_MFHI:
1912
        gen_load_HI(t0, 0);
1913
        gen_store_gpr(t0, reg);
1914
        opn = "mfhi";
1915
        break;
1916
    case OPC_MFLO:
1917
        gen_load_LO(t0, 0);
1918
        gen_store_gpr(t0, reg);
1919
        opn = "mflo";
1920
        break;
1921
    case OPC_MTHI:
1922
        gen_load_gpr(t0, reg);
1923
        gen_store_HI(t0, 0);
1924
        opn = "mthi";
1925
        break;
1926
    case OPC_MTLO:
1927
        gen_load_gpr(t0, reg);
1928
        gen_store_LO(t0, 0);
1929
        opn = "mtlo";
1930
        break;
1931
    default:
1932
        MIPS_INVAL(opn);
1933
        generate_exception(ctx, EXCP_RI);
1934
        goto out;
1935
    }
1936
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1937
 out:
1938
    tcg_temp_free(t0);
1939
}
1940

    
1941
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1942
                        int rs, int rt)
1943
{
1944
    const char *opn = "mul/div";
1945
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1946
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1947

    
1948
    gen_load_gpr(t0, rs);
1949
    gen_load_gpr(t1, rt);
1950
    switch (opc) {
1951
    case OPC_DIV:
1952
        {
1953
            int l1 = gen_new_label();
1954

    
1955
            tcg_gen_ext32s_tl(t0, t0);
1956
            tcg_gen_ext32s_tl(t1, t1);
1957
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1958
            {
1959
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1960
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1961
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1962

    
1963
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1964
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1965
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1966
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1967
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1968
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1969
                tcg_temp_free(r_tmp1);
1970
                tcg_temp_free(r_tmp2);
1971
                tcg_temp_free(r_tmp3);
1972
                tcg_gen_ext32s_tl(t0, t0);
1973
                tcg_gen_ext32s_tl(t1, t1);
1974
                gen_store_LO(t0, 0);
1975
                gen_store_HI(t1, 0);
1976
            }
1977
            gen_set_label(l1);
1978
        }
1979
        opn = "div";
1980
        break;
1981
    case OPC_DIVU:
1982
        {
1983
            int l1 = gen_new_label();
1984

    
1985
            tcg_gen_ext32s_tl(t1, t1);
1986
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1987
            {
1988
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1989
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1990
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1991

    
1992
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1993
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1994
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1995
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1996
                tcg_gen_ext_i32_tl(t0, r_tmp3);
1997
                tcg_gen_ext_i32_tl(t1, r_tmp1);
1998
                tcg_temp_free(r_tmp1);
1999
                tcg_temp_free(r_tmp2);
2000
                tcg_temp_free(r_tmp3);
2001
                gen_store_LO(t0, 0);
2002
                gen_store_HI(t1, 0);
2003
            }
2004
            gen_set_label(l1);
2005
        }
2006
        opn = "divu";
2007
        break;
2008
    case OPC_MULT:
2009
        {
2010
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2011
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2012

    
2013
            tcg_gen_ext32s_tl(t0, t0);
2014
            tcg_gen_ext32s_tl(t1, t1);
2015
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2016
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2017
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2018
            tcg_temp_free(r_tmp2);
2019
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2020
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2021
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2022
            tcg_temp_free(r_tmp1);
2023
            tcg_gen_ext32s_tl(t0, t0);
2024
            tcg_gen_ext32s_tl(t1, t1);
2025
            gen_store_LO(t0, 0);
2026
            gen_store_HI(t1, 0);
2027
        }
2028
        opn = "mult";
2029
        break;
2030
    case OPC_MULTU:
2031
        {
2032
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2033
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2034

    
2035
            tcg_gen_ext32u_tl(t0, t0);
2036
            tcg_gen_ext32u_tl(t1, t1);
2037
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2038
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2039
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2040
            tcg_temp_free(r_tmp2);
2041
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2042
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2043
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2044
            tcg_temp_free(r_tmp1);
2045
            tcg_gen_ext32s_tl(t0, t0);
2046
            tcg_gen_ext32s_tl(t1, t1);
2047
            gen_store_LO(t0, 0);
2048
            gen_store_HI(t1, 0);
2049
        }
2050
        opn = "multu";
2051
        break;
2052
#if defined(TARGET_MIPS64)
2053
    case OPC_DDIV:
2054
        {
2055
            int l1 = gen_new_label();
2056

    
2057
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2058
            {
2059
                int l2 = gen_new_label();
2060

    
2061
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2062
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2063
                {
2064
                    tcg_gen_movi_tl(t1, 0);
2065
                    gen_store_LO(t0, 0);
2066
                    gen_store_HI(t1, 0);
2067
                    tcg_gen_br(l1);
2068
                }
2069
                gen_set_label(l2);
2070
                {
2071
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2072
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2073

    
2074
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2075
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2076
                    gen_store_LO(r_tmp1, 0);
2077
                    gen_store_HI(r_tmp2, 0);
2078
                    tcg_temp_free(r_tmp1);
2079
                    tcg_temp_free(r_tmp2);
2080
                }
2081
            }
2082
            gen_set_label(l1);
2083
        }
2084
        opn = "ddiv";
2085
        break;
2086
    case OPC_DDIVU:
2087
        {
2088
            int l1 = gen_new_label();
2089

    
2090
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2091
            {
2092
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2093
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2094

    
2095
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2096
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2097
                tcg_temp_free(r_tmp1);
2098
                tcg_temp_free(r_tmp2);
2099
                gen_store_LO(r_tmp1, 0);
2100
                gen_store_HI(r_tmp2, 0);
2101
            }
2102
            gen_set_label(l1);
2103
        }
2104
        opn = "ddivu";
2105
        break;
2106
    case OPC_DMULT:
2107
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2108
        opn = "dmult";
2109
        break;
2110
    case OPC_DMULTU:
2111
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2112
        opn = "dmultu";
2113
        break;
2114
#endif
2115
    case OPC_MADD:
2116
        {
2117
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2118
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2119
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2120

    
2121
            tcg_gen_ext32s_tl(t0, t0);
2122
            tcg_gen_ext32s_tl(t1, t1);
2123
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2124
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2125
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2126
            gen_load_LO(t0, 0);
2127
            gen_load_HI(t1, 0);
2128
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2129
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2130
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2131
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2132
            tcg_temp_free(r_tmp3);
2133
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2134
            tcg_temp_free(r_tmp2);
2135
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2136
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2137
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2138
            tcg_temp_free(r_tmp1);
2139
            tcg_gen_ext32s_tl(t0, t0);
2140
            tcg_gen_ext32s_tl(t1, t1);
2141
            gen_store_LO(t0, 0);
2142
            gen_store_HI(t1, 0);
2143
        }
2144
        opn = "madd";
2145
        break;
2146
    case OPC_MADDU:
2147
       {
2148
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2149
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2150
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2151

    
2152
            tcg_gen_ext32u_tl(t0, t0);
2153
            tcg_gen_ext32u_tl(t1, t1);
2154
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2155
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2156
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2157
            gen_load_LO(t0, 0);
2158
            gen_load_HI(t1, 0);
2159
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2160
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2161
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2162
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2163
            tcg_temp_free(r_tmp3);
2164
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2165
            tcg_temp_free(r_tmp2);
2166
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2167
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2168
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2169
            tcg_temp_free(r_tmp1);
2170
            tcg_gen_ext32s_tl(t0, t0);
2171
            tcg_gen_ext32s_tl(t1, t1);
2172
            gen_store_LO(t0, 0);
2173
            gen_store_HI(t1, 0);
2174
        }
2175
        opn = "maddu";
2176
        break;
2177
    case OPC_MSUB:
2178
        {
2179
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2180
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2181
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2182

    
2183
            tcg_gen_ext32s_tl(t0, t0);
2184
            tcg_gen_ext32s_tl(t1, t1);
2185
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2186
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2187
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2188
            gen_load_LO(t0, 0);
2189
            gen_load_HI(t1, 0);
2190
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2191
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2192
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2193
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2194
            tcg_temp_free(r_tmp3);
2195
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2196
            tcg_temp_free(r_tmp2);
2197
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2198
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2199
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2200
            tcg_temp_free(r_tmp1);
2201
            tcg_gen_ext32s_tl(t0, t0);
2202
            tcg_gen_ext32s_tl(t1, t1);
2203
            gen_store_LO(t0, 0);
2204
            gen_store_HI(t1, 0);
2205
        }
2206
        opn = "msub";
2207
        break;
2208
    case OPC_MSUBU:
2209
        {
2210
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2211
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2212
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2213

    
2214
            tcg_gen_ext32u_tl(t0, t0);
2215
            tcg_gen_ext32u_tl(t1, t1);
2216
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2217
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2218
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2219
            gen_load_LO(t0, 0);
2220
            gen_load_HI(t1, 0);
2221
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2222
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2223
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2224
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2225
            tcg_temp_free(r_tmp3);
2226
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2227
            tcg_temp_free(r_tmp2);
2228
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2229
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2230
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2231
            tcg_temp_free(r_tmp1);
2232
            tcg_gen_ext32s_tl(t0, t0);
2233
            tcg_gen_ext32s_tl(t1, t1);
2234
            gen_store_LO(t0, 0);
2235
            gen_store_HI(t1, 0);
2236
        }
2237
        opn = "msubu";
2238
        break;
2239
    default:
2240
        MIPS_INVAL(opn);
2241
        generate_exception(ctx, EXCP_RI);
2242
        goto out;
2243
    }
2244
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2245
 out:
2246
    tcg_temp_free(t0);
2247
    tcg_temp_free(t1);
2248
}
2249

    
2250
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2251
                            int rd, int rs, int rt)
2252
{
2253
    const char *opn = "mul vr54xx";
2254
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2255
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2256

    
2257
    gen_load_gpr(t0, rs);
2258
    gen_load_gpr(t1, rt);
2259

    
2260
    switch (opc) {
2261
    case OPC_VR54XX_MULS:
2262
        tcg_gen_helper_1_2(do_muls, t0, t0, t1);
2263
        opn = "muls";
2264
        break;
2265
    case OPC_VR54XX_MULSU:
2266
        tcg_gen_helper_1_2(do_mulsu, t0, t0, t1);
2267
        opn = "mulsu";
2268
        break;
2269
    case OPC_VR54XX_MACC:
2270
        tcg_gen_helper_1_2(do_macc, t0, t0, t1);
2271
        opn = "macc";
2272
        break;
2273
    case OPC_VR54XX_MACCU:
2274
        tcg_gen_helper_1_2(do_maccu, t0, t0, t1);
2275
        opn = "maccu";
2276
        break;
2277
    case OPC_VR54XX_MSAC:
2278
        tcg_gen_helper_1_2(do_msac, t0, t0, t1);
2279
        opn = "msac";
2280
        break;
2281
    case OPC_VR54XX_MSACU:
2282
        tcg_gen_helper_1_2(do_msacu, t0, t0, t1);
2283
        opn = "msacu";
2284
        break;
2285
    case OPC_VR54XX_MULHI:
2286
        tcg_gen_helper_1_2(do_mulhi, t0, t0, t1);
2287
        opn = "mulhi";
2288
        break;
2289
    case OPC_VR54XX_MULHIU:
2290
        tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1);
2291
        opn = "mulhiu";
2292
        break;
2293
    case OPC_VR54XX_MULSHI:
2294
        tcg_gen_helper_1_2(do_mulshi, t0, t0, t1);
2295
        opn = "mulshi";
2296
        break;
2297
    case OPC_VR54XX_MULSHIU:
2298
        tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1);
2299
        opn = "mulshiu";
2300
        break;
2301
    case OPC_VR54XX_MACCHI:
2302
        tcg_gen_helper_1_2(do_macchi, t0, t0, t1);
2303
        opn = "macchi";
2304
        break;
2305
    case OPC_VR54XX_MACCHIU:
2306
        tcg_gen_helper_1_2(do_macchiu, t0, t0, t1);
2307
        opn = "macchiu";
2308
        break;
2309
    case OPC_VR54XX_MSACHI:
2310
        tcg_gen_helper_1_2(do_msachi, t0, t0, t1);
2311
        opn = "msachi";
2312
        break;
2313
    case OPC_VR54XX_MSACHIU:
2314
        tcg_gen_helper_1_2(do_msachiu, t0, t0, t1);
2315
        opn = "msachiu";
2316
        break;
2317
    default:
2318
        MIPS_INVAL("mul vr54xx");
2319
        generate_exception(ctx, EXCP_RI);
2320
        goto out;
2321
    }
2322
    gen_store_gpr(t0, rd);
2323
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2324

    
2325
 out:
2326
    tcg_temp_free(t0);
2327
    tcg_temp_free(t1);
2328
}
2329

    
2330
static void gen_cl (DisasContext *ctx, uint32_t opc,
2331
                    int rd, int rs)
2332
{
2333
    const char *opn = "CLx";
2334
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2335

    
2336
    if (rd == 0) {
2337
        /* Treat as NOP. */
2338
        MIPS_DEBUG("NOP");
2339
        goto out;
2340
    }
2341
    gen_load_gpr(t0, rs);
2342
    switch (opc) {
2343
    case OPC_CLO:
2344
        tcg_gen_helper_1_1(do_clo, t0, t0);
2345
        opn = "clo";
2346
        break;
2347
    case OPC_CLZ:
2348
        tcg_gen_helper_1_1(do_clz, t0, t0);
2349
        opn = "clz";
2350
        break;
2351
#if defined(TARGET_MIPS64)
2352
    case OPC_DCLO:
2353
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2354
        opn = "dclo";
2355
        break;
2356
    case OPC_DCLZ:
2357
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2358
        opn = "dclz";
2359
        break;
2360
#endif
2361
    default:
2362
        MIPS_INVAL(opn);
2363
        generate_exception(ctx, EXCP_RI);
2364
        goto out;
2365
    }
2366
    gen_store_gpr(t0, rd);
2367
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2368

    
2369
 out:
2370
    tcg_temp_free(t0);
2371
}
2372

    
2373
/* Traps */
2374
static void gen_trap (DisasContext *ctx, uint32_t opc,
2375
                      int rs, int rt, int16_t imm)
2376
{
2377
    int cond;
2378
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2379
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2380

    
2381
    cond = 0;
2382
    /* Load needed operands */
2383
    switch (opc) {
2384
    case OPC_TEQ:
2385
    case OPC_TGE:
2386
    case OPC_TGEU:
2387
    case OPC_TLT:
2388
    case OPC_TLTU:
2389
    case OPC_TNE:
2390
        /* Compare two registers */
2391
        if (rs != rt) {
2392
            gen_load_gpr(t0, rs);
2393
            gen_load_gpr(t1, rt);
2394
            cond = 1;
2395
        }
2396
        break;
2397
    case OPC_TEQI:
2398
    case OPC_TGEI:
2399
    case OPC_TGEIU:
2400
    case OPC_TLTI:
2401
    case OPC_TLTIU:
2402
    case OPC_TNEI:
2403
        /* Compare register to immediate */
2404
        if (rs != 0 || imm != 0) {
2405
            gen_load_gpr(t0, rs);
2406
            tcg_gen_movi_tl(t1, (int32_t)imm);
2407
            cond = 1;
2408
        }
2409
        break;
2410
    }
2411
    if (cond == 0) {
2412
        switch (opc) {
2413
        case OPC_TEQ:   /* rs == rs */
2414
        case OPC_TEQI:  /* r0 == 0  */
2415
        case OPC_TGE:   /* rs >= rs */
2416
        case OPC_TGEI:  /* r0 >= 0  */
2417
        case OPC_TGEU:  /* rs >= rs unsigned */
2418
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2419
            /* Always trap */
2420
            tcg_gen_movi_tl(t0, 1);
2421
            break;
2422
        case OPC_TLT:   /* rs < rs           */
2423
        case OPC_TLTI:  /* r0 < 0            */
2424
        case OPC_TLTU:  /* rs < rs unsigned  */
2425
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2426
        case OPC_TNE:   /* rs != rs          */
2427
        case OPC_TNEI:  /* r0 != 0           */
2428
            /* Never trap: treat as NOP. */
2429
            goto out;
2430
        default:
2431
            MIPS_INVAL("trap");
2432
            generate_exception(ctx, EXCP_RI);
2433
            goto out;
2434
        }
2435
    } else {
2436
        switch (opc) {
2437
        case OPC_TEQ:
2438
        case OPC_TEQI:
2439
            gen_op_eq(t0, t1);
2440
            break;
2441
        case OPC_TGE:
2442
        case OPC_TGEI:
2443
            gen_op_ge(t0, t1);
2444
            break;
2445
        case OPC_TGEU:
2446
        case OPC_TGEIU:
2447
            gen_op_geu(t0, t1);
2448
            break;
2449
        case OPC_TLT:
2450
        case OPC_TLTI:
2451
            gen_op_lt(t0, t1);
2452
            break;
2453
        case OPC_TLTU:
2454
        case OPC_TLTIU:
2455
            gen_op_ltu(t0, t1);
2456
            break;
2457
        case OPC_TNE:
2458
        case OPC_TNEI:
2459
            gen_op_ne(t0, t1);
2460
            break;
2461
        default:
2462
            MIPS_INVAL("trap");
2463
            generate_exception(ctx, EXCP_RI);
2464
            goto out;
2465
        }
2466
    }
2467
    save_cpu_state(ctx, 1);
2468
    {
2469
        int l1 = gen_new_label();
2470

    
2471
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2472
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2473
        gen_set_label(l1);
2474
    }
2475
    ctx->bstate = BS_STOP;
2476
 out:
2477
    tcg_temp_free(t0);
2478
    tcg_temp_free(t1);
2479
}
2480

    
2481
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2482
{
2483
    TranslationBlock *tb;
2484
    tb = ctx->tb;
2485
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2486
        tcg_gen_goto_tb(n);
2487
        gen_save_pc(dest);
2488
        tcg_gen_exit_tb((long)tb + n);
2489
    } else {
2490
        gen_save_pc(dest);
2491
        tcg_gen_exit_tb(0);
2492
    }
2493
}
2494

    
2495
/* Branches (before delay slot) */
2496
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2497
                                int rs, int rt, int32_t offset)
2498
{
2499
    target_ulong btgt = -1;
2500
    int blink = 0;
2501
    int bcond = 0;
2502
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2503
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2504

    
2505
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2506
#ifdef MIPS_DEBUG_DISAS
2507
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2508
            fprintf(logfile,
2509
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2510
                    ctx->pc);
2511
        }
2512
#endif
2513
        generate_exception(ctx, EXCP_RI);
2514
        goto out;
2515
    }
2516

    
2517
    /* Load needed operands */
2518
    switch (opc) {
2519
    case OPC_BEQ:
2520
    case OPC_BEQL:
2521
    case OPC_BNE:
2522
    case OPC_BNEL:
2523
        /* Compare two registers */
2524
        if (rs != rt) {
2525
            gen_load_gpr(t0, rs);
2526
            gen_load_gpr(t1, rt);
2527
            bcond = 1;
2528
        }
2529
        btgt = ctx->pc + 4 + offset;
2530
        break;
2531
    case OPC_BGEZ:
2532
    case OPC_BGEZAL:
2533
    case OPC_BGEZALL:
2534
    case OPC_BGEZL:
2535
    case OPC_BGTZ:
2536
    case OPC_BGTZL:
2537
    case OPC_BLEZ:
2538
    case OPC_BLEZL:
2539
    case OPC_BLTZ:
2540
    case OPC_BLTZAL:
2541
    case OPC_BLTZALL:
2542
    case OPC_BLTZL:
2543
        /* Compare to zero */
2544
        if (rs != 0) {
2545
            gen_load_gpr(t0, rs);
2546
            bcond = 1;
2547
        }
2548
        btgt = ctx->pc + 4 + offset;
2549
        break;
2550
    case OPC_J:
2551
    case OPC_JAL:
2552
        /* Jump to immediate */
2553
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2554
        break;
2555
    case OPC_JR:
2556
    case OPC_JALR:
2557
        /* Jump to register */
2558
        if (offset != 0 && offset != 16) {
2559
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2560
               others are reserved. */
2561
            MIPS_INVAL("jump hint");
2562
            generate_exception(ctx, EXCP_RI);
2563
            goto out;
2564
        }
2565
        gen_load_gpr(btarget, rs);
2566
        break;
2567
    default:
2568
        MIPS_INVAL("branch/jump");
2569
        generate_exception(ctx, EXCP_RI);
2570
        goto out;
2571
    }
2572
    if (bcond == 0) {
2573
        /* No condition to be computed */
2574
        switch (opc) {
2575
        case OPC_BEQ:     /* rx == rx        */
2576
        case OPC_BEQL:    /* rx == rx likely */
2577
        case OPC_BGEZ:    /* 0 >= 0          */
2578
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2579
        case OPC_BLEZ:    /* 0 <= 0          */
2580
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2581
            /* Always take */
2582
            ctx->hflags |= MIPS_HFLAG_B;
2583
            MIPS_DEBUG("balways");
2584
            break;
2585
        case OPC_BGEZAL:  /* 0 >= 0          */
2586
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2587
            /* Always take and link */
2588
            blink = 31;
2589
            ctx->hflags |= MIPS_HFLAG_B;
2590
            MIPS_DEBUG("balways and link");
2591
            break;
2592
        case OPC_BNE:     /* rx != rx        */
2593
        case OPC_BGTZ:    /* 0 > 0           */
2594
        case OPC_BLTZ:    /* 0 < 0           */
2595
            /* Treat as NOP. */
2596
            MIPS_DEBUG("bnever (NOP)");
2597
            goto out;
2598
        case OPC_BLTZAL:  /* 0 < 0           */
2599
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2600
            gen_store_gpr(t0, 31);
2601
            MIPS_DEBUG("bnever and link");
2602
            goto out;
2603
        case OPC_BLTZALL: /* 0 < 0 likely */
2604
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2605
            gen_store_gpr(t0, 31);
2606
            /* Skip the instruction in the delay slot */
2607
            MIPS_DEBUG("bnever, link and skip");
2608
            ctx->pc += 4;
2609
            goto out;
2610
        case OPC_BNEL:    /* rx != rx likely */
2611
        case OPC_BGTZL:   /* 0 > 0 likely */
2612
        case OPC_BLTZL:   /* 0 < 0 likely */
2613
            /* Skip the instruction in the delay slot */
2614
            MIPS_DEBUG("bnever and skip");
2615
            ctx->pc += 4;
2616
            goto out;
2617
        case OPC_J:
2618
            ctx->hflags |= MIPS_HFLAG_B;
2619
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2620
            break;
2621
        case OPC_JAL:
2622
            blink = 31;
2623
            ctx->hflags |= MIPS_HFLAG_B;
2624
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2625
            break;
2626
        case OPC_JR:
2627
            ctx->hflags |= MIPS_HFLAG_BR;
2628
            MIPS_DEBUG("jr %s", regnames[rs]);
2629
            break;
2630
        case OPC_JALR:
2631
            blink = rt;
2632
            ctx->hflags |= MIPS_HFLAG_BR;
2633
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2634
            break;
2635
        default:
2636
            MIPS_INVAL("branch/jump");
2637
            generate_exception(ctx, EXCP_RI);
2638
            goto out;
2639
        }
2640
    } else {
2641
        switch (opc) {
2642
        case OPC_BEQ:
2643
            gen_op_eq(t0, t1);
2644
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2645
                       regnames[rs], regnames[rt], btgt);
2646
            goto not_likely;
2647
        case OPC_BEQL:
2648
            gen_op_eq(t0, t1);
2649
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2650
                       regnames[rs], regnames[rt], btgt);
2651
            goto likely;
2652
        case OPC_BNE:
2653
            gen_op_ne(t0, t1);
2654
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2655
                       regnames[rs], regnames[rt], btgt);
2656
            goto not_likely;
2657
        case OPC_BNEL:
2658
            gen_op_ne(t0, t1);
2659
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2660
                       regnames[rs], regnames[rt], btgt);
2661
            goto likely;
2662
        case OPC_BGEZ:
2663
            gen_op_gez(t0);
2664
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2665
            goto not_likely;
2666
        case OPC_BGEZL:
2667
            gen_op_gez(t0);
2668
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2669
            goto likely;
2670
        case OPC_BGEZAL:
2671
            gen_op_gez(t0);
2672
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2673
            blink = 31;
2674
            goto not_likely;
2675
        case OPC_BGEZALL:
2676
            gen_op_gez(t0);
2677
            blink = 31;
2678
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2679
            goto likely;
2680
        case OPC_BGTZ:
2681
            gen_op_gtz(t0);
2682
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2683
            goto not_likely;
2684
        case OPC_BGTZL:
2685
            gen_op_gtz(t0);
2686
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2687
            goto likely;
2688
        case OPC_BLEZ:
2689
            gen_op_lez(t0);
2690
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2691
            goto not_likely;
2692
        case OPC_BLEZL:
2693
            gen_op_lez(t0);
2694
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2695
            goto likely;
2696
        case OPC_BLTZ:
2697
            gen_op_ltz(t0);
2698
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2699
            goto not_likely;
2700
        case OPC_BLTZL:
2701
            gen_op_ltz(t0);
2702
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2703
            goto likely;
2704
        case OPC_BLTZAL:
2705
            gen_op_ltz(t0);
2706
            blink = 31;
2707
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2708
        not_likely:
2709
            ctx->hflags |= MIPS_HFLAG_BC;
2710
            tcg_gen_trunc_tl_i32(bcond, t0);
2711
            break;
2712
        case OPC_BLTZALL:
2713
            gen_op_ltz(t0);
2714
            blink = 31;
2715
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2716
        likely:
2717
            ctx->hflags |= MIPS_HFLAG_BL;
2718
            tcg_gen_trunc_tl_i32(bcond, t0);
2719
            break;
2720
        default:
2721
            MIPS_INVAL("conditional branch/jump");
2722
            generate_exception(ctx, EXCP_RI);
2723
            goto out;
2724
        }
2725
    }
2726
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2727
               blink, ctx->hflags, btgt);
2728

    
2729
    ctx->btarget = btgt;
2730
    if (blink > 0) {
2731
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2732
        gen_store_gpr(t0, blink);
2733
    }
2734

    
2735
 out:
2736
    tcg_temp_free(t0);
2737
    tcg_temp_free(t1);
2738
}
2739

    
2740
/* special3 bitfield operations */
2741
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2742
                        int rs, int lsb, int msb)
2743
{
2744
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2745
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2746

    
2747
    gen_load_gpr(t1, rs);
2748
    switch (opc) {
2749
    case OPC_EXT:
2750
        if (lsb + msb > 31)
2751
            goto fail;
2752
        tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
2753
        break;
2754
#if defined(TARGET_MIPS64)
2755
    case OPC_DEXTM:
2756
        if (lsb + msb > 63)
2757
            goto fail;
2758
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
2759
        break;
2760
    case OPC_DEXTU:
2761
        if (lsb + msb > 63)
2762
            goto fail;
2763
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
2764
        break;
2765
    case OPC_DEXT:
2766
        if (lsb + msb > 63)
2767
            goto fail;
2768
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
2769
        break;
2770
#endif
2771
    case OPC_INS:
2772
        if (lsb > msb)
2773
            goto fail;
2774
        gen_load_gpr(t0, rt);
2775
        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
2776
        break;
2777
#if defined(TARGET_MIPS64)
2778
    case OPC_DINSM:
2779
        if (lsb > msb)
2780
            goto fail;
2781
        gen_load_gpr(t0, rt);
2782
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
2783
        break;
2784
    case OPC_DINSU:
2785
        if (lsb > msb)
2786
            goto fail;
2787
        gen_load_gpr(t0, rt);
2788
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
2789
        break;
2790
    case OPC_DINS:
2791
        if (lsb > msb)
2792
            goto fail;
2793
        gen_load_gpr(t0, rt);
2794
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
2795
        break;
2796
#endif
2797
    default:
2798
fail:
2799
        MIPS_INVAL("bitops");
2800
        generate_exception(ctx, EXCP_RI);
2801
        tcg_temp_free(t0);
2802
        tcg_temp_free(t1);
2803
        return;
2804
    }
2805
    gen_store_gpr(t0, rt);
2806
    tcg_temp_free(t0);
2807
    tcg_temp_free(t1);
2808
}
2809

    
2810
#ifndef CONFIG_USER_ONLY
2811
/* CP0 (MMU and control) */
2812
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2813
{
2814
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2815

    
2816
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2817
    tcg_gen_ext_i32_tl(t, r_tmp);
2818
    tcg_temp_free(r_tmp);
2819
}
2820

    
2821
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2822
{
2823
    tcg_gen_ld_tl(t, cpu_env, off);
2824
    tcg_gen_ext32s_tl(t, t);
2825
}
2826

    
2827
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2828
{
2829
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2830

    
2831
    tcg_gen_trunc_tl_i32(r_tmp, t);
2832
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2833
    tcg_temp_free(r_tmp);
2834
}
2835

    
2836
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2837
{
2838
    tcg_gen_ext32s_tl(t, t);
2839
    tcg_gen_st_tl(t, cpu_env, off);
2840
}
2841

    
2842
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2843
{
2844
    const char *rn = "invalid";
2845

    
2846
    if (sel != 0)
2847
        check_insn(env, ctx, ISA_MIPS32);
2848

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

    
3418
die:
3419
#if defined MIPS_DEBUG_DISAS
3420
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3421
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3422
                rn, reg, sel);
3423
    }
3424
#endif
3425
    generate_exception(ctx, EXCP_RI);
3426
}
3427

    
3428
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3429
{
3430
    const char *rn = "invalid";
3431

    
3432
    if (sel != 0)
3433
        check_insn(env, ctx, ISA_MIPS32);
3434

    
3435
    if (use_icount)
3436
        gen_io_start();
3437

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

    
4027
die:
4028
#if defined MIPS_DEBUG_DISAS
4029
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4030
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4031
                rn, reg, sel);
4032
    }
4033
#endif
4034
    generate_exception(ctx, EXCP_RI);
4035
}
4036

    
4037
#if defined(TARGET_MIPS64)
4038
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4039
{
4040
    const char *rn = "invalid";
4041

    
4042
    if (sel != 0)
4043
        check_insn(env, ctx, ISA_MIPS64);
4044

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

    
4602
die:
4603
#if defined MIPS_DEBUG_DISAS
4604
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4605
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4606
                rn, reg, sel);
4607
    }
4608
#endif
4609
    generate_exception(ctx, EXCP_RI);
4610
}
4611

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

    
4616
    if (sel != 0)
4617
        check_insn(env, ctx, ISA_MIPS64);
4618

    
4619
    if (use_icount)
4620
        gen_io_start();
4621

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

    
5199
die:
5200
    tcg_temp_free(t0);
5201
#if defined MIPS_DEBUG_DISAS
5202
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5203
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5204
                rn, reg, sel);
5205
    }
5206
#endif
5207
    generate_exception(ctx, EXCP_RI);
5208
}
5209
#endif /* TARGET_MIPS64 */
5210

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

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

    
5342
            gen_load_fpr32(fp0, rt);
5343
            tcg_gen_ext_i32_tl(t0, fp0);
5344
            tcg_temp_free(fp0);
5345
        } else {
5346
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5347

    
5348
            gen_load_fpr32h(fp0, rt);
5349
            tcg_gen_ext_i32_tl(t0, fp0);
5350
            tcg_temp_free(fp0);
5351
        }
5352
        break;
5353
    case 3:
5354
        /* XXX: For now we support only a single FPU context. */
5355
        tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt);
5356
        break;
5357
    /* COP2: Not implemented. */
5358
    case 4:
5359
    case 5:
5360
        /* fall through */
5361
    default:
5362
        goto die;
5363
    }
5364
#if defined MIPS_DEBUG_DISAS
5365
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5366
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5367
                rt, u, sel, h);
5368
    }
5369
#endif
5370
    gen_store_gpr(t0, rd);
5371
    tcg_temp_free(t0);
5372
    return;
5373

    
5374
die:
5375
    tcg_temp_free(t0);
5376
#if defined MIPS_DEBUG_DISAS
5377
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5378
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5379
                rt, u, sel, h);
5380
    }
5381
#endif
5382
    generate_exception(ctx, EXCP_RI);
5383
}
5384

    
5385
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5386
                     int u, int sel, int h)
5387
{
5388
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5389
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5390

    
5391
    gen_load_gpr(t0, rt);
5392
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5393
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5394
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5395
        /* NOP */ ;
5396
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5397
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5398
        /* NOP */ ;
5399
    else if (u == 0) {
5400
        switch (rd) {
5401
        case 2:
5402
            switch (sel) {
5403
            case 1:
5404
                tcg_gen_helper_0_1(do_mttc0_tcstatus, t0);
5405
                break;
5406
            case 2:
5407
                tcg_gen_helper_0_1(do_mttc0_tcbind, t0);
5408
                break;
5409
            case 3:
5410
                tcg_gen_helper_0_1(do_mttc0_tcrestart, t0);
5411
                break;
5412
            case 4:
5413
                tcg_gen_helper_0_1(do_mttc0_tchalt, t0);
5414
                break;
5415
            case 5:
5416
                tcg_gen_helper_0_1(do_mttc0_tccontext, t0);
5417
                break;
5418
            case 6:
5419
                tcg_gen_helper_0_1(do_mttc0_tcschedule, t0);
5420
                break;
5421
            case 7:
5422
                tcg_gen_helper_0_1(do_mttc0_tcschefback, t0);
5423
                break;
5424
            default:
5425
                gen_mtc0(env, ctx, t0, rd, sel);
5426
                break;
5427
            }
5428
            break;
5429
        case 10:
5430
            switch (sel) {
5431
            case 0:
5432
                tcg_gen_helper_0_1(do_mttc0_entryhi, t0);
5433
                break;
5434
            default:
5435
                gen_mtc0(env, ctx, t0, rd, sel);
5436
                break;
5437
            }
5438
        case 12:
5439
            switch (sel) {
5440
            case 0:
5441
                tcg_gen_helper_0_1(do_mttc0_status, t0);
5442
                break;
5443
            default:
5444
                gen_mtc0(env, ctx, t0, rd, sel);
5445
                break;
5446
            }
5447
        case 23:
5448
            switch (sel) {
5449
            case 0:
5450
                tcg_gen_helper_0_1(do_mttc0_debug, t0);
5451
                break;
5452
            default:
5453
                gen_mtc0(env, ctx, t0, rd, sel);
5454
                break;
5455
            }
5456
            break;
5457
        default:
5458
            gen_mtc0(env, ctx, t0, rd, sel);
5459
        }
5460
    } else switch (sel) {
5461
    /* GPR registers. */
5462
    case 0:
5463
        tcg_gen_helper_0_1i(do_mttgpr, t0, rd);
5464
        break;
5465
    /* Auxiliary CPU registers */
5466
    case 1:
5467
        switch (rd) {
5468
        case 0:
5469
            tcg_gen_helper_0_1i(do_mttlo, t0, 0);
5470
            break;
5471
        case 1:
5472
            tcg_gen_helper_0_1i(do_mtthi, t0, 0);
5473
            break;
5474
        case 2:
5475
            tcg_gen_helper_0_1i(do_mttacx, t0, 0);
5476
            break;
5477
        case 4:
5478
            tcg_gen_helper_0_1i(do_mttlo, t0, 1);
5479
            break;
5480
        case 5:
5481
            tcg_gen_helper_0_1i(do_mtthi, t0, 1);
5482
            break;
5483
        case 6:
5484
            tcg_gen_helper_0_1i(do_mttacx, t0, 1);
5485
            break;
5486
        case 8:
5487
            tcg_gen_helper_0_1i(do_mttlo, t0, 2);
5488
            break;
5489
        case 9:
5490
            tcg_gen_helper_0_1i(do_mtthi, t0, 2);
5491
            break;
5492
        case 10:
5493
            tcg_gen_helper_0_1i(do_mttacx, t0, 2);
5494
            break;
5495
        case 12:
5496
            tcg_gen_helper_0_1i(do_mttlo, t0, 3);
5497
            break;
5498
        case 13:
5499
            tcg_gen_helper_0_1i(do_mtthi, t0, 3);
5500
            break;
5501
        case 14:
5502
            tcg_gen_helper_0_1i(do_mttacx, t0, 3);
5503
            break;
5504
        case 16:
5505
            tcg_gen_helper_0_1(do_mttdsp, t0);
5506
            break;
5507
        default:
5508
            goto die;
5509
        }
5510
        break;
5511
    /* Floating point (COP1). */
5512
    case 2:
5513
        /* XXX: For now we support only a single FPU context. */
5514
        if (h == 0) {
5515
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5516

    
5517
            tcg_gen_trunc_tl_i32(fp0, t0);
5518
            gen_store_fpr32(fp0, rd);
5519
            tcg_temp_free(fp0);
5520
        } else {
5521
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5522

    
5523
            tcg_gen_trunc_tl_i32(fp0, t0);
5524
            gen_store_fpr32h(fp0, rd);
5525
            tcg_temp_free(fp0);
5526
        }
5527
        break;
5528
    case 3:
5529
        /* XXX: For now we support only a single FPU context. */
5530
        tcg_gen_helper_0_1i(do_ctc1, t0, rd);
5531
        break;
5532
    /* COP2: Not implemented. */
5533
    case 4:
5534
    case 5:
5535
        /* fall through */
5536
    default:
5537
        goto die;
5538
    }
5539
#if defined MIPS_DEBUG_DISAS
5540
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5541
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5542
                rd, u, sel, h);
5543
    }
5544
#endif
5545
    tcg_temp_free(t0);
5546
    return;
5547

    
5548
die:
5549
    tcg_temp_free(t0);
5550
#if defined MIPS_DEBUG_DISAS
5551
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5552
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5553
                rd, u, sel, h);
5554
    }
5555
#endif
5556
    generate_exception(ctx, EXCP_RI);
5557
}
5558

    
5559
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5560
{
5561
    const char *opn = "ldst";
5562

    
5563
    switch (opc) {
5564
    case OPC_MFC0:
5565
        if (rt == 0) {
5566
            /* Treat as NOP. */
5567
            return;
5568
        }
5569
        {
5570
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5571

    
5572
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5573
            gen_store_gpr(t0, rt);
5574
            tcg_temp_free(t0);
5575
        }
5576
        opn = "mfc0";
5577
        break;
5578
    case OPC_MTC0:
5579
        {
5580
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5581

    
5582
            gen_load_gpr(t0, rt);
5583
            save_cpu_state(ctx, 1);
5584
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5585
            tcg_temp_free(t0);
5586
        }
5587
        opn = "mtc0";
5588
        break;
5589
#if defined(TARGET_MIPS64)
5590
    case OPC_DMFC0:
5591
        check_insn(env, ctx, ISA_MIPS3);
5592
        if (rt == 0) {
5593
            /* Treat as NOP. */
5594
            return;
5595
        }
5596
        {
5597
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5598

    
5599
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5600
            gen_store_gpr(t0, rt);
5601
            tcg_temp_free(t0);
5602
        }
5603
        opn = "dmfc0";
5604
        break;
5605
    case OPC_DMTC0:
5606
        check_insn(env, ctx, ISA_MIPS3);
5607
        {
5608
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5609

    
5610
            gen_load_gpr(t0, rt);
5611
            save_cpu_state(ctx, 1);
5612
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5613
            tcg_temp_free(t0);
5614
        }
5615
        opn = "dmtc0";
5616
        break;
5617
#endif
5618
    case OPC_MFTR:
5619
        check_insn(env, ctx, ASE_MT);
5620
        if (rd == 0) {
5621
            /* Treat as NOP. */
5622
            return;
5623
        }
5624
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5625
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5626
        opn = "mftr";
5627
        break;
5628
    case OPC_MTTR:
5629
        check_insn(env, ctx, ASE_MT);
5630
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5631
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5632
        opn = "mttr";
5633
        break;
5634
    case OPC_TLBWI:
5635
        opn = "tlbwi";
5636
        if (!env->tlb->do_tlbwi)
5637
            goto die;
5638
        tcg_gen_helper_0_0(env->tlb->do_tlbwi);
5639
        break;
5640
    case OPC_TLBWR:
5641
        opn = "tlbwr";
5642
        if (!env->tlb->do_tlbwr)
5643
            goto die;
5644
        tcg_gen_helper_0_0(env->tlb->do_tlbwr);
5645
        break;
5646
    case OPC_TLBP:
5647
        opn = "tlbp";
5648
        if (!env->tlb->do_tlbp)
5649
            goto die;
5650
        tcg_gen_helper_0_0(env->tlb->do_tlbp);
5651
        break;
5652
    case OPC_TLBR:
5653
        opn = "tlbr";
5654
        if (!env->tlb->do_tlbr)
5655
            goto die;
5656
        tcg_gen_helper_0_0(env->tlb->do_tlbr);
5657
        break;
5658
    case OPC_ERET:
5659
        opn = "eret";
5660
        check_insn(env, ctx, ISA_MIPS2);
5661
        save_cpu_state(ctx, 1);
5662
        tcg_gen_helper_0_0(do_eret);
5663
        ctx->bstate = BS_EXCP;
5664
        break;
5665
    case OPC_DERET:
5666
        opn = "deret";
5667
        check_insn(env, ctx, ISA_MIPS32);
5668
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5669
            MIPS_INVAL(opn);
5670
            generate_exception(ctx, EXCP_RI);
5671
        } else {
5672
            save_cpu_state(ctx, 1);
5673
            tcg_gen_helper_0_0(do_deret);
5674
            ctx->bstate = BS_EXCP;
5675
        }
5676
        break;
5677
    case OPC_WAIT:
5678
        opn = "wait";
5679
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5680
        /* If we get an exception, we want to restart at next instruction */
5681
        ctx->pc += 4;
5682
        save_cpu_state(ctx, 1);
5683
        ctx->pc -= 4;
5684
        tcg_gen_helper_0_0(do_wait);
5685
        ctx->bstate = BS_EXCP;
5686
        break;
5687
    default:
5688
 die:
5689
        MIPS_INVAL(opn);
5690
        generate_exception(ctx, EXCP_RI);
5691
        return;
5692
    }
5693
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5694
}
5695
#endif /* !CONFIG_USER_ONLY */
5696

    
5697
/* CP1 Branches (before delay slot) */
5698
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5699
                                 int32_t cc, int32_t offset)
5700
{
5701
    target_ulong btarget;
5702
    const char *opn = "cp1 cond branch";
5703
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5704
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5705

    
5706
    if (cc != 0)
5707
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5708

    
5709
    btarget = ctx->pc + 4 + offset;
5710

    
5711
    switch (op) {
5712
    case OPC_BC1F:
5713
        {
5714
            int l1 = gen_new_label();
5715
            int l2 = gen_new_label();
5716
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5717

    
5718
            get_fp_cond(r_tmp1);
5719
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5720
            tcg_temp_free(r_tmp1);
5721
            tcg_gen_not_tl(t0, t0);
5722
            tcg_gen_movi_tl(t1, 0x1 << cc);
5723
            tcg_gen_and_tl(t0, t0, t1);
5724
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5725
            tcg_gen_movi_tl(t0, 0);
5726
            tcg_gen_br(l2);
5727
            gen_set_label(l1);
5728
            tcg_gen_movi_tl(t0, 1);
5729
            gen_set_label(l2);
5730
        }
5731
        opn = "bc1f";
5732
        goto not_likely;
5733
    case OPC_BC1FL:
5734
        {
5735
            int l1 = gen_new_label();
5736
            int l2 = gen_new_label();
5737
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5738

    
5739
            get_fp_cond(r_tmp1);
5740
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5741
            tcg_temp_free(r_tmp1);
5742
            tcg_gen_not_tl(t0, t0);
5743
            tcg_gen_movi_tl(t1, 0x1 << cc);
5744
            tcg_gen_and_tl(t0, t0, t1);
5745
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5746
            tcg_gen_movi_tl(t0, 0);
5747
            tcg_gen_br(l2);
5748
            gen_set_label(l1);
5749
            tcg_gen_movi_tl(t0, 1);
5750
            gen_set_label(l2);
5751
        }
5752
        opn = "bc1fl";
5753
        goto likely;
5754
    case OPC_BC1T:
5755
        {
5756
            int l1 = gen_new_label();
5757
            int l2 = gen_new_label();
5758
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5759

    
5760
            get_fp_cond(r_tmp1);
5761
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5762
            tcg_temp_free(r_tmp1);
5763
            tcg_gen_movi_tl(t1, 0x1 << cc);
5764
            tcg_gen_and_tl(t0, t0, t1);
5765
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5766
            tcg_gen_movi_tl(t0, 0);
5767
            tcg_gen_br(l2);
5768
            gen_set_label(l1);
5769
            tcg_gen_movi_tl(t0, 1);
5770
            gen_set_label(l2);
5771
        }
5772
        opn = "bc1t";
5773
        goto not_likely;
5774
    case OPC_BC1TL:
5775
        {
5776
            int l1 = gen_new_label();
5777
            int l2 = gen_new_label();
5778
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5779

    
5780
            get_fp_cond(r_tmp1);
5781
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5782
            tcg_temp_free(r_tmp1);
5783
            tcg_gen_movi_tl(t1, 0x1 << cc);
5784
            tcg_gen_and_tl(t0, t0, t1);
5785
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5786
            tcg_gen_movi_tl(t0, 0);
5787
            tcg_gen_br(l2);
5788
            gen_set_label(l1);
5789
            tcg_gen_movi_tl(t0, 1);
5790
            gen_set_label(l2);
5791
        }
5792
        opn = "bc1tl";
5793
    likely:
5794
        ctx->hflags |= MIPS_HFLAG_BL;
5795
        tcg_gen_trunc_tl_i32(bcond, t0);
5796
        break;
5797
    case OPC_BC1FANY2:
5798
        {
5799
            int l1 = gen_new_label();
5800
            int l2 = gen_new_label();
5801
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5802

    
5803
            get_fp_cond(r_tmp1);
5804
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5805
            tcg_temp_free(r_tmp1);
5806
            tcg_gen_not_tl(t0, t0);
5807
            tcg_gen_movi_tl(t1, 0x3 << cc);
5808
            tcg_gen_and_tl(t0, t0, t1);
5809
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5810
            tcg_gen_movi_tl(t0, 0);
5811
            tcg_gen_br(l2);
5812
            gen_set_label(l1);
5813
            tcg_gen_movi_tl(t0, 1);
5814
            gen_set_label(l2);
5815
        }
5816
        opn = "bc1any2f";
5817
        goto not_likely;
5818
    case OPC_BC1TANY2:
5819
        {
5820
            int l1 = gen_new_label();
5821
            int l2 = gen_new_label();
5822
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5823

    
5824
            get_fp_cond(r_tmp1);
5825
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5826
            tcg_temp_free(r_tmp1);
5827
            tcg_gen_movi_tl(t1, 0x3 << cc);
5828
            tcg_gen_and_tl(t0, t0, t1);
5829
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5830
            tcg_gen_movi_tl(t0, 0);
5831
            tcg_gen_br(l2);
5832
            gen_set_label(l1);
5833
            tcg_gen_movi_tl(t0, 1);
5834
            gen_set_label(l2);
5835
        }
5836
        opn = "bc1any2t";
5837
        goto not_likely;
5838
    case OPC_BC1FANY4:
5839
        {
5840
            int l1 = gen_new_label();
5841
            int l2 = gen_new_label();
5842
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5843

    
5844
            get_fp_cond(r_tmp1);
5845
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5846
            tcg_temp_free(r_tmp1);
5847
            tcg_gen_not_tl(t0, t0);
5848
            tcg_gen_movi_tl(t1, 0xf << cc);
5849
            tcg_gen_and_tl(t0, t0, t1);
5850
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5851
            tcg_gen_movi_tl(t0, 0);
5852
            tcg_gen_br(l2);
5853
            gen_set_label(l1);
5854
            tcg_gen_movi_tl(t0, 1);
5855
            gen_set_label(l2);
5856
        }
5857
        opn = "bc1any4f";
5858
        goto not_likely;
5859
    case OPC_BC1TANY4:
5860
        {
5861
            int l1 = gen_new_label();
5862
            int l2 = gen_new_label();
5863
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5864

    
5865
            get_fp_cond(r_tmp1);
5866
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5867
            tcg_temp_free(r_tmp1);
5868
            tcg_gen_movi_tl(t1, 0xf << cc);
5869
            tcg_gen_and_tl(t0, t0, t1);
5870
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5871
            tcg_gen_movi_tl(t0, 0);
5872
            tcg_gen_br(l2);
5873
            gen_set_label(l1);
5874
            tcg_gen_movi_tl(t0, 1);
5875
            gen_set_label(l2);
5876
        }
5877
        opn = "bc1any4t";
5878
    not_likely:
5879
        ctx->hflags |= MIPS_HFLAG_BC;
5880
        tcg_gen_trunc_tl_i32(bcond, t0);
5881
        break;
5882
    default:
5883
        MIPS_INVAL(opn);
5884
        generate_exception (ctx, EXCP_RI);
5885
        goto out;
5886
    }
5887
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5888
               ctx->hflags, btarget);
5889
    ctx->btarget = btarget;
5890

    
5891
 out:
5892
    tcg_temp_free(t0);
5893
    tcg_temp_free(t1);
5894
}
5895

    
5896
/* Coprocessor 1 (FPU) */
5897

    
5898
#define FOP(func, fmt) (((fmt) << 21) | (func))
5899

    
5900
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5901
{
5902
    const char *opn = "cp1 move";
5903
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5904

    
5905
    switch (opc) {
5906
    case OPC_MFC1:
5907
        {
5908
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5909

    
5910
            gen_load_fpr32(fp0, fs);
5911
            tcg_gen_ext_i32_tl(t0, fp0);
5912
            tcg_temp_free(fp0);
5913
        }
5914
        gen_store_gpr(t0, rt);
5915
        opn = "mfc1";
5916
        break;
5917
    case OPC_MTC1:
5918
        gen_load_gpr(t0, rt);
5919
        {
5920
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5921

    
5922
            tcg_gen_trunc_tl_i32(fp0, t0);
5923
            gen_store_fpr32(fp0, fs);
5924
            tcg_temp_free(fp0);
5925
        }
5926
        opn = "mtc1";
5927
        break;
5928
    case OPC_CFC1:
5929
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5930
        gen_store_gpr(t0, rt);
5931
        opn = "cfc1";
5932
        break;
5933
    case OPC_CTC1:
5934
        gen_load_gpr(t0, rt);
5935
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5936
        opn = "ctc1";
5937
        break;
5938
    case OPC_DMFC1:
5939
        {
5940
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5941

    
5942
            gen_load_fpr64(ctx, fp0, fs);
5943
            tcg_gen_mov_tl(t0, fp0);
5944
            tcg_temp_free(fp0);
5945
        }
5946
        gen_store_gpr(t0, rt);
5947
        opn = "dmfc1";
5948
        break;
5949
    case OPC_DMTC1:
5950
        gen_load_gpr(t0, rt);
5951
        {
5952
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5953

    
5954
            tcg_gen_mov_tl(fp0, t0);
5955
            gen_store_fpr64(ctx, fp0, fs);
5956
            tcg_temp_free(fp0);
5957
        }
5958
        opn = "dmtc1";
5959
        break;
5960
    case OPC_MFHC1:
5961
        {
5962
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5963

    
5964
            gen_load_fpr32h(fp0, fs);
5965
            tcg_gen_ext_i32_tl(t0, fp0);
5966
            tcg_temp_free(fp0);
5967
        }
5968
        gen_store_gpr(t0, rt);
5969
        opn = "mfhc1";
5970
        break;
5971
    case OPC_MTHC1:
5972
        gen_load_gpr(t0, rt);
5973
        {
5974
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5975

    
5976
            tcg_gen_trunc_tl_i32(fp0, t0);
5977
            gen_store_fpr32h(fp0, fs);
5978
            tcg_temp_free(fp0);
5979
        }
5980
        opn = "mthc1";
5981
        break;
5982
    default:
5983
        MIPS_INVAL(opn);
5984
        generate_exception (ctx, EXCP_RI);
5985
        goto out;
5986
    }
5987
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5988

    
5989
 out:
5990
    tcg_temp_free(t0);
5991
}
5992

    
5993
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5994
{
5995
    int l1 = gen_new_label();
5996
    uint32_t ccbit;
5997
    TCGCond cond;
5998
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5999
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
6000
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
6001

    
6002
    if (cc)
6003
        ccbit = 1 << (24 + cc);
6004
    else
6005
        ccbit = 1 << 23;
6006
    if (tf)
6007
        cond = TCG_COND_EQ;
6008
    else
6009
        cond = TCG_COND_NE;
6010

    
6011
    gen_load_gpr(t0, rd);
6012
    gen_load_gpr(t1, rs);
6013
    tcg_gen_ld_i32(r_tmp, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6014
    tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
6015
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
6016
    tcg_temp_free(r_tmp);
6017

    
6018
    tcg_gen_mov_tl(t0, t1);
6019
    tcg_temp_free(t1);
6020

    
6021
    gen_set_label(l1);
6022
    gen_store_gpr(t0, rd);
6023
    tcg_temp_free(t0);
6024
}
6025

    
6026
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6027
{
6028
    uint32_t ccbit;
6029
    int cond;
6030
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6031
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6032
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6033
    int l1 = gen_new_label();
6034

    
6035
    if (cc)
6036
        ccbit = 1 << (24 + cc);
6037
    else
6038
        ccbit = 1 << 23;
6039

    
6040
    if (tf)
6041
        cond = TCG_COND_EQ;
6042
    else
6043
        cond = TCG_COND_NE;
6044

    
6045
    gen_load_fpr32(fp0, fs);
6046
    gen_load_fpr32(fp1, fd);
6047
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6048
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6049
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6050
    tcg_gen_movi_i32(fp1, fp0);
6051
    tcg_temp_free(fp0);
6052
    gen_set_label(l1);
6053
    tcg_temp_free(r_tmp1);
6054
    gen_store_fpr32(fp1, fd);
6055
    tcg_temp_free(fp1);
6056
}
6057

    
6058
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6059
{
6060
    uint32_t ccbit;
6061
    int cond;
6062
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6063
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6064
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I64);
6065
    int l1 = gen_new_label();
6066

    
6067
    if (cc)
6068
        ccbit = 1 << (24 + cc);
6069
    else
6070
        ccbit = 1 << 23;
6071

    
6072
    if (tf)
6073
        cond = TCG_COND_EQ;
6074
    else
6075
        cond = TCG_COND_NE;
6076

    
6077
    gen_load_fpr64(ctx, fp0, fs);
6078
    gen_load_fpr64(ctx, fp1, fd);
6079
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6080
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6081
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6082
    tcg_gen_movi_i64(fp1, fp0);
6083
    tcg_temp_free(fp0);
6084
    gen_set_label(l1);
6085
    tcg_temp_free(r_tmp1);
6086
    gen_store_fpr64(ctx, fp1, fd);
6087
    tcg_temp_free(fp1);
6088
}
6089

    
6090
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6091
{
6092
    int cond;
6093
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6094
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6095
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6096
    TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
6097
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6098
    TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
6099
    int l1 = gen_new_label();
6100
    int l2 = gen_new_label();
6101

    
6102
    if (tf)
6103
        cond = TCG_COND_EQ;
6104
    else
6105
        cond = TCG_COND_NE;
6106

    
6107
    gen_load_fpr32(fp0, fs);
6108
    gen_load_fpr32h(fph0, fs);
6109
    gen_load_fpr32(fp1, fd);
6110
    gen_load_fpr32h(fph1, fd);
6111
    get_fp_cond(r_tmp1);
6112
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6113
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6114
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6115
    tcg_gen_movi_i32(fp1, fp0);
6116
    tcg_temp_free(fp0);
6117
    gen_set_label(l1);
6118
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6119
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6120
    tcg_gen_movi_i32(fph1, fph0);
6121
    tcg_temp_free(fph0);
6122
    gen_set_label(l2);
6123
    tcg_temp_free(r_tmp1);
6124
    tcg_temp_free(r_tmp2);
6125
    gen_store_fpr32(fp1, fd);
6126
    gen_store_fpr32h(fph1, fd);
6127
    tcg_temp_free(fp1);
6128
    tcg_temp_free(fph1);
6129
}
6130

    
6131

    
6132
static void gen_farith (DisasContext *ctx, uint32_t op1,
6133
                        int ft, int fs, int fd, int cc)
6134
{
6135
    const char *opn = "farith";
6136
    const char *condnames[] = {
6137
            "c.f",
6138
            "c.un",
6139
            "c.eq",
6140
            "c.ueq",
6141
            "c.olt",
6142
            "c.ult",
6143
            "c.ole",
6144
            "c.ule",
6145
            "c.sf",
6146
            "c.ngle",
6147
            "c.seq",
6148
            "c.ngl",
6149
            "c.lt",
6150
            "c.nge",
6151
            "c.le",
6152
            "c.ngt",
6153
    };
6154
    const char *condnames_abs[] = {
6155
            "cabs.f",
6156
            "cabs.un",
6157
            "cabs.eq",
6158
            "cabs.ueq",
6159
            "cabs.olt",
6160
            "cabs.ult",
6161
            "cabs.ole",
6162
            "cabs.ule",
6163
            "cabs.sf",
6164
            "cabs.ngle",
6165
            "cabs.seq",
6166
            "cabs.ngl",
6167
            "cabs.lt",
6168
            "cabs.nge",
6169
            "cabs.le",
6170
            "cabs.ngt",
6171
    };
6172
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6173
    uint32_t func = ctx->opcode & 0x3f;
6174

    
6175
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6176
    case FOP(0, 16):
6177
        {
6178
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6179
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6180

    
6181
            gen_load_fpr32(fp0, fs);
6182
            gen_load_fpr32(fp1, ft);
6183
            tcg_gen_helper_1_2(do_float_add_s, fp0, fp0, fp1);
6184
            tcg_temp_free(fp1);
6185
            gen_store_fpr32(fp0, fd);
6186
            tcg_temp_free(fp0);
6187
        }
6188
        opn = "add.s";
6189
        optype = BINOP;
6190
        break;
6191
    case FOP(1, 16):
6192
        {
6193
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6194
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6195

    
6196
            gen_load_fpr32(fp0, fs);
6197
            gen_load_fpr32(fp1, ft);
6198
            tcg_gen_helper_1_2(do_float_sub_s, fp0, fp0, fp1);
6199
            tcg_temp_free(fp1);
6200
            gen_store_fpr32(fp0, fd);
6201
            tcg_temp_free(fp0);
6202
        }
6203
        opn = "sub.s";
6204
        optype = BINOP;
6205
        break;
6206
    case FOP(2, 16):
6207
        {
6208
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6209
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6210

    
6211
            gen_load_fpr32(fp0, fs);
6212
            gen_load_fpr32(fp1, ft);
6213
            tcg_gen_helper_1_2(do_float_mul_s, fp0, fp0, fp1);
6214
            tcg_temp_free(fp1);
6215
            gen_store_fpr32(fp0, fd);
6216
            tcg_temp_free(fp0);
6217
        }
6218
        opn = "mul.s";
6219
        optype = BINOP;
6220
        break;
6221
    case FOP(3, 16):
6222
        {
6223
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6224
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6225

    
6226
            gen_load_fpr32(fp0, fs);
6227
            gen_load_fpr32(fp1, ft);
6228
            tcg_gen_helper_1_2(do_float_div_s, fp0, fp0, fp1);
6229
            tcg_temp_free(fp1);
6230
            gen_store_fpr32(fp0, fd);
6231
            tcg_temp_free(fp0);
6232
        }
6233
        opn = "div.s";
6234
        optype = BINOP;
6235
        break;
6236
    case FOP(4, 16):
6237
        {
6238
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6239

    
6240
            gen_load_fpr32(fp0, fs);
6241
            tcg_gen_helper_1_1(do_float_sqrt_s, fp0, fp0);
6242
            gen_store_fpr32(fp0, fd);
6243
            tcg_temp_free(fp0);
6244
        }
6245
        opn = "sqrt.s";
6246
        break;
6247
    case FOP(5, 16):
6248
        {
6249
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6250

    
6251
            gen_load_fpr32(fp0, fs);
6252
            tcg_gen_helper_1_1(do_float_abs_s, fp0, fp0);
6253
            gen_store_fpr32(fp0, fd);
6254
            tcg_temp_free(fp0);
6255
        }
6256
        opn = "abs.s";
6257
        break;
6258
    case FOP(6, 16):
6259
        {
6260
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6261

    
6262
            gen_load_fpr32(fp0, fs);
6263
            gen_store_fpr32(fp0, fd);
6264
            tcg_temp_free(fp0);
6265
        }
6266
        opn = "mov.s";
6267
        break;
6268
    case FOP(7, 16):
6269
        {
6270
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6271

    
6272
            gen_load_fpr32(fp0, fs);
6273
            tcg_gen_helper_1_1(do_float_chs_s, fp0, fp0);
6274
            gen_store_fpr32(fp0, fd);
6275
            tcg_temp_free(fp0);
6276
        }
6277
        opn = "neg.s";
6278
        break;
6279
    case FOP(8, 16):
6280
        check_cp1_64bitmode(ctx);
6281
        {
6282
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6283
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6284

    
6285
            gen_load_fpr32(fp32, fs);
6286
            tcg_gen_helper_1_1(do_float_roundl_s, fp64, fp32);
6287
            tcg_temp_free(fp32);
6288
            gen_store_fpr64(ctx, fp64, fd);
6289
            tcg_temp_free(fp64);
6290
        }
6291
        opn = "round.l.s";
6292
        break;
6293
    case FOP(9, 16):
6294
        check_cp1_64bitmode(ctx);
6295
        {
6296
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6297
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6298

    
6299
            gen_load_fpr32(fp32, fs);
6300
            tcg_gen_helper_1_1(do_float_truncl_s, fp64, fp32);
6301
            tcg_temp_free(fp32);
6302
            gen_store_fpr64(ctx, fp64, fd);
6303
            tcg_temp_free(fp64);
6304
        }
6305
        opn = "trunc.l.s";
6306
        break;
6307
    case FOP(10, 16):
6308
        check_cp1_64bitmode(ctx);
6309
        {
6310
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6311
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6312

    
6313
            gen_load_fpr32(fp32, fs);
6314
            tcg_gen_helper_1_1(do_float_ceill_s, fp64, fp32);
6315
            tcg_temp_free(fp32);
6316
            gen_store_fpr64(ctx, fp64, fd);
6317
            tcg_temp_free(fp64);
6318
        }
6319
        opn = "ceil.l.s";
6320
        break;
6321
    case FOP(11, 16):
6322
        check_cp1_64bitmode(ctx);
6323
        {
6324
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6325
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6326

    
6327
            gen_load_fpr32(fp32, fs);
6328
            tcg_gen_helper_1_1(do_float_floorl_s, fp64, fp32);
6329
            tcg_temp_free(fp32);
6330
            gen_store_fpr64(ctx, fp64, fd);
6331
            tcg_temp_free(fp64);
6332
        }
6333
        opn = "floor.l.s";
6334
        break;
6335
    case FOP(12, 16):
6336
        {
6337
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6338

    
6339
            gen_load_fpr32(fp0, fs);
6340
            tcg_gen_helper_1_1(do_float_roundw_s, fp0, fp0);
6341
            gen_store_fpr32(fp0, fd);
6342
            tcg_temp_free(fp0);
6343
        }
6344
        opn = "round.w.s";
6345
        break;
6346
    case FOP(13, 16):
6347
        {
6348
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6349

    
6350
            gen_load_fpr32(fp0, fs);
6351
            tcg_gen_helper_1_1(do_float_truncw_s, fp0, fp0);
6352
            gen_store_fpr32(fp0, fd);
6353
            tcg_temp_free(fp0);
6354
        }
6355
        opn = "trunc.w.s";
6356
        break;
6357
    case FOP(14, 16):
6358
        {
6359
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6360

    
6361
            gen_load_fpr32(fp0, fs);
6362
            tcg_gen_helper_1_1(do_float_ceilw_s, fp0, fp0);
6363
            gen_store_fpr32(fp0, fd);
6364
            tcg_temp_free(fp0);
6365
        }
6366
        opn = "ceil.w.s";
6367
        break;
6368
    case FOP(15, 16):
6369
        {
6370
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6371

    
6372
            gen_load_fpr32(fp0, fs);
6373
            tcg_gen_helper_1_1(do_float_floorw_s, fp0, fp0);
6374
            gen_store_fpr32(fp0, fd);
6375
            tcg_temp_free(fp0);
6376
        }
6377
        opn = "floor.w.s";
6378
        break;
6379
    case FOP(17, 16):
6380
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6381
        opn = "movcf.s";
6382
        break;
6383
    case FOP(18, 16):
6384
        {
6385
            int l1 = gen_new_label();
6386
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6387
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6388

    
6389
            gen_load_gpr(t0, ft);
6390
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6391
            tcg_temp_free(t0);
6392
            gen_load_fpr32(fp0, fs);
6393
            gen_store_fpr32(fp0, fd);
6394
            tcg_temp_free(fp0);
6395
            gen_set_label(l1);
6396
        }
6397
        opn = "movz.s";
6398
        break;
6399
    case FOP(19, 16):
6400
        {
6401
            int l1 = gen_new_label();
6402
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6403
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6404

    
6405
            gen_load_gpr(t0, ft);
6406
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6407
            tcg_temp_free(t0);
6408
            gen_load_fpr32(fp0, fs);
6409
            gen_store_fpr32(fp0, fd);
6410
            tcg_temp_free(fp0);
6411
            gen_set_label(l1);
6412
        }
6413
        opn = "movn.s";
6414
        break;
6415
    case FOP(21, 16):
6416
        check_cop1x(ctx);
6417
        {
6418
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6419

    
6420
            gen_load_fpr32(fp0, fs);
6421
            tcg_gen_helper_1_1(do_float_recip_s, fp0, fp0);
6422
            gen_store_fpr32(fp0, fd);
6423
            tcg_temp_free(fp0);
6424
        }
6425
        opn = "recip.s";
6426
        break;
6427
    case FOP(22, 16):
6428
        check_cop1x(ctx);
6429
        {
6430
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6431

    
6432
            gen_load_fpr32(fp0, fs);
6433
            tcg_gen_helper_1_1(do_float_rsqrt_s, fp0, fp0);
6434
            gen_store_fpr32(fp0, fd);
6435
            tcg_temp_free(fp0);
6436
        }
6437
        opn = "rsqrt.s";
6438
        break;
6439
    case FOP(28, 16):
6440
        check_cp1_64bitmode(ctx);
6441
        {
6442
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6443
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6444

    
6445
            gen_load_fpr32(fp0, fs);
6446
            gen_load_fpr32(fp1, fd);
6447
            tcg_gen_helper_1_2(do_float_recip2_s, fp0, fp0, fp1);
6448
            tcg_temp_free(fp1);
6449
            gen_store_fpr32(fp0, fd);
6450
            tcg_temp_free(fp0);
6451
        }
6452
        opn = "recip2.s";
6453
        break;
6454
    case FOP(29, 16):
6455
        check_cp1_64bitmode(ctx);
6456
        {
6457
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6458

    
6459
            gen_load_fpr32(fp0, fs);
6460
            tcg_gen_helper_1_1(do_float_recip1_s, fp0, fp0);
6461
            gen_store_fpr32(fp0, fd);
6462
            tcg_temp_free(fp0);
6463
        }
6464
        opn = "recip1.s";
6465
        break;
6466
    case FOP(30, 16):
6467
        check_cp1_64bitmode(ctx);
6468
        {
6469
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6470

    
6471
            gen_load_fpr32(fp0, fs);
6472
            tcg_gen_helper_1_1(do_float_rsqrt1_s, fp0, fp0);
6473
            gen_store_fpr32(fp0, fd);
6474
            tcg_temp_free(fp0);
6475
        }
6476
        opn = "rsqrt1.s";
6477
        break;
6478
    case FOP(31, 16):
6479
        check_cp1_64bitmode(ctx);
6480
        {
6481
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6482
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6483

    
6484
            gen_load_fpr32(fp0, fs);
6485
            gen_load_fpr32(fp1, ft);
6486
            tcg_gen_helper_1_2(do_float_rsqrt2_s, fp0, fp0, fp1);
6487
            tcg_temp_free(fp1);
6488
            gen_store_fpr32(fp0, fd);
6489
            tcg_temp_free(fp0);
6490
        }
6491
        opn = "rsqrt2.s";
6492
        break;
6493
    case FOP(33, 16):
6494
        check_cp1_registers(ctx, fd);
6495
        {
6496
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6497
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6498

    
6499
            gen_load_fpr32(fp32, fs);
6500
            tcg_gen_helper_1_1(do_float_cvtd_s, fp64, fp32);
6501
            tcg_temp_free(fp32);
6502
            gen_store_fpr64(ctx, fp64, fd);
6503
            tcg_temp_free(fp64);
6504
        }
6505
        opn = "cvt.d.s";
6506
        break;
6507
    case FOP(36, 16):
6508
        {
6509
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6510

    
6511
            gen_load_fpr32(fp0, fs);
6512
            tcg_gen_helper_1_1(do_float_cvtw_s, fp0, fp0);
6513
            gen_store_fpr32(fp0, fd);
6514
            tcg_temp_free(fp0);
6515
        }
6516
        opn = "cvt.w.s";
6517
        break;
6518
    case FOP(37, 16):
6519
        check_cp1_64bitmode(ctx);
6520
        {
6521
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6522
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6523

    
6524
            gen_load_fpr32(fp32, fs);
6525
            tcg_gen_helper_1_1(do_float_cvtl_s, fp64, fp32);
6526
            tcg_temp_free(fp32);
6527
            gen_store_fpr64(ctx, fp64, fd);
6528
            tcg_temp_free(fp64);
6529
        }
6530
        opn = "cvt.l.s";
6531
        break;
6532
    case FOP(38, 16):
6533
        check_cp1_64bitmode(ctx);
6534
        {
6535
            TCGv fp64_0 = tcg_temp_new(TCG_TYPE_I64);
6536
            TCGv fp64_1 = tcg_temp_new(TCG_TYPE_I64);
6537
            TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
6538
            TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
6539

    
6540
            gen_load_fpr32(fp32_0, fs);
6541
            gen_load_fpr32(fp32_1, ft);
6542
            tcg_gen_extu_i32_i64(fp64_0, fp32_0);
6543
            tcg_gen_extu_i32_i64(fp64_1, fp32_1);
6544
            tcg_temp_free(fp32_0);
6545
            tcg_temp_free(fp32_1);
6546
            tcg_gen_shli_i64(fp64_1, fp64_1, 32);
6547
            tcg_gen_or_i64(fp64_0, fp64_0, fp64_1);
6548
            tcg_temp_free(fp64_1);
6549
            gen_store_fpr64(ctx, fp64_0, fd);
6550
            tcg_temp_free(fp64_0);
6551
        }
6552
        opn = "cvt.ps.s";
6553
        break;
6554
    case FOP(48, 16):
6555
    case FOP(49, 16):
6556
    case FOP(50, 16):
6557
    case FOP(51, 16):
6558
    case FOP(52, 16):
6559
    case FOP(53, 16):
6560
    case FOP(54, 16):
6561
    case FOP(55, 16):
6562
    case FOP(56, 16):
6563
    case FOP(57, 16):
6564
    case FOP(58, 16):
6565
    case FOP(59, 16):
6566
    case FOP(60, 16):
6567
    case FOP(61, 16):
6568
    case FOP(62, 16):
6569
    case FOP(63, 16):
6570
        {
6571
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6572
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6573

    
6574
            gen_load_fpr32(fp0, fs);
6575
            gen_load_fpr32(fp1, ft);
6576
            if (ctx->opcode & (1 << 6)) {
6577
                check_cop1x(ctx);
6578
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6579
                opn = condnames_abs[func-48];
6580
            } else {
6581
                gen_cmp_s(func-48, fp0, fp1, cc);
6582
                opn = condnames[func-48];
6583
            }
6584
            tcg_temp_free(fp0);
6585
            tcg_temp_free(fp1);
6586
        }
6587
        break;
6588
    case FOP(0, 17):
6589
        check_cp1_registers(ctx, fs | ft | fd);
6590
        {
6591
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6592
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6593

    
6594
            gen_load_fpr64(ctx, fp0, fs);
6595
            gen_load_fpr64(ctx, fp1, ft);
6596
            tcg_gen_helper_1_2(do_float_add_d, fp0, fp0, fp1);
6597
            tcg_temp_free(fp1);
6598
            gen_store_fpr64(ctx, fp0, fd);
6599
            tcg_temp_free(fp0);
6600
        }
6601
        opn = "add.d";
6602
        optype = BINOP;
6603
        break;
6604
    case FOP(1, 17):
6605
        check_cp1_registers(ctx, fs | ft | fd);
6606
        {
6607
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6608
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6609

    
6610
            gen_load_fpr64(ctx, fp0, fs);
6611
            gen_load_fpr64(ctx, fp1, ft);
6612
            tcg_gen_helper_1_2(do_float_sub_d, fp0, fp0, fp1);
6613
            tcg_temp_free(fp1);
6614
            gen_store_fpr64(ctx, fp0, fd);
6615
            tcg_temp_free(fp0);
6616
        }
6617
        opn = "sub.d";
6618
        optype = BINOP;
6619
        break;
6620
    case FOP(2, 17):
6621
        check_cp1_registers(ctx, fs | ft | fd);
6622
        {
6623
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6624
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6625

    
6626
            gen_load_fpr64(ctx, fp0, fs);
6627
            gen_load_fpr64(ctx, fp1, ft);
6628
            tcg_gen_helper_1_2(do_float_mul_d, fp0, fp0, fp1);
6629
            tcg_temp_free(fp1);
6630
            gen_store_fpr64(ctx, fp0, fd);
6631
            tcg_temp_free(fp0);
6632
        }
6633
        opn = "mul.d";
6634
        optype = BINOP;
6635
        break;
6636
    case FOP(3, 17):
6637
        check_cp1_registers(ctx, fs | ft | fd);
6638
        {
6639
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6640
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6641

    
6642
            gen_load_fpr64(ctx, fp0, fs);
6643
            gen_load_fpr64(ctx, fp1, ft);
6644
            tcg_gen_helper_1_2(do_float_div_d, fp0, fp0, fp1);
6645
            tcg_temp_free(fp1);
6646
            gen_store_fpr64(ctx, fp0, fd);
6647
            tcg_temp_free(fp0);
6648
        }
6649
        opn = "div.d";
6650
        optype = BINOP;
6651
        break;
6652
    case FOP(4, 17):
6653
        check_cp1_registers(ctx, fs | fd);
6654
        {
6655
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6656

    
6657
            gen_load_fpr64(ctx, fp0, fs);
6658
            tcg_gen_helper_1_1(do_float_sqrt_d, fp0, fp0);
6659
            gen_store_fpr64(ctx, fp0, fd);
6660
            tcg_temp_free(fp0);
6661
        }
6662
        opn = "sqrt.d";
6663
        break;
6664
    case FOP(5, 17):
6665
        check_cp1_registers(ctx, fs | fd);
6666
        {
6667
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6668

    
6669
            gen_load_fpr64(ctx, fp0, fs);
6670
            tcg_gen_helper_1_1(do_float_abs_d, fp0, fp0);
6671
            gen_store_fpr64(ctx, fp0, fd);
6672
            tcg_temp_free(fp0);
6673
        }
6674
        opn = "abs.d";
6675
        break;
6676
    case FOP(6, 17):
6677
        check_cp1_registers(ctx, fs | fd);
6678
        {
6679
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6680

    
6681
            gen_load_fpr64(ctx, fp0, fs);
6682
            gen_store_fpr64(ctx, fp0, fd);
6683
            tcg_temp_free(fp0);
6684
        }
6685
        opn = "mov.d";
6686
        break;
6687
    case FOP(7, 17):
6688
        check_cp1_registers(ctx, fs | fd);
6689
        {
6690
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6691

    
6692
            gen_load_fpr64(ctx, fp0, fs);
6693
            tcg_gen_helper_1_1(do_float_chs_d, fp0, fp0);
6694
            gen_store_fpr64(ctx, fp0, fd);
6695
            tcg_temp_free(fp0);
6696
        }
6697
        opn = "neg.d";
6698
        break;
6699
    case FOP(8, 17):
6700
        check_cp1_64bitmode(ctx);
6701
        {
6702
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6703

    
6704
            gen_load_fpr64(ctx, fp0, fs);
6705
            tcg_gen_helper_1_1(do_float_roundl_d, fp0, fp0);
6706
            gen_store_fpr64(ctx, fp0, fd);
6707
            tcg_temp_free(fp0);
6708
        }
6709
        opn = "round.l.d";
6710
        break;
6711
    case FOP(9, 17):
6712
        check_cp1_64bitmode(ctx);
6713
        {
6714
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6715

    
6716
            gen_load_fpr64(ctx, fp0, fs);
6717
            tcg_gen_helper_1_1(do_float_truncl_d, fp0, fp0);
6718
            gen_store_fpr64(ctx, fp0, fd);
6719
            tcg_temp_free(fp0);
6720
        }
6721
        opn = "trunc.l.d";
6722
        break;
6723
    case FOP(10, 17):
6724
        check_cp1_64bitmode(ctx);
6725
        {
6726
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6727

    
6728
            gen_load_fpr64(ctx, fp0, fs);
6729
            tcg_gen_helper_1_1(do_float_ceill_d, fp0, fp0);
6730
            gen_store_fpr64(ctx, fp0, fd);
6731
            tcg_temp_free(fp0);
6732
        }
6733
        opn = "ceil.l.d";
6734
        break;
6735
    case FOP(11, 17):
6736
        check_cp1_64bitmode(ctx);
6737
        {
6738
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6739

    
6740
            gen_load_fpr64(ctx, fp0, fs);
6741
            tcg_gen_helper_1_1(do_float_floorl_d, fp0, fp0);
6742
            gen_store_fpr64(ctx, fp0, fd);
6743
            tcg_temp_free(fp0);
6744
        }
6745
        opn = "floor.l.d";
6746
        break;
6747
    case FOP(12, 17):
6748
        check_cp1_registers(ctx, fs);
6749
        {
6750
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6751
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6752

    
6753
            gen_load_fpr64(ctx, fp64, fs);
6754
            tcg_gen_helper_1_1(do_float_roundw_d, fp32, fp64);
6755
            tcg_temp_free(fp64);
6756
            gen_store_fpr32(fp32, fd);
6757
            tcg_temp_free(fp32);
6758
        }
6759
        opn = "round.w.d";
6760
        break;
6761
    case FOP(13, 17):
6762
        check_cp1_registers(ctx, fs);
6763
        {
6764
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6765
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6766

    
6767
            gen_load_fpr64(ctx, fp64, fs);
6768
            tcg_gen_helper_1_1(do_float_truncw_d, fp32, fp64);
6769
            tcg_temp_free(fp64);
6770
            gen_store_fpr32(fp32, fd);
6771
            tcg_temp_free(fp32);
6772
        }
6773
        opn = "trunc.w.d";
6774
        break;
6775
    case FOP(14, 17):
6776
        check_cp1_registers(ctx, fs);
6777
        {
6778
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6779
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6780

    
6781
            gen_load_fpr64(ctx, fp64, fs);
6782
            tcg_gen_helper_1_1(do_float_ceilw_d, fp32, fp64);
6783
            tcg_temp_free(fp64);
6784
            gen_store_fpr32(fp32, fd);
6785
            tcg_temp_free(fp32);
6786
        }
6787
        opn = "ceil.w.d";
6788
        break;
6789
    case FOP(15, 17):
6790
        check_cp1_registers(ctx, fs);
6791
        {
6792
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6793
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6794

    
6795
            gen_load_fpr64(ctx, fp64, fs);
6796
            tcg_gen_helper_1_1(do_float_floorw_d, fp32, fp64);
6797
            tcg_temp_free(fp64);
6798
            gen_store_fpr32(fp32, fd);
6799
            tcg_temp_free(fp32);
6800
        }
6801
        opn = "floor.w.d";
6802
        break;
6803
    case FOP(17, 17):
6804
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6805
        opn = "movcf.d";
6806
        break;
6807
    case FOP(18, 17):
6808
        {
6809
            int l1 = gen_new_label();
6810
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6811
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6812

    
6813
            gen_load_gpr(t0, ft);
6814
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6815
            tcg_temp_free(t0);
6816
            gen_load_fpr64(ctx, fp0, fs);
6817
            gen_store_fpr64(ctx, fp0, fd);
6818
            tcg_temp_free(fp0);
6819
            gen_set_label(l1);
6820
        }
6821
        opn = "movz.d";
6822
        break;
6823
    case FOP(19, 17):
6824
        {
6825
            int l1 = gen_new_label();
6826
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6827
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6828

    
6829
            gen_load_gpr(t0, ft);
6830
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6831
            tcg_temp_free(t0);
6832
            gen_load_fpr64(ctx, fp0, fs);
6833
            gen_store_fpr64(ctx, fp0, fd);
6834
            tcg_temp_free(fp0);
6835
            gen_set_label(l1);
6836
        }
6837
        opn = "movn.d";
6838
        break;
6839
    case FOP(21, 17):
6840
        check_cp1_64bitmode(ctx);
6841
        {
6842
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6843

    
6844
            gen_load_fpr64(ctx, fp0, fs);
6845
            tcg_gen_helper_1_1(do_float_recip_d, fp0, fp0);
6846
            gen_store_fpr64(ctx, fp0, fd);
6847
            tcg_temp_free(fp0);
6848
        }
6849
        opn = "recip.d";
6850
        break;
6851
    case FOP(22, 17):
6852
        check_cp1_64bitmode(ctx);
6853
        {
6854
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6855

    
6856
            gen_load_fpr64(ctx, fp0, fs);
6857
            tcg_gen_helper_1_1(do_float_rsqrt_d, fp0, fp0);
6858
            gen_store_fpr64(ctx, fp0, fd);
6859
            tcg_temp_free(fp0);
6860
        }
6861
        opn = "rsqrt.d";
6862
        break;
6863
    case FOP(28, 17):
6864
        check_cp1_64bitmode(ctx);
6865
        {
6866
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6867
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6868

    
6869
            gen_load_fpr64(ctx, fp0, fs);
6870
            gen_load_fpr64(ctx, fp1, ft);
6871
            tcg_gen_helper_1_2(do_float_recip2_d, fp0, fp0, fp1);
6872
            tcg_temp_free(fp1);
6873
            gen_store_fpr64(ctx, fp0, fd);
6874
            tcg_temp_free(fp0);
6875
        }
6876
        opn = "recip2.d";
6877
        break;
6878
    case FOP(29, 17):
6879
        check_cp1_64bitmode(ctx);
6880
        {
6881
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6882

    
6883
            gen_load_fpr64(ctx, fp0, fs);
6884
            tcg_gen_helper_1_1(do_float_recip1_d, fp0, fp0);
6885
            gen_store_fpr64(ctx, fp0, fd);
6886
            tcg_temp_free(fp0);
6887
        }
6888
        opn = "recip1.d";
6889
        break;
6890
    case FOP(30, 17):
6891
        check_cp1_64bitmode(ctx);
6892
        {
6893
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6894

    
6895
            gen_load_fpr64(ctx, fp0, fs);
6896
            tcg_gen_helper_1_1(do_float_rsqrt1_d, fp0, fp0);
6897
            gen_store_fpr64(ctx, fp0, fd);
6898
            tcg_temp_free(fp0);
6899
        }
6900
        opn = "rsqrt1.d";
6901
        break;
6902
    case FOP(31, 17):
6903
        check_cp1_64bitmode(ctx);
6904
        {
6905
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6906
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6907

    
6908
            gen_load_fpr64(ctx, fp0, fs);
6909
            gen_load_fpr64(ctx, fp1, ft);
6910
            tcg_gen_helper_1_2(do_float_rsqrt2_d, fp0, fp0, fp1);
6911
            tcg_temp_free(fp1);
6912
            gen_store_fpr64(ctx, fp0, fd);
6913
            tcg_temp_free(fp0);
6914
        }
6915
        opn = "rsqrt2.d";
6916
        break;
6917
    case FOP(48, 17):
6918
    case FOP(49, 17):
6919
    case FOP(50, 17):
6920
    case FOP(51, 17):
6921
    case FOP(52, 17):
6922
    case FOP(53, 17):
6923
    case FOP(54, 17):
6924
    case FOP(55, 17):
6925
    case FOP(56, 17):
6926
    case FOP(57, 17):
6927
    case FOP(58, 17):
6928
    case FOP(59, 17):
6929
    case FOP(60, 17):
6930
    case FOP(61, 17):
6931
    case FOP(62, 17):
6932
    case FOP(63, 17):
6933
        {
6934
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6935
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6936

    
6937
            gen_load_fpr64(ctx, fp0, fs);
6938
            gen_load_fpr64(ctx, fp1, ft);
6939
            if (ctx->opcode & (1 << 6)) {
6940
                check_cop1x(ctx);
6941
                check_cp1_registers(ctx, fs | ft);
6942
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6943
                opn = condnames_abs[func-48];
6944
            } else {
6945
                check_cp1_registers(ctx, fs | ft);
6946
                gen_cmp_d(func-48, fp0, fp1, cc);
6947
                opn = condnames[func-48];
6948
            }
6949
            tcg_temp_free(fp0);
6950
            tcg_temp_free(fp1);
6951
        }
6952
        break;
6953
    case FOP(32, 17):
6954
        check_cp1_registers(ctx, fs);
6955
        {
6956
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6957
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6958

    
6959
            gen_load_fpr64(ctx, fp64, fs);
6960
            tcg_gen_helper_1_1(do_float_cvts_d, fp32, fp64);
6961
            tcg_temp_free(fp64);
6962
            gen_store_fpr32(fp32, fd);
6963
            tcg_temp_free(fp32);
6964
        }
6965
        opn = "cvt.s.d";
6966
        break;
6967
    case FOP(36, 17):
6968
        check_cp1_registers(ctx, fs);
6969
        {
6970
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6971
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6972

    
6973
            gen_load_fpr64(ctx, fp64, fs);
6974
            tcg_gen_helper_1_1(do_float_cvtw_d, fp32, fp64);
6975
            tcg_temp_free(fp64);
6976
            gen_store_fpr32(fp32, fd);
6977
            tcg_temp_free(fp32);
6978
        }
6979
        opn = "cvt.w.d";
6980
        break;
6981
    case FOP(37, 17):
6982
        check_cp1_64bitmode(ctx);
6983
        {
6984
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6985

    
6986
            gen_load_fpr64(ctx, fp0, fs);
6987
            tcg_gen_helper_1_1(do_float_cvtl_d, fp0, fp0);
6988
            gen_store_fpr64(ctx, fp0, fd);
6989
            tcg_temp_free(fp0);
6990
        }
6991
        opn = "cvt.l.d";
6992
        break;
6993
    case FOP(32, 20):
6994
        {
6995
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6996

    
6997
            gen_load_fpr32(fp0, fs);
6998
            tcg_gen_helper_1_1(do_float_cvts_w, fp0, fp0);
6999
            gen_store_fpr32(fp0, fd);
7000
            tcg_temp_free(fp0);
7001
        }
7002
        opn = "cvt.s.w";
7003
        break;
7004
    case FOP(33, 20):
7005
        check_cp1_registers(ctx, fd);
7006
        {
7007
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
7008
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
7009

    
7010
            gen_load_fpr32(fp32, fs);
7011
            tcg_gen_helper_1_1(do_float_cvtd_w, fp64, fp32);
7012
            tcg_temp_free(fp32);
7013
            gen_store_fpr64(ctx, fp64, fd);
7014
            tcg_temp_free(fp64);
7015
        }
7016
        opn = "cvt.d.w";
7017
        break;
7018
    case FOP(32, 21):
7019
        check_cp1_64bitmode(ctx);
7020
        {
7021
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
7022
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
7023

    
7024
            gen_load_fpr64(ctx, fp64, fs);
7025
            tcg_gen_helper_1_1(do_float_cvts_l, fp32, fp64);
7026
            tcg_temp_free(fp64);
7027
            gen_store_fpr32(fp32, fd);
7028
            tcg_temp_free(fp32);
7029
        }
7030
        opn = "cvt.s.l";
7031
        break;
7032
    case FOP(33, 21):
7033
        check_cp1_64bitmode(ctx);
7034
        {
7035
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7036

    
7037
            gen_load_fpr64(ctx, fp0, fs);
7038
            tcg_gen_helper_1_1(do_float_cvtd_l, fp0, fp0);
7039
            gen_store_fpr64(ctx, fp0, fd);
7040
            tcg_temp_free(fp0);
7041
        }
7042
        opn = "cvt.d.l";
7043
        break;
7044
    case FOP(38, 20):
7045
        check_cp1_64bitmode(ctx);
7046
        {
7047
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7048

    
7049
            gen_load_fpr64(ctx, fp0, fs);
7050
            tcg_gen_helper_1_1(do_float_cvtps_pw, fp0, fp0);
7051
            gen_store_fpr64(ctx, fp0, fd);
7052
            tcg_temp_free(fp0);
7053
        }
7054
        opn = "cvt.ps.pw";
7055
        break;
7056
    case FOP(0, 22):
7057
        check_cp1_64bitmode(ctx);
7058
        {
7059
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7060
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7061

    
7062
            gen_load_fpr64(ctx, fp0, fs);
7063
            gen_load_fpr64(ctx, fp1, ft);
7064
            tcg_gen_helper_1_2(do_float_add_ps, fp0, fp0, fp1);
7065
            tcg_temp_free(fp1);
7066
            gen_store_fpr64(ctx, fp0, fd);
7067
            tcg_temp_free(fp0);
7068
        }
7069
        opn = "add.ps";
7070
        break;
7071
    case FOP(1, 22):
7072
        check_cp1_64bitmode(ctx);
7073
        {
7074
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7075
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7076

    
7077
            gen_load_fpr64(ctx, fp0, fs);
7078
            gen_load_fpr64(ctx, fp1, ft);
7079
            tcg_gen_helper_1_2(do_float_sub_ps, fp0, fp0, fp1);
7080
            tcg_temp_free(fp1);
7081
            gen_store_fpr64(ctx, fp0, fd);
7082
            tcg_temp_free(fp0);
7083
        }
7084
        opn = "sub.ps";
7085
        break;
7086
    case FOP(2, 22):
7087
        check_cp1_64bitmode(ctx);
7088
        {
7089
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7090
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7091

    
7092
            gen_load_fpr64(ctx, fp0, fs);
7093
            gen_load_fpr64(ctx, fp1, ft);
7094
            tcg_gen_helper_1_2(do_float_mul_ps, fp0, fp0, fp1);
7095
            tcg_temp_free(fp1);
7096
            gen_store_fpr64(ctx, fp0, fd);
7097
            tcg_temp_free(fp0);
7098
        }
7099
        opn = "mul.ps";
7100
        break;
7101
    case FOP(5, 22):
7102
        check_cp1_64bitmode(ctx);
7103
        {
7104
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7105

    
7106
            gen_load_fpr64(ctx, fp0, fs);
7107
            tcg_gen_helper_1_1(do_float_abs_ps, fp0, fp0);
7108
            gen_store_fpr64(ctx, fp0, fd);
7109
            tcg_temp_free(fp0);
7110
        }
7111
        opn = "abs.ps";
7112
        break;
7113
    case FOP(6, 22):
7114
        check_cp1_64bitmode(ctx);
7115
        {
7116
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7117

    
7118
            gen_load_fpr64(ctx, fp0, fs);
7119
            gen_store_fpr64(ctx, fp0, fd);
7120
            tcg_temp_free(fp0);
7121
        }
7122
        opn = "mov.ps";
7123
        break;
7124
    case FOP(7, 22):
7125
        check_cp1_64bitmode(ctx);
7126
        {
7127
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7128

    
7129
            gen_load_fpr64(ctx, fp0, fs);
7130
            tcg_gen_helper_1_1(do_float_chs_ps, fp0, fp0);
7131
            gen_store_fpr64(ctx, fp0, fd);
7132
            tcg_temp_free(fp0);
7133
        }
7134
        opn = "neg.ps";
7135
        break;
7136
    case FOP(17, 22):
7137
        check_cp1_64bitmode(ctx);
7138
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7139
        opn = "movcf.ps";
7140
        break;
7141
    case FOP(18, 22):
7142
        check_cp1_64bitmode(ctx);
7143
        {
7144
            int l1 = gen_new_label();
7145
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7146
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7147
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7148

    
7149
            gen_load_gpr(t0, ft);
7150
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7151
            tcg_temp_free(t0);
7152
            gen_load_fpr32(fp0, fs);
7153
            gen_load_fpr32h(fph0, fs);
7154
            gen_store_fpr32(fp0, fd);
7155
            gen_store_fpr32h(fph0, fd);
7156
            tcg_temp_free(fp0);
7157
            tcg_temp_free(fph0);
7158
            gen_set_label(l1);
7159
        }
7160
        opn = "movz.ps";
7161
        break;
7162
    case FOP(19, 22):
7163
        check_cp1_64bitmode(ctx);
7164
        {
7165
            int l1 = gen_new_label();
7166
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7167
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7168
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7169

    
7170
            gen_load_gpr(t0, ft);
7171
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
7172
            tcg_temp_free(t0);
7173
            gen_load_fpr32(fp0, fs);
7174
            gen_load_fpr32h(fph0, fs);
7175
            gen_store_fpr32(fp0, fd);
7176
            gen_store_fpr32h(fph0, fd);
7177
            tcg_temp_free(fp0);
7178
            tcg_temp_free(fph0);
7179
            gen_set_label(l1);
7180
        }
7181
        opn = "movn.ps";
7182
        break;
7183
    case FOP(24, 22):
7184
        check_cp1_64bitmode(ctx);
7185
        {
7186
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7187
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7188

    
7189
            gen_load_fpr64(ctx, fp0, ft);
7190
            gen_load_fpr64(ctx, fp1, fs);
7191
            tcg_gen_helper_1_2(do_float_addr_ps, fp0, fp0, fp1);
7192
            tcg_temp_free(fp1);
7193
            gen_store_fpr64(ctx, fp0, fd);
7194
            tcg_temp_free(fp0);
7195
        }
7196
        opn = "addr.ps";
7197
        break;
7198
    case FOP(26, 22):
7199
        check_cp1_64bitmode(ctx);
7200
        {
7201
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7202
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7203

    
7204
            gen_load_fpr64(ctx, fp0, ft);
7205
            gen_load_fpr64(ctx, fp1, fs);
7206
            tcg_gen_helper_1_2(do_float_mulr_ps, fp0, fp0, fp1);
7207
            tcg_temp_free(fp1);
7208
            gen_store_fpr64(ctx, fp0, fd);
7209
            tcg_temp_free(fp0);
7210
        }
7211
        opn = "mulr.ps";
7212
        break;
7213
    case FOP(28, 22):
7214
        check_cp1_64bitmode(ctx);
7215
        {
7216
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7217
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7218

    
7219
            gen_load_fpr64(ctx, fp0, fs);
7220
            gen_load_fpr64(ctx, fp1, fd);
7221
            tcg_gen_helper_1_2(do_float_recip2_ps, fp0, fp0, fp1);
7222
            tcg_temp_free(fp1);
7223
            gen_store_fpr64(ctx, fp0, fd);
7224
            tcg_temp_free(fp0);
7225
        }
7226
        opn = "recip2.ps";
7227
        break;
7228
    case FOP(29, 22):
7229
        check_cp1_64bitmode(ctx);
7230
        {
7231
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7232

    
7233
            gen_load_fpr64(ctx, fp0, fs);
7234
            tcg_gen_helper_1_1(do_float_recip1_ps, fp0, fp0);
7235
            gen_store_fpr64(ctx, fp0, fd);
7236
            tcg_temp_free(fp0);
7237
        }
7238
        opn = "recip1.ps";
7239
        break;
7240
    case FOP(30, 22):
7241
        check_cp1_64bitmode(ctx);
7242
        {
7243
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7244

    
7245
            gen_load_fpr64(ctx, fp0, fs);
7246
            tcg_gen_helper_1_1(do_float_rsqrt1_ps, fp0, fp0);
7247
            gen_store_fpr64(ctx, fp0, fd);
7248
            tcg_temp_free(fp0);
7249
        }
7250
        opn = "rsqrt1.ps";
7251
        break;
7252
    case FOP(31, 22):
7253
        check_cp1_64bitmode(ctx);
7254
        {
7255
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7256
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7257

    
7258
            gen_load_fpr64(ctx, fp0, fs);
7259
            gen_load_fpr64(ctx, fp1, ft);
7260
            tcg_gen_helper_1_2(do_float_rsqrt2_ps, fp0, fp0, fp1);
7261
            tcg_temp_free(fp1);
7262
            gen_store_fpr64(ctx, fp0, fd);
7263
            tcg_temp_free(fp0);
7264
        }
7265
        opn = "rsqrt2.ps";
7266
        break;
7267
    case FOP(32, 22):
7268
        check_cp1_64bitmode(ctx);
7269
        {
7270
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7271

    
7272
            gen_load_fpr32h(fp0, fs);
7273
            tcg_gen_helper_1_1(do_float_cvts_pu, fp0, fp0);
7274
            gen_store_fpr32(fp0, fd);
7275
            tcg_temp_free(fp0);
7276
        }
7277
        opn = "cvt.s.pu";
7278
        break;
7279
    case FOP(36, 22):
7280
        check_cp1_64bitmode(ctx);
7281
        {
7282
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7283

    
7284
            gen_load_fpr64(ctx, fp0, fs);
7285
            tcg_gen_helper_1_1(do_float_cvtpw_ps, fp0, fp0);
7286
            gen_store_fpr64(ctx, fp0, fd);
7287
            tcg_temp_free(fp0);
7288
        }
7289
        opn = "cvt.pw.ps";
7290
        break;
7291
    case FOP(40, 22):
7292
        check_cp1_64bitmode(ctx);
7293
        {
7294
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7295

    
7296
            gen_load_fpr32(fp0, fs);
7297
            tcg_gen_helper_1_1(do_float_cvts_pl, fp0, fp0);
7298
            gen_store_fpr32(fp0, fd);
7299
            tcg_temp_free(fp0);
7300
        }
7301
        opn = "cvt.s.pl";
7302
        break;
7303
    case FOP(44, 22):
7304
        check_cp1_64bitmode(ctx);
7305
        {
7306
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7307
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7308

    
7309
            gen_load_fpr32(fp0, fs);
7310
            gen_load_fpr32(fp1, ft);
7311
            gen_store_fpr32h(fp0, fd);
7312
            gen_store_fpr32(fp1, fd);
7313
            tcg_temp_free(fp0);
7314
            tcg_temp_free(fp1);
7315
        }
7316
        opn = "pll.ps";
7317
        break;
7318
    case FOP(45, 22):
7319
        check_cp1_64bitmode(ctx);
7320
        {
7321
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7322
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7323

    
7324
            gen_load_fpr32(fp0, fs);
7325
            gen_load_fpr32h(fp1, ft);
7326
            gen_store_fpr32(fp1, fd);
7327
            gen_store_fpr32h(fp0, fd);
7328
            tcg_temp_free(fp0);
7329
            tcg_temp_free(fp1);
7330
        }
7331
        opn = "plu.ps";
7332
        break;
7333
    case FOP(46, 22):
7334
        check_cp1_64bitmode(ctx);
7335
        {
7336
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7337
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7338

    
7339
            gen_load_fpr32h(fp0, fs);
7340
            gen_load_fpr32(fp1, ft);
7341
            gen_store_fpr32(fp1, fd);
7342
            gen_store_fpr32h(fp0, fd);
7343
            tcg_temp_free(fp0);
7344
            tcg_temp_free(fp1);
7345
        }
7346
        opn = "pul.ps";
7347
        break;
7348
    case FOP(47, 22):
7349
        check_cp1_64bitmode(ctx);
7350
        {
7351
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7352
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7353

    
7354
            gen_load_fpr32h(fp0, fs);
7355
            gen_load_fpr32h(fp1, ft);
7356
            gen_store_fpr32(fp1, fd);
7357
            gen_store_fpr32h(fp0, fd);
7358
            tcg_temp_free(fp0);
7359
            tcg_temp_free(fp1);
7360
        }
7361
        opn = "puu.ps";
7362
        break;
7363
    case FOP(48, 22):
7364
    case FOP(49, 22):
7365
    case FOP(50, 22):
7366
    case FOP(51, 22):
7367
    case FOP(52, 22):
7368
    case FOP(53, 22):
7369
    case FOP(54, 22):
7370
    case FOP(55, 22):
7371
    case FOP(56, 22):
7372
    case FOP(57, 22):
7373
    case FOP(58, 22):
7374
    case FOP(59, 22):
7375
    case FOP(60, 22):
7376
    case FOP(61, 22):
7377
    case FOP(62, 22):
7378
    case FOP(63, 22):
7379
        check_cp1_64bitmode(ctx);
7380
        {
7381
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7382
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7383

    
7384
            gen_load_fpr64(ctx, fp0, fs);
7385
            gen_load_fpr64(ctx, fp1, ft);
7386
            if (ctx->opcode & (1 << 6)) {
7387
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7388
                opn = condnames_abs[func-48];
7389
            } else {
7390
                gen_cmp_ps(func-48, fp0, fp1, cc);
7391
                opn = condnames[func-48];
7392
            }
7393
            tcg_temp_free(fp0);
7394
            tcg_temp_free(fp1);
7395
        }
7396
        break;
7397
    default:
7398
        MIPS_INVAL(opn);
7399
        generate_exception (ctx, EXCP_RI);
7400
        return;
7401
    }
7402
    switch (optype) {
7403
    case BINOP:
7404
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7405
        break;
7406
    case CMPOP:
7407
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7408
        break;
7409
    default:
7410
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7411
        break;
7412
    }
7413
}
7414

    
7415
/* Coprocessor 3 (FPU) */
7416
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7417
                           int fd, int fs, int base, int index)
7418
{
7419
    const char *opn = "extended float load/store";
7420
    int store = 0;
7421
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7422
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7423

    
7424
    if (base == 0) {
7425
        gen_load_gpr(t0, index);
7426
    } else if (index == 0) {
7427
        gen_load_gpr(t0, base);
7428
    } else {
7429
        gen_load_gpr(t0, base);
7430
        gen_load_gpr(t1, index);
7431
        gen_op_addr_add(t0, t1);
7432
    }
7433
    /* Don't do NOP if destination is zero: we must perform the actual
7434
       memory access. */
7435
    switch (opc) {
7436
    case OPC_LWXC1:
7437
        check_cop1x(ctx);
7438
        {
7439
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7440

    
7441
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
7442
            gen_store_fpr32(fp0, fd);
7443
            tcg_temp_free(fp0);
7444
        }
7445
        opn = "lwxc1";
7446
        break;
7447
    case OPC_LDXC1:
7448
        check_cop1x(ctx);
7449
        check_cp1_registers(ctx, fd);
7450
        {
7451
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7452

    
7453
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7454
            gen_store_fpr64(ctx, fp0, fd);
7455
            tcg_temp_free(fp0);
7456
        }
7457
        opn = "ldxc1";
7458
        break;
7459
    case OPC_LUXC1:
7460
        check_cp1_64bitmode(ctx);
7461
        tcg_gen_andi_tl(t0, t0, ~0x7);
7462
        {
7463
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7464

    
7465
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7466
            gen_store_fpr64(ctx, fp0, fd);
7467
            tcg_temp_free(fp0);
7468
        }
7469
        opn = "luxc1";
7470
        break;
7471
    case OPC_SWXC1:
7472
        check_cop1x(ctx);
7473
        {
7474
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7475

    
7476
            gen_load_fpr32(fp0, fs);
7477
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
7478
            tcg_temp_free(fp0);
7479
        }
7480
        opn = "swxc1";
7481
        store = 1;
7482
        break;
7483
    case OPC_SDXC1:
7484
        check_cop1x(ctx);
7485
        check_cp1_registers(ctx, fs);
7486
        {
7487
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7488

    
7489
            gen_load_fpr64(ctx, fp0, fs);
7490
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7491
            tcg_temp_free(fp0);
7492
        }
7493
        opn = "sdxc1";
7494
        store = 1;
7495
        break;
7496
    case OPC_SUXC1:
7497
        check_cp1_64bitmode(ctx);
7498
        tcg_gen_andi_tl(t0, t0, ~0x7);
7499
        {
7500
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7501

    
7502
            gen_load_fpr64(ctx, fp0, fs);
7503
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7504
            tcg_temp_free(fp0);
7505
        }
7506
        opn = "suxc1";
7507
        store = 1;
7508
        break;
7509
    default:
7510
        MIPS_INVAL(opn);
7511
        generate_exception(ctx, EXCP_RI);
7512
        tcg_temp_free(t0);
7513
        tcg_temp_free(t1);
7514
        return;
7515
    }
7516
    tcg_temp_free(t0);
7517
    tcg_temp_free(t1);
7518
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7519
               regnames[index], regnames[base]);
7520
}
7521

    
7522
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7523
                            int fd, int fr, int fs, int ft)
7524
{
7525
    const char *opn = "flt3_arith";
7526

    
7527
    switch (opc) {
7528
    case OPC_ALNV_PS:
7529
        check_cp1_64bitmode(ctx);
7530
        {
7531
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7532
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7533
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7534
            TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
7535
            TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
7536
            int l1 = gen_new_label();
7537
            int l2 = gen_new_label();
7538

    
7539
            gen_load_gpr(t0, fr);
7540
            tcg_gen_andi_tl(t0, t0, 0x7);
7541
            gen_load_fpr32(fp0, fs);
7542
            gen_load_fpr32h(fph0, fs);
7543
            gen_load_fpr32(fp1, ft);
7544
            gen_load_fpr32h(fph1, ft);
7545

    
7546
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7547
            gen_store_fpr32(fp0, fd);
7548
            gen_store_fpr32h(fph0, fd);
7549
            tcg_gen_br(l2);
7550
            gen_set_label(l1);
7551
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7552
            tcg_temp_free(t0);
7553
#ifdef TARGET_WORDS_BIGENDIAN
7554
            gen_store_fpr32(fph1, fd);
7555
            gen_store_fpr32h(fp0, fd);
7556
#else
7557
            gen_store_fpr32(fph0, fd);
7558
            gen_store_fpr32h(fp1, fd);
7559
#endif
7560
            gen_set_label(l2);
7561
            tcg_temp_free(fp0);
7562
            tcg_temp_free(fph0);
7563
            tcg_temp_free(fp1);
7564
            tcg_temp_free(fph1);
7565
        }
7566
        opn = "alnv.ps";
7567
        break;
7568
    case OPC_MADD_S:
7569
        check_cop1x(ctx);
7570
        {
7571
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7572
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7573
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7574

    
7575
            gen_load_fpr32(fp0, fs);
7576
            gen_load_fpr32(fp1, ft);
7577
            gen_load_fpr32(fp2, fr);
7578
            tcg_gen_helper_1_3(do_float_muladd_s, fp2, fp0, fp1, fp2);
7579
            tcg_temp_free(fp0);
7580
            tcg_temp_free(fp1);
7581
            gen_store_fpr32(fp2, fd);
7582
            tcg_temp_free(fp2);
7583
        }
7584
        opn = "madd.s";
7585
        break;
7586
    case OPC_MADD_D:
7587
        check_cop1x(ctx);
7588
        check_cp1_registers(ctx, fd | fs | ft | fr);
7589
        {
7590
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7591
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7592
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7593

    
7594
            gen_load_fpr64(ctx, fp0, fs);
7595
            gen_load_fpr64(ctx, fp1, ft);
7596
            gen_load_fpr64(ctx, fp2, fr);
7597
            tcg_gen_helper_1_3(do_float_muladd_d, fp2, fp0, fp1, fp2);
7598
            tcg_temp_free(fp0);
7599
            tcg_temp_free(fp1);
7600
            gen_store_fpr64(ctx, fp2, fd);
7601
            tcg_temp_free(fp2);
7602
        }
7603
        opn = "madd.d";
7604
        break;
7605
    case OPC_MADD_PS:
7606
        check_cp1_64bitmode(ctx);
7607
        {
7608
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7609
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7610
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7611

    
7612
            gen_load_fpr64(ctx, fp0, fs);
7613
            gen_load_fpr64(ctx, fp1, ft);
7614
            gen_load_fpr64(ctx, fp2, fr);
7615
            tcg_gen_helper_1_3(do_float_muladd_ps, fp2, fp0, fp1, fp2);
7616
            tcg_temp_free(fp0);
7617
            tcg_temp_free(fp1);
7618
            gen_store_fpr64(ctx, fp2, fd);
7619
            tcg_temp_free(fp2);
7620
        }
7621
        opn = "madd.ps";
7622
        break;
7623
    case OPC_MSUB_S:
7624
        check_cop1x(ctx);
7625
        {
7626
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7627
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7628
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7629

    
7630
            gen_load_fpr32(fp0, fs);
7631
            gen_load_fpr32(fp1, ft);
7632
            gen_load_fpr32(fp2, fr);
7633
            tcg_gen_helper_1_3(do_float_mulsub_s, fp2, fp0, fp1, fp2);
7634
            tcg_temp_free(fp0);
7635
            tcg_temp_free(fp1);
7636
            gen_store_fpr32(fp2, fd);
7637
            tcg_temp_free(fp2);
7638
        }
7639
        opn = "msub.s";
7640
        break;
7641
    case OPC_MSUB_D:
7642
        check_cop1x(ctx);
7643
        check_cp1_registers(ctx, fd | fs | ft | fr);
7644
        {
7645
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7646
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7647
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7648

    
7649
            gen_load_fpr64(ctx, fp0, fs);
7650
            gen_load_fpr64(ctx, fp1, ft);
7651
            gen_load_fpr64(ctx, fp2, fr);
7652
            tcg_gen_helper_1_3(do_float_mulsub_d, fp2, fp0, fp1, fp2);
7653
            tcg_temp_free(fp0);
7654
            tcg_temp_free(fp1);
7655
            gen_store_fpr64(ctx, fp2, fd);
7656
            tcg_temp_free(fp2);
7657
        }
7658
        opn = "msub.d";
7659
        break;
7660
    case OPC_MSUB_PS:
7661
        check_cp1_64bitmode(ctx);
7662
        {
7663
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7664
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7665
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7666

    
7667
            gen_load_fpr64(ctx, fp0, fs);
7668
            gen_load_fpr64(ctx, fp1, ft);
7669
            gen_load_fpr64(ctx, fp2, fr);
7670
            tcg_gen_helper_1_3(do_float_mulsub_ps, fp2, fp0, fp1, fp2);
7671
            tcg_temp_free(fp0);
7672
            tcg_temp_free(fp1);
7673
            gen_store_fpr64(ctx, fp2, fd);
7674
            tcg_temp_free(fp2);
7675
        }
7676
        opn = "msub.ps";
7677
        break;
7678
    case OPC_NMADD_S:
7679
        check_cop1x(ctx);
7680
        {
7681
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7682
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7683
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7684

    
7685
            gen_load_fpr32(fp0, fs);
7686
            gen_load_fpr32(fp1, ft);
7687
            gen_load_fpr32(fp2, fr);
7688
            tcg_gen_helper_1_3(do_float_nmuladd_s, fp2, fp0, fp1, fp2);
7689
            tcg_temp_free(fp0);
7690
            tcg_temp_free(fp1);
7691
            gen_store_fpr32(fp2, fd);
7692
            tcg_temp_free(fp2);
7693
        }
7694
        opn = "nmadd.s";
7695
        break;
7696
    case OPC_NMADD_D:
7697
        check_cop1x(ctx);
7698
        check_cp1_registers(ctx, fd | fs | ft | fr);
7699
        {
7700
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7701
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7702
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7703

    
7704
            gen_load_fpr64(ctx, fp0, fs);
7705
            gen_load_fpr64(ctx, fp1, ft);
7706
            gen_load_fpr64(ctx, fp2, fr);
7707
            tcg_gen_helper_1_3(do_float_nmuladd_d, fp2, fp0, fp1, fp2);
7708
            tcg_temp_free(fp0);
7709
            tcg_temp_free(fp1);
7710
            gen_store_fpr64(ctx, fp2, fd);
7711
            tcg_temp_free(fp2);
7712
        }
7713
        opn = "nmadd.d";
7714
        break;
7715
    case OPC_NMADD_PS:
7716
        check_cp1_64bitmode(ctx);
7717
        {
7718
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7719
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7720
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7721

    
7722
            gen_load_fpr64(ctx, fp0, fs);
7723
            gen_load_fpr64(ctx, fp1, ft);
7724
            gen_load_fpr64(ctx, fp2, fr);
7725
            tcg_gen_helper_1_3(do_float_nmuladd_ps, fp2, fp0, fp1, fp2);
7726
            tcg_temp_free(fp0);
7727
            tcg_temp_free(fp1);
7728
            gen_store_fpr64(ctx, fp2, fd);
7729
            tcg_temp_free(fp2);
7730
        }
7731
        opn = "nmadd.ps";
7732
        break;
7733
    case OPC_NMSUB_S:
7734
        check_cop1x(ctx);
7735
        {
7736
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7737
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7738
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7739

    
7740
            gen_load_fpr32(fp0, fs);
7741
            gen_load_fpr32(fp1, ft);
7742
            gen_load_fpr32(fp2, fr);
7743
            tcg_gen_helper_1_3(do_float_nmulsub_s, fp2, fp0, fp1, fp2);
7744
            tcg_temp_free(fp0);
7745
            tcg_temp_free(fp1);
7746
            gen_store_fpr32(fp2, fd);
7747
            tcg_temp_free(fp2);
7748
        }
7749
        opn = "nmsub.s";
7750
        break;
7751
    case OPC_NMSUB_D:
7752
        check_cop1x(ctx);
7753
        check_cp1_registers(ctx, fd | fs | ft | fr);
7754
        {
7755
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7756
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7757
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7758

    
7759
            gen_load_fpr64(ctx, fp0, fs);
7760
            gen_load_fpr64(ctx, fp1, ft);
7761
            gen_load_fpr64(ctx, fp2, fr);
7762
            tcg_gen_helper_1_3(do_float_nmulsub_d, fp2, fp0, fp1, fp2);
7763
            tcg_temp_free(fp0);
7764
            tcg_temp_free(fp1);
7765
            gen_store_fpr64(ctx, fp2, fd);
7766
            tcg_temp_free(fp2);
7767
        }
7768
        opn = "nmsub.d";
7769
        break;
7770
    case OPC_NMSUB_PS:
7771
        check_cp1_64bitmode(ctx);
7772
        {
7773
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7774
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7775
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7776

    
7777
            gen_load_fpr64(ctx, fp0, fs);
7778
            gen_load_fpr64(ctx, fp1, ft);
7779
            gen_load_fpr64(ctx, fp2, fr);
7780
            tcg_gen_helper_1_3(do_float_nmulsub_ps, fp2, fp0, fp1, fp2);
7781
            tcg_temp_free(fp0);
7782
            tcg_temp_free(fp1);
7783
            gen_store_fpr64(ctx, fp2, fd);
7784
            tcg_temp_free(fp2);
7785
        }
7786
        opn = "nmsub.ps";
7787
        break;
7788
    default:
7789
        MIPS_INVAL(opn);
7790
        generate_exception (ctx, EXCP_RI);
7791
        return;
7792
    }
7793
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7794
               fregnames[fs], fregnames[ft]);
7795
}
7796

    
7797
/* ISA extensions (ASEs) */
7798
/* MIPS16 extension to MIPS32 */
7799
/* SmartMIPS extension to MIPS32 */
7800

    
7801
#if defined(TARGET_MIPS64)
7802

    
7803
/* MDMX extension to MIPS64 */
7804

    
7805
#endif
7806

    
7807
static void decode_opc (CPUState *env, DisasContext *ctx)
7808
{
7809
    int32_t offset;
7810
    int rs, rt, rd, sa;
7811
    uint32_t op, op1, op2;
7812
    int16_t imm;
7813

    
7814
    /* make sure instructions are on a word boundary */
7815
    if (ctx->pc & 0x3) {
7816
        env->CP0_BadVAddr = ctx->pc;
7817
        generate_exception(ctx, EXCP_AdEL);
7818
        return;
7819
    }
7820

    
7821
    /* Handle blikely not taken case */
7822
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7823
        int l1 = gen_new_label();
7824

    
7825
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7826
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7827
        {
7828
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
7829

    
7830
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7831
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7832
            tcg_temp_free(r_tmp);
7833
        }
7834
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7835
        gen_set_label(l1);
7836
    }
7837
    op = MASK_OP_MAJOR(ctx->opcode);
7838
    rs = (ctx->opcode >> 21) & 0x1f;
7839
    rt = (ctx->opcode >> 16) & 0x1f;
7840
    rd = (ctx->opcode >> 11) & 0x1f;
7841
    sa = (ctx->opcode >> 6) & 0x1f;
7842
    imm = (int16_t)ctx->opcode;
7843
    switch (op) {
7844
    case OPC_SPECIAL:
7845
        op1 = MASK_SPECIAL(ctx->opcode);
7846
        switch (op1) {
7847
        case OPC_SLL:          /* Arithmetic with immediate */
7848
        case OPC_SRL ... OPC_SRA:
7849
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7850
            break;
7851
        case OPC_MOVZ ... OPC_MOVN:
7852
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7853
        case OPC_SLLV:         /* Arithmetic */
7854
        case OPC_SRLV ... OPC_SRAV:
7855
        case OPC_ADD ... OPC_NOR:
7856
        case OPC_SLT ... OPC_SLTU:
7857
            gen_arith(env, ctx, op1, rd, rs, rt);
7858
            break;
7859
        case OPC_MULT ... OPC_DIVU:
7860
            if (sa) {
7861
                check_insn(env, ctx, INSN_VR54XX);
7862
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7863
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7864
            } else
7865
                gen_muldiv(ctx, op1, rs, rt);
7866
            break;
7867
        case OPC_JR ... OPC_JALR:
7868
            gen_compute_branch(ctx, op1, rs, rd, sa);
7869
            return;
7870
        case OPC_TGE ... OPC_TEQ: /* Traps */
7871
        case OPC_TNE:
7872
            gen_trap(ctx, op1, rs, rt, -1);
7873
            break;
7874
        case OPC_MFHI:          /* Move from HI/LO */
7875
        case OPC_MFLO:
7876
            gen_HILO(ctx, op1, rd);
7877
            break;
7878
        case OPC_MTHI:
7879
        case OPC_MTLO:          /* Move to HI/LO */
7880
            gen_HILO(ctx, op1, rs);
7881
            break;
7882
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7883
#ifdef MIPS_STRICT_STANDARD
7884
            MIPS_INVAL("PMON / selsl");
7885
            generate_exception(ctx, EXCP_RI);
7886
#else
7887
            tcg_gen_helper_0_i(do_pmon, sa);
7888
#endif
7889
            break;
7890
        case OPC_SYSCALL:
7891
            generate_exception(ctx, EXCP_SYSCALL);
7892
            break;
7893
        case OPC_BREAK:
7894
            generate_exception(ctx, EXCP_BREAK);
7895
            break;
7896
        case OPC_SPIM:
7897
#ifdef MIPS_STRICT_STANDARD
7898
            MIPS_INVAL("SPIM");
7899
            generate_exception(ctx, EXCP_RI);
7900
#else
7901
           /* Implemented as RI exception for now. */
7902
            MIPS_INVAL("spim (unofficial)");
7903
            generate_exception(ctx, EXCP_RI);
7904
#endif
7905
            break;
7906
        case OPC_SYNC:
7907
            /* Treat as NOP. */
7908
            break;
7909

    
7910
        case OPC_MOVCI:
7911
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7912
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7913
                save_cpu_state(ctx, 1);
7914
                check_cp1_enabled(ctx);
7915
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7916
                          (ctx->opcode >> 16) & 1);
7917
            } else {
7918
                generate_exception_err(ctx, EXCP_CpU, 1);
7919
            }
7920
            break;
7921

    
7922
#if defined(TARGET_MIPS64)
7923
       /* MIPS64 specific opcodes */
7924
        case OPC_DSLL:
7925
        case OPC_DSRL ... OPC_DSRA:
7926
        case OPC_DSLL32:
7927
        case OPC_DSRL32 ... OPC_DSRA32:
7928
            check_insn(env, ctx, ISA_MIPS3);
7929
            check_mips_64(ctx);
7930
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7931
            break;
7932
        case OPC_DSLLV:
7933
        case OPC_DSRLV ... OPC_DSRAV:
7934
        case OPC_DADD ... OPC_DSUBU:
7935
            check_insn(env, ctx, ISA_MIPS3);
7936
            check_mips_64(ctx);
7937
            gen_arith(env, ctx, op1, rd, rs, rt);
7938
            break;
7939
        case OPC_DMULT ... OPC_DDIVU:
7940
            check_insn(env, ctx, ISA_MIPS3);
7941
            check_mips_64(ctx);
7942
            gen_muldiv(ctx, op1, rs, rt);
7943
            break;
7944
#endif
7945
        default:            /* Invalid */
7946
            MIPS_INVAL("special");
7947
            generate_exception(ctx, EXCP_RI);
7948
            break;
7949
        }
7950
        break;
7951
    case OPC_SPECIAL2:
7952
        op1 = MASK_SPECIAL2(ctx->opcode);
7953
        switch (op1) {
7954
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7955
        case OPC_MSUB ... OPC_MSUBU:
7956
            check_insn(env, ctx, ISA_MIPS32);
7957
            gen_muldiv(ctx, op1, rs, rt);
7958
            break;
7959
        case OPC_MUL:
7960
            gen_arith(env, ctx, op1, rd, rs, rt);
7961
            break;
7962
        case OPC_CLZ ... OPC_CLO:
7963
            check_insn(env, ctx, ISA_MIPS32);
7964
            gen_cl(ctx, op1, rd, rs);
7965
            break;
7966
        case OPC_SDBBP:
7967
            /* XXX: not clear which exception should be raised
7968
             *      when in debug mode...
7969
             */
7970
            check_insn(env, ctx, ISA_MIPS32);
7971
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7972
                generate_exception(ctx, EXCP_DBp);
7973
            } else {
7974
                generate_exception(ctx, EXCP_DBp);
7975
            }
7976
            /* Treat as NOP. */
7977
            break;
7978
#if defined(TARGET_MIPS64)
7979
        case OPC_DCLZ ... OPC_DCLO:
7980
            check_insn(env, ctx, ISA_MIPS64);
7981
            check_mips_64(ctx);
7982
            gen_cl(ctx, op1, rd, rs);
7983
            break;
7984
#endif
7985
        default:            /* Invalid */
7986
            MIPS_INVAL("special2");
7987
            generate_exception(ctx, EXCP_RI);
7988
            break;
7989
        }
7990
        break;
7991
    case OPC_SPECIAL3:
7992
        op1 = MASK_SPECIAL3(ctx->opcode);
7993
        switch (op1) {
7994
        case OPC_EXT:
7995
        case OPC_INS:
7996
            check_insn(env, ctx, ISA_MIPS32R2);
7997
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7998
            break;
7999
        case OPC_BSHFL:
8000
            check_insn(env, ctx, ISA_MIPS32R2);
8001
            op2 = MASK_BSHFL(ctx->opcode);
8002
            {
8003
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8004
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8005

    
8006
                switch (op2) {
8007
                case OPC_WSBH:
8008
                    gen_load_gpr(t1, rt);
8009
                    tcg_gen_helper_1_1(do_wsbh, t0, t1);
8010
                    gen_store_gpr(t0, rd);
8011
                    break;
8012
                case OPC_SEB:
8013
                    gen_load_gpr(t1, rt);
8014
                    tcg_gen_ext8s_tl(t0, t1);
8015
                    gen_store_gpr(t0, rd);
8016
                    break;
8017
                case OPC_SEH:
8018
                    gen_load_gpr(t1, rt);
8019
                    tcg_gen_ext16s_tl(t0, t1);
8020
                    gen_store_gpr(t0, rd);
8021
                    break;
8022
                default:            /* Invalid */
8023
                    MIPS_INVAL("bshfl");
8024
                    generate_exception(ctx, EXCP_RI);
8025
                    break;
8026
                }
8027
                tcg_temp_free(t0);
8028
                tcg_temp_free(t1);
8029
            }
8030
            break;
8031
        case OPC_RDHWR:
8032
            check_insn(env, ctx, ISA_MIPS32R2);
8033
            {
8034
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8035

    
8036
                switch (rd) {
8037
                case 0:
8038
                    save_cpu_state(ctx, 1);
8039
                    tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
8040
                    break;
8041
                case 1:
8042
                    save_cpu_state(ctx, 1);
8043
                    tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
8044
                    break;
8045
                case 2:
8046
                    save_cpu_state(ctx, 1);
8047
                    tcg_gen_helper_1_0(do_rdhwr_cc, t0);
8048
                    break;
8049
                case 3:
8050
                    save_cpu_state(ctx, 1);
8051
                    tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
8052
                    break;
8053
                case 29:
8054
                    if (env->user_mode_only) {
8055
                        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8056
                        break;
8057
                    } else {
8058
                        /* XXX: Some CPUs implement this in hardware.
8059
                           Not supported yet. */
8060
                    }
8061
                default:            /* Invalid */
8062
                    MIPS_INVAL("rdhwr");
8063
                    generate_exception(ctx, EXCP_RI);
8064
                    break;
8065
                }
8066
                gen_store_gpr(t0, rt);
8067
                tcg_temp_free(t0);
8068
            }
8069
            break;
8070
        case OPC_FORK:
8071
            check_insn(env, ctx, ASE_MT);
8072
            {
8073
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8074
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8075

    
8076
                gen_load_gpr(t0, rt);
8077
                gen_load_gpr(t1, rs);
8078
                tcg_gen_helper_0_2(do_fork, t0, t1);
8079
                tcg_temp_free(t0);
8080
                tcg_temp_free(t1);
8081
            }
8082
            break;
8083
        case OPC_YIELD:
8084
            check_insn(env, ctx, ASE_MT);
8085
            {
8086
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8087

    
8088
                gen_load_gpr(t0, rs);
8089
                tcg_gen_helper_1_1(do_yield, t0, t0);
8090
                gen_store_gpr(t0, rd);
8091
                tcg_temp_free(t0);
8092
            }
8093
            break;
8094
#if defined(TARGET_MIPS64)
8095
        case OPC_DEXTM ... OPC_DEXT:
8096
        case OPC_DINSM ... OPC_DINS:
8097
            check_insn(env, ctx, ISA_MIPS64R2);
8098
            check_mips_64(ctx);
8099
            gen_bitops(ctx, op1, rt, rs, sa, rd);
8100
            break;
8101
        case OPC_DBSHFL:
8102
            check_insn(env, ctx, ISA_MIPS64R2);
8103
            check_mips_64(ctx);
8104
            op2 = MASK_DBSHFL(ctx->opcode);
8105
            {
8106
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8107
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8108

    
8109
                switch (op2) {
8110
                case OPC_DSBH:
8111
                    gen_load_gpr(t1, rt);
8112
                    tcg_gen_helper_1_1(do_dsbh, t0, t1);
8113
                    break;
8114
                case OPC_DSHD:
8115
                    gen_load_gpr(t1, rt);
8116
                    tcg_gen_helper_1_1(do_dshd, t0, t1);
8117
                    break;
8118
                default:            /* Invalid */
8119
                    MIPS_INVAL("dbshfl");
8120
                    generate_exception(ctx, EXCP_RI);
8121
                    break;
8122
                }
8123
                gen_store_gpr(t0, rd);
8124
                tcg_temp_free(t0);
8125
                tcg_temp_free(t1);
8126
            }
8127
            break;
8128
#endif
8129
        default:            /* Invalid */
8130
            MIPS_INVAL("special3");
8131
            generate_exception(ctx, EXCP_RI);
8132
            break;
8133
        }
8134
        break;
8135
    case OPC_REGIMM:
8136
        op1 = MASK_REGIMM(ctx->opcode);
8137
        switch (op1) {
8138
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
8139
        case OPC_BLTZAL ... OPC_BGEZALL:
8140
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
8141
            return;
8142
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
8143
        case OPC_TNEI:
8144
            gen_trap(ctx, op1, rs, -1, imm);
8145
            break;
8146
        case OPC_SYNCI:
8147
            check_insn(env, ctx, ISA_MIPS32R2);
8148
            /* Treat as NOP. */
8149
            break;
8150
        default:            /* Invalid */
8151
            MIPS_INVAL("regimm");
8152
            generate_exception(ctx, EXCP_RI);
8153
            break;
8154
        }
8155
        break;
8156
    case OPC_CP0:
8157
        check_cp0_enabled(ctx);
8158
        op1 = MASK_CP0(ctx->opcode);
8159
        switch (op1) {
8160
        case OPC_MFC0:
8161
        case OPC_MTC0:
8162
        case OPC_MFTR:
8163
        case OPC_MTTR:
8164
#if defined(TARGET_MIPS64)
8165
        case OPC_DMFC0:
8166
        case OPC_DMTC0:
8167
#endif
8168
#ifndef CONFIG_USER_ONLY
8169
            if (!env->user_mode_only)
8170
                gen_cp0(env, ctx, op1, rt, rd);
8171
#endif /* !CONFIG_USER_ONLY */
8172
            break;
8173
        case OPC_C0_FIRST ... OPC_C0_LAST:
8174
#ifndef CONFIG_USER_ONLY
8175
            if (!env->user_mode_only)
8176
                gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
8177
#endif /* !CONFIG_USER_ONLY */
8178
            break;
8179
        case OPC_MFMC0:
8180
#ifndef CONFIG_USER_ONLY
8181
            if (!env->user_mode_only) {
8182
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8183

    
8184
                op2 = MASK_MFMC0(ctx->opcode);
8185
                switch (op2) {
8186
                case OPC_DMT:
8187
                    check_insn(env, ctx, ASE_MT);
8188
                    tcg_gen_helper_1_1(do_dmt, t0, t0);
8189
                    break;
8190
                case OPC_EMT:
8191
                    check_insn(env, ctx, ASE_MT);
8192
                    tcg_gen_helper_1_1(do_emt, t0, t0);
8193
                     break;
8194
                case OPC_DVPE:
8195
                    check_insn(env, ctx, ASE_MT);
8196
                    tcg_gen_helper_1_1(do_dvpe, t0, t0);
8197
                    break;
8198
                case OPC_EVPE:
8199
                    check_insn(env, ctx, ASE_MT);
8200
                    tcg_gen_helper_1_1(do_evpe, t0, t0);
8201
                    break;
8202
                case OPC_DI:
8203
                    check_insn(env, ctx, ISA_MIPS32R2);
8204
                    save_cpu_state(ctx, 1);
8205
                    tcg_gen_helper_1_0(do_di, t0);
8206
                    /* Stop translation as we may have switched the execution mode */
8207
                    ctx->bstate = BS_STOP;
8208
                    break;
8209
                case OPC_EI:
8210
                    check_insn(env, ctx, ISA_MIPS32R2);
8211
                    save_cpu_state(ctx, 1);
8212
                    tcg_gen_helper_1_0(do_ei, t0);
8213
                    /* Stop translation as we may have switched the execution mode */
8214
                    ctx->bstate = BS_STOP;
8215
                    break;
8216
                default:            /* Invalid */
8217
                    MIPS_INVAL("mfmc0");
8218
                    generate_exception(ctx, EXCP_RI);
8219
                    break;
8220
                }
8221
                gen_store_gpr(t0, rt);
8222
                tcg_temp_free(t0);
8223
            }
8224
#endif /* !CONFIG_USER_ONLY */
8225
            break;
8226
        case OPC_RDPGPR:
8227
            check_insn(env, ctx, ISA_MIPS32R2);
8228
            gen_load_srsgpr(rt, rd);
8229
            break;
8230
        case OPC_WRPGPR:
8231
            check_insn(env, ctx, ISA_MIPS32R2);
8232
            gen_store_srsgpr(rt, rd);
8233
            break;
8234
        default:
8235
            MIPS_INVAL("cp0");
8236
            generate_exception(ctx, EXCP_RI);
8237
            break;
8238
        }
8239
        break;
8240
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
8241
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8242
         break;
8243
    case OPC_J ... OPC_JAL: /* Jump */
8244
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8245
         gen_compute_branch(ctx, op, rs, rt, offset);
8246
         return;
8247
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8248
    case OPC_BEQL ... OPC_BGTZL:
8249
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8250
         return;
8251
    case OPC_LB ... OPC_LWR: /* Load and stores */
8252
    case OPC_SB ... OPC_SW:
8253
    case OPC_SWR:
8254
    case OPC_LL:
8255
    case OPC_SC:
8256
         gen_ldst(ctx, op, rt, rs, imm);
8257
         break;
8258
    case OPC_CACHE:
8259
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8260
        /* Treat as NOP. */
8261
        break;
8262
    case OPC_PREF:
8263
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8264
        /* Treat as NOP. */
8265
        break;
8266

    
8267
    /* Floating point (COP1). */
8268
    case OPC_LWC1:
8269
    case OPC_LDC1:
8270
    case OPC_SWC1:
8271
    case OPC_SDC1:
8272
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8273
            save_cpu_state(ctx, 1);
8274
            check_cp1_enabled(ctx);
8275
            gen_flt_ldst(ctx, op, rt, rs, imm);
8276
        } else {
8277
            generate_exception_err(ctx, EXCP_CpU, 1);
8278
        }
8279
        break;
8280

    
8281
    case OPC_CP1:
8282
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8283
            save_cpu_state(ctx, 1);
8284
            check_cp1_enabled(ctx);
8285
            op1 = MASK_CP1(ctx->opcode);
8286
            switch (op1) {
8287
            case OPC_MFHC1:
8288
            case OPC_MTHC1:
8289
                check_insn(env, ctx, ISA_MIPS32R2);
8290
            case OPC_MFC1:
8291
            case OPC_CFC1:
8292
            case OPC_MTC1:
8293
            case OPC_CTC1:
8294
                gen_cp1(ctx, op1, rt, rd);
8295
                break;
8296
#if defined(TARGET_MIPS64)
8297
            case OPC_DMFC1:
8298
            case OPC_DMTC1:
8299
                check_insn(env, ctx, ISA_MIPS3);
8300
                gen_cp1(ctx, op1, rt, rd);
8301
                break;
8302
#endif
8303
            case OPC_BC1ANY2:
8304
            case OPC_BC1ANY4:
8305
                check_cop1x(ctx);
8306
                check_insn(env, ctx, ASE_MIPS3D);
8307
                /* fall through */
8308
            case OPC_BC1:
8309
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8310
                                    (rt >> 2) & 0x7, imm << 2);
8311
                return;
8312
            case OPC_S_FMT:
8313
            case OPC_D_FMT:
8314
            case OPC_W_FMT:
8315
            case OPC_L_FMT:
8316
            case OPC_PS_FMT:
8317
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8318
                           (imm >> 8) & 0x7);
8319
                break;
8320
            default:
8321
                MIPS_INVAL("cp1");
8322
                generate_exception (ctx, EXCP_RI);
8323
                break;
8324
            }
8325
        } else {
8326
            generate_exception_err(ctx, EXCP_CpU, 1);
8327
        }
8328
        break;
8329

    
8330
    /* COP2.  */
8331
    case OPC_LWC2:
8332
    case OPC_LDC2:
8333
    case OPC_SWC2:
8334
    case OPC_SDC2:
8335
    case OPC_CP2:
8336
        /* COP2: Not implemented. */
8337
        generate_exception_err(ctx, EXCP_CpU, 2);
8338
        break;
8339

    
8340
    case OPC_CP3:
8341
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8342
            save_cpu_state(ctx, 1);
8343
            check_cp1_enabled(ctx);
8344
            op1 = MASK_CP3(ctx->opcode);
8345
            switch (op1) {
8346
            case OPC_LWXC1:
8347
            case OPC_LDXC1:
8348
            case OPC_LUXC1:
8349
            case OPC_SWXC1:
8350
            case OPC_SDXC1:
8351
            case OPC_SUXC1:
8352
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8353
                break;
8354
            case OPC_PREFX:
8355
                /* Treat as NOP. */
8356
                break;
8357
            case OPC_ALNV_PS:
8358
            case OPC_MADD_S:
8359
            case OPC_MADD_D:
8360
            case OPC_MADD_PS:
8361
            case OPC_MSUB_S:
8362
            case OPC_MSUB_D:
8363
            case OPC_MSUB_PS:
8364
            case OPC_NMADD_S:
8365
            case OPC_NMADD_D:
8366
            case OPC_NMADD_PS:
8367
            case OPC_NMSUB_S:
8368
            case OPC_NMSUB_D:
8369
            case OPC_NMSUB_PS:
8370
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8371
                break;
8372
            default:
8373
                MIPS_INVAL("cp3");
8374
                generate_exception (ctx, EXCP_RI);
8375
                break;
8376
            }
8377
        } else {
8378
            generate_exception_err(ctx, EXCP_CpU, 1);
8379
        }
8380
        break;
8381

    
8382
#if defined(TARGET_MIPS64)
8383
    /* MIPS64 opcodes */
8384
    case OPC_LWU:
8385
    case OPC_LDL ... OPC_LDR:
8386
    case OPC_SDL ... OPC_SDR:
8387
    case OPC_LLD:
8388
    case OPC_LD:
8389
    case OPC_SCD:
8390
    case OPC_SD:
8391
        check_insn(env, ctx, ISA_MIPS3);
8392
        check_mips_64(ctx);
8393
        gen_ldst(ctx, op, rt, rs, imm);
8394
        break;
8395
    case OPC_DADDI ... OPC_DADDIU:
8396
        check_insn(env, ctx, ISA_MIPS3);
8397
        check_mips_64(ctx);
8398
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8399
        break;
8400
#endif
8401
    case OPC_JALX:
8402
        check_insn(env, ctx, ASE_MIPS16);
8403
        /* MIPS16: Not implemented. */
8404
    case OPC_MDMX:
8405
        check_insn(env, ctx, ASE_MDMX);
8406
        /* MDMX: Not implemented. */
8407
    default:            /* Invalid */
8408
        MIPS_INVAL("major opcode");
8409
        generate_exception(ctx, EXCP_RI);
8410
        break;
8411
    }
8412
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8413
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8414
        /* Branches completion */
8415
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8416
        ctx->bstate = BS_BRANCH;
8417
        save_cpu_state(ctx, 0);
8418
        /* FIXME: Need to clear can_do_io.  */
8419
        switch (hflags) {
8420
        case MIPS_HFLAG_B:
8421
            /* unconditional branch */
8422
            MIPS_DEBUG("unconditional branch");
8423
            gen_goto_tb(ctx, 0, ctx->btarget);
8424
            break;
8425
        case MIPS_HFLAG_BL:
8426
            /* blikely taken case */
8427
            MIPS_DEBUG("blikely branch taken");
8428
            gen_goto_tb(ctx, 0, ctx->btarget);
8429
            break;
8430
        case MIPS_HFLAG_BC:
8431
            /* Conditional branch */
8432
            MIPS_DEBUG("conditional branch");
8433
            {
8434
                int l1 = gen_new_label();
8435

    
8436
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8437
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8438
                gen_set_label(l1);
8439
                gen_goto_tb(ctx, 0, ctx->btarget);
8440
            }
8441
            break;
8442
        case MIPS_HFLAG_BR:
8443
            /* unconditional branch to register */
8444
            MIPS_DEBUG("branch to register");
8445
            tcg_gen_st_tl(btarget, cpu_env, offsetof(CPUState, active_tc.PC));
8446
            tcg_gen_exit_tb(0);
8447
            break;
8448
        default:
8449
            MIPS_DEBUG("unknown branch");
8450
            break;
8451
        }
8452
    }
8453
}
8454

    
8455
static inline void
8456
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8457
                                int search_pc)
8458
{
8459
    DisasContext ctx;
8460
    target_ulong pc_start;
8461
    uint16_t *gen_opc_end;
8462
    int j, lj = -1;
8463
    int num_insns;
8464
    int max_insns;
8465

    
8466
    if (search_pc && loglevel)
8467
        fprintf (logfile, "search pc %d\n", search_pc);
8468

    
8469
    pc_start = tb->pc;
8470
    /* Leave some spare opc slots for branch handling. */
8471
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8472
    ctx.pc = pc_start;
8473
    ctx.saved_pc = -1;
8474
    ctx.tb = tb;
8475
    ctx.bstate = BS_NONE;
8476
    /* Restore delay slot state from the tb context.  */
8477
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8478
    restore_cpu_state(env, &ctx);
8479
    if (env->user_mode_only)
8480
        ctx.mem_idx = MIPS_HFLAG_UM;
8481
    else
8482
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8483
    num_insns = 0;
8484
    max_insns = tb->cflags & CF_COUNT_MASK;
8485
    if (max_insns == 0)
8486
        max_insns = CF_COUNT_MASK;
8487
#ifdef DEBUG_DISAS
8488
    if (loglevel & CPU_LOG_TB_CPU) {
8489
        fprintf(logfile, "------------------------------------------------\n");
8490
        /* FIXME: This may print out stale hflags from env... */
8491
        cpu_dump_state(env, logfile, fprintf, 0);
8492
    }
8493
#endif
8494
#ifdef MIPS_DEBUG_DISAS
8495
    if (loglevel & CPU_LOG_TB_IN_ASM)
8496
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
8497
                tb, ctx.mem_idx, ctx.hflags);
8498
#endif
8499
    gen_icount_start();
8500
    while (ctx.bstate == BS_NONE) {
8501
        if (env->nb_breakpoints > 0) {
8502
            for(j = 0; j < env->nb_breakpoints; j++) {
8503
                if (env->breakpoints[j] == ctx.pc) {
8504
                    save_cpu_state(&ctx, 1);
8505
                    ctx.bstate = BS_BRANCH;
8506
                    tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8507
                    /* Include the breakpoint location or the tb won't
8508
                     * be flushed when it must be.  */
8509
                    ctx.pc += 4;
8510
                    goto done_generating;
8511
                }
8512
            }
8513
        }
8514

    
8515
        if (search_pc) {
8516
            j = gen_opc_ptr - gen_opc_buf;
8517
            if (lj < j) {
8518
                lj++;
8519
                while (lj < j)
8520
                    gen_opc_instr_start[lj++] = 0;
8521
            }
8522
            gen_opc_pc[lj] = ctx.pc;
8523
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8524
            gen_opc_instr_start[lj] = 1;
8525
            gen_opc_icount[lj] = num_insns;
8526
        }
8527
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8528
            gen_io_start();
8529
        ctx.opcode = ldl_code(ctx.pc);
8530
        decode_opc(env, &ctx);
8531
        ctx.pc += 4;
8532
        num_insns++;
8533

    
8534
        if (env->singlestep_enabled)
8535
            break;
8536

    
8537
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8538
            break;
8539

    
8540
        if (gen_opc_ptr >= gen_opc_end)
8541
            break;
8542

    
8543
        if (num_insns >= max_insns)
8544
            break;
8545
#if defined (MIPS_SINGLE_STEP)
8546
        break;
8547
#endif
8548
    }
8549
    if (tb->cflags & CF_LAST_IO)
8550
        gen_io_end();
8551
    if (env->singlestep_enabled) {
8552
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8553
        tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8554
    } else {
8555
        switch (ctx.bstate) {
8556
        case BS_STOP:
8557
            tcg_gen_helper_0_0(do_interrupt_restart);
8558
            gen_goto_tb(&ctx, 0, ctx.pc);
8559
            break;
8560
        case BS_NONE:
8561
            save_cpu_state(&ctx, 0);
8562
            gen_goto_tb(&ctx, 0, ctx.pc);
8563
            break;
8564
        case BS_EXCP:
8565
            tcg_gen_helper_0_0(do_interrupt_restart);
8566
            tcg_gen_exit_tb(0);
8567
            break;
8568
        case BS_BRANCH:
8569
        default:
8570
            break;
8571
        }
8572
    }
8573
done_generating:
8574
    gen_icount_end(tb, num_insns);
8575
    *gen_opc_ptr = INDEX_op_end;
8576
    if (search_pc) {
8577
        j = gen_opc_ptr - gen_opc_buf;
8578
        lj++;
8579
        while (lj <= j)
8580
            gen_opc_instr_start[lj++] = 0;
8581
    } else {
8582
        tb->size = ctx.pc - pc_start;
8583
        tb->icount = num_insns;
8584
    }
8585
#ifdef DEBUG_DISAS
8586
#if defined MIPS_DEBUG_DISAS
8587
    if (loglevel & CPU_LOG_TB_IN_ASM)
8588
        fprintf(logfile, "\n");
8589
#endif
8590
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8591
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8592
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8593
        fprintf(logfile, "\n");
8594
    }
8595
    if (loglevel & CPU_LOG_TB_CPU) {
8596
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8597
    }
8598
#endif
8599
}
8600

    
8601
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8602
{
8603
    gen_intermediate_code_internal(env, tb, 0);
8604
}
8605

    
8606
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8607
{
8608
    gen_intermediate_code_internal(env, tb, 1);
8609
}
8610

    
8611
static void fpu_dump_state(CPUState *env, FILE *f,
8612
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8613
                           int flags)
8614
{
8615
    int i;
8616
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8617

    
8618
#define printfpr(fp)                                                        \
8619
    do {                                                                    \
8620
        if (is_fpu64)                                                       \
8621
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8622
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8623
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8624
        else {                                                              \
8625
            fpr_t tmp;                                                      \
8626
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8627
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8628
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8629
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8630
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8631
        }                                                                   \
8632
    } while(0)
8633

    
8634

    
8635
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8636
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
8637
                get_float_exception_flags(&env->fpu->fp_status));
8638
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8639
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8640
        printfpr(&env->fpu->fpr[i]);
8641
    }
8642

    
8643
#undef printfpr
8644
}
8645

    
8646
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8647
/* Debug help: The architecture requires 32bit code to maintain proper
8648
   sign-extended values on 64bit machines.  */
8649

    
8650
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8651

    
8652
static void
8653
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8654
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8655
                                int flags)
8656
{
8657
    int i;
8658

    
8659
    if (!SIGN_EXT_P(env->active_tc.PC))
8660
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8661
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8662
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8663
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8664
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8665
    if (!SIGN_EXT_P(env->btarget))
8666
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8667

    
8668
    for (i = 0; i < 32; i++) {
8669
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8670
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8671
    }
8672

    
8673
    if (!SIGN_EXT_P(env->CP0_EPC))
8674
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8675
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8676
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8677
}
8678
#endif
8679

    
8680
void cpu_dump_state (CPUState *env, FILE *f,
8681
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8682
                     int flags)
8683
{
8684
    int i;
8685

    
8686
    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",
8687
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8688
                env->hflags, env->btarget, env->bcond);
8689
    for (i = 0; i < 32; i++) {
8690
        if ((i & 3) == 0)
8691
            cpu_fprintf(f, "GPR%02d:", i);
8692
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8693
        if ((i & 3) == 3)
8694
            cpu_fprintf(f, "\n");
8695
    }
8696

    
8697
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8698
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8699
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8700
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8701
    if (env->hflags & MIPS_HFLAG_FPU)
8702
        fpu_dump_state(env, f, cpu_fprintf, flags);
8703
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8704
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8705
#endif
8706
}
8707

    
8708
static void mips_tcg_init(void)
8709
{
8710
    static int inited;
8711

    
8712
    /* Initialize various static tables. */
8713
    if (inited)
8714
        return;
8715

    
8716
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8717
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8718
                               offsetof(CPUState, bcond), "bcond");
8719
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8720
                                 offsetof(CPUState, btarget), "btarget");
8721
    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
8722
                                     TCG_AREG0,
8723
                                     offsetof(CPUState, fpu),
8724
                                     "current_fpu");
8725

    
8726
    /* register helpers */
8727
#undef DEF_HELPER
8728
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8729
#include "helper.h"
8730

    
8731
    inited = 1;
8732
}
8733

    
8734
#include "translate_init.c"
8735

    
8736
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8737
{
8738
    CPUMIPSState *env;
8739
    const mips_def_t *def;
8740

    
8741
    def = cpu_mips_find_by_name(cpu_model);
8742
    if (!def)
8743
        return NULL;
8744
    env = qemu_mallocz(sizeof(CPUMIPSState));
8745
    if (!env)
8746
        return NULL;
8747
    env->cpu_model = def;
8748

    
8749
    cpu_exec_init(env);
8750
    env->cpu_model_str = cpu_model;
8751
    mips_tcg_init();
8752
    cpu_reset(env);
8753
    return env;
8754
}
8755

    
8756
void cpu_reset (CPUMIPSState *env)
8757
{
8758
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8759

    
8760
    tlb_flush(env, 1);
8761

    
8762
    /* Minimal init */
8763
#if defined(CONFIG_USER_ONLY)
8764
    env->user_mode_only = 1;
8765
#endif
8766
    if (env->user_mode_only) {
8767
        env->hflags = MIPS_HFLAG_UM;
8768
    } else {
8769
        if (env->hflags & MIPS_HFLAG_BMASK) {
8770
            /* If the exception was raised from a delay slot,
8771
               come back to the jump.  */
8772
            env->CP0_ErrorEPC = env->active_tc.PC - 4;
8773
        } else {
8774
            env->CP0_ErrorEPC = env->active_tc.PC;
8775
        }
8776
        env->active_tc.PC = (int32_t)0xBFC00000;
8777
        env->CP0_Wired = 0;
8778
        /* SMP not implemented */
8779
        env->CP0_EBase = 0x80000000;
8780
        env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8781
        /* vectored interrupts not implemented, timer on int 7,
8782
           no performance counters. */
8783
        env->CP0_IntCtl = 0xe0000000;
8784
        {
8785
            int i;
8786

    
8787
            for (i = 0; i < 7; i++) {
8788
                env->CP0_WatchLo[i] = 0;
8789
                env->CP0_WatchHi[i] = 0x80000000;
8790
            }
8791
            env->CP0_WatchLo[7] = 0;
8792
            env->CP0_WatchHi[7] = 0;
8793
        }
8794
        /* Count register increments in debug mode, EJTAG version 1 */
8795
        env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8796
        env->hflags = MIPS_HFLAG_CP0;
8797
    }
8798
    env->exception_index = EXCP_NONE;
8799
    cpu_mips_register(env, env->cpu_model);
8800
}
8801

    
8802
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8803
                unsigned long searched_pc, int pc_pos, void *puc)
8804
{
8805
    env->active_tc.PC = gen_opc_pc[pc_pos];
8806
    env->hflags &= ~MIPS_HFLAG_BMASK;
8807
    env->hflags |= gen_opc_hflags[pc_pos];
8808
}