Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a4e8338d

History | View | Annotate | Download (244.4 kB)

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

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

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

    
35
#include "helper.h"
36
#define GEN_HELPER 1
37
#include "helper.h"
38

    
39
//#define MIPS_DEBUG_DISAS
40
//#define MIPS_DEBUG_SIGN_EXTENSIONS
41

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

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

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

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

    
186
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
388
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
389

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

    
402
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
403

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

    
427
/* global register indices */
428
static TCGv_ptr cpu_env;
429
static TCGv cpu_gpr[32], cpu_PC;
430
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
431
static TCGv cpu_dspctrl, btarget, bcond;
432
static TCGv_i32 hflags;
433
static TCGv_i32 fpu_fcr0, fpu_fcr31;
434

    
435
#include "gen-icount.h"
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1456
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1457
       && opc != OPC_DADD && opc != OPC_DSUB) {
1458
        /* If no destination, treat it as a NOP.
1459
           For add & sub, we must generate the overflow exception when needed. */
1460
        MIPS_DEBUG("NOP");
1461
        return;
1462
    }
1463

    
1464
    switch (opc) {
1465
    case OPC_ADD:
1466
        {
1467
            TCGv t0 = tcg_temp_local_new();
1468
            TCGv t1 = tcg_temp_new();
1469
            TCGv t2 = tcg_temp_new();
1470
            int l1 = gen_new_label();
1471

    
1472
            gen_load_gpr(t1, rs);
1473
            gen_load_gpr(t2, rt);
1474
            tcg_gen_add_tl(t0, t1, t2);
1475
            tcg_gen_ext32s_tl(t0, t0);
1476
            tcg_gen_xor_tl(t1, t1, t2);
1477
            tcg_gen_not_tl(t1, t1);
1478
            tcg_gen_xor_tl(t2, t0, t2);
1479
            tcg_gen_and_tl(t1, t1, t2);
1480
            tcg_temp_free(t2);
1481
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1482
            tcg_temp_free(t1);
1483
            /* operands of same sign, result different sign */
1484
            generate_exception(ctx, EXCP_OVERFLOW);
1485
            gen_set_label(l1);
1486
            gen_store_gpr(t0, rd);
1487
            tcg_temp_free(t0);
1488
        }
1489
        opn = "add";
1490
        break;
1491
    case OPC_ADDU:
1492
        if (rs != 0 && rt != 0) {
1493
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1494
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1495
        } else if (rs == 0 && rt != 0) {
1496
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1497
        } else if (rs != 0 && rt == 0) {
1498
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1499
        } else {
1500
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1501
        }
1502
        opn = "addu";
1503
        break;
1504
    case OPC_SUB:
1505
        {
1506
            TCGv t0 = tcg_temp_local_new();
1507
            TCGv t1 = tcg_temp_new();
1508
            TCGv t2 = tcg_temp_new();
1509
            int l1 = gen_new_label();
1510

    
1511
            gen_load_gpr(t1, rs);
1512
            gen_load_gpr(t2, rt);
1513
            tcg_gen_sub_tl(t0, t1, t2);
1514
            tcg_gen_ext32s_tl(t0, t0);
1515
            tcg_gen_xor_tl(t2, t1, t2);
1516
            tcg_gen_xor_tl(t1, t0, t1);
1517
            tcg_gen_and_tl(t1, t1, t2);
1518
            tcg_temp_free(t2);
1519
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1520
            tcg_temp_free(t1);
1521
            /* operands of same sign, result different sign */
1522
            generate_exception(ctx, EXCP_OVERFLOW);
1523
            gen_set_label(l1);
1524
            gen_store_gpr(t0, rd);
1525
            tcg_temp_free(t0);
1526
        }
1527
        opn = "sub";
1528
        break;
1529
    case OPC_SUBU:
1530
        if (rs != 0 && rt != 0) {
1531
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1532
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1533
        } else if (rs == 0 && rt != 0) {
1534
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1535
        } else if (rs != 0 && rt == 0) {
1536
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1537
        } else {
1538
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1539
        }
1540
        opn = "subu";
1541
        break;
1542
#if defined(TARGET_MIPS64)
1543
    case OPC_DADD:
1544
        {
1545
            TCGv t0 = tcg_temp_local_new();
1546
            TCGv t1 = tcg_temp_new();
1547
            TCGv t2 = tcg_temp_new();
1548
            int l1 = gen_new_label();
1549

    
1550
            gen_load_gpr(t1, rs);
1551
            gen_load_gpr(t2, rt);
1552
            tcg_gen_add_tl(t0, t1, t2);
1553
            tcg_gen_xor_tl(t1, t1, t2);
1554
            tcg_gen_not_tl(t1, t1);
1555
            tcg_gen_xor_tl(t2, t0, t2);
1556
            tcg_gen_and_tl(t1, t1, t2);
1557
            tcg_temp_free(t2);
1558
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1559
            tcg_temp_free(t1);
1560
            /* operands of same sign, result different sign */
1561
            generate_exception(ctx, EXCP_OVERFLOW);
1562
            gen_set_label(l1);
1563
            gen_store_gpr(t0, rd);
1564
            tcg_temp_free(t0);
1565
        }
1566
        opn = "dadd";
1567
        break;
1568
    case OPC_DADDU:
1569
        if (rs != 0 && rt != 0) {
1570
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1571
        } else if (rs == 0 && rt != 0) {
1572
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1573
        } else if (rs != 0 && rt == 0) {
1574
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1575
        } else {
1576
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1577
        }
1578
        opn = "daddu";
1579
        break;
1580
    case OPC_DSUB:
1581
        {
1582
            TCGv t0 = tcg_temp_local_new();
1583
            TCGv t1 = tcg_temp_new();
1584
            TCGv t2 = tcg_temp_new();
1585
            int l1 = gen_new_label();
1586

    
1587
            gen_load_gpr(t1, rs);
1588
            gen_load_gpr(t2, rt);
1589
            tcg_gen_sub_tl(t0, t1, t2);
1590
            tcg_gen_xor_tl(t2, t1, t2);
1591
            tcg_gen_xor_tl(t1, t0, t1);
1592
            tcg_gen_and_tl(t1, t1, t2);
1593
            tcg_temp_free(t2);
1594
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1595
            tcg_temp_free(t1);
1596
            /* operands of same sign, result different sign */
1597
            generate_exception(ctx, EXCP_OVERFLOW);
1598
            gen_set_label(l1);
1599
            gen_store_gpr(t0, rd);
1600
            tcg_temp_free(t0);
1601
        }
1602
        opn = "dsub";
1603
        break;
1604
    case OPC_DSUBU:
1605
        if (rs != 0 && rt != 0) {
1606
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1607
        } else if (rs == 0 && rt != 0) {
1608
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1609
        } else if (rs != 0 && rt == 0) {
1610
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1611
        } else {
1612
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1613
        }
1614
        opn = "dsubu";
1615
        break;
1616
#endif
1617
    case OPC_MUL:
1618
        if (likely(rs != 0 && rt != 0)) {
1619
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1620
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1621
        } else {
1622
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1623
        }
1624
        opn = "mul";
1625
        break;
1626
    }
1627
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1628
}
1629

    
1630
/* Conditional move */
1631
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1632
{
1633
    const char *opn = "cond move";
1634
    int l1;
1635

    
1636
    if (rd == 0) {
1637
        /* If no destination, treat it as a NOP.
1638
           For add & sub, we must generate the overflow exception when needed. */
1639
        MIPS_DEBUG("NOP");
1640
        return;
1641
    }
1642

    
1643
    l1 = gen_new_label();
1644
    switch (opc) {
1645
    case OPC_MOVN:
1646
        if (likely(rt != 0))
1647
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1648
        else
1649
            tcg_gen_br(l1);
1650
        opn = "movn";
1651
        break;
1652
    case OPC_MOVZ:
1653
        if (likely(rt != 0))
1654
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1655
        opn = "movz";
1656
        break;
1657
    }
1658
    if (rs != 0)
1659
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1660
    else
1661
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1662
    gen_set_label(l1);
1663

    
1664
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1665
}
1666

    
1667
/* Logic */
1668
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1669
{
1670
    const char *opn = "logic";
1671

    
1672
    if (rd == 0) {
1673
        /* If no destination, treat it as a NOP. */
1674
        MIPS_DEBUG("NOP");
1675
        return;
1676
    }
1677

    
1678
    switch (opc) {
1679
    case OPC_AND:
1680
        if (likely(rs != 0 && rt != 0)) {
1681
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1682
        } else {
1683
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1684
        }
1685
        opn = "and";
1686
        break;
1687
    case OPC_NOR:
1688
        if (rs != 0 && rt != 0) {
1689
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1690
        } else if (rs == 0 && rt != 0) {
1691
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1692
        } else if (rs != 0 && rt == 0) {
1693
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1694
        } else {
1695
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1696
        }
1697
        opn = "nor";
1698
        break;
1699
    case OPC_OR:
1700
        if (likely(rs != 0 && rt != 0)) {
1701
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1702
        } else if (rs == 0 && rt != 0) {
1703
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1704
        } else if (rs != 0 && rt == 0) {
1705
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1706
        } else {
1707
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1708
        }
1709
        opn = "or";
1710
        break;
1711
    case OPC_XOR:
1712
        if (likely(rs != 0 && rt != 0)) {
1713
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1714
        } else if (rs == 0 && rt != 0) {
1715
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1716
        } else if (rs != 0 && rt == 0) {
1717
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1718
        } else {
1719
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1720
        }
1721
        opn = "xor";
1722
        break;
1723
    }
1724
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1725
}
1726

    
1727
/* Set on lower than */
1728
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1729
{
1730
    const char *opn = "slt";
1731
    TCGv t0, t1;
1732

    
1733
    if (rd == 0) {
1734
        /* If no destination, treat it as a NOP. */
1735
        MIPS_DEBUG("NOP");
1736
        return;
1737
    }
1738

    
1739
    t0 = tcg_temp_new();
1740
    t1 = tcg_temp_new();
1741
    gen_load_gpr(t0, rs);
1742
    gen_load_gpr(t1, rt);
1743
    switch (opc) {
1744
    case OPC_SLT:
1745
        gen_op_lt(cpu_gpr[rd], t0, t1);
1746
        opn = "slt";
1747
        break;
1748
    case OPC_SLTU:
1749
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1750
        opn = "sltu";
1751
        break;
1752
    }
1753
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1754
    tcg_temp_free(t0);
1755
    tcg_temp_free(t1);
1756
}
1757

    
1758
/* Shifts */
1759
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1760
                       int rd, int rs, int rt)
1761
{
1762
    const char *opn = "shifts";
1763
    TCGv t0, t1;
1764

    
1765
    if (rd == 0) {
1766
        /* If no destination, treat it as a NOP.
1767
           For add & sub, we must generate the overflow exception when needed. */
1768
        MIPS_DEBUG("NOP");
1769
        return;
1770
    }
1771

    
1772
    t0 = tcg_temp_new();
1773
    t1 = tcg_temp_new();
1774
    gen_load_gpr(t0, rs);
1775
    gen_load_gpr(t1, rt);
1776
    switch (opc) {
1777
    case OPC_SLLV:
1778
        tcg_gen_andi_tl(t0, t0, 0x1f);
1779
        tcg_gen_shl_tl(t0, t1, t0);
1780
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1781
        opn = "sllv";
1782
        break;
1783
    case OPC_SRAV:
1784
        tcg_gen_ext32s_tl(t1, t1);
1785
        tcg_gen_andi_tl(t0, t0, 0x1f);
1786
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1787
        opn = "srav";
1788
        break;
1789
    case OPC_SRLV:
1790
        switch ((ctx->opcode >> 6) & 0x1f) {
1791
        case 0:
1792
            tcg_gen_ext32u_tl(t1, t1);
1793
            tcg_gen_andi_tl(t0, t0, 0x1f);
1794
            tcg_gen_shr_tl(t0, t1, t0);
1795
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1796
            opn = "srlv";
1797
            break;
1798
        case 1:
1799
            /* rotrv is decoded as srlv on non-R2 CPUs */
1800
            if (env->insn_flags & ISA_MIPS32R2) {
1801
                TCGv_i32 t2 = tcg_temp_new_i32();
1802
                TCGv_i32 t3 = tcg_temp_new_i32();
1803

    
1804
                tcg_gen_trunc_tl_i32(t2, t0);
1805
                tcg_gen_trunc_tl_i32(t3, t1);
1806
                tcg_gen_andi_i32(t2, t2, 0x1f);
1807
                tcg_gen_rotr_i32(t2, t3, t2);
1808
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1809
                tcg_temp_free_i32(t2);
1810
                tcg_temp_free_i32(t3);
1811
                opn = "rotrv";
1812
            } else {
1813
                tcg_gen_ext32u_tl(t1, t1);
1814
                tcg_gen_andi_tl(t0, t0, 0x1f);
1815
                tcg_gen_shr_tl(t0, t1, t0);
1816
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1817
                opn = "srlv";
1818
            }
1819
            break;
1820
        default:
1821
            MIPS_INVAL("invalid srlv flag");
1822
            generate_exception(ctx, EXCP_RI);
1823
            break;
1824
        }
1825
        break;
1826
#if defined(TARGET_MIPS64)
1827
    case OPC_DSLLV:
1828
        tcg_gen_andi_tl(t0, t0, 0x3f);
1829
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1830
        opn = "dsllv";
1831
        break;
1832
    case OPC_DSRAV:
1833
        tcg_gen_andi_tl(t0, t0, 0x3f);
1834
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1835
        opn = "dsrav";
1836
        break;
1837
    case OPC_DSRLV:
1838
        switch ((ctx->opcode >> 6) & 0x1f) {
1839
        case 0:
1840
            tcg_gen_andi_tl(t0, t0, 0x3f);
1841
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1842
            opn = "dsrlv";
1843
            break;
1844
        case 1:
1845
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1846
            if (env->insn_flags & ISA_MIPS32R2) {
1847
                tcg_gen_andi_tl(t0, t0, 0x3f);
1848
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1849
                opn = "drotrv";
1850
            } else {
1851
                tcg_gen_andi_tl(t0, t0, 0x3f);
1852
                tcg_gen_shr_tl(t0, t1, t0);
1853
                opn = "dsrlv";
1854
            }
1855
            break;
1856
        default:
1857
            MIPS_INVAL("invalid dsrlv flag");
1858
            generate_exception(ctx, EXCP_RI);
1859
            break;
1860
        }
1861
        break;
1862
#endif
1863
    }
1864
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1865
    tcg_temp_free(t0);
1866
    tcg_temp_free(t1);
1867
}
1868

    
1869
/* Arithmetic on HI/LO registers */
1870
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1871
{
1872
    const char *opn = "hilo";
1873

    
1874
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1875
        /* Treat as NOP. */
1876
        MIPS_DEBUG("NOP");
1877
        return;
1878
    }
1879
    switch (opc) {
1880
    case OPC_MFHI:
1881
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1882
        opn = "mfhi";
1883
        break;
1884
    case OPC_MFLO:
1885
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1886
        opn = "mflo";
1887
        break;
1888
    case OPC_MTHI:
1889
        if (reg != 0)
1890
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1891
        else
1892
            tcg_gen_movi_tl(cpu_HI[0], 0);
1893
        opn = "mthi";
1894
        break;
1895
    case OPC_MTLO:
1896
        if (reg != 0)
1897
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1898
        else
1899
            tcg_gen_movi_tl(cpu_LO[0], 0);
1900
        opn = "mtlo";
1901
        break;
1902
    }
1903
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1904
}
1905

    
1906
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1907
                        int rs, int rt)
1908
{
1909
    const char *opn = "mul/div";
1910
    TCGv t0, t1;
1911

    
1912
    switch (opc) {
1913
    case OPC_DIV:
1914
    case OPC_DIVU:
1915
#if defined(TARGET_MIPS64)
1916
    case OPC_DDIV:
1917
    case OPC_DDIVU:
1918
#endif
1919
        t0 = tcg_temp_local_new();
1920
        t1 = tcg_temp_local_new();
1921
        break;
1922
    default:
1923
        t0 = tcg_temp_new();
1924
        t1 = tcg_temp_new();
1925
        break;
1926
    }
1927

    
1928
    gen_load_gpr(t0, rs);
1929
    gen_load_gpr(t1, rt);
1930
    switch (opc) {
1931
    case OPC_DIV:
1932
        {
1933
            int l1 = gen_new_label();
1934
            int l2 = gen_new_label();
1935

    
1936
            tcg_gen_ext32s_tl(t0, t0);
1937
            tcg_gen_ext32s_tl(t1, t1);
1938
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1939
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1940
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1941

    
1942
            tcg_gen_mov_tl(cpu_LO[0], t0);
1943
            tcg_gen_movi_tl(cpu_HI[0], 0);
1944
            tcg_gen_br(l1);
1945
            gen_set_label(l2);
1946
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1947
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1948
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1949
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1950
            gen_set_label(l1);
1951
        }
1952
        opn = "div";
1953
        break;
1954
    case OPC_DIVU:
1955
        {
1956
            int l1 = gen_new_label();
1957

    
1958
            tcg_gen_ext32u_tl(t0, t0);
1959
            tcg_gen_ext32u_tl(t1, t1);
1960
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1961
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1962
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1963
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1964
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1965
            gen_set_label(l1);
1966
        }
1967
        opn = "divu";
1968
        break;
1969
    case OPC_MULT:
1970
        {
1971
            TCGv_i64 t2 = tcg_temp_new_i64();
1972
            TCGv_i64 t3 = tcg_temp_new_i64();
1973

    
1974
            tcg_gen_ext_tl_i64(t2, t0);
1975
            tcg_gen_ext_tl_i64(t3, t1);
1976
            tcg_gen_mul_i64(t2, t2, t3);
1977
            tcg_temp_free_i64(t3);
1978
            tcg_gen_trunc_i64_tl(t0, t2);
1979
            tcg_gen_shri_i64(t2, t2, 32);
1980
            tcg_gen_trunc_i64_tl(t1, t2);
1981
            tcg_temp_free_i64(t2);
1982
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1983
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1984
        }
1985
        opn = "mult";
1986
        break;
1987
    case OPC_MULTU:
1988
        {
1989
            TCGv_i64 t2 = tcg_temp_new_i64();
1990
            TCGv_i64 t3 = tcg_temp_new_i64();
1991

    
1992
            tcg_gen_ext32u_tl(t0, t0);
1993
            tcg_gen_ext32u_tl(t1, t1);
1994
            tcg_gen_extu_tl_i64(t2, t0);
1995
            tcg_gen_extu_tl_i64(t3, t1);
1996
            tcg_gen_mul_i64(t2, t2, t3);
1997
            tcg_temp_free_i64(t3);
1998
            tcg_gen_trunc_i64_tl(t0, t2);
1999
            tcg_gen_shri_i64(t2, t2, 32);
2000
            tcg_gen_trunc_i64_tl(t1, t2);
2001
            tcg_temp_free_i64(t2);
2002
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2003
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2004
        }
2005
        opn = "multu";
2006
        break;
2007
#if defined(TARGET_MIPS64)
2008
    case OPC_DDIV:
2009
        {
2010
            int l1 = gen_new_label();
2011
            int l2 = gen_new_label();
2012

    
2013
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2014
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2015
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2016
            tcg_gen_mov_tl(cpu_LO[0], t0);
2017
            tcg_gen_movi_tl(cpu_HI[0], 0);
2018
            tcg_gen_br(l1);
2019
            gen_set_label(l2);
2020
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2021
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2022
            gen_set_label(l1);
2023
        }
2024
        opn = "ddiv";
2025
        break;
2026
    case OPC_DDIVU:
2027
        {
2028
            int l1 = gen_new_label();
2029

    
2030
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2031
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2032
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2033
            gen_set_label(l1);
2034
        }
2035
        opn = "ddivu";
2036
        break;
2037
    case OPC_DMULT:
2038
        gen_helper_dmult(t0, t1);
2039
        opn = "dmult";
2040
        break;
2041
    case OPC_DMULTU:
2042
        gen_helper_dmultu(t0, t1);
2043
        opn = "dmultu";
2044
        break;
2045
#endif
2046
    case OPC_MADD:
2047
        {
2048
            TCGv_i64 t2 = tcg_temp_new_i64();
2049
            TCGv_i64 t3 = tcg_temp_new_i64();
2050

    
2051
            tcg_gen_ext_tl_i64(t2, t0);
2052
            tcg_gen_ext_tl_i64(t3, t1);
2053
            tcg_gen_mul_i64(t2, t2, t3);
2054
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2055
            tcg_gen_add_i64(t2, t2, t3);
2056
            tcg_temp_free_i64(t3);
2057
            tcg_gen_trunc_i64_tl(t0, t2);
2058
            tcg_gen_shri_i64(t2, t2, 32);
2059
            tcg_gen_trunc_i64_tl(t1, t2);
2060
            tcg_temp_free_i64(t2);
2061
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2062
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
2063
        }
2064
        opn = "madd";
2065
        break;
2066
    case OPC_MADDU:
2067
       {
2068
            TCGv_i64 t2 = tcg_temp_new_i64();
2069
            TCGv_i64 t3 = tcg_temp_new_i64();
2070

    
2071
            tcg_gen_ext32u_tl(t0, t0);
2072
            tcg_gen_ext32u_tl(t1, t1);
2073
            tcg_gen_extu_tl_i64(t2, t0);
2074
            tcg_gen_extu_tl_i64(t3, t1);
2075
            tcg_gen_mul_i64(t2, t2, t3);
2076
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2077
            tcg_gen_add_i64(t2, t2, t3);
2078
            tcg_temp_free_i64(t3);
2079
            tcg_gen_trunc_i64_tl(t0, t2);
2080
            tcg_gen_shri_i64(t2, t2, 32);
2081
            tcg_gen_trunc_i64_tl(t1, t2);
2082
            tcg_temp_free_i64(t2);
2083
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2084
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2085
        }
2086
        opn = "maddu";
2087
        break;
2088
    case OPC_MSUB:
2089
        {
2090
            TCGv_i64 t2 = tcg_temp_new_i64();
2091
            TCGv_i64 t3 = tcg_temp_new_i64();
2092

    
2093
            tcg_gen_ext_tl_i64(t2, t0);
2094
            tcg_gen_ext_tl_i64(t3, t1);
2095
            tcg_gen_mul_i64(t2, t2, t3);
2096
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2097
            tcg_gen_sub_i64(t2, t2, t3);
2098
            tcg_temp_free_i64(t3);
2099
            tcg_gen_trunc_i64_tl(t0, t2);
2100
            tcg_gen_shri_i64(t2, t2, 32);
2101
            tcg_gen_trunc_i64_tl(t1, t2);
2102
            tcg_temp_free_i64(t2);
2103
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2104
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2105
        }
2106
        opn = "msub";
2107
        break;
2108
    case OPC_MSUBU:
2109
        {
2110
            TCGv_i64 t2 = tcg_temp_new_i64();
2111
            TCGv_i64 t3 = tcg_temp_new_i64();
2112

    
2113
            tcg_gen_ext32u_tl(t0, t0);
2114
            tcg_gen_ext32u_tl(t1, t1);
2115
            tcg_gen_extu_tl_i64(t2, t0);
2116
            tcg_gen_extu_tl_i64(t3, t1);
2117
            tcg_gen_mul_i64(t2, t2, t3);
2118
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2119
            tcg_gen_sub_i64(t2, t2, t3);
2120
            tcg_temp_free_i64(t3);
2121
            tcg_gen_trunc_i64_tl(t0, t2);
2122
            tcg_gen_shri_i64(t2, t2, 32);
2123
            tcg_gen_trunc_i64_tl(t1, t2);
2124
            tcg_temp_free_i64(t2);
2125
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2126
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2127
        }
2128
        opn = "msubu";
2129
        break;
2130
    default:
2131
        MIPS_INVAL(opn);
2132
        generate_exception(ctx, EXCP_RI);
2133
        goto out;
2134
    }
2135
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2136
 out:
2137
    tcg_temp_free(t0);
2138
    tcg_temp_free(t1);
2139
}
2140

    
2141
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2142
                            int rd, int rs, int rt)
2143
{
2144
    const char *opn = "mul vr54xx";
2145
    TCGv t0 = tcg_temp_new();
2146
    TCGv t1 = tcg_temp_new();
2147

    
2148
    gen_load_gpr(t0, rs);
2149
    gen_load_gpr(t1, rt);
2150

    
2151
    switch (opc) {
2152
    case OPC_VR54XX_MULS:
2153
        gen_helper_muls(t0, t0, t1);
2154
        opn = "muls";
2155
        break;
2156
    case OPC_VR54XX_MULSU:
2157
        gen_helper_mulsu(t0, t0, t1);
2158
        opn = "mulsu";
2159
        break;
2160
    case OPC_VR54XX_MACC:
2161
        gen_helper_macc(t0, t0, t1);
2162
        opn = "macc";
2163
        break;
2164
    case OPC_VR54XX_MACCU:
2165
        gen_helper_maccu(t0, t0, t1);
2166
        opn = "maccu";
2167
        break;
2168
    case OPC_VR54XX_MSAC:
2169
        gen_helper_msac(t0, t0, t1);
2170
        opn = "msac";
2171
        break;
2172
    case OPC_VR54XX_MSACU:
2173
        gen_helper_msacu(t0, t0, t1);
2174
        opn = "msacu";
2175
        break;
2176
    case OPC_VR54XX_MULHI:
2177
        gen_helper_mulhi(t0, t0, t1);
2178
        opn = "mulhi";
2179
        break;
2180
    case OPC_VR54XX_MULHIU:
2181
        gen_helper_mulhiu(t0, t0, t1);
2182
        opn = "mulhiu";
2183
        break;
2184
    case OPC_VR54XX_MULSHI:
2185
        gen_helper_mulshi(t0, t0, t1);
2186
        opn = "mulshi";
2187
        break;
2188
    case OPC_VR54XX_MULSHIU:
2189
        gen_helper_mulshiu(t0, t0, t1);
2190
        opn = "mulshiu";
2191
        break;
2192
    case OPC_VR54XX_MACCHI:
2193
        gen_helper_macchi(t0, t0, t1);
2194
        opn = "macchi";
2195
        break;
2196
    case OPC_VR54XX_MACCHIU:
2197
        gen_helper_macchiu(t0, t0, t1);
2198
        opn = "macchiu";
2199
        break;
2200
    case OPC_VR54XX_MSACHI:
2201
        gen_helper_msachi(t0, t0, t1);
2202
        opn = "msachi";
2203
        break;
2204
    case OPC_VR54XX_MSACHIU:
2205
        gen_helper_msachiu(t0, t0, t1);
2206
        opn = "msachiu";
2207
        break;
2208
    default:
2209
        MIPS_INVAL("mul vr54xx");
2210
        generate_exception(ctx, EXCP_RI);
2211
        goto out;
2212
    }
2213
    gen_store_gpr(t0, rd);
2214
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2215

    
2216
 out:
2217
    tcg_temp_free(t0);
2218
    tcg_temp_free(t1);
2219
}
2220

    
2221
static void gen_cl (DisasContext *ctx, uint32_t opc,
2222
                    int rd, int rs)
