Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 36aa55dc

History | View | Annotate | Download (259.6 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, cpu_gpr[32], cpu_PC;
427
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
428
static TCGv cpu_dspctrl, bcond, btarget;
429
static TCGv fpu_fpr32[32], fpu_fpr32h[32], fpu_fpr64[32], fpu_fcr0, fpu_fcr31;
430

    
431
#include "gen-icount.h"
432

    
433
static inline void tcg_gen_helper_0_i(void *func, uint32_t arg)
434

    
435
{
436
    TCGv tmp = tcg_const_i32(arg);
437

    
438
    tcg_gen_helper_0_1(func, tmp);
439
    tcg_temp_free(tmp);
440
}
441

    
442
static inline void tcg_gen_helper_0_ii(void *func, uint32_t arg1, uint32_t arg2)
443
{
444
    TCGv tmp1 = tcg_const_i32(arg1);
445
    TCGv tmp2 = tcg_const_i32(arg2);
446

    
447
    tcg_gen_helper_0_2(func, tmp1, tmp2);
448
    tcg_temp_free(tmp1);
449
    tcg_temp_free(tmp2);
450
}
451

    
452
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, uint32_t arg2)
453
{
454
    TCGv tmp = tcg_const_i32(arg2);
455

    
456
    tcg_gen_helper_0_2(func, arg1, tmp);
457
    tcg_temp_free(tmp);
458
}
459

    
460
static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, uint32_t arg3)
461
{
462
    TCGv tmp = tcg_const_i32(arg3);
463

    
464
    tcg_gen_helper_0_3(func, arg1, arg2, tmp);
465
    tcg_temp_free(tmp);
466
}
467

    
468
static inline void tcg_gen_helper_0_1ii(void *func, TCGv arg1, uint32_t arg2, uint32_t arg3)
469
{
470
    TCGv tmp1 = tcg_const_i32(arg2);
471
    TCGv tmp2 = tcg_const_i32(arg3);
472

    
473
    tcg_gen_helper_0_3(func, arg1, tmp1, tmp2);
474
    tcg_temp_free(tmp1);
475
    tcg_temp_free(tmp2);
476
}
477

    
478
static inline void tcg_gen_helper_1_i(void *func, TCGv ret, uint32_t arg)
479
{
480
    TCGv tmp = tcg_const_i32(arg);
481

    
482
    tcg_gen_helper_1_1(func, ret, tmp);
483
    tcg_temp_free(tmp);
484
}
485

    
486
static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, uint32_t arg2)
487
{
488
    TCGv tmp = tcg_const_i32(arg2);
489

    
490
    tcg_gen_helper_1_2(func, ret, arg1, tmp);
491
    tcg_temp_free(tmp);
492
}
493

    
494
static inline void tcg_gen_helper_1_1ii(void *func, TCGv ret, TCGv arg1, uint32_t arg2, uint32_t arg3)
495
{
496
    TCGv tmp1 = tcg_const_i32(arg2);
497
    TCGv tmp2 = tcg_const_i32(arg3);
498

    
499
    tcg_gen_helper_1_3(func, ret, arg1, tmp1, tmp2);
500
    tcg_temp_free(tmp1);
501
    tcg_temp_free(tmp2);
502
}
503

    
504
static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, uint32_t arg3)
505
{
506
    TCGv tmp = tcg_const_i32(arg3);
507

    
508
    tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp);
509
    tcg_temp_free(tmp);
510
}
511

    
512
static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, uint32_t arg3, uint32_t arg4)
513
{
514
    TCGv tmp1 = tcg_const_i32(arg3);
515
    TCGv tmp2 = tcg_const_i32(arg4);
516

    
517
    tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2);
518
    tcg_temp_free(tmp1);
519
    tcg_temp_free(tmp2);
520
}
521

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

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

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

    
547
static const char *regnames_HI[] =
548
    { "HI0", "HI1", "HI2", "HI3", };
549

    
550
static const char *regnames_LO[] =
551
    { "LO0", "LO1", "LO2", "LO3", };
552

    
553
static const char *regnames_ACX[] =
554
    { "ACX0", "ACX1", "ACX2", "ACX3", };
555

    
556
static const char *fregnames[] =
557
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
558
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
559
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
560
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
561

    
562
static const char *fregnames_64[] =
563
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
564
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
565
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
566
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
567

    
568
static const char *fregnames_h[] =
569
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
570
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
571
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
572
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
573

    
574
#ifdef MIPS_DEBUG_DISAS
575
#define MIPS_DEBUG(fmt, args...)                                              \
576
do {                                                                          \
577
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
578
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
579
                ctx->pc, ctx->opcode , ##args);                               \
580
    }                                                                         \
581
} while (0)
582
#else
583
#define MIPS_DEBUG(fmt, args...) do { } while(0)
584
#endif
585

    
586
#define MIPS_INVAL(op)                                                        \
587
do {                                                                          \
588
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
589
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
590
} while (0)
591

    
592
/* General purpose registers moves. */
593
static inline void gen_load_gpr (TCGv t, int reg)
594
{
595
    if (reg == 0)
596
        tcg_gen_movi_tl(t, 0);
597
    else
598
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
599
}
600

    
601
static inline void gen_store_gpr (TCGv t, int reg)
602
{
603
    if (reg != 0)
604
        tcg_gen_mov_tl(cpu_gpr[reg], t);
605
}
606

    
607
/* Moves to/from HI and LO registers.  */
608
static inline void gen_load_HI (TCGv t, int reg)
609
{
610
    tcg_gen_mov_tl(t, cpu_HI[reg]);
611
}
612

    
613
static inline void gen_store_HI (TCGv t, int reg)
614
{
615
    tcg_gen_mov_tl(cpu_HI[reg], t);
616
}
617

    
618
static inline void gen_load_LO (TCGv t, int reg)
619
{
620
    tcg_gen_mov_tl(t, cpu_LO[reg]);
621
}
622

    
623
static inline void gen_store_LO (TCGv t, int reg)
624
{
625
    tcg_gen_mov_tl(cpu_LO[reg], t);
626
}
627

    
628
static inline void gen_load_ACX (TCGv t, int reg)
629
{
630
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
631
}
632

    
633
static inline void gen_store_ACX (TCGv t, int reg)
634
{
635
    tcg_gen_mov_tl(cpu_ACX[reg], t);
636
}
637

    
638
/* Moves to/from shadow registers. */
639
static inline void gen_load_srsgpr (int from, int to)
640
{
641
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
642

    
643
    if (from == 0)
644
        tcg_gen_movi_tl(r_tmp1, 0);
645
    else {
646
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
647

    
648
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
649
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
650
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
651
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
652
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
653

    
654
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
655
        tcg_temp_free(r_tmp2);
656
    }
657
    gen_store_gpr(r_tmp1, to);
658
    tcg_temp_free(r_tmp1);
659
}
660

    
661
static inline void gen_store_srsgpr (int from, int to)
662
{
663
    if (to != 0) {
664
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
665
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
666

    
667
        gen_load_gpr(r_tmp1, from);
668
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
669
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
670
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
671
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
672
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
673

    
674
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
675
        tcg_temp_free(r_tmp1);
676
        tcg_temp_free(r_tmp2);
677
    }
678
}
679

    
680
/* Floating point register moves. */
681
static inline void gen_load_fpr32 (TCGv t, int reg)
682
{
683
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
684
}
685

    
686
static inline void gen_store_fpr32 (TCGv t, int reg)
687
{
688
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
689
}
690

    
691
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
692
{
693
    if (ctx->hflags & MIPS_HFLAG_F64)
694
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
695
    else {
696
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
697
    }
698
}
699

    
700
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
701
{
702
    if (ctx->hflags & MIPS_HFLAG_F64)
703
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
704
    else {
705
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
706
        tcg_gen_shri_i64(t, t, 32);
707
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
708
    }
709
}
710

    
711
static inline void gen_load_fpr32h (TCGv t, int reg)
712
{
713
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
714
}
715

    
716
static inline void gen_store_fpr32h (TCGv t, int reg)
717
{
718
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
719
}
720

    
721
static inline void get_fp_cond (TCGv t)
722
{
723
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
724
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
725

    
726
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
727
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
728
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
729
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
730
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
731
    tcg_temp_free(r_tmp1);
732
    tcg_temp_free(r_tmp2);
733
}
734

    
735
typedef void (fcmp_fun32)(uint32_t, uint32_t, int);
736
typedef void (fcmp_fun64)(uint64_t, uint64_t, int);
737

    
738
#define FOP_CONDS(fcmp_fun, type, fmt)                                        \
739
static fcmp_fun * fcmp ## type ## _ ## fmt ## _table[16] = {                  \
740
    do_cmp ## type ## _ ## fmt ## _f,                                         \
741
    do_cmp ## type ## _ ## fmt ## _un,                                        \
742
    do_cmp ## type ## _ ## fmt ## _eq,                                        \
743
    do_cmp ## type ## _ ## fmt ## _ueq,                                       \
744
    do_cmp ## type ## _ ## fmt ## _olt,                                       \
745
    do_cmp ## type ## _ ## fmt ## _ult,                                       \
746
    do_cmp ## type ## _ ## fmt ## _ole,                                       \
747
    do_cmp ## type ## _ ## fmt ## _ule,                                       \
748
    do_cmp ## type ## _ ## fmt ## _sf,                                        \
749
    do_cmp ## type ## _ ## fmt ## _ngle,                                      \
750
    do_cmp ## type ## _ ## fmt ## _seq,                                       \
751
    do_cmp ## type ## _ ## fmt ## _ngl,                                       \
752
    do_cmp ## type ## _ ## fmt ## _lt,                                        \
753
    do_cmp ## type ## _ ## fmt ## _nge,                                       \
754
    do_cmp ## type ## _ ## fmt ## _le,                                        \
755
    do_cmp ## type ## _ ## fmt ## _ngt,                                       \
