Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 2cfc5f17

History | View | Annotate | Download (258.4 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

    
29
#include "cpu.h"
30
#include "exec-all.h"
31
#include "disas.h"
32
#include "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
428
#include "gen-icount.h"
429

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3436
    if (use_icount)
3437
        gen_io_start();
3438

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

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

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

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

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

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

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

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

    
4620
    if (use_icount)
4621
        gen_io_start();
4622

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5897
/* Coprocessor 1 (FPU) */
5898

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

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

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

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

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

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

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

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

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

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

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

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

    
6011
    gen_load_gpr(t0, rd);
6012
    gen_load_gpr(t1, rs);
6013
    {
6014
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
6015
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
6016

    
6017
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
6018
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
6019
        tcg_temp_free(r_ptr);
6020
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
6021
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
6022
        tcg_temp_free(r_tmp);
6023
    }
6024
    tcg_gen_mov_tl(t0, t1);
6025
    tcg_temp_free(t1);
6026

    
6027
    gen_set_label(l1);
6028
    gen_store_gpr(t0, rd);
6029
    tcg_temp_free(t0);
6030
}
6031

    
6032
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6033
{
6034
    uint32_t ccbit;
6035
    int cond;
6036
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6037
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6038
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6039
    int l1 = gen_new_label();
6040

    
6041
    if (cc)
6042
        ccbit = 1 << (24 + cc);
6043
    else
6044
        ccbit = 1 << 23;
6045

    
6046
    if (tf)
6047
        cond = TCG_COND_EQ;
6048
    else
6049
        cond = TCG_COND_NE;
6050

    
6051
    gen_load_fpr32(fp0, fs);
6052
    gen_load_fpr32(fp1, fd);
6053
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6054
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6055
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6056
    tcg_gen_movi_i32(fp1, fp0);
6057
    tcg_temp_free(fp0);
6058
    gen_set_label(l1);
6059
    tcg_temp_free(r_tmp1);
6060
    gen_store_fpr32(fp1, fd);
6061
    tcg_temp_free(fp1);
6062
}
6063

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

    
6073
    if (cc)
6074
        ccbit = 1 << (24 + cc);
6075
    else
6076
        ccbit = 1 << 23;
6077

    
6078
    if (tf)
6079
        cond = TCG_COND_EQ;
6080
    else
6081
        cond = TCG_COND_NE;
6082

    
6083
    gen_load_fpr64(ctx, fp0, fs);
6084
    gen_load_fpr64(ctx, fp1, fd);
6085
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6086
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6087
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6088
    tcg_gen_movi_i64(fp1, fp0);
6089
    tcg_temp_free(fp0);
6090
    gen_set_label(l1);
6091
    tcg_temp_free(r_tmp1);
6092
    gen_store_fpr64(ctx, fp1, fd);
6093
    tcg_temp_free(fp1);
6094
}
6095

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

    
6108
    if (tf)
6109
        cond = TCG_COND_EQ;
6110
    else
6111
        cond = TCG_COND_NE;
6112

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

    
6137

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7545
            gen_load_gpr(t0, fr);
7546
            tcg_gen_andi_tl(t0, t0, 0x7);
7547
            gen_load_fpr32(fp0, fs);
7548
            gen_load_fpr32h(fph0, fs);
7549
            gen_load_fpr32(fp1, ft);
7550
            gen_load_fpr32h(fph1, ft);
7551

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7803
/* ISA extensions (ASEs) */
7804
/* MIPS16 extension to MIPS32 */
7805
/* SmartMIPS extension to MIPS32 */
7806

    
7807
#if defined(TARGET_MIPS64)
7808

    
7809
/* MDMX extension to MIPS64 */
7810

    
7811
#endif
7812

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8636

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

    
8645
#undef printfpr
8646
}
8647

    
8648
void dump_fpu (CPUState *env)
8649
{
8650
    if (loglevel) {
8651
        fprintf(logfile,
8652
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
8653
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
8654
                " %04x\n",
8655
                env->active_tc.PC, env->active_tc.HI[0],
8656
                env->active_tc.LO[0], env->hflags, env->btarget,
8657
                env->bcond);
8658
       fpu_dump_state(env, logfile, fprintf, 0);
8659
    }
8660
}
8661

    
8662
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8663
/* Debug help: The architecture requires 32bit code to maintain proper
8664
   sign-extended values on 64bit machines.  */
8665

    
8666
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8667

    
8668
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8669
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8670
                     int flags)