2223
{
2224
    const char *opn = "CLx";
2225
    TCGv t0;
2226

    
2227
    if (rd == 0) {
2228
        /* Treat as NOP. */
2229
        MIPS_DEBUG("NOP");
2230
        return;
2231
    }
2232
    t0 = tcg_temp_new();
2233
    gen_load_gpr(t0, rs);
2234
    switch (opc) {
2235
    case OPC_CLO:
2236
        gen_helper_clo(cpu_gpr[rd], t0);
2237
        opn = "clo";
2238
        break;
2239
    case OPC_CLZ:
2240
        gen_helper_clz(cpu_gpr[rd], t0);
2241
        opn = "clz";
2242
        break;
2243
#if defined(TARGET_MIPS64)
2244
    case OPC_DCLO:
2245
        gen_helper_dclo(cpu_gpr[rd], t0);
2246
        opn = "dclo";
2247
        break;
2248
    case OPC_DCLZ:
2249
        gen_helper_dclz(cpu_gpr[rd], t0);
2250
        opn = "dclz";
2251
        break;
2252
#endif
2253
    }
2254
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2255
    tcg_temp_free(t0);
2256
}
2257

    
2258
/* Traps */
2259
static void gen_trap (DisasContext *ctx, uint32_t opc,
2260
                      int rs, int rt, int16_t imm)
2261
{
2262
    int cond;
2263
    TCGv t0 = tcg_temp_new();
2264
    TCGv t1 = tcg_temp_new();
2265

    
2266
    cond = 0;
2267
    /* Load needed operands */
2268
    switch (opc) {
2269
    case OPC_TEQ:
2270
    case OPC_TGE:
2271
    case OPC_TGEU:
2272
    case OPC_TLT:
2273
    case OPC_TLTU:
2274
    case OPC_TNE:
2275
        /* Compare two registers */
2276
        if (rs != rt) {
2277
            gen_load_gpr(t0, rs);
2278
            gen_load_gpr(t1, rt);
2279
            cond = 1;
2280
        }
2281
        break;
2282
    case OPC_TEQI:
2283
    case OPC_TGEI:
2284
    case OPC_TGEIU:
2285
    case OPC_TLTI:
2286
    case OPC_TLTIU:
2287
    case OPC_TNEI:
2288
        /* Compare register to immediate */
2289
        if (rs != 0 || imm != 0) {
2290
            gen_load_gpr(t0, rs);
2291
            tcg_gen_movi_tl(t1, (int32_t)imm);
2292
            cond = 1;
2293
        }
2294
        break;
2295
    }
2296
    if (cond == 0) {
2297
        switch (opc) {
2298
        case OPC_TEQ:   /* rs == rs */
2299
        case OPC_TEQI:  /* r0 == 0  */
2300
        case OPC_TGE:   /* rs >= rs */
2301
        case OPC_TGEI:  /* r0 >= 0  */
2302
        case OPC_TGEU:  /* rs >= rs unsigned */
2303
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2304
            /* Always trap */
2305
            generate_exception(ctx, EXCP_TRAP);
2306
            break;
2307
        case OPC_TLT:   /* rs < rs           */
2308
        case OPC_TLTI:  /* r0 < 0            */
2309
        case OPC_TLTU:  /* rs < rs unsigned  */
2310
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2311
        case OPC_TNE:   /* rs != rs          */
2312
        case OPC_TNEI:  /* r0 != 0           */
2313
            /* Never trap: treat as NOP. */
2314
            break;
2315
        }
2316
    } else {
2317
        int l1 = gen_new_label();
2318

    
2319
        switch (opc) {
2320
        case OPC_TEQ:
2321
        case OPC_TEQI:
2322
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2323
            break;
2324
        case OPC_TGE:
2325
        case OPC_TGEI:
2326
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2327
            break;
2328
        case OPC_TGEU:
2329
        case OPC_TGEIU:
2330
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2331
            break;
2332
        case OPC_TLT:
2333
        case OPC_TLTI:
2334
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2335
            break;
2336
        case OPC_TLTU:
2337
        case OPC_TLTIU:
2338
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2339
            break;
2340
        case OPC_TNE:
2341
        case OPC_TNEI:
2342
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2343
            break;
2344
        }
2345
        generate_exception(ctx, EXCP_TRAP);
2346
        gen_set_label(l1);
2347
    }
2348
    tcg_temp_free(t0);
2349
    tcg_temp_free(t1);
2350
}
2351

    
2352
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2353
{
2354
    TranslationBlock *tb;
2355
    tb = ctx->tb;
2356
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2357
        tcg_gen_goto_tb(n);
2358
        gen_save_pc(dest);
2359
        tcg_gen_exit_tb((long)tb + n);
2360
    } else {
2361
        gen_save_pc(dest);
2362
        tcg_gen_exit_tb(0);
2363
    }
2364
}
2365

    
2366
/* Branches (before delay slot) */
2367
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2368
                                int rs, int rt, int32_t offset)
2369
{
2370
    target_ulong btgt = -1;
2371
    int blink = 0;
2372
    int bcond_compute = 0;
2373
    TCGv t0 = tcg_temp_new();
2374
    TCGv t1 = tcg_temp_new();
2375

    
2376
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2377
#ifdef MIPS_DEBUG_DISAS
2378
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2379
#endif
2380
        generate_exception(ctx, EXCP_RI);
2381
        goto out;
2382
    }
2383

    
2384
    /* Load needed operands */
2385
    switch (opc) {
2386
    case OPC_BEQ:
2387
    case OPC_BEQL:
2388
    case OPC_BNE:
2389
    case OPC_BNEL:
2390
        /* Compare two registers */
2391
        if (rs != rt) {
2392
            gen_load_gpr(t0, rs);
2393
            gen_load_gpr(t1, rt);
2394
            bcond_compute = 1;
2395
        }
2396
        btgt = ctx->pc + 4 + offset;
2397
        break;
2398
    case OPC_BGEZ:
2399
    case OPC_BGEZAL:
2400
    case OPC_BGEZALL:
2401
    case OPC_BGEZL:
2402
    case OPC_BGTZ:
2403
    case OPC_BGTZL:
2404
    case OPC_BLEZ:
2405
    case OPC_BLEZL:
2406
    case OPC_BLTZ:
2407
    case OPC_BLTZAL:
2408
    case OPC_BLTZALL:
2409
    case OPC_BLTZL:
2410
        /* Compare to zero */
2411
        if (rs != 0) {
2412
            gen_load_gpr(t0, rs);
2413
            bcond_compute = 1;
2414
        }
2415
        btgt = ctx->pc + 4 + offset;
2416
        break;
2417
    case OPC_J:
2418
    case OPC_JAL:
2419
        /* Jump to immediate */
2420
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2421
        break;
2422
    case OPC_JR:
2423
    case OPC_JALR:
2424
        /* Jump to register */
2425
        if (offset != 0 && offset != 16) {
2426
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2427
               others are reserved. */
2428
            MIPS_INVAL("jump hint");
2429
            generate_exception(ctx, EXCP_RI);
2430
            goto out;
2431
        }
2432
        gen_load_gpr(btarget, rs);
2433
        break;
2434
    default:
2435
        MIPS_INVAL("branch/jump");
2436
        generate_exception(ctx, EXCP_RI);
2437
        goto out;
2438
    }
2439
    if (bcond_compute == 0) {
2440
        /* No condition to be computed */
2441
        switch (opc) {
2442
        case OPC_BEQ:     /* rx == rx        */
2443
        case OPC_BEQL:    /* rx == rx likely */
2444
        case OPC_BGEZ:    /* 0 >= 0          */
2445
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2446
        case OPC_BLEZ:    /* 0 <= 0          */
2447
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2448
            /* Always take */
2449
            ctx->hflags |= MIPS_HFLAG_B;
2450
            MIPS_DEBUG("balways");
2451
            break;
2452
        case OPC_BGEZAL:  /* 0 >= 0          */
2453
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2454
            /* Always take and link */
2455
            blink = 31;
2456
            ctx->hflags |= MIPS_HFLAG_B;
2457
            MIPS_DEBUG("balways and link");
2458
            break;
2459
        case OPC_BNE:     /* rx != rx        */
2460
        case OPC_BGTZ:    /* 0 > 0           */
2461
        case OPC_BLTZ:    /* 0 < 0           */
2462
            /* Treat as NOP. */
2463
            MIPS_DEBUG("bnever (NOP)");
2464
            goto out;
2465
        case OPC_BLTZAL:  /* 0 < 0           */
2466
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2467
            MIPS_DEBUG("bnever and link");
2468
            goto out;
2469
        case OPC_BLTZALL: /* 0 < 0 likely */
2470
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2471
            /* Skip the instruction in the delay slot */
2472
            MIPS_DEBUG("bnever, link and skip");
2473
            ctx->pc += 4;
2474
            goto out;
2475
        case OPC_BNEL:    /* rx != rx likely */
2476
        case OPC_BGTZL:   /* 0 > 0 likely */
2477
        case OPC_BLTZL:   /* 0 < 0 likely */
2478
            /* Skip the instruction in the delay slot */
2479
            MIPS_DEBUG("bnever and skip");
2480
            ctx->pc += 4;
2481
            goto out;
2482
        case OPC_J:
2483
            ctx->hflags |= MIPS_HFLAG_B;
2484
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2485
            break;
2486
        case OPC_JAL:
2487
            blink = 31;
2488
            ctx->hflags |= MIPS_HFLAG_B;
2489
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2490
            break;
2491
        case OPC_JR:
2492
            ctx->hflags |= MIPS_HFLAG_BR;
2493
            MIPS_DEBUG("jr %s", regnames[rs]);
2494
            break;
2495
        case OPC_JALR:
2496
            blink = rt;
2497
            ctx->hflags |= MIPS_HFLAG_BR;
2498
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2499
            break;
2500
        default:
2501
            MIPS_INVAL("branch/jump");
2502
            generate_exception(ctx, EXCP_RI);
2503
            goto out;
2504
        }
2505
    } else {
2506
        switch (opc) {
2507
        case OPC_BEQ:
2508
            gen_op_eq(bcond, t0, t1);
2509
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2510
                       regnames[rs], regnames[rt], btgt);
2511
            goto not_likely;
2512
        case OPC_BEQL:
2513
            gen_op_eq(bcond, t0, t1);
2514
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2515
                       regnames[rs], regnames[rt], btgt);
2516
            goto likely;
2517
        case OPC_BNE:
2518
            gen_op_ne(bcond, t0, t1);
2519
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2520
                       regnames[rs], regnames[rt], btgt);
2521
            goto not_likely;
2522
        case OPC_BNEL:
2523
            gen_op_ne(bcond, t0, t1);
2524
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2525
                       regnames[rs], regnames[rt], btgt);
2526
            goto likely;
2527
        case OPC_BGEZ:
2528
            gen_op_gez(bcond, t0);
2529
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2530
            goto not_likely;
2531
        case OPC_BGEZL:
2532
            gen_op_gez(bcond, t0);
2533
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2534
            goto likely;
2535
        case OPC_BGEZAL:
2536
            gen_op_gez(bcond, t0);
2537
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2538
            blink = 31;
2539
            goto not_likely;
2540
        case OPC_BGEZALL:
2541
            gen_op_gez(bcond, t0);
2542
            blink = 31;
2543
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2544
            goto likely;
2545
        case OPC_BGTZ:
2546
            gen_op_gtz(bcond, t0);
2547
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2548
            goto not_likely;
2549
        case OPC_BGTZL:
2550
            gen_op_gtz(bcond, t0);
2551
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2552
            goto likely;
2553
        case OPC_BLEZ:
2554
            gen_op_lez(bcond, t0);
2555
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2556
            goto not_likely;
2557
        case OPC_BLEZL:
2558
            gen_op_lez(bcond, t0);
2559
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2560
            goto likely;
2561
        case OPC_BLTZ:
2562
            gen_op_ltz(bcond, t0);
2563
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2564
            goto not_likely;
2565
        case OPC_BLTZL:
2566
            gen_op_ltz(bcond, t0);
2567
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2568
            goto likely;
2569
        case OPC_BLTZAL:
2570
            gen_op_ltz(bcond, t0);
2571
            blink = 31;
2572
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2573
        not_likely:
2574
            ctx->hflags |= MIPS_HFLAG_BC;
2575
            break;
2576
        case OPC_BLTZALL:
2577
            gen_op_ltz(bcond, t0);
2578
            blink = 31;
2579
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2580
        likely:
2581
            ctx->hflags |= MIPS_HFLAG_BL;
2582
            break;
2583
        default:
2584
            MIPS_INVAL("conditional branch/jump");
2585
            generate_exception(ctx, EXCP_RI);
2586
            goto out;
2587
        }
2588
    }
2589
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2590
               blink, ctx->hflags, btgt);
2591

    
2592
    ctx->btarget = btgt;
2593
    if (blink > 0) {
2594
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2595
    }
2596

    
2597
 out:
2598
    tcg_temp_free(t0);
2599
    tcg_temp_free(t1);
2600
}
2601

    
2602
/* special3 bitfield operations */
2603
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2604
                        int rs, int lsb, int msb)