756
};                                                                            \
757
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv a, TCGv b, int cc) \
758
{                                                                             \
759
    tcg_gen_helper_0_2i(fcmp ## type ## _ ## fmt ## _table[n], a, b, cc);     \
760
}
761

    
762
FOP_CONDS(fcmp_fun64, , d)
763
FOP_CONDS(fcmp_fun64, abs, d)
764
FOP_CONDS(fcmp_fun32, , s)
765
FOP_CONDS(fcmp_fun32, abs, s)
766
FOP_CONDS(fcmp_fun64, , ps)
767
FOP_CONDS(fcmp_fun64, abs, ps)
768
#undef FOP_CONDS
769

    
770
/* Tests */
771
#define OP_COND(name, cond)                                   \
772
static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
773
{                                                             \
774
    int l1 = gen_new_label();                                 \
775
    int l2 = gen_new_label();                                 \
776
                                                              \
777
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
778
    tcg_gen_movi_tl(t0, 0);                                   \
779
    tcg_gen_br(l2);                                           \
780
    gen_set_label(l1);                                        \
781
    tcg_gen_movi_tl(t0, 1);                                   \
782
    gen_set_label(l2);                                        \
783
}
784
OP_COND(eq, TCG_COND_EQ);
785
OP_COND(ne, TCG_COND_NE);
786
OP_COND(ge, TCG_COND_GE);
787
OP_COND(geu, TCG_COND_GEU);
788
OP_COND(lt, TCG_COND_LT);
789
OP_COND(ltu, TCG_COND_LTU);
790
#undef OP_COND
791

    
792
#define OP_CONDI(name, cond)                                  \
793
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
794
{                                                             \
795
    int l1 = gen_new_label();                                 \
796
    int l2 = gen_new_label();                                 \
797
                                                              \
798
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
799
    tcg_gen_movi_tl(t, 0);                                    \
800
    tcg_gen_br(l2);                                           \
801
    gen_set_label(l1);                                        \
802
    tcg_gen_movi_tl(t, 1);                                    \
803
    gen_set_label(l2);                                        \
804
}
805
OP_CONDI(lti, TCG_COND_LT);
806
OP_CONDI(ltiu, TCG_COND_LTU);
807
#undef OP_CONDI
808

    
809
#define OP_CONDZ(name, cond)                                  \
810
static inline void glue(gen_op_, name) (TCGv t)               \
811
{                                                             \
812
    int l1 = gen_new_label();                                 \
813
    int l2 = gen_new_label();                                 \
814
                                                              \
815
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
816
    tcg_gen_movi_tl(t, 0);                                    \
817
    tcg_gen_br(l2);                                           \
818
    gen_set_label(l1);                                        \
819
    tcg_gen_movi_tl(t, 1);                                    \
820
    gen_set_label(l2);                                        \
821
}
822
OP_CONDZ(gez, TCG_COND_GE);
823
OP_CONDZ(gtz, TCG_COND_GT);
824
OP_CONDZ(lez, TCG_COND_LE);
825
OP_CONDZ(ltz, TCG_COND_LT);
826
#undef OP_CONDZ
827

    
828
static inline void gen_save_pc(target_ulong pc)
829
{
830
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
831

    
832
    tcg_gen_movi_tl(r_tmp, pc);
833
    tcg_gen_mov_tl(cpu_PC, r_tmp);
834
    tcg_temp_free(r_tmp);
835
}
836

    
837
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
838
{
839
#if defined MIPS_DEBUG_DISAS
840
    if (loglevel & CPU_LOG_TB_IN_ASM) {
841
            fprintf(logfile, "hflags %08x saved %08x\n",
842
                    ctx->hflags, ctx->saved_hflags);
843
    }
844
#endif
845
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
846
        gen_save_pc(ctx->pc);
847
        ctx->saved_pc = ctx->pc;
848
    }
849
    if (ctx->hflags != ctx->saved_hflags) {
850
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
851

    
852
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
853
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
854
        tcg_temp_free(r_tmp);
855
        ctx->saved_hflags = ctx->hflags;
856
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
857
        case MIPS_HFLAG_BR:
858
            break;
859
        case MIPS_HFLAG_BC:
860
        case MIPS_HFLAG_BL:
861
        case MIPS_HFLAG_B:
862
            tcg_gen_movi_tl(btarget, ctx->btarget);
863
            break;
864
        }
865
    }
866
}
867

    
868
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
869
{
870
    ctx->saved_hflags = ctx->hflags;
871
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
872
    case MIPS_HFLAG_BR:
873
        break;
874
    case MIPS_HFLAG_BC:
875
    case MIPS_HFLAG_BL:
876
    case MIPS_HFLAG_B:
877
        ctx->btarget = env->btarget;
878
        break;
879
    }
880
}
881

    
882
static inline void
883
generate_exception_err (DisasContext *ctx, int excp, int err)
884
{
885
    save_cpu_state(ctx, 1);
886
    tcg_gen_helper_0_ii(do_raise_exception_err, excp, err);
887
    tcg_gen_helper_0_0(do_interrupt_restart);
888
    tcg_gen_exit_tb(0);
889
}
890

    
891
static inline void
892
generate_exception (DisasContext *ctx, int excp)
893
{
894
    save_cpu_state(ctx, 1);
895
    tcg_gen_helper_0_i(do_raise_exception, excp);
896
    tcg_gen_helper_0_0(do_interrupt_restart);
897
    tcg_gen_exit_tb(0);
898
}
899

    
900
/* Addresses computation */
901
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
902
{
903
    tcg_gen_add_tl(t0, t0, t1);
904

    
905
#if defined(TARGET_MIPS64)
906
    /* For compatibility with 32-bit code, data reference in user mode
907
       with Status_UX = 0 should be casted to 32-bit and sign extended.
908
       See the MIPS64 PRA manual, section 4.10. */
909
    {
910
        int l1 = gen_new_label();
911
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
912

    
913
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
914
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
915
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
916
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
917
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
918
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
919
        tcg_temp_free(r_tmp);
920
        tcg_gen_ext32s_i64(t0, t0);
921
        gen_set_label(l1);
922
    }
923
#endif
924
}
925

    
926
static inline void check_cp0_enabled(DisasContext *ctx)
927
{
928
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
929
        generate_exception_err(ctx, EXCP_CpU, 1);
930
}
931

    
932
static inline void check_cp1_enabled(DisasContext *ctx)
933
{
934
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
935
        generate_exception_err(ctx, EXCP_CpU, 1);
936
}
937

    
938
/* Verify that the processor is running with COP1X instructions enabled.
939
   This is associated with the nabla symbol in the MIPS32 and MIPS64
940
   opcode tables.  */
941

    
942
static inline void check_cop1x(DisasContext *ctx)
943
{
944
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
945
        generate_exception(ctx, EXCP_RI);
946
}
947

    
948
/* Verify that the processor is running with 64-bit floating-point
949
   operations enabled.  */
950

    
951
static inline void check_cp1_64bitmode(DisasContext *ctx)
952
{
953
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
954
        generate_exception(ctx, EXCP_RI);
955
}
956

    
957
/*
958
 * Verify if floating point register is valid; an operation is not defined
959
 * if bit 0 of any register specification is set and the FR bit in the
960
 * Status register equals zero, since the register numbers specify an
961
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
962
 * in the Status register equals one, both even and odd register numbers
963
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
964
 *
965
 * Multiple 64 bit wide registers can be checked by calling
966
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
967
 */
968
static inline void check_cp1_registers(DisasContext *ctx, int regs)
969
{
970
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
971
        generate_exception(ctx, EXCP_RI);
972
}
973

    
974
/* This code generates a "reserved instruction" exception if the
975
   CPU does not support the instruction set corresponding to flags. */
976
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
977
{
978
    if (unlikely(!(env->insn_flags & flags)))
979
        generate_exception(ctx, EXCP_RI);
980
}
981

    
982
/* This code generates a "reserved instruction" exception if 64-bit
983
   instructions are not enabled. */
984
static inline void check_mips_64(DisasContext *ctx)
985
{
986
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
987
        generate_exception(ctx, EXCP_RI);
988
}
989

    
990
/* load/store instructions. */
991
#define OP_LD(insn,fname)                                        \
992
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
993
{                                                                \
994
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
995
}
996
OP_LD(lb,ld8s);
997
OP_LD(lbu,ld8u);
998
OP_LD(lh,ld16s);
999
OP_LD(lhu,ld16u);
1000
OP_LD(lw,ld32s);
1001
#if defined(TARGET_MIPS64)
1002
OP_LD(lwu,ld32u);
1003
OP_LD(ld,ld64);
1004
#endif
1005
#undef OP_LD
1006

    
1007
#define OP_ST(insn,fname)                                        \
1008
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
1009
{                                                                \
1010
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
1011
}
1012
OP_ST(sb,st8);
1013
OP_ST(sh,st16);
1014
OP_ST(sw,st32);
1015
#if defined(TARGET_MIPS64)
1016
OP_ST(sd,st64);
1017
#endif
1018
#undef OP_ST
1019

    
1020
#define OP_LD_ATOMIC(insn,fname)                                        \
1021
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1022
{                                                                       \
1023
    tcg_gen_mov_tl(t1, t0);                                             \
1024
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
1025
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
1026
}
1027
OP_LD_ATOMIC(ll,ld32s);
1028
#if defined(TARGET_MIPS64)
1029
OP_LD_ATOMIC(lld,ld64);
1030
#endif
1031
#undef OP_LD_ATOMIC
1032

    
1033
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1034
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1035
{                                                                       \
1036
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1037
    int l1 = gen_new_label();                                           \
1038
    int l2 = gen_new_label();                                           \
1039
    int l3 = gen_new_label();                                           \
1040
                                                                        \
1041
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
1042
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1043
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
1044
    generate_exception(ctx, EXCP_AdES);                                 \
1045
    gen_set_label(l1);                                                  \
1046
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1047
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
1048
    tcg_temp_free(r_tmp);                                               \
1049
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
1050
    tcg_gen_movi_tl(t0, 1);                                             \
1051
    tcg_gen_br(l3);                                                     \
1052
    gen_set_label(l2);                                                  \
1053
    tcg_gen_movi_tl(t0, 0);                                             \
1054
    gen_set_label(l3);                                                  \
1055
}
1056
OP_ST_ATOMIC(sc,st32,0x3);
1057
#if defined(TARGET_MIPS64)
1058
OP_ST_ATOMIC(scd,st64,0x7);
1059
#endif
1060
#undef OP_ST_ATOMIC
1061

    
1062
/* Load and store */
1063
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1064
                      int base, int16_t offset)
1065
{
1066
    const char *opn = "ldst";
1067
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1068
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1069

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

    
1226
/* Load and store */
1227
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1228
                          int base, int16_t offset)
1229
{
1230
    const char *opn = "flt_ldst";
1231
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1232

    
1233
    if (base == 0) {
1234
        tcg_gen_movi_tl(t0, offset);
1235
    } else if (offset == 0) {
1236
        gen_load_gpr(t0, base);
1237
    } else {
1238
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1239

    
1240
        gen_load_gpr(t0, base);
1241
        tcg_gen_movi_tl(t1, offset);
1242
        gen_op_addr_add(t0, t1);
1243
        tcg_temp_free(t1);
1244
    }
1245
    /* Don't do NOP if destination is zero: we must perform the actual
1246
       memory access. */
1247
    switch (opc) {
1248
    case OPC_LWC1:
1249
        {
1250
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1251

    
1252
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
1253
            gen_store_fpr32(fp0, ft);
1254
            tcg_temp_free(fp0);
1255
        }
1256
        opn = "lwc1";
1257
        break;
1258
    case OPC_SWC1:
1259
        {
1260
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1261

    
1262
            gen_load_fpr32(fp0, ft);
1263
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
1264
            tcg_temp_free(fp0);
1265
        }
1266
        opn = "swc1";
1267
        break;
1268
    case OPC_LDC1:
1269
        {
1270
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1271

    
1272
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1273
            gen_store_fpr64(ctx, fp0, ft);
1274
            tcg_temp_free(fp0);
1275
        }
1276
        opn = "ldc1";
1277
        break;
1278
    case OPC_SDC1:
1279
        {
1280
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1281

    
1282
            gen_load_fpr64(ctx, fp0, ft);
1283
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1284
            tcg_temp_free(fp0);
1285
        }
1286
        opn = "sdc1";
1287
        break;
1288
    default:
1289
        MIPS_INVAL(opn);
1290
        generate_exception(ctx, EXCP_RI);
1291
        goto out;
1292
    }
1293
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1294
 out:
1295
    tcg_temp_free(t0);
1296
}
1297

    
1298
/* Arithmetic with immediate operand */
1299
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1300
                           int rt, int rs, int16_t imm)