8671
{
8672
    int i;
8673

    
8674
    if (!SIGN_EXT_P(env->active_tc.PC))
8675
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8676
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8677
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8678
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8679
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8680
    if (!SIGN_EXT_P(env->btarget))
8681
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8682

    
8683
    for (i = 0; i < 32; i++) {
8684
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8685
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8686
    }
8687

    
8688
    if (!SIGN_EXT_P(env->CP0_EPC))
8689
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8690
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8691
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8692
}
8693
#endif
8694

    
8695
void cpu_dump_state (CPUState *env, FILE *f,
8696
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8697
                     int flags)
8698
{
8699
    int i;
8700

    
8701
    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",
8702
                env->active_tc.PC, env->active_tc.HI, env->active_tc.LO, env->hflags, env->btarget, env->bcond);
8703
    for (i = 0; i < 32; i++) {
8704
        if ((i & 3) == 0)
8705
            cpu_fprintf(f, "GPR%02d:", i);
8706
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8707
        if ((i & 3) == 3)
8708
            cpu_fprintf(f, "\n");
8709
    }
8710

    
8711
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8712
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8713
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8714
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8715
    if (env->hflags & MIPS_HFLAG_FPU)
8716
        fpu_dump_state(env, f, cpu_fprintf, flags);
8717
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8718
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8719
#endif
8720
}
8721

    
8722
static void mips_tcg_init(void)
8723
{
8724
    static int inited;
8725

    
8726
    /* Initialize various static tables. */
8727
    if (inited)
8728
        return;
8729

    
8730
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8731
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8732
                               offsetof(CPUState, bcond), "bcond");
8733
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8734
                                 offsetof(CPUState, btarget), "btarget");
8735
    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
8736
                                     TCG_AREG0,
8737
                                     offsetof(CPUState, fpu),
8738
                                     "current_fpu");
8739

    
8740
    /* register helpers */
8741
#undef DEF_HELPER
8742
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8743
#include "helper.h"
8744

    
8745
    inited = 1;
8746
}
8747

    
8748
#include "translate_init.c"
8749

    
8750
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8751
{
8752
    CPUMIPSState *env;
8753
    const mips_def_t *def;
8754

    
8755
    def = cpu_mips_find_by_name(cpu_model);
8756
    if (!def)
8757
        return NULL;
8758
    env = qemu_mallocz(sizeof(CPUMIPSState));
8759
    if (!env)
8760
        return NULL;
8761
    env->cpu_model = def;
8762

    
8763
    cpu_exec_init(env);
8764
    env->cpu_model_str = cpu_model;
8765
    mips_tcg_init();
8766
    cpu_reset(env);
8767
    return env;
8768
}
8769

    
8770
void cpu_reset (CPUMIPSState *env)
8771
{
8772
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8773

    
8774
    tlb_flush(env, 1);
8775

    
8776
    /* Minimal init */
8777
#if !defined(CONFIG_USER_ONLY)
8778
    if (env->hflags & MIPS_HFLAG_BMASK) {
8779
        /* If the exception was raised from a delay slot,
8780
         * come back to the jump.  */
8781
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8782
    } else {
8783
        env->CP0_ErrorEPC = env->active_tc.PC;
8784
    }
8785
    env->active_tc.PC = (int32_t)0xBFC00000;
8786
    env->CP0_Wired = 0;
8787
    /* SMP not implemented */
8788
    env->CP0_EBase = 0x80000000;
8789
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8790
    /* vectored interrupts not implemented, timer on int 7,
8791
       no performance counters. */
8792
    env->CP0_IntCtl = 0xe0000000;
8793
    {
8794
        int i;
8795

    
8796
        for (i = 0; i < 7; i++) {
8797
            env->CP0_WatchLo[i] = 0;
8798
            env->CP0_WatchHi[i] = 0x80000000;
8799
        }
8800
        env->CP0_WatchLo[7] = 0;
8801
        env->CP0_WatchHi[7] = 0;
8802
    }
8803
    /* Count register increments in debug mode, EJTAG version 1 */
8804
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8805
#endif
8806
    env->exception_index = EXCP_NONE;
8807
#if defined(CONFIG_USER_ONLY)
8808
    env->hflags = MIPS_HFLAG_UM;
8809
    env->user_mode_only = 1;
8810
#else
8811
    env->hflags = MIPS_HFLAG_CP0;
8812
#endif
8813
    cpu_mips_register(env, env->cpu_model);
8814
}
8815

    
8816
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8817
                unsigned long searched_pc, int pc_pos, void *puc)
8818
{
8819
    env->active_tc.PC = gen_opc_pc[pc_pos];
8820
    env->hflags &= ~MIPS_HFLAG_BMASK;
8821
    env->hflags |= gen_opc_hflags[pc_pos];
8822
}