2605
{
2606
    TCGv t0 = tcg_temp_new();
2607
    TCGv t1 = tcg_temp_new();
2608
    target_ulong mask;
2609

    
2610
    gen_load_gpr(t1, rs);
2611
    switch (opc) {
2612
    case OPC_EXT:
2613
        if (lsb + msb > 31)
2614
            goto fail;
2615
        tcg_gen_shri_tl(t0, t1, lsb);
2616
        if (msb != 31) {
2617
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2618
        } else {
2619
            tcg_gen_ext32s_tl(t0, t0);
2620
        }
2621
        break;
2622
#if defined(TARGET_MIPS64)
2623
    case OPC_DEXTM:
2624
        tcg_gen_shri_tl(t0, t1, lsb);
2625
        if (msb != 31) {
2626
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2627
        }
2628
        break;
2629
    case OPC_DEXTU:
2630
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2631
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2632
        break;
2633
    case OPC_DEXT:
2634
        tcg_gen_shri_tl(t0, t1, lsb);
2635
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2636
        break;
2637
#endif
2638
    case OPC_INS:
2639
        if (lsb > msb)
2640
            goto fail;
2641
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2642
        gen_load_gpr(t0, rt);
2643
        tcg_gen_andi_tl(t0, t0, ~mask);
2644
        tcg_gen_shli_tl(t1, t1, lsb);
2645
        tcg_gen_andi_tl(t1, t1, mask);
2646
        tcg_gen_or_tl(t0, t0, t1);
2647
        tcg_gen_ext32s_tl(t0, t0);
2648
        break;
2649
#if defined(TARGET_MIPS64)
2650
    case OPC_DINSM:
2651
        if (lsb > msb)
2652
            goto fail;
2653
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2654
        gen_load_gpr(t0, rt);
2655
        tcg_gen_andi_tl(t0, t0, ~mask);
2656
        tcg_gen_shli_tl(t1, t1, lsb);
2657
        tcg_gen_andi_tl(t1, t1, mask);
2658
        tcg_gen_or_tl(t0, t0, t1);
2659
        break;
2660
    case OPC_DINSU:
2661
        if (lsb > msb)
2662
            goto fail;
2663
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2664
        gen_load_gpr(t0, rt);
2665
        tcg_gen_andi_tl(t0, t0, ~mask);
2666
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2667
        tcg_gen_andi_tl(t1, t1, mask);
2668
        tcg_gen_or_tl(t0, t0, t1);
2669
        break;
2670
    case OPC_DINS:
2671
        if (lsb > msb)
2672
            goto fail;
2673
        gen_load_gpr(t0, rt);
2674
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2675
        gen_load_gpr(t0, rt);
2676
        tcg_gen_andi_tl(t0, t0, ~mask);
2677
        tcg_gen_shli_tl(t1, t1, lsb);
2678
        tcg_gen_andi_tl(t1, t1, mask);
2679
        tcg_gen_or_tl(t0, t0, t1);
2680
        break;
2681
#endif
2682
    default:
2683
fail:
2684
        MIPS_INVAL("bitops");
2685
        generate_exception(ctx, EXCP_RI);
2686
        tcg_temp_free(t0);
2687
        tcg_temp_free(t1);
2688
        return;
2689
    }
2690
    gen_store_gpr(t0, rt);
2691
    tcg_temp_free(t0);
2692
    tcg_temp_free(t1);
2693
}
2694

    
2695
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2696
{
2697
    TCGv t0;
2698

    
2699
    if (rd == 0) {
2700
        /* If no destination, treat it as a NOP. */
2701
        MIPS_DEBUG("NOP");
2702
        return;
2703
    }
2704

    
2705
    t0 = tcg_temp_new();
2706
    gen_load_gpr(t0, rt);
2707
    switch (op2) {
2708
    case OPC_WSBH:
2709
        {
2710
            TCGv t1 = tcg_temp_new();
2711

    
2712
            tcg_gen_shri_tl(t1, t0, 8);
2713
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2714
            tcg_gen_shli_tl(t0, t0, 8);
2715
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2716
            tcg_gen_or_tl(t0, t0, t1);
2717
            tcg_temp_free(t1);
2718
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2719
        }
2720
        break;
2721
    case OPC_SEB:
2722
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2723
        break;
2724
    case OPC_SEH:
2725
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2726
        break;
2727
#if defined(TARGET_MIPS64)
2728
    case OPC_DSBH:
2729
        {
2730
            TCGv t1 = tcg_temp_new();
2731

    
2732
            tcg_gen_shri_tl(t1, t0, 8);
2733
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2734
            tcg_gen_shli_tl(t0, t0, 8);
2735
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2736
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2737
            tcg_temp_free(t1);
2738
        }
2739
        break;
2740
    case OPC_DSHD:
2741
        {
2742
            TCGv t1 = tcg_temp_new();
2743

    
2744
            tcg_gen_shri_tl(t1, t0, 16);
2745
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2746
            tcg_gen_shli_tl(t0, t0, 16);
2747
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2748
            tcg_gen_or_tl(t0, t0, t1);
2749
            tcg_gen_shri_tl(t1, t0, 32);
2750
            tcg_gen_shli_tl(t0, t0, 32);
2751
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2752
            tcg_temp_free(t1);
2753
        }
2754
        break;
2755
#endif
2756
    default:
2757
        MIPS_INVAL("bsfhl");
2758
        generate_exception(ctx, EXCP_RI);
2759
        tcg_temp_free(t0);
2760
        return;
2761
    }
2762
    tcg_temp_free(t0);
2763
}
2764

    
2765
#ifndef CONFIG_USER_ONLY
2766
/* CP0 (MMU and control) */
2767
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2768
{
2769
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2770

    
2771
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2772
    tcg_gen_ext_i32_tl(t, r_tmp);
2773
    tcg_temp_free_i32(r_tmp);
2774
}
2775

    
2776
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2777
{
2778
    tcg_gen_ld_tl(t, cpu_env, off);
2779
    tcg_gen_ext32s_tl(t, t);
2780
}
2781

    
2782
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2783
{
2784
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2785

    
2786
    tcg_gen_trunc_tl_i32(r_tmp, t);
2787
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2788
    tcg_temp_free_i32(r_tmp);
2789
}
2790

    
2791
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2792
{
2793
    tcg_gen_ext32s_tl(t, t);
2794
    tcg_gen_st_tl(t, cpu_env, off);
2795
}
2796

    
2797
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2798
{
2799
    const char *rn = "invalid";
2800

    
2801
    if (sel != 0)
2802
        check_insn(env, ctx, ISA_MIPS32);
2803

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

    
3369
die:
3370
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3371
    generate_exception(ctx, EXCP_RI);
3372
}
3373

    
3374
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3375
{
3376
    const char *rn = "invalid";
3377

    
3378
    if (sel != 0)
3379
        check_insn(env, ctx, ISA_MIPS32);
3380

    
3381
    if (use_icount)
3382
        gen_io_start();
3383

    
3384
    switch (reg) {
3385
    case 0:
3386
        switch (sel) {
3387
        case 0:
3388
            gen_helper_mtc0_index(t0);
3389
            rn = "Index";
3390
            break;
3391
        case 1:
3392
            check_insn(env, ctx, ASE_MT);
3393
            gen_helper_mtc0_mvpcontrol(t0);
3394
            rn = "MVPControl";
3395
            break;
3396
        case 2:
3397
            check_insn(env, ctx, ASE_MT);
3398
            /* ignored */
3399
            rn = "MVPConf0";
3400
            break;
3401
        case 3:
3402
            check_insn(env, ctx, ASE_MT);
3403
            /* ignored */
3404
            rn = "MVPConf1";
3405
            break;
3406
        default:
3407
            goto die;
3408
        }
3409
        break;
3410
    case 1:
3411
        switch (sel) {
3412
        case 0:
3413
            /* ignored */
3414
            rn = "Random";
3415
            break;
3416
        case 1:
3417
            check_insn(env, ctx, ASE_MT);
3418
            gen_helper_mtc0_vpecontrol(t0);
3419
            rn = "VPEControl";
3420
            break;
3421
        case 2:
3422
            check_insn(env, ctx, ASE_MT);
3423
            gen_helper_mtc0_vpeconf0(t0);
3424
            rn = "VPEConf0";
3425
            break;
3426
        case 3:
3427
            check_insn(env, ctx, ASE_MT);
3428
            gen_helper_mtc0_vpeconf1(t0);
3429
            rn = "VPEConf1";
3430
            break;
3431
        case 4:
3432
            check_insn(env, ctx, ASE_MT);
3433
            gen_helper_mtc0_yqmask(t0);
3434
            rn = "YQMask";
3435
            break;
3436
        case 5:
3437
            check_insn(env, ctx, ASE_MT);
3438
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3439
            rn = "VPESchedule";
3440
            break;
3441
        case 6:
3442
            check_insn(env, ctx, ASE_MT);
3443
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3444
            rn = "VPEScheFBack";
3445
            break;
3446
        case 7:
3447
            check_insn(env, ctx, ASE_MT);
3448
            gen_helper_mtc0_vpeopt(t0);
3449
            rn = "VPEOpt";
3450
            break;
3451
        default:
3452
            goto die;
3453
        }
3454
        break;
3455
    case 2:
3456
        switch (sel) {
3457
        case 0:
3458
            gen_helper_mtc0_entrylo0(t0);
3459
            rn = "EntryLo0";
3460
            break;
3461
        case 1:
3462
            check_insn(env, ctx, ASE_MT);
3463
            gen_helper_mtc0_tcstatus(t0);
3464
            rn = "TCStatus";
3465
            break;
3466
        case 2:
3467
            check_insn(env, ctx, ASE_MT);
3468
            gen_helper_mtc0_tcbind(t0);
3469
            rn = "TCBind";
3470
            break;
3471
        case 3:
3472
            check_insn(env, ctx, ASE_MT);
3473
            gen_helper_mtc0_tcrestart(t0);
3474
            rn = "TCRestart";
3475
            break;
3476
        case 4:
3477
            check_insn(env, ctx, ASE_MT);
3478
            gen_helper_mtc0_tchalt(t0);
3479
            rn = "TCHalt";
3480
            break;
3481
        case 5:
3482
            check_insn(env, ctx, ASE_MT);
3483
            gen_helper_mtc0_tccontext(t0);
3484
            rn = "TCContext";
3485
            break;
3486
        case 6:
3487
            check_insn(env, ctx, ASE_MT);
3488
            gen_helper_mtc0_tcschedule(t0);
3489
            rn = "TCSchedule";
3490
            break;
3491
        case 7:
3492
            check_insn(env, ctx, ASE_MT);
3493
            gen_helper_mtc0_tcschefback(t0);
3494
            rn = "TCScheFBack";
3495
            break;
3496
        default:
3497
            goto die;
3498
        }
3499
        break;
3500
    case 3:
3501
        switch (sel) {
3502
        case 0:
3503
            gen_helper_mtc0_entrylo1(t0);
3504
            rn = "EntryLo1";
3505
            break;
3506
        default:
3507
            goto die;
3508
        }
3509
        break;
3510
    case 4:
3511
        switch (sel) {
3512
        case 0:
3513
            gen_helper_mtc0_context(t0);
3514
            rn = "Context";
3515
            break;
3516
        case 1:
3517
//            gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
3518
            rn = "ContextConfig";
3519
//            break;
3520
        default:
3521
            goto die;
3522
        }
3523
        break;
3524
    case 5:
3525
        switch (sel) {
3526
        case 0:
3527
            gen_helper_mtc0_pagemask(t0);
3528
            rn = "PageMask";
3529
            break;
3530
        case 1:
3531
            check_insn(env, ctx, ISA_MIPS32R2);
3532
            gen_helper_mtc0_pagegrain(t0);
3533
            rn = "PageGrain";
3534
            break;
3535
        default:
3536
            goto die;
3537
        }
3538
        break;
3539
    case 6:
3540
        switch (sel) {
3541
        case 0:
3542
            gen_helper_mtc0_wired(t0);
3543
            rn = "Wired";
3544
            break;
3545
        case 1:
3546
            check_insn(env, ctx, ISA_MIPS32R2);
3547
            gen_helper_mtc0_srsconf0(t0);
3548
            rn = "SRSConf0";
3549
            break;
3550
        case 2:
3551
            check_insn(env, ctx, ISA_MIPS32R2);
3552
            gen_helper_mtc0_srsconf1(t0);
3553
            rn = "SRSConf1";
3554
            break;
3555
        case 3:
3556
            check_insn(env, ctx, ISA_MIPS32R2);
3557
            gen_helper_mtc0_srsconf2(t0);
3558
            rn = "SRSConf2";
3559
            break;
3560
        case 4:
3561
            check_insn(env, ctx, ISA_MIPS32R2);
3562
            gen_helper_mtc0_srsconf3(t0);
3563
            rn = "SRSConf3";
3564
            break;
3565
        case 5:
3566
            check_insn(env, ctx, ISA_MIPS32R2);
3567
            gen_helper_mtc0_srsconf4(t0);
3568
            rn = "SRSConf4";
3569
            break;
3570
        default:
3571
            goto die;
3572
        }
3573
        break;
3574
    case 7:
3575
        switch (sel) {
3576
        case 0:
3577
            check_insn(env, ctx, ISA_MIPS32R2);
3578
            gen_helper_mtc0_hwrena(t0);
3579
            rn = "HWREna";
3580
            break;
3581
        default:
3582
            goto die;
3583
        }
3584
        break;
3585
    case 8:
3586
        /* ignored */
3587
        rn = "BadVAddr";
3588
        break;
3589
    case 9:
3590
        switch (sel) {
3591
        case 0:
3592
            gen_helper_mtc0_count(t0);
3593
            rn = "Count";
3594
            break;
3595
        /* 6,7 are implementation dependent */
3596
        default:
3597
            goto die;
3598
        }
3599
        break;
3600
    case 10:
3601
        switch (sel) {
3602
        case 0:
3603
            gen_helper_mtc0_entryhi(t0);
3604
            rn = "EntryHi";
3605
            break;
3606
        default:
3607
            goto die;
3608
        }
3609
        break;
3610
    case 11:
3611
        switch (sel) {
3612
        case 0:
3613
            gen_helper_mtc0_compare(t0);
3614
            rn = "Compare";
3615
            break;
3616
        /* 6,7 are implementation dependent */
3617
        default:
3618
            goto die;
3619
        }
3620
        break;
3621
    case 12:
3622
        switch (sel) {
3623
        case 0:
3624
            gen_helper_mtc0_status(t0);
3625
            /* BS_STOP isn't good enough here, hflags may have changed. */
3626
            gen_save_pc(ctx->pc + 4);
3627
            ctx->bstate = BS_EXCP;
3628
            rn = "Status";
3629
            break;
3630
        case 1:
3631
            check_insn(env, ctx, ISA_MIPS32R2);
3632
            gen_helper_mtc0_intctl(t0);
3633
            /* Stop translation as we may have switched the execution mode */
3634
            ctx->bstate = BS_STOP;
3635
            rn = "IntCtl";
3636
            break;
3637
        case 2:
3638
            check_insn(env, ctx, ISA_MIPS32R2);
3639
            gen_helper_mtc0_srsctl(t0);
3640
            /* Stop translation as we may have switched the execution mode */
3641
            ctx->bstate = BS_STOP;
3642
            rn = "SRSCtl";
3643
            break;
3644
        case 3:
3645
            check_insn(env, ctx, ISA_MIPS32R2);
3646
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3647
            /* Stop translation as we may have switched the execution mode */
3648
            ctx->bstate = BS_STOP;
3649
            rn = "SRSMap";
3650
            break;
3651
        default:
3652
            goto die;
3653
        }
3654
        break;
3655
    case 13:
3656
        switch (sel) {
3657
        case 0:
3658
            gen_helper_mtc0_cause(t0);
3659
            rn = "Cause";
3660
            break;
3661
        default:
3662
            goto die;
3663
        }
3664
        break;
3665
    case 14:
3666
        switch (sel) {
3667
        case 0:
3668
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3669
            rn = "EPC";
3670
            break;
3671
        default:
3672
            goto die;
3673
        }
3674
        break;
3675
    case 15:
3676
        switch (sel) {
3677
        case 0:
3678
            /* ignored */
3679
            rn = "PRid";
3680
            break;
3681
        case 1:
3682
            check_insn(env, ctx, ISA_MIPS32R2);
3683
            gen_helper_mtc0_ebase(t0);
3684
            rn = "EBase";
3685
            break;
3686
        default:
3687
            goto die;
3688
        }
3689
        break;
3690
    case 16:
3691
        switch (sel) {
3692
        case 0:
3693
            gen_helper_mtc0_config0(t0);
3694
            rn = "Config";
3695
            /* Stop translation as we may have switched the execution mode */
3696
            ctx->bstate = BS_STOP;
3697
            break;
3698
        case 1:
3699
            /* ignored, read only */
3700
            rn = "Config1";
3701
            break;
3702
        case 2:
3703
            gen_helper_mtc0_config2(t0);
3704
            rn = "Config2";
3705
            /* Stop translation as we may have switched the execution mode */
3706
            ctx->bstate = BS_STOP;
3707
            break;
3708
        case 3:
3709
            /* ignored, read only */
3710
            rn = "Config3";
3711
            break;
3712
        /* 4,5 are reserved */
3713
        /* 6,7 are implementation dependent */
3714
        case 6:
3715
            /* ignored */
3716
            rn = "Config6";
3717
            break;
3718
        case 7:
3719
            /* ignored */
3720
            rn = "Config7";
3721
            break;
3722
        default:
3723
            rn = "Invalid config selector";
3724
            goto die;
3725
        }
3726
        break;
3727
    case 17:
3728
        switch (sel) {
3729
        case 0:
3730
            /* ignored */
3731
            rn = "LLAddr";
3732
            break;
3733
        default:
3734
            goto die;
3735
        }
3736
        break;
3737
    case 18:
3738
        switch (sel) {
3739
        case 0 ... 7:
3740
            gen_helper_1i(mtc0_watchlo, t0, sel);
3741
            rn = "WatchLo";
3742
            break;
3743
        default:
3744
            goto die;
3745
        }
3746
        break;
3747
    case 19:
3748
        switch (sel) {
3749
        case 0 ... 7:
3750
            gen_helper_1i(mtc0_watchhi, t0, sel);
3751
            rn = "WatchHi";
3752
            break;
3753
        default:
3754
            goto die;
3755
        }
3756
        break;
3757
    case 20:
3758
        switch (sel) {
3759
        case 0:
3760
#if defined(TARGET_MIPS64)
3761
            check_insn(env, ctx, ISA_MIPS3);
3762
            gen_helper_mtc0_xcontext(t0);
3763
            rn = "XContext";
3764
            break;
3765
#endif
3766
        default:
3767
            goto die;
3768
        }
3769
        break;
3770
    case 21:
3771
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3772
        switch (sel) {
3773
        case 0:
3774
            gen_helper_mtc0_framemask(t0);
3775
            rn = "Framemask";
3776
            break;
3777
        default:
3778
            goto die;
3779
        }
3780
        break;
3781
    case 22:
3782
        /* ignored */
3783
        rn = "Diagnostic"; /* implementation dependent */
3784
        break;
3785
    case 23:
3786
        switch (sel) {
3787
        case 0:
3788
            gen_helper_mtc0_debug(t0); /* EJTAG support */
3789
            /* BS_STOP isn't good enough here, hflags may have changed. */
3790
            gen_save_pc(ctx->pc + 4);
3791
            ctx->bstate = BS_EXCP;
3792
            rn = "Debug";
3793
            break;
3794
        case 1:
3795
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
3796
            rn = "TraceControl";
3797
            /* Stop translation as we may have switched the execution mode */
3798
            ctx->bstate = BS_STOP;
3799
//            break;
3800
        case 2:
3801
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
3802
            rn = "TraceControl2";
3803
            /* Stop translation as we may have switched the execution mode */
3804
            ctx->bstate = BS_STOP;
3805
//            break;
3806
        case 3:
3807
            /* Stop translation as we may have switched the execution mode */
3808
            ctx->bstate = BS_STOP;
3809
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
3810
            rn = "UserTraceData";
3811
            /* Stop translation as we may have switched the execution mode */
3812
            ctx->bstate = BS_STOP;
3813
//            break;
3814
        case 4:
3815
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
3816
            /* Stop translation as we may have switched the execution mode */
3817
            ctx->bstate = BS_STOP;
3818
            rn = "TraceBPC";
3819
//            break;
3820
        default:
3821
            goto die;
3822
        }
3823
        break;
3824
    case 24:
3825
        switch (sel) {
3826
        case 0:
3827
            /* EJTAG support */
3828
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3829
            rn = "DEPC";
3830
            break;
3831
        default:
3832
            goto die;
3833
        }
3834
        break;
3835
    case 25:
3836
        switch (sel) {
3837
        case 0:
3838
            gen_helper_mtc0_performance0(t0);
3839
            rn = "Performance0";
3840
            break;
3841
        case 1:
3842
//            gen_helper_mtc0_performance1(t0);
3843
            rn = "Performance1";
3844
//            break;
3845
        case 2:
3846
//            gen_helper_mtc0_performance2(t0);
3847
            rn = "Performance2";
3848
//            break;
3849
        case 3:
3850
//            gen_helper_mtc0_performance3(t0);
3851
            rn = "Performance3";
3852
//            break;
3853
        case 4:
3854
//            gen_helper_mtc0_performance4(t0);
3855
            rn = "Performance4";
3856
//            break;
3857
        case 5:
3858
//            gen_helper_mtc0_performance5(t0);
3859
            rn = "Performance5";
3860
//            break;
3861
        case 6:
3862
//            gen_helper_mtc0_performance6(t0);
3863
            rn = "Performance6";
3864
//            break;
3865
        case 7:
3866
//            gen_helper_mtc0_performance7(t0);
3867
            rn = "Performance7";
3868
//            break;
3869
        default:
3870
            goto die;
3871
        }
3872
       break;
3873
    case 26:
3874
        /* ignored */
3875
        rn = "ECC";
3876
        break;
3877
    case 27:
3878
        switch (sel) {
3879
        case 0 ... 3:
3880
            /* ignored */
3881
            rn = "CacheErr";
3882
            break;
3883
        default:
3884
            goto die;
3885
        }
3886
       break;
3887
    case 28:
3888
        switch (sel) {
3889
        case 0:
3890
        case 2:
3891
        case 4:
3892
        case 6:
3893
            gen_helper_mtc0_taglo(t0);
3894
            rn = "TagLo";
3895
            break;
3896
        case 1:
3897
        case 3:
3898
        case 5:
3899
        case 7:
3900
            gen_helper_mtc0_datalo(t0);
3901
            rn = "DataLo";
3902
            break;
3903
        default:
3904
            goto die;
3905
        }
3906
        break;
3907
    case 29:
3908
        switch (sel) {
3909
        case 0:
3910
        case 2:
3911
        case 4:
3912
        case 6:
3913
            gen_helper_mtc0_taghi(t0);
3914
            rn = "TagHi";
3915
            break;
3916
        case 1:
3917
        case 3:
3918
        case 5:
3919
        case 7:
3920
            gen_helper_mtc0_datahi(t0);
3921
            rn = "DataHi";
3922
            break;
3923
        default:
3924
            rn = "invalid sel";
3925
            goto die;
3926
        }
3927
       break;
3928
    case 30:
3929
        switch (sel) {
3930
        case 0:
3931
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3932
            rn = "ErrorEPC";
3933
            break;
3934
        default:
3935
            goto die;
3936
        }
3937
        break;
3938
    case 31:
3939
        switch (sel) {
3940
        case 0:
3941
            /* EJTAG support */
3942
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3943
            rn = "DESAVE";
3944
            break;
3945
        default:
3946
            goto die;
3947
        }
3948
        /* Stop translation as we may have switched the execution mode */
3949
        ctx->bstate = BS_STOP;
3950
        break;
3951
    default:
3952
       goto die;
3953
    }
3954
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3955
    /* For simplicity assume that all writes can cause interrupts.  */
3956
    if (use_icount) {
3957
        gen_io_end();
3958
        ctx->bstate = BS_STOP;
3959
    }
3960
    return;
3961

    
3962
die:
3963
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3964
    generate_exception(ctx, EXCP_RI);
3965
}
3966

    
3967
#if defined(TARGET_MIPS64)
3968
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3969
{
3970
    const char *rn = "invalid";
3971

    
3972
    if (sel != 0)
3973
        check_insn(env, ctx, ISA_MIPS64);
3974

    
3975
    switch (reg) {
3976
    case 0:
3977
        switch (sel) {
3978
        case 0:
3979
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
3980
            rn = "Index";
3981
            break;
3982
        case 1:
3983
            check_insn(env, ctx, ASE_MT);
3984
            gen_helper_mfc0_mvpcontrol(t0);
3985
            rn = "MVPControl";
3986
            break;
3987
        case 2:
3988
            check_insn(env, ctx, ASE_MT);
3989
            gen_helper_mfc0_mvpconf0(t0);
3990
            rn = "MVPConf0";
3991
            break;
3992
        case 3:
3993
            check_insn(env, ctx, ASE_MT);
3994
            gen_helper_mfc0_mvpconf1(t0);
3995
            rn = "MVPConf1";
3996
            break;
3997
        default:
3998
            goto die;
3999
        }
4000
        break;
4001
    case 1:
4002
        switch (sel) {
4003
        case 0:
4004
            gen_helper_mfc0_random(t0);
4005
            rn = "Random";
4006
            break;
4007
        case 1:
4008
            check_insn(env, ctx, ASE_MT);
4009
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
4010
            rn = "VPEControl";
4011
            break;
4012
        case 2:
4013
            check_insn(env, ctx, ASE_MT);
4014
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
4015
            rn = "VPEConf0";
4016
            break;
4017
        case 3:
4018
            check_insn(env, ctx, ASE_MT);
4019
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
4020
            rn = "VPEConf1";
4021
            break;
4022
        case 4:
4023
            check_insn(env, ctx, ASE_MT);
4024
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
4025
            rn = "YQMask";
4026
            break;
4027
        case 5:
4028
            check_insn(env, ctx, ASE_MT);
4029
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4030
            rn = "VPESchedule";
4031
            break;
4032
        case 6:
4033
            check_insn(env, ctx, ASE_MT);
4034
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4035
            rn = "VPEScheFBack";
4036
            break;
4037
        case 7:
4038
            check_insn(env, ctx, ASE_MT);
4039
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
4040
            rn = "VPEOpt";
4041
            break;
4042
        default:
4043
            goto die;
4044
        }
4045
        break;
4046
    case 2:
4047
        switch (sel) {
4048
        case 0:
4049
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4050
            rn = "EntryLo0";
4051
            break;
4052
        case 1:
4053
            check_insn(env, ctx, ASE_MT);
4054
            gen_helper_mfc0_tcstatus(t0);
4055
            rn = "TCStatus";
4056
            break;
4057
        case 2:
4058
            check_insn(env, ctx, ASE_MT);
4059
            gen_helper_mfc0_tcbind(t0);
4060
            rn = "TCBind";
4061
            break;
4062
        case 3:
4063
            check_insn(env, ctx, ASE_MT);
4064
            gen_helper_dmfc0_tcrestart(t0);
4065
            rn = "TCRestart";
4066
            break;
4067
        case 4:
4068
            check_insn(env, ctx, ASE_MT);
4069
            gen_helper_dmfc0_tchalt(t0);
4070
            rn = "TCHalt";
4071
            break;
4072
        case 5:
4073
            check_insn(env, ctx, ASE_MT);
4074
            gen_helper_dmfc0_tccontext(t0);
4075
            rn = "TCContext";
4076
            break;
4077
        case 6:
4078
            check_insn(env, ctx, ASE_MT);
4079
            gen_helper_dmfc0_tcschedule(t0);
4080
            rn = "TCSchedule";
4081
            break;
4082
        case 7:
4083
            check_insn(env, ctx, ASE_MT);
4084
            gen_helper_dmfc0_tcschefback(t0);
4085
            rn = "TCScheFBack";
4086
            break;
4087
        default:
4088
            goto die;
4089
        }
4090
        break;
4091
    case 3:
4092
        switch (sel) {
4093
        case 0:
4094
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4095
            rn = "EntryLo1";
4096
            break;
4097
        default:
4098
            goto die;
4099
        }
4100
        break;
4101
    case 4:
4102
        switch (sel) {
4103
        case 0:
4104
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
4105
            rn = "Context";
4106
            break;
4107
        case 1:
4108
//            gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
4109
            rn = "ContextConfig";
4110
//            break;
4111
        default:
4112
            goto die;
4113
        }
4114
        break;
4115
    case 5:
4116
        switch (sel) {
4117
        case 0:
4118
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
4119
            rn = "PageMask";
4120
            break;
4121
        case 1:
4122
            check_insn(env, ctx, ISA_MIPS32R2);
4123
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
4124
            rn = "PageGrain";
4125
            break;
4126
        default:
4127
            goto die;
4128
        }
4129
        break;
4130
    case 6:
4131
        switch (sel) {
4132
        case 0:
4133
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
4134
            rn = "Wired";
4135
            break;
4136
        case 1:
4137
            check_insn(env, ctx, ISA_MIPS32R2);
4138
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
4139
            rn = "SRSConf0";
4140
            break;
4141
        case 2:
4142
            check_insn(env, ctx, ISA_MIPS32R2);
4143
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
4144
            rn = "SRSConf1";
4145
            break;
4146
        case 3:
4147
            check_insn(env, ctx, ISA_MIPS32R2);
4148
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
4149
            rn = "SRSConf2";
4150
            break;
4151
        case 4:
4152
            check_insn(env, ctx, ISA_MIPS32R2);
4153
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
4154
            rn = "SRSConf3";
4155
            break;
4156
        case 5:
4157
            check_insn(env, ctx, ISA_MIPS32R2);
4158
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
4159
            rn = "SRSConf4";
4160
            break;
4161
        default:
4162
            goto die;
4163
        }
4164
        break;
4165
    case 7:
4166
        switch (sel) {
4167
        case 0:
4168
            check_insn(env, ctx, ISA_MIPS32R2);
4169
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
4170
            rn = "HWREna";
4171
            break;
4172
        default:
4173
            goto die;
4174
        }
4175
        break;
4176
    case 8:
4177
        switch (sel) {
4178
        case 0:
4179
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4180
            rn = "BadVAddr";
4181
            break;
4182
        default:
4183
            goto die;
4184
        }
4185
        break;
4186
    case 9:
4187
        switch (sel) {
4188
        case 0:
4189
            /* Mark as an IO operation because we read the time.  */
4190
            if (use_icount)
4191
                gen_io_start();
4192
            gen_helper_mfc0_count(t0);
4193
            if (use_icount) {
4194
                gen_io_end();
4195
                ctx->bstate = BS_STOP;
4196
            }
4197
            rn = "Count";
4198
            break;
4199
        /* 6,7 are implementation dependent */
4200
        default:
4201
            goto die;
4202
        }
4203
        break;
4204
    case 10:
4205
        switch (sel) {
4206
        case 0:
4207
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
4208
            rn = "EntryHi";
4209
            break;
4210
        default:
4211
            goto die;
4212
        }
4213
        break;
4214
    case 11:
4215
        switch (sel) {
4216
        case 0:
4217
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
4218
            rn = "Compare";
4219
            break;
4220
        /* 6,7 are implementation dependent */
4221
        default:
4222
            goto die;
4223
        }
4224
        break;
4225
    case 12:
4226
        switch (sel) {
4227
        case 0:
4228
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
4229
            rn = "Status";
4230
            break;
4231
        case 1:
4232
            check_insn(env, ctx, ISA_MIPS32R2);
4233
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
4234
            rn = "IntCtl";
4235
            break;
4236
        case 2:
4237
            check_insn(env, ctx, ISA_MIPS32R2);
4238
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
4239
            rn = "SRSCtl";
4240
            break;
4241
        case 3:
4242
            check_insn(env, ctx, ISA_MIPS32R2);
4243
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
4244
            rn = "SRSMap";
4245
            break;
4246
        default:
4247
            goto die;
4248
        }
4249
        break;
4250
    case 13:
4251
        switch (sel) {
4252
        case 0:
4253
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
4254
            rn = "Cause";
4255
            break;
4256
        default:
4257
            goto die;
4258
        }
4259
        break;
4260
    case 14:
4261
        switch (sel) {
4262
        case 0:
4263
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4264
            rn = "EPC";
4265
            break;
4266
        default:
4267
            goto die;
4268
        }
4269
        break;
4270
    case 15:
4271
        switch (sel) {
4272
        case 0:
4273
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
4274
            rn = "PRid";
4275
            break;
4276
        case 1:
4277
            check_insn(env, ctx, ISA_MIPS32R2);
4278
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
4279
            rn = "EBase";
4280
            break;
4281
        default:
4282
            goto die;
4283
        }
4284
        break;
4285
    case 16:
4286
        switch (sel) {
4287
        case 0:
4288
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
4289
            rn = "Config";
4290
            break;
4291
        case 1:
4292
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
4293
            rn = "Config1";
4294
            break;
4295
        case 2:
4296
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
4297
            rn = "Config2";
4298
            break;
4299
        case 3:
4300
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
4301
            rn = "Config3";
4302
            break;
4303
       /* 6,7 are implementation dependent */
4304
        case 6:
4305
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
4306
            rn = "Config6";
4307
            break;
4308
        case 7:
4309
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
4310
            rn = "Config7";
4311
            break;
4312
        default:
4313
            goto die;
4314
        }
4315
        break;
4316
    case 17:
4317
        switch (sel) {
4318
        case 0:
4319
            gen_helper_dmfc0_lladdr(t0);
4320
            rn = "LLAddr";
4321
            break;
4322
        default:
4323
            goto die;
4324
        }
4325
        break;
4326
    case 18:
4327
        switch (sel) {
4328
        case 0 ... 7:
4329
            gen_helper_1i(dmfc0_watchlo, t0, sel);
4330
            rn = "WatchLo";
4331
            break;
4332
        default:
4333
            goto die;
4334
        }
4335
        break;
4336
    case 19:
4337
        switch (sel) {
4338
        case 0 ... 7:
4339
            gen_helper_1i(mfc0_watchhi, t0, sel);
4340
            rn = "WatchHi";
4341
            break;
4342
        default:
4343
            goto die;
4344
        }
4345
        break;
4346
    case 20:
4347
        switch (sel) {
4348
        case 0:
4349
            check_insn(env, ctx, ISA_MIPS3);
4350
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
4351
            rn = "XContext";
4352
            break;
4353
        default:
4354
            goto die;
4355
        }
4356
        break;
4357
    case 21:
4358
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4359
        switch (sel) {
4360
        case 0:
4361
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
4362
            rn = "Framemask";
4363
            break;
4364
        default:
4365
            goto die;
4366
        }
4367
        break;
4368
    case 22:
4369
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4370
        rn = "'Diagnostic"; /* implementation dependent */
4371
        break;
4372
    case 23:
4373
        switch (sel) {
4374
        case 0:
4375
            gen_helper_mfc0_debug(t0); /* EJTAG support */
4376
            rn = "Debug";
4377
            break;
4378
        case 1:
4379
//            gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
4380
            rn = "TraceControl";
4381
//            break;
4382
        case 2:
4383
//            gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
4384
            rn = "TraceControl2";
4385
//            break;
4386
        case 3:
4387
//            gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
4388
            rn = "UserTraceData";
4389
//            break;
4390
        case 4:
4391
//            gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
4392
            rn = "TraceBPC";
4393
//            break;
4394
        default:
4395
            goto die;
4396
        }
4397
        break;
4398
    case 24:
4399
        switch (sel) {
4400
        case 0:
4401
            /* EJTAG support */
4402
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4403
            rn = "DEPC";
4404
            break;
4405
        default:
4406
            goto die;
4407
        }
4408
        break;
4409
    case 25:
4410
        switch (sel) {
4411
        case 0:
4412
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
4413
            rn = "Performance0";
4414
            break;
4415
        case 1:
4416
//            gen_helper_dmfc0_performance1(t0);
4417
            rn = "Performance1";
4418
//            break;
4419
        case 2:
4420
//            gen_helper_dmfc0_performance2(t0);
4421
            rn = "Performance2";
4422
//            break;
4423
        case 3:
4424
//            gen_helper_dmfc0_performance3(t0);
4425
            rn = "Performance3";
4426
//            break;
4427
        case 4:
4428
//            gen_helper_dmfc0_performance4(t0);
4429
            rn = "Performance4";
4430
//            break;
4431
        case 5:
4432
//            gen_helper_dmfc0_performance5(t0);
4433
            rn = "Performance5";
4434
//            break;
4435
        case 6:
4436
//            gen_helper_dmfc0_performance6(t0);
4437
            rn = "Performance6";
4438
//            break;
4439
        case 7:
4440
//            gen_helper_dmfc0_performance7(t0);
4441
            rn = "Performance7";
4442
//            break;
4443
        default:
4444
            goto die;
4445
        }
4446
        break;
4447
    case 26:
4448
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4449
        rn = "ECC";
4450
        break;
4451
    case 27:
4452
        switch (sel) {
4453
        /* ignored */
4454
        case 0 ... 3:
4455
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
4456
            rn = "CacheErr";
4457
            break;
4458
        default:
4459
            goto die;
4460
        }
4461
        break;
4462
    case 28:
4463
        switch (sel) {
4464
        case 0:
4465
        case 2:
4466
        case 4:
4467
        case 6:
4468
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
4469
            rn = "TagLo";
4470
            break;
4471
        case 1:
4472
        case 3:
4473
        case 5:
4474
        case 7:
4475
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
4476
            rn = "DataLo";
4477
            break;
4478
        default:
4479
            goto die;
4480
        }
4481
        break;
4482
    case 29:
4483
        switch (sel) {
4484
        case 0:
4485
        case 2:
4486
        case 4:
4487
        case 6:
4488
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
4489
            rn = "TagHi";
4490
            break;
4491
        case 1:
4492
        case 3:
4493
        case 5:
4494
        case 7:
4495
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
4496
            rn = "DataHi";
4497
            break;
4498
        default:
4499
            goto die;
4500
        }
4501
        break;
4502
    case 30:
4503
        switch (sel) {
4504
        case 0:
4505
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4506
            rn = "ErrorEPC";
4507
            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    case 31:
4513
        switch (sel) {
4514
        case 0:
4515
            /* EJTAG support */
4516
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
4517
            rn = "DESAVE";
4518
            break;
4519
        default:
4520
            goto die;
4521
        }
4522
        break;
4523
    default:
4524
        goto die;
4525
    }
4526
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4527
    return;
4528

    
4529
die:
4530
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4531
    generate_exception(ctx, EXCP_RI);
4532
}
4533

    
4534
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4535
{
4536
    const char *rn = "invalid";
4537

    
4538
    if (sel != 0)
4539
        check_insn(env, ctx, ISA_MIPS64);
4540

    
4541
    if (use_icount)
4542
        gen_io_start();
4543

    
4544
    switch (reg) {
4545
    case 0:
4546
        switch (sel) {
4547
        case 0:
4548
            gen_helper_mtc0_index(t0);
4549
            rn = "Index";
4550
            break;
4551
        case 1:
4552
            check_insn(env, ctx, ASE_MT);
4553
            gen_helper_mtc0_mvpcontrol(t0);
4554
            rn = "MVPControl";
4555
            break;
4556
        case 2:
4557
            check_insn(env, ctx, ASE_MT);
4558
            /* ignored */
4559
            rn = "MVPConf0";
4560
            break;
4561
        case 3:
4562
            check_insn(env, ctx, ASE_MT);
4563
            /* ignored */
4564
            rn = "MVPConf1";
4565
            break;
4566
        default:
4567
            goto die;
4568
        }
4569
        break;
4570
    case 1:
4571
        switch (sel) {
4572
        case 0:
4573
            /* ignored */
4574
            rn = "Random";
4575
            break;
4576
        case 1:
4577
            check_insn(env, ctx, ASE_MT);
4578
            gen_helper_mtc0_vpecontrol(t0);
4579
            rn = "VPEControl";
4580
            break;
4581
        case 2:
4582
            check_insn(env, ctx, ASE_MT);
4583
            gen_helper_mtc0_vpeconf0(t0);
4584
            rn = "VPEConf0";
4585
            break;
4586
        case 3:
4587
            check_insn(env, ctx, ASE_MT);
4588
            gen_helper_mtc0_vpeconf1(t0);
4589
            rn = "VPEConf1";
4590
            break;
4591
        case 4:
4592
            check_insn(env, ctx, ASE_MT);
4593
            gen_helper_mtc0_yqmask(t0);
4594
            rn = "YQMask";
4595
            break;
4596
        case 5:
4597
            check_insn(env, ctx, ASE_MT);
4598
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4599
            rn = "VPESchedule";
4600
            break;
4601
        case 6:
4602
            check_insn(env, ctx, ASE_MT);
4603
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4604
            rn = "VPEScheFBack";
4605
            break;
4606
        case 7:
4607
            check_insn(env, ctx, ASE_MT);
4608
            gen_helper_mtc0_vpeopt(t0);
4609
            rn = "VPEOpt";
4610
            break;
4611
        default:
4612
            goto die;
4613
        }
4614
        break;
4615
    case 2:
4616
        switch (sel) {
4617
        case 0:
4618
            gen_helper_mtc0_entrylo0(t0);
4619
            rn = "EntryLo0";
4620
            break;
4621
        case 1:
4622
            check_insn(env, ctx, ASE_MT);
4623
            gen_helper_mtc0_tcstatus(t0);
4624
            rn = "TCStatus";
4625
            break;
4626
        case 2:
4627
            check_insn(env, ctx, ASE_MT);
4628
            gen_helper_mtc0_tcbind(t0);
4629
            rn = "TCBind";
4630
            break;
4631
        case 3:
4632
            check_insn(env, ctx, ASE_MT);
4633
            gen_helper_mtc0_tcrestart(t0);
4634
            rn = "TCRestart";
4635
            break;
4636
        case 4:
4637
            check_insn(env, ctx, ASE_MT);
4638
            gen_helper_mtc0_tchalt(t0);
4639
            rn = "TCHalt";
4640
            break;
4641
        case 5:
4642
            check_insn(env, ctx, ASE_MT);
4643
            gen_helper_mtc0_tccontext(t0);
4644
            rn = "TCContext";
4645
            break;
4646
        case 6:
4647
            check_insn(env, ctx, ASE_MT);
4648
            gen_helper_mtc0_tcschedule(t0);
4649
            rn = "TCSchedule";
4650
            break;
4651
        case 7:
4652
            check_insn(env, ctx, ASE_MT);
4653
            gen_helper_mtc0_tcschefback(t0);
4654
            rn = "TCScheFBack";
4655
            break;
4656
        default:
4657
            goto die;
4658
        }
4659
        break;
4660
    case 3:
4661
        switch (sel) {
4662
        case 0:
4663
            gen_helper_mtc0_entrylo1(t0);
4664
            rn = "EntryLo1";
4665
            break;
4666
        default:
4667
            goto die;
4668
        }
4669
        break;
4670
    case 4:
4671
        switch (sel) {
4672
        case 0:
4673
            gen_helper_mtc0_context(t0);
4674
            rn = "Context";
4675
            break;
4676
        case 1:
4677
//           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4678
            rn = "ContextConfig";
4679
//           break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    case 5:
4685
        switch (sel) {
4686
        case 0:
4687
            gen_helper_mtc0_pagemask(t0);
4688
            rn = "PageMask";
4689
            break;
4690
        case 1:
4691
            check_insn(env, ctx, ISA_MIPS32R2);
4692
            gen_helper_mtc0_pagegrain(t0);
4693
            rn = "PageGrain";
4694
            break;
4695
        default:
4696
            goto die;
4697
        }
4698
        break;
4699
    case 6:
4700
        switch (sel) {
4701
        case 0:
4702
            gen_helper_mtc0_wired(t0);
4703
            rn = "Wired";
4704
            break;
4705
        case 1:
4706
            check_insn(env, ctx, ISA_MIPS32R2);
4707
            gen_helper_mtc0_srsconf0(t0);
4708
            rn = "SRSConf0";
4709
            break;
4710
        case 2:
4711
            check_insn(env, ctx, ISA_MIPS32R2);
4712
            gen_helper_mtc0_srsconf1(t0);
4713
            rn = "SRSConf1";
4714
            break;
4715
        case 3:
4716
            check_insn(env, ctx, ISA_MIPS32R2);
4717
            gen_helper_mtc0_srsconf2(t0);
4718
            rn = "SRSConf2";
4719
            break;
4720
        case 4:
4721
            check_insn(env, ctx, ISA_MIPS32R2);
4722
            gen_helper_mtc0_srsconf3(t0);
4723
            rn = "SRSConf3";
4724
            break;
4725
        case 5:
4726
            check_insn(env, ctx, ISA_MIPS32R2);
4727
            gen_helper_mtc0_srsconf4(t0);
4728
            rn = "SRSConf4";
4729
            break;
4730
        default:
4731
            goto die;
4732
        }
4733
        break;
4734
    case 7:
4735
        switch (sel) {
4736
        case 0:
4737
            check_insn(env, ctx, ISA_MIPS32R2);
4738
            gen_helper_mtc0_hwrena(t0);
4739
            rn = "HWREna";
4740
            break;
4741
        default:
4742
            goto die;
4743
        }
4744
        break;
4745
    case 8:
4746
        /* ignored */
4747
        rn = "BadVAddr";
4748
        break;
4749
    case 9:
4750
        switch (sel) {
4751
        case 0:
4752
            gen_helper_mtc0_count(t0);
4753
            rn = "Count";
4754
            break;
4755
        /* 6,7 are implementation dependent */
4756
        default:
4757
            goto die;
4758
        }
4759
        /* Stop translation as we may have switched the execution mode */
4760
        ctx->bstate = BS_STOP;
4761
        break;
4762
    case 10:
4763
        switch (sel) {
4764
        case 0:
4765
            gen_helper_mtc0_entryhi(t0);
4766
            rn = "EntryHi";
4767
            break;
4768
        default:
4769
            goto die;
4770
        }
4771
        break;
4772
    case 11:
4773
        switch (sel) {
4774
        case 0:
4775
            gen_helper_mtc0_compare(t0);
4776
            rn = "Compare";
4777
            break;
4778
        /* 6,7 are implementation dependent */
4779
        default:
4780
            goto die;
4781
        }
4782
        /* Stop translation as we may have switched the execution mode */
4783
        ctx->bstate = BS_STOP;
4784
        break;
4785
    case 12:
4786
        switch (sel) {
4787
        case 0:
4788
            gen_helper_mtc0_status(t0);
4789
            /* BS_STOP isn't good enough here, hflags may have changed. */
4790
            gen_save_pc(ctx->pc + 4);
4791
            ctx->bstate = BS_EXCP;
4792
            rn = "Status";
4793
            break;
4794
        case 1:
4795
            check_insn(env, ctx, ISA_MIPS32R2);
4796
            gen_helper_mtc0_intctl(t0);
4797
            /* Stop translation as we may have switched the execution mode */
4798
            ctx->bstate = BS_STOP;
4799
            rn = "IntCtl";
4800
            break;
4801
        case 2:
4802
            check_insn(env, ctx, ISA_MIPS32R2);
4803
            gen_helper_mtc0_srsctl(t0);
4804
            /* Stop translation as we may have switched the execution mode */
4805
            ctx->bstate = BS_STOP;
4806
            rn = "SRSCtl";
4807
            break;
4808
        case 3:
4809
            check_insn(env, ctx, ISA_MIPS32R2);
4810
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4811
            /* Stop translation as we may have switched the execution mode */
4812
            ctx->bstate = BS_STOP;
4813
            rn = "SRSMap";
4814
            break;
4815
        default:
4816
            goto die;
4817
        }
4818
        break;
4819
    case 13:
4820
        switch (sel) {
4821
        case 0:
4822
            gen_helper_mtc0_cause(t0);
4823
            rn = "Cause";
4824
            break;
4825
        default:
4826
            goto die;
4827
        }
4828
        /* Stop translation as we may have switched the execution mode */
4829
        ctx->bstate = BS_STOP;
4830
        break;
4831
    case 14:
4832
        switch (sel) {
4833
        case 0:
4834
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4835
            rn = "EPC";
4836
            break;
4837
        default:
4838
            goto die;
4839
        }
4840
        break;
4841
    case 15:
4842
        switch (sel) {
4843
        case 0:
4844
            /* ignored */
4845
            rn = "PRid";
4846
            break;
4847
        case 1:
4848
            check_insn(env, ctx, ISA_MIPS32R2);
4849
            gen_helper_mtc0_ebase(t0);
4850
            rn = "EBase";
4851
            break;
4852
        default:
4853
            goto die;
4854
        }
4855
        break;
4856
    case 16:
4857
        switch (sel) {
4858
        case 0:
4859
            gen_helper_mtc0_config0(t0);
4860
            rn = "Config";
4861
            /* Stop translation as we may have switched the execution mode */
4862
            ctx->bstate = BS_STOP;
4863
            break;
4864
        case 1:
4865
            /* ignored, read only */
4866
            rn = "Config1";
4867
            break;
4868
        case 2:
4869
            gen_helper_mtc0_config2(t0);
4870
            rn = "Config2";
4871
            /* Stop translation as we may have switched the execution mode */
4872
            ctx->bstate = BS_STOP;
4873
            break;
4874
        case 3:
4875
            /* ignored */
4876
            rn = "Config3";
4877
            break;
4878
        /* 6,7 are implementation dependent */
4879
        default:
4880
            rn = "Invalid config selector";
4881
            goto die;
4882
        }
4883
        break;
4884
    case 17:
4885
        switch (sel) {
4886
        case 0:
4887
            /* ignored */
4888
            rn = "LLAddr";
4889
            break;
4890
        default:
4891
            goto die;
4892
        }
4893
        break;
4894
    case 18:
4895
        switch (sel) {
4896
        case 0 ... 7:
4897
            gen_helper_1i(mtc0_watchlo, t0, sel);
4898
            rn = "WatchLo";
4899
            break;
4900
        default:
4901
            goto die;
4902
        }
4903
        break;
4904
    case 19:
4905
        switch (sel) {
4906
        case 0 ... 7:
4907
            gen_helper_1i(mtc0_watchhi, t0, sel);
4908
            rn = "WatchHi";
4909
            break;
4910
        default:
4911
            goto die;
4912
        }
4913
        break;
4914
    case 20:
4915
        switch (sel) {
4916
        case 0:
4917
            check_insn(env, ctx, ISA_MIPS3);
4918
            gen_helper_mtc0_xcontext(t0);
4919
            rn = "XContext";
4920
            break;
4921
        default:
4922
            goto die;
4923
        }
4924
        break;
4925
    case 21:
4926
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4927
        switch (sel) {
4928
        case 0:
4929
            gen_helper_mtc0_framemask(t0);
4930
            rn = "Framemask";
4931
            break;
4932
        default:
4933
            goto die;
4934
        }
4935
        break;
4936
    case 22:
4937
        /* ignored */
4938
        rn = "Diagnostic"; /* implementation dependent */
4939
        break;
4940
    case 23:
4941
        switch (sel) {
4942
        case 0:
4943
            gen_helper_mtc0_debug(t0); /* EJTAG support */
4944
            /* BS_STOP isn't good enough here, hflags may have changed. */
4945
            gen_save_pc(ctx->pc + 4);
4946
            ctx->bstate = BS_EXCP;
4947
            rn = "Debug";
4948
            break;
4949
        case 1:
4950
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
4951
            /* Stop translation as we may have switched the execution mode */
4952
            ctx->bstate = BS_STOP;
4953
            rn = "TraceControl";
4954
//            break;
4955
        case 2:
4956
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
4957
            /* Stop translation as we may have switched the execution mode */
4958
            ctx->bstate = BS_STOP;
4959
            rn = "TraceControl2";
4960
//            break;
4961
        case 3:
4962
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
4963
            /* Stop translation as we may have switched the execution mode */
4964
            ctx->bstate = BS_STOP;
4965
            rn = "UserTraceData";
4966
//            break;
4967
        case 4:
4968
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
4969
            /* Stop translation as we may have switched the execution mode */
4970
            ctx->bstate = BS_STOP;
4971
            rn = "TraceBPC";
4972
//            break;
4973
        default:
4974
            goto die;
4975
        }
4976
        break;
4977
    case 24:
4978
        switch (sel) {
4979
        case 0:
4980
            /* EJTAG support */
4981
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4982
            rn = "DEPC";
4983
            break;
4984
        default:
4985
            goto die;
4986
        }
4987
        break;
4988
    case 25:
4989
        switch (sel) {
4990
        case 0:
4991
            gen_helper_mtc0_performance0(t0);
4992
            rn = "Performance0";
4993
            break;
4994
        case 1:
4995
//            gen_helper_mtc0_performance1(t0);
4996
            rn = "Performance1";
4997
//            break;
4998
        case 2:
4999
//            gen_helper_mtc0_performance2(t0);
5000
            rn = "Performance2";
5001
//            break;
5002
        case 3:
5003
//            gen_helper_mtc0_performance3(t0);
5004
            rn = "Performance3";
5005
//            break;
5006
        case 4:
5007
//            gen_helper_mtc0_performance4(t0);
5008
            rn = "Performance4";
5009
//            break;
5010
        case 5:
5011
//            gen_helper_mtc0_performance5(t0);
5012
            rn = "Performance5";
5013
//            break;
5014
        case 6:
5015
//            gen_helper_mtc0_performance6(t0);
5016
            rn = "Performance6";
5017
//            break;
5018
        case 7:
5019
//            gen_helper_mtc0_performance7(t0);
5020
            rn = "Performance7";
5021
//            break;
5022
        default:
5023
            goto die;
5024
        }
5025
        break;
5026
    case 26:
5027
        /* ignored */
5028
        rn = "ECC";
5029
        break;
5030
    case 27:
5031
        switch (sel) {
5032
        case 0 ... 3:
5033
            /* ignored */
5034
            rn = "CacheErr";
5035
            break;
5036
        default:
5037
            goto die;
5038
        }
5039
        break;
5040
    case 28:
5041
        switch (sel) {
5042
        case 0:
5043
        case 2:
5044
        case 4:
5045
        case 6:
5046
            gen_helper_mtc0_taglo(t0);
5047
            rn = "TagLo";
5048
            break;
5049
        case 1:
5050
        case 3:
5051
        case 5:
5052
        case 7:
5053
            gen_helper_mtc0_datalo(t0);
5054
            rn = "DataLo";
5055
            break;
5056
        default:
5057
            goto die;
5058
        }
5059
        break;
5060
    case 29:
5061
        switch (sel) {
5062
        case 0:
5063
        case 2:
5064
        case 4:
5065
        case 6:
5066
            gen_helper_mtc0_taghi(t0);
5067
            rn = "TagHi";
5068
            break;
5069
        case 1:
5070
        case 3:
5071
        case 5:
5072
        case 7:
5073
            gen_helper_mtc0_datahi(t0);
5074
            rn = "DataHi";
5075
            break;
5076
        default:
5077
            rn = "invalid sel";
5078
            goto die;
5079
        }
5080
        break;
5081
    case 30:
5082
        switch (sel) {
5083
        case 0:
5084
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5085
            rn = "ErrorEPC";
5086
            break;
5087
        default:
5088
            goto die;
5089
        }
5090
        break;
5091
    case 31:
5092
        switch (sel) {
5093
        case 0:
5094
            /* EJTAG support */
5095
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
5096
            rn = "DESAVE";
5097
            break;
5098
        default:
5099
            goto die;
5100
        }
5101
        /* Stop translation as we may have switched the execution mode */
5102
        ctx->bstate = BS_STOP;
5103
        break;
5104
    default:
5105
        goto die;
5106
    }
5107
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5108
    /* For simplicity assume that all writes can cause interrupts.  */
5109
    if (use_icount) {
5110
        gen_io_end();
5111
        ctx->bstate = BS_STOP;
5112
    }
5113
    return;
5114

    
5115
die:
5116
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5117
    generate_exception(ctx, EXCP_RI);
5118
}
5119
#endif /* TARGET_MIPS64 */
5120

    
5121
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5122
                     int u, int sel, int h)
5123
{
5124
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5125
    TCGv t0 = tcg_temp_local_new();
5126

    
5127
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5128
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5129
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5130
        tcg_gen_movi_tl(t0, -1);
5131
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5132
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5133
        tcg_gen_movi_tl(t0, -1);
5134
    else if (u == 0) {
5135
        switch (rt) {
5136
        case 2:
5137
            switch (sel) {
5138
            case 1:
5139
                gen_helper_mftc0_tcstatus(t0);
5140
                break;
5141
            case 2:
5142
                gen_helper_mftc0_tcbind(t0);
5143
                break;
5144
            case 3:
5145
                gen_helper_mftc0_tcrestart(t0);
5146
                break;
5147
            case 4:
5148
                gen_helper_mftc0_tchalt(t0);
5149
                break;
5150
            case 5:
5151
                gen_helper_mftc0_tccontext(t0);
5152
                break;
5153
            case 6:
5154
                gen_helper_mftc0_tcschedule(t0);
5155
                break;
5156
            case 7:
5157
                gen_helper_mftc0_tcschefback(t0);
5158
                break;
5159
            default:
5160
                gen_mfc0(env, ctx, t0, rt, sel);
5161
                break;
5162
            }
5163
            break;
5164
        case 10:
5165
            switch (sel) {
5166
            case 0:
5167
                gen_helper_mftc0_entryhi(t0);
5168
                break;
5169
            default:
5170
                gen_mfc0(env, ctx, t0, rt, sel);
5171
                break;
5172
            }
5173
        case 12:
5174
            switch (sel) {
5175
            case 0:
5176
                gen_helper_mftc0_status(t0);
5177
                break;
5178
            default:
5179
                gen_mfc0(env, ctx, t0, rt, sel);
5180
                break;
5181
            }
5182
        case 23:
5183
            switch (sel) {
5184
            case 0:
5185
                gen_helper_mftc0_debug(t0);
5186
                break;
5187
            default:
5188
                gen_mfc0(env, ctx, t0, rt, sel);
5189
                break;
5190
            }
5191
            break;
5192
        default:
5193
            gen_mfc0(env, ctx, t0, rt, sel);
5194
        }
5195
    } else switch (sel) {
5196
    /* GPR registers. */
5197
    case 0:
5198
        gen_helper_1i(mftgpr, t0, rt);
5199
        break;
5200
    /* Auxiliary CPU registers */
5201
    case 1:
5202
        switch (rt) {
5203
        case 0:
5204
            gen_helper_1i(mftlo, t0, 0);
5205
            break;
5206
        case 1:
5207
            gen_helper_1i(mfthi, t0, 0);
5208
            break;
5209
        case 2:
5210
            gen_helper_1i(mftacx, t0, 0);
5211
            break;
5212
        case 4:
5213
            gen_helper_1i(mftlo, t0, 1);
5214
            break;
5215
        case 5:
5216
            gen_helper_1i(mfthi, t0, 1);
5217
            break;
5218
        case 6:
5219
            gen_helper_1i(mftacx, t0, 1);
5220
            break;
5221
        case 8:
5222
            gen_helper_1i(mftlo, t0, 2);
5223
            break;
5224
        case 9:
5225
            gen_helper_1i(mfthi, t0, 2);
5226
            break;
5227
        case 10:
5228
            gen_helper_1i(mftacx, t0, 2);
5229
            break;
5230
        case 12:
5231
            gen_helper_1i(mftlo, t0, 3);
5232
            break;
5233
        case 13:
5234
            gen_helper_1i(mfthi, t0, 3);
5235
            break;
5236
        case 14:
5237
            gen_helper_1i(mftacx, t0, 3);
5238
            break;
5239
        case 16:
5240
            gen_helper_mftdsp(t0);
5241
            break;
5242
        default:
5243
            goto die;
5244
        }
5245
        break;
5246
    /* Floating point (COP1). */
5247
    case 2:
5248
        /* XXX: For now we support only a single FPU context. */
5249
        if (h == 0) {
5250
            TCGv_i32 fp0 = tcg_temp_new_i32();
5251

    
5252
            gen_load_fpr32(fp0, rt);
5253
            tcg_gen_ext_i32_tl(t0, fp0);
5254
            tcg_temp_free_i32(fp0);
5255
        } else {
5256
            TCGv_i32 fp0 = tcg_temp_new_i32();
5257

    
5258
            gen_load_fpr32h(fp0, rt);
5259
            tcg_gen_ext_i32_tl(t0, fp0);
5260
            tcg_temp_free_i32(fp0);
5261
        }
5262
        break;
5263
    case 3:
5264
        /* XXX: For now we support only a single FPU context. */
5265
        gen_helper_1i(cfc1, t0, rt);
5266
        break;
5267
    /* COP2: Not implemented. */
5268
    case 4:
5269
    case 5:
5270
        /* fall through */
5271
    default:
5272
        goto die;
5273
    }
5274
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5275
    gen_store_gpr(t0, rd);
5276
    tcg_temp_free(t0);
5277
    return;
5278

    
5279
die:
5280
    tcg_temp_free(t0);
5281
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5282
    generate_exception(ctx, EXCP_RI);
5283
}
5284

    
5285
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5286
                     int u, int sel, int h)