1301
{
1302
    target_ulong uimm;
1303
    const char *opn = "imm arith";
1304
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1305

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

    
1354
            save_cpu_state(ctx, 1);
1355
            tcg_gen_ext32s_tl(r_tmp1, t0);
1356
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1357

    
1358
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1359
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1360
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1361
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1362
            tcg_temp_free(r_tmp2);
1363
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1364
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1365
            tcg_temp_free(r_tmp1);
1366
            /* operands of same sign, result different sign */
1367
            generate_exception(ctx, EXCP_OVERFLOW);
1368
            gen_set_label(l1);
1369

    
1370
            tcg_gen_ext32s_tl(t0, t0);
1371
        }
1372
        opn = "addi";
1373
        break;
1374
    case OPC_ADDIU:
1375
        tcg_gen_ext32s_tl(t0, t0);
1376
        tcg_gen_addi_tl(t0, t0, uimm);
1377
        tcg_gen_ext32s_tl(t0, t0);
1378
        opn = "addiu";
1379
        break;
1380
#if defined(TARGET_MIPS64)
1381
    case OPC_DADDI:
1382
        {
1383
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1384
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1385
            int l1 = gen_new_label();
1386

    
1387
            save_cpu_state(ctx, 1);
1388
            tcg_gen_mov_tl(r_tmp1, t0);
1389
            tcg_gen_addi_tl(t0, t0, uimm);
1390

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

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

    
1505
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1506
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1507
                    tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1508
                    tcg_gen_shri_tl(t0, t0, uimm);
1509
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1510
                    tcg_temp_free(r_tmp1);
1511
                }
1512
                opn = "drotr";
1513
            } else {
1514
                tcg_gen_shri_tl(t0, t0, uimm);
1515
                opn = "dsrl";
1516
            }
1517
            break;
1518
        default:
1519
            MIPS_INVAL("invalid dsrl flag");
1520
            generate_exception(ctx, EXCP_RI);
1521
            break;
1522
        }
1523
        break;
1524
    case OPC_DSLL32:
1525
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1526
        opn = "dsll32";
1527
        break;
1528
    case OPC_DSRA32:
1529
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1530
        opn = "dsra32";
1531
        break;
1532
    case OPC_DSRL32:
1533
        switch ((ctx->opcode >> 21) & 0x1f) {
1534
        case 0:
1535
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1536
            opn = "dsrl32";
1537
            break;
1538
        case 1:
1539
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1540
            if (env->insn_flags & ISA_MIPS32R2) {
1541
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1542
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1543

    
1544
                tcg_gen_movi_tl(r_tmp1, 0x40);
1545
                tcg_gen_movi_tl(r_tmp2, 32);
1546
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1547
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1548
                tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1549
                tcg_gen_shr_tl(t0, t0, r_tmp2);
1550
                tcg_gen_or_tl(t0, t0, r_tmp1);
1551
                tcg_temp_free(r_tmp1);
1552
                tcg_temp_free(r_tmp2);
1553
                opn = "drotr32";
1554
            } else {
1555
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1556
                opn = "dsrl32";
1557
            }
1558
            break;
1559
        default:
1560
            MIPS_INVAL("invalid dsrl32 flag");
1561
            generate_exception(ctx, EXCP_RI);
1562
            break;
1563
        }
1564
        break;
1565
#endif
1566
    default:
1567
        MIPS_INVAL(opn);
1568
        generate_exception(ctx, EXCP_RI);
1569
        goto out;
1570
    }
1571
    gen_store_gpr(t0, rt);
1572
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1573
 out:
1574
    tcg_temp_free(t0);
1575
}
1576

    
1577
/* Arithmetic */
1578
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1579
                       int rd, int rs, int rt)
1580
{
1581
    const char *opn = "arith";
1582
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1583
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1584

    
1585
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1586
       && opc != OPC_DADD && opc != OPC_DSUB) {
1587
        /* If no destination, treat it as a NOP.
1588
           For add & sub, we must generate the overflow exception when needed. */
1589
        MIPS_DEBUG("NOP");
1590
        goto out;
1591
    }
1592
    gen_load_gpr(t0, rs);
1593
    /* Specialcase the conventional move operation. */
1594
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1595
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1596
        gen_store_gpr(t0, rd);
1597
        goto out;
1598
    }
1599
    gen_load_gpr(t1, rt);
1600
    switch (opc) {
1601
    case OPC_ADD:
1602
        {
1603
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1604
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1605
            int l1 = gen_new_label();
1606

    
1607
            save_cpu_state(ctx, 1);
1608
            tcg_gen_ext32s_tl(r_tmp1, t0);
1609
            tcg_gen_ext32s_tl(r_tmp2, t1);
1610
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1611

    
1612
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1613
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1614
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1615
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1616
            tcg_temp_free(r_tmp2);
1617
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1618
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1619
            tcg_temp_free(r_tmp1);
1620
            /* operands of same sign, result different sign */
1621
            generate_exception(ctx, EXCP_OVERFLOW);
1622
            gen_set_label(l1);
1623

    
1624
            tcg_gen_ext32s_tl(t0, t0);
1625
        }
1626
        opn = "add";
1627
        break;
1628
    case OPC_ADDU:
1629
        tcg_gen_ext32s_tl(t0, t0);
1630
        tcg_gen_ext32s_tl(t1, t1);
1631
        tcg_gen_add_tl(t0, t0, t1);
1632
        tcg_gen_ext32s_tl(t0, t0);
1633
        opn = "addu";
1634
        break;
1635
    case OPC_SUB:
1636
        {
1637
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1638
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1639
            int l1 = gen_new_label();
1640

    
1641
            save_cpu_state(ctx, 1);
1642
            tcg_gen_ext32s_tl(r_tmp1, t0);
1643
            tcg_gen_ext32s_tl(r_tmp2, t1);
1644
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1645

    
1646
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1647
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1648
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1649
            tcg_temp_free(r_tmp2);
1650
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1651
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1652
            tcg_temp_free(r_tmp1);
1653
            /* operands of different sign, first operand and result different sign */
1654
            generate_exception(ctx, EXCP_OVERFLOW);
1655
            gen_set_label(l1);
1656

    
1657
            tcg_gen_ext32s_tl(t0, t0);
1658
        }
1659
        opn = "sub";
1660
        break;
1661
    case OPC_SUBU:
1662
        tcg_gen_ext32s_tl(t0, t0);
1663
        tcg_gen_ext32s_tl(t1, t1);
1664
        tcg_gen_sub_tl(t0, t0, t1);
1665
        tcg_gen_ext32s_tl(t0, t0);
1666
        opn = "subu";
1667
        break;
1668
#if defined(TARGET_MIPS64)
1669
    case OPC_DADD:
1670
        {
1671
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1672
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1673
            int l1 = gen_new_label();
1674

    
1675
            save_cpu_state(ctx, 1);
1676
            tcg_gen_mov_tl(r_tmp1, t0);
1677
            tcg_gen_add_tl(t0, t0, t1);
1678

    
1679
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1680
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1681
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1682
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1683
            tcg_temp_free(r_tmp2);
1684
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1685
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1686
            tcg_temp_free(r_tmp1);
1687
            /* operands of same sign, result different sign */
1688
            generate_exception(ctx, EXCP_OVERFLOW);
1689
            gen_set_label(l1);
1690
        }
1691
        opn = "dadd";
1692
        break;
1693
    case OPC_DADDU:
1694
        tcg_gen_add_tl(t0, t0, t1);
1695
        opn = "daddu";
1696
        break;
1697
    case OPC_DSUB:
1698
        {
1699
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1700
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1701
            int l1 = gen_new_label();
1702

    
1703
            save_cpu_state(ctx, 1);
1704
            tcg_gen_mov_tl(r_tmp1, t0);
1705
            tcg_gen_sub_tl(t0, t0, t1);
1706

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

    
1761
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1762
            gen_store_gpr(t0, rd);
1763
            gen_set_label(l1);
1764
        }
1765
        opn = "movn";
1766
        goto print;
1767
    case OPC_MOVZ:
1768
        {
1769
            int l1 = gen_new_label();
1770

    
1771
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1772
            gen_store_gpr(t0, rd);
1773
            gen_set_label(l1);
1774
        }
1775
        opn = "movz";
1776
        goto print;
1777
    case OPC_SLLV:
1778
        tcg_gen_ext32u_tl(t0, t0);
1779
        tcg_gen_ext32u_tl(t1, t1);
1780
        tcg_gen_andi_tl(t0, t0, 0x1f);
1781
        tcg_gen_shl_tl(t0, t1, t0);
1782
        tcg_gen_ext32s_tl(t0, t0);
1783
        opn = "sllv";
1784
        break;
1785
    case OPC_SRAV:
1786
        tcg_gen_ext32s_tl(t1, t1);
1787
        tcg_gen_andi_tl(t0, t0, 0x1f);
1788
        tcg_gen_sar_tl(t0, t1, t0);
1789
        tcg_gen_ext32s_tl(t0, t0);
1790
        opn = "srav";
1791
        break;
1792
    case OPC_SRLV:
1793
        switch ((ctx->opcode >> 6) & 0x1f) {
1794
        case 0:
1795
            tcg_gen_ext32u_tl(t1, t1);
1796
            tcg_gen_andi_tl(t0, t0, 0x1f);
1797
            tcg_gen_shr_tl(t0, t1, t0);
1798
            tcg_gen_ext32s_tl(t0, t0);
1799
            opn = "srlv";
1800
            break;
1801
        case 1:
1802
            /* rotrv is decoded as srlv on non-R2 CPUs */
1803
            if (env->insn_flags & ISA_MIPS32R2) {
1804
                int l1 = gen_new_label();
1805
                int l2 = gen_new_label();
1806

    
1807
                tcg_gen_andi_tl(t0, t0, 0x1f);
1808
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1809
                {
1810
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1811
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1812
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1813

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

    
1869
                tcg_gen_andi_tl(t0, t0, 0x3f);
1870
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1871
                {
1872
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1873

    
1874
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1875
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, t0);
1876
                    tcg_gen_shl_tl(r_tmp1, t1, r_tmp1);
1877
                    tcg_gen_shr_tl(t0, t1, t0);
1878
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1879
                    tcg_temp_free(r_tmp1);
1880
                    tcg_gen_br(l2);
1881
                }
1882
                gen_set_label(l1);
1883
                tcg_gen_mov_tl(t0, t1);
1884
                gen_set_label(l2);
1885
                opn = "drotrv";
1886
            } else {
1887
                tcg_gen_andi_tl(t0, t0, 0x3f);
1888
                tcg_gen_shr_tl(t0, t1, t0);
1889
                opn = "dsrlv";
1890
            }
1891
            break;
1892
        default:
1893
            MIPS_INVAL("invalid dsrlv flag");
1894
            generate_exception(ctx, EXCP_RI);
1895
            break;
1896
        }
1897
        break;
1898
#endif
1899
    default:
1900
        MIPS_INVAL(opn);
1901
        generate_exception(ctx, EXCP_RI);
1902
        goto out;
1903
    }
