Statistics
| Branch: | Revision:

root / target-mips / translate.c @ f36672ae

History | View | Annotate | Download (258.2 kB)

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

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

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

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
428
#include "gen-icount.h"
429

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3435
    if (use_icount)
3436
        gen_io_start();
3437

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

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

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

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

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

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

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

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

    
4619
    if (use_icount)
4620
        gen_io_start();
4621

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5707
    btarget = ctx->pc + 4 + offset;
5708

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

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

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

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

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

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

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

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

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

    
5889
 out:
5890
    tcg_temp_free(t0);
5891
    tcg_temp_free(t1);
5892
}
5893

    
5894
/* Coprocessor 1 (FPU) */
5895

    
5896
#define FOP(func, fmt) (((fmt) << 21) | (func))
5897

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

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

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

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

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

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

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

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

    
5987
 out:
5988
    tcg_temp_free(t0);
5989
}
5990

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

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

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

    
6016
    tcg_gen_mov_tl(t0, t1);
6017
    tcg_temp_free(t1);
6018

    
6019
    gen_set_label(l1);
6020
    gen_store_gpr(t0, rd);
6021
    tcg_temp_free(t0);
6022
}
6023

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

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

    
6038
    if (tf)
6039
        cond = TCG_COND_EQ;
6040
    else
6041
        cond = TCG_COND_NE;
6042

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

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

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

    
6070
    if (tf)
6071
        cond = TCG_COND_EQ;
6072
    else
6073
        cond = TCG_COND_NE;
6074

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

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

    
6100
    if (tf)
6101
        cond = TCG_COND_EQ;
6102
    else
6103
        cond = TCG_COND_NE;
6104

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

    
6129

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7795
/* ISA extensions (ASEs) */
7796
/* MIPS16 extension to MIPS32 */
7797
/* SmartMIPS extension to MIPS32 */
7798

    
7799
#if defined(TARGET_MIPS64)
7800

    
7801
/* MDMX extension to MIPS64 */
7802

    
7803
#endif
7804

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8532
        if (env->singlestep_enabled)
8533
            break;
8534

    
8535
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8536
            break;
8537

    
8538
        if (gen_opc_ptr >= gen_opc_end)
8539
            break;
8540

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

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

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

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

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

    
8632

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

    
8641
#undef printfpr
8642
}
8643

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

    
8648
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8649

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

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

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

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

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

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

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

    
8706
static void mips_tcg_init(void)
8707
{
8708
    static int inited;
8709

    
8710
    /* Initialize various static tables. */
8711
    if (inited)
8712
        return;
8713

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

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

    
8729
    inited = 1;
8730
}
8731

    
8732
#include "translate_init.c"
8733

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

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

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

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

    
8758
    tlb_flush(env, 1);
8759

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

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

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