5287
{
5288
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5289
    TCGv t0 = tcg_temp_local_new();
5290

    
5291
    gen_load_gpr(t0, rt);
5292
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5293
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5294
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5295
        /* NOP */ ;
5296
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5297
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5298
        /* NOP */ ;
5299
    else if (u == 0) {
5300
        switch (rd) {
5301
        case 2:
5302
            switch (sel) {
5303
            case 1:
5304
                gen_helper_mttc0_tcstatus(t0);
5305
                break;
5306
            case 2:
5307
                gen_helper_mttc0_tcbind(t0);
5308
                break;
5309
            case 3:
5310
                gen_helper_mttc0_tcrestart(t0);
5311
                break;
5312
            case 4:
5313
                gen_helper_mttc0_tchalt(t0);
5314
                break;
5315
            case 5:
5316
                gen_helper_mttc0_tccontext(t0);
5317
                break;
5318
            case 6:
5319
                gen_helper_mttc0_tcschedule(t0);
5320
                break;
5321
            case 7:
5322
                gen_helper_mttc0_tcschefback(t0);
5323
                break;
5324
            default:
5325
                gen_mtc0(env, ctx, t0, rd, sel);
5326
                break;
5327
            }
5328
            break;
5329
        case 10:
5330
            switch (sel) {
5331
            case 0:
5332
                gen_helper_mttc0_entryhi(t0);
5333
                break;
5334
            default:
5335
                gen_mtc0(env, ctx, t0, rd, sel);
5336
                break;
5337
            }
5338
        case 12:
5339
            switch (sel) {
5340
            case 0:
5341
                gen_helper_mttc0_status(t0);
5342
                break;
5343
            default:
5344
                gen_mtc0(env, ctx, t0, rd, sel);
5345
                break;
5346
            }
5347
        case 23:
5348
            switch (sel) {
5349
            case 0:
5350
                gen_helper_mttc0_debug(t0);
5351
                break;
5352
            default:
5353
                gen_mtc0(env, ctx, t0, rd, sel);
5354
                break;
5355
            }
5356
            break;
5357
        default:
5358
            gen_mtc0(env, ctx, t0, rd, sel);
5359
        }
5360
    } else switch (sel) {
5361
    /* GPR registers. */
5362
    case 0:
5363
        gen_helper_1i(mttgpr, t0, rd);
5364
        break;
5365
    /* Auxiliary CPU registers */
5366
    case 1:
5367
        switch (rd) {
5368
        case 0:
5369
            gen_helper_1i(mttlo, t0, 0);
5370
            break;
5371
        case 1:
5372
            gen_helper_1i(mtthi, t0, 0);
5373
            break;
5374
        case 2:
5375
            gen_helper_1i(mttacx, t0, 0);
5376
            break;
5377
        case 4:
5378
            gen_helper_1i(mttlo, t0, 1);
5379
            break;
5380
        case 5:
5381
            gen_helper_1i(mtthi, t0, 1);
5382
            break;
5383
        case 6:
5384
            gen_helper_1i(mttacx, t0, 1);
5385
            break;
5386
        case 8:
5387
            gen_helper_1i(mttlo, t0, 2);
5388
            break;
5389
        case 9:
5390
            gen_helper_1i(mtthi, t0, 2);
5391
            break;
5392
        case 10:
5393
            gen_helper_1i(mttacx, t0, 2);
5394
            break;
5395
        case 12:
5396
            gen_helper_1i(mttlo, t0, 3);
5397
            break;
5398
        case 13:
5399
            gen_helper_1i(mtthi, t0, 3);
5400
            break;
5401
        case 14:
5402
            gen_helper_1i(mttacx, t0, 3);
5403
            break;
5404
        case 16:
5405
            gen_helper_mttdsp(t0);
5406
            break;
5407
        default:
5408
            goto die;
5409
        }
5410
        break;
5411
    /* Floating point (COP1). */
5412
    case 2:
5413
        /* XXX: For now we support only a single FPU context. */
5414
        if (h == 0) {
5415
            TCGv_i32 fp0 = tcg_temp_new_i32();
5416

    
5417
            tcg_gen_trunc_tl_i32(fp0, t0);
5418
            gen_store_fpr32(fp0, rd);
5419
            tcg_temp_free_i32(fp0);
5420
        } else {
5421
            TCGv_i32 fp0 = tcg_temp_new_i32();
5422

    
5423
            tcg_gen_trunc_tl_i32(fp0, t0);
5424
            gen_store_fpr32h(fp0, rd);
5425
            tcg_temp_free_i32(fp0);
5426
        }
5427
        break;
5428
    case 3:
5429
        /* XXX: For now we support only a single FPU context. */
5430
        gen_helper_1i(ctc1, t0, rd);
5431
        break;
5432
    /* COP2: Not implemented. */
5433
    case 4:
5434
    case 5:
5435
        /* fall through */
5436
    default:
5437
        goto die;
5438
    }
5439
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5440
    tcg_temp_free(t0);
5441
    return;
5442

    
5443
die:
5444
    tcg_temp_free(t0);
5445
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5446
    generate_exception(ctx, EXCP_RI);
5447
}
5448

    
5449
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5450
{
5451
    const char *opn = "ldst";
5452

    
5453
    switch (opc) {
5454
    case OPC_MFC0:
5455
        if (rt == 0) {
5456
            /* Treat as NOP. */
5457
            return;
5458
        }
5459
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5460
        opn = "mfc0";
5461
        break;
5462
    case OPC_MTC0:
5463
        {
5464
            TCGv t0 = tcg_temp_new();
5465

    
5466
            gen_load_gpr(t0, rt);
5467
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5468
            tcg_temp_free(t0);
5469
        }
5470
        opn = "mtc0";
5471
        break;
5472
#if defined(TARGET_MIPS64)
5473
    case OPC_DMFC0:
5474
        check_insn(env, ctx, ISA_MIPS3);
5475
        if (rt == 0) {
5476
            /* Treat as NOP. */
5477
            return;
5478
        }
5479
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5480
        opn = "dmfc0";
5481
        break;
5482
    case OPC_DMTC0:
5483
        check_insn(env, ctx, ISA_MIPS3);
5484
        {
5485
            TCGv t0 = tcg_temp_new();
5486

    
5487
            gen_load_gpr(t0, rt);
5488
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5489
            tcg_temp_free(t0);
5490
        }
5491
        opn = "dmtc0";
5492
        break;
5493
#endif
5494
    case OPC_MFTR:
5495
        check_insn(env, ctx, ASE_MT);
5496
        if (rd == 0) {
5497
            /* Treat as NOP. */
5498
            return;
5499
        }
5500
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5501
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5502
        opn = "mftr";
5503
        break;
5504
    case OPC_MTTR:
5505
        check_insn(env, ctx, ASE_MT);
5506
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5507
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5508
        opn = "mttr";
5509
        break;
5510
    case OPC_TLBWI:
5511
        opn = "tlbwi";
5512
        if (!env->tlb->helper_tlbwi)
5513
            goto die;
5514
        gen_helper_tlbwi();
5515
        break;
5516
    case OPC_TLBWR:
5517
        opn = "tlbwr";
5518
        if (!env->tlb->helper_tlbwr)
5519
            goto die;
5520
        gen_helper_tlbwr();
5521
        break;
5522
    case OPC_TLBP:
5523
        opn = "tlbp";
5524
        if (!env->tlb->helper_tlbp)
5525
            goto die;
5526
        gen_helper_tlbp();
5527
        break;
5528
    case OPC_TLBR:
5529
        opn = "tlbr";
5530
        if (!env->tlb->helper_tlbr)
5531
            goto die;
5532
        gen_helper_tlbr();
5533
        break;
5534
    case OPC_ERET:
5535
        opn = "eret";
5536
        check_insn(env, ctx, ISA_MIPS2);
5537
        gen_helper_eret();
5538
        ctx->bstate = BS_EXCP;
5539
        break;
5540
    case OPC_DERET:
5541
        opn = "deret";
5542
        check_insn(env, ctx, ISA_MIPS32);
5543
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5544
            MIPS_INVAL(opn);
5545
            generate_exception(ctx, EXCP_RI);
5546
        } else {
5547
            gen_helper_deret();
5548
            ctx->bstate = BS_EXCP;
5549
        }
5550
        break;
5551
    case OPC_WAIT:
5552
        opn = "wait";
5553
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5554
        /* If we get an exception, we want to restart at next instruction */
5555
        ctx->pc += 4;
5556
        save_cpu_state(ctx, 1);
5557
        ctx->pc -= 4;
5558
        gen_helper_wait();
5559
        ctx->bstate = BS_EXCP;
5560
        break;
5561
    default:
5562
 die:
5563
        MIPS_INVAL(opn);
5564
        generate_exception(ctx, EXCP_RI);
5565
        return;
5566
    }
5567
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5568
}
5569
#endif /* !CONFIG_USER_ONLY */
5570

    
5571
/* CP1 Branches (before delay slot) */
5572
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5573
                                 int32_t cc, int32_t offset)