1904
    gen_store_gpr(t0, rd);
1905
 print:
1906
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1907
 out:
1908
    tcg_temp_free(t0);
1909
    tcg_temp_free(t1);
1910
}
1911

    
1912
/* Arithmetic on HI/LO registers */
1913
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1914
{
1915
    const char *opn = "hilo";
1916
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1917

    
1918
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1919
        /* Treat as NOP. */
1920
        MIPS_DEBUG("NOP");
1921
        goto out;
1922
    }
1923
    switch (opc) {
1924
    case OPC_MFHI:
1925
        gen_load_HI(t0, 0);
1926
        gen_store_gpr(t0, reg);
1927
        opn = "mfhi";
1928
        break;
1929
    case OPC_MFLO:
1930
        gen_load_LO(t0, 0);
1931
        gen_store_gpr(t0, reg);
1932
        opn = "mflo";
1933
        break;
1934
    case OPC_MTHI:
1935
        gen_load_gpr(t0, reg);
1936
        gen_store_HI(t0, 0);
1937
        opn = "mthi";
1938
        break;
1939
    case OPC_MTLO:
1940
        gen_load_gpr(t0, reg);
1941
        gen_store_LO(t0, 0);
1942
        opn = "mtlo";
1943
        break;
1944
    default:
1945
        MIPS_INVAL(opn);
1946
        generate_exception(ctx, EXCP_RI);
1947
        goto out;
1948
    }
1949
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1950
 out:
1951
    tcg_temp_free(t0);
1952
}
1953

    
1954
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1955
                        int rs, int rt)
1956
{
1957
    const char *opn = "mul/div";
1958
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1959
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1960

    
1961
    gen_load_gpr(t0, rs);
1962
    gen_load_gpr(t1, rt);
1963
    switch (opc) {
1964
    case OPC_DIV:
1965
        {
1966
            int l1 = gen_new_label();
1967

    
1968
            tcg_gen_ext32s_tl(t0, t0);
1969
            tcg_gen_ext32s_tl(t1, t1);
1970
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1971
            {
1972
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1973
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1974
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1975

    
1976
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1977
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1978
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1979
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1980
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1981
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1982
                tcg_temp_free(r_tmp1);
1983
                tcg_temp_free(r_tmp2);
1984
                tcg_temp_free(r_tmp3);
1985
                tcg_gen_ext32s_tl(t0, t0);
1986
                tcg_gen_ext32s_tl(t1, t1);
1987
                gen_store_LO(t0, 0);
1988
                gen_store_HI(t1, 0);
1989
            }
1990
            gen_set_label(l1);
1991
        }
1992
        opn = "div";
1993
        break;
1994
    case OPC_DIVU:
1995
        {
1996
            int l1 = gen_new_label();
1997

    
1998
            tcg_gen_ext32s_tl(t1, t1);
1999
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2000
            {
2001
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
2002
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
2003
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
2004

    
2005
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
2006
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
2007
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
2008
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
2009
                tcg_gen_ext_i32_tl(t0, r_tmp3);
2010
                tcg_gen_ext_i32_tl(t1, r_tmp1);
2011
                tcg_temp_free(r_tmp1);
2012
                tcg_temp_free(r_tmp2);
2013
                tcg_temp_free(r_tmp3);
2014
                gen_store_LO(t0, 0);
2015
                gen_store_HI(t1, 0);
2016
            }
2017
            gen_set_label(l1);
2018
        }
2019
        opn = "divu";
2020
        break;
2021
    case OPC_MULT:
2022
        {
2023
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2024
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2025

    
2026
            tcg_gen_ext32s_tl(t0, t0);
2027
            tcg_gen_ext32s_tl(t1, t1);
2028
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2029
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2030
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2031
            tcg_temp_free(r_tmp2);
2032
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2033
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2034
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2035
            tcg_temp_free(r_tmp1);
2036
            tcg_gen_ext32s_tl(t0, t0);
2037
            tcg_gen_ext32s_tl(t1, t1);
2038
            gen_store_LO(t0, 0);
2039
            gen_store_HI(t1, 0);
2040
        }
2041
        opn = "mult";
2042
        break;
2043
    case OPC_MULTU:
2044
        {
2045
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2046
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2047

    
2048
            tcg_gen_ext32u_tl(t0, t0);
2049
            tcg_gen_ext32u_tl(t1, t1);
2050
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2051
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2052
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2053
            tcg_temp_free(r_tmp2);
2054
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2055
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2056
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2057
            tcg_temp_free(r_tmp1);
2058
            tcg_gen_ext32s_tl(t0, t0);
2059
            tcg_gen_ext32s_tl(t1, t1);
2060
            gen_store_LO(t0, 0);
2061
            gen_store_HI(t1, 0);
2062
        }
2063
        opn = "multu";
2064
        break;
2065
#if defined(TARGET_MIPS64)
2066
    case OPC_DDIV:
2067
        {
2068
            int l1 = gen_new_label();
2069

    
2070
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2071
            {
2072
                int l2 = gen_new_label();
2073

    
2074
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2075
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2076
                {
2077
                    tcg_gen_movi_tl(t1, 0);
2078
                    gen_store_LO(t0, 0);
2079
                    gen_store_HI(t1, 0);
2080
                    tcg_gen_br(l1);
2081
                }
2082
                gen_set_label(l2);
2083
                {
2084
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2085
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2086

    
2087
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2088
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2089
                    gen_store_LO(r_tmp1, 0);
2090
                    gen_store_HI(r_tmp2, 0);
2091
                    tcg_temp_free(r_tmp1);
2092
                    tcg_temp_free(r_tmp2);
2093
                }
2094
            }
2095
            gen_set_label(l1);
2096
        }
2097
        opn = "ddiv";
2098
        break;
2099
    case OPC_DDIVU:
2100
        {
2101
            int l1 = gen_new_label();
2102

    
2103
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2104
            {
2105
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2106
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2107

    
2108
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2109
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2110
                tcg_temp_free(r_tmp1);
2111
                tcg_temp_free(r_tmp2);
2112
                gen_store_LO(r_tmp1, 0);
2113
                gen_store_HI(r_tmp2, 0);
2114
            }
2115
            gen_set_label(l1);
2116
        }
2117
        opn = "ddivu";
2118
        break;
2119
    case OPC_DMULT:
2120
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2121
        opn = "dmult";
2122
        break;
2123
    case OPC_DMULTU:
2124
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2125
        opn = "dmultu";
2126
        break;
2127
#endif
2128
    case OPC_MADD:
2129
        {
2130
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2131
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2132
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2133

    
2134
            tcg_gen_ext32s_tl(t0, t0);
2135
            tcg_gen_ext32s_tl(t1, t1);
2136
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2137
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2138
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2139
            gen_load_LO(t0, 0);
2140
            gen_load_HI(t1, 0);
2141
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2142
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2143
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2144
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2145
            tcg_temp_free(r_tmp3);
2146
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2147
            tcg_temp_free(r_tmp2);
2148
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2149
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2150
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2151
            tcg_temp_free(r_tmp1);
2152
            tcg_gen_ext32s_tl(t0, t0);
2153
            tcg_gen_ext32s_tl(t1, t1);
2154
            gen_store_LO(t0, 0);
2155
            gen_store_HI(t1, 0);
2156
        }
2157
        opn = "madd";
2158
        break;
2159
    case OPC_MADDU:
2160
       {
2161
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2162
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2163
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2164

    
2165
            tcg_gen_ext32u_tl(t0, t0);
2166
            tcg_gen_ext32u_tl(t1, t1);
2167
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2168
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2169
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2170
            gen_load_LO(t0, 0);
2171
            gen_load_HI(t1, 0);
2172
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2173
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2174
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2175
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2176
            tcg_temp_free(r_tmp3);
2177
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2178
            tcg_temp_free(r_tmp2);
2179
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2180
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2181
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2182
            tcg_temp_free(r_tmp1);
2183
            tcg_gen_ext32s_tl(t0, t0);
2184
            tcg_gen_ext32s_tl(t1, t1);
2185
            gen_store_LO(t0, 0);
2186
            gen_store_HI(t1, 0);
2187
        }
2188
        opn = "maddu";
2189
        break;
2190
    case OPC_MSUB:
2191
        {
2192
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2193
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2194
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2195

    
2196
            tcg_gen_ext32s_tl(t0, t0);
2197
            tcg_gen_ext32s_tl(t1, t1);
2198
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2199
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2200
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2201
            gen_load_LO(t0, 0);
2202
            gen_load_HI(t1, 0);
2203
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2204
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2205
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2206
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2207
            tcg_temp_free(r_tmp3);
2208
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2209
            tcg_temp_free(r_tmp2);
2210
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2211
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2212
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2213
            tcg_temp_free(r_tmp1);
2214
            tcg_gen_ext32s_tl(t0, t0);
2215
            tcg_gen_ext32s_tl(t1, t1);
2216
            gen_store_LO(t0, 0);
2217
            gen_store_HI(t1, 0);
2218
        }
2219
        opn = "msub";
2220
        break;
2221
    case OPC_MSUBU:
2222
        {
2223
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2224
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2225
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2226

    
2227
            tcg_gen_ext32u_tl(t0, t0);
2228
            tcg_gen_ext32u_tl(t1, t1);
2229
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2230
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2231
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2232
            gen_load_LO(t0, 0);
2233
            gen_load_HI(t1, 0);
2234
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2235
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2236
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2237
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2238
            tcg_temp_free(r_tmp3);
2239
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2240
            tcg_temp_free(r_tmp2);
2241
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2242
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2243
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2244
            tcg_temp_free(r_tmp1);
2245
            tcg_gen_ext32s_tl(t0, t0);
2246
            tcg_gen_ext32s_tl(t1, t1);
2247
            gen_store_LO(t0, 0);
2248
            gen_store_HI(t1, 0);
2249
        }
2250
        opn = "msubu";
2251
        break;
2252
    default:
2253
        MIPS_INVAL(opn);
2254
        generate_exception(ctx, EXCP_RI);
2255
        goto out;
2256
    }
2257
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2258
 out:
2259
    tcg_temp_free(t0);
2260
    tcg_temp_free(t1);
2261
}
2262

    
2263
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2264
                            int rd, int rs, int rt)