5574
{
5575
    target_ulong btarget;
5576
    const char *opn = "cp1 cond branch";
5577
    TCGv_i32 t0 = tcg_temp_new_i32();
5578

    
5579
    if (cc != 0)
5580
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5581

    
5582
    btarget = ctx->pc + 4 + offset;
5583

    
5584
    switch (op) {
5585
    case OPC_BC1F:
5586
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5587
        tcg_gen_not_i32(t0, t0);
5588
        tcg_gen_andi_i32(t0, t0, 1);
5589
        tcg_gen_extu_i32_tl(bcond, t0);
5590
        opn = "bc1f";
5591
        goto not_likely;
5592
    case OPC_BC1FL:
5593
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5594
        tcg_gen_not_i32(t0, t0);
5595
        tcg_gen_andi_i32(t0, t0, 1);
5596
        tcg_gen_extu_i32_tl(bcond, t0);
5597
        opn = "bc1fl";
5598
        goto likely;
5599
    case OPC_BC1T:
5600
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5601
        tcg_gen_andi_i32(t0, t0, 1);
5602
        tcg_gen_extu_i32_tl(bcond, t0);
5603
        opn = "bc1t";
5604
        goto not_likely;
5605
    case OPC_BC1TL:
5606
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5607
        tcg_gen_andi_i32(t0, t0, 1);
5608
        tcg_gen_extu_i32_tl(bcond, t0);
5609
        opn = "bc1tl";
5610
    likely:
5611
        ctx->hflags |= MIPS_HFLAG_BL;
5612
        break;
5613
    case OPC_BC1FANY2:
5614
        {
5615
            TCGv_i32 t1 = tcg_temp_new_i32();
5616
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5617
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5618
            tcg_gen_or_i32(t0, t0, t1);
5619
            tcg_temp_free_i32(t1);
5620
            tcg_gen_not_i32(t0, t0);
5621
            tcg_gen_andi_i32(t0, t0, 1);
5622
            tcg_gen_extu_i32_tl(bcond, t0);
5623
        }
5624
        opn = "bc1any2f";
5625
        goto not_likely;
5626
    case OPC_BC1TANY2:
5627
        {
5628
            TCGv_i32 t1 = tcg_temp_new_i32();
5629
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5630
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5631
            tcg_gen_or_i32(t0, t0, t1);
5632
            tcg_temp_free_i32(t1);
5633
            tcg_gen_andi_i32(t0, t0, 1);
5634
            tcg_gen_extu_i32_tl(bcond, t0);
5635
        }
5636
        opn = "bc1any2t";
5637
        goto not_likely;
5638
    case OPC_BC1FANY4:
5639
        {
5640
            TCGv_i32 t1 = tcg_temp_new_i32();
5641
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5642
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5643
            tcg_gen_or_i32(t0, t0, t1);
5644
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5645
            tcg_gen_or_i32(t0, t0, t1);
5646
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5647
            tcg_gen_or_i32(t0, t0, t1);
5648
            tcg_temp_free_i32(t1);
5649
            tcg_gen_not_i32(t0, t0);
5650
            tcg_gen_andi_i32(t0, t0, 1);
5651
            tcg_gen_extu_i32_tl(bcond, t0);
5652
        }
5653
        opn = "bc1any4f";
5654
        goto not_likely;
5655
    case OPC_BC1TANY4:
5656
        {
5657
            TCGv_i32 t1 = tcg_temp_new_i32();
5658
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5659
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5660
            tcg_gen_or_i32(t0, t0, t1);
5661
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5662
            tcg_gen_or_i32(t0, t0, t1);
5663
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5664
            tcg_gen_or_i32(t0, t0, t1);
5665
            tcg_temp_free_i32(t1);
5666
            tcg_gen_andi_i32(t0, t0, 1);
5667
            tcg_gen_extu_i32_tl(bcond, t0);
5668
        }
5669
        opn = "bc1any4t";
5670
    not_likely:
5671
        ctx->hflags |= MIPS_HFLAG_BC;
5672
        break;
5673
    default:
5674
        MIPS_INVAL(opn);
5675
        generate_exception (ctx, EXCP_RI);
5676
        goto out;
5677
    }
5678
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5679
               ctx->hflags, btarget);
5680
    ctx->btarget = btarget;
5681

    
5682
 out:
5683
    tcg_temp_free_i32(t0);
5684
}
5685

    
5686
/* Coprocessor 1 (FPU) */
5687

    
5688
#define FOP(func, fmt) (((fmt) << 21) | (func))
5689

    
5690
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5691
{
5692
    const char *opn = "cp1 move";
5693
    TCGv t0 = tcg_temp_new();
5694

    
5695
    switch (opc) {
5696
    case OPC_MFC1:
5697
        {
5698
            TCGv_i32 fp0 = tcg_temp_new_i32();
5699

    
5700
            gen_load_fpr32(fp0, fs);
5701
            tcg_gen_ext_i32_tl(t0, fp0);
5702
            tcg_temp_free_i32(fp0);
5703
        }
5704
        gen_store_gpr(t0, rt);
5705
        opn = "mfc1";
5706
        break;
5707
    case OPC_MTC1:
5708
        gen_load_gpr(t0, rt);
5709
        {
5710
            TCGv_i32 fp0 = tcg_temp_new_i32();
5711

    
5712
            tcg_gen_trunc_tl_i32(fp0, t0);
5713
            gen_store_fpr32(fp0, fs);
5714
            tcg_temp_free_i32(fp0);
5715
        }
5716
        opn = "mtc1";
5717
        break;
5718
    case OPC_CFC1:
5719
        gen_helper_1i(cfc1, t0, fs);
5720
        gen_store_gpr(t0, rt);
5721
        opn = "cfc1";
5722
        break;
5723
    case OPC_CTC1:
5724
        gen_load_gpr(t0, rt);
5725
        gen_helper_1i(ctc1, t0, fs);
5726
        opn = "ctc1";
5727
        break;
5728
#if defined(TARGET_MIPS64)
5729
    case OPC_DMFC1:
5730
        gen_load_fpr64(ctx, t0, fs);
5731
        gen_store_gpr(t0, rt);
5732
        opn = "dmfc1";
5733
        break;
5734
    case OPC_DMTC1:
5735
        gen_load_gpr(t0, rt);
5736
        gen_store_fpr64(ctx, t0, fs);
5737
        opn = "dmtc1";
5738
        break;
5739
#endif
5740
    case OPC_MFHC1:
5741
        {
5742
            TCGv_i32 fp0 = tcg_temp_new_i32();
5743

    
5744
            gen_load_fpr32h(fp0, fs);
5745
            tcg_gen_ext_i32_tl(t0, fp0);
5746
            tcg_temp_free_i32(fp0);
5747
        }
5748
        gen_store_gpr(t0, rt);
5749
        opn = "mfhc1";
5750
        break;
5751
    case OPC_MTHC1:
5752
        gen_load_gpr(t0, rt);
5753
        {
5754
            TCGv_i32 fp0 = tcg_temp_new_i32();
5755

    
5756
            tcg_gen_trunc_tl_i32(fp0, t0);
5757
            gen_store_fpr32h(fp0, fs);
5758
            tcg_temp_free_i32(fp0);
5759
        }
5760
        opn = "mthc1";
5761
        break;
5762
    default:
5763
        MIPS_INVAL(opn);
5764
        generate_exception (ctx, EXCP_RI);
5765
        goto out;
5766
    }
5767
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5768

    
5769
 out:
5770
    tcg_temp_free(t0);
5771
}
5772

    
5773
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5774
{
5775
    int l1;
5776
    TCGCond cond;
5777
    TCGv_i32 t0;
5778

    
5779
    if (rd == 0) {
5780
        /* Treat as NOP. */
5781
        return;
5782
    }
5783

    
5784
    if (tf)
5785
        cond = TCG_COND_EQ;
5786
    else
5787
        cond = TCG_COND_NE;
5788

    
5789
    l1 = gen_new_label();
5790
    t0 = tcg_temp_new_i32();
5791
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5792
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5793
    tcg_temp_free_i32(t0);
5794
    if (rs == 0) {
5795
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5796
    } else {
5797
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5798
    }
5799
    gen_set_label(l1);
5800
}
5801

    
5802
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5803
{
5804
    int cond;
5805
    TCGv_i32 t0 = tcg_temp_new_i32();
5806
    int l1 = gen_new_label();
5807

    
5808
    if (tf)
5809
        cond = TCG_COND_EQ;
5810
    else
5811
        cond = TCG_COND_NE;
5812

    
5813
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5814
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5815
    gen_load_fpr32(t0, fs);
5816
    gen_store_fpr32(t0, fd);
5817
    gen_set_label(l1);
5818
    tcg_temp_free_i32(t0);
5819
}
5820

    
5821
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5822
{
5823
    int cond;
5824
    TCGv_i32 t0 = tcg_temp_new_i32();
5825
    TCGv_i64 fp0;
5826
    int l1 = gen_new_label();
5827

    
5828
    if (tf)
5829
        cond = TCG_COND_EQ;
5830
    else
5831
        cond = TCG_COND_NE;
5832

    
5833
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5834
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5835
    tcg_temp_free_i32(t0);
5836
    fp0 = tcg_temp_local_new_i64();
5837
    gen_load_fpr64(ctx, fp0, fs);
5838
    gen_store_fpr64(ctx, fp0, fd);
5839
    tcg_temp_free_i64(fp0);
5840
    gen_set_label(l1);
5841
}
5842

    
5843
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5844
{
5845
    int cond;
5846
    TCGv_i32 t0 = tcg_temp_new_i32();
5847
    int l1 = gen_new_label();
5848
    int l2 = gen_new_label();
5849

    
5850
    if (tf)
5851
        cond = TCG_COND_EQ;
5852
    else
5853
        cond = TCG_COND_NE;
5854

    
5855
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5856
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5857
    gen_load_fpr32(t0, fs);
5858
    gen_store_fpr32(t0, fd);
5859
    gen_set_label(l1);
5860

    
5861
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5862
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5863
    tcg_temp_free_i32(t0);
5864
    gen_load_fpr32h(t0, fs);
5865
    gen_store_fpr32h(t0, fd);
5866
    gen_set_label(l2);
5867

    
5868
}
5869

    
5870

    
5871
static void gen_farith (DisasContext *ctx, uint32_t op1,
5872
                        int ft, int fs, int fd, int cc)
5873
{
5874
    const char *opn = "farith";
5875
    const char *condnames[] = {
5876
            "c.f",
5877
            "c.un",
5878
            "c.eq",
5879
            "c.ueq",
5880
            "c.olt",
5881
            "c.ult",
5882
            "c.ole",
5883
            "c.ule",
5884
            "c.sf",
5885
            "c.ngle",
5886
            "c.seq",
5887
            "c.ngl",
5888
            "c.lt",
5889
            "c.nge",
5890
            "c.le",
5891
            "c.ngt",
5892
    };
5893
    const char *condnames_abs[] = {
5894
            "cabs.f",
5895
            "cabs.un",
5896
            "cabs.eq",
5897
            "cabs.ueq",
5898
            "cabs.olt",
5899
            "cabs.ult",
5900
            "cabs.ole",
5901
            "cabs.ule",
5902
            "cabs.sf",
5903
            "cabs.ngle",
5904
            "cabs.seq",
5905
            "cabs.ngl",
5906
            "cabs.lt",
5907
            "cabs.nge",
5908
            "cabs.le",
5909
            "cabs.ngt",
5910
    };
5911
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5912
    uint32_t func = ctx->opcode & 0x3f;
5913

    
5914
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5915
    case FOP(0, 16):
5916
        {
5917
            TCGv_i32 fp0 = tcg_temp_new_i32();
5918
            TCGv_i32 fp1 = tcg_temp_new_i32();
5919

    
5920
            gen_load_fpr32(fp0, fs);
5921
            gen_load_fpr32(fp1, ft);
5922
            gen_helper_float_add_s(fp0, fp0, fp1);
5923
            tcg_temp_free_i32(fp1);
5924
            gen_store_fpr32(fp0, fd);
5925
            tcg_temp_free_i32(fp0);
5926
        }
5927
        opn = "add.s";
5928
        optype = BINOP;
5929
        break;
5930
    case FOP(1, 16):
5931
        {
5932
            TCGv_i32 fp0 = tcg_temp_new_i32();
5933
            TCGv_i32 fp1 = tcg_temp_new_i32();
5934

    
5935
            gen_load_fpr32(fp0, fs);
5936
            gen_load_fpr32(fp1, ft);
5937
            gen_helper_float_sub_s(fp0, fp0, fp1);
5938
            tcg_temp_free_i32(fp1);
5939
            gen_store_fpr32(fp0, fd);
5940
            tcg_temp_free_i32(fp0);
5941
        }
5942
        opn = "sub.s";
5943
        optype = BINOP;
5944
        break;
5945
    case FOP(2, 16):
5946
        {
5947
            TCGv_i32 fp0 = tcg_temp_new_i32();
5948
            TCGv_i32 fp1 = tcg_temp_new_i32();
5949

    
5950
            gen_load_fpr32(fp0, fs);
5951
            gen_load_fpr32(fp1, ft);
5952
            gen_helper_float_mul_s(fp0, fp0, fp1);
5953
            tcg_temp_free_i32(fp1);
5954
            gen_store_fpr32(fp0, fd);
5955
            tcg_temp_free_i32(fp0);
5956
        }
5957
        opn = "mul.s";
5958
        optype = BINOP;
5959
        break;
5960
    case FOP(3, 16):
5961
        {
5962
            TCGv_i32 fp0 = tcg_temp_new_i32();
5963
            TCGv_i32 fp1 = tcg_temp_new_i32();
5964

    
5965
            gen_load_fpr32(fp0, fs);
5966
            gen_load_fpr32(fp1, ft);
5967
            gen_helper_float_div_s(fp0, fp0, fp1);
5968
            tcg_temp_free_i32(fp1);
5969
            gen_store_fpr32(fp0, fd);
5970
            tcg_temp_free_i32(fp0);
5971
        }
5972
        opn = "div.s";
5973
        optype = BINOP;
5974
        break;
5975
    case FOP(4, 16):
5976
        {
5977
            TCGv_i32 fp0 = tcg_temp_new_i32();
5978

    
5979
            gen_load_fpr32(fp0, fs);
5980
            gen_helper_float_sqrt_s(fp0, fp0);
5981
            gen_store_fpr32(fp0, fd);
5982
            tcg_temp_free_i32(fp0);
5983
        }
5984
        opn = "sqrt.s";
5985
        break;
5986
    case FOP(5, 16):
5987
        {
5988
            TCGv_i32 fp0 = tcg_temp_new_i32();
5989

    
5990
            gen_load_fpr32(fp0, fs);
5991
            gen_helper_float_abs_s(fp0, fp0);
5992
            gen_store_fpr32(fp0, fd);
5993
            tcg_temp_free_i32(fp0);
5994
        }
5995
        opn = "abs.s";
5996
        break;
5997
    case FOP(6, 16):
5998
        {
5999
            TCGv_i32 fp0 = tcg_temp_new_i32();
6000

    
6001
            gen_load_fpr32(fp0, fs);
6002
            gen_store_fpr32(fp0, fd);
6003
            tcg_temp_free_i32(fp0);
6004
        }
6005
        opn = "mov.s";
6006
        break;
6007
    case FOP(7, 16):
6008
        {
6009
            TCGv_i32 fp0 = tcg_temp_new_i32();
6010

    
6011
            gen_load_fpr32(fp0, fs);
6012
            gen_helper_float_chs_s(fp0, fp0);
6013
            gen_store_fpr32(fp0, fd);
6014
            tcg_temp_free_i32(fp0);
6015
        }
6016
        opn = "neg.s";
6017
        break;
6018
    case FOP(8, 16):
6019
        check_cp1_64bitmode(ctx);
6020
        {
6021
            TCGv_i32 fp32 = tcg_temp_new_i32();
6022
            TCGv_i64 fp64 = tcg_temp_new_i64();
6023

    
6024
            gen_load_fpr32(fp32, fs);
6025
            gen_helper_float_roundl_s(fp64, fp32);
6026
            tcg_temp_free_i32(fp32);
6027
            gen_store_fpr64(ctx, fp64, fd);
6028
            tcg_temp_free_i64(fp64);
6029
        }
6030
        opn = "round.l.s";
6031
        break;
6032
    case FOP(9, 16):
6033
        check_cp1_64bitmode(ctx);
6034
        {
6035
            TCGv_i32 fp32 = tcg_temp_new_i32();
6036
            TCGv_i64 fp64 = tcg_temp_new_i64();
6037

    
6038
            gen_load_fpr32(fp32, fs);
6039
            gen_helper_float_truncl_s(fp64, fp32);
6040
            tcg_temp_free_i32(fp32);
6041
            gen_store_fpr64(ctx, fp64, fd);
6042
            tcg_temp_free_i64(fp64);
6043
        }
6044
        opn = "trunc.l.s";
6045
        break;
6046
    case FOP(10, 16):
6047
        check_cp1_64bitmode(ctx);
6048
        {
6049
            TCGv_i32 fp32 = tcg_temp_new_i32();
6050
            TCGv_i64 fp64 = tcg_temp_new_i64();
6051

    
6052
            gen_load_fpr32(fp32, fs);
6053
            gen_helper_float_ceill_s(fp64, fp32);
6054
            tcg_temp_free_i32(fp32);
6055
            gen_store_fpr64(ctx, fp64, fd);
6056
            tcg_temp_free_i64(fp64);
6057
        }
6058
        opn = "ceil.l.s";
6059
        break;
6060
    case FOP(11, 16):
6061
        check_cp1_64bitmode(ctx);
6062
        {
6063
            TCGv_i32 fp32 = tcg_temp_new_i32();
6064
            TCGv_i64 fp64 = tcg_temp_new_i64();
6065

    
6066
            gen_load_fpr32(fp32, fs);
6067
            gen_helper_float_floorl_s(fp64, fp32);
6068
            tcg_temp_free_i32(fp32);
6069
            gen_store_fpr64(ctx, fp64, fd);
6070
            tcg_temp_free_i64(fp64);
6071
        }
6072
        opn = "floor.l.s";
6073
        break;
6074
    case FOP(12, 16):
6075
        {
6076
            TCGv_i32 fp0 = tcg_temp_new_i32();
6077

    
6078
            gen_load_fpr32(fp0, fs);
6079
            gen_helper_float_roundw_s(fp0, fp0);
6080
            gen_store_fpr32(fp0, fd);
6081
            tcg_temp_free_i32(fp0);
6082
        }
6083
        opn = "round.w.s";
6084
        break;
6085
    case FOP(13, 16):
6086
        {
6087
            TCGv_i32 fp0 = tcg_temp_new_i32();
6088

    
6089
            gen_load_fpr32(fp0, fs);
6090
            gen_helper_float_truncw_s(fp0, fp0);
6091
            gen_store_fpr32(fp0, fd);
6092
            tcg_temp_free_i32(fp0);
6093
        }
6094
        opn = "trunc.w.s";
6095
        break;
6096
    case FOP(14, 16):
6097
        {
6098
            TCGv_i32 fp0 = tcg_temp_new_i32();
6099

    
6100
            gen_load_fpr32(fp0, fs);
6101
            gen_helper_float_ceilw_s(fp0, fp0);
6102
            gen_store_fpr32(fp0, fd);
6103
            tcg_temp_free_i32(fp0);
6104
        }
6105
        opn = "ceil.w.s";
6106
        break;
6107
    case FOP(15, 16):
6108
        {
6109
            TCGv_i32 fp0 = tcg_temp_new_i32();
6110

    
6111
            gen_load_fpr32(fp0, fs);
6112
            gen_helper_float_floorw_s(fp0, fp0);
6113
            gen_store_fpr32(fp0, fd);
6114
            tcg_temp_free_i32(fp0);
6115
        }
6116
        opn = "floor.w.s";
6117
        break;
6118
    case FOP(17, 16):
6119
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6120
        opn = "movcf.s";
6121
        break;
6122
    case FOP(18, 16):
6123
        {
6124
            int l1 = gen_new_label();
6125
            TCGv_i32 fp0;
6126

    
6127
            if (ft != 0) {
6128
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6129
            }
6130
            fp0 = tcg_temp_new_i32();
6131
            gen_load_fpr32(fp0, fs);
6132
            gen_store_fpr32(fp0, fd);
6133
            tcg_temp_free_i32(fp0);
6134
            gen_set_label(l1);
6135
        }
6136
        opn = "movz.s";
6137
        break;
6138
    case FOP(19, 16):
6139
        {
6140
            int l1 = gen_new_label();
6141
            TCGv_i32 fp0;
6142

    
6143
            if (ft != 0) {
6144
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6145
                fp0 = tcg_temp_new_i32();
6146
                gen_load_fpr32(fp0, fs);
6147
                gen_store_fpr32(fp0, fd);
6148
                tcg_temp_free_i32(fp0);
6149
                gen_set_label(l1);
6150
            }
6151
        }
6152
        opn = "movn.s";
6153
        break;
6154
    case FOP(21, 16):
6155
        check_cop1x(ctx);
6156
        {
6157
            TCGv_i32 fp0 = tcg_temp_new_i32();
6158

    
6159
            gen_load_fpr32(fp0, fs);
6160
            gen_helper_float_recip_s(fp0, fp0);
6161
            gen_store_fpr32(fp0, fd);
6162
            tcg_temp_free_i32(fp0);
6163
        }
6164
        opn = "recip.s";
6165
        break;
6166
    case FOP(22, 16):
6167
        check_cop1x(ctx);
6168
        {
6169
            TCGv_i32 fp0 = tcg_temp_new_i32();
6170

    
6171
            gen_load_fpr32(fp0, fs);
6172
            gen_helper_float_rsqrt_s(fp0, fp0);
6173
            gen_store_fpr32(fp0, fd);
6174
            tcg_temp_free_i32(fp0);
6175
        }
6176
        opn = "rsqrt.s";
6177
        break;
6178
    case FOP(28, 16):
6179
        check_cp1_64bitmode(ctx);
6180
        {
6181
            TCGv_i32 fp0 = tcg_temp_new_i32();
6182
            TCGv_i32 fp1 = tcg_temp_new_i32();
6183

    
6184
            gen_load_fpr32(fp0, fs);
6185
            gen_load_fpr32(fp1, fd);
6186
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6187
            tcg_temp_free_i32(fp1);
6188
            gen_store_fpr32(fp0, fd);
6189
            tcg_temp_free_i32(fp0);
6190
        }
6191
        opn = "recip2.s";
6192
        break;
6193
    case FOP(29, 16):
6194
        check_cp1_64bitmode(ctx);
6195
        {
6196
            TCGv_i32 fp0 = tcg_temp_new_i32();
6197

    
6198
            gen_load_fpr32(fp0, fs);
6199
            gen_helper_float_recip1_s(fp0, fp0);
6200
            gen_store_fpr32(fp0, fd);
6201
            tcg_temp_free_i32(fp0);
6202
        }
6203
        opn = "recip1.s";
6204
        break;
6205
    case FOP(30, 16):
6206
        check_cp1_64bitmode(ctx);
6207
        {
6208
            TCGv_i32 fp0 = tcg_temp_new_i32();
6209

    
6210
            gen_load_fpr32(fp0, fs);
6211
            gen_helper_float_rsqrt1_s(fp0, fp0);
6212
            gen_store_fpr32(fp0, fd);
6213
            tcg_temp_free_i32(fp0);
6214
        }
6215
        opn = "rsqrt1.s";
6216
        break;
6217
    case FOP(31, 16):
6218
        check_cp1_64bitmode(ctx);
6219
        {
6220
            TCGv_i32 fp0 = tcg_temp_new_i32();
6221
            TCGv_i32 fp1 = tcg_temp_new_i32();
6222

    
6223
            gen_load_fpr32(fp0, fs);
6224
            gen_load_fpr32(fp1, ft);
6225
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6226
            tcg_temp_free_i32(fp1);
6227
            gen_store_fpr32(fp0, fd);
6228
            tcg_temp_free_i32(fp0);
6229
        }
6230
        opn = "rsqrt2.s";
6231
        break;
6232
    case FOP(33, 16):
6233
        check_cp1_registers(ctx, fd);
6234
        {
6235
            TCGv_i32 fp32 = tcg_temp_new_i32();
6236
            TCGv_i64 fp64 = tcg_temp_new_i64();
6237

    
6238
            gen_load_fpr32(fp32, fs);
6239
            gen_helper_float_cvtd_s(fp64, fp32);
6240
            tcg_temp_free_i32(fp32);
6241
            gen_store_fpr64(ctx, fp64, fd);
6242
            tcg_temp_free_i64(fp64);
6243
        }
6244
        opn = "cvt.d.s";
6245
        break;
6246
    case FOP(36, 16):
6247
        {
6248
            TCGv_i32 fp0 = tcg_temp_new_i32();
6249

    
6250
            gen_load_fpr32(fp0, fs);
6251
            gen_helper_float_cvtw_s(fp0, fp0);
6252
            gen_store_fpr32(fp0, fd);
6253
            tcg_temp_free_i32(fp0);
6254
        }
6255
        opn = "cvt.w.s";
6256
        break;
6257
    case FOP(37, 16):
6258
        check_cp1_64bitmode(ctx);
6259
        {
6260
            TCGv_i32 fp32 = tcg_temp_new_i32();
6261
            TCGv_i64 fp64 = tcg_temp_new_i64();
6262

    
6263
            gen_load_fpr32(fp32, fs);
6264
            gen_helper_float_cvtl_s(fp64, fp32);
6265
            tcg_temp_free_i32(fp32);
6266
            gen_store_fpr64(ctx, fp64, fd);
6267
            tcg_temp_free_i64(fp64);
6268
        }
6269
        opn = "cvt.l.s";
6270
        break;
6271
    case FOP(38, 16):
6272
        check_cp1_64bitmode(ctx);
6273
        {
6274
            TCGv_i64 fp64 = tcg_temp_new_i64();
6275
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6276
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6277

    
6278
            gen_load_fpr32(fp32_0, fs);
6279
            gen_load_fpr32(fp32_1, ft);
6280
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6281
            tcg_temp_free_i32(fp32_1);
6282
            tcg_temp_free_i32(fp32_0);
6283
            gen_store_fpr64(ctx, fp64, fd);
6284
            tcg_temp_free_i64(fp64);
6285
        }
6286
        opn = "cvt.ps.s";
6287
        break;
6288
    case FOP(48, 16):
6289
    case FOP(49, 16):
6290
    case FOP(50, 16):
6291
    case FOP(51, 16):
6292
    case FOP(52, 16):
6293
    case FOP(53, 16):
6294
    case FOP(54, 16):
6295
    case FOP(55, 16):
6296
    case FOP(56, 16):
6297
    case FOP(57, 16):
6298
    case FOP(58, 16):
6299
    case FOP(59, 16):
6300
    case FOP(60, 16):
6301
    case FOP(61, 16):
6302
    case FOP(62, 16):
6303
    case FOP(63, 16):
6304
        {
6305
            TCGv_i32 fp0 = tcg_temp_new_i32();
6306
            TCGv_i32 fp1 = tcg_temp_new_i32();
6307

    
6308
            gen_load_fpr32(fp0, fs);
6309
            gen_load_fpr32(fp1, ft);
6310
            if (ctx->opcode & (1 << 6)) {
6311
                check_cop1x(ctx);
6312
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6313
                opn = condnames_abs[func-48];
6314
            } else {
6315
                gen_cmp_s(func-48, fp0, fp1, cc);
6316
                opn = condnames[func-48];
6317
            }
6318
            tcg_temp_free_i32(fp0);
6319
            tcg_temp_free_i32(fp1);
6320
        }
6321
        break;
6322
    case FOP(0, 17):
6323
        check_cp1_registers(ctx, fs | ft | fd);
6324
        {
6325
            TCGv_i64 fp0 = tcg_temp_new_i64();
6326
            TCGv_i64 fp1 = tcg_temp_new_i64();
6327

    
6328
            gen_load_fpr64(ctx, fp0, fs);
6329
            gen_load_fpr64(ctx, fp1, ft);
6330
            gen_helper_float_add_d(fp0, fp0, fp1);
6331
            tcg_temp_free_i64(fp1);
6332
            gen_store_fpr64(ctx, fp0, fd);
6333
            tcg_temp_free_i64(fp0);
6334
        }
6335
        opn = "add.d";
6336
        optype = BINOP;
6337
        break;
6338
    case FOP(1, 17):
6339
        check_cp1_registers(ctx, fs | ft | fd);
6340
        {
6341
            TCGv_i64 fp0 = tcg_temp_new_i64();
6342
            TCGv_i64 fp1 = tcg_temp_new_i64();
6343

    
6344
            gen_load_fpr64(ctx, fp0, fs);
6345
            gen_load_fpr64(ctx, fp1, ft);
6346
            gen_helper_float_sub_d(fp0, fp0, fp1);
6347
            tcg_temp_free_i64(fp1);
6348
            gen_store_fpr64(ctx, fp0, fd);
6349
            tcg_temp_free_i64(fp0);
6350
        }
6351
        opn = "sub.d";
6352
        optype = BINOP;
6353
        break;
6354
    case FOP(2, 17):
6355
        check_cp1_registers(ctx, fs | ft | fd);
6356
        {
6357
            TCGv_i64 fp0 = tcg_temp_new_i64();
6358
            TCGv_i64 fp1 = tcg_temp_new_i64();
6359

    
6360
            gen_load_fpr64(ctx, fp0, fs);
6361
            gen_load_fpr64(ctx, fp1, ft);
6362
            gen_helper_float_mul_d(fp0, fp0, fp1);
6363
            tcg_temp_free_i64(fp1);
6364
            gen_store_fpr64(ctx, fp0, fd);
6365
            tcg_temp_free_i64(fp0);
6366
        }
6367
        opn = "mul.d";
6368
        optype = BINOP;
6369
        break;
6370
    case FOP(3, 17):
6371
        check_cp1_registers(ctx, fs | ft | fd);
6372
        {
6373
            TCGv_i64 fp0 = tcg_temp_new_i64();
6374
            TCGv_i64 fp1 = tcg_temp_new_i64();
6375

    
6376
            gen_load_fpr64(ctx, fp0, fs);
6377
            gen_load_fpr64(ctx, fp1, ft);
6378
            gen_helper_float_div_d(fp0, fp0, fp1);
6379
            tcg_temp_free_i64(fp1);
6380
            gen_store_fpr64(ctx, fp0, fd);
6381
            tcg_temp_free_i64(fp0);
6382
        }
6383
        opn = "div.d";
6384
        optype = BINOP;
6385
        break;
6386
    case FOP(4, 17):
6387
        check_cp1_registers(ctx, fs | fd);
6388
        {
6389
            TCGv_i64 fp0 = tcg_temp_new_i64();
6390

    
6391
            gen_load_fpr64(ctx, fp0, fs);
6392
            gen_helper_float_sqrt_d(fp0, fp0);
6393
            gen_store_fpr64(ctx, fp0, fd);
6394
            tcg_temp_free_i64(fp0);
6395
        }
6396
        opn = "sqrt.d";
6397
        break;
6398
    case FOP(5, 17):
6399
        check_cp1_registers(ctx, fs | fd);
6400
        {
6401
            TCGv_i64 fp0 = tcg_temp_new_i64();
6402

    
6403
            gen_load_fpr64(ctx, fp0, fs);
6404
            gen_helper_float_abs_d(fp0, fp0);
6405
            gen_store_fpr64(ctx, fp0, fd);
6406
            tcg_temp_free_i64(fp0);
6407
        }
6408
        opn = "abs.d";
6409
        break;
6410
    case FOP(6, 17):
6411
        check_cp1_registers(ctx, fs | fd);
6412
        {
6413
            TCGv_i64 fp0 = tcg_temp_new_i64();
6414

    
6415
            gen_load_fpr64(ctx, fp0, fs);
6416
            gen_store_fpr64(ctx, fp0, fd);
6417
            tcg_temp_free_i64(fp0);
6418
        }
6419
        opn = "mov.d";
6420
        break;
6421
    case FOP(7, 17):
6422
        check_cp1_registers(ctx, fs | fd);
6423
        {
6424
            TCGv_i64 fp0 = tcg_temp_new_i64();
6425

    
6426
            gen_load_fpr64(ctx, fp0, fs);
6427
            gen_helper_float_chs_d(fp0, fp0);
6428
            gen_store_fpr64(ctx, fp0, fd);
6429
            tcg_temp_free_i64(fp0);
6430
        }
6431
        opn = "neg.d";
6432
        break;
6433
    case FOP(8, 17):
6434
        check_cp1_64bitmode(ctx);
6435
        {
6436
            TCGv_i64 fp0 = tcg_temp_new_i64();
6437

    
6438
            gen_load_fpr64(ctx, fp0, fs);
6439
            gen_helper_float_roundl_d(fp0, fp0);
6440
            gen_store_fpr64(ctx, fp0, fd);
6441
            tcg_temp_free_i64(fp0);
6442
        }
6443
        opn = "round.l.d";
6444
        break;
6445
    case FOP(9, 17):
6446
        check_cp1_64bitmode(ctx);
6447
        {
6448
            TCGv_i64 fp0 = tcg_temp_new_i64();
6449

    
6450
            gen_load_fpr64(ctx, fp0, fs);
6451
            gen_helper_float_truncl_d(fp0, fp0);
6452
            gen_store_fpr64(ctx, fp0, fd);
6453
            tcg_temp_free_i64(fp0);
6454
        }
6455
        opn = "trunc.l.d";
6456
        break;
6457
    case FOP(10, 17):
6458
        check_cp1_64bitmode(ctx);
6459
        {
6460
            TCGv_i64 fp0 = tcg_temp_new_i64();
6461

    
6462
            gen_load_fpr64(ctx, fp0, fs);
6463
            gen_helper_float_ceill_d(fp0, fp0);
6464
            gen_store_fpr64(ctx, fp0, fd);
6465
            tcg_temp_free_i64(fp0);
6466
        }
6467
        opn = "ceil.l.d";
6468
        break;
6469
    case FOP(11, 17):
6470
        check_cp1_64bitmode(ctx);
6471
        {
6472
            TCGv_i64 fp0 = tcg_temp_new_i64();
6473

    
6474
            gen_load_fpr64(ctx, fp0, fs);
6475
            gen_helper_float_floorl_d(fp0, fp0);
6476
            gen_store_fpr64(ctx, fp0, fd);
6477
            tcg_temp_free_i64(fp0);
6478
        }
6479
        opn = "floor.l.d";
6480
        break;
6481
    case FOP(12, 17):
6482
        check_cp1_registers(ctx, fs);
6483
        {
6484
            TCGv_i32 fp32 = tcg_temp_new_i32();
6485
            TCGv_i64 fp64 = tcg_temp_new_i64();
6486

    
6487
            gen_load_fpr64(ctx, fp64, fs);
6488
            gen_helper_float_roundw_d(fp32, fp64);
6489
            tcg_temp_free_i64(fp64);
6490
            gen_store_fpr32(fp32, fd);
6491
            tcg_temp_free_i32(fp32);
6492
        }
6493
        opn = "round.w.d";
6494
        break;
6495
    case FOP(13, 17):
6496
        check_cp1_registers(ctx, fs);
6497
        {
6498
            TCGv_i32 fp32 = tcg_temp_new_i32();
6499
            TCGv_i64 fp64 = tcg_temp_new_i64();
6500

    
6501
            gen_load_fpr64(ctx, fp64, fs);
6502
            gen_helper_float_truncw_d(fp32, fp64);
6503
            tcg_temp_free_i64(fp64);
6504
            gen_store_fpr32(fp32, fd);
6505
            tcg_temp_free_i32(fp32);
6506
        }
6507
        opn = "trunc.w.d";
6508
        break;
6509
    case FOP(14, 17):
6510
        check_cp1_registers(ctx, fs);
6511
        {
6512
            TCGv_i32 fp32 = tcg_temp_new_i32();
6513
            TCGv_i64 fp64 = tcg_temp_new_i64();
6514

    
6515
            gen_load_fpr64(ctx, fp64, fs);
6516
            gen_helper_float_ceilw_d(fp32, fp64);
6517
            tcg_temp_free_i64(fp64);
6518
            gen_store_fpr32(fp32, fd);
6519
            tcg_temp_free_i32(fp32);
6520
        }
6521
        opn = "ceil.w.d";
6522
        break;
6523
    case FOP(15, 17):
6524
        check_cp1_registers(ctx, fs);
6525
        {
6526
            TCGv_i32 fp32 = tcg_temp_new_i32();
6527
            TCGv_i64 fp64 = tcg_temp_new_i64();
6528

    
6529
            gen_load_fpr64(ctx, fp64, fs);
6530
            gen_helper_float_floorw_d(fp32, fp64);
6531
            tcg_temp_free_i64(fp64);
6532
            gen_store_fpr32(fp32, fd);
6533
            tcg_temp_free_i32(fp32);
6534
        }
6535
        opn = "floor.w.d";
6536
        break;
6537
    case FOP(17, 17):
6538
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6539
        opn = "movcf.d";
6540
        break;
6541
    case FOP(18, 17):
6542
        {
6543
            int l1 = gen_new_label();
6544
            TCGv_i64 fp0;
6545

    
6546
            if (ft != 0) {
6547
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6548
            }
6549
            fp0 = tcg_temp_new_i64();
6550
            gen_load_fpr64(ctx, fp0, fs);
6551
            gen_store_fpr64(ctx, fp0, fd);
6552
            tcg_temp_free_i64(fp0);
6553
            gen_set_label(l1);
6554
        }
6555
        opn = "movz.d";
6556
        break;
6557
    case FOP(19, 17):
6558
        {
6559
            int l1 = gen_new_label();
6560
            TCGv_i64 fp0;
6561

    
6562
            if (ft != 0) {
6563
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6564
                fp0 = tcg_temp_new_i64();
6565
                gen_load_fpr64(ctx, fp0, fs);
6566
                gen_store_fpr64(ctx, fp0, fd);
6567
                tcg_temp_free_i64(fp0);
6568
                gen_set_label(l1);
6569
            }
6570
        }
6571
        opn = "movn.d";
6572
        break;
6573
    case FOP(21, 17):
6574
        check_cp1_64bitmode(ctx);
6575
        {
6576
            TCGv_i64 fp0 = tcg_temp_new_i64();
6577

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

    
6590
            gen_load_fpr64(ctx, fp0, fs);
6591
            gen_helper_float_rsqrt_d(fp0, fp0);
6592
            gen_store_fpr64(ctx, fp0, fd);
6593
            tcg_temp_free_i64(fp0);
6594
        }
6595
        opn = "rsqrt.d";
6596
        break;
6597
    case FOP(28, 17):
6598
        check_cp1_64bitmode(ctx);
6599
        {
6600
            TCGv_i64 fp0 = tcg_temp_new_i64();
6601
            TCGv_i64 fp1 = tcg_temp_new_i64();
6602

    
6603
            gen_load_fpr64(ctx, fp0, fs);
6604
            gen_load_fpr64(ctx, fp1, ft);
6605
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6606
            tcg_temp_free_i64(fp1);
6607
            gen_store_fpr64(ctx, fp0, fd);
6608
            tcg_temp_free_i64(fp0);
6609
        }
6610
        opn = "recip2.d";
6611
        break;
6612
    case FOP(29, 17):
6613
        check_cp1_64bitmode(ctx);
6614
        {
6615
            TCGv_i64 fp0 = tcg_temp_new_i64();
6616

    
6617
            gen_load_fpr64(ctx, fp0, fs);
6618
            gen_helper_float_recip1_d(fp0, fp0);
6619
            gen_store_fpr64(ctx, fp0, fd);
6620
            tcg_temp_free_i64(fp0);
6621
        }
6622
        opn = "recip1.d";
6623
        break;
6624
    case FOP(30, 17):
6625
        check_cp1_64bitmode(ctx);
6626
        {
6627
            TCGv_i64 fp0 = tcg_temp_new_i64();
6628

    
6629
            gen_load_fpr64(ctx, fp0, fs);
6630
            gen_helper_float_rsqrt1_d(fp0, fp0);
6631
            gen_store_fpr64(ctx, fp0, fd);
6632
            tcg_temp_free_i64(fp0);
6633
        }
6634
        opn = "rsqrt1.d";
6635
        break;
6636
    case FOP(31, 17):
6637
        check_cp1_64bitmode(ctx);
6638
        {
6639
            TCGv_i64 fp0 = tcg_temp_new_i64();
6640
            TCGv_i64 fp1 = tcg_temp_new_i64();
6641

    
6642
            gen_load_fpr64(ctx, fp0, fs);
6643
            gen_load_fpr64(ctx, fp1, ft);
6644
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6645
            tcg_temp_free_i64(fp1);
6646
            gen_store_fpr64(ctx, fp0, fd);
6647
            tcg_temp_free_i64(fp0);
6648
        }
6649
        opn = "rsqrt2.d";
6650
        break;
6651
    case FOP(48, 17):
6652
    case FOP(49, 17):
6653
    case FOP(50, 17):
6654
    case FOP(51, 17):
6655
    case FOP(52, 17):
6656
    case FOP(53, 17):
6657
    case FOP(54, 17):
6658
    case FOP(55, 17):
6659
    case FOP(56, 17):
6660
    case FOP(57, 17):
6661
    case FOP(58, 17):
6662
    case FOP(59, 17):
6663
    case FOP(60, 17):
6664
    case FOP(61, 17):
6665
    case FOP(62, 17):
6666
    case FOP(63, 17):
6667
        {
6668
            TCGv_i64 fp0 = tcg_temp_new_i64();
6669
            TCGv_i64 fp1 = tcg_temp_new_i64();
6670

    
6671
            gen_load_fpr64(ctx, fp0, fs);
6672
            gen_load_fpr64(ctx, fp1, ft);
6673
            if (ctx->opcode & (1 << 6)) {
6674
                check_cop1x(ctx);
6675
                check_cp1_registers(ctx, fs | ft);
6676
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6677
                opn = condnames_abs[func-48];
6678
            } else {
6679
                check_cp1_registers(ctx, fs | ft);
6680
                gen_cmp_d(func-48, fp0, fp1, cc);
6681
                opn = condnames[func-48];
6682
            }
6683
            tcg_temp_free_i64(fp0);
6684
            tcg_temp_free_i64(fp1);
6685
        }
6686
        break;
6687
    case FOP(32, 17):
6688
        check_cp1_registers(ctx, fs);
6689
        {
6690
            TCGv_i32 fp32 = tcg_temp_new_i32();
6691
            TCGv_i64 fp64 = tcg_temp_new_i64();
6692

    
6693
            gen_load_fpr64(ctx, fp64, fs);
6694
            gen_helper_float_cvts_d(fp32, fp64);
6695
            tcg_temp_free_i64(fp64);
6696
            gen_store_fpr32(fp32, fd);
6697
            tcg_temp_free_i32(fp32);
6698
        }
6699
        opn = "cvt.s.d";
6700
        break;
6701
    case FOP(36, 17):
6702
        check_cp1_registers(ctx, fs);
6703
        {
6704
            TCGv_i32 fp32 = tcg_temp_new_i32();
6705
            TCGv_i64 fp64 = tcg_temp_new_i64();
6706

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

    
6720
            gen_load_fpr64(ctx, fp0, fs);
6721
            gen_helper_float_cvtl_d(fp0, fp0);
6722
            gen_store_fpr64(ctx, fp0, fd);
6723
            tcg_temp_free_i64(fp0);
6724
        }
6725
        opn = "cvt.l.d";
6726
        break;
6727
    case FOP(32, 20):
6728
        {
6729
            TCGv_i32 fp0 = tcg_temp_new_i32();
6730

    
6731
            gen_load_fpr32(fp0, fs);
6732
            gen_helper_float_cvts_w(fp0, fp0);
6733
            gen_store_fpr32(fp0, fd);
6734
            tcg_temp_free_i32(fp0);
6735
        }
6736
        opn = "cvt.s.w";
6737
        break;
6738
    case FOP(33, 20):
6739
        check_cp1_registers(ctx, fd);
6740
        {
6741
            TCGv_i32 fp32 = tcg_temp_new_i32();
6742
            TCGv_i64 fp64 = tcg_temp_new_i64();
6743

    
6744
            gen_load_fpr32(fp32, fs);
6745
            gen_helper_float_cvtd_w(fp64, fp32);
6746
            tcg_temp_free_i32(fp32);
6747
            gen_store_fpr64(ctx, fp64, fd);
6748
            tcg_temp_free_i64(fp64);
6749
        }
6750
        opn = "cvt.d.w";
6751
        break;
6752
    case FOP(32, 21):
6753
        check_cp1_64bitmode(ctx);
6754
        {
6755
            TCGv_i32 fp32 = tcg_temp_new_i32();
6756
            TCGv_i64 fp64 = tcg_temp_new_i64();
6757

    
6758
            gen_load_fpr64(ctx, fp64, fs);
6759
            gen_helper_float_cvts_l(fp32, fp64);
6760
            tcg_temp_free_i64(fp64);
6761
            gen_store_fpr32(fp32, fd);
6762
            tcg_temp_free_i32(fp32);
6763
        }
6764
        opn = "cvt.s.l";
6765
        break;
6766
    case FOP(33, 21):
6767
        check_cp1_64bitmode(ctx);
6768
        {
6769
            TCGv_i64 fp0 = tcg_temp_new_i64();
6770

    
6771
            gen_load_fpr64(ctx, fp0, fs);
6772
            gen_helper_float_cvtd_l(fp0, fp0);
6773
            gen_store_fpr64(ctx, fp0, fd);
6774
            tcg_temp_free_i64(fp0);
6775
        }
6776
        opn = "cvt.d.l";
6777
        break;
6778
    case FOP(38, 20):
6779
        check_cp1_64bitmode(ctx);
6780
        {
6781
            TCGv_i64 fp0 = tcg_temp_new_i64();
6782

    
6783
            gen_load_fpr64(ctx, fp0, fs);
6784
            gen_helper_float_cvtps_pw(fp0, fp0);
6785
            gen_store_fpr64(ctx, fp0, fd);
6786
            tcg_temp_free_i64(fp0);
6787
        }
6788
        opn = "cvt.ps.pw";
6789
        break;
6790
    case FOP(0, 22):
6791
        check_cp1_64bitmode(ctx);
6792
        {
6793
            TCGv_i64 fp0 = tcg_temp_new_i64();
6794
            TCGv_i64 fp1 = tcg_temp_new_i64();
6795

    
6796
            gen_load_fpr64(ctx, fp0, fs);
6797
            gen_load_fpr64(ctx, fp1, ft);
6798
            gen_helper_float_add_ps(fp0, fp0, fp1);
6799
            tcg_temp_free_i64(fp1);
6800
            gen_store_fpr64(ctx, fp0, fd);
6801
            tcg_temp_free_i64(fp0);
6802
        }
6803
        opn = "add.ps";
6804
        break;
6805
    case FOP(1, 22):
6806
        check_cp1_64bitmode(ctx);
6807
        {
6808
            TCGv_i64 fp0 = tcg_temp_new_i64();
6809
            TCGv_i64 fp1 = tcg_temp_new_i64();
6810

    
6811
            gen_load_fpr64(ctx, fp0, fs);
6812
            gen_load_fpr64(ctx, fp1, ft);
6813
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6814
            tcg_temp_free_i64(fp1);
6815
            gen_store_fpr64(ctx, fp0, fd);
6816
            tcg_temp_free_i64(fp0);
6817
        }
6818
        opn = "sub.ps";
6819
        break;
6820
    case FOP(2, 22):
6821
        check_cp1_64bitmode(ctx);
6822
        {
6823
            TCGv_i64 fp0 = tcg_temp_new_i64();
6824
            TCGv_i64 fp1 = tcg_temp_new_i64();
6825

    
6826
            gen_load_fpr64(ctx, fp0, fs);
6827
            gen_load_fpr64(ctx, fp1, ft);
6828
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6829
            tcg_temp_free_i64(fp1);
6830
            gen_store_fpr64(ctx, fp0, fd);
6831
            tcg_temp_free_i64(fp0);
6832
        }
6833
        opn = "mul.ps";
6834
        break;
6835
    case FOP(5, 22):
6836
        check_cp1_64bitmode(ctx);
6837
        {
6838
            TCGv_i64 fp0 = tcg_temp_new_i64();
6839

    
6840
            gen_load_fpr64(ctx, fp0, fs);
6841
            gen_helper_float_abs_ps(fp0, fp0);
6842
            gen_store_fpr64(ctx, fp0, fd);
6843
            tcg_temp_free_i64(fp0);
6844
        }
6845
        opn = "abs.ps";
6846
        break;
6847
    case FOP(6, 22):
6848
        check_cp1_64bitmode(ctx);
6849
        {
6850
            TCGv_i64 fp0 = tcg_temp_new_i64();
6851

    
6852
            gen_load_fpr64(ctx, fp0, fs);
6853
            gen_store_fpr64(ctx, fp0, fd);
6854
            tcg_temp_free_i64(fp0);
6855
        }
6856
        opn = "mov.ps";
6857
        break;
6858
    case FOP(7, 22):
6859
        check_cp1_64bitmode(ctx);
6860
        {
6861
            TCGv_i64 fp0 = tcg_temp_new_i64();
6862

    
6863
            gen_load_fpr64(ctx, fp0, fs);
6864
            gen_helper_float_chs_ps(fp0, fp0);
6865
            gen_store_fpr64(ctx, fp0, fd);
6866
            tcg_temp_free_i64(fp0);
6867
        }
6868
        opn = "neg.ps";
6869
        break;
6870
    case FOP(17, 22):
6871
        check_cp1_64bitmode(ctx);
6872
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6873
        opn = "movcf.ps";
6874
        break;
6875
    case FOP(18, 22):
6876
        check_cp1_64bitmode(ctx);
6877
        {
6878
            int l1 = gen_new_label();
6879
            TCGv_i32 fp0;
6880

    
6881
            if (ft != 0)
6882
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6883
            fp0 = tcg_temp_new_i64();
6884
            gen_load_fpr64(ctx, fp0, fs);
6885
            gen_store_fpr64(ctx, fp0, fd);
6886
            tcg_temp_free_i64(fp0);
6887
            gen_set_label(l1);
6888
        }
6889
        opn = "movz.ps";
6890
        break;
6891
    case FOP(19, 22):
6892
        check_cp1_64bitmode(ctx);
6893
        {
6894
            int l1 = gen_new_label();
6895
            TCGv_i32 fp0;
6896

    
6897
            if (ft != 0) {
6898
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6899
                fp0 = tcg_temp_new_i64();
6900
                gen_load_fpr64(ctx, fp0, fs);
6901
                gen_store_fpr64(ctx, fp0, fd);
6902
                tcg_temp_free_i64(fp0);
6903
                gen_set_label(l1);
6904
            }
6905
        }
6906
        opn = "movn.ps";
6907
        break;
6908
    case FOP(24, 22):
6909
        check_cp1_64bitmode(ctx);
6910
        {
6911
            TCGv_i64 fp0 = tcg_temp_new_i64();
6912
            TCGv_i64 fp1 = tcg_temp_new_i64();
6913

    
6914
            gen_load_fpr64(ctx, fp0, ft);
6915
            gen_load_fpr64(ctx, fp1, fs);
6916
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6917
            tcg_temp_free_i64(fp1);
6918
            gen_store_fpr64(ctx, fp0, fd);
6919
            tcg_temp_free_i64(fp0);
6920
        }
6921
        opn = "addr.ps";
6922
        break;
6923
    case FOP(26, 22):
6924
        check_cp1_64bitmode(ctx);
6925
        {
6926
            TCGv_i64 fp0 = tcg_temp_new_i64();
6927
            TCGv_i64 fp1 = tcg_temp_new_i64();
6928

    
6929
            gen_load_fpr64(ctx, fp0, ft);
6930
            gen_load_fpr64(ctx, fp1, fs);
6931
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6932
            tcg_temp_free_i64(fp1);
6933
            gen_store_fpr64(ctx, fp0, fd);
6934
            tcg_temp_free_i64(fp0);
6935
        }
6936
        opn = "mulr.ps";
6937
        break;
6938
    case FOP(28, 22):
6939
        check_cp1_64bitmode(ctx);
6940
        {
6941
            TCGv_i64 fp0 = tcg_temp_new_i64();
6942
            TCGv_i64 fp1 = tcg_temp_new_i64();
6943

    
6944
            gen_load_fpr64(ctx, fp0, fs);
6945
            gen_load_fpr64(ctx, fp1, fd);
6946
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6947
            tcg_temp_free_i64(fp1);
6948
            gen_store_fpr64(ctx, fp0, fd);
6949
            tcg_temp_free_i64(fp0);
6950
        }
6951
        opn = "recip2.ps";
6952
        break;
6953
    case FOP(29, 22):
6954
        check_cp1_64bitmode(ctx);
6955
        {
6956
            TCGv_i64 fp0 = tcg_temp_new_i64();
6957

    
6958
            gen_load_fpr64(ctx, fp0, fs);
6959
            gen_helper_float_recip1_ps(fp0, fp0);
6960
            gen_store_fpr64(ctx, fp0, fd);
6961
            tcg_temp_free_i64(fp0);
6962
        }
6963
        opn = "recip1.ps";
6964
        break;
6965
    case FOP(30, 22):
6966
        check_cp1_64bitmode(ctx);
6967
        {
6968
            TCGv_i64 fp0 = tcg_temp_new_i64();
6969

    
6970
            gen_load_fpr64(ctx, fp0, fs);
6971
            gen_helper_float_rsqrt1_ps(fp0, fp0);
6972
            gen_store_fpr64(ctx, fp0, fd);
6973
            tcg_temp_free_i64(fp0);
6974
        }
6975
        opn = "rsqrt1.ps";
6976
        break;
6977
    case FOP(31, 22):
6978
        check_cp1_64bitmode(ctx);
6979
        {
6980
            TCGv_i64 fp0 = tcg_temp_new_i64();
6981
            TCGv_i64 fp1 = tcg_temp_new_i64();
6982

    
6983
            gen_load_fpr64(ctx, fp0, fs);
6984
            gen_load_fpr64(ctx, fp1, ft);
6985
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
6986
            tcg_temp_free_i64(fp1);
6987
            gen_store_fpr64(ctx, fp0, fd);
6988
            tcg_temp_free_i64(fp0);
6989
        }
6990
        opn = "rsqrt2.ps";
6991
        break;
6992
    case FOP(32, 22):
6993
        check_cp1_64bitmode(ctx);
6994
        {
6995
            TCGv_i32 fp0 = tcg_temp_new_i32();
6996

    
6997
            gen_load_fpr32h(fp0, fs);
6998
            gen_helper_float_cvts_pu(fp0, fp0);
6999
            gen_store_fpr32(fp0, fd);
7000
            tcg_temp_free_i32(fp0);
7001
        }
7002
        opn = "cvt.s.pu";
7003
        break;
7004
    case FOP(36, 22):
7005
        check_cp1_64bitmode(ctx);
7006
        {
7007
            TCGv_i64 fp0 = tcg_temp_new_i64();
7008

    
7009
            gen_load_fpr64(ctx, fp0, fs);
7010
            gen_helper_float_cvtpw_ps(fp0, fp0);
7011
            gen_store_fpr64(ctx, fp0, fd);
7012
            tcg_temp_free_i64(fp0);
7013
        }
7014
        opn = "cvt.pw.ps";
7015
        break;
7016
    case FOP(40, 22):
7017
        check_cp1_64bitmode(ctx);
7018
        {
7019
            TCGv_i32 fp0 = tcg_temp_new_i32();
7020

    
7021
            gen_load_fpr32(fp0, fs);
7022
            gen_helper_float_cvts_pl(fp0, fp0);
7023
            gen_store_fpr32(fp0, fd);
7024
            tcg_temp_free_i32(fp0);
7025
        }
7026
        opn = "cvt.s.pl";
7027
        break;
7028
    case FOP(44, 22):
7029
        check_cp1_64bitmode(ctx);
7030
        {
7031
            TCGv_i32 fp0 = tcg_temp_new_i32();
7032
            TCGv_i32 fp1 = tcg_temp_new_i32();
7033

    
7034
            gen_load_fpr32(fp0, fs);
7035
            gen_load_fpr32(fp1, ft);
7036
            gen_store_fpr32h(fp0, fd);
7037
            gen_store_fpr32(fp1, fd);
7038
            tcg_temp_free_i32(fp0);
7039
            tcg_temp_free_i32(fp1);
7040
        }
7041
        opn = "pll.ps";
7042
        break;
7043
    case FOP(45, 22):
7044
        check_cp1_64bitmode(ctx);
7045
        {
7046
            TCGv_i32 fp0 = tcg_temp_new_i32();
7047
            TCGv_i32 fp1 = tcg_temp_new_i32();
7048

    
7049
            gen_load_fpr32(fp0, fs);
7050
            gen_load_fpr32h(fp1, ft);
7051
            gen_store_fpr32(fp1, fd);
7052
            gen_store_fpr32h(fp0, fd);
7053
            tcg_temp_free_i32(fp0);
7054
            tcg_temp_free_i32(fp1);
7055
        }
7056
        opn = "plu.ps";
7057
        break;
7058
    case FOP(46, 22):
7059
        check_cp1_64bitmode(ctx);
7060
        {
7061
            TCGv_i32 fp0 = tcg_temp_new_i32();
7062
            TCGv_i32 fp1 = tcg_temp_new_i32();
7063

    
7064
            gen_load_fpr32h(fp0, fs);
7065
            gen_load_fpr32(fp1, ft);
7066
            gen_store_fpr32(fp1, fd);
7067
            gen_store_fpr32h(fp0, fd);
7068
            tcg_temp_free_i32(fp0);
7069
            tcg_temp_free_i32(fp1);
7070
        }
7071
        opn = "pul.ps";
7072
        break;
7073
    case FOP(47, 22):
7074
        check_cp1_64bitmode(ctx);
7075
        {
7076
            TCGv_i32 fp0 = tcg_temp_new_i32();
7077
            TCGv_i32 fp1 = tcg_temp_new_i32();
7078

    
7079
            gen_load_fpr32h(fp0, fs);
7080
            gen_load_fpr32h(fp1, ft);
7081
            gen_store_fpr32(fp1, fd);
7082
            gen_store_fpr32h(fp0, fd);
7083
            tcg_temp_free_i32(fp0);
7084
            tcg_temp_free_i32(fp1);
7085
        }
7086
        opn = "puu.ps";
7087
        break;
7088
    case FOP(48, 22):
7089
    case FOP(49, 22):
7090
    case FOP(50, 22):
7091
    case FOP(51, 22):
7092
    case FOP(52, 22):
7093
    case FOP(53, 22):
7094
    case FOP(54, 22):
7095
    case FOP(55, 22):
7096
    case FOP(56, 22):
7097
    case FOP(57, 22):
7098
    case FOP(58, 22):
7099
    case FOP(59, 22):
7100
    case FOP(60, 22):
7101
    case FOP(61, 22):
7102
    case FOP(62, 22):
7103
    case FOP(63, 22):
7104
        check_cp1_64bitmode(ctx);
7105
        {
7106
            TCGv_i64 fp0 = tcg_temp_new_i64();
7107
            TCGv_i64 fp1 = tcg_temp_new_i64();
7108

    
7109
            gen_load_fpr64(ctx, fp0, fs);
7110
            gen_load_fpr64(ctx, fp1, ft);
7111
            if (ctx->opcode & (1 << 6)) {
7112
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7113
                opn = condnames_abs[func-48];
7114
            } else {
7115
                gen_cmp_ps(func-48, fp0, fp1, cc);
7116
                opn = condnames[func-48];
7117
            }
7118
            tcg_temp_free_i64(fp0);
7119
            tcg_temp_free_i64(fp1);
7120
        }
7121
        break;
7122
    default:
7123
        MIPS_INVAL(opn);
7124
        generate_exception (ctx, EXCP_RI);
7125
        return;
7126
    }