2265
{
2266
    const char *opn = "mul vr54xx";
2267
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2268
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2269

    
2270
    gen_load_gpr(t0, rs);
2271
    gen_load_gpr(t1, rt);
2272

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

    
2338
 out:
2339
    tcg_temp_free(t0);
2340
    tcg_temp_free(t1);
2341
}
2342

    
2343
static void gen_cl (DisasContext *ctx, uint32_t opc,
2344
                    int rd, int rs)
2345
{
2346
    const char *opn = "CLx";
2347
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2348

    
2349
    if (rd == 0) {
2350
        /* Treat as NOP. */
2351
        MIPS_DEBUG("NOP");
2352
        goto out;
2353
    }
2354
    gen_load_gpr(t0, rs);
2355
    switch (opc) {
2356
    case OPC_CLO:
2357
        tcg_gen_helper_1_1(do_clo, t0, t0);
2358
        opn = "clo";
2359
        break;
2360
    case OPC_CLZ:
2361
        tcg_gen_helper_1_1(do_clz, t0, t0);
2362
        opn = "clz";
2363
        break;
2364
#if defined(TARGET_MIPS64)
2365
    case OPC_DCLO:
2366
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2367
        opn = "dclo";
2368
        break;
2369
    case OPC_DCLZ:
2370
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2371
        opn = "dclz";
2372
        break;
2373
#endif
2374
    default:
2375
        MIPS_INVAL(opn);
2376
        generate_exception(ctx, EXCP_RI);
2377
        goto out;
2378
    }
2379
    gen_store_gpr(t0, rd);
2380
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2381

    
2382
 out:
2383
    tcg_temp_free(t0);
2384
}
2385

    
2386
/* Traps */
2387
static void gen_trap (DisasContext *ctx, uint32_t opc,
2388
                      int rs, int rt, int16_t imm)
2389
{
2390
    int cond;
2391
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2392
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2393

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

    
2484
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2485
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2486
        gen_set_label(l1);
2487
    }
2488
    ctx->bstate = BS_STOP;
2489
 out:
2490
    tcg_temp_free(t0);
2491
    tcg_temp_free(t1);
2492
}
2493

    
2494
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2495
{
2496
    TranslationBlock *tb;
2497
    tb = ctx->tb;
2498
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2499
        tcg_gen_goto_tb(n);
2500
        gen_save_pc(dest);
2501
        tcg_gen_exit_tb((long)tb + n);
2502
    } else {
2503
        gen_save_pc(dest);
2504
        tcg_gen_exit_tb(0);
2505
    }
2506
}
2507

    
2508
/* Branches (before delay slot) */
2509
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2510
                                int rs, int rt, int32_t offset)
2511
{
2512
    target_ulong btgt = -1;
2513
    int blink = 0;
2514
    int bcond_compute = 0;
2515
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2516
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2517

    
2518
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2519
#ifdef MIPS_DEBUG_DISAS
2520
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2521
            fprintf(logfile,
2522
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2523
                    ctx->pc);
2524
        }
2525
#endif
2526
        generate_exception(ctx, EXCP_RI);
2527
        goto out;
2528
    }
2529

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

    
2742
    ctx->btarget = btgt;
2743
    if (blink > 0) {
2744
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2745
        gen_store_gpr(t0, blink);
2746
    }
2747

    
2748
 out:
2749
    tcg_temp_free(t0);
2750
    tcg_temp_free(t1);
2751
}
2752

    
2753
/* special3 bitfield operations */
2754
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2755
                        int rs, int lsb, int msb)
2756
{
2757
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2758
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2759

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

    
2823
#ifndef CONFIG_USER_ONLY
2824
/* CP0 (MMU and control) */
2825
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2826
{
2827
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2828

    
2829
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2830
    tcg_gen_ext_i32_tl(t, r_tmp);
2831
    tcg_temp_free(r_tmp);
2832
}
2833

    
2834
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2835
{
2836
    tcg_gen_ld_tl(t, cpu_env, off);
2837
    tcg_gen_ext32s_tl(t, t);
2838
}
2839

    
2840
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2841
{
2842
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2843

    
2844
    tcg_gen_trunc_tl_i32(r_tmp, t);
2845
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2846
    tcg_temp_free(r_tmp);
2847
}
2848

    
2849
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2850
{
2851
    tcg_gen_ext32s_tl(t, t);
2852
    tcg_gen_st_tl(t, cpu_env, off);
2853
}
2854

    
2855
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2856
{
2857
    const char *rn = "invalid";
2858

    
2859
    if (sel != 0)
2860
        check_insn(env, ctx, ISA_MIPS32);
2861

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

    
3431
die:
3432
#if defined MIPS_DEBUG_DISAS
3433
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3434
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3435
                rn, reg, sel);
3436
    }
3437
#endif
3438
    generate_exception(ctx, EXCP_RI);
3439
}
3440

    
3441
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3442
{
3443
    const char *rn = "invalid";
3444

    
3445
    if (sel != 0)
3446
        check_insn(env, ctx, ISA_MIPS32);
3447

    
3448
    if (use_icount)
3449
        gen_io_start();
3450

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

    
4040
die:
4041
#if defined MIPS_DEBUG_DISAS
4042
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4043
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4044
                rn, reg, sel);
4045
    }
4046
#endif
4047
    generate_exception(ctx, EXCP_RI);
4048
}
4049

    
4050
#if defined(TARGET_MIPS64)
4051
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4052
{
4053
    const char *rn = "invalid";
4054

    
4055
    if (sel != 0)
4056
        check_insn(env, ctx, ISA_MIPS64);
4057

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

    
4615
die:
4616
#if defined MIPS_DEBUG_DISAS
4617
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4618
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4619
                rn, reg, sel);
4620
    }
4621
#endif
4622
    generate_exception(ctx, EXCP_RI);
4623
}
4624

    
4625
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4626
{
4627
    const char *rn = "invalid";
4628

    
4629
    if (sel != 0)
4630
        check_insn(env, ctx, ISA_MIPS64);
4631

    
4632
    if (use_icount)
4633
        gen_io_start();
4634

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

    
5211
die:
5212
#if defined MIPS_DEBUG_DISAS
5213
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5214
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5215
                rn, reg, sel);
5216
    }
5217
#endif
5218
    generate_exception(ctx, EXCP_RI);
5219
}
5220
#endif /* TARGET_MIPS64 */
5221

    
5222
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5223
                     int u, int sel, int h)
5224
{
5225
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5226
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5227

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

    
5353
            gen_load_fpr32(fp0, rt);
5354
            tcg_gen_ext_i32_tl(t0, fp0);
5355
            tcg_temp_free(fp0);
5356
        } else {
5357
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5358

    
5359
            gen_load_fpr32h(fp0, rt);
5360
            tcg_gen_ext_i32_tl(t0, fp0);
5361
            tcg_temp_free(fp0);
5362
        }
5363
        break;
5364
    case 3:
5365
        /* XXX: For now we support only a single FPU context. */
5366
        tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt);
5367
        break;
5368
    /* COP2: Not implemented. */
5369
    case 4:
5370
    case 5:
5371
        /* fall through */
5372
    default:
5373
        goto die;
5374
    }
5375
#if defined MIPS_DEBUG_DISAS
5376
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5377
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5378
                rt, u, sel, h);
5379
    }
5380
#endif
5381
    gen_store_gpr(t0, rd);
5382
    tcg_temp_free(t0);
5383
    return;
5384

    
5385
die:
5386
    tcg_temp_free(t0);
5387
#if defined MIPS_DEBUG_DISAS
5388
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5389
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5390
                rt, u, sel, h);
5391
    }
5392
#endif
5393
    generate_exception(ctx, EXCP_RI);
5394
}
5395

    
5396
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5397
                     int u, int sel, int h)
5398
{
5399
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5400
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5401

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

    
5528
            tcg_gen_trunc_tl_i32(fp0, t0);
5529
            gen_store_fpr32(fp0, rd);
5530
            tcg_temp_free(fp0);
5531
        } else {
5532
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5533

    
5534
            tcg_gen_trunc_tl_i32(fp0, t0);
5535
            gen_store_fpr32h(fp0, rd);
5536
            tcg_temp_free(fp0);
5537
        }
5538
        break;
5539
    case 3:
5540
        /* XXX: For now we support only a single FPU context. */
5541
        tcg_gen_helper_0_1i(do_ctc1, t0, rd);
5542
        break;
5543
    /* COP2: Not implemented. */
5544
    case 4:
5545
    case 5:
5546
        /* fall through */
5547
    default:
5548
        goto die;
5549
    }
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
    tcg_temp_free(t0);
5557
    return;
5558

    
5559
die:
5560
    tcg_temp_free(t0);
5561
#if defined MIPS_DEBUG_DISAS
5562
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5563
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5564
                rd, u, sel, h);
5565
    }
5566
#endif
5567
    generate_exception(ctx, EXCP_RI);
5568
}
5569

    
5570
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5571
{
5572
    const char *opn = "ldst";
5573

    
5574
    switch (opc) {
5575
    case OPC_MFC0:
5576
        if (rt == 0) {
5577
            /* Treat as NOP. */
5578
            return;
5579
        }
5580
        {
5581
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5582

    
5583
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5584
            gen_store_gpr(t0, rt);
5585
            tcg_temp_free(t0);
5586
        }
5587
        opn = "mfc0";
5588
        break;
5589
    case OPC_MTC0:
5590
        {
5591
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5592

    
5593
            gen_load_gpr(t0, rt);
5594
            save_cpu_state(ctx, 1);
5595
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5596
            tcg_temp_free(t0);
5597
        }
5598
        opn = "mtc0";
5599
        break;
5600
#if defined(TARGET_MIPS64)
5601
    case OPC_DMFC0:
5602
        check_insn(env, ctx, ISA_MIPS3);
5603
        if (rt == 0) {
5604
            /* Treat as NOP. */
5605
            return;
5606
        }
5607
        {
5608
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5609

    
5610
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5611
            gen_store_gpr(t0, rt);
5612
            tcg_temp_free(t0);
5613
        }
5614
        opn = "dmfc0";
5615
        break;
5616
    case OPC_DMTC0:
5617
        check_insn(env, ctx, ISA_MIPS3);
5618
        {
5619
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5620

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

    
5708
/* CP1 Branches (before delay slot) */
5709
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5710
                                 int32_t cc, int32_t offset)
5711
{
5712
    target_ulong btarget;
5713
    const char *opn = "cp1 cond branch";
5714
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5715
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5716

    
5717
    if (cc != 0)
5718
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5719

    
5720
    btarget = ctx->pc + 4 + offset;
5721

    
5722
    switch (op) {
5723
    case OPC_BC1F:
5724
        {
5725
            int l1 = gen_new_label();
5726
            int l2 = gen_new_label();
5727
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5728

    
5729
            get_fp_cond(r_tmp1);
5730
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5731
            tcg_temp_free(r_tmp1);
5732
            tcg_gen_not_tl(t0, t0);
5733
            tcg_gen_movi_tl(t1, 0x1 << cc);
5734
            tcg_gen_and_tl(t0, t0, t1);
5735
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5736
            tcg_gen_movi_tl(t0, 0);
5737
            tcg_gen_br(l2);
5738
            gen_set_label(l1);
5739
            tcg_gen_movi_tl(t0, 1);
5740
            gen_set_label(l2);
5741
        }
5742
        opn = "bc1f";
5743
        goto not_likely;
5744
    case OPC_BC1FL:
5745
        {
5746
            int l1 = gen_new_label();
5747
            int l2 = gen_new_label();
5748
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5749

    
5750
            get_fp_cond(r_tmp1);
5751
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5752
            tcg_temp_free(r_tmp1);
5753
            tcg_gen_not_tl(t0, t0);
5754
            tcg_gen_movi_tl(t1, 0x1 << cc);
5755
            tcg_gen_and_tl(t0, t0, t1);
5756
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5757
            tcg_gen_movi_tl(t0, 0);
5758
            tcg_gen_br(l2);
5759
            gen_set_label(l1);
5760
            tcg_gen_movi_tl(t0, 1);
5761
            gen_set_label(l2);
5762
        }
5763
        opn = "bc1fl";
5764
        goto likely;
5765
    case OPC_BC1T:
5766
        {
5767
            int l1 = gen_new_label();
5768
            int l2 = gen_new_label();
5769
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5770

    
5771
            get_fp_cond(r_tmp1);
5772
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5773
            tcg_temp_free(r_tmp1);
5774
            tcg_gen_movi_tl(t1, 0x1 << cc);
5775
            tcg_gen_and_tl(t0, t0, t1);
5776
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5777
            tcg_gen_movi_tl(t0, 0);
5778
            tcg_gen_br(l2);
5779
            gen_set_label(l1);
5780
            tcg_gen_movi_tl(t0, 1);
5781
            gen_set_label(l2);
5782
        }
5783
        opn = "bc1t";
5784
        goto not_likely;
5785
    case OPC_BC1TL:
5786
        {
5787
            int l1 = gen_new_label();
5788
            int l2 = gen_new_label();
5789
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5790

    
5791
            get_fp_cond(r_tmp1);
5792
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5793
            tcg_temp_free(r_tmp1);
5794
            tcg_gen_movi_tl(t1, 0x1 << cc);
5795
            tcg_gen_and_tl(t0, t0, t1);
5796
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5797
            tcg_gen_movi_tl(t0, 0);
5798
            tcg_gen_br(l2);
5799
            gen_set_label(l1);
5800
            tcg_gen_movi_tl(t0, 1);
5801
            gen_set_label(l2);
5802
        }
5803
        opn = "bc1tl";
5804
    likely:
5805
        ctx->hflags |= MIPS_HFLAG_BL;
5806
        tcg_gen_trunc_tl_i32(bcond, t0);
5807
        break;
5808
    case OPC_BC1FANY2:
5809
        {
5810
            int l1 = gen_new_label();
5811
            int l2 = gen_new_label();
5812
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5813

    
5814
            get_fp_cond(r_tmp1);
5815
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5816
            tcg_temp_free(r_tmp1);
5817
            tcg_gen_not_tl(t0, t0);
5818
            tcg_gen_movi_tl(t1, 0x3 << cc);
5819
            tcg_gen_and_tl(t0, t0, t1);
5820
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5821
            tcg_gen_movi_tl(t0, 0);
5822
            tcg_gen_br(l2);
5823
            gen_set_label(l1);
5824
            tcg_gen_movi_tl(t0, 1);
5825
            gen_set_label(l2);
5826
        }
5827
        opn = "bc1any2f";
5828
        goto not_likely;
5829
    case OPC_BC1TANY2:
5830
        {
5831
            int l1 = gen_new_label();
5832
            int l2 = gen_new_label();
5833
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5834

    
5835
            get_fp_cond(r_tmp1);
5836
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5837
            tcg_temp_free(r_tmp1);
5838
            tcg_gen_movi_tl(t1, 0x3 << cc);
5839
            tcg_gen_and_tl(t0, t0, t1);
5840
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5841
            tcg_gen_movi_tl(t0, 0);
5842
            tcg_gen_br(l2);
5843
            gen_set_label(l1);
5844
            tcg_gen_movi_tl(t0, 1);
5845
            gen_set_label(l2);
5846
        }
5847
        opn = "bc1any2t";
5848
        goto not_likely;
5849
    case OPC_BC1FANY4:
5850
        {
5851
            int l1 = gen_new_label();
5852
            int l2 = gen_new_label();
5853
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5854

    
5855
            get_fp_cond(r_tmp1);
5856
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5857
            tcg_temp_free(r_tmp1);
5858
            tcg_gen_not_tl(t0, t0);
5859
            tcg_gen_movi_tl(t1, 0xf << cc);
5860
            tcg_gen_and_tl(t0, t0, t1);
5861
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5862
            tcg_gen_movi_tl(t0, 0);
5863
            tcg_gen_br(l2);
5864
            gen_set_label(l1);
5865
            tcg_gen_movi_tl(t0, 1);
5866
            gen_set_label(l2);
5867
        }
5868
        opn = "bc1any4f";
5869
        goto not_likely;
5870
    case OPC_BC1TANY4:
5871
        {
5872
            int l1 = gen_new_label();
5873
            int l2 = gen_new_label();
5874
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5875

    
5876
            get_fp_cond(r_tmp1);
5877
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5878
            tcg_temp_free(r_tmp1);
5879
            tcg_gen_movi_tl(t1, 0xf << cc);
5880
            tcg_gen_and_tl(t0, t0, t1);
5881
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5882
            tcg_gen_movi_tl(t0, 0);
5883
            tcg_gen_br(l2);
5884
            gen_set_label(l1);
5885
            tcg_gen_movi_tl(t0, 1);
5886
            gen_set_label(l2);
5887
        }
5888
        opn = "bc1any4t";
5889
    not_likely:
5890
        ctx->hflags |= MIPS_HFLAG_BC;
5891
        tcg_gen_trunc_tl_i32(bcond, t0);
5892
        break;
5893
    default:
5894
        MIPS_INVAL(opn);
5895
        generate_exception (ctx, EXCP_RI);
5896
        goto out;
5897
    }
5898
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5899
               ctx->hflags, btarget);
5900
    ctx->btarget = btarget;
5901

    
5902
 out:
5903
    tcg_temp_free(t0);
5904
    tcg_temp_free(t1);
5905
}
5906

    
5907
/* Coprocessor 1 (FPU) */
5908

    
5909
#define FOP(func, fmt) (((fmt) << 21) | (func))
5910

    
5911
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5912
{
5913
    const char *opn = "cp1 move";
5914
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5915

    
5916
    switch (opc) {
5917
    case OPC_MFC1:
5918
        {
5919
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5920

    
5921
            gen_load_fpr32(fp0, fs);
5922
            tcg_gen_ext_i32_tl(t0, fp0);
5923
            tcg_temp_free(fp0);
5924
        }
5925
        gen_store_gpr(t0, rt);
5926
        opn = "mfc1";
5927
        break;
5928
    case OPC_MTC1:
5929
        gen_load_gpr(t0, rt);
5930
        {
5931
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5932

    
5933
            tcg_gen_trunc_tl_i32(fp0, t0);
5934
            gen_store_fpr32(fp0, fs);
5935
            tcg_temp_free(fp0);
5936
        }
5937
        opn = "mtc1";
5938
        break;
5939
    case OPC_CFC1:
5940
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5941
        gen_store_gpr(t0, rt);
5942
        opn = "cfc1";
5943
        break;
5944
    case OPC_CTC1:
5945
        gen_load_gpr(t0, rt);
5946
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5947
        opn = "ctc1";
5948
        break;
5949
    case OPC_DMFC1:
5950
        {
5951
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5952

    
5953
            gen_load_fpr64(ctx, fp0, fs);
5954
            tcg_gen_mov_tl(t0, fp0);
5955
            tcg_temp_free(fp0);
5956
        }
5957
        gen_store_gpr(t0, rt);
5958
        opn = "dmfc1";
5959
        break;
5960
    case OPC_DMTC1:
5961
        gen_load_gpr(t0, rt);
5962
        {
5963
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5964

    
5965
            tcg_gen_mov_tl(fp0, t0);
5966
            gen_store_fpr64(ctx, fp0, fs);
5967
            tcg_temp_free(fp0);
5968
        }
5969
        opn = "dmtc1";
5970
        break;
5971
    case OPC_MFHC1:
5972
        {
5973
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5974

    
5975
            gen_load_fpr32h(fp0, fs);
5976
            tcg_gen_ext_i32_tl(t0, fp0);
5977
            tcg_temp_free(fp0);
5978
        }
5979
        gen_store_gpr(t0, rt);
5980
        opn = "mfhc1";
5981
        break;
5982
    case OPC_MTHC1:
5983
        gen_load_gpr(t0, rt);
5984
        {
5985
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5986

    
5987
            tcg_gen_trunc_tl_i32(fp0, t0);
5988
            gen_store_fpr32h(fp0, fs);
5989
            tcg_temp_free(fp0);
5990
        }
5991
        opn = "mthc1";
5992
        break;
5993
    default:
5994
        MIPS_INVAL(opn);
5995
        generate_exception (ctx, EXCP_RI);
5996
        goto out;
5997
    }
5998
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5999

    
6000
 out:
6001
    tcg_temp_free(t0);
6002
}
6003

    
6004
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6005
{
6006
    int l1 = gen_new_label();
6007
    uint32_t ccbit;
6008
    TCGCond cond;
6009
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6010
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
6011
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
6012

    
6013
    if (cc)
6014
        ccbit = 1 << (24 + cc);
6015
    else
6016
        ccbit = 1 << 23;
6017
    if (tf)
6018
        cond = TCG_COND_EQ;
6019
    else
6020
        cond = TCG_COND_NE;
6021

    
6022
    gen_load_gpr(t0, rd);
6023
    gen_load_gpr(t1, rs);
6024
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
6025
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
6026
    tcg_temp_free(r_tmp);
6027

    
6028
    tcg_gen_mov_tl(t0, t1);
6029
    tcg_temp_free(t1);
6030

    
6031
    gen_set_label(l1);
6032
    gen_store_gpr(t0, rd);
6033
    tcg_temp_free(t0);
6034
}
6035

    
6036
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6037
{
6038
    uint32_t ccbit;
6039
    int cond;
6040
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6041
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6042
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6043
    int l1 = gen_new_label();
6044

    
6045
    if (cc)
6046
        ccbit = 1 << (24 + cc);
6047
    else
6048
        ccbit = 1 << 23;
6049

    
6050
    if (tf)
6051
        cond = TCG_COND_EQ;
6052
    else
6053
        cond = TCG_COND_NE;
6054

    
6055
    gen_load_fpr32(fp0, fs);
6056
    gen_load_fpr32(fp1, fd);
6057
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6058
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6059
    tcg_gen_mov_i32(fp1, fp0);
6060
    tcg_temp_free(fp0);
6061
    gen_set_label(l1);
6062
    tcg_temp_free(r_tmp1);
6063
    gen_store_fpr32(fp1, fd);
6064
    tcg_temp_free(fp1);
6065
}
6066

    
6067
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6068
{
6069
    uint32_t ccbit;
6070
    int cond;
6071
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6072
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6073
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I64);
6074
    int l1 = gen_new_label();
6075

    
6076
    if (cc)
6077
        ccbit = 1 << (24 + cc);
6078
    else
6079
        ccbit = 1 << 23;
6080

    
6081
    if (tf)
6082
        cond = TCG_COND_EQ;
6083
    else
6084
        cond = TCG_COND_NE;
6085

    
6086
    gen_load_fpr64(ctx, fp0, fs);
6087
    gen_load_fpr64(ctx, fp1, fd);
6088
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6089
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6090
    tcg_gen_mov_i64(fp1, fp0);
6091
    tcg_temp_free(fp0);
6092
    gen_set_label(l1);
6093
    tcg_temp_free(r_tmp1);
6094
    gen_store_fpr64(ctx, fp1, fd);
6095
    tcg_temp_free(fp1);
6096
}
6097

    
6098
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6099
{
6100
    int cond;
6101
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6102
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6103
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6104
    TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
6105
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6106
    TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
6107
    int l1 = gen_new_label();
6108
    int l2 = gen_new_label();
6109

    
6110
    if (tf)
6111
        cond = TCG_COND_EQ;
6112
    else
6113
        cond = TCG_COND_NE;
6114

    
6115
    gen_load_fpr32(fp0, fs);
6116
    gen_load_fpr32h(fph0, fs);
6117
    gen_load_fpr32(fp1, fd);
6118
    gen_load_fpr32h(fph1, fd);
6119
    get_fp_cond(r_tmp1);
6120
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6121
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6122
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6123
    tcg_gen_mov_i32(fp1, fp0);
6124
    tcg_temp_free(fp0);
6125
    gen_set_label(l1);
6126
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6127
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6128
    tcg_gen_mov_i32(fph1, fph0);
6129
    tcg_temp_free(fph0);
6130
    gen_set_label(l2);
6131
    tcg_temp_free(r_tmp1);
6132
    tcg_temp_free(r_tmp2);
6133
    gen_store_fpr32(fp1, fd);
6134
    gen_store_fpr32h(fph1, fd);
6135
    tcg_temp_free(fp1);
6136
    tcg_temp_free(fph1);
6137
}
6138

    
6139

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

    
6183
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6184
    case FOP(0, 16):