7127
    switch (optype) {
7128
    case BINOP:
7129
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7130
        break;
7131
    case CMPOP:
7132
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7133
        break;
7134
    default:
7135
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7136
        break;
7137
    }
7138
}
7139

    
7140
/* Coprocessor 3 (FPU) */
7141
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7142
                           int fd, int fs, int base, int index)
7143
{
7144
    const char *opn = "extended float load/store";
7145
    int store = 0;
7146
    TCGv t0 = tcg_temp_new();
7147
    TCGv t1 = tcg_temp_new();
7148

    
7149
    if (base == 0) {
7150
        gen_load_gpr(t0, index);
7151
    } else if (index == 0) {
7152
        gen_load_gpr(t0, base);
7153
    } else {
7154
        gen_load_gpr(t0, index);
7155
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7156
    }
7157
    /* Don't do NOP if destination is zero: we must perform the actual
7158
       memory access. */
7159
    save_cpu_state(ctx, 0);
7160
    switch (opc) {
7161
    case OPC_LWXC1:
7162
        check_cop1x(ctx);
7163
        {
7164
            TCGv_i32 fp0 = tcg_temp_new_i32();
7165

    
7166
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7167
            tcg_gen_trunc_tl_i32(fp0, t1);
7168
            gen_store_fpr32(fp0, fd);
7169
            tcg_temp_free_i32(fp0);
7170
        }
7171
        opn = "lwxc1";
7172
        break;
7173
    case OPC_LDXC1:
7174
        check_cop1x(ctx);
7175
        check_cp1_registers(ctx, fd);
7176
        {
7177
            TCGv_i64 fp0 = tcg_temp_new_i64();
7178

    
7179
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7180
            gen_store_fpr64(ctx, fp0, fd);
7181
            tcg_temp_free_i64(fp0);
7182
        }
7183
        opn = "ldxc1";
7184
        break;
7185
    case OPC_LUXC1:
7186
        check_cp1_64bitmode(ctx);
7187
        tcg_gen_andi_tl(t0, t0, ~0x7);
7188
        {
7189
            TCGv_i64 fp0 = tcg_temp_new_i64();
7190

    
7191
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7192
            gen_store_fpr64(ctx, fp0, fd);
7193
            tcg_temp_free_i64(fp0);
7194
        }
7195
        opn = "luxc1";
7196
        break;
7197
    case OPC_SWXC1:
7198
        check_cop1x(ctx);
7199
        {
7200
            TCGv_i32 fp0 = tcg_temp_new_i32();
7201

    
7202
            gen_load_fpr32(fp0, fs);
7203
            tcg_gen_extu_i32_tl(t1, fp0);
7204
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7205
            tcg_temp_free_i32(fp0);
7206
        }
7207
        opn = "swxc1";
7208
        store = 1;
7209
        break;
7210
    case OPC_SDXC1:
7211
        check_cop1x(ctx);
7212
        check_cp1_registers(ctx, fs);
7213
        {
7214
            TCGv_i64 fp0 = tcg_temp_new_i64();
7215

    
7216
            gen_load_fpr64(ctx, fp0, fs);
7217
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7218
            tcg_temp_free_i64(fp0);
7219
        }
7220
        opn = "sdxc1";
7221
        store = 1;
7222
        break;
7223
    case OPC_SUXC1:
7224
        check_cp1_64bitmode(ctx);
7225
        tcg_gen_andi_tl(t0, t0, ~0x7);
7226
        {
7227
            TCGv_i64 fp0 = tcg_temp_new_i64();
7228

    
7229
            gen_load_fpr64(ctx, fp0, fs);
7230
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7231
            tcg_temp_free_i64(fp0);
7232
        }
7233
        opn = "suxc1";
7234
        store = 1;
7235
        break;
7236
    }
7237
    tcg_temp_free(t0);
7238
    tcg_temp_free(t1);
7239
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7240
               regnames[index], regnames[base]);
7241
}
7242

    
7243
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7244
                            int fd, int fr, int fs, int ft)
7245
{
7246
    const char *opn = "flt3_arith";
7247

    
7248
    switch (opc) {
7249
    case OPC_ALNV_PS:
7250
        check_cp1_64bitmode(ctx);
7251
        {
7252
            TCGv t0 = tcg_temp_local_new();
7253
            TCGv_i32 fp = tcg_temp_new_i32();
7254
            TCGv_i32 fph = tcg_temp_new_i32();
7255
            int l1 = gen_new_label();
7256
            int l2 = gen_new_label();
7257

    
7258
            gen_load_gpr(t0, fr);
7259
            tcg_gen_andi_tl(t0, t0, 0x7);
7260

    
7261
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7262
            gen_load_fpr32(fp, fs);
7263
            gen_load_fpr32h(fph, fs);
7264
            gen_store_fpr32(fp, fd);
7265
            gen_store_fpr32h(fph, fd);
7266
            tcg_gen_br(l2);
7267
            gen_set_label(l1);
7268
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7269
            tcg_temp_free(t0);
7270
#ifdef TARGET_WORDS_BIGENDIAN
7271
            gen_load_fpr32(fp, fs);
7272
            gen_load_fpr32h(fph, ft);
7273
            gen_store_fpr32h(fp, fd);
7274
            gen_store_fpr32(fph, fd);
7275
#else
7276
            gen_load_fpr32h(fph, fs);
7277
            gen_load_fpr32(fp, ft);
7278
            gen_store_fpr32(fph, fd);
7279
            gen_store_fpr32h(fp, fd);
7280
#endif
7281
            gen_set_label(l2);
7282
            tcg_temp_free_i32(fp);
7283
            tcg_temp_free_i32(fph);
7284
        }
7285
        opn = "alnv.ps";
7286
        break;
7287
    case OPC_MADD_S:
7288
        check_cop1x(ctx);
7289
        {
7290
            TCGv_i32 fp0 = tcg_temp_new_i32();
7291
            TCGv_i32 fp1 = tcg_temp_new_i32();
7292
            TCGv_i32 fp2 = tcg_temp_new_i32();
7293

    
7294
            gen_load_fpr32(fp0, fs);
7295
            gen_load_fpr32(fp1, ft);
7296
            gen_load_fpr32(fp2, fr);
7297
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7298
            tcg_temp_free_i32(fp0);
7299
            tcg_temp_free_i32(fp1);
7300
            gen_store_fpr32(fp2, fd);
7301
            tcg_temp_free_i32(fp2);
7302
        }
7303
        opn = "madd.s";
7304
        break;
7305
    case OPC_MADD_D:
7306
        check_cop1x(ctx);
7307
        check_cp1_registers(ctx, fd | fs | ft | fr);
7308
        {
7309
            TCGv_i64 fp0 = tcg_temp_new_i64();
7310
            TCGv_i64 fp1 = tcg_temp_new_i64();
7311
            TCGv_i64 fp2 = tcg_temp_new_i64();
7312

    
7313
            gen_load_fpr64(ctx, fp0, fs);
7314
            gen_load_fpr64(ctx, fp1, ft);
7315
            gen_load_fpr64(ctx, fp2, fr);
7316
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7317
            tcg_temp_free_i64(fp0);
7318
            tcg_temp_free_i64(fp1);
7319
            gen_store_fpr64(ctx, fp2, fd);
7320
            tcg_temp_free_i64(fp2);
7321
        }
7322
        opn = "madd.d";
7323
        break;
7324
    case OPC_MADD_PS:
7325
        check_cp1_64bitmode(ctx);
7326
        {
7327
            TCGv_i64 fp0 = tcg_temp_new_i64();
7328
            TCGv_i64 fp1 = tcg_temp_new_i64();
7329
            TCGv_i64 fp2 = tcg_temp_new_i64();
7330

    
7331
            gen_load_fpr64(ctx, fp0, fs);
7332
            gen_load_fpr64(ctx, fp1, ft);
7333
            gen_load_fpr64(ctx, fp2, fr);
7334
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7335
            tcg_temp_free_i64(fp0);
7336
            tcg_temp_free_i64(fp1);
7337
            gen_store_fpr64(ctx, fp2, fd);
7338
            tcg_temp_free_i64(fp2);
7339
        }
7340
        opn = "madd.ps";
7341
        break;
7342
    case OPC_MSUB_S:
7343
        check_cop1x(ctx);
7344
        {
7345
            TCGv_i32 fp0 = tcg_temp_new_i32();
7346
            TCGv_i32 fp1 = tcg_temp_new_i32();
7347
            TCGv_i32 fp2 = tcg_temp_new_i32();
7348

    
7349
            gen_load_fpr32(fp0, fs);
7350
            gen_load_fpr32(fp1, ft);
7351
            gen_load_fpr32(fp2, fr);
7352
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7353
            tcg_temp_free_i32(fp0);
7354
            tcg_temp_free_i32(fp1);
7355
            gen_store_fpr32(fp2, fd);
7356
            tcg_temp_free_i32(fp2);
7357
        }
7358
        opn = "msub.s";
7359
        break;
7360
    case OPC_MSUB_D:
7361
        check_cop1x(ctx);
7362
        check_cp1_registers(ctx, fd | fs | ft | fr);
7363
        {
7364
            TCGv_i64 fp0 = tcg_temp_new_i64();
7365
            TCGv_i64 fp1 = tcg_temp_new_i64();
7366
            TCGv_i64 fp2 = tcg_temp_new_i64();
7367

    
7368
            gen_load_fpr64(ctx, fp0, fs);
7369
            gen_load_fpr64(ctx, fp1, ft);
7370
            gen_load_fpr64(ctx, fp2, fr);
7371
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7372
            tcg_temp_free_i64(fp0);
7373
            tcg_temp_free_i64(fp1);
7374
            gen_store_fpr64(ctx, fp2, fd);
7375
            tcg_temp_free_i64(fp2);
7376
        }
7377
        opn = "msub.d";
7378
        break;
7379
    case OPC_MSUB_PS:
7380
        check_cp1_64bitmode(ctx);
7381
        {
7382
            TCGv_i64 fp0 = tcg_temp_new_i64();
7383
            TCGv_i64 fp1 = tcg_temp_new_i64();
7384
            TCGv_i64 fp2 = tcg_temp_new_i64();
7385

    
7386
            gen_load_fpr64(ctx, fp0, fs);
7387
            gen_load_fpr64(ctx, fp1, ft);
7388
            gen_load_fpr64(ctx, fp2, fr);
7389
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7390
            tcg_temp_free_i64(fp0);
7391
            tcg_temp_free_i64(fp1);
7392
            gen_store_fpr64(ctx, fp2, fd);
7393
            tcg_temp_free_i64(fp2);
7394
        }
7395
        opn = "msub.ps";
7396
        break;
7397
    case OPC_NMADD_S:
7398
        check_cop1x(ctx);
7399
        {
7400
            TCGv_i32 fp0 = tcg_temp_new_i32();
7401
            TCGv_i32 fp1 = tcg_temp_new_i32();
7402
            TCGv_i32 fp2 = tcg_temp_new_i32();
7403

    
7404
            gen_load_fpr32(fp0, fs);
7405
            gen_load_fpr32(fp1, ft);
7406
            gen_load_fpr32(fp2, fr);
7407
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7408
            tcg_temp_free_i32(fp0);
7409
            tcg_temp_free_i32(fp1);
7410
            gen_store_fpr32(fp2, fd);
7411
            tcg_temp_free_i32(fp2);
7412
        }
7413
        opn = "nmadd.s";
7414
        break;
7415
    case OPC_NMADD_D:
7416
        check_cop1x(ctx);
7417
        check_cp1_registers(ctx, fd | fs | ft | fr);
7418
        {
7419
            TCGv_i64 fp0 = tcg_temp_new_i64();
7420
            TCGv_i64 fp1 = tcg_temp_new_i64();
7421
            TCGv_i64 fp2 = tcg_temp_new_i64();
7422

    
7423
            gen_load_fpr64(ctx, fp0, fs);
7424
            gen_load_fpr64(ctx, fp1, ft);
7425
            gen_load_fpr64(ctx, fp2, fr);
7426
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7427
            tcg_temp_free_i64(fp0);
7428
            tcg_temp_free_i64(fp1);
7429
            gen_store_fpr64(ctx, fp2, fd);
7430
            tcg_temp_free_i64(fp2);
7431
        }
7432
        opn = "nmadd.d";
7433
        break;
7434
    case OPC_NMADD_PS:
7435
        check_cp1_64bitmode(ctx);
7436
        {
7437
            TCGv_i64 fp0 = tcg_temp_new_i64();
7438
            TCGv_i64 fp1 = tcg_temp_new_i64();
7439
            TCGv_i64 fp2 = tcg_temp_new_i64();
7440

    
7441
            gen_load_fpr64(ctx, fp0, fs);
7442
            gen_load_fpr64(ctx, fp1, ft);
7443
            gen_load_fpr64(ctx, fp2, fr);
7444
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7445
            tcg_temp_free_i64(fp0);
7446
            tcg_temp_free_i64(fp1);
7447
            gen_store_fpr64(ctx, fp2, fd);
7448
            tcg_temp_free_i64(fp2);
7449
        }
7450
        opn = "nmadd.ps";
7451
        break;
7452
    case OPC_NMSUB_S:
7453
        check_cop1x(ctx);
7454
        {
7455
            TCGv_i32 fp0 = tcg_temp_new_i32();
7456
            TCGv_i32 fp1 = tcg_temp_new_i32();
7457
            TCGv_i32 fp2 = tcg_temp_new_i32();
7458

    
7459
            gen_load_fpr32(fp0, fs);
7460
            gen_load_fpr32(fp1, ft);
7461
            gen_load_fpr32(fp2, fr);
7462
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7463
            tcg_temp_free_i32(fp0);
7464
            tcg_temp_free_i32(fp1);
7465
            gen_store_fpr32(fp2, fd);
7466
            tcg_temp_free_i32(fp2);
7467
        }
7468
        opn = "nmsub.s";
7469
        break;
7470
    case OPC_NMSUB_D:
7471
        check_cop1x(ctx);
7472
        check_cp1_registers(ctx, fd | fs | ft | fr);
7473
        {
7474
            TCGv_i64 fp0 = tcg_temp_new_i64();
7475
            TCGv_i64 fp1 = tcg_temp_new_i64();
7476
            TCGv_i64 fp2 = tcg_temp_new_i64();
7477

    
7478
            gen_load_fpr64(ctx, fp0, fs);
7479
            gen_load_fpr64(ctx, fp1, ft);
7480
            gen_load_fpr64(ctx, fp2, fr);
7481
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7482
            tcg_temp_free_i64(fp0);
7483
            tcg_temp_free_i64(fp1);
7484
            gen_store_fpr64(ctx, fp2, fd);
7485
            tcg_temp_free_i64(fp2);
7486
        }
7487
        opn = "nmsub.d";
7488
        break;
7489
    case OPC_NMSUB_PS:
7490
        check_cp1_64bitmode(ctx);
7491
        {
7492
            TCGv_i64 fp0 = tcg_temp_new_i64();
7493
            TCGv_i64 fp1 = tcg_temp_new_i64();
7494
            TCGv_i64 fp2 = tcg_temp_new_i64();
7495

    
7496
            gen_load_fpr64(ctx, fp0, fs);
7497
            gen_load_fpr64(ctx, fp1, ft);
7498
            gen_load_fpr64(ctx, fp2, fr);
7499
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7500
            tcg_temp_free_i64(fp0);
7501
            tcg_temp_free_i64(fp1);
7502
            gen_store_fpr64(ctx, fp2, fd);
7503
            tcg_temp_free_i64(fp2);
7504
        }
7505
        opn = "nmsub.ps";
7506
        break;
7507
    default:
7508
        MIPS_INVAL(opn);
7509
        generate_exception (ctx, EXCP_RI);
7510
        return;
7511
    }
7512
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7513
               fregnames[fs], fregnames[ft]);
7514
}
7515

    
7516
/* ISA extensions (ASEs) */
7517
/* MIPS16 extension to MIPS32 */
7518
/* SmartMIPS extension to MIPS32 */
7519

    
7520
#if defined(TARGET_MIPS64)
7521

    
7522
/* MDMX extension to MIPS64 */
7523

    
7524
#endif
7525

    
7526
static void decode_opc (CPUState *env, DisasContext *ctx)
7527
{
7528
    int32_t offset;
7529
    int rs, rt, rd, sa;
7530
    uint32_t op, op1, op2;
7531
    int16_t imm;
7532

    
7533
    /* make sure instructions are on a word boundary */
7534
    if (ctx->pc & 0x3) {
7535
        env->CP0_BadVAddr = ctx->pc;
7536
        generate_exception(ctx, EXCP_AdEL);
7537
        return;
7538
    }
7539

    
7540
    /* Handle blikely not taken case */
7541
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7542
        int l1 = gen_new_label();
7543

    
7544
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7545
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7546
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7547
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7548
        gen_set_label(l1);
7549
    }
7550
    op = MASK_OP_MAJOR(ctx->opcode);
7551
    rs = (ctx->opcode >> 21) & 0x1f;
7552
    rt = (ctx->opcode >> 16) & 0x1f;
7553
    rd = (ctx->opcode >> 11) & 0x1f;
7554
    sa = (ctx->opcode >> 6) & 0x1f;
7555
    imm = (int16_t)ctx->opcode;
7556
    switch (op) {
7557
    case OPC_SPECIAL:
7558
        op1 = MASK_SPECIAL(ctx->opcode);
7559
        switch (op1) {
7560
        case OPC_SLL:          /* Arithmetic with immediate */
7561
        case OPC_SRL ... OPC_SRA:
7562
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7563
            break;
7564
        case OPC_MOVN:         /* Conditional move */
7565
        case OPC_MOVZ:
7566
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7567
            gen_cond_move(env, op1, rd, rs, rt);
7568
            break;
7569
        case OPC_ADD ... OPC_SUBU:
7570
            gen_arith(env, ctx, op1, rd, rs, rt);
7571
            break;
7572
        case OPC_SLLV:         /* Shifts */
7573
        case OPC_SRLV:
7574
        case OPC_SRAV:
7575
            gen_shift(env, ctx, op1, rd, rs, rt);
7576
            break;
7577
        case OPC_SLT:          /* Set on less than */
7578
        case OPC_SLTU:
7579
            gen_slt(env, op1, rd, rs, rt);
7580
            break;
7581
        case OPC_AND:          /* Logic*/
7582
        case OPC_OR:
7583
        case OPC_NOR:
7584
        case OPC_XOR:
7585
            gen_logic(env, op1, rd, rs, rt);
7586
            break;
7587
        case OPC_MULT ... OPC_DIVU:
7588
            if (sa) {
7589
                check_insn(env, ctx, INSN_VR54XX);
7590
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7591
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7592
            } else
7593
                gen_muldiv(ctx, op1, rs, rt);
7594
            break;
7595
        case OPC_JR ... OPC_JALR:
7596
            gen_compute_branch(ctx, op1, rs, rd, sa);
7597
            return;
7598
        case OPC_TGE ... OPC_TEQ: /* Traps */
7599
        case OPC_TNE:
7600
            gen_trap(ctx, op1, rs, rt, -1);
7601
            break;
7602
        case OPC_MFHI:          /* Move from HI/LO */
7603
        case OPC_MFLO:
7604
            gen_HILO(ctx, op1, rd);
7605
            break;
7606
        case OPC_MTHI:
7607
        case OPC_MTLO:          /* Move to HI/LO */
7608
            gen_HILO(ctx, op1, rs);
7609
            break;
7610
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7611
#ifdef MIPS_STRICT_STANDARD
7612
            MIPS_INVAL("PMON / selsl");
7613
            generate_exception(ctx, EXCP_RI);
7614
#else
7615
            gen_helper_0i(pmon, sa);
7616
#endif
7617
            break;
7618
        case OPC_SYSCALL:
7619
            generate_exception(ctx, EXCP_SYSCALL);
7620
            break;
7621
        case OPC_BREAK:
7622
            generate_exception(ctx, EXCP_BREAK);
7623
            break;
7624
        case OPC_SPIM:
7625
#ifdef MIPS_STRICT_STANDARD
7626
            MIPS_INVAL("SPIM");
7627
            generate_exception(ctx, EXCP_RI);
7628
#else
7629
           /* Implemented as RI exception for now. */
7630
            MIPS_INVAL("spim (unofficial)");
7631
            generate_exception(ctx, EXCP_RI);
7632
#endif
7633
            break;
7634
        case OPC_SYNC:
7635
            /* Treat as NOP. */
7636
            break;
7637

    
7638
        case OPC_MOVCI:
7639
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7640
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7641
                check_cp1_enabled(ctx);
7642
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7643
                          (ctx->opcode >> 16) & 1);
7644
            } else {
7645
                generate_exception_err(ctx, EXCP_CpU, 1);
7646
            }
7647
            break;
7648

    
7649
#if defined(TARGET_MIPS64)
7650
       /* MIPS64 specific opcodes */
7651
        case OPC_DSLL:
7652
        case OPC_DSRL ... OPC_DSRA:
7653
        case OPC_DSLL32:
7654
        case OPC_DSRL32 ... OPC_DSRA32:
7655
            check_insn(env, ctx, ISA_MIPS3);
7656
            check_mips_64(ctx);
7657
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7658
            break;
7659
        case OPC_DADD ... OPC_DSUBU:
7660
            check_insn(env, ctx, ISA_MIPS3);
7661
            check_mips_64(ctx);
7662
            gen_arith(env, ctx, op1, rd, rs, rt);
7663
            break;
7664
        case OPC_DSLLV:
7665
        case OPC_DSRAV:
7666
        case OPC_DSRLV:
7667
            check_insn(env, ctx, ISA_MIPS3);
7668
            check_mips_64(ctx);
7669
            gen_shift(env, ctx, op1, rd, rs, rt);
7670
            break;
7671
        case OPC_DMULT ... OPC_DDIVU:
7672
            check_insn(env, ctx, ISA_MIPS3);
7673
            check_mips_64(ctx);
7674
            gen_muldiv(ctx, op1, rs, rt);
7675
            break;
7676
#endif
7677
        default:            /* Invalid */
7678
            MIPS_INVAL("special");
7679
            generate_exception(ctx, EXCP_RI);
7680
            break;
7681
        }
7682
        break;
7683
    case OPC_SPECIAL2:
7684
        op1 = MASK_SPECIAL2(ctx->opcode);
7685
        switch (op1) {
7686
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7687
        case OPC_MSUB ... OPC_MSUBU:
7688
            check_insn(env, ctx, ISA_MIPS32);
7689
            gen_muldiv(ctx, op1, rs, rt);
7690
            break;
7691
        case OPC_MUL:
7692
            gen_arith(env, ctx, op1, rd, rs, rt);
7693
            break;
7694
        case OPC_CLO:
7695
        case OPC_CLZ:
7696
            check_insn(env, ctx, ISA_MIPS32);
7697
            gen_cl(ctx, op1, rd, rs);
7698
            break;
7699
        case OPC_SDBBP:
7700
            /* XXX: not clear which exception should be raised
7701
             *      when in debug mode...
7702
             */
7703
            check_insn(env, ctx, ISA_MIPS32);
7704
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7705
                generate_exception(ctx, EXCP_DBp);
7706
            } else {
7707
                generate_exception(ctx, EXCP_DBp);
7708
            }