6185
        {
6186
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6187
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6188

    
6189
            gen_load_fpr32(fp0, fs);
6190
            gen_load_fpr32(fp1, ft);
6191
            tcg_gen_helper_1_2(do_float_add_s, fp0, fp0, fp1);
6192
            tcg_temp_free(fp1);
6193
            gen_store_fpr32(fp0, fd);
6194
            tcg_temp_free(fp0);
6195
        }
6196
        opn = "add.s";
6197
        optype = BINOP;
6198
        break;
6199
    case FOP(1, 16):
6200
        {
6201
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6202
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6203

    
6204
            gen_load_fpr32(fp0, fs);
6205
            gen_load_fpr32(fp1, ft);
6206
            tcg_gen_helper_1_2(do_float_sub_s, fp0, fp0, fp1);
6207
            tcg_temp_free(fp1);
6208
            gen_store_fpr32(fp0, fd);
6209
            tcg_temp_free(fp0);
6210
        }
6211
        opn = "sub.s";
6212
        optype = BINOP;
6213
        break;
6214
    case FOP(2, 16):
6215
        {
6216
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6217
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6218

    
6219
            gen_load_fpr32(fp0, fs);
6220
            gen_load_fpr32(fp1, ft);
6221
            tcg_gen_helper_1_2(do_float_mul_s, fp0, fp0, fp1);
6222
            tcg_temp_free(fp1);
6223
            gen_store_fpr32(fp0, fd);
6224
            tcg_temp_free(fp0);
6225
        }
6226
        opn = "mul.s";
6227
        optype = BINOP;
6228
        break;
6229
    case FOP(3, 16):
6230
        {
6231
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6232
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6233

    
6234
            gen_load_fpr32(fp0, fs);
6235
            gen_load_fpr32(fp1, ft);
6236
            tcg_gen_helper_1_2(do_float_div_s, fp0, fp0, fp1);
6237
            tcg_temp_free(fp1);
6238
            gen_store_fpr32(fp0, fd);
6239
            tcg_temp_free(fp0);
6240
        }
6241
        opn = "div.s";
6242
        optype = BINOP;
6243
        break;
6244
    case FOP(4, 16):
6245
        {
6246
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6247

    
6248
            gen_load_fpr32(fp0, fs);
6249
            tcg_gen_helper_1_1(do_float_sqrt_s, fp0, fp0);
6250
            gen_store_fpr32(fp0, fd);
6251
            tcg_temp_free(fp0);
6252
        }
6253
        opn = "sqrt.s";
6254
        break;
6255
    case FOP(5, 16):
6256
        {
6257
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6258

    
6259
            gen_load_fpr32(fp0, fs);
6260
            tcg_gen_helper_1_1(do_float_abs_s, fp0, fp0);
6261
            gen_store_fpr32(fp0, fd);
6262
            tcg_temp_free(fp0);
6263
        }
6264
        opn = "abs.s";
6265
        break;
6266
    case FOP(6, 16):
6267
        {
6268
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6269

    
6270
            gen_load_fpr32(fp0, fs);
6271
            gen_store_fpr32(fp0, fd);
6272
            tcg_temp_free(fp0);
6273
        }
6274
        opn = "mov.s";
6275
        break;
6276
    case FOP(7, 16):
6277
        {
6278
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6279

    
6280
            gen_load_fpr32(fp0, fs);
6281
            tcg_gen_helper_1_1(do_float_chs_s, fp0, fp0);
6282
            gen_store_fpr32(fp0, fd);
6283
            tcg_temp_free(fp0);
6284
        }
6285
        opn = "neg.s";
6286
        break;
6287
    case FOP(8, 16):
6288
        check_cp1_64bitmode(ctx);
6289
        {
6290
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6291
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6292

    
6293
            gen_load_fpr32(fp32, fs);
6294
            tcg_gen_helper_1_1(do_float_roundl_s, fp64, fp32);
6295
            tcg_temp_free(fp32);
6296
            gen_store_fpr64(ctx, fp64, fd);
6297
            tcg_temp_free(fp64);
6298
        }
6299
        opn = "round.l.s";
6300
        break;
6301
    case FOP(9, 16):
6302
        check_cp1_64bitmode(ctx);
6303
        {
6304
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6305
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6306

    
6307
            gen_load_fpr32(fp32, fs);
6308
            tcg_gen_helper_1_1(do_float_truncl_s, fp64, fp32);
6309
            tcg_temp_free(fp32);
6310
            gen_store_fpr64(ctx, fp64, fd);
6311
            tcg_temp_free(fp64);
6312
        }
6313
        opn = "trunc.l.s";
6314
        break;
6315
    case FOP(10, 16):
6316
        check_cp1_64bitmode(ctx);
6317
        {
6318
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6319
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6320

    
6321
            gen_load_fpr32(fp32, fs);
6322
            tcg_gen_helper_1_1(do_float_ceill_s, fp64, fp32);
6323
            tcg_temp_free(fp32);
6324
            gen_store_fpr64(ctx, fp64, fd);
6325
            tcg_temp_free(fp64);
6326
        }
6327
        opn = "ceil.l.s";
6328
        break;
6329
    case FOP(11, 16):
6330
        check_cp1_64bitmode(ctx);
6331
        {
6332
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6333
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6334

    
6335
            gen_load_fpr32(fp32, fs);
6336
            tcg_gen_helper_1_1(do_float_floorl_s, fp64, fp32);
6337
            tcg_temp_free(fp32);
6338
            gen_store_fpr64(ctx, fp64, fd);
6339
            tcg_temp_free(fp64);
6340
        }
6341
        opn = "floor.l.s";
6342
        break;
6343
    case FOP(12, 16):
6344
        {
6345
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6346

    
6347
            gen_load_fpr32(fp0, fs);
6348
            tcg_gen_helper_1_1(do_float_roundw_s, fp0, fp0);
6349
            gen_store_fpr32(fp0, fd);
6350
            tcg_temp_free(fp0);
6351
        }
6352
        opn = "round.w.s";
6353
        break;
6354
    case FOP(13, 16):
6355
        {
6356
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6357

    
6358
            gen_load_fpr32(fp0, fs);
6359
            tcg_gen_helper_1_1(do_float_truncw_s, fp0, fp0);
6360
            gen_store_fpr32(fp0, fd);
6361
            tcg_temp_free(fp0);
6362
        }
6363
        opn = "trunc.w.s";
6364
        break;
6365
    case FOP(14, 16):
6366
        {
6367
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6368

    
6369
            gen_load_fpr32(fp0, fs);
6370
            tcg_gen_helper_1_1(do_float_ceilw_s, fp0, fp0);
6371
            gen_store_fpr32(fp0, fd);
6372
            tcg_temp_free(fp0);
6373
        }
6374
        opn = "ceil.w.s";
6375
        break;
6376
    case FOP(15, 16):
6377
        {
6378
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6379

    
6380
            gen_load_fpr32(fp0, fs);
6381
            tcg_gen_helper_1_1(do_float_floorw_s, fp0, fp0);
6382
            gen_store_fpr32(fp0, fd);
6383
            tcg_temp_free(fp0);
6384
        }
6385
        opn = "floor.w.s";
6386
        break;
6387
    case FOP(17, 16):
6388
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6389
        opn = "movcf.s";
6390
        break;
6391
    case FOP(18, 16):
6392
        {
6393
            int l1 = gen_new_label();
6394
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6395
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6396

    
6397
            gen_load_gpr(t0, ft);
6398
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6399
            tcg_temp_free(t0);
6400
            gen_load_fpr32(fp0, fs);
6401
            gen_store_fpr32(fp0, fd);
6402
            tcg_temp_free(fp0);
6403
            gen_set_label(l1);
6404
        }
6405
        opn = "movz.s";
6406
        break;
6407
    case FOP(19, 16):
6408
        {
6409
            int l1 = gen_new_label();
6410
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6411
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6412

    
6413
            gen_load_gpr(t0, ft);
6414
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6415
            tcg_temp_free(t0);
6416
            gen_load_fpr32(fp0, fs);
6417
            gen_store_fpr32(fp0, fd);
6418
            tcg_temp_free(fp0);
6419
            gen_set_label(l1);
6420
        }
6421
        opn = "movn.s";
6422
        break;
6423
    case FOP(21, 16):
6424
        check_cop1x(ctx);
6425
        {
6426
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6427

    
6428
            gen_load_fpr32(fp0, fs);
6429
            tcg_gen_helper_1_1(do_float_recip_s, fp0, fp0);
6430
            gen_store_fpr32(fp0, fd);
6431
            tcg_temp_free(fp0);
6432
        }
6433
        opn = "recip.s";
6434
        break;
6435
    case FOP(22, 16):
6436
        check_cop1x(ctx);
6437
        {
6438
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6439

    
6440
            gen_load_fpr32(fp0, fs);
6441
            tcg_gen_helper_1_1(do_float_rsqrt_s, fp0, fp0);
6442
            gen_store_fpr32(fp0, fd);
6443
            tcg_temp_free(fp0);
6444
        }
6445
        opn = "rsqrt.s";
6446
        break;
6447
    case FOP(28, 16):
6448
        check_cp1_64bitmode(ctx);
6449
        {
6450
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6451
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6452

    
6453
            gen_load_fpr32(fp0, fs);
6454
            gen_load_fpr32(fp1, fd);
6455
            tcg_gen_helper_1_2(do_float_recip2_s, fp0, fp0, fp1);
6456
            tcg_temp_free(fp1);
6457
            gen_store_fpr32(fp0, fd);
6458
            tcg_temp_free(fp0);
6459
        }
6460
        opn = "recip2.s";
6461
        break;
6462
    case FOP(29, 16):
6463
        check_cp1_64bitmode(ctx);
6464
        {
6465
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6466

    
6467
            gen_load_fpr32(fp0, fs);
6468
            tcg_gen_helper_1_1(do_float_recip1_s, fp0, fp0);
6469
            gen_store_fpr32(fp0, fd);
6470
            tcg_temp_free(fp0);
6471
        }
6472
        opn = "recip1.s";
6473
        break;
6474
    case FOP(30, 16):
6475
        check_cp1_64bitmode(ctx);
6476
        {
6477
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6478

    
6479
            gen_load_fpr32(fp0, fs);
6480
            tcg_gen_helper_1_1(do_float_rsqrt1_s, fp0, fp0);
6481
            gen_store_fpr32(fp0, fd);
6482
            tcg_temp_free(fp0);
6483
        }
6484
        opn = "rsqrt1.s";
6485
        break;
6486
    case FOP(31, 16):
6487
        check_cp1_64bitmode(ctx);
6488
        {
6489
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6490
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6491

    
6492
            gen_load_fpr32(fp0, fs);
6493
            gen_load_fpr32(fp1, ft);
6494
            tcg_gen_helper_1_2(do_float_rsqrt2_s, fp0, fp0, fp1);
6495
            tcg_temp_free(fp1);
6496
            gen_store_fpr32(fp0, fd);
6497
            tcg_temp_free(fp0);
6498
        }
6499
        opn = "rsqrt2.s";
6500
        break;
6501
    case FOP(33, 16):
6502
        check_cp1_registers(ctx, fd);
6503
        {
6504
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6505
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6506

    
6507
            gen_load_fpr32(fp32, fs);
6508
            tcg_gen_helper_1_1(do_float_cvtd_s, fp64, fp32);
6509
            tcg_temp_free(fp32);
6510
            gen_store_fpr64(ctx, fp64, fd);
6511
            tcg_temp_free(fp64);
6512
        }
6513
        opn = "cvt.d.s";
6514
        break;
6515
    case FOP(36, 16):
6516
        {
6517
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6518

    
6519
            gen_load_fpr32(fp0, fs);
6520
            tcg_gen_helper_1_1(do_float_cvtw_s, fp0, fp0);
6521
            gen_store_fpr32(fp0, fd);
6522
            tcg_temp_free(fp0);
6523
        }
6524
        opn = "cvt.w.s";
6525
        break;
6526
    case FOP(37, 16):
6527
        check_cp1_64bitmode(ctx);
6528
        {
6529
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6530
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6531

    
6532
            gen_load_fpr32(fp32, fs);
6533
            tcg_gen_helper_1_1(do_float_cvtl_s, fp64, fp32);
6534
            tcg_temp_free(fp32);
6535
            gen_store_fpr64(ctx, fp64, fd);
6536
            tcg_temp_free(fp64);
6537
        }
6538
        opn = "cvt.l.s";
6539
        break;
6540
    case FOP(38, 16):
6541
        check_cp1_64bitmode(ctx);
6542
        {
6543
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6544
            TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
6545
            TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
6546

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7542
            gen_load_gpr(t0, fr);
7543
            tcg_gen_andi_tl(t0, t0, 0x7);
7544
            gen_load_fpr32(fp0, fs);
7545
            gen_load_fpr32h(fph0, fs);
7546
            gen_load_fpr32(fp1, ft);
7547
            gen_load_fpr32h(fph1, ft);
7548

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7800
/* ISA extensions (ASEs) */
7801
/* MIPS16 extension to MIPS32 */
7802
/* SmartMIPS extension to MIPS32 */
7803

    
7804
#if defined(TARGET_MIPS64)
7805

    
7806
/* MDMX extension to MIPS64 */
7807

    
7808
#endif
7809

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8439
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8440
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8441
                gen_set_label(l1);
8442
                gen_goto_tb(ctx, 0, ctx->btarget);
8443
            }
8444
            break;
8445
        case MIPS_HFLAG_BR:
8446
            /* unconditional branch to register */
8447
            MIPS_DEBUG("branch to register");
8448
            tcg_gen_mov_tl(cpu_PC, btarget);
8449
            tcg_gen_exit_tb(0);
8450
            break;
8451
        default:
8452
            MIPS_DEBUG("unknown branch");
8453
            break;
8454
        }
8455
    }
8456
}
8457

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

    
8469
    if (search_pc && loglevel)
8470
        fprintf (logfile, "search pc %d\n", search_pc);
8471

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

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

    
8537
        if (env->singlestep_enabled)
8538
            break;
8539

    
8540
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8541
            break;
8542

    
8543
        if (gen_opc_ptr >= gen_opc_end)
8544
            break;
8545

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

    
8604
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8605
{
8606
    gen_intermediate_code_internal(env, tb, 0);
8607
}
8608

    
8609
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8610
{
8611
    gen_intermediate_code_internal(env, tb, 1);
8612
}
8613

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

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

    
8637

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

    
8646
#undef printfpr
8647
}
8648

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

    
8653
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8654

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

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

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

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

    
8683
void cpu_dump_state (CPUState *env, FILE *f,
8684
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8685
                     int flags)
8686
{
8687
    int i;
8688

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

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

    
8711
static void mips_tcg_init(void)
8712
{
8713
    int i;
8714
    static int inited;
8715

    
8716
    /* Initialize various static tables. */
8717
    if (inited)
8718
        return;
8719

    
8720
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8721
    for (i = 0; i < 32; i++)
8722
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8723
                                        offsetof(CPUState, active_tc.gpr[i]),
8724
                                        regnames[i]);
8725
    cpu_PC = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8726
                                offsetof(CPUState, active_tc.PC), "PC");
8727
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8728
        cpu_HI[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8729
                                       offsetof(CPUState, active_tc.HI[i]),
8730
                                       regnames_HI[i]);
8731
        cpu_LO[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8732
                                       offsetof(CPUState, active_tc.LO[i]),
8733
                                       regnames_LO[i]);
8734
        cpu_ACX[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8735
                                        offsetof(CPUState, active_tc.ACX[i]),
8736
                                        regnames_ACX[i]);
8737
    }
8738
    cpu_dspctrl = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8739
                                     offsetof(CPUState, active_tc.DSPControl),
8740
                                     "DSPControl");
8741
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8742
                               offsetof(CPUState, bcond), "bcond");
8743
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8744
                                 offsetof(CPUState, btarget), "btarget");
8745
    for (i = 0; i < 32; i++)
8746
        fpu_fpr32[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8747
                                          offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8748
                                          fregnames[i]);
8749
    for (i = 0; i < 32; i++)
8750
        fpu_fpr64[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
8751
                                          offsetof(CPUState, active_fpu.fpr[i]),
8752
                                          fregnames_64[i]);
8753
    for (i = 0; i < 32; i++)
8754
        fpu_fpr32h[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8755
                                           offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8756
                                           fregnames_h[i]);
8757
    fpu_fcr0 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8758
                                   offsetof(CPUState, active_fpu.fcr0),
8759
                                   "fcr0");
8760
    fpu_fcr31 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8761
                                   offsetof(CPUState, active_fpu.fcr31),
8762
                                   "fcr31");
8763

    
8764
    /* register helpers */
8765
#undef DEF_HELPER
8766
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8767
#include "helper.h"
8768

    
8769
    inited = 1;
8770
}
8771

    
8772
#include "translate_init.c"
8773

    
8774
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8775
{
8776
    CPUMIPSState *env;
8777
    const mips_def_t *def;
8778

    
8779
    def = cpu_mips_find_by_name(cpu_model);
8780
    if (!def)
8781
        return NULL;
8782
    env = qemu_mallocz(sizeof(CPUMIPSState));
8783
    if (!env)
8784
        return NULL;
8785
    env->cpu_model = def;
8786

    
8787
    cpu_exec_init(env);
8788
    env->cpu_model_str = cpu_model;
8789
    mips_tcg_init();
8790
    cpu_reset(env);
8791
    return env;
8792
}
8793

    
8794
void cpu_reset (CPUMIPSState *env)
8795
{
8796
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8797

    
8798
    tlb_flush(env, 1);
8799

    
8800
    /* Minimal init */
8801
#if defined(CONFIG_USER_ONLY)
8802
    env->user_mode_only = 1;
8803
#endif
8804
    if (env->user_mode_only) {
8805
        env->hflags = MIPS_HFLAG_UM;
8806
    } else {
8807
        if (env->hflags & MIPS_HFLAG_BMASK) {
8808
            /* If the exception was raised from a delay slot,
8809
               come back to the jump.  */
8810
            env->CP0_ErrorEPC = env->active_tc.PC - 4;
8811
        } else {
8812
            env->CP0_ErrorEPC = env->active_tc.PC;
8813
        }
8814
        env->active_tc.PC = (int32_t)0xBFC00000;
8815
        env->CP0_Wired = 0;
8816
        /* SMP not implemented */
8817
        env->CP0_EBase = 0x80000000;
8818
        env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8819
        /* vectored interrupts not implemented, timer on int 7,
8820
           no performance counters. */
8821
        env->CP0_IntCtl = 0xe0000000;
8822
        {
8823
            int i;
8824

    
8825
            for (i = 0; i < 7; i++) {
8826
                env->CP0_WatchLo[i] = 0;
8827
                env->CP0_WatchHi[i] = 0x80000000;
8828
            }
8829
            env->CP0_WatchLo[7] = 0;
8830
            env->CP0_WatchHi[7] = 0;
8831
        }
8832
        /* Count register increments in debug mode, EJTAG version 1 */
8833
        env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8834
        env->hflags = MIPS_HFLAG_CP0;
8835
    }
8836
    env->exception_index = EXCP_NONE;
8837
    cpu_mips_register(env, env->cpu_model);
8838
}
8839

    
8840
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8841
                unsigned long searched_pc, int pc_pos, void *puc)
8842
{
8843
    env->active_tc.PC = gen_opc_pc[pc_pos];
8844
    env->hflags &= ~MIPS_HFLAG_BMASK;
8845
    env->hflags |= gen_opc_hflags[pc_pos];
8846
}