7709
            /* Treat as NOP. */
7710
            break;
7711
#if defined(TARGET_MIPS64)
7712
        case OPC_DCLO:
7713
        case OPC_DCLZ:
7714
            check_insn(env, ctx, ISA_MIPS64);
7715
            check_mips_64(ctx);
7716
            gen_cl(ctx, op1, rd, rs);
7717
            break;
7718
#endif
7719
        default:            /* Invalid */
7720
            MIPS_INVAL("special2");
7721
            generate_exception(ctx, EXCP_RI);
7722
            break;
7723
        }
7724
        break;
7725
    case OPC_SPECIAL3:
7726
        op1 = MASK_SPECIAL3(ctx->opcode);
7727
        switch (op1) {
7728
        case OPC_EXT:
7729
        case OPC_INS:
7730
            check_insn(env, ctx, ISA_MIPS32R2);
7731
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7732
            break;
7733
        case OPC_BSHFL:
7734
            check_insn(env, ctx, ISA_MIPS32R2);
7735
            op2 = MASK_BSHFL(ctx->opcode);
7736
            gen_bshfl(ctx, op2, rt, rd);
7737
            break;
7738
        case OPC_RDHWR:
7739
            check_insn(env, ctx, ISA_MIPS32R2);
7740
            {
7741
                TCGv t0 = tcg_temp_new();
7742

    
7743
                switch (rd) {
7744
                case 0:
7745
                    save_cpu_state(ctx, 1);
7746
                    gen_helper_rdhwr_cpunum(t0);
7747
                    gen_store_gpr(t0, rt);
7748
                    break;
7749
                case 1:
7750
                    save_cpu_state(ctx, 1);
7751
                    gen_helper_rdhwr_synci_step(t0);
7752
                    gen_store_gpr(t0, rt);
7753
                    break;
7754
                case 2:
7755
                    save_cpu_state(ctx, 1);
7756
                    gen_helper_rdhwr_cc(t0);
7757
                    gen_store_gpr(t0, rt);
7758
                    break;
7759
                case 3:
7760
                    save_cpu_state(ctx, 1);
7761
                    gen_helper_rdhwr_ccres(t0);
7762
                    gen_store_gpr(t0, rt);
7763
                    break;
7764
                case 29:
7765
#if defined(CONFIG_USER_ONLY)
7766
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7767
                    gen_store_gpr(t0, rt);
7768
                    break;
7769
#else
7770
                    /* XXX: Some CPUs implement this in hardware.
7771
                       Not supported yet. */
7772
#endif
7773
                default:            /* Invalid */
7774
                    MIPS_INVAL("rdhwr");
7775
                    generate_exception(ctx, EXCP_RI);
7776
                    break;
7777
                }
7778
                tcg_temp_free(t0);
7779
            }
7780
            break;
7781
        case OPC_FORK:
7782
            check_insn(env, ctx, ASE_MT);
7783
            {
7784
                TCGv t0 = tcg_temp_new();
7785
                TCGv t1 = tcg_temp_new();
7786

    
7787
                gen_load_gpr(t0, rt);
7788
                gen_load_gpr(t1, rs);
7789
                gen_helper_fork(t0, t1);
7790
                tcg_temp_free(t0);
7791
                tcg_temp_free(t1);
7792
            }
7793
            break;
7794
        case OPC_YIELD:
7795
            check_insn(env, ctx, ASE_MT);
7796
            {
7797
                TCGv t0 = tcg_temp_new();
7798

    
7799
                save_cpu_state(ctx, 1);
7800
                gen_load_gpr(t0, rs);
7801
                gen_helper_yield(t0, t0);
7802
                gen_store_gpr(t0, rd);
7803
                tcg_temp_free(t0);
7804
            }
7805
            break;
7806
#if defined(TARGET_MIPS64)
7807
        case OPC_DEXTM ... OPC_DEXT:
7808
        case OPC_DINSM ... OPC_DINS:
7809
            check_insn(env, ctx, ISA_MIPS64R2);
7810
            check_mips_64(ctx);
7811
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7812
            break;
7813
        case OPC_DBSHFL:
7814
            check_insn(env, ctx, ISA_MIPS64R2);
7815
            check_mips_64(ctx);
7816
            op2 = MASK_DBSHFL(ctx->opcode);
7817
            gen_bshfl(ctx, op2, rt, rd);
7818
            break;
7819
#endif
7820
        default:            /* Invalid */
7821
            MIPS_INVAL("special3");
7822
            generate_exception(ctx, EXCP_RI);
7823
            break;
7824
        }
7825
        break;
7826
    case OPC_REGIMM:
7827
        op1 = MASK_REGIMM(ctx->opcode);
7828
        switch (op1) {
7829
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7830
        case OPC_BLTZAL ... OPC_BGEZALL:
7831
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7832
            return;
7833
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7834
        case OPC_TNEI:
7835
            gen_trap(ctx, op1, rs, -1, imm);
7836
            break;
7837
        case OPC_SYNCI:
7838
            check_insn(env, ctx, ISA_MIPS32R2);
7839
            /* Treat as NOP. */
7840
            break;
7841
        default:            /* Invalid */
7842
            MIPS_INVAL("regimm");
7843
            generate_exception(ctx, EXCP_RI);
7844
            break;
7845
        }
7846
        break;
7847
    case OPC_CP0:
7848
        check_cp0_enabled(ctx);
7849
        op1 = MASK_CP0(ctx->opcode);
7850
        switch (op1) {
7851
        case OPC_MFC0:
7852
        case OPC_MTC0:
7853
        case OPC_MFTR:
7854
        case OPC_MTTR:
7855
#if defined(TARGET_MIPS64)
7856
        case OPC_DMFC0:
7857
        case OPC_DMTC0:
7858
#endif
7859
#ifndef CONFIG_USER_ONLY
7860
            gen_cp0(env, ctx, op1, rt, rd);
7861
#endif /* !CONFIG_USER_ONLY */
7862
            break;
7863
        case OPC_C0_FIRST ... OPC_C0_LAST:
7864
#ifndef CONFIG_USER_ONLY
7865
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7866
#endif /* !CONFIG_USER_ONLY */
7867
            break;
7868
        case OPC_MFMC0:
7869
#ifndef CONFIG_USER_ONLY
7870
            {
7871
                TCGv t0 = tcg_temp_new();
7872

    
7873
                op2 = MASK_MFMC0(ctx->opcode);
7874
                switch (op2) {
7875
                case OPC_DMT:
7876
                    check_insn(env, ctx, ASE_MT);
7877
                    gen_helper_dmt(t0, t0);
7878
                    gen_store_gpr(t0, rt);
7879
                    break;
7880
                case OPC_EMT:
7881
                    check_insn(env, ctx, ASE_MT);
7882
                    gen_helper_emt(t0, t0);
7883
                    gen_store_gpr(t0, rt);
7884
                    break;
7885
                case OPC_DVPE:
7886
                    check_insn(env, ctx, ASE_MT);
7887
                    gen_helper_dvpe(t0, t0);
7888
                    gen_store_gpr(t0, rt);
7889
                    break;
7890
                case OPC_EVPE:
7891
                    check_insn(env, ctx, ASE_MT);
7892
                    gen_helper_evpe(t0, t0);
7893
                    gen_store_gpr(t0, rt);
7894
                    break;
7895
                case OPC_DI:
7896
                    check_insn(env, ctx, ISA_MIPS32R2);
7897
                    gen_helper_di(t0);
7898
                    gen_store_gpr(t0, rt);
7899
                    /* Stop translation as we may have switched the execution mode */
7900
                    ctx->bstate = BS_STOP;
7901
                    break;
7902
                case OPC_EI:
7903
                    check_insn(env, ctx, ISA_MIPS32R2);
7904
                    gen_helper_ei(t0);
7905
                    gen_store_gpr(t0, rt);
7906
                    /* Stop translation as we may have switched the execution mode */
7907
                    ctx->bstate = BS_STOP;
7908
                    break;
7909
                default:            /* Invalid */
7910
                    MIPS_INVAL("mfmc0");
7911
                    generate_exception(ctx, EXCP_RI);
7912
                    break;
7913
                }
7914
                tcg_temp_free(t0);
7915
            }
7916
#endif /* !CONFIG_USER_ONLY */
7917
            break;
7918
        case OPC_RDPGPR:
7919
            check_insn(env, ctx, ISA_MIPS32R2);
7920
            gen_load_srsgpr(rt, rd);
7921
            break;
7922
        case OPC_WRPGPR:
7923
            check_insn(env, ctx, ISA_MIPS32R2);
7924
            gen_store_srsgpr(rt, rd);
7925
            break;
7926
        default:
7927
            MIPS_INVAL("cp0");
7928
            generate_exception(ctx, EXCP_RI);
7929
            break;
7930
        }
7931
        break;
7932
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7933
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7934
         break;
7935
    case OPC_J ... OPC_JAL: /* Jump */
7936
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7937
         gen_compute_branch(ctx, op, rs, rt, offset);
7938
         return;
7939
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7940
    case OPC_BEQL ... OPC_BGTZL:
7941
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7942
         return;
7943
    case OPC_LB ... OPC_LWR: /* Load and stores */
7944
    case OPC_SB ... OPC_SW:
7945
    case OPC_SWR:
7946
    case OPC_LL:
7947
    case OPC_SC:
7948
         gen_ldst(ctx, op, rt, rs, imm);
7949
         break;
7950
    case OPC_CACHE:
7951
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7952
        /* Treat as NOP. */
7953
        break;
7954
    case OPC_PREF:
7955
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7956
        /* Treat as NOP. */
7957
        break;
7958

    
7959
    /* Floating point (COP1). */
7960
    case OPC_LWC1:
7961
    case OPC_LDC1:
7962
    case OPC_SWC1:
7963
    case OPC_SDC1:
7964
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7965
            check_cp1_enabled(ctx);
7966
            gen_flt_ldst(ctx, op, rt, rs, imm);
7967
        } else {
7968
            generate_exception_err(ctx, EXCP_CpU, 1);
7969
        }
7970
        break;
7971

    
7972
    case OPC_CP1:
7973
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7974
            check_cp1_enabled(ctx);
7975
            op1 = MASK_CP1(ctx->opcode);
7976
            switch (op1) {
7977
            case OPC_MFHC1:
7978
            case OPC_MTHC1:
7979
                check_insn(env, ctx, ISA_MIPS32R2);
7980
            case OPC_MFC1:
7981
            case OPC_CFC1:
7982
            case OPC_MTC1:
7983
            case OPC_CTC1:
7984
                gen_cp1(ctx, op1, rt, rd);
7985
                break;
7986
#if defined(TARGET_MIPS64)
7987
            case OPC_DMFC1:
7988
            case OPC_DMTC1:
7989
                check_insn(env, ctx, ISA_MIPS3);
7990
                gen_cp1(ctx, op1, rt, rd);
7991
                break;
7992
#endif
7993
            case OPC_BC1ANY2:
7994
            case OPC_BC1ANY4:
7995
                check_cop1x(ctx);
7996
                check_insn(env, ctx, ASE_MIPS3D);
7997
                /* fall through */
7998
            case OPC_BC1:
7999
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8000
                                    (rt >> 2) & 0x7, imm << 2);
8001
                return;
8002
            case OPC_S_FMT:
8003
            case OPC_D_FMT:
8004
            case OPC_W_FMT:
8005
            case OPC_L_FMT:
8006
            case OPC_PS_FMT:
8007
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8008
                           (imm >> 8) & 0x7);
8009
                break;
8010
            default:
8011
                MIPS_INVAL("cp1");
8012
                generate_exception (ctx, EXCP_RI);
8013
                break;
8014
            }
8015
        } else {
8016
            generate_exception_err(ctx, EXCP_CpU, 1);
8017
        }
8018
        break;
8019

    
8020
    /* COP2.  */
8021
    case OPC_LWC2:
8022
    case OPC_LDC2:
8023
    case OPC_SWC2:
8024
    case OPC_SDC2:
8025
    case OPC_CP2:
8026
        /* COP2: Not implemented. */
8027
        generate_exception_err(ctx, EXCP_CpU, 2);
8028
        break;
8029

    
8030
    case OPC_CP3:
8031
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8032
            check_cp1_enabled(ctx);
8033
            op1 = MASK_CP3(ctx->opcode);
8034
            switch (op1) {
8035
            case OPC_LWXC1:
8036
            case OPC_LDXC1:
8037
            case OPC_LUXC1:
8038
            case OPC_SWXC1:
8039
            case OPC_SDXC1:
8040
            case OPC_SUXC1:
8041
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8042
                break;
8043
            case OPC_PREFX:
8044
                /* Treat as NOP. */
8045
                break;
8046
            case OPC_ALNV_PS:
8047
            case OPC_MADD_S:
8048
            case OPC_MADD_D:
8049
            case OPC_MADD_PS:
8050
            case OPC_MSUB_S:
8051
            case OPC_MSUB_D:
8052
            case OPC_MSUB_PS:
8053
            case OPC_NMADD_S:
8054
            case OPC_NMADD_D:
8055
            case OPC_NMADD_PS:
8056
            case OPC_NMSUB_S:
8057
            case OPC_NMSUB_D:
8058
            case OPC_NMSUB_PS:
8059
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8060
                break;
8061
            default:
8062
                MIPS_INVAL("cp3");
8063
                generate_exception (ctx, EXCP_RI);
8064
                break;
8065
            }
8066
        } else {
8067
            generate_exception_err(ctx, EXCP_CpU, 1);
8068
        }
8069
        break;
8070

    
8071
#if defined(TARGET_MIPS64)
8072
    /* MIPS64 opcodes */
8073
    case OPC_LWU:
8074
    case OPC_LDL ... OPC_LDR:
8075
    case OPC_SDL ... OPC_SDR:
8076
    case OPC_LLD:
8077
    case OPC_LD:
8078
    case OPC_SCD:
8079
    case OPC_SD:
8080
        check_insn(env, ctx, ISA_MIPS3);
8081
        check_mips_64(ctx);
8082
        gen_ldst(ctx, op, rt, rs, imm);
8083
        break;
8084
    case OPC_DADDI ... OPC_DADDIU:
8085
        check_insn(env, ctx, ISA_MIPS3);
8086
        check_mips_64(ctx);
8087
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8088
        break;
8089
#endif
8090
    case OPC_JALX:
8091
        check_insn(env, ctx, ASE_MIPS16);
8092
        /* MIPS16: Not implemented. */
8093
    case OPC_MDMX:
8094
        check_insn(env, ctx, ASE_MDMX);
8095
        /* MDMX: Not implemented. */
8096
    default:            /* Invalid */
8097
        MIPS_INVAL("major opcode");
8098
        generate_exception(ctx, EXCP_RI);
8099
        break;
8100
    }
8101
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8102
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8103
        /* Branches completion */
8104
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8105
        ctx->bstate = BS_BRANCH;
8106
        save_cpu_state(ctx, 0);
8107
        /* FIXME: Need to clear can_do_io.  */
8108
        switch (hflags) {
8109
        case MIPS_HFLAG_B:
8110
            /* unconditional branch */
8111
            MIPS_DEBUG("unconditional branch");
8112
            gen_goto_tb(ctx, 0, ctx->btarget);
8113
            break;
8114
        case MIPS_HFLAG_BL:
8115
            /* blikely taken case */
8116
            MIPS_DEBUG("blikely branch taken");
8117
            gen_goto_tb(ctx, 0, ctx->btarget);
8118
            break;
8119
        case MIPS_HFLAG_BC:
8120
            /* Conditional branch */
8121
            MIPS_DEBUG("conditional branch");
8122
            {
8123
                int l1 = gen_new_label();
8124

    
8125
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8126
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8127
                gen_set_label(l1);
8128
                gen_goto_tb(ctx, 0, ctx->btarget);
8129
            }
8130
            break;
8131
        case MIPS_HFLAG_BR:
8132
            /* unconditional branch to register */
8133
            MIPS_DEBUG("branch to register");
8134
            tcg_gen_mov_tl(cpu_PC, btarget);
8135
            tcg_gen_exit_tb(0);
8136
            break;
8137
        default:
8138
            MIPS_DEBUG("unknown branch");
8139
            break;
8140
        }
8141
    }
8142
}
8143

    
8144
static inline void
8145
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8146
                                int search_pc)
8147
{
8148
    DisasContext ctx;
8149
    target_ulong pc_start;
8150
    uint16_t *gen_opc_end;
8151
    CPUBreakpoint *bp;
8152
    int j, lj = -1;
8153
    int num_insns;
8154
    int max_insns;
8155

    
8156
    if (search_pc)
8157
        qemu_log("search pc %d\n", search_pc);
8158

    
8159
    pc_start = tb->pc;
8160
    /* Leave some spare opc slots for branch handling. */
8161
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8162
    ctx.pc = pc_start;
8163
    ctx.saved_pc = -1;
8164
    ctx.tb = tb;
8165
    ctx.bstate = BS_NONE;
8166
    /* Restore delay slot state from the tb context.  */
8167
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8168
    restore_cpu_state(env, &ctx);
8169
#ifdef CONFIG_USER_ONLY
8170
        ctx.mem_idx = MIPS_HFLAG_UM;
8171
#else
8172
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8173
#endif
8174
    num_insns = 0;
8175
    max_insns = tb->cflags & CF_COUNT_MASK;
8176
    if (max_insns == 0)
8177
        max_insns = CF_COUNT_MASK;
8178
#ifdef DEBUG_DISAS
8179
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8180
    /* FIXME: This may print out stale hflags from env... */
8181
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8182
#endif
8183
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8184
    gen_icount_start();
8185
    while (ctx.bstate == BS_NONE) {
8186
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8187
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8188
                if (bp->pc == ctx.pc) {
8189
                    save_cpu_state(&ctx, 1);
8190
                    ctx.bstate = BS_BRANCH;
8191
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8192
                    /* Include the breakpoint location or the tb won't
8193
                     * be flushed when it must be.  */
8194
                    ctx.pc += 4;
8195
                    goto done_generating;
8196
                }
8197
            }
8198
        }
8199

    
8200
        if (search_pc) {
8201
            j = gen_opc_ptr - gen_opc_buf;
8202
            if (lj < j) {
8203
                lj++;
8204
                while (lj < j)
8205
                    gen_opc_instr_start[lj++] = 0;
8206
            }
8207
            gen_opc_pc[lj] = ctx.pc;
8208
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8209
            gen_opc_instr_start[lj] = 1;
8210
            gen_opc_icount[lj] = num_insns;
8211
        }
8212
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8213
            gen_io_start();
8214
        ctx.opcode = ldl_code(ctx.pc);
8215
        decode_opc(env, &ctx);
8216
        ctx.pc += 4;
8217
        num_insns++;
8218

    
8219
        if (env->singlestep_enabled)
8220
            break;
8221

    
8222
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8223
            break;
8224

    
8225
        if (gen_opc_ptr >= gen_opc_end)
8226
            break;
8227

    
8228
        if (num_insns >= max_insns)
8229
            break;
8230

    
8231
        if (singlestep)
8232
            break;
8233
    }
8234
    if (tb->cflags & CF_LAST_IO)
8235
        gen_io_end();
8236
    if (env->singlestep_enabled) {
8237
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8238
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8239
    } else {
8240
        switch (ctx.bstate) {
8241
        case BS_STOP:
8242
            gen_helper_interrupt_restart();
8243
            gen_goto_tb(&ctx, 0, ctx.pc);
8244
            break;
8245
        case BS_NONE:
8246
            save_cpu_state(&ctx, 0);
8247
            gen_goto_tb(&ctx, 0, ctx.pc);
8248
            break;
8249
        case BS_EXCP:
8250
            gen_helper_interrupt_restart();
8251
            tcg_gen_exit_tb(0);
8252
            break;
8253
        case BS_BRANCH:
8254
        default:
8255
            break;
8256
        }
8257
    }
8258
done_generating:
8259
    gen_icount_end(tb, num_insns);
8260
    *gen_opc_ptr = INDEX_op_end;
8261
    if (search_pc) {
8262
        j = gen_opc_ptr - gen_opc_buf;
8263
        lj++;
8264
        while (lj <= j)
8265
            gen_opc_instr_start[lj++] = 0;
8266
    } else {
8267
        tb->size = ctx.pc - pc_start;
8268
        tb->icount = num_insns;
8269
    }
8270
#ifdef DEBUG_DISAS
8271
    LOG_DISAS("\n");
8272
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8273
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8274
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8275
        qemu_log("\n");
8276
    }
8277
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8278
#endif
8279
}
8280

    
8281
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8282
{
8283
    gen_intermediate_code_internal(env, tb, 0);
8284
}
8285

    
8286
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8287
{
8288
    gen_intermediate_code_internal(env, tb, 1);
8289
}
8290

    
8291
static void fpu_dump_state(CPUState *env, FILE *f,
8292
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8293
                           int flags)
8294
{
8295
    int i;
8296
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8297

    
8298
#define printfpr(fp)                                                        \
8299
    do {                                                                    \
8300
        if (is_fpu64)                                                       \
8301
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8302
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8303
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8304
        else {                                                              \
8305
            fpr_t tmp;                                                      \
8306
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8307
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8308
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8309
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8310
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8311
        }                                                                   \
8312
    } while(0)
8313

    
8314

    
8315
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8316
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8317
                get_float_exception_flags(&env->active_fpu.fp_status));
8318
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8319
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8320
        printfpr(&env->active_fpu.fpr[i]);
8321
    }
8322

    
8323
#undef printfpr
8324
}
8325

    
8326
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8327
/* Debug help: The architecture requires 32bit code to maintain proper
8328
   sign-extended values on 64bit machines.  */
8329

    
8330
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8331

    
8332
static void
8333
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8334
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8335
                                int flags)
8336
{
8337
    int i;
8338

    
8339
    if (!SIGN_EXT_P(env->active_tc.PC))
8340
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8341
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8342
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8343
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8344
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8345
    if (!SIGN_EXT_P(env->btarget))
8346
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8347

    
8348
    for (i = 0; i < 32; i++) {
8349
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8350
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8351
    }
8352

    
8353
    if (!SIGN_EXT_P(env->CP0_EPC))
8354
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8355
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8356
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8357
}
8358
#endif
8359

    
8360
void cpu_dump_state (CPUState *env, FILE *f,
8361
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8362
                     int flags)
8363
{
8364
    int i;
8365

    
8366
    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",
8367
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8368
                env->hflags, env->btarget, env->bcond);
8369
    for (i = 0; i < 32; i++) {
8370
        if ((i & 3) == 0)
8371
            cpu_fprintf(f, "GPR%02d:", i);
8372
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8373
        if ((i & 3) == 3)
8374
            cpu_fprintf(f, "\n");
8375
    }
8376

    
8377
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8378
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8379
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8380
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8381
    if (env->hflags & MIPS_HFLAG_FPU)
8382
        fpu_dump_state(env, f, cpu_fprintf, flags);
8383
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8384
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8385
#endif
8386
}
8387

    
8388
static void mips_tcg_init(void)
8389
{
8390
    int i;
8391
    static int inited;
8392

    
8393
    /* Initialize various static tables. */
8394
    if (inited)
8395
        return;
8396

    
8397
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8398
    for (i = 0; i < 32; i++)
8399
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8400
                                        offsetof(CPUState, active_tc.gpr[i]),
8401
                                        regnames[i]);
8402
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8403
                                offsetof(CPUState, active_tc.PC), "PC");
8404
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8405
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8406
                                       offsetof(CPUState, active_tc.HI[i]),
8407
                                       regnames_HI[i]);
8408
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8409
                                       offsetof(CPUState, active_tc.LO[i]),
8410
                                       regnames_LO[i]);
8411
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8412
                                        offsetof(CPUState, active_tc.ACX[i]),
8413
                                        regnames_ACX[i]);
8414
    }
8415
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8416
                                     offsetof(CPUState, active_tc.DSPControl),
8417
                                     "DSPControl");
8418
    bcond = tcg_global_mem_new(TCG_AREG0,
8419
                               offsetof(CPUState, bcond), "bcond");
8420
    btarget = tcg_global_mem_new(TCG_AREG0,
8421
                                 offsetof(CPUState, btarget), "btarget");
8422
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8423
                                    offsetof(CPUState, hflags), "hflags");
8424

    
8425
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8426
                                      offsetof(CPUState, active_fpu.fcr0),
8427
                                      "fcr0");
8428
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8429
                                       offsetof(CPUState, active_fpu.fcr31),
8430
                                       "fcr31");
8431

    
8432
    /* register helpers */
8433
#define GEN_HELPER 2
8434
#include "helper.h"
8435

    
8436
    inited = 1;
8437
}
8438

    
8439
#include "translate_init.c"
8440

    
8441
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8442
{
8443
    CPUMIPSState *env;
8444
    const mips_def_t *def;
8445

    
8446
    def = cpu_mips_find_by_name(cpu_model);
8447
    if (!def)
8448
        return NULL;
8449
    env = qemu_mallocz(sizeof(CPUMIPSState));
8450
    env->cpu_model = def;
8451

    
8452
    cpu_exec_init(env);
8453
    env->cpu_model_str = cpu_model;
8454
    mips_tcg_init();
8455
    cpu_reset(env);
8456
    return env;
8457
}
8458

    
8459
void cpu_reset (CPUMIPSState *env)
8460
{
8461
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8462
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8463
        log_cpu_state(env, 0);
8464
    }
8465

    
8466
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8467

    
8468
    tlb_flush(env, 1);
8469

    
8470
    /* Minimal init */
8471
#if defined(CONFIG_USER_ONLY)
8472
    env->hflags = MIPS_HFLAG_UM;
8473
#else
8474
    if (env->hflags & MIPS_HFLAG_BMASK) {
8475
        /* If the exception was raised from a delay slot,
8476
           come back to the jump.  */
8477
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8478
    } else {
8479
        env->CP0_ErrorEPC = env->active_tc.PC;
8480
    }
8481
    env->active_tc.PC = (int32_t)0xBFC00000;
8482
    env->CP0_Wired = 0;
8483
    /* SMP not implemented */
8484
    env->CP0_EBase = 0x80000000;
8485
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8486
    /* vectored interrupts not implemented, timer on int 7,
8487
       no performance counters. */
8488
    env->CP0_IntCtl = 0xe0000000;
8489
    {
8490
        int i;
8491

    
8492
        for (i = 0; i < 7; i++) {
8493
            env->CP0_WatchLo[i] = 0;
8494
            env->CP0_WatchHi[i] = 0x80000000;
8495
        }
8496
        env->CP0_WatchLo[7] = 0;
8497
        env->CP0_WatchHi[7] = 0;
8498
    }
8499
    /* Count register increments in debug mode, EJTAG version 1 */
8500
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8501
    env->hflags = MIPS_HFLAG_CP0;
8502
#endif
8503
    env->exception_index = EXCP_NONE;
8504
    cpu_mips_register(env, env->cpu_model);
8505
}
8506

    
8507
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8508
                unsigned long searched_pc, int pc_pos, void *puc)
8509
{
8510
    env->active_tc.PC = gen_opc_pc[pc_pos];
8511
    env->hflags &= ~MIPS_HFLAG_BMASK;
8512
    env->hflags |= gen_opc_hflags[pc_pos];
8513
}