Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 2623c1ec

History | View | Annotate | Download (256.3 kB)

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

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

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

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
425
/* global register indices */
426
static TCGv cpu_env, cpu_gpr[32], cpu_PC;
427
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
428
static TCGv cpu_dspctrl, bcond, btarget;
429
static TCGv fpu_fpr32[32], fpu_fpr32h[32], fpu_fpr64[32], fpu_fcr0, fpu_fcr31;
430

    
431
#include "gen-icount.h"
432

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
828
static inline void gen_save_pc(target_ulong pc)
829
{
830
    tcg_gen_movi_tl(cpu_PC, pc);
831
}
832

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

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

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

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

    
887
static inline void
888
generate_exception (DisasContext *ctx, int excp)
889
{
890
    save_cpu_state(ctx, 1);
891
    tcg_gen_helper_0_i(do_raise_exception, excp);
892
    tcg_gen_helper_0_0(do_interrupt_restart);
893
    tcg_gen_exit_tb(0);
894
}
895

    
896
/* Addresses computation */
897
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
898
{
899
    tcg_gen_add_tl(t0, t0, t1);
900

    
901
#if defined(TARGET_MIPS64)
902
    /* For compatibility with 32-bit code, data reference in user mode
903
       with Status_UX = 0 should be casted to 32-bit and sign extended.
904
       See the MIPS64 PRA manual, section 4.10. */
905
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
906
        !(ctx->hflags & MIPS_HFLAG_UX)) {
907
        tcg_gen_ext32s_i64(t0, t0);
908
    }
909
#endif
910
}
911

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1445
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1446
                    tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
1447
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1448
                    tcg_temp_free(r_tmp1);
1449
                }
1450
                opn = "rotr";
1451
            } else {
1452
                tcg_gen_ext32u_tl(t0, t0);
1453
                tcg_gen_shri_tl(t0, t0, uimm);
1454
                tcg_gen_ext32s_tl(t0, t0);
1455
                opn = "srl";
1456
            }
1457
            break;
1458
        default:
1459
            MIPS_INVAL("invalid srl flag");
1460
            generate_exception(ctx, EXCP_RI);
1461
            break;
1462
        }
1463
        break;
1464
#if defined(TARGET_MIPS64)
1465
    case OPC_DSLL:
1466
        tcg_gen_shli_tl(t0, t0, uimm);
1467
        opn = "dsll";
1468
        break;
1469
    case OPC_DSRA:
1470
        tcg_gen_sari_tl(t0, t0, uimm);
1471
        opn = "dsra";
1472
        break;
1473
    case OPC_DSRL:
1474
        switch ((ctx->opcode >> 21) & 0x1f) {
1475
        case 0:
1476
            tcg_gen_shri_tl(t0, t0, uimm);
1477
            opn = "dsrl";
1478
            break;
1479
        case 1:
1480
            /* drotr is decoded as dsrl on non-R2 CPUs */
1481
            if (env->insn_flags & ISA_MIPS32R2) {
1482
                if (uimm != 0) {
1483
                    tcg_gen_rotri_tl(t0, t0, uimm);
1484
                }
1485
                opn = "drotr";
1486
            } else {
1487
                tcg_gen_shri_tl(t0, t0, uimm);
1488
                opn = "dsrl";
1489
            }
1490
            break;
1491
        default:
1492
            MIPS_INVAL("invalid dsrl flag");
1493
            generate_exception(ctx, EXCP_RI);
1494
            break;
1495
        }
1496
        break;
1497
    case OPC_DSLL32:
1498
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1499
        opn = "dsll32";
1500
        break;
1501
    case OPC_DSRA32:
1502
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1503
        opn = "dsra32";
1504
        break;
1505
    case OPC_DSRL32:
1506
        switch ((ctx->opcode >> 21) & 0x1f) {
1507
        case 0:
1508
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1509
            opn = "dsrl32";
1510
            break;
1511
        case 1:
1512
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1513
            if (env->insn_flags & ISA_MIPS32R2) {
1514
                tcg_gen_rotri_tl(t0, t0, uimm + 32);
1515
                opn = "drotr32";
1516
            } else {
1517
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1518
                opn = "dsrl32";
1519
            }
1520
            break;
1521
        default:
1522
            MIPS_INVAL("invalid dsrl32 flag");
1523
            generate_exception(ctx, EXCP_RI);
1524
            break;
1525
        }
1526
        break;
1527
#endif
1528
    default:
1529
        MIPS_INVAL(opn);
1530
        generate_exception(ctx, EXCP_RI);
1531
        goto out;
1532
    }
1533
    gen_store_gpr(t0, rt);
1534
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1535
 out:
1536
    tcg_temp_free(t0);
1537
}
1538

    
1539
/* Arithmetic */
1540
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1541
                       int rd, int rs, int rt)
1542
{
1543
    const char *opn = "arith";
1544
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1545
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1546

    
1547
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1548
       && opc != OPC_DADD && opc != OPC_DSUB) {
1549
        /* If no destination, treat it as a NOP.
1550
           For add & sub, we must generate the overflow exception when needed. */
1551
        MIPS_DEBUG("NOP");
1552
        goto out;
1553
    }
1554
    gen_load_gpr(t0, rs);
1555
    /* Specialcase the conventional move operation. */
1556
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1557
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1558
        gen_store_gpr(t0, rd);
1559
        goto out;
1560
    }
1561
    gen_load_gpr(t1, rt);
1562
    switch (opc) {
1563
    case OPC_ADD:
1564
        {
1565
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1566
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1567
            int l1 = gen_new_label();
1568

    
1569
            save_cpu_state(ctx, 1);
1570
            tcg_gen_ext32s_tl(r_tmp1, t0);
1571
            tcg_gen_ext32s_tl(r_tmp2, t1);
1572
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1573

    
1574
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1575
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1576
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1577
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1578
            tcg_temp_free(r_tmp2);
1579
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1580
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1581
            tcg_temp_free(r_tmp1);
1582
            /* operands of same sign, result different sign */
1583
            generate_exception(ctx, EXCP_OVERFLOW);
1584
            gen_set_label(l1);
1585

    
1586
            tcg_gen_ext32s_tl(t0, t0);
1587
        }
1588
        opn = "add";
1589
        break;
1590
    case OPC_ADDU:
1591
        tcg_gen_ext32s_tl(t0, t0);
1592
        tcg_gen_ext32s_tl(t1, t1);
1593
        tcg_gen_add_tl(t0, t0, t1);
1594
        tcg_gen_ext32s_tl(t0, t0);
1595
        opn = "addu";
1596
        break;
1597
    case OPC_SUB:
1598
        {
1599
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1600
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1601
            int l1 = gen_new_label();
1602

    
1603
            save_cpu_state(ctx, 1);
1604
            tcg_gen_ext32s_tl(r_tmp1, t0);
1605
            tcg_gen_ext32s_tl(r_tmp2, t1);
1606
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1607

    
1608
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1609
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1610
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1611
            tcg_temp_free(r_tmp2);
1612
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1613
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1614
            tcg_temp_free(r_tmp1);
1615
            /* operands of different sign, first operand and result different sign */
1616
            generate_exception(ctx, EXCP_OVERFLOW);
1617
            gen_set_label(l1);
1618

    
1619
            tcg_gen_ext32s_tl(t0, t0);
1620
        }
1621
        opn = "sub";
1622
        break;
1623
    case OPC_SUBU:
1624
        tcg_gen_ext32s_tl(t0, t0);
1625
        tcg_gen_ext32s_tl(t1, t1);
1626
        tcg_gen_sub_tl(t0, t0, t1);
1627
        tcg_gen_ext32s_tl(t0, t0);
1628
        opn = "subu";
1629
        break;
1630
#if defined(TARGET_MIPS64)
1631
    case OPC_DADD:
1632
        {
1633
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1634
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1635
            int l1 = gen_new_label();
1636

    
1637
            save_cpu_state(ctx, 1);
1638
            tcg_gen_mov_tl(r_tmp1, t0);
1639
            tcg_gen_add_tl(t0, t0, t1);
1640

    
1641
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1642
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1643
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1644
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1645
            tcg_temp_free(r_tmp2);
1646
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1647
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1648
            tcg_temp_free(r_tmp1);
1649
            /* operands of same sign, result different sign */
1650
            generate_exception(ctx, EXCP_OVERFLOW);
1651
            gen_set_label(l1);
1652
        }
1653
        opn = "dadd";
1654
        break;
1655
    case OPC_DADDU:
1656
        tcg_gen_add_tl(t0, t0, t1);
1657
        opn = "daddu";
1658
        break;
1659
    case OPC_DSUB:
1660
        {
1661
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1662
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1663
            int l1 = gen_new_label();
1664

    
1665
            save_cpu_state(ctx, 1);
1666
            tcg_gen_mov_tl(r_tmp1, t0);
1667
            tcg_gen_sub_tl(t0, t0, t1);
1668

    
1669
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1670
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1671
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1672
            tcg_temp_free(r_tmp2);
1673
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1674
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1675
            tcg_temp_free(r_tmp1);
1676
            /* operands of different sign, first operand and result different sign */
1677
            generate_exception(ctx, EXCP_OVERFLOW);
1678
            gen_set_label(l1);
1679
        }
1680
        opn = "dsub";
1681
        break;
1682
    case OPC_DSUBU:
1683
        tcg_gen_sub_tl(t0, t0, t1);
1684
        opn = "dsubu";
1685
        break;
1686
#endif
1687
    case OPC_SLT:
1688
        gen_op_lt(t0, t1);
1689
        opn = "slt";
1690
        break;
1691
    case OPC_SLTU:
1692
        gen_op_ltu(t0, t1);
1693
        opn = "sltu";
1694
        break;
1695
    case OPC_AND:
1696
        tcg_gen_and_tl(t0, t0, t1);
1697
        opn = "and";
1698
        break;
1699
    case OPC_NOR:
1700
        tcg_gen_or_tl(t0, t0, t1);
1701
        tcg_gen_not_tl(t0, t0);
1702
        opn = "nor";
1703
        break;
1704
    case OPC_OR:
1705
        tcg_gen_or_tl(t0, t0, t1);
1706
        opn = "or";
1707
        break;
1708
    case OPC_XOR:
1709
        tcg_gen_xor_tl(t0, t0, t1);
1710
        opn = "xor";
1711
        break;
1712
    case OPC_MUL:
1713
        tcg_gen_ext32s_tl(t0, t0);
1714
        tcg_gen_ext32s_tl(t1, t1);
1715
        tcg_gen_mul_tl(t0, t0, t1);
1716
        tcg_gen_ext32s_tl(t0, t0);
1717
        opn = "mul";
1718
        break;
1719
    case OPC_MOVN:
1720
        {
1721
            int l1 = gen_new_label();
1722

    
1723
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1724
            gen_store_gpr(t0, rd);
1725
            gen_set_label(l1);
1726
        }
1727
        opn = "movn";
1728
        goto print;
1729
    case OPC_MOVZ:
1730
        {
1731
            int l1 = gen_new_label();
1732

    
1733
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1734
            gen_store_gpr(t0, rd);
1735
            gen_set_label(l1);
1736
        }
1737
        opn = "movz";
1738
        goto print;
1739
    case OPC_SLLV:
1740
        tcg_gen_ext32u_tl(t0, t0);
1741
        tcg_gen_ext32u_tl(t1, t1);
1742
        tcg_gen_andi_tl(t0, t0, 0x1f);
1743
        tcg_gen_shl_tl(t0, t1, t0);
1744
        tcg_gen_ext32s_tl(t0, t0);
1745
        opn = "sllv";
1746
        break;
1747
    case OPC_SRAV:
1748
        tcg_gen_ext32s_tl(t1, t1);
1749
        tcg_gen_andi_tl(t0, t0, 0x1f);
1750
        tcg_gen_sar_tl(t0, t1, t0);
1751
        tcg_gen_ext32s_tl(t0, t0);
1752
        opn = "srav";
1753
        break;
1754
    case OPC_SRLV:
1755
        switch ((ctx->opcode >> 6) & 0x1f) {
1756
        case 0:
1757
            tcg_gen_ext32u_tl(t1, t1);
1758
            tcg_gen_andi_tl(t0, t0, 0x1f);
1759
            tcg_gen_shr_tl(t0, t1, t0);
1760
            tcg_gen_ext32s_tl(t0, t0);
1761
            opn = "srlv";
1762
            break;
1763
        case 1:
1764
            /* rotrv is decoded as srlv on non-R2 CPUs */
1765
            if (env->insn_flags & ISA_MIPS32R2) {
1766
                int l1 = gen_new_label();
1767
                int l2 = gen_new_label();
1768

    
1769
                tcg_gen_andi_tl(t0, t0, 0x1f);
1770
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1771
                {
1772
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1773
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1774

    
1775
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1776
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1777
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1778
                    tcg_temp_free(r_tmp1);
1779
                    tcg_temp_free(r_tmp2);
1780
                    tcg_gen_br(l2);
1781
                }
1782
                gen_set_label(l1);
1783
                tcg_gen_mov_tl(t0, t1);
1784
                gen_set_label(l2);
1785
                opn = "rotrv";
1786
            } else {
1787
                tcg_gen_ext32u_tl(t1, t1);
1788
                tcg_gen_andi_tl(t0, t0, 0x1f);
1789
                tcg_gen_shr_tl(t0, t1, t0);
1790
                tcg_gen_ext32s_tl(t0, t0);
1791
                opn = "srlv";
1792
            }
1793
            break;
1794
        default:
1795
            MIPS_INVAL("invalid srlv flag");
1796
            generate_exception(ctx, EXCP_RI);
1797
            break;
1798
        }
1799
        break;
1800
#if defined(TARGET_MIPS64)
1801
    case OPC_DSLLV:
1802
        tcg_gen_andi_tl(t0, t0, 0x3f);
1803
        tcg_gen_shl_tl(t0, t1, t0);
1804
        opn = "dsllv";
1805
        break;
1806
    case OPC_DSRAV:
1807
        tcg_gen_andi_tl(t0, t0, 0x3f);
1808
        tcg_gen_sar_tl(t0, t1, t0);
1809
        opn = "dsrav";
1810
        break;
1811
    case OPC_DSRLV:
1812
        switch ((ctx->opcode >> 6) & 0x1f) {
1813
        case 0:
1814
            tcg_gen_andi_tl(t0, t0, 0x3f);
1815
            tcg_gen_shr_tl(t0, t1, t0);
1816
            opn = "dsrlv";
1817
            break;
1818
        case 1:
1819
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1820
            if (env->insn_flags & ISA_MIPS32R2) {
1821
                int l1 = gen_new_label();
1822
                int l2 = gen_new_label();
1823

    
1824
                tcg_gen_andi_tl(t0, t0, 0x3f);
1825
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1826
                {
1827
                    tcg_gen_rotr_tl(t0, t1, t0);
1828
                    tcg_gen_br(l2);
1829
                }
1830
                gen_set_label(l1);
1831
                tcg_gen_mov_tl(t0, t1);
1832
                gen_set_label(l2);
1833
                opn = "drotrv";
1834
            } else {
1835
                tcg_gen_andi_tl(t0, t0, 0x3f);
1836
                tcg_gen_shr_tl(t0, t1, t0);
1837
                opn = "dsrlv";
1838
            }
1839
            break;
1840
        default:
1841
            MIPS_INVAL("invalid dsrlv flag");
1842
            generate_exception(ctx, EXCP_RI);
1843
            break;
1844
        }
1845
        break;
1846
#endif
1847
    default:
1848
        MIPS_INVAL(opn);
1849
        generate_exception(ctx, EXCP_RI);
1850
        goto out;
1851
    }
1852
    gen_store_gpr(t0, rd);
1853
 print:
1854
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1855
 out:
1856
    tcg_temp_free(t0);
1857
    tcg_temp_free(t1);
1858
}
1859

    
1860
/* Arithmetic on HI/LO registers */
1861
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1862
{
1863
    const char *opn = "hilo";
1864
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1865

    
1866
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1867
        /* Treat as NOP. */
1868
        MIPS_DEBUG("NOP");
1869
        goto out;
1870
    }
1871
    switch (opc) {
1872
    case OPC_MFHI:
1873
        gen_load_HI(t0, 0);
1874
        gen_store_gpr(t0, reg);
1875
        opn = "mfhi";
1876
        break;
1877
    case OPC_MFLO:
1878
        gen_load_LO(t0, 0);
1879
        gen_store_gpr(t0, reg);
1880
        opn = "mflo";
1881
        break;
1882
    case OPC_MTHI:
1883
        gen_load_gpr(t0, reg);
1884
        gen_store_HI(t0, 0);
1885
        opn = "mthi";
1886
        break;
1887
    case OPC_MTLO:
1888
        gen_load_gpr(t0, reg);
1889
        gen_store_LO(t0, 0);
1890
        opn = "mtlo";
1891
        break;
1892
    default:
1893
        MIPS_INVAL(opn);
1894
        generate_exception(ctx, EXCP_RI);
1895
        goto out;
1896
    }
1897
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1898
 out:
1899
    tcg_temp_free(t0);
1900
}
1901

    
1902
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1903
                        int rs, int rt)
1904
{
1905
    const char *opn = "mul/div";
1906
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1907
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1908

    
1909
    gen_load_gpr(t0, rs);
1910
    gen_load_gpr(t1, rt);
1911
    switch (opc) {
1912
    case OPC_DIV:
1913
        {
1914
            int l1 = gen_new_label();
1915

    
1916
            tcg_gen_ext32s_tl(t0, t0);
1917
            tcg_gen_ext32s_tl(t1, t1);
1918
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1919
            {
1920
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1921
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1922
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1923

    
1924
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1925
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1926
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1927
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1928
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1929
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1930
                tcg_temp_free(r_tmp1);
1931
                tcg_temp_free(r_tmp2);
1932
                tcg_temp_free(r_tmp3);
1933
                tcg_gen_ext32s_tl(t0, t0);
1934
                tcg_gen_ext32s_tl(t1, t1);
1935
                gen_store_LO(t0, 0);
1936
                gen_store_HI(t1, 0);
1937
            }
1938
            gen_set_label(l1);
1939
        }
1940
        opn = "div";
1941
        break;
1942
    case OPC_DIVU:
1943
        {
1944
            int l1 = gen_new_label();
1945

    
1946
            tcg_gen_ext32s_tl(t1, t1);
1947
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1948
            {
1949
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1950
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1951
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1952

    
1953
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1954
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1955
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1956
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1957
                tcg_gen_ext_i32_tl(t0, r_tmp3);
1958
                tcg_gen_ext_i32_tl(t1, r_tmp1);
1959
                tcg_temp_free(r_tmp1);
1960
                tcg_temp_free(r_tmp2);
1961
                tcg_temp_free(r_tmp3);
1962
                gen_store_LO(t0, 0);
1963
                gen_store_HI(t1, 0);
1964
            }
1965
            gen_set_label(l1);
1966
        }
1967
        opn = "divu";
1968
        break;
1969
    case OPC_MULT:
1970
        {
1971
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1972
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1973

    
1974
            tcg_gen_ext32s_tl(t0, t0);
1975
            tcg_gen_ext32s_tl(t1, t1);
1976
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1977
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1978
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1979
            tcg_temp_free(r_tmp2);
1980
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1981
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1982
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1983
            tcg_temp_free(r_tmp1);
1984
            tcg_gen_ext32s_tl(t0, t0);
1985
            tcg_gen_ext32s_tl(t1, t1);
1986
            gen_store_LO(t0, 0);
1987
            gen_store_HI(t1, 0);
1988
        }
1989
        opn = "mult";
1990
        break;
1991
    case OPC_MULTU:
1992
        {
1993
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1994
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1995

    
1996
            tcg_gen_ext32u_tl(t0, t0);
1997
            tcg_gen_ext32u_tl(t1, t1);
1998
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1999
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2000
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2001
            tcg_temp_free(r_tmp2);
2002
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2003
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2004
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2005
            tcg_temp_free(r_tmp1);
2006
            tcg_gen_ext32s_tl(t0, t0);
2007
            tcg_gen_ext32s_tl(t1, t1);
2008
            gen_store_LO(t0, 0);
2009
            gen_store_HI(t1, 0);
2010
        }
2011
        opn = "multu";
2012
        break;
2013
#if defined(TARGET_MIPS64)
2014
    case OPC_DDIV:
2015
        {
2016
            int l1 = gen_new_label();
2017

    
2018
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2019
            {
2020
                int l2 = gen_new_label();
2021

    
2022
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2023
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2024
                {
2025
                    tcg_gen_movi_tl(t1, 0);
2026
                    gen_store_LO(t0, 0);
2027
                    gen_store_HI(t1, 0);
2028
                    tcg_gen_br(l1);
2029
                }
2030
                gen_set_label(l2);
2031
                {
2032
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2033
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2034

    
2035
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2036
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2037
                    gen_store_LO(r_tmp1, 0);
2038
                    gen_store_HI(r_tmp2, 0);
2039
                    tcg_temp_free(r_tmp1);
2040
                    tcg_temp_free(r_tmp2);
2041
                }
2042
            }
2043
            gen_set_label(l1);
2044
        }
2045
        opn = "ddiv";
2046
        break;
2047
    case OPC_DDIVU:
2048
        {
2049
            int l1 = gen_new_label();
2050

    
2051
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2052
            {
2053
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2054
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2055

    
2056
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2057
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2058
                tcg_temp_free(r_tmp1);
2059
                tcg_temp_free(r_tmp2);
2060
                gen_store_LO(r_tmp1, 0);
2061
                gen_store_HI(r_tmp2, 0);
2062
            }
2063
            gen_set_label(l1);
2064
        }
2065
        opn = "ddivu";
2066
        break;
2067
    case OPC_DMULT:
2068
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2069
        opn = "dmult";
2070
        break;
2071
    case OPC_DMULTU:
2072
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2073
        opn = "dmultu";
2074
        break;
2075
#endif
2076
    case OPC_MADD:
2077
        {
2078
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2079
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2080

    
2081
            tcg_gen_ext32s_tl(t0, t0);
2082
            tcg_gen_ext32s_tl(t1, t1);
2083
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2084
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2085
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2086
            gen_load_LO(t0, 0);
2087
            gen_load_HI(t1, 0);
2088
            tcg_gen_concat_tl_i64(r_tmp2, t0, t1);
2089
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2090
            tcg_temp_free(r_tmp2);
2091
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2092
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2093
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2094
            tcg_temp_free(r_tmp1);
2095
            tcg_gen_ext32s_tl(t0, t0);
2096
            tcg_gen_ext32s_tl(t1, t1);
2097
            gen_store_LO(t0, 0);
2098
            gen_store_HI(t1, 0);
2099
        }
2100
        opn = "madd";
2101
        break;
2102
    case OPC_MADDU:
2103
       {
2104
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2105
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2106

    
2107
            tcg_gen_ext32u_tl(t0, t0);
2108
            tcg_gen_ext32u_tl(t1, t1);
2109
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2110
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2111
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2112
            gen_load_LO(t0, 0);
2113
            gen_load_HI(t1, 0);
2114
            tcg_gen_concat_tl_i64(r_tmp2, t0, t1);
2115
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2116
            tcg_temp_free(r_tmp2);
2117
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2118
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2119
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2120
            tcg_temp_free(r_tmp1);
2121
            tcg_gen_ext32s_tl(t0, t0);
2122
            tcg_gen_ext32s_tl(t1, t1);
2123
            gen_store_LO(t0, 0);
2124
            gen_store_HI(t1, 0);
2125
        }
2126
        opn = "maddu";
2127
        break;
2128
    case OPC_MSUB:
2129
        {
2130
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2131
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2132

    
2133
            tcg_gen_ext32s_tl(t0, t0);
2134
            tcg_gen_ext32s_tl(t1, t1);
2135
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2136
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2137
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2138
            gen_load_LO(t0, 0);
2139
            gen_load_HI(t1, 0);
2140
            tcg_gen_concat_tl_i64(r_tmp2, t0, t1);
2141
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2142
            tcg_temp_free(r_tmp2);
2143
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2144
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2145
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2146
            tcg_temp_free(r_tmp1);
2147
            tcg_gen_ext32s_tl(t0, t0);
2148
            tcg_gen_ext32s_tl(t1, t1);
2149
            gen_store_LO(t0, 0);
2150
            gen_store_HI(t1, 0);
2151
        }
2152
        opn = "msub";
2153
        break;
2154
    case OPC_MSUBU:
2155
        {
2156
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2157
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2158

    
2159
            tcg_gen_ext32u_tl(t0, t0);
2160
            tcg_gen_ext32u_tl(t1, t1);
2161
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2162
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2163
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2164
            gen_load_LO(t0, 0);
2165
            gen_load_HI(t1, 0);
2166
            tcg_gen_concat_tl_i64(r_tmp2, t0, t1);
2167
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2168
            tcg_temp_free(r_tmp2);
2169
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2170
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2171
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2172
            tcg_temp_free(r_tmp1);
2173
            tcg_gen_ext32s_tl(t0, t0);
2174
            tcg_gen_ext32s_tl(t1, t1);
2175
            gen_store_LO(t0, 0);
2176
            gen_store_HI(t1, 0);
2177
        }
2178
        opn = "msubu";
2179
        break;
2180
    default:
2181
        MIPS_INVAL(opn);
2182
        generate_exception(ctx, EXCP_RI);
2183
        goto out;
2184
    }
2185
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2186
 out:
2187
    tcg_temp_free(t0);
2188
    tcg_temp_free(t1);
2189
}
2190

    
2191
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2192
                            int rd, int rs, int rt)
2193
{
2194
    const char *opn = "mul vr54xx";
2195
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2196
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2197

    
2198
    gen_load_gpr(t0, rs);
2199
    gen_load_gpr(t1, rt);
2200

    
2201
    switch (opc) {
2202
    case OPC_VR54XX_MULS:
2203
        tcg_gen_helper_1_2(do_muls, t0, t0, t1);
2204
        opn = "muls";
2205
        break;
2206
    case OPC_VR54XX_MULSU:
2207
        tcg_gen_helper_1_2(do_mulsu, t0, t0, t1);
2208
        opn = "mulsu";
2209
        break;
2210
    case OPC_VR54XX_MACC:
2211
        tcg_gen_helper_1_2(do_macc, t0, t0, t1);
2212
        opn = "macc";
2213
        break;
2214
    case OPC_VR54XX_MACCU:
2215
        tcg_gen_helper_1_2(do_maccu, t0, t0, t1);
2216
        opn = "maccu";
2217
        break;
2218
    case OPC_VR54XX_MSAC:
2219
        tcg_gen_helper_1_2(do_msac, t0, t0, t1);
2220
        opn = "msac";
2221
        break;
2222
    case OPC_VR54XX_MSACU:
2223
        tcg_gen_helper_1_2(do_msacu, t0, t0, t1);
2224
        opn = "msacu";
2225
        break;
2226
    case OPC_VR54XX_MULHI:
2227
        tcg_gen_helper_1_2(do_mulhi, t0, t0, t1);
2228
        opn = "mulhi";
2229
        break;
2230
    case OPC_VR54XX_MULHIU:
2231
        tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1);
2232
        opn = "mulhiu";
2233
        break;
2234
    case OPC_VR54XX_MULSHI:
2235
        tcg_gen_helper_1_2(do_mulshi, t0, t0, t1);
2236
        opn = "mulshi";
2237
        break;
2238
    case OPC_VR54XX_MULSHIU:
2239
        tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1);
2240
        opn = "mulshiu";
2241
        break;
2242
    case OPC_VR54XX_MACCHI:
2243
        tcg_gen_helper_1_2(do_macchi, t0, t0, t1);
2244
        opn = "macchi";
2245
        break;
2246
    case OPC_VR54XX_MACCHIU:
2247
        tcg_gen_helper_1_2(do_macchiu, t0, t0, t1);
2248
        opn = "macchiu";
2249
        break;
2250
    case OPC_VR54XX_MSACHI:
2251
        tcg_gen_helper_1_2(do_msachi, t0, t0, t1);
2252
        opn = "msachi";
2253
        break;
2254
    case OPC_VR54XX_MSACHIU:
2255
        tcg_gen_helper_1_2(do_msachiu, t0, t0, t1);
2256
        opn = "msachiu";
2257
        break;
2258
    default:
2259
        MIPS_INVAL("mul vr54xx");
2260
        generate_exception(ctx, EXCP_RI);
2261
        goto out;
2262
    }
2263
    gen_store_gpr(t0, rd);
2264
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2265

    
2266
 out:
2267
    tcg_temp_free(t0);
2268
    tcg_temp_free(t1);
2269
}
2270

    
2271
static void gen_cl (DisasContext *ctx, uint32_t opc,
2272
                    int rd, int rs)
2273
{
2274
    const char *opn = "CLx";
2275
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2276

    
2277
    if (rd == 0) {
2278
        /* Treat as NOP. */
2279
        MIPS_DEBUG("NOP");
2280
        goto out;
2281
    }
2282
    gen_load_gpr(t0, rs);
2283
    switch (opc) {
2284
    case OPC_CLO:
2285
        tcg_gen_helper_1_1(do_clo, t0, t0);
2286
        opn = "clo";
2287
        break;
2288
    case OPC_CLZ:
2289
        tcg_gen_helper_1_1(do_clz, t0, t0);
2290
        opn = "clz";
2291
        break;
2292
#if defined(TARGET_MIPS64)
2293
    case OPC_DCLO:
2294
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2295
        opn = "dclo";
2296
        break;
2297
    case OPC_DCLZ:
2298
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2299
        opn = "dclz";
2300
        break;
2301
#endif
2302
    default:
2303
        MIPS_INVAL(opn);
2304
        generate_exception(ctx, EXCP_RI);
2305
        goto out;
2306
    }
2307
    gen_store_gpr(t0, rd);
2308
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2309

    
2310
 out:
2311
    tcg_temp_free(t0);
2312
}
2313

    
2314
/* Traps */
2315
static void gen_trap (DisasContext *ctx, uint32_t opc,
2316
                      int rs, int rt, int16_t imm)
2317
{
2318
    int cond;
2319
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2320
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2321

    
2322
    cond = 0;
2323
    /* Load needed operands */
2324
    switch (opc) {
2325
    case OPC_TEQ:
2326
    case OPC_TGE:
2327
    case OPC_TGEU:
2328
    case OPC_TLT:
2329
    case OPC_TLTU:
2330
    case OPC_TNE:
2331
        /* Compare two registers */
2332
        if (rs != rt) {
2333
            gen_load_gpr(t0, rs);
2334
            gen_load_gpr(t1, rt);
2335
            cond = 1;
2336
        }
2337
        break;
2338
    case OPC_TEQI:
2339
    case OPC_TGEI:
2340
    case OPC_TGEIU:
2341
    case OPC_TLTI:
2342
    case OPC_TLTIU:
2343
    case OPC_TNEI:
2344
        /* Compare register to immediate */
2345
        if (rs != 0 || imm != 0) {
2346
            gen_load_gpr(t0, rs);
2347
            tcg_gen_movi_tl(t1, (int32_t)imm);
2348
            cond = 1;
2349
        }
2350
        break;
2351
    }
2352
    if (cond == 0) {
2353
        switch (opc) {
2354
        case OPC_TEQ:   /* rs == rs */
2355
        case OPC_TEQI:  /* r0 == 0  */
2356
        case OPC_TGE:   /* rs >= rs */
2357
        case OPC_TGEI:  /* r0 >= 0  */
2358
        case OPC_TGEU:  /* rs >= rs unsigned */
2359
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2360
            /* Always trap */
2361
            tcg_gen_movi_tl(t0, 1);
2362
            break;
2363
        case OPC_TLT:   /* rs < rs           */
2364
        case OPC_TLTI:  /* r0 < 0            */
2365
        case OPC_TLTU:  /* rs < rs unsigned  */
2366
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2367
        case OPC_TNE:   /* rs != rs          */
2368
        case OPC_TNEI:  /* r0 != 0           */
2369
            /* Never trap: treat as NOP. */
2370
            goto out;
2371
        default:
2372
            MIPS_INVAL("trap");
2373
            generate_exception(ctx, EXCP_RI);
2374
            goto out;
2375
        }
2376
    } else {
2377
        switch (opc) {
2378
        case OPC_TEQ:
2379
        case OPC_TEQI:
2380
            gen_op_eq(t0, t1);
2381
            break;
2382
        case OPC_TGE:
2383
        case OPC_TGEI:
2384
            gen_op_ge(t0, t1);
2385
            break;
2386
        case OPC_TGEU:
2387
        case OPC_TGEIU:
2388
            gen_op_geu(t0, t1);
2389
            break;
2390
        case OPC_TLT:
2391
        case OPC_TLTI:
2392
            gen_op_lt(t0, t1);
2393
            break;
2394
        case OPC_TLTU:
2395
        case OPC_TLTIU:
2396
            gen_op_ltu(t0, t1);
2397
            break;
2398
        case OPC_TNE:
2399
        case OPC_TNEI:
2400
            gen_op_ne(t0, t1);
2401
            break;
2402
        default:
2403
            MIPS_INVAL("trap");
2404
            generate_exception(ctx, EXCP_RI);
2405
            goto out;
2406
        }
2407
    }
2408
    save_cpu_state(ctx, 1);
2409
    {
2410
        int l1 = gen_new_label();
2411

    
2412
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2413
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2414
        gen_set_label(l1);
2415
    }
2416
    ctx->bstate = BS_STOP;
2417
 out:
2418
    tcg_temp_free(t0);
2419
    tcg_temp_free(t1);
2420
}
2421

    
2422
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2423
{
2424
    TranslationBlock *tb;
2425
    tb = ctx->tb;
2426
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2427
        tcg_gen_goto_tb(n);
2428
        gen_save_pc(dest);
2429
        tcg_gen_exit_tb((long)tb + n);
2430
    } else {
2431
        gen_save_pc(dest);
2432
        tcg_gen_exit_tb(0);
2433
    }
2434
}
2435

    
2436
/* Branches (before delay slot) */
2437
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2438
                                int rs, int rt, int32_t offset)
2439
{
2440
    target_ulong btgt = -1;
2441
    int blink = 0;
2442
    int bcond_compute = 0;
2443
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2444
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2445

    
2446
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2447
#ifdef MIPS_DEBUG_DISAS
2448
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2449
            fprintf(logfile,
2450
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2451
                    ctx->pc);
2452
        }
2453
#endif
2454
        generate_exception(ctx, EXCP_RI);
2455
        goto out;
2456
    }
2457

    
2458
    /* Load needed operands */
2459
    switch (opc) {
2460
    case OPC_BEQ:
2461
    case OPC_BEQL:
2462
    case OPC_BNE:
2463
    case OPC_BNEL:
2464
        /* Compare two registers */
2465
        if (rs != rt) {
2466
            gen_load_gpr(t0, rs);
2467
            gen_load_gpr(t1, rt);
2468
            bcond_compute = 1;
2469
        }
2470
        btgt = ctx->pc + 4 + offset;
2471
        break;
2472
    case OPC_BGEZ:
2473
    case OPC_BGEZAL:
2474
    case OPC_BGEZALL:
2475
    case OPC_BGEZL:
2476
    case OPC_BGTZ:
2477
    case OPC_BGTZL:
2478
    case OPC_BLEZ:
2479
    case OPC_BLEZL:
2480
    case OPC_BLTZ:
2481
    case OPC_BLTZAL:
2482
    case OPC_BLTZALL:
2483
    case OPC_BLTZL:
2484
        /* Compare to zero */
2485
        if (rs != 0) {
2486
            gen_load_gpr(t0, rs);
2487
            bcond_compute = 1;
2488
        }
2489
        btgt = ctx->pc + 4 + offset;
2490
        break;
2491
    case OPC_J:
2492
    case OPC_JAL:
2493
        /* Jump to immediate */
2494
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2495
        break;
2496
    case OPC_JR:
2497
    case OPC_JALR:
2498
        /* Jump to register */
2499
        if (offset != 0 && offset != 16) {
2500
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2501
               others are reserved. */
2502
            MIPS_INVAL("jump hint");
2503
            generate_exception(ctx, EXCP_RI);
2504
            goto out;
2505
        }
2506
        gen_load_gpr(btarget, rs);
2507
        break;
2508
    default:
2509
        MIPS_INVAL("branch/jump");
2510
        generate_exception(ctx, EXCP_RI);
2511
        goto out;
2512
    }
2513
    if (bcond_compute == 0) {
2514
        /* No condition to be computed */
2515
        switch (opc) {
2516
        case OPC_BEQ:     /* rx == rx        */
2517
        case OPC_BEQL:    /* rx == rx likely */
2518
        case OPC_BGEZ:    /* 0 >= 0          */
2519
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2520
        case OPC_BLEZ:    /* 0 <= 0          */
2521
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2522
            /* Always take */
2523
            ctx->hflags |= MIPS_HFLAG_B;
2524
            MIPS_DEBUG("balways");
2525
            break;
2526
        case OPC_BGEZAL:  /* 0 >= 0          */
2527
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2528
            /* Always take and link */
2529
            blink = 31;
2530
            ctx->hflags |= MIPS_HFLAG_B;
2531
            MIPS_DEBUG("balways and link");
2532
            break;
2533
        case OPC_BNE:     /* rx != rx        */
2534
        case OPC_BGTZ:    /* 0 > 0           */
2535
        case OPC_BLTZ:    /* 0 < 0           */
2536
            /* Treat as NOP. */
2537
            MIPS_DEBUG("bnever (NOP)");
2538
            goto out;
2539
        case OPC_BLTZAL:  /* 0 < 0           */
2540
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2541
            gen_store_gpr(t0, 31);
2542
            MIPS_DEBUG("bnever and link");
2543
            goto out;
2544
        case OPC_BLTZALL: /* 0 < 0 likely */
2545
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2546
            gen_store_gpr(t0, 31);
2547
            /* Skip the instruction in the delay slot */
2548
            MIPS_DEBUG("bnever, link and skip");
2549
            ctx->pc += 4;
2550
            goto out;
2551
        case OPC_BNEL:    /* rx != rx likely */
2552
        case OPC_BGTZL:   /* 0 > 0 likely */
2553
        case OPC_BLTZL:   /* 0 < 0 likely */
2554
            /* Skip the instruction in the delay slot */
2555
            MIPS_DEBUG("bnever and skip");
2556
            ctx->pc += 4;
2557
            goto out;
2558
        case OPC_J:
2559
            ctx->hflags |= MIPS_HFLAG_B;
2560
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2561
            break;
2562
        case OPC_JAL:
2563
            blink = 31;
2564
            ctx->hflags |= MIPS_HFLAG_B;
2565
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2566
            break;
2567
        case OPC_JR:
2568
            ctx->hflags |= MIPS_HFLAG_BR;
2569
            MIPS_DEBUG("jr %s", regnames[rs]);
2570
            break;
2571
        case OPC_JALR:
2572
            blink = rt;
2573
            ctx->hflags |= MIPS_HFLAG_BR;
2574
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2575
            break;
2576
        default:
2577
            MIPS_INVAL("branch/jump");
2578
            generate_exception(ctx, EXCP_RI);
2579
            goto out;
2580
        }
2581
    } else {
2582
        switch (opc) {
2583
        case OPC_BEQ:
2584
            gen_op_eq(t0, t1);
2585
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2586
                       regnames[rs], regnames[rt], btgt);
2587
            goto not_likely;
2588
        case OPC_BEQL:
2589
            gen_op_eq(t0, t1);
2590
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2591
                       regnames[rs], regnames[rt], btgt);
2592
            goto likely;
2593
        case OPC_BNE:
2594
            gen_op_ne(t0, t1);
2595
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2596
                       regnames[rs], regnames[rt], btgt);
2597
            goto not_likely;
2598
        case OPC_BNEL:
2599
            gen_op_ne(t0, t1);
2600
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2601
                       regnames[rs], regnames[rt], btgt);
2602
            goto likely;
2603
        case OPC_BGEZ:
2604
            gen_op_gez(t0);
2605
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2606
            goto not_likely;
2607
        case OPC_BGEZL:
2608
            gen_op_gez(t0);
2609
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2610
            goto likely;
2611
        case OPC_BGEZAL:
2612
            gen_op_gez(t0);
2613
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2614
            blink = 31;
2615
            goto not_likely;
2616
        case OPC_BGEZALL:
2617
            gen_op_gez(t0);
2618
            blink = 31;
2619
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2620
            goto likely;
2621
        case OPC_BGTZ:
2622
            gen_op_gtz(t0);
2623
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2624
            goto not_likely;
2625
        case OPC_BGTZL:
2626
            gen_op_gtz(t0);
2627
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2628
            goto likely;
2629
        case OPC_BLEZ:
2630
            gen_op_lez(t0);
2631
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2632
            goto not_likely;
2633
        case OPC_BLEZL:
2634
            gen_op_lez(t0);
2635
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636
            goto likely;
2637
        case OPC_BLTZ:
2638
            gen_op_ltz(t0);
2639
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640
            goto not_likely;
2641
        case OPC_BLTZL:
2642
            gen_op_ltz(t0);
2643
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644
            goto likely;
2645
        case OPC_BLTZAL:
2646
            gen_op_ltz(t0);
2647
            blink = 31;
2648
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2649
        not_likely:
2650
            ctx->hflags |= MIPS_HFLAG_BC;
2651
            tcg_gen_trunc_tl_i32(bcond, t0);
2652
            break;
2653
        case OPC_BLTZALL:
2654
            gen_op_ltz(t0);
2655
            blink = 31;
2656
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2657
        likely:
2658
            ctx->hflags |= MIPS_HFLAG_BL;
2659
            tcg_gen_trunc_tl_i32(bcond, t0);
2660
            break;
2661
        default:
2662
            MIPS_INVAL("conditional branch/jump");
2663
            generate_exception(ctx, EXCP_RI);
2664
            goto out;
2665
        }
2666
    }
2667
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2668
               blink, ctx->hflags, btgt);
2669

    
2670
    ctx->btarget = btgt;
2671
    if (blink > 0) {
2672
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2673
        gen_store_gpr(t0, blink);
2674
    }
2675

    
2676
 out:
2677
    tcg_temp_free(t0);
2678
    tcg_temp_free(t1);
2679
}
2680

    
2681
/* special3 bitfield operations */
2682
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2683
                        int rs, int lsb, int msb)
2684
{
2685
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2686
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2687

    
2688
    gen_load_gpr(t1, rs);
2689
    switch (opc) {
2690
    case OPC_EXT:
2691
        if (lsb + msb > 31)
2692
            goto fail;
2693
        tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
2694
        break;
2695
#if defined(TARGET_MIPS64)
2696
    case OPC_DEXTM:
2697
        if (lsb + msb > 63)
2698
            goto fail;
2699
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
2700
        break;
2701
    case OPC_DEXTU:
2702
        if (lsb + msb > 63)
2703
            goto fail;
2704
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
2705
        break;
2706
    case OPC_DEXT:
2707
        if (lsb + msb > 63)
2708
            goto fail;
2709
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
2710
        break;
2711
#endif
2712
    case OPC_INS:
2713
        if (lsb > msb)
2714
            goto fail;
2715
        gen_load_gpr(t0, rt);
2716
        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
2717
        break;
2718
#if defined(TARGET_MIPS64)
2719
    case OPC_DINSM:
2720
        if (lsb > msb)
2721
            goto fail;
2722
        gen_load_gpr(t0, rt);
2723
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
2724
        break;
2725
    case OPC_DINSU:
2726
        if (lsb > msb)
2727
            goto fail;
2728
        gen_load_gpr(t0, rt);
2729
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
2730
        break;
2731
    case OPC_DINS:
2732
        if (lsb > msb)
2733
            goto fail;
2734
        gen_load_gpr(t0, rt);
2735
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
2736
        break;
2737
#endif
2738
    default:
2739
fail:
2740
        MIPS_INVAL("bitops");
2741
        generate_exception(ctx, EXCP_RI);
2742
        tcg_temp_free(t0);
2743
        tcg_temp_free(t1);
2744
        return;
2745
    }
2746
    gen_store_gpr(t0, rt);
2747
    tcg_temp_free(t0);
2748
    tcg_temp_free(t1);
2749
}
2750

    
2751
#ifndef CONFIG_USER_ONLY
2752
/* CP0 (MMU and control) */
2753
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2754
{
2755
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2756

    
2757
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2758
    tcg_gen_ext_i32_tl(t, r_tmp);
2759
    tcg_temp_free(r_tmp);
2760
}
2761

    
2762
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2763
{
2764
    tcg_gen_ld_tl(t, cpu_env, off);
2765
    tcg_gen_ext32s_tl(t, t);
2766
}
2767

    
2768
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2769
{
2770
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2771

    
2772
    tcg_gen_trunc_tl_i32(r_tmp, t);
2773
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2774
    tcg_temp_free(r_tmp);
2775
}
2776

    
2777
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2778
{
2779
    tcg_gen_ext32s_tl(t, t);
2780
    tcg_gen_st_tl(t, cpu_env, off);
2781
}
2782

    
2783
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2784
{
2785
    const char *rn = "invalid";
2786

    
2787
    if (sel != 0)
2788
        check_insn(env, ctx, ISA_MIPS32);
2789

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

    
3359
die:
3360
#if defined MIPS_DEBUG_DISAS
3361
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3362
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3363
                rn, reg, sel);
3364
    }
3365
#endif
3366
    generate_exception(ctx, EXCP_RI);
3367
}
3368

    
3369
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3370
{
3371
    const char *rn = "invalid";
3372

    
3373
    if (sel != 0)
3374
        check_insn(env, ctx, ISA_MIPS32);
3375

    
3376
    if (use_icount)
3377
        gen_io_start();
3378

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

    
3968
die:
3969
#if defined MIPS_DEBUG_DISAS
3970
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3971
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3972
                rn, reg, sel);
3973
    }
3974
#endif
3975
    generate_exception(ctx, EXCP_RI);
3976
}
3977

    
3978
#if defined(TARGET_MIPS64)
3979
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3980
{
3981
    const char *rn = "invalid";
3982

    
3983
    if (sel != 0)
3984
        check_insn(env, ctx, ISA_MIPS64);
3985

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

    
4543
die:
4544
#if defined MIPS_DEBUG_DISAS
4545
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4546
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4547
                rn, reg, sel);
4548
    }
4549
#endif
4550
    generate_exception(ctx, EXCP_RI);
4551
}
4552

    
4553
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4554
{
4555
    const char *rn = "invalid";
4556

    
4557
    if (sel != 0)
4558
        check_insn(env, ctx, ISA_MIPS64);
4559

    
4560
    if (use_icount)
4561
        gen_io_start();
4562

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

    
5139
die:
5140
#if defined MIPS_DEBUG_DISAS
5141
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5142
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5143
                rn, reg, sel);
5144
    }
5145
#endif
5146
    generate_exception(ctx, EXCP_RI);
5147
}
5148
#endif /* TARGET_MIPS64 */
5149

    
5150
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5151
                     int u, int sel, int h)
5152
{
5153
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5154
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5155

    
5156
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5157
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5158
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5159
        tcg_gen_movi_tl(t0, -1);
5160
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5161
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5162
        tcg_gen_movi_tl(t0, -1);
5163
    else if (u == 0) {
5164
        switch (rt) {
5165
        case 2:
5166
            switch (sel) {
5167
            case 1:
5168
                tcg_gen_helper_1_0(do_mftc0_tcstatus, t0);
5169
                break;
5170
            case 2:
5171
                tcg_gen_helper_1_0(do_mftc0_tcbind, t0);
5172
                break;
5173
            case 3:
5174
                tcg_gen_helper_1_0(do_mftc0_tcrestart, t0);
5175
                break;
5176
            case 4:
5177
                tcg_gen_helper_1_0(do_mftc0_tchalt, t0);
5178
                break;
5179
            case 5:
5180
                tcg_gen_helper_1_0(do_mftc0_tccontext, t0);
5181
                break;
5182
            case 6:
5183
                tcg_gen_helper_1_0(do_mftc0_tcschedule, t0);
5184
                break;
5185
            case 7:
5186
                tcg_gen_helper_1_0(do_mftc0_tcschefback, t0);
5187
                break;
5188
            default:
5189
                gen_mfc0(env, ctx, t0, rt, sel);
5190
                break;
5191
            }
5192
            break;
5193
        case 10:
5194
            switch (sel) {
5195
            case 0:
5196
                tcg_gen_helper_1_0(do_mftc0_entryhi, t0);
5197
                break;
5198
            default:
5199
                gen_mfc0(env, ctx, t0, rt, sel);
5200
                break;
5201
            }
5202
        case 12:
5203
            switch (sel) {
5204
            case 0:
5205
                tcg_gen_helper_1_0(do_mftc0_status, t0);
5206
                break;
5207
            default:
5208
                gen_mfc0(env, ctx, t0, rt, sel);
5209
                break;
5210
            }
5211
        case 23:
5212
            switch (sel) {
5213
            case 0:
5214
                tcg_gen_helper_1_0(do_mftc0_debug, t0);
5215
                break;
5216
            default:
5217
                gen_mfc0(env, ctx, t0, rt, sel);
5218
                break;
5219
            }
5220
            break;
5221
        default:
5222
            gen_mfc0(env, ctx, t0, rt, sel);
5223
        }
5224
    } else switch (sel) {
5225
    /* GPR registers. */
5226
    case 0:
5227
        tcg_gen_helper_1_i(do_mftgpr, t0, rt);
5228
        break;
5229
    /* Auxiliary CPU registers */
5230
    case 1:
5231
        switch (rt) {
5232
        case 0:
5233
            tcg_gen_helper_1_i(do_mftlo, t0, 0);
5234
            break;
5235
        case 1:
5236
            tcg_gen_helper_1_i(do_mfthi, t0, 0);
5237
            break;
5238
        case 2:
5239
            tcg_gen_helper_1_i(do_mftacx, t0, 0);
5240
            break;
5241
        case 4:
5242
            tcg_gen_helper_1_i(do_mftlo, t0, 1);
5243
            break;
5244
        case 5:
5245
            tcg_gen_helper_1_i(do_mfthi, t0, 1);
5246
            break;
5247
        case 6:
5248
            tcg_gen_helper_1_i(do_mftacx, t0, 1);
5249
            break;
5250
        case 8:
5251
            tcg_gen_helper_1_i(do_mftlo, t0, 2);
5252
            break;
5253
        case 9:
5254
            tcg_gen_helper_1_i(do_mfthi, t0, 2);
5255
            break;
5256
        case 10:
5257
            tcg_gen_helper_1_i(do_mftacx, t0, 2);
5258
            break;
5259
        case 12:
5260
            tcg_gen_helper_1_i(do_mftlo, t0, 3);
5261
            break;
5262
        case 13:
5263
            tcg_gen_helper_1_i(do_mfthi, t0, 3);
5264
            break;
5265
        case 14:
5266
            tcg_gen_helper_1_i(do_mftacx, t0, 3);
5267
            break;
5268
        case 16:
5269
            tcg_gen_helper_1_0(do_mftdsp, t0);
5270
            break;
5271
        default:
5272
            goto die;
5273
        }
5274
        break;
5275
    /* Floating point (COP1). */
5276
    case 2:
5277
        /* XXX: For now we support only a single FPU context. */
5278
        if (h == 0) {
5279
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5280

    
5281
            gen_load_fpr32(fp0, rt);
5282
            tcg_gen_ext_i32_tl(t0, fp0);
5283
            tcg_temp_free(fp0);
5284
        } else {
5285
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5286

    
5287
            gen_load_fpr32h(fp0, rt);
5288
            tcg_gen_ext_i32_tl(t0, fp0);
5289
            tcg_temp_free(fp0);
5290
        }
5291
        break;
5292
    case 3:
5293
        /* XXX: For now we support only a single FPU context. */
5294
        tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt);
5295
        break;
5296
    /* COP2: Not implemented. */
5297
    case 4:
5298
    case 5:
5299
        /* fall through */
5300
    default:
5301
        goto die;
5302
    }
5303
#if defined MIPS_DEBUG_DISAS
5304
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5305
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5306
                rt, u, sel, h);
5307
    }
5308
#endif
5309
    gen_store_gpr(t0, rd);
5310
    tcg_temp_free(t0);
5311
    return;
5312

    
5313
die:
5314
    tcg_temp_free(t0);
5315
#if defined MIPS_DEBUG_DISAS
5316
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5317
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5318
                rt, u, sel, h);
5319
    }
5320
#endif
5321
    generate_exception(ctx, EXCP_RI);
5322
}
5323

    
5324
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5325
                     int u, int sel, int h)
5326
{
5327
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5328
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5329

    
5330
    gen_load_gpr(t0, rt);
5331
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5332
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5333
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5334
        /* NOP */ ;
5335
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5336
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5337
        /* NOP */ ;
5338
    else if (u == 0) {
5339
        switch (rd) {
5340
        case 2:
5341
            switch (sel) {
5342
            case 1:
5343
                tcg_gen_helper_0_1(do_mttc0_tcstatus, t0);
5344
                break;
5345
            case 2:
5346
                tcg_gen_helper_0_1(do_mttc0_tcbind, t0);
5347
                break;
5348
            case 3:
5349
                tcg_gen_helper_0_1(do_mttc0_tcrestart, t0);
5350
                break;
5351
            case 4:
5352
                tcg_gen_helper_0_1(do_mttc0_tchalt, t0);
5353
                break;
5354
            case 5:
5355
                tcg_gen_helper_0_1(do_mttc0_tccontext, t0);
5356
                break;
5357
            case 6:
5358
                tcg_gen_helper_0_1(do_mttc0_tcschedule, t0);
5359
                break;
5360
            case 7:
5361
                tcg_gen_helper_0_1(do_mttc0_tcschefback, t0);
5362
                break;
5363
            default:
5364
                gen_mtc0(env, ctx, t0, rd, sel);
5365
                break;
5366
            }
5367
            break;
5368
        case 10:
5369
            switch (sel) {
5370
            case 0:
5371
                tcg_gen_helper_0_1(do_mttc0_entryhi, t0);
5372
                break;
5373
            default:
5374
                gen_mtc0(env, ctx, t0, rd, sel);
5375
                break;
5376
            }
5377
        case 12:
5378
            switch (sel) {
5379
            case 0:
5380
                tcg_gen_helper_0_1(do_mttc0_status, t0);
5381
                break;
5382
            default:
5383
                gen_mtc0(env, ctx, t0, rd, sel);
5384
                break;
5385
            }
5386
        case 23:
5387
            switch (sel) {
5388
            case 0:
5389
                tcg_gen_helper_0_1(do_mttc0_debug, t0);
5390
                break;
5391
            default:
5392
                gen_mtc0(env, ctx, t0, rd, sel);
5393
                break;
5394
            }
5395
            break;
5396
        default:
5397
            gen_mtc0(env, ctx, t0, rd, sel);
5398
        }
5399
    } else switch (sel) {
5400
    /* GPR registers. */
5401
    case 0:
5402
        tcg_gen_helper_0_1i(do_mttgpr, t0, rd);
5403
        break;
5404
    /* Auxiliary CPU registers */
5405
    case 1:
5406
        switch (rd) {
5407
        case 0:
5408
            tcg_gen_helper_0_1i(do_mttlo, t0, 0);
5409
            break;
5410
        case 1:
5411
            tcg_gen_helper_0_1i(do_mtthi, t0, 0);
5412
            break;
5413
        case 2:
5414
            tcg_gen_helper_0_1i(do_mttacx, t0, 0);
5415
            break;
5416
        case 4:
5417
            tcg_gen_helper_0_1i(do_mttlo, t0, 1);
5418
            break;
5419
        case 5:
5420
            tcg_gen_helper_0_1i(do_mtthi, t0, 1);
5421
            break;
5422
        case 6:
5423
            tcg_gen_helper_0_1i(do_mttacx, t0, 1);
5424
            break;
5425
        case 8:
5426
            tcg_gen_helper_0_1i(do_mttlo, t0, 2);
5427
            break;
5428
        case 9:
5429
            tcg_gen_helper_0_1i(do_mtthi, t0, 2);
5430
            break;
5431
        case 10:
5432
            tcg_gen_helper_0_1i(do_mttacx, t0, 2);
5433
            break;
5434
        case 12:
5435
            tcg_gen_helper_0_1i(do_mttlo, t0, 3);
5436
            break;
5437
        case 13:
5438
            tcg_gen_helper_0_1i(do_mtthi, t0, 3);
5439
            break;
5440
        case 14:
5441
            tcg_gen_helper_0_1i(do_mttacx, t0, 3);
5442
            break;
5443
        case 16:
5444
            tcg_gen_helper_0_1(do_mttdsp, t0);
5445
            break;
5446
        default:
5447
            goto die;
5448
        }
5449
        break;
5450
    /* Floating point (COP1). */
5451
    case 2:
5452
        /* XXX: For now we support only a single FPU context. */
5453
        if (h == 0) {
5454
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5455

    
5456
            tcg_gen_trunc_tl_i32(fp0, t0);
5457
            gen_store_fpr32(fp0, rd);
5458
            tcg_temp_free(fp0);
5459
        } else {
5460
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5461

    
5462
            tcg_gen_trunc_tl_i32(fp0, t0);
5463
            gen_store_fpr32h(fp0, rd);
5464
            tcg_temp_free(fp0);
5465
        }
5466
        break;
5467
    case 3:
5468
        /* XXX: For now we support only a single FPU context. */
5469
        tcg_gen_helper_0_1i(do_ctc1, t0, rd);
5470
        break;
5471
    /* COP2: Not implemented. */
5472
    case 4:
5473
    case 5:
5474
        /* fall through */
5475
    default:
5476
        goto die;
5477
    }
5478
#if defined MIPS_DEBUG_DISAS
5479
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5480
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5481
                rd, u, sel, h);
5482
    }
5483
#endif
5484
    tcg_temp_free(t0);
5485
    return;
5486

    
5487
die:
5488
    tcg_temp_free(t0);
5489
#if defined MIPS_DEBUG_DISAS
5490
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5491
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5492
                rd, u, sel, h);
5493
    }
5494
#endif
5495
    generate_exception(ctx, EXCP_RI);
5496
}
5497

    
5498
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5499
{
5500
    const char *opn = "ldst";
5501

    
5502
    switch (opc) {
5503
    case OPC_MFC0:
5504
        if (rt == 0) {
5505
            /* Treat as NOP. */
5506
            return;
5507
        }
5508
        {
5509
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5510

    
5511
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5512
            gen_store_gpr(t0, rt);
5513
            tcg_temp_free(t0);
5514
        }
5515
        opn = "mfc0";
5516
        break;
5517
    case OPC_MTC0:
5518
        {
5519
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5520

    
5521
            gen_load_gpr(t0, rt);
5522
            save_cpu_state(ctx, 1);
5523
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5524
            tcg_temp_free(t0);
5525
        }
5526
        opn = "mtc0";
5527
        break;
5528
#if defined(TARGET_MIPS64)
5529
    case OPC_DMFC0:
5530
        check_insn(env, ctx, ISA_MIPS3);
5531
        if (rt == 0) {
5532
            /* Treat as NOP. */
5533
            return;
5534
        }
5535
        {
5536
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5537

    
5538
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5539
            gen_store_gpr(t0, rt);
5540
            tcg_temp_free(t0);
5541
        }
5542
        opn = "dmfc0";
5543
        break;
5544
    case OPC_DMTC0:
5545
        check_insn(env, ctx, ISA_MIPS3);
5546
        {
5547
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5548

    
5549
            gen_load_gpr(t0, rt);
5550
            save_cpu_state(ctx, 1);
5551
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5552
            tcg_temp_free(t0);
5553
        }
5554
        opn = "dmtc0";
5555
        break;
5556
#endif
5557
    case OPC_MFTR:
5558
        check_insn(env, ctx, ASE_MT);
5559
        if (rd == 0) {
5560
            /* Treat as NOP. */
5561
            return;
5562
        }
5563
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5564
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5565
        opn = "mftr";
5566
        break;
5567
    case OPC_MTTR:
5568
        check_insn(env, ctx, ASE_MT);
5569
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5570
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5571
        opn = "mttr";
5572
        break;
5573
    case OPC_TLBWI:
5574
        opn = "tlbwi";
5575
        if (!env->tlb->do_tlbwi)
5576
            goto die;
5577
        tcg_gen_helper_0_0(env->tlb->do_tlbwi);
5578
        break;
5579
    case OPC_TLBWR:
5580
        opn = "tlbwr";
5581
        if (!env->tlb->do_tlbwr)
5582
            goto die;
5583
        tcg_gen_helper_0_0(env->tlb->do_tlbwr);
5584
        break;
5585
    case OPC_TLBP:
5586
        opn = "tlbp";
5587
        if (!env->tlb->do_tlbp)
5588
            goto die;
5589
        tcg_gen_helper_0_0(env->tlb->do_tlbp);
5590
        break;
5591
    case OPC_TLBR:
5592
        opn = "tlbr";
5593
        if (!env->tlb->do_tlbr)
5594
            goto die;
5595
        tcg_gen_helper_0_0(env->tlb->do_tlbr);
5596
        break;
5597
    case OPC_ERET:
5598
        opn = "eret";
5599
        check_insn(env, ctx, ISA_MIPS2);
5600
        save_cpu_state(ctx, 1);
5601
        tcg_gen_helper_0_0(do_eret);
5602
        ctx->bstate = BS_EXCP;
5603
        break;
5604
    case OPC_DERET:
5605
        opn = "deret";
5606
        check_insn(env, ctx, ISA_MIPS32);
5607
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5608
            MIPS_INVAL(opn);
5609
            generate_exception(ctx, EXCP_RI);
5610
        } else {
5611
            save_cpu_state(ctx, 1);
5612
            tcg_gen_helper_0_0(do_deret);
5613
            ctx->bstate = BS_EXCP;
5614
        }
5615
        break;
5616
    case OPC_WAIT:
5617
        opn = "wait";
5618
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5619
        /* If we get an exception, we want to restart at next instruction */
5620
        ctx->pc += 4;
5621
        save_cpu_state(ctx, 1);
5622
        ctx->pc -= 4;
5623
        tcg_gen_helper_0_0(do_wait);
5624
        ctx->bstate = BS_EXCP;
5625
        break;
5626
    default:
5627
 die:
5628
        MIPS_INVAL(opn);
5629
        generate_exception(ctx, EXCP_RI);
5630
        return;
5631
    }
5632
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5633
}
5634
#endif /* !CONFIG_USER_ONLY */
5635

    
5636
/* CP1 Branches (before delay slot) */
5637
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5638
                                 int32_t cc, int32_t offset)
5639
{
5640
    target_ulong btarget;
5641
    const char *opn = "cp1 cond branch";
5642
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5643
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5644

    
5645
    if (cc != 0)
5646
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5647

    
5648
    btarget = ctx->pc + 4 + offset;
5649

    
5650
    switch (op) {
5651
    case OPC_BC1F:
5652
        {
5653
            int l1 = gen_new_label();
5654
            int l2 = gen_new_label();
5655
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5656

    
5657
            get_fp_cond(r_tmp1);
5658
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5659
            tcg_temp_free(r_tmp1);
5660
            tcg_gen_not_tl(t0, t0);
5661
            tcg_gen_movi_tl(t1, 0x1 << cc);
5662
            tcg_gen_and_tl(t0, t0, t1);
5663
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5664
            tcg_gen_movi_tl(t0, 0);
5665
            tcg_gen_br(l2);
5666
            gen_set_label(l1);
5667
            tcg_gen_movi_tl(t0, 1);
5668
            gen_set_label(l2);
5669
        }
5670
        opn = "bc1f";
5671
        goto not_likely;
5672
    case OPC_BC1FL:
5673
        {
5674
            int l1 = gen_new_label();
5675
            int l2 = gen_new_label();
5676
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5677

    
5678
            get_fp_cond(r_tmp1);
5679
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5680
            tcg_temp_free(r_tmp1);
5681
            tcg_gen_not_tl(t0, t0);
5682
            tcg_gen_movi_tl(t1, 0x1 << cc);
5683
            tcg_gen_and_tl(t0, t0, t1);
5684
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5685
            tcg_gen_movi_tl(t0, 0);
5686
            tcg_gen_br(l2);
5687
            gen_set_label(l1);
5688
            tcg_gen_movi_tl(t0, 1);
5689
            gen_set_label(l2);
5690
        }
5691
        opn = "bc1fl";
5692
        goto likely;
5693
    case OPC_BC1T:
5694
        {
5695
            int l1 = gen_new_label();
5696
            int l2 = gen_new_label();
5697
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5698

    
5699
            get_fp_cond(r_tmp1);
5700
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5701
            tcg_temp_free(r_tmp1);
5702
            tcg_gen_movi_tl(t1, 0x1 << cc);
5703
            tcg_gen_and_tl(t0, t0, t1);
5704
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5705
            tcg_gen_movi_tl(t0, 0);
5706
            tcg_gen_br(l2);
5707
            gen_set_label(l1);
5708
            tcg_gen_movi_tl(t0, 1);
5709
            gen_set_label(l2);
5710
        }
5711
        opn = "bc1t";
5712
        goto not_likely;
5713
    case OPC_BC1TL:
5714
        {
5715
            int l1 = gen_new_label();
5716
            int l2 = gen_new_label();
5717
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5718

    
5719
            get_fp_cond(r_tmp1);
5720
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5721
            tcg_temp_free(r_tmp1);
5722
            tcg_gen_movi_tl(t1, 0x1 << cc);
5723
            tcg_gen_and_tl(t0, t0, t1);
5724
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5725
            tcg_gen_movi_tl(t0, 0);
5726
            tcg_gen_br(l2);
5727
            gen_set_label(l1);
5728
            tcg_gen_movi_tl(t0, 1);
5729
            gen_set_label(l2);
5730
        }
5731
        opn = "bc1tl";
5732
    likely:
5733
        ctx->hflags |= MIPS_HFLAG_BL;
5734
        tcg_gen_trunc_tl_i32(bcond, t0);
5735
        break;
5736
    case OPC_BC1FANY2:
5737
        {
5738
            int l1 = gen_new_label();
5739
            int l2 = gen_new_label();
5740
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5741

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

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

    
5783
            get_fp_cond(r_tmp1);
5784
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5785
            tcg_temp_free(r_tmp1);
5786
            tcg_gen_not_tl(t0, t0);
5787
            tcg_gen_movi_tl(t1, 0xf << cc);
5788
            tcg_gen_and_tl(t0, t0, t1);
5789
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5790
            tcg_gen_movi_tl(t0, 0);
5791
            tcg_gen_br(l2);
5792
            gen_set_label(l1);
5793
            tcg_gen_movi_tl(t0, 1);
5794
            gen_set_label(l2);
5795
        }
5796
        opn = "bc1any4f";
5797
        goto not_likely;
5798
    case OPC_BC1TANY4:
5799
        {
5800
            int l1 = gen_new_label();
5801
            int l2 = gen_new_label();
5802
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5803

    
5804
            get_fp_cond(r_tmp1);
5805
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5806
            tcg_temp_free(r_tmp1);
5807
            tcg_gen_movi_tl(t1, 0xf << cc);
5808
            tcg_gen_and_tl(t0, t0, t1);
5809
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5810
            tcg_gen_movi_tl(t0, 0);
5811
            tcg_gen_br(l2);
5812
            gen_set_label(l1);
5813
            tcg_gen_movi_tl(t0, 1);
5814
            gen_set_label(l2);
5815
        }
5816
        opn = "bc1any4t";
5817
    not_likely:
5818
        ctx->hflags |= MIPS_HFLAG_BC;
5819
        tcg_gen_trunc_tl_i32(bcond, t0);
5820
        break;
5821
    default:
5822
        MIPS_INVAL(opn);
5823
        generate_exception (ctx, EXCP_RI);
5824
        goto out;
5825
    }
5826
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5827
               ctx->hflags, btarget);
5828
    ctx->btarget = btarget;
5829

    
5830
 out:
5831
    tcg_temp_free(t0);
5832
    tcg_temp_free(t1);
5833
}
5834

    
5835
/* Coprocessor 1 (FPU) */
5836

    
5837
#define FOP(func, fmt) (((fmt) << 21) | (func))
5838

    
5839
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5840
{
5841
    const char *opn = "cp1 move";
5842
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5843

    
5844
    switch (opc) {
5845
    case OPC_MFC1:
5846
        {
5847
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5848

    
5849
            gen_load_fpr32(fp0, fs);
5850
            tcg_gen_ext_i32_tl(t0, fp0);
5851
            tcg_temp_free(fp0);
5852
        }
5853
        gen_store_gpr(t0, rt);
5854
        opn = "mfc1";
5855
        break;
5856
    case OPC_MTC1:
5857
        gen_load_gpr(t0, rt);
5858
        {
5859
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5860

    
5861
            tcg_gen_trunc_tl_i32(fp0, t0);
5862
            gen_store_fpr32(fp0, fs);
5863
            tcg_temp_free(fp0);
5864
        }
5865
        opn = "mtc1";
5866
        break;
5867
    case OPC_CFC1:
5868
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5869
        gen_store_gpr(t0, rt);
5870
        opn = "cfc1";
5871
        break;
5872
    case OPC_CTC1:
5873
        gen_load_gpr(t0, rt);
5874
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5875
        opn = "ctc1";
5876
        break;
5877
    case OPC_DMFC1:
5878
        {
5879
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5880

    
5881
            gen_load_fpr64(ctx, fp0, fs);
5882
            tcg_gen_mov_tl(t0, fp0);
5883
            tcg_temp_free(fp0);
5884
        }
5885
        gen_store_gpr(t0, rt);
5886
        opn = "dmfc1";
5887
        break;
5888
    case OPC_DMTC1:
5889
        gen_load_gpr(t0, rt);
5890
        {
5891
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5892

    
5893
            tcg_gen_mov_tl(fp0, t0);
5894
            gen_store_fpr64(ctx, fp0, fs);
5895
            tcg_temp_free(fp0);
5896
        }
5897
        opn = "dmtc1";
5898
        break;
5899
    case OPC_MFHC1:
5900
        {
5901
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5902

    
5903
            gen_load_fpr32h(fp0, fs);
5904
            tcg_gen_ext_i32_tl(t0, fp0);
5905
            tcg_temp_free(fp0);
5906
        }
5907
        gen_store_gpr(t0, rt);
5908
        opn = "mfhc1";
5909
        break;
5910
    case OPC_MTHC1:
5911
        gen_load_gpr(t0, rt);
5912
        {
5913
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5914

    
5915
            tcg_gen_trunc_tl_i32(fp0, t0);
5916
            gen_store_fpr32h(fp0, fs);
5917
            tcg_temp_free(fp0);
5918
        }
5919
        opn = "mthc1";
5920
        break;
5921
    default:
5922
        MIPS_INVAL(opn);
5923
        generate_exception (ctx, EXCP_RI);
5924
        goto out;
5925
    }
5926
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5927

    
5928
 out:
5929
    tcg_temp_free(t0);
5930
}
5931

    
5932
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5933
{
5934
    int l1 = gen_new_label();
5935
    uint32_t ccbit;
5936
    TCGCond cond;
5937
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5938
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5939
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
5940

    
5941
    if (cc)
5942
        ccbit = 1 << (24 + cc);
5943
    else
5944
        ccbit = 1 << 23;
5945
    if (tf)
5946
        cond = TCG_COND_EQ;
5947
    else
5948
        cond = TCG_COND_NE;
5949

    
5950
    gen_load_gpr(t0, rd);
5951
    gen_load_gpr(t1, rs);
5952
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5953
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5954
    tcg_temp_free(r_tmp);
5955

    
5956
    tcg_gen_mov_tl(t0, t1);
5957
    tcg_temp_free(t1);
5958

    
5959
    gen_set_label(l1);
5960
    gen_store_gpr(t0, rd);
5961
    tcg_temp_free(t0);
5962
}
5963

    
5964
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5965
{
5966
    uint32_t ccbit;
5967
    int cond;
5968
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
5969
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
5970
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
5971
    int l1 = gen_new_label();
5972

    
5973
    if (cc)
5974
        ccbit = 1 << (24 + cc);
5975
    else
5976
        ccbit = 1 << 23;
5977

    
5978
    if (tf)
5979
        cond = TCG_COND_EQ;
5980
    else
5981
        cond = TCG_COND_NE;
5982

    
5983
    gen_load_fpr32(fp0, fs);
5984
    gen_load_fpr32(fp1, fd);
5985
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5986
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5987
    tcg_gen_mov_i32(fp1, fp0);
5988
    tcg_temp_free(fp0);
5989
    gen_set_label(l1);
5990
    tcg_temp_free(r_tmp1);
5991
    gen_store_fpr32(fp1, fd);
5992
    tcg_temp_free(fp1);
5993
}
5994

    
5995
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5996
{
5997
    uint32_t ccbit;
5998
    int cond;
5999
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6000
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6001
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I64);
6002
    int l1 = gen_new_label();
6003

    
6004
    if (cc)
6005
        ccbit = 1 << (24 + cc);
6006
    else
6007
        ccbit = 1 << 23;
6008

    
6009
    if (tf)
6010
        cond = TCG_COND_EQ;
6011
    else
6012
        cond = TCG_COND_NE;
6013

    
6014
    gen_load_fpr64(ctx, fp0, fs);
6015
    gen_load_fpr64(ctx, fp1, fd);
6016
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6017
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6018
    tcg_gen_mov_i64(fp1, fp0);
6019
    tcg_temp_free(fp0);
6020
    gen_set_label(l1);
6021
    tcg_temp_free(r_tmp1);
6022
    gen_store_fpr64(ctx, fp1, fd);
6023
    tcg_temp_free(fp1);
6024
}
6025

    
6026
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6027
{
6028
    int cond;
6029
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6030
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6031
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6032
    TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
6033
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6034
    TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
6035
    int l1 = gen_new_label();
6036
    int l2 = gen_new_label();
6037

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

    
6043
    gen_load_fpr32(fp0, fs);
6044
    gen_load_fpr32h(fph0, fs);
6045
    gen_load_fpr32(fp1, fd);
6046
    gen_load_fpr32h(fph1, fd);
6047
    get_fp_cond(r_tmp1);
6048
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6049
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6050
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6051
    tcg_gen_mov_i32(fp1, fp0);
6052
    tcg_temp_free(fp0);
6053
    gen_set_label(l1);
6054
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6055
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6056
    tcg_gen_mov_i32(fph1, fph0);
6057
    tcg_temp_free(fph0);
6058
    gen_set_label(l2);
6059
    tcg_temp_free(r_tmp1);
6060
    tcg_temp_free(r_tmp2);
6061
    gen_store_fpr32(fp1, fd);
6062
    gen_store_fpr32h(fph1, fd);
6063
    tcg_temp_free(fp1);
6064
    tcg_temp_free(fph1);
6065
}
6066

    
6067

    
6068
static void gen_farith (DisasContext *ctx, uint32_t op1,
6069
                        int ft, int fs, int fd, int cc)
6070
{
6071
    const char *opn = "farith";
6072
    const char *condnames[] = {
6073
            "c.f",
6074
            "c.un",
6075
            "c.eq",
6076
            "c.ueq",
6077
            "c.olt",
6078
            "c.ult",
6079
            "c.ole",
6080
            "c.ule",
6081
            "c.sf",
6082
            "c.ngle",
6083
            "c.seq",
6084
            "c.ngl",
6085
            "c.lt",
6086
            "c.nge",
6087
            "c.le",
6088
            "c.ngt",
6089
    };
6090
    const char *condnames_abs[] = {
6091
            "cabs.f",
6092
            "cabs.un",
6093
            "cabs.eq",
6094
            "cabs.ueq",
6095
            "cabs.olt",
6096
            "cabs.ult",
6097
            "cabs.ole",
6098
            "cabs.ule",
6099
            "cabs.sf",
6100
            "cabs.ngle",
6101
            "cabs.seq",
6102
            "cabs.ngl",
6103
            "cabs.lt",
6104
            "cabs.nge",
6105
            "cabs.le",
6106
            "cabs.ngt",
6107
    };
6108
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6109
    uint32_t func = ctx->opcode & 0x3f;
6110

    
6111
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6112
    case FOP(0, 16):
6113
        {
6114
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6115
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6116

    
6117
            gen_load_fpr32(fp0, fs);
6118
            gen_load_fpr32(fp1, ft);
6119
            tcg_gen_helper_1_2(do_float_add_s, fp0, fp0, fp1);
6120
            tcg_temp_free(fp1);
6121
            gen_store_fpr32(fp0, fd);
6122
            tcg_temp_free(fp0);
6123
        }
6124
        opn = "add.s";
6125
        optype = BINOP;
6126
        break;
6127
    case FOP(1, 16):
6128
        {
6129
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6130
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6131

    
6132
            gen_load_fpr32(fp0, fs);
6133
            gen_load_fpr32(fp1, ft);
6134
            tcg_gen_helper_1_2(do_float_sub_s, fp0, fp0, fp1);
6135
            tcg_temp_free(fp1);
6136
            gen_store_fpr32(fp0, fd);
6137
            tcg_temp_free(fp0);
6138
        }
6139
        opn = "sub.s";
6140
        optype = BINOP;
6141
        break;
6142
    case FOP(2, 16):
6143
        {
6144
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6145
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6146

    
6147
            gen_load_fpr32(fp0, fs);
6148
            gen_load_fpr32(fp1, ft);
6149
            tcg_gen_helper_1_2(do_float_mul_s, fp0, fp0, fp1);
6150
            tcg_temp_free(fp1);
6151
            gen_store_fpr32(fp0, fd);
6152
            tcg_temp_free(fp0);
6153
        }
6154
        opn = "mul.s";
6155
        optype = BINOP;
6156
        break;
6157
    case FOP(3, 16):
6158
        {
6159
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6160
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6161

    
6162
            gen_load_fpr32(fp0, fs);
6163
            gen_load_fpr32(fp1, ft);
6164
            tcg_gen_helper_1_2(do_float_div_s, fp0, fp0, fp1);
6165
            tcg_temp_free(fp1);
6166
            gen_store_fpr32(fp0, fd);
6167
            tcg_temp_free(fp0);
6168
        }
6169
        opn = "div.s";
6170
        optype = BINOP;
6171
        break;
6172
    case FOP(4, 16):
6173
        {
6174
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6175

    
6176
            gen_load_fpr32(fp0, fs);
6177
            tcg_gen_helper_1_1(do_float_sqrt_s, fp0, fp0);
6178
            gen_store_fpr32(fp0, fd);
6179
            tcg_temp_free(fp0);
6180
        }
6181
        opn = "sqrt.s";
6182
        break;
6183
    case FOP(5, 16):
6184
        {
6185
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6186

    
6187
            gen_load_fpr32(fp0, fs);
6188
            tcg_gen_helper_1_1(do_float_abs_s, fp0, fp0);
6189
            gen_store_fpr32(fp0, fd);
6190
            tcg_temp_free(fp0);
6191
        }
6192
        opn = "abs.s";
6193
        break;
6194
    case FOP(6, 16):
6195
        {
6196
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6197

    
6198
            gen_load_fpr32(fp0, fs);
6199
            gen_store_fpr32(fp0, fd);
6200
            tcg_temp_free(fp0);
6201
        }
6202
        opn = "mov.s";
6203
        break;
6204
    case FOP(7, 16):
6205
        {
6206
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6207

    
6208
            gen_load_fpr32(fp0, fs);
6209
            tcg_gen_helper_1_1(do_float_chs_s, fp0, fp0);
6210
            gen_store_fpr32(fp0, fd);
6211
            tcg_temp_free(fp0);
6212
        }
6213
        opn = "neg.s";
6214
        break;
6215
    case FOP(8, 16):
6216
        check_cp1_64bitmode(ctx);
6217
        {
6218
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6219
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6220

    
6221
            gen_load_fpr32(fp32, fs);
6222
            tcg_gen_helper_1_1(do_float_roundl_s, fp64, fp32);
6223
            tcg_temp_free(fp32);
6224
            gen_store_fpr64(ctx, fp64, fd);
6225
            tcg_temp_free(fp64);
6226
        }
6227
        opn = "round.l.s";
6228
        break;
6229
    case FOP(9, 16):
6230
        check_cp1_64bitmode(ctx);
6231
        {
6232
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6233
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6234

    
6235
            gen_load_fpr32(fp32, fs);
6236
            tcg_gen_helper_1_1(do_float_truncl_s, fp64, fp32);
6237
            tcg_temp_free(fp32);
6238
            gen_store_fpr64(ctx, fp64, fd);
6239
            tcg_temp_free(fp64);
6240
        }
6241
        opn = "trunc.l.s";
6242
        break;
6243
    case FOP(10, 16):
6244
        check_cp1_64bitmode(ctx);
6245
        {
6246
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6247
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6248

    
6249
            gen_load_fpr32(fp32, fs);
6250
            tcg_gen_helper_1_1(do_float_ceill_s, fp64, fp32);
6251
            tcg_temp_free(fp32);
6252
            gen_store_fpr64(ctx, fp64, fd);
6253
            tcg_temp_free(fp64);
6254
        }
6255
        opn = "ceil.l.s";
6256
        break;
6257
    case FOP(11, 16):
6258
        check_cp1_64bitmode(ctx);
6259
        {
6260
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6261
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6262

    
6263
            gen_load_fpr32(fp32, fs);
6264
            tcg_gen_helper_1_1(do_float_floorl_s, fp64, fp32);
6265
            tcg_temp_free(fp32);
6266
            gen_store_fpr64(ctx, fp64, fd);
6267
            tcg_temp_free(fp64);
6268
        }
6269
        opn = "floor.l.s";
6270
        break;
6271
    case FOP(12, 16):
6272
        {
6273
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6274

    
6275
            gen_load_fpr32(fp0, fs);
6276
            tcg_gen_helper_1_1(do_float_roundw_s, fp0, fp0);
6277
            gen_store_fpr32(fp0, fd);
6278
            tcg_temp_free(fp0);
6279
        }
6280
        opn = "round.w.s";
6281
        break;
6282
    case FOP(13, 16):
6283
        {
6284
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6285

    
6286
            gen_load_fpr32(fp0, fs);
6287
            tcg_gen_helper_1_1(do_float_truncw_s, fp0, fp0);
6288
            gen_store_fpr32(fp0, fd);
6289
            tcg_temp_free(fp0);
6290
        }
6291
        opn = "trunc.w.s";
6292
        break;
6293
    case FOP(14, 16):
6294
        {
6295
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6296

    
6297
            gen_load_fpr32(fp0, fs);
6298
            tcg_gen_helper_1_1(do_float_ceilw_s, fp0, fp0);
6299
            gen_store_fpr32(fp0, fd);
6300
            tcg_temp_free(fp0);
6301
        }
6302
        opn = "ceil.w.s";
6303
        break;
6304
    case FOP(15, 16):
6305
        {
6306
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6307

    
6308
            gen_load_fpr32(fp0, fs);
6309
            tcg_gen_helper_1_1(do_float_floorw_s, fp0, fp0);
6310
            gen_store_fpr32(fp0, fd);
6311
            tcg_temp_free(fp0);
6312
        }
6313
        opn = "floor.w.s";
6314
        break;
6315
    case FOP(17, 16):
6316
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6317
        opn = "movcf.s";
6318
        break;
6319
    case FOP(18, 16):
6320
        {
6321
            int l1 = gen_new_label();
6322
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6323
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6324

    
6325
            gen_load_gpr(t0, ft);
6326
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6327
            tcg_temp_free(t0);
6328
            gen_load_fpr32(fp0, fs);
6329
            gen_store_fpr32(fp0, fd);
6330
            tcg_temp_free(fp0);
6331
            gen_set_label(l1);
6332
        }
6333
        opn = "movz.s";
6334
        break;
6335
    case FOP(19, 16):
6336
        {
6337
            int l1 = gen_new_label();
6338
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6339
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6340

    
6341
            gen_load_gpr(t0, ft);
6342
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6343
            tcg_temp_free(t0);
6344
            gen_load_fpr32(fp0, fs);
6345
            gen_store_fpr32(fp0, fd);
6346
            tcg_temp_free(fp0);
6347
            gen_set_label(l1);
6348
        }
6349
        opn = "movn.s";
6350
        break;
6351
    case FOP(21, 16):
6352
        check_cop1x(ctx);
6353
        {
6354
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6355

    
6356
            gen_load_fpr32(fp0, fs);
6357
            tcg_gen_helper_1_1(do_float_recip_s, fp0, fp0);
6358
            gen_store_fpr32(fp0, fd);
6359
            tcg_temp_free(fp0);
6360
        }
6361
        opn = "recip.s";
6362
        break;
6363
    case FOP(22, 16):
6364
        check_cop1x(ctx);
6365
        {
6366
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6367

    
6368
            gen_load_fpr32(fp0, fs);
6369
            tcg_gen_helper_1_1(do_float_rsqrt_s, fp0, fp0);
6370
            gen_store_fpr32(fp0, fd);
6371
            tcg_temp_free(fp0);
6372
        }
6373
        opn = "rsqrt.s";
6374
        break;
6375
    case FOP(28, 16):
6376
        check_cp1_64bitmode(ctx);
6377
        {
6378
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6379
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6380

    
6381
            gen_load_fpr32(fp0, fs);
6382
            gen_load_fpr32(fp1, fd);
6383
            tcg_gen_helper_1_2(do_float_recip2_s, fp0, fp0, fp1);
6384
            tcg_temp_free(fp1);
6385
            gen_store_fpr32(fp0, fd);
6386
            tcg_temp_free(fp0);
6387
        }
6388
        opn = "recip2.s";
6389
        break;
6390
    case FOP(29, 16):
6391
        check_cp1_64bitmode(ctx);
6392
        {
6393
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6394

    
6395
            gen_load_fpr32(fp0, fs);
6396
            tcg_gen_helper_1_1(do_float_recip1_s, fp0, fp0);
6397
            gen_store_fpr32(fp0, fd);
6398
            tcg_temp_free(fp0);
6399
        }
6400
        opn = "recip1.s";
6401
        break;
6402
    case FOP(30, 16):
6403
        check_cp1_64bitmode(ctx);
6404
        {
6405
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6406

    
6407
            gen_load_fpr32(fp0, fs);
6408
            tcg_gen_helper_1_1(do_float_rsqrt1_s, fp0, fp0);
6409
            gen_store_fpr32(fp0, fd);
6410
            tcg_temp_free(fp0);
6411
        }
6412
        opn = "rsqrt1.s";
6413
        break;
6414
    case FOP(31, 16):
6415
        check_cp1_64bitmode(ctx);
6416
        {
6417
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6418
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6419

    
6420
            gen_load_fpr32(fp0, fs);
6421
            gen_load_fpr32(fp1, ft);
6422
            tcg_gen_helper_1_2(do_float_rsqrt2_s, fp0, fp0, fp1);
6423
            tcg_temp_free(fp1);
6424
            gen_store_fpr32(fp0, fd);
6425
            tcg_temp_free(fp0);
6426
        }
6427
        opn = "rsqrt2.s";
6428
        break;
6429
    case FOP(33, 16):
6430
        check_cp1_registers(ctx, fd);
6431
        {
6432
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6433
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6434

    
6435
            gen_load_fpr32(fp32, fs);
6436
            tcg_gen_helper_1_1(do_float_cvtd_s, fp64, fp32);
6437
            tcg_temp_free(fp32);
6438
            gen_store_fpr64(ctx, fp64, fd);
6439
            tcg_temp_free(fp64);
6440
        }
6441
        opn = "cvt.d.s";
6442
        break;
6443
    case FOP(36, 16):
6444
        {
6445
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6446

    
6447
            gen_load_fpr32(fp0, fs);
6448
            tcg_gen_helper_1_1(do_float_cvtw_s, fp0, fp0);
6449
            gen_store_fpr32(fp0, fd);
6450
            tcg_temp_free(fp0);
6451
        }
6452
        opn = "cvt.w.s";
6453
        break;
6454
    case FOP(37, 16):
6455
        check_cp1_64bitmode(ctx);
6456
        {
6457
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6458
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6459

    
6460
            gen_load_fpr32(fp32, fs);
6461
            tcg_gen_helper_1_1(do_float_cvtl_s, fp64, fp32);
6462
            tcg_temp_free(fp32);
6463
            gen_store_fpr64(ctx, fp64, fd);
6464
            tcg_temp_free(fp64);
6465
        }
6466
        opn = "cvt.l.s";
6467
        break;
6468
    case FOP(38, 16):
6469
        check_cp1_64bitmode(ctx);
6470
        {
6471
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6472
            TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
6473
            TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
6474

    
6475
            gen_load_fpr32(fp32_0, fs);
6476
            gen_load_fpr32(fp32_1, ft);
6477
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6478
            tcg_temp_free(fp32_1);
6479
            tcg_temp_free(fp32_0);
6480
            gen_store_fpr64(ctx, fp64, fd);
6481
            tcg_temp_free(fp64);
6482
        }
6483
        opn = "cvt.ps.s";
6484
        break;
6485
    case FOP(48, 16):
6486
    case FOP(49, 16):
6487
    case FOP(50, 16):
6488
    case FOP(51, 16):
6489
    case FOP(52, 16):
6490
    case FOP(53, 16):
6491
    case FOP(54, 16):
6492
    case FOP(55, 16):
6493
    case FOP(56, 16):
6494
    case FOP(57, 16):
6495
    case FOP(58, 16):
6496
    case FOP(59, 16):
6497
    case FOP(60, 16):
6498
    case FOP(61, 16):
6499
    case FOP(62, 16):
6500
    case FOP(63, 16):
6501
        {
6502
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6503
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6504

    
6505
            gen_load_fpr32(fp0, fs);
6506
            gen_load_fpr32(fp1, ft);
6507
            if (ctx->opcode & (1 << 6)) {
6508
                check_cop1x(ctx);
6509
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6510
                opn = condnames_abs[func-48];
6511
            } else {
6512
                gen_cmp_s(func-48, fp0, fp1, cc);
6513
                opn = condnames[func-48];
6514
            }
6515
            tcg_temp_free(fp0);
6516
            tcg_temp_free(fp1);
6517
        }
6518
        break;
6519
    case FOP(0, 17):
6520
        check_cp1_registers(ctx, fs | ft | fd);
6521
        {
6522
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6523
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6524

    
6525
            gen_load_fpr64(ctx, fp0, fs);
6526
            gen_load_fpr64(ctx, fp1, ft);
6527
            tcg_gen_helper_1_2(do_float_add_d, fp0, fp0, fp1);
6528
            tcg_temp_free(fp1);
6529
            gen_store_fpr64(ctx, fp0, fd);
6530
            tcg_temp_free(fp0);
6531
        }
6532
        opn = "add.d";
6533
        optype = BINOP;
6534
        break;
6535
    case FOP(1, 17):
6536
        check_cp1_registers(ctx, fs | ft | fd);
6537
        {
6538
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6539
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6540

    
6541
            gen_load_fpr64(ctx, fp0, fs);
6542
            gen_load_fpr64(ctx, fp1, ft);
6543
            tcg_gen_helper_1_2(do_float_sub_d, fp0, fp0, fp1);
6544
            tcg_temp_free(fp1);
6545
            gen_store_fpr64(ctx, fp0, fd);
6546
            tcg_temp_free(fp0);
6547
        }
6548
        opn = "sub.d";
6549
        optype = BINOP;
6550
        break;
6551
    case FOP(2, 17):
6552
        check_cp1_registers(ctx, fs | ft | fd);
6553
        {
6554
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6555
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6556

    
6557
            gen_load_fpr64(ctx, fp0, fs);
6558
            gen_load_fpr64(ctx, fp1, ft);
6559
            tcg_gen_helper_1_2(do_float_mul_d, fp0, fp0, fp1);
6560
            tcg_temp_free(fp1);
6561
            gen_store_fpr64(ctx, fp0, fd);
6562
            tcg_temp_free(fp0);
6563
        }
6564
        opn = "mul.d";
6565
        optype = BINOP;
6566
        break;
6567
    case FOP(3, 17):
6568
        check_cp1_registers(ctx, fs | ft | fd);
6569
        {
6570
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6571
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6572

    
6573
            gen_load_fpr64(ctx, fp0, fs);
6574
            gen_load_fpr64(ctx, fp1, ft);
6575
            tcg_gen_helper_1_2(do_float_div_d, fp0, fp0, fp1);
6576
            tcg_temp_free(fp1);
6577
            gen_store_fpr64(ctx, fp0, fd);
6578
            tcg_temp_free(fp0);
6579
        }
6580
        opn = "div.d";
6581
        optype = BINOP;
6582
        break;
6583
    case FOP(4, 17):
6584
        check_cp1_registers(ctx, fs | fd);
6585
        {
6586
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6587

    
6588
            gen_load_fpr64(ctx, fp0, fs);
6589
            tcg_gen_helper_1_1(do_float_sqrt_d, fp0, fp0);
6590
            gen_store_fpr64(ctx, fp0, fd);
6591
            tcg_temp_free(fp0);
6592
        }
6593
        opn = "sqrt.d";
6594
        break;
6595
    case FOP(5, 17):
6596
        check_cp1_registers(ctx, fs | fd);
6597
        {
6598
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6599

    
6600
            gen_load_fpr64(ctx, fp0, fs);
6601
            tcg_gen_helper_1_1(do_float_abs_d, fp0, fp0);
6602
            gen_store_fpr64(ctx, fp0, fd);
6603
            tcg_temp_free(fp0);
6604
        }
6605
        opn = "abs.d";
6606
        break;
6607
    case FOP(6, 17):
6608
        check_cp1_registers(ctx, fs | fd);
6609
        {
6610
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6611

    
6612
            gen_load_fpr64(ctx, fp0, fs);
6613
            gen_store_fpr64(ctx, fp0, fd);
6614
            tcg_temp_free(fp0);
6615
        }
6616
        opn = "mov.d";
6617
        break;
6618
    case FOP(7, 17):
6619
        check_cp1_registers(ctx, fs | fd);
6620
        {
6621
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6622

    
6623
            gen_load_fpr64(ctx, fp0, fs);
6624
            tcg_gen_helper_1_1(do_float_chs_d, fp0, fp0);
6625
            gen_store_fpr64(ctx, fp0, fd);
6626
            tcg_temp_free(fp0);
6627
        }
6628
        opn = "neg.d";
6629
        break;
6630
    case FOP(8, 17):
6631
        check_cp1_64bitmode(ctx);
6632
        {
6633
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6634

    
6635
            gen_load_fpr64(ctx, fp0, fs);
6636
            tcg_gen_helper_1_1(do_float_roundl_d, fp0, fp0);
6637
            gen_store_fpr64(ctx, fp0, fd);
6638
            tcg_temp_free(fp0);
6639
        }
6640
        opn = "round.l.d";
6641
        break;
6642
    case FOP(9, 17):
6643
        check_cp1_64bitmode(ctx);
6644
        {
6645
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6646

    
6647
            gen_load_fpr64(ctx, fp0, fs);
6648
            tcg_gen_helper_1_1(do_float_truncl_d, fp0, fp0);
6649
            gen_store_fpr64(ctx, fp0, fd);
6650
            tcg_temp_free(fp0);
6651
        }
6652
        opn = "trunc.l.d";
6653
        break;
6654
    case FOP(10, 17):
6655
        check_cp1_64bitmode(ctx);
6656
        {
6657
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6658

    
6659
            gen_load_fpr64(ctx, fp0, fs);
6660
            tcg_gen_helper_1_1(do_float_ceill_d, fp0, fp0);
6661
            gen_store_fpr64(ctx, fp0, fd);
6662
            tcg_temp_free(fp0);
6663
        }
6664
        opn = "ceil.l.d";
6665
        break;
6666
    case FOP(11, 17):
6667
        check_cp1_64bitmode(ctx);
6668
        {
6669
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6670

    
6671
            gen_load_fpr64(ctx, fp0, fs);
6672
            tcg_gen_helper_1_1(do_float_floorl_d, fp0, fp0);
6673
            gen_store_fpr64(ctx, fp0, fd);
6674
            tcg_temp_free(fp0);
6675
        }
6676
        opn = "floor.l.d";
6677
        break;
6678
    case FOP(12, 17):
6679
        check_cp1_registers(ctx, fs);
6680
        {
6681
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6682
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6683

    
6684
            gen_load_fpr64(ctx, fp64, fs);
6685
            tcg_gen_helper_1_1(do_float_roundw_d, fp32, fp64);
6686
            tcg_temp_free(fp64);
6687
            gen_store_fpr32(fp32, fd);
6688
            tcg_temp_free(fp32);
6689
        }
6690
        opn = "round.w.d";
6691
        break;
6692
    case FOP(13, 17):
6693
        check_cp1_registers(ctx, fs);
6694
        {
6695
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6696
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6697

    
6698
            gen_load_fpr64(ctx, fp64, fs);
6699
            tcg_gen_helper_1_1(do_float_truncw_d, fp32, fp64);
6700
            tcg_temp_free(fp64);
6701
            gen_store_fpr32(fp32, fd);
6702
            tcg_temp_free(fp32);
6703
        }
6704
        opn = "trunc.w.d";
6705
        break;
6706
    case FOP(14, 17):
6707
        check_cp1_registers(ctx, fs);
6708
        {
6709
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6710
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6711

    
6712
            gen_load_fpr64(ctx, fp64, fs);
6713
            tcg_gen_helper_1_1(do_float_ceilw_d, fp32, fp64);
6714
            tcg_temp_free(fp64);
6715
            gen_store_fpr32(fp32, fd);
6716
            tcg_temp_free(fp32);
6717
        }
6718
        opn = "ceil.w.d";
6719
        break;
6720
    case FOP(15, 17):
6721
        check_cp1_registers(ctx, fs);
6722
        {
6723
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6724
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6725

    
6726
            gen_load_fpr64(ctx, fp64, fs);
6727
            tcg_gen_helper_1_1(do_float_floorw_d, fp32, fp64);
6728
            tcg_temp_free(fp64);
6729
            gen_store_fpr32(fp32, fd);
6730
            tcg_temp_free(fp32);
6731
        }
6732
        opn = "floor.w.d";
6733
        break;
6734
    case FOP(17, 17):
6735
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6736
        opn = "movcf.d";
6737
        break;
6738
    case FOP(18, 17):
6739
        {
6740
            int l1 = gen_new_label();
6741
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6742
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6743

    
6744
            gen_load_gpr(t0, ft);
6745
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6746
            tcg_temp_free(t0);
6747
            gen_load_fpr64(ctx, fp0, fs);
6748
            gen_store_fpr64(ctx, fp0, fd);
6749
            tcg_temp_free(fp0);
6750
            gen_set_label(l1);
6751
        }
6752
        opn = "movz.d";
6753
        break;
6754
    case FOP(19, 17):
6755
        {
6756
            int l1 = gen_new_label();
6757
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6758
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6759

    
6760
            gen_load_gpr(t0, ft);
6761
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6762
            tcg_temp_free(t0);
6763
            gen_load_fpr64(ctx, fp0, fs);
6764
            gen_store_fpr64(ctx, fp0, fd);
6765
            tcg_temp_free(fp0);
6766
            gen_set_label(l1);
6767
        }
6768
        opn = "movn.d";
6769
        break;
6770
    case FOP(21, 17):
6771
        check_cp1_64bitmode(ctx);
6772
        {
6773
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6774

    
6775
            gen_load_fpr64(ctx, fp0, fs);
6776
            tcg_gen_helper_1_1(do_float_recip_d, fp0, fp0);
6777
            gen_store_fpr64(ctx, fp0, fd);
6778
            tcg_temp_free(fp0);
6779
        }
6780
        opn = "recip.d";
6781
        break;
6782
    case FOP(22, 17):
6783
        check_cp1_64bitmode(ctx);
6784
        {
6785
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6786

    
6787
            gen_load_fpr64(ctx, fp0, fs);
6788
            tcg_gen_helper_1_1(do_float_rsqrt_d, fp0, fp0);
6789
            gen_store_fpr64(ctx, fp0, fd);
6790
            tcg_temp_free(fp0);
6791
        }
6792
        opn = "rsqrt.d";
6793
        break;
6794
    case FOP(28, 17):
6795
        check_cp1_64bitmode(ctx);
6796
        {
6797
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6798
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6799

    
6800
            gen_load_fpr64(ctx, fp0, fs);
6801
            gen_load_fpr64(ctx, fp1, ft);
6802
            tcg_gen_helper_1_2(do_float_recip2_d, fp0, fp0, fp1);
6803
            tcg_temp_free(fp1);
6804
            gen_store_fpr64(ctx, fp0, fd);
6805
            tcg_temp_free(fp0);
6806
        }
6807
        opn = "recip2.d";
6808
        break;
6809
    case FOP(29, 17):
6810
        check_cp1_64bitmode(ctx);
6811
        {
6812
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6813

    
6814
            gen_load_fpr64(ctx, fp0, fs);
6815
            tcg_gen_helper_1_1(do_float_recip1_d, fp0, fp0);
6816
            gen_store_fpr64(ctx, fp0, fd);
6817
            tcg_temp_free(fp0);
6818
        }
6819
        opn = "recip1.d";
6820
        break;
6821
    case FOP(30, 17):
6822
        check_cp1_64bitmode(ctx);
6823
        {
6824
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6825

    
6826
            gen_load_fpr64(ctx, fp0, fs);
6827
            tcg_gen_helper_1_1(do_float_rsqrt1_d, fp0, fp0);
6828
            gen_store_fpr64(ctx, fp0, fd);
6829
            tcg_temp_free(fp0);
6830
        }
6831
        opn = "rsqrt1.d";
6832
        break;
6833
    case FOP(31, 17):
6834
        check_cp1_64bitmode(ctx);
6835
        {
6836
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6837
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6838

    
6839
            gen_load_fpr64(ctx, fp0, fs);
6840
            gen_load_fpr64(ctx, fp1, ft);
6841
            tcg_gen_helper_1_2(do_float_rsqrt2_d, fp0, fp0, fp1);
6842
            tcg_temp_free(fp1);
6843
            gen_store_fpr64(ctx, fp0, fd);
6844
            tcg_temp_free(fp0);
6845
        }
6846
        opn = "rsqrt2.d";
6847
        break;
6848
    case FOP(48, 17):
6849
    case FOP(49, 17):
6850
    case FOP(50, 17):
6851
    case FOP(51, 17):
6852
    case FOP(52, 17):
6853
    case FOP(53, 17):
6854
    case FOP(54, 17):
6855
    case FOP(55, 17):
6856
    case FOP(56, 17):
6857
    case FOP(57, 17):
6858
    case FOP(58, 17):
6859
    case FOP(59, 17):
6860
    case FOP(60, 17):
6861
    case FOP(61, 17):
6862
    case FOP(62, 17):
6863
    case FOP(63, 17):
6864
        {
6865
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6866
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6867

    
6868
            gen_load_fpr64(ctx, fp0, fs);
6869
            gen_load_fpr64(ctx, fp1, ft);
6870
            if (ctx->opcode & (1 << 6)) {
6871
                check_cop1x(ctx);
6872
                check_cp1_registers(ctx, fs | ft);
6873
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6874
                opn = condnames_abs[func-48];
6875
            } else {
6876
                check_cp1_registers(ctx, fs | ft);
6877
                gen_cmp_d(func-48, fp0, fp1, cc);
6878
                opn = condnames[func-48];
6879
            }
6880
            tcg_temp_free(fp0);
6881
            tcg_temp_free(fp1);
6882
        }
6883
        break;
6884
    case FOP(32, 17):
6885
        check_cp1_registers(ctx, fs);
6886
        {
6887
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6888
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6889

    
6890
            gen_load_fpr64(ctx, fp64, fs);
6891
            tcg_gen_helper_1_1(do_float_cvts_d, fp32, fp64);
6892
            tcg_temp_free(fp64);
6893
            gen_store_fpr32(fp32, fd);
6894
            tcg_temp_free(fp32);
6895
        }
6896
        opn = "cvt.s.d";
6897
        break;
6898
    case FOP(36, 17):
6899
        check_cp1_registers(ctx, fs);
6900
        {
6901
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6902
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6903

    
6904
            gen_load_fpr64(ctx, fp64, fs);
6905
            tcg_gen_helper_1_1(do_float_cvtw_d, fp32, fp64);
6906
            tcg_temp_free(fp64);
6907
            gen_store_fpr32(fp32, fd);
6908
            tcg_temp_free(fp32);
6909
        }
6910
        opn = "cvt.w.d";
6911
        break;
6912
    case FOP(37, 17):
6913
        check_cp1_64bitmode(ctx);
6914
        {
6915
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6916

    
6917
            gen_load_fpr64(ctx, fp0, fs);
6918
            tcg_gen_helper_1_1(do_float_cvtl_d, fp0, fp0);
6919
            gen_store_fpr64(ctx, fp0, fd);
6920
            tcg_temp_free(fp0);
6921
        }
6922
        opn = "cvt.l.d";
6923
        break;
6924
    case FOP(32, 20):
6925
        {
6926
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6927

    
6928
            gen_load_fpr32(fp0, fs);
6929
            tcg_gen_helper_1_1(do_float_cvts_w, fp0, fp0);
6930
            gen_store_fpr32(fp0, fd);
6931
            tcg_temp_free(fp0);
6932
        }
6933
        opn = "cvt.s.w";
6934
        break;
6935
    case FOP(33, 20):
6936
        check_cp1_registers(ctx, fd);
6937
        {
6938
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6939
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6940

    
6941
            gen_load_fpr32(fp32, fs);
6942
            tcg_gen_helper_1_1(do_float_cvtd_w, fp64, fp32);
6943
            tcg_temp_free(fp32);
6944
            gen_store_fpr64(ctx, fp64, fd);
6945
            tcg_temp_free(fp64);
6946
        }
6947
        opn = "cvt.d.w";
6948
        break;
6949
    case FOP(32, 21):
6950
        check_cp1_64bitmode(ctx);
6951
        {
6952
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6953
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6954

    
6955
            gen_load_fpr64(ctx, fp64, fs);
6956
            tcg_gen_helper_1_1(do_float_cvts_l, fp32, fp64);
6957
            tcg_temp_free(fp64);
6958
            gen_store_fpr32(fp32, fd);
6959
            tcg_temp_free(fp32);
6960
        }
6961
        opn = "cvt.s.l";
6962
        break;
6963
    case FOP(33, 21):
6964
        check_cp1_64bitmode(ctx);
6965
        {
6966
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6967

    
6968
            gen_load_fpr64(ctx, fp0, fs);
6969
            tcg_gen_helper_1_1(do_float_cvtd_l, fp0, fp0);
6970
            gen_store_fpr64(ctx, fp0, fd);
6971
            tcg_temp_free(fp0);
6972
        }
6973
        opn = "cvt.d.l";
6974
        break;
6975
    case FOP(38, 20):
6976
        check_cp1_64bitmode(ctx);
6977
        {
6978
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6979

    
6980
            gen_load_fpr64(ctx, fp0, fs);
6981
            tcg_gen_helper_1_1(do_float_cvtps_pw, fp0, fp0);
6982
            gen_store_fpr64(ctx, fp0, fd);
6983
            tcg_temp_free(fp0);
6984
        }
6985
        opn = "cvt.ps.pw";
6986
        break;
6987
    case FOP(0, 22):
6988
        check_cp1_64bitmode(ctx);
6989
        {
6990
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6991
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6992

    
6993
            gen_load_fpr64(ctx, fp0, fs);
6994
            gen_load_fpr64(ctx, fp1, ft);
6995
            tcg_gen_helper_1_2(do_float_add_ps, fp0, fp0, fp1);
6996
            tcg_temp_free(fp1);
6997
            gen_store_fpr64(ctx, fp0, fd);
6998
            tcg_temp_free(fp0);
6999
        }
7000
        opn = "add.ps";
7001
        break;
7002
    case FOP(1, 22):
7003
        check_cp1_64bitmode(ctx);
7004
        {
7005
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7006
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7007

    
7008
            gen_load_fpr64(ctx, fp0, fs);
7009
            gen_load_fpr64(ctx, fp1, ft);
7010
            tcg_gen_helper_1_2(do_float_sub_ps, fp0, fp0, fp1);
7011
            tcg_temp_free(fp1);
7012
            gen_store_fpr64(ctx, fp0, fd);
7013
            tcg_temp_free(fp0);
7014
        }
7015
        opn = "sub.ps";
7016
        break;
7017
    case FOP(2, 22):
7018
        check_cp1_64bitmode(ctx);
7019
        {
7020
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7021
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7022

    
7023
            gen_load_fpr64(ctx, fp0, fs);
7024
            gen_load_fpr64(ctx, fp1, ft);
7025
            tcg_gen_helper_1_2(do_float_mul_ps, fp0, fp0, fp1);
7026
            tcg_temp_free(fp1);
7027
            gen_store_fpr64(ctx, fp0, fd);
7028
            tcg_temp_free(fp0);
7029
        }
7030
        opn = "mul.ps";
7031
        break;
7032
    case FOP(5, 22):
7033
        check_cp1_64bitmode(ctx);
7034
        {
7035
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7036

    
7037
            gen_load_fpr64(ctx, fp0, fs);
7038
            tcg_gen_helper_1_1(do_float_abs_ps, fp0, fp0);
7039
            gen_store_fpr64(ctx, fp0, fd);
7040
            tcg_temp_free(fp0);
7041
        }
7042
        opn = "abs.ps";
7043
        break;
7044
    case FOP(6, 22):
7045
        check_cp1_64bitmode(ctx);
7046
        {
7047
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7048

    
7049
            gen_load_fpr64(ctx, fp0, fs);
7050
            gen_store_fpr64(ctx, fp0, fd);
7051
            tcg_temp_free(fp0);
7052
        }
7053
        opn = "mov.ps";
7054
        break;
7055
    case FOP(7, 22):
7056
        check_cp1_64bitmode(ctx);
7057
        {
7058
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7059

    
7060
            gen_load_fpr64(ctx, fp0, fs);
7061
            tcg_gen_helper_1_1(do_float_chs_ps, fp0, fp0);
7062
            gen_store_fpr64(ctx, fp0, fd);
7063
            tcg_temp_free(fp0);
7064
        }
7065
        opn = "neg.ps";
7066
        break;
7067
    case FOP(17, 22):
7068
        check_cp1_64bitmode(ctx);
7069
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7070
        opn = "movcf.ps";
7071
        break;
7072
    case FOP(18, 22):
7073
        check_cp1_64bitmode(ctx);
7074
        {
7075
            int l1 = gen_new_label();
7076
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7077
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7078
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7079

    
7080
            gen_load_gpr(t0, ft);
7081
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7082
            tcg_temp_free(t0);
7083
            gen_load_fpr32(fp0, fs);
7084
            gen_load_fpr32h(fph0, fs);
7085
            gen_store_fpr32(fp0, fd);
7086
            gen_store_fpr32h(fph0, fd);
7087
            tcg_temp_free(fp0);
7088
            tcg_temp_free(fph0);
7089
            gen_set_label(l1);
7090
        }
7091
        opn = "movz.ps";
7092
        break;
7093
    case FOP(19, 22):
7094
        check_cp1_64bitmode(ctx);
7095
        {
7096
            int l1 = gen_new_label();
7097
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7098
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7099
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7100

    
7101
            gen_load_gpr(t0, ft);
7102
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
7103
            tcg_temp_free(t0);
7104
            gen_load_fpr32(fp0, fs);
7105
            gen_load_fpr32h(fph0, fs);
7106
            gen_store_fpr32(fp0, fd);
7107
            gen_store_fpr32h(fph0, fd);
7108
            tcg_temp_free(fp0);
7109
            tcg_temp_free(fph0);
7110
            gen_set_label(l1);
7111
        }
7112
        opn = "movn.ps";
7113
        break;
7114
    case FOP(24, 22):
7115
        check_cp1_64bitmode(ctx);
7116
        {
7117
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7118
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7119

    
7120
            gen_load_fpr64(ctx, fp0, ft);
7121
            gen_load_fpr64(ctx, fp1, fs);
7122
            tcg_gen_helper_1_2(do_float_addr_ps, fp0, fp0, fp1);
7123
            tcg_temp_free(fp1);
7124
            gen_store_fpr64(ctx, fp0, fd);
7125
            tcg_temp_free(fp0);
7126
        }
7127
        opn = "addr.ps";
7128
        break;
7129
    case FOP(26, 22):
7130
        check_cp1_64bitmode(ctx);
7131
        {
7132
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7133
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7134

    
7135
            gen_load_fpr64(ctx, fp0, ft);
7136
            gen_load_fpr64(ctx, fp1, fs);
7137
            tcg_gen_helper_1_2(do_float_mulr_ps, fp0, fp0, fp1);
7138
            tcg_temp_free(fp1);
7139
            gen_store_fpr64(ctx, fp0, fd);
7140
            tcg_temp_free(fp0);
7141
        }
7142
        opn = "mulr.ps";
7143
        break;
7144
    case FOP(28, 22):
7145
        check_cp1_64bitmode(ctx);
7146
        {
7147
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7148
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7149

    
7150
            gen_load_fpr64(ctx, fp0, fs);
7151
            gen_load_fpr64(ctx, fp1, fd);
7152
            tcg_gen_helper_1_2(do_float_recip2_ps, fp0, fp0, fp1);
7153
            tcg_temp_free(fp1);
7154
            gen_store_fpr64(ctx, fp0, fd);
7155
            tcg_temp_free(fp0);
7156
        }
7157
        opn = "recip2.ps";
7158
        break;
7159
    case FOP(29, 22):
7160
        check_cp1_64bitmode(ctx);
7161
        {
7162
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7163

    
7164
            gen_load_fpr64(ctx, fp0, fs);
7165
            tcg_gen_helper_1_1(do_float_recip1_ps, fp0, fp0);
7166
            gen_store_fpr64(ctx, fp0, fd);
7167
            tcg_temp_free(fp0);
7168
        }
7169
        opn = "recip1.ps";
7170
        break;
7171
    case FOP(30, 22):
7172
        check_cp1_64bitmode(ctx);
7173
        {
7174
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7175

    
7176
            gen_load_fpr64(ctx, fp0, fs);
7177
            tcg_gen_helper_1_1(do_float_rsqrt1_ps, fp0, fp0);
7178
            gen_store_fpr64(ctx, fp0, fd);
7179
            tcg_temp_free(fp0);
7180
        }
7181
        opn = "rsqrt1.ps";
7182
        break;
7183
    case FOP(31, 22):
7184
        check_cp1_64bitmode(ctx);
7185
        {
7186
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7187
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7188

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

    
7203
            gen_load_fpr32h(fp0, fs);
7204
            tcg_gen_helper_1_1(do_float_cvts_pu, fp0, fp0);
7205
            gen_store_fpr32(fp0, fd);
7206
            tcg_temp_free(fp0);
7207
        }
7208
        opn = "cvt.s.pu";
7209
        break;
7210
    case FOP(36, 22):
7211
        check_cp1_64bitmode(ctx);
7212
        {
7213
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7214

    
7215
            gen_load_fpr64(ctx, fp0, fs);
7216
            tcg_gen_helper_1_1(do_float_cvtpw_ps, fp0, fp0);
7217
            gen_store_fpr64(ctx, fp0, fd);
7218
            tcg_temp_free(fp0);
7219
        }
7220
        opn = "cvt.pw.ps";
7221
        break;
7222
    case FOP(40, 22):
7223
        check_cp1_64bitmode(ctx);
7224
        {
7225
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7226

    
7227
            gen_load_fpr32(fp0, fs);
7228
            tcg_gen_helper_1_1(do_float_cvts_pl, fp0, fp0);
7229
            gen_store_fpr32(fp0, fd);
7230
            tcg_temp_free(fp0);
7231
        }
7232
        opn = "cvt.s.pl";
7233
        break;
7234
    case FOP(44, 22):
7235
        check_cp1_64bitmode(ctx);
7236
        {
7237
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7238
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7239

    
7240
            gen_load_fpr32(fp0, fs);
7241
            gen_load_fpr32(fp1, ft);
7242
            gen_store_fpr32h(fp0, fd);
7243
            gen_store_fpr32(fp1, fd);
7244
            tcg_temp_free(fp0);
7245
            tcg_temp_free(fp1);
7246
        }
7247
        opn = "pll.ps";
7248
        break;
7249
    case FOP(45, 22):
7250
        check_cp1_64bitmode(ctx);
7251
        {
7252
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7253
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7254

    
7255
            gen_load_fpr32(fp0, fs);
7256
            gen_load_fpr32h(fp1, ft);
7257
            gen_store_fpr32(fp1, fd);
7258
            gen_store_fpr32h(fp0, fd);
7259
            tcg_temp_free(fp0);
7260
            tcg_temp_free(fp1);
7261
        }
7262
        opn = "plu.ps";
7263
        break;
7264
    case FOP(46, 22):
7265
        check_cp1_64bitmode(ctx);
7266
        {
7267
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7268
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7269

    
7270
            gen_load_fpr32h(fp0, fs);
7271
            gen_load_fpr32(fp1, ft);
7272
            gen_store_fpr32(fp1, fd);
7273
            gen_store_fpr32h(fp0, fd);
7274
            tcg_temp_free(fp0);
7275
            tcg_temp_free(fp1);
7276
        }
7277
        opn = "pul.ps";
7278
        break;
7279
    case FOP(47, 22):
7280
        check_cp1_64bitmode(ctx);
7281
        {
7282
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7283
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7284

    
7285
            gen_load_fpr32h(fp0, fs);
7286
            gen_load_fpr32h(fp1, ft);
7287
            gen_store_fpr32(fp1, fd);
7288
            gen_store_fpr32h(fp0, fd);
7289
            tcg_temp_free(fp0);
7290
            tcg_temp_free(fp1);
7291
        }
7292
        opn = "puu.ps";
7293
        break;
7294
    case FOP(48, 22):
7295
    case FOP(49, 22):
7296
    case FOP(50, 22):
7297
    case FOP(51, 22):
7298
    case FOP(52, 22):
7299
    case FOP(53, 22):
7300
    case FOP(54, 22):
7301
    case FOP(55, 22):
7302
    case FOP(56, 22):
7303
    case FOP(57, 22):
7304
    case FOP(58, 22):
7305
    case FOP(59, 22):
7306
    case FOP(60, 22):
7307
    case FOP(61, 22):
7308
    case FOP(62, 22):
7309
    case FOP(63, 22):
7310
        check_cp1_64bitmode(ctx);
7311
        {
7312
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7313
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7314

    
7315
            gen_load_fpr64(ctx, fp0, fs);
7316
            gen_load_fpr64(ctx, fp1, ft);
7317
            if (ctx->opcode & (1 << 6)) {
7318
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7319
                opn = condnames_abs[func-48];
7320
            } else {
7321
                gen_cmp_ps(func-48, fp0, fp1, cc);
7322
                opn = condnames[func-48];
7323
            }
7324
            tcg_temp_free(fp0);
7325
            tcg_temp_free(fp1);
7326
        }
7327
        break;
7328
    default:
7329
        MIPS_INVAL(opn);
7330
        generate_exception (ctx, EXCP_RI);
7331
        return;
7332
    }
7333
    switch (optype) {
7334
    case BINOP:
7335
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7336
        break;
7337
    case CMPOP:
7338
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7339
        break;
7340
    default:
7341
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7342
        break;
7343
    }
7344
}
7345

    
7346
/* Coprocessor 3 (FPU) */
7347
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7348
                           int fd, int fs, int base, int index)
7349
{
7350
    const char *opn = "extended float load/store";
7351
    int store = 0;
7352
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7353
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7354

    
7355
    if (base == 0) {
7356
        gen_load_gpr(t0, index);
7357
    } else if (index == 0) {
7358
        gen_load_gpr(t0, base);
7359
    } else {
7360
        gen_load_gpr(t0, base);
7361
        gen_load_gpr(t1, index);
7362
        gen_op_addr_add(ctx, t0, t1);
7363
    }
7364
    /* Don't do NOP if destination is zero: we must perform the actual
7365
       memory access. */
7366
    switch (opc) {
7367
    case OPC_LWXC1:
7368
        check_cop1x(ctx);
7369
        {
7370
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7371

    
7372
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
7373
            gen_store_fpr32(fp0, fd);
7374
            tcg_temp_free(fp0);
7375
        }
7376
        opn = "lwxc1";
7377
        break;
7378
    case OPC_LDXC1:
7379
        check_cop1x(ctx);
7380
        check_cp1_registers(ctx, fd);
7381
        {
7382
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7383

    
7384
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7385
            gen_store_fpr64(ctx, fp0, fd);
7386
            tcg_temp_free(fp0);
7387
        }
7388
        opn = "ldxc1";
7389
        break;
7390
    case OPC_LUXC1:
7391
        check_cp1_64bitmode(ctx);
7392
        tcg_gen_andi_tl(t0, t0, ~0x7);
7393
        {
7394
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7395

    
7396
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7397
            gen_store_fpr64(ctx, fp0, fd);
7398
            tcg_temp_free(fp0);
7399
        }
7400
        opn = "luxc1";
7401
        break;
7402
    case OPC_SWXC1:
7403
        check_cop1x(ctx);
7404
        {
7405
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7406

    
7407
            gen_load_fpr32(fp0, fs);
7408
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
7409
            tcg_temp_free(fp0);
7410
        }
7411
        opn = "swxc1";
7412
        store = 1;
7413
        break;
7414
    case OPC_SDXC1:
7415
        check_cop1x(ctx);
7416
        check_cp1_registers(ctx, fs);
7417
        {
7418
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7419

    
7420
            gen_load_fpr64(ctx, fp0, fs);
7421
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7422
            tcg_temp_free(fp0);
7423
        }
7424
        opn = "sdxc1";
7425
        store = 1;
7426
        break;
7427
    case OPC_SUXC1:
7428
        check_cp1_64bitmode(ctx);
7429
        tcg_gen_andi_tl(t0, t0, ~0x7);
7430
        {
7431
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7432

    
7433
            gen_load_fpr64(ctx, fp0, fs);
7434
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7435
            tcg_temp_free(fp0);
7436
        }
7437
        opn = "suxc1";
7438
        store = 1;
7439
        break;
7440
    default:
7441
        MIPS_INVAL(opn);
7442
        generate_exception(ctx, EXCP_RI);
7443
        tcg_temp_free(t0);
7444
        tcg_temp_free(t1);
7445
        return;
7446
    }
7447
    tcg_temp_free(t0);
7448
    tcg_temp_free(t1);
7449
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7450
               regnames[index], regnames[base]);
7451
}
7452

    
7453
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7454
                            int fd, int fr, int fs, int ft)
7455
{
7456
    const char *opn = "flt3_arith";
7457

    
7458
    switch (opc) {
7459
    case OPC_ALNV_PS:
7460
        check_cp1_64bitmode(ctx);
7461
        {
7462
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7463
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7464
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7465
            TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
7466
            TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
7467
            int l1 = gen_new_label();
7468
            int l2 = gen_new_label();
7469

    
7470
            gen_load_gpr(t0, fr);
7471
            tcg_gen_andi_tl(t0, t0, 0x7);
7472
            gen_load_fpr32(fp0, fs);
7473
            gen_load_fpr32h(fph0, fs);
7474
            gen_load_fpr32(fp1, ft);
7475
            gen_load_fpr32h(fph1, ft);
7476

    
7477
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7478
            gen_store_fpr32(fp0, fd);
7479
            gen_store_fpr32h(fph0, fd);
7480
            tcg_gen_br(l2);
7481
            gen_set_label(l1);
7482
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7483
            tcg_temp_free(t0);
7484
#ifdef TARGET_WORDS_BIGENDIAN
7485
            gen_store_fpr32(fph1, fd);
7486
            gen_store_fpr32h(fp0, fd);
7487
#else
7488
            gen_store_fpr32(fph0, fd);
7489
            gen_store_fpr32h(fp1, fd);
7490
#endif
7491
            gen_set_label(l2);
7492
            tcg_temp_free(fp0);
7493
            tcg_temp_free(fph0);
7494
            tcg_temp_free(fp1);
7495
            tcg_temp_free(fph1);
7496
        }
7497
        opn = "alnv.ps";
7498
        break;
7499
    case OPC_MADD_S:
7500
        check_cop1x(ctx);
7501
        {
7502
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7503
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7504
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7505

    
7506
            gen_load_fpr32(fp0, fs);
7507
            gen_load_fpr32(fp1, ft);
7508
            gen_load_fpr32(fp2, fr);
7509
            tcg_gen_helper_1_3(do_float_muladd_s, fp2, fp0, fp1, fp2);
7510
            tcg_temp_free(fp0);
7511
            tcg_temp_free(fp1);
7512
            gen_store_fpr32(fp2, fd);
7513
            tcg_temp_free(fp2);
7514
        }
7515
        opn = "madd.s";
7516
        break;
7517
    case OPC_MADD_D:
7518
        check_cop1x(ctx);
7519
        check_cp1_registers(ctx, fd | fs | ft | fr);
7520
        {
7521
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7522
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7523
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7524

    
7525
            gen_load_fpr64(ctx, fp0, fs);
7526
            gen_load_fpr64(ctx, fp1, ft);
7527
            gen_load_fpr64(ctx, fp2, fr);
7528
            tcg_gen_helper_1_3(do_float_muladd_d, fp2, fp0, fp1, fp2);
7529
            tcg_temp_free(fp0);
7530
            tcg_temp_free(fp1);
7531
            gen_store_fpr64(ctx, fp2, fd);
7532
            tcg_temp_free(fp2);
7533
        }
7534
        opn = "madd.d";
7535
        break;
7536
    case OPC_MADD_PS:
7537
        check_cp1_64bitmode(ctx);
7538
        {
7539
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7540
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7541
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7542

    
7543
            gen_load_fpr64(ctx, fp0, fs);
7544
            gen_load_fpr64(ctx, fp1, ft);
7545
            gen_load_fpr64(ctx, fp2, fr);
7546
            tcg_gen_helper_1_3(do_float_muladd_ps, fp2, fp0, fp1, fp2);
7547
            tcg_temp_free(fp0);
7548
            tcg_temp_free(fp1);
7549
            gen_store_fpr64(ctx, fp2, fd);
7550
            tcg_temp_free(fp2);
7551
        }
7552
        opn = "madd.ps";
7553
        break;
7554
    case OPC_MSUB_S:
7555
        check_cop1x(ctx);
7556
        {
7557
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7558
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7559
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7560

    
7561
            gen_load_fpr32(fp0, fs);
7562
            gen_load_fpr32(fp1, ft);
7563
            gen_load_fpr32(fp2, fr);
7564
            tcg_gen_helper_1_3(do_float_mulsub_s, fp2, fp0, fp1, fp2);
7565
            tcg_temp_free(fp0);
7566
            tcg_temp_free(fp1);
7567
            gen_store_fpr32(fp2, fd);
7568
            tcg_temp_free(fp2);
7569
        }
7570
        opn = "msub.s";
7571
        break;
7572
    case OPC_MSUB_D:
7573
        check_cop1x(ctx);
7574
        check_cp1_registers(ctx, fd | fs | ft | fr);
7575
        {
7576
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7577
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7578
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7579

    
7580
            gen_load_fpr64(ctx, fp0, fs);
7581
            gen_load_fpr64(ctx, fp1, ft);
7582
            gen_load_fpr64(ctx, fp2, fr);
7583
            tcg_gen_helper_1_3(do_float_mulsub_d, fp2, fp0, fp1, fp2);
7584
            tcg_temp_free(fp0);
7585
            tcg_temp_free(fp1);
7586
            gen_store_fpr64(ctx, fp2, fd);
7587
            tcg_temp_free(fp2);
7588
        }
7589
        opn = "msub.d";
7590
        break;
7591
    case OPC_MSUB_PS:
7592
        check_cp1_64bitmode(ctx);
7593
        {
7594
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7595
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7596
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7597

    
7598
            gen_load_fpr64(ctx, fp0, fs);
7599
            gen_load_fpr64(ctx, fp1, ft);
7600
            gen_load_fpr64(ctx, fp2, fr);
7601
            tcg_gen_helper_1_3(do_float_mulsub_ps, fp2, fp0, fp1, fp2);
7602
            tcg_temp_free(fp0);
7603
            tcg_temp_free(fp1);
7604
            gen_store_fpr64(ctx, fp2, fd);
7605
            tcg_temp_free(fp2);
7606
        }
7607
        opn = "msub.ps";
7608
        break;
7609
    case OPC_NMADD_S:
7610
        check_cop1x(ctx);
7611
        {
7612
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7613
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7614
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7615

    
7616
            gen_load_fpr32(fp0, fs);
7617
            gen_load_fpr32(fp1, ft);
7618
            gen_load_fpr32(fp2, fr);
7619
            tcg_gen_helper_1_3(do_float_nmuladd_s, fp2, fp0, fp1, fp2);
7620
            tcg_temp_free(fp0);
7621
            tcg_temp_free(fp1);
7622
            gen_store_fpr32(fp2, fd);
7623
            tcg_temp_free(fp2);
7624
        }
7625
        opn = "nmadd.s";
7626
        break;
7627
    case OPC_NMADD_D:
7628
        check_cop1x(ctx);
7629
        check_cp1_registers(ctx, fd | fs | ft | fr);
7630
        {
7631
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7632
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7633
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7634

    
7635
            gen_load_fpr64(ctx, fp0, fs);
7636
            gen_load_fpr64(ctx, fp1, ft);
7637
            gen_load_fpr64(ctx, fp2, fr);
7638
            tcg_gen_helper_1_3(do_float_nmuladd_d, fp2, fp0, fp1, fp2);
7639
            tcg_temp_free(fp0);
7640
            tcg_temp_free(fp1);
7641
            gen_store_fpr64(ctx, fp2, fd);
7642
            tcg_temp_free(fp2);
7643
        }
7644
        opn = "nmadd.d";
7645
        break;
7646
    case OPC_NMADD_PS:
7647
        check_cp1_64bitmode(ctx);
7648
        {
7649
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7650
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7651
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7652

    
7653
            gen_load_fpr64(ctx, fp0, fs);
7654
            gen_load_fpr64(ctx, fp1, ft);
7655
            gen_load_fpr64(ctx, fp2, fr);
7656
            tcg_gen_helper_1_3(do_float_nmuladd_ps, fp2, fp0, fp1, fp2);
7657
            tcg_temp_free(fp0);
7658
            tcg_temp_free(fp1);
7659
            gen_store_fpr64(ctx, fp2, fd);
7660
            tcg_temp_free(fp2);
7661
        }
7662
        opn = "nmadd.ps";
7663
        break;
7664
    case OPC_NMSUB_S:
7665
        check_cop1x(ctx);
7666
        {
7667
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7668
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7669
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7670

    
7671
            gen_load_fpr32(fp0, fs);
7672
            gen_load_fpr32(fp1, ft);
7673
            gen_load_fpr32(fp2, fr);
7674
            tcg_gen_helper_1_3(do_float_nmulsub_s, fp2, fp0, fp1, fp2);
7675
            tcg_temp_free(fp0);
7676
            tcg_temp_free(fp1);
7677
            gen_store_fpr32(fp2, fd);
7678
            tcg_temp_free(fp2);
7679
        }
7680
        opn = "nmsub.s";
7681
        break;
7682
    case OPC_NMSUB_D:
7683
        check_cop1x(ctx);
7684
        check_cp1_registers(ctx, fd | fs | ft | fr);
7685
        {
7686
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7687
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7688
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7689

    
7690
            gen_load_fpr64(ctx, fp0, fs);
7691
            gen_load_fpr64(ctx, fp1, ft);
7692
            gen_load_fpr64(ctx, fp2, fr);
7693
            tcg_gen_helper_1_3(do_float_nmulsub_d, fp2, fp0, fp1, fp2);
7694
            tcg_temp_free(fp0);
7695
            tcg_temp_free(fp1);
7696
            gen_store_fpr64(ctx, fp2, fd);
7697
            tcg_temp_free(fp2);
7698
        }
7699
        opn = "nmsub.d";
7700
        break;
7701
    case OPC_NMSUB_PS:
7702
        check_cp1_64bitmode(ctx);
7703
        {
7704
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7705
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7706
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7707

    
7708
            gen_load_fpr64(ctx, fp0, fs);
7709
            gen_load_fpr64(ctx, fp1, ft);
7710
            gen_load_fpr64(ctx, fp2, fr);
7711
            tcg_gen_helper_1_3(do_float_nmulsub_ps, fp2, fp0, fp1, fp2);
7712
            tcg_temp_free(fp0);
7713
            tcg_temp_free(fp1);
7714
            gen_store_fpr64(ctx, fp2, fd);
7715
            tcg_temp_free(fp2);
7716
        }
7717
        opn = "nmsub.ps";
7718
        break;
7719
    default:
7720
        MIPS_INVAL(opn);
7721
        generate_exception (ctx, EXCP_RI);
7722
        return;
7723
    }
7724
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7725
               fregnames[fs], fregnames[ft]);
7726
}
7727

    
7728
/* ISA extensions (ASEs) */
7729
/* MIPS16 extension to MIPS32 */
7730
/* SmartMIPS extension to MIPS32 */
7731

    
7732
#if defined(TARGET_MIPS64)
7733

    
7734
/* MDMX extension to MIPS64 */
7735

    
7736
#endif
7737

    
7738
static void decode_opc (CPUState *env, DisasContext *ctx)
7739
{
7740
    int32_t offset;
7741
    int rs, rt, rd, sa;
7742
    uint32_t op, op1, op2;
7743
    int16_t imm;
7744

    
7745
    /* make sure instructions are on a word boundary */
7746
    if (ctx->pc & 0x3) {
7747
        env->CP0_BadVAddr = ctx->pc;
7748
        generate_exception(ctx, EXCP_AdEL);
7749
        return;
7750
    }
7751

    
7752
    /* Handle blikely not taken case */
7753
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7754
        int l1 = gen_new_label();
7755

    
7756
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7757
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7758
        {
7759
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
7760

    
7761
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7762
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7763
            tcg_temp_free(r_tmp);
7764
        }
7765
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7766
        gen_set_label(l1);
7767
    }
7768
    op = MASK_OP_MAJOR(ctx->opcode);
7769
    rs = (ctx->opcode >> 21) & 0x1f;
7770
    rt = (ctx->opcode >> 16) & 0x1f;
7771
    rd = (ctx->opcode >> 11) & 0x1f;
7772
    sa = (ctx->opcode >> 6) & 0x1f;
7773
    imm = (int16_t)ctx->opcode;
7774
    switch (op) {
7775
    case OPC_SPECIAL:
7776
        op1 = MASK_SPECIAL(ctx->opcode);
7777
        switch (op1) {
7778
        case OPC_SLL:          /* Arithmetic with immediate */
7779
        case OPC_SRL ... OPC_SRA:
7780
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7781
            break;
7782
        case OPC_MOVZ ... OPC_MOVN:
7783
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7784
        case OPC_SLLV:         /* Arithmetic */
7785
        case OPC_SRLV ... OPC_SRAV:
7786
        case OPC_ADD ... OPC_NOR:
7787
        case OPC_SLT ... OPC_SLTU:
7788
            gen_arith(env, ctx, op1, rd, rs, rt);
7789
            break;
7790
        case OPC_MULT ... OPC_DIVU:
7791
            if (sa) {
7792
                check_insn(env, ctx, INSN_VR54XX);
7793
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7794
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7795
            } else
7796
                gen_muldiv(ctx, op1, rs, rt);
7797
            break;
7798
        case OPC_JR ... OPC_JALR:
7799
            gen_compute_branch(ctx, op1, rs, rd, sa);
7800
            return;
7801
        case OPC_TGE ... OPC_TEQ: /* Traps */
7802
        case OPC_TNE:
7803
            gen_trap(ctx, op1, rs, rt, -1);
7804
            break;
7805
        case OPC_MFHI:          /* Move from HI/LO */
7806
        case OPC_MFLO:
7807
            gen_HILO(ctx, op1, rd);
7808
            break;
7809
        case OPC_MTHI:
7810
        case OPC_MTLO:          /* Move to HI/LO */
7811
            gen_HILO(ctx, op1, rs);
7812
            break;
7813
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7814
#ifdef MIPS_STRICT_STANDARD
7815
            MIPS_INVAL("PMON / selsl");
7816
            generate_exception(ctx, EXCP_RI);
7817
#else
7818
            tcg_gen_helper_0_i(do_pmon, sa);
7819
#endif
7820
            break;
7821
        case OPC_SYSCALL:
7822
            generate_exception(ctx, EXCP_SYSCALL);
7823
            break;
7824
        case OPC_BREAK:
7825
            generate_exception(ctx, EXCP_BREAK);
7826
            break;
7827
        case OPC_SPIM:
7828
#ifdef MIPS_STRICT_STANDARD
7829
            MIPS_INVAL("SPIM");
7830
            generate_exception(ctx, EXCP_RI);
7831
#else
7832
           /* Implemented as RI exception for now. */
7833
            MIPS_INVAL("spim (unofficial)");
7834
            generate_exception(ctx, EXCP_RI);
7835
#endif
7836
            break;
7837
        case OPC_SYNC:
7838
            /* Treat as NOP. */
7839
            break;
7840

    
7841
        case OPC_MOVCI:
7842
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7843
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7844
                save_cpu_state(ctx, 1);
7845
                check_cp1_enabled(ctx);
7846
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7847
                          (ctx->opcode >> 16) & 1);
7848
            } else {
7849
                generate_exception_err(ctx, EXCP_CpU, 1);
7850
            }
7851
            break;
7852

    
7853
#if defined(TARGET_MIPS64)
7854
       /* MIPS64 specific opcodes */
7855
        case OPC_DSLL:
7856
        case OPC_DSRL ... OPC_DSRA:
7857
        case OPC_DSLL32:
7858
        case OPC_DSRL32 ... OPC_DSRA32:
7859
            check_insn(env, ctx, ISA_MIPS3);
7860
            check_mips_64(ctx);
7861
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7862
            break;
7863
        case OPC_DSLLV:
7864
        case OPC_DSRLV ... OPC_DSRAV:
7865
        case OPC_DADD ... OPC_DSUBU:
7866
            check_insn(env, ctx, ISA_MIPS3);
7867
            check_mips_64(ctx);
7868
            gen_arith(env, ctx, op1, rd, rs, rt);
7869
            break;
7870
        case OPC_DMULT ... OPC_DDIVU:
7871
            check_insn(env, ctx, ISA_MIPS3);
7872
            check_mips_64(ctx);
7873
            gen_muldiv(ctx, op1, rs, rt);
7874
            break;
7875
#endif
7876
        default:            /* Invalid */
7877
            MIPS_INVAL("special");
7878
            generate_exception(ctx, EXCP_RI);
7879
            break;
7880
        }
7881
        break;
7882
    case OPC_SPECIAL2:
7883
        op1 = MASK_SPECIAL2(ctx->opcode);
7884
        switch (op1) {
7885
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7886
        case OPC_MSUB ... OPC_MSUBU:
7887
            check_insn(env, ctx, ISA_MIPS32);
7888
            gen_muldiv(ctx, op1, rs, rt);
7889
            break;
7890
        case OPC_MUL:
7891
            gen_arith(env, ctx, op1, rd, rs, rt);
7892
            break;
7893
        case OPC_CLZ ... OPC_CLO:
7894
            check_insn(env, ctx, ISA_MIPS32);
7895
            gen_cl(ctx, op1, rd, rs);
7896
            break;
7897
        case OPC_SDBBP:
7898
            /* XXX: not clear which exception should be raised
7899
             *      when in debug mode...
7900
             */
7901
            check_insn(env, ctx, ISA_MIPS32);
7902
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7903
                generate_exception(ctx, EXCP_DBp);
7904
            } else {
7905
                generate_exception(ctx, EXCP_DBp);
7906
            }
7907
            /* Treat as NOP. */
7908
            break;
7909
#if defined(TARGET_MIPS64)
7910
        case OPC_DCLZ ... OPC_DCLO:
7911
            check_insn(env, ctx, ISA_MIPS64);
7912
            check_mips_64(ctx);
7913
            gen_cl(ctx, op1, rd, rs);
7914
            break;
7915
#endif
7916
        default:            /* Invalid */
7917
            MIPS_INVAL("special2");
7918
            generate_exception(ctx, EXCP_RI);
7919
            break;
7920
        }
7921
        break;
7922
    case OPC_SPECIAL3:
7923
        op1 = MASK_SPECIAL3(ctx->opcode);
7924
        switch (op1) {
7925
        case OPC_EXT:
7926
        case OPC_INS:
7927
            check_insn(env, ctx, ISA_MIPS32R2);
7928
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7929
            break;
7930
        case OPC_BSHFL:
7931
            check_insn(env, ctx, ISA_MIPS32R2);
7932
            op2 = MASK_BSHFL(ctx->opcode);
7933
            {
7934
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7935
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7936

    
7937
                switch (op2) {
7938
                case OPC_WSBH:
7939
                    gen_load_gpr(t1, rt);
7940
                    tcg_gen_helper_1_1(do_wsbh, t0, t1);
7941
                    gen_store_gpr(t0, rd);
7942
                    break;
7943
                case OPC_SEB:
7944
                    gen_load_gpr(t1, rt);
7945
                    tcg_gen_ext8s_tl(t0, t1);
7946
                    gen_store_gpr(t0, rd);
7947
                    break;
7948
                case OPC_SEH:
7949
                    gen_load_gpr(t1, rt);
7950
                    tcg_gen_ext16s_tl(t0, t1);
7951
                    gen_store_gpr(t0, rd);
7952
                    break;
7953
                default:            /* Invalid */
7954
                    MIPS_INVAL("bshfl");
7955
                    generate_exception(ctx, EXCP_RI);
7956
                    break;
7957
                }
7958
                tcg_temp_free(t0);
7959
                tcg_temp_free(t1);
7960
            }
7961
            break;
7962
        case OPC_RDHWR:
7963
            check_insn(env, ctx, ISA_MIPS32R2);
7964
            {
7965
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7966

    
7967
                switch (rd) {
7968
                case 0:
7969
                    save_cpu_state(ctx, 1);
7970
                    tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
7971
                    break;
7972
                case 1:
7973
                    save_cpu_state(ctx, 1);
7974
                    tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
7975
                    break;
7976
                case 2:
7977
                    save_cpu_state(ctx, 1);
7978
                    tcg_gen_helper_1_0(do_rdhwr_cc, t0);
7979
                    break;
7980
                case 3:
7981
                    save_cpu_state(ctx, 1);
7982
                    tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
7983
                    break;
7984
                case 29:
7985
                    if (env->user_mode_only) {
7986
                        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7987
                        break;
7988
                    } else {
7989
                        /* XXX: Some CPUs implement this in hardware.
7990
                           Not supported yet. */
7991
                    }
7992
                default:            /* Invalid */
7993
                    MIPS_INVAL("rdhwr");
7994
                    generate_exception(ctx, EXCP_RI);
7995
                    break;
7996
                }
7997
                gen_store_gpr(t0, rt);
7998
                tcg_temp_free(t0);
7999
            }
8000
            break;
8001
        case OPC_FORK:
8002
            check_insn(env, ctx, ASE_MT);
8003
            {
8004
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8005
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8006

    
8007
                gen_load_gpr(t0, rt);
8008
                gen_load_gpr(t1, rs);
8009
                tcg_gen_helper_0_2(do_fork, t0, t1);
8010
                tcg_temp_free(t0);
8011
                tcg_temp_free(t1);
8012
            }
8013
            break;
8014
        case OPC_YIELD:
8015
            check_insn(env, ctx, ASE_MT);
8016
            {
8017
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8018

    
8019
                gen_load_gpr(t0, rs);
8020
                tcg_gen_helper_1_1(do_yield, t0, t0);
8021
                gen_store_gpr(t0, rd);
8022
                tcg_temp_free(t0);
8023
            }
8024
            break;
8025
#if defined(TARGET_MIPS64)
8026
        case OPC_DEXTM ... OPC_DEXT:
8027
        case OPC_DINSM ... OPC_DINS:
8028
            check_insn(env, ctx, ISA_MIPS64R2);
8029
            check_mips_64(ctx);
8030
            gen_bitops(ctx, op1, rt, rs, sa, rd);
8031
            break;
8032
        case OPC_DBSHFL:
8033
            check_insn(env, ctx, ISA_MIPS64R2);
8034
            check_mips_64(ctx);
8035
            op2 = MASK_DBSHFL(ctx->opcode);
8036
            {
8037
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8038
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8039

    
8040
                switch (op2) {
8041
                case OPC_DSBH:
8042
                    gen_load_gpr(t1, rt);
8043
                    tcg_gen_helper_1_1(do_dsbh, t0, t1);
8044
                    break;
8045
                case OPC_DSHD:
8046
                    gen_load_gpr(t1, rt);
8047
                    tcg_gen_helper_1_1(do_dshd, t0, t1);
8048
                    break;
8049
                default:            /* Invalid */
8050
                    MIPS_INVAL("dbshfl");
8051
                    generate_exception(ctx, EXCP_RI);
8052
                    break;
8053
                }
8054
                gen_store_gpr(t0, rd);
8055
                tcg_temp_free(t0);
8056
                tcg_temp_free(t1);
8057
            }
8058
            break;
8059
#endif
8060
        default:            /* Invalid */
8061
            MIPS_INVAL("special3");
8062
            generate_exception(ctx, EXCP_RI);
8063
            break;
8064
        }
8065
        break;
8066
    case OPC_REGIMM:
8067
        op1 = MASK_REGIMM(ctx->opcode);
8068
        switch (op1) {
8069
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
8070
        case OPC_BLTZAL ... OPC_BGEZALL:
8071
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
8072
            return;
8073
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
8074
        case OPC_TNEI:
8075
            gen_trap(ctx, op1, rs, -1, imm);
8076
            break;
8077
        case OPC_SYNCI:
8078
            check_insn(env, ctx, ISA_MIPS32R2);
8079
            /* Treat as NOP. */
8080
            break;
8081
        default:            /* Invalid */
8082
            MIPS_INVAL("regimm");
8083
            generate_exception(ctx, EXCP_RI);
8084
            break;
8085
        }
8086
        break;
8087
    case OPC_CP0:
8088
        check_cp0_enabled(ctx);
8089
        op1 = MASK_CP0(ctx->opcode);
8090
        switch (op1) {
8091
        case OPC_MFC0:
8092
        case OPC_MTC0:
8093
        case OPC_MFTR:
8094
        case OPC_MTTR:
8095
#if defined(TARGET_MIPS64)
8096
        case OPC_DMFC0:
8097
        case OPC_DMTC0:
8098
#endif
8099
#ifndef CONFIG_USER_ONLY
8100
            if (!env->user_mode_only)
8101
                gen_cp0(env, ctx, op1, rt, rd);
8102
#endif /* !CONFIG_USER_ONLY */
8103
            break;
8104
        case OPC_C0_FIRST ... OPC_C0_LAST:
8105
#ifndef CONFIG_USER_ONLY
8106
            if (!env->user_mode_only)
8107
                gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
8108
#endif /* !CONFIG_USER_ONLY */
8109
            break;
8110
        case OPC_MFMC0:
8111
#ifndef CONFIG_USER_ONLY
8112
            if (!env->user_mode_only) {
8113
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8114

    
8115
                op2 = MASK_MFMC0(ctx->opcode);
8116
                switch (op2) {
8117
                case OPC_DMT:
8118
                    check_insn(env, ctx, ASE_MT);
8119
                    tcg_gen_helper_1_1(do_dmt, t0, t0);
8120
                    break;
8121
                case OPC_EMT:
8122
                    check_insn(env, ctx, ASE_MT);
8123
                    tcg_gen_helper_1_1(do_emt, t0, t0);
8124
                     break;
8125
                case OPC_DVPE:
8126
                    check_insn(env, ctx, ASE_MT);
8127
                    tcg_gen_helper_1_1(do_dvpe, t0, t0);
8128
                    break;
8129
                case OPC_EVPE:
8130
                    check_insn(env, ctx, ASE_MT);
8131
                    tcg_gen_helper_1_1(do_evpe, t0, t0);
8132
                    break;
8133
                case OPC_DI:
8134
                    check_insn(env, ctx, ISA_MIPS32R2);
8135
                    save_cpu_state(ctx, 1);
8136
                    tcg_gen_helper_1_0(do_di, t0);
8137
                    /* Stop translation as we may have switched the execution mode */
8138
                    ctx->bstate = BS_STOP;
8139
                    break;
8140
                case OPC_EI:
8141
                    check_insn(env, ctx, ISA_MIPS32R2);
8142
                    save_cpu_state(ctx, 1);
8143
                    tcg_gen_helper_1_0(do_ei, t0);
8144
                    /* Stop translation as we may have switched the execution mode */
8145
                    ctx->bstate = BS_STOP;
8146
                    break;
8147
                default:            /* Invalid */
8148
                    MIPS_INVAL("mfmc0");
8149
                    generate_exception(ctx, EXCP_RI);
8150
                    break;
8151
                }
8152
                gen_store_gpr(t0, rt);
8153
                tcg_temp_free(t0);
8154
            }
8155
#endif /* !CONFIG_USER_ONLY */
8156
            break;
8157
        case OPC_RDPGPR:
8158
            check_insn(env, ctx, ISA_MIPS32R2);
8159
            gen_load_srsgpr(rt, rd);
8160
            break;
8161
        case OPC_WRPGPR:
8162
            check_insn(env, ctx, ISA_MIPS32R2);
8163
            gen_store_srsgpr(rt, rd);
8164
            break;
8165
        default:
8166
            MIPS_INVAL("cp0");
8167
            generate_exception(ctx, EXCP_RI);
8168
            break;
8169
        }
8170
        break;
8171
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
8172
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8173
         break;
8174
    case OPC_J ... OPC_JAL: /* Jump */
8175
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8176
         gen_compute_branch(ctx, op, rs, rt, offset);
8177
         return;
8178
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8179
    case OPC_BEQL ... OPC_BGTZL:
8180
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8181
         return;
8182
    case OPC_LB ... OPC_LWR: /* Load and stores */
8183
    case OPC_SB ... OPC_SW:
8184
    case OPC_SWR:
8185
    case OPC_LL:
8186
    case OPC_SC:
8187
         gen_ldst(ctx, op, rt, rs, imm);
8188
         break;
8189
    case OPC_CACHE:
8190
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8191
        /* Treat as NOP. */
8192
        break;
8193
    case OPC_PREF:
8194
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8195
        /* Treat as NOP. */
8196
        break;
8197

    
8198
    /* Floating point (COP1). */
8199
    case OPC_LWC1:
8200
    case OPC_LDC1:
8201
    case OPC_SWC1:
8202
    case OPC_SDC1:
8203
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8204
            save_cpu_state(ctx, 1);
8205
            check_cp1_enabled(ctx);
8206
            gen_flt_ldst(ctx, op, rt, rs, imm);
8207
        } else {
8208
            generate_exception_err(ctx, EXCP_CpU, 1);
8209
        }
8210
        break;
8211

    
8212
    case OPC_CP1:
8213
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8214
            save_cpu_state(ctx, 1);
8215
            check_cp1_enabled(ctx);
8216
            op1 = MASK_CP1(ctx->opcode);
8217
            switch (op1) {
8218
            case OPC_MFHC1:
8219
            case OPC_MTHC1:
8220
                check_insn(env, ctx, ISA_MIPS32R2);
8221
            case OPC_MFC1:
8222
            case OPC_CFC1:
8223
            case OPC_MTC1:
8224
            case OPC_CTC1:
8225
                gen_cp1(ctx, op1, rt, rd);
8226
                break;
8227
#if defined(TARGET_MIPS64)
8228
            case OPC_DMFC1:
8229
            case OPC_DMTC1:
8230
                check_insn(env, ctx, ISA_MIPS3);
8231
                gen_cp1(ctx, op1, rt, rd);
8232
                break;
8233
#endif
8234
            case OPC_BC1ANY2:
8235
            case OPC_BC1ANY4:
8236
                check_cop1x(ctx);
8237
                check_insn(env, ctx, ASE_MIPS3D);
8238
                /* fall through */
8239
            case OPC_BC1:
8240
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8241
                                    (rt >> 2) & 0x7, imm << 2);
8242
                return;
8243
            case OPC_S_FMT:
8244
            case OPC_D_FMT:
8245
            case OPC_W_FMT:
8246
            case OPC_L_FMT:
8247
            case OPC_PS_FMT:
8248
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8249
                           (imm >> 8) & 0x7);
8250
                break;
8251
            default:
8252
                MIPS_INVAL("cp1");
8253
                generate_exception (ctx, EXCP_RI);
8254
                break;
8255
            }
8256
        } else {
8257
            generate_exception_err(ctx, EXCP_CpU, 1);
8258
        }
8259
        break;
8260

    
8261
    /* COP2.  */
8262
    case OPC_LWC2:
8263
    case OPC_LDC2:
8264
    case OPC_SWC2:
8265
    case OPC_SDC2:
8266
    case OPC_CP2:
8267
        /* COP2: Not implemented. */
8268
        generate_exception_err(ctx, EXCP_CpU, 2);
8269
        break;
8270

    
8271
    case OPC_CP3:
8272
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8273
            save_cpu_state(ctx, 1);
8274
            check_cp1_enabled(ctx);
8275
            op1 = MASK_CP3(ctx->opcode);
8276
            switch (op1) {
8277
            case OPC_LWXC1:
8278
            case OPC_LDXC1:
8279
            case OPC_LUXC1:
8280
            case OPC_SWXC1:
8281
            case OPC_SDXC1:
8282
            case OPC_SUXC1:
8283
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8284
                break;
8285
            case OPC_PREFX:
8286
                /* Treat as NOP. */
8287
                break;
8288
            case OPC_ALNV_PS:
8289
            case OPC_MADD_S:
8290
            case OPC_MADD_D:
8291
            case OPC_MADD_PS:
8292
            case OPC_MSUB_S:
8293
            case OPC_MSUB_D:
8294
            case OPC_MSUB_PS:
8295
            case OPC_NMADD_S:
8296
            case OPC_NMADD_D:
8297
            case OPC_NMADD_PS:
8298
            case OPC_NMSUB_S:
8299
            case OPC_NMSUB_D:
8300
            case OPC_NMSUB_PS:
8301
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8302
                break;
8303
            default:
8304
                MIPS_INVAL("cp3");
8305
                generate_exception (ctx, EXCP_RI);
8306
                break;
8307
            }
8308
        } else {
8309
            generate_exception_err(ctx, EXCP_CpU, 1);
8310
        }
8311
        break;
8312

    
8313
#if defined(TARGET_MIPS64)
8314
    /* MIPS64 opcodes */
8315
    case OPC_LWU:
8316
    case OPC_LDL ... OPC_LDR:
8317
    case OPC_SDL ... OPC_SDR:
8318
    case OPC_LLD:
8319
    case OPC_LD:
8320
    case OPC_SCD:
8321
    case OPC_SD:
8322
        check_insn(env, ctx, ISA_MIPS3);
8323
        check_mips_64(ctx);
8324
        gen_ldst(ctx, op, rt, rs, imm);
8325
        break;
8326
    case OPC_DADDI ... OPC_DADDIU:
8327
        check_insn(env, ctx, ISA_MIPS3);
8328
        check_mips_64(ctx);
8329
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8330
        break;
8331
#endif
8332
    case OPC_JALX:
8333
        check_insn(env, ctx, ASE_MIPS16);
8334
        /* MIPS16: Not implemented. */
8335
    case OPC_MDMX:
8336
        check_insn(env, ctx, ASE_MDMX);
8337
        /* MDMX: Not implemented. */
8338
    default:            /* Invalid */
8339
        MIPS_INVAL("major opcode");
8340
        generate_exception(ctx, EXCP_RI);
8341
        break;
8342
    }
8343
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8344
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8345
        /* Branches completion */
8346
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8347
        ctx->bstate = BS_BRANCH;
8348
        save_cpu_state(ctx, 0);
8349
        /* FIXME: Need to clear can_do_io.  */
8350
        switch (hflags) {
8351
        case MIPS_HFLAG_B:
8352
            /* unconditional branch */
8353
            MIPS_DEBUG("unconditional branch");
8354
            gen_goto_tb(ctx, 0, ctx->btarget);
8355
            break;
8356
        case MIPS_HFLAG_BL:
8357
            /* blikely taken case */
8358
            MIPS_DEBUG("blikely branch taken");
8359
            gen_goto_tb(ctx, 0, ctx->btarget);
8360
            break;
8361
        case MIPS_HFLAG_BC:
8362
            /* Conditional branch */
8363
            MIPS_DEBUG("conditional branch");
8364
            {
8365
                int l1 = gen_new_label();
8366

    
8367
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8368
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8369
                gen_set_label(l1);
8370
                gen_goto_tb(ctx, 0, ctx->btarget);
8371
            }
8372
            break;
8373
        case MIPS_HFLAG_BR:
8374
            /* unconditional branch to register */
8375
            MIPS_DEBUG("branch to register");
8376
            tcg_gen_mov_tl(cpu_PC, btarget);
8377
            tcg_gen_exit_tb(0);
8378
            break;
8379
        default:
8380
            MIPS_DEBUG("unknown branch");
8381
            break;
8382
        }
8383
    }
8384
}
8385

    
8386
static inline void
8387
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8388
                                int search_pc)
8389
{
8390
    DisasContext ctx;
8391
    target_ulong pc_start;
8392
    uint16_t *gen_opc_end;
8393
    int j, lj = -1;
8394
    int num_insns;
8395
    int max_insns;
8396

    
8397
    if (search_pc && loglevel)
8398
        fprintf (logfile, "search pc %d\n", search_pc);
8399

    
8400
    pc_start = tb->pc;
8401
    /* Leave some spare opc slots for branch handling. */
8402
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8403
    ctx.pc = pc_start;
8404
    ctx.saved_pc = -1;
8405
    ctx.tb = tb;
8406
    ctx.bstate = BS_NONE;
8407
    /* Restore delay slot state from the tb context.  */
8408
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8409
    restore_cpu_state(env, &ctx);
8410
    if (env->user_mode_only)
8411
        ctx.mem_idx = MIPS_HFLAG_UM;
8412
    else
8413
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8414
    num_insns = 0;
8415
    max_insns = tb->cflags & CF_COUNT_MASK;
8416
    if (max_insns == 0)
8417
        max_insns = CF_COUNT_MASK;
8418
#ifdef DEBUG_DISAS
8419
    if (loglevel & CPU_LOG_TB_CPU) {
8420
        fprintf(logfile, "------------------------------------------------\n");
8421
        /* FIXME: This may print out stale hflags from env... */
8422
        cpu_dump_state(env, logfile, fprintf, 0);
8423
    }
8424
#endif
8425
#ifdef MIPS_DEBUG_DISAS
8426
    if (loglevel & CPU_LOG_TB_IN_ASM)
8427
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
8428
                tb, ctx.mem_idx, ctx.hflags);
8429
#endif
8430
    gen_icount_start();
8431
    while (ctx.bstate == BS_NONE) {
8432
        if (env->nb_breakpoints > 0) {
8433
            for(j = 0; j < env->nb_breakpoints; j++) {
8434
                if (env->breakpoints[j] == ctx.pc) {
8435
                    save_cpu_state(&ctx, 1);
8436
                    ctx.bstate = BS_BRANCH;
8437
                    tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8438
                    /* Include the breakpoint location or the tb won't
8439
                     * be flushed when it must be.  */
8440
                    ctx.pc += 4;
8441
                    goto done_generating;
8442
                }
8443
            }
8444
        }
8445

    
8446
        if (search_pc) {
8447
            j = gen_opc_ptr - gen_opc_buf;
8448
            if (lj < j) {
8449
                lj++;
8450
                while (lj < j)
8451
                    gen_opc_instr_start[lj++] = 0;
8452
            }
8453
            gen_opc_pc[lj] = ctx.pc;
8454
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8455
            gen_opc_instr_start[lj] = 1;
8456
            gen_opc_icount[lj] = num_insns;
8457
        }
8458
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8459
            gen_io_start();
8460
        ctx.opcode = ldl_code(ctx.pc);
8461
        decode_opc(env, &ctx);
8462
        ctx.pc += 4;
8463
        num_insns++;
8464

    
8465
        if (env->singlestep_enabled)
8466
            break;
8467

    
8468
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8469
            break;
8470

    
8471
        if (gen_opc_ptr >= gen_opc_end)
8472
            break;
8473

    
8474
        if (num_insns >= max_insns)
8475
            break;
8476
#if defined (MIPS_SINGLE_STEP)
8477
        break;
8478
#endif
8479
    }
8480
    if (tb->cflags & CF_LAST_IO)
8481
        gen_io_end();
8482
    if (env->singlestep_enabled) {
8483
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8484
        tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8485
    } else {
8486
        switch (ctx.bstate) {
8487
        case BS_STOP:
8488
            tcg_gen_helper_0_0(do_interrupt_restart);
8489
            gen_goto_tb(&ctx, 0, ctx.pc);
8490
            break;
8491
        case BS_NONE:
8492
            save_cpu_state(&ctx, 0);
8493
            gen_goto_tb(&ctx, 0, ctx.pc);
8494
            break;
8495
        case BS_EXCP:
8496
            tcg_gen_helper_0_0(do_interrupt_restart);
8497
            tcg_gen_exit_tb(0);
8498
            break;
8499
        case BS_BRANCH:
8500
        default:
8501
            break;
8502
        }
8503
    }
8504
done_generating:
8505
    gen_icount_end(tb, num_insns);
8506
    *gen_opc_ptr = INDEX_op_end;
8507
    if (search_pc) {
8508
        j = gen_opc_ptr - gen_opc_buf;
8509
        lj++;
8510
        while (lj <= j)
8511
            gen_opc_instr_start[lj++] = 0;
8512
    } else {
8513
        tb->size = ctx.pc - pc_start;
8514
        tb->icount = num_insns;
8515
    }
8516
#ifdef DEBUG_DISAS
8517
#if defined MIPS_DEBUG_DISAS
8518
    if (loglevel & CPU_LOG_TB_IN_ASM)
8519
        fprintf(logfile, "\n");
8520
#endif
8521
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8522
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8523
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8524
        fprintf(logfile, "\n");
8525
    }
8526
    if (loglevel & CPU_LOG_TB_CPU) {
8527
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8528
    }
8529
#endif
8530
}
8531

    
8532
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8533
{
8534
    gen_intermediate_code_internal(env, tb, 0);
8535
}
8536

    
8537
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8538
{
8539
    gen_intermediate_code_internal(env, tb, 1);
8540
}
8541

    
8542
static void fpu_dump_state(CPUState *env, FILE *f,
8543
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8544
                           int flags)
8545
{
8546
    int i;
8547
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8548

    
8549
#define printfpr(fp)                                                        \
8550
    do {                                                                    \
8551
        if (is_fpu64)                                                       \
8552
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8553
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8554
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8555
        else {                                                              \
8556
            fpr_t tmp;                                                      \
8557
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8558
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8559
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8560
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8561
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8562
        }                                                                   \
8563
    } while(0)
8564

    
8565

    
8566
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8567
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8568
                get_float_exception_flags(&env->active_fpu.fp_status));
8569
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8570
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8571
        printfpr(&env->active_fpu.fpr[i]);
8572
    }
8573

    
8574
#undef printfpr
8575
}
8576

    
8577
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8578
/* Debug help: The architecture requires 32bit code to maintain proper
8579
   sign-extended values on 64bit machines.  */
8580

    
8581
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8582

    
8583
static void
8584
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8585
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8586
                                int flags)
8587
{
8588
    int i;
8589

    
8590
    if (!SIGN_EXT_P(env->active_tc.PC))
8591
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8592
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8593
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8594
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8595
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8596
    if (!SIGN_EXT_P(env->btarget))
8597
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8598

    
8599
    for (i = 0; i < 32; i++) {
8600
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8601
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8602
    }
8603

    
8604
    if (!SIGN_EXT_P(env->CP0_EPC))
8605
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8606
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8607
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8608
}
8609
#endif
8610

    
8611
void cpu_dump_state (CPUState *env, FILE *f,
8612
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8613
                     int flags)
8614
{
8615
    int i;
8616

    
8617
    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",
8618
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8619
                env->hflags, env->btarget, env->bcond);
8620
    for (i = 0; i < 32; i++) {
8621
        if ((i & 3) == 0)
8622
            cpu_fprintf(f, "GPR%02d:", i);
8623
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8624
        if ((i & 3) == 3)
8625
            cpu_fprintf(f, "\n");
8626
    }
8627

    
8628
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8629
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8630
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8631
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8632
    if (env->hflags & MIPS_HFLAG_FPU)
8633
        fpu_dump_state(env, f, cpu_fprintf, flags);
8634
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8635
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8636
#endif
8637
}
8638

    
8639
static void mips_tcg_init(void)
8640
{
8641
    int i;
8642
    static int inited;
8643

    
8644
    /* Initialize various static tables. */
8645
    if (inited)
8646
        return;
8647

    
8648
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8649
    for (i = 0; i < 32; i++)
8650
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8651
                                        offsetof(CPUState, active_tc.gpr[i]),
8652
                                        regnames[i]);
8653
    cpu_PC = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8654
                                offsetof(CPUState, active_tc.PC), "PC");
8655
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8656
        cpu_HI[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8657
                                       offsetof(CPUState, active_tc.HI[i]),
8658
                                       regnames_HI[i]);
8659
        cpu_LO[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8660
                                       offsetof(CPUState, active_tc.LO[i]),
8661
                                       regnames_LO[i]);
8662
        cpu_ACX[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8663
                                        offsetof(CPUState, active_tc.ACX[i]),
8664
                                        regnames_ACX[i]);
8665
    }
8666
    cpu_dspctrl = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8667
                                     offsetof(CPUState, active_tc.DSPControl),
8668
                                     "DSPControl");
8669
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8670
                               offsetof(CPUState, bcond), "bcond");
8671
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8672
                                 offsetof(CPUState, btarget), "btarget");
8673
    for (i = 0; i < 32; i++)
8674
        fpu_fpr32[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8675
                                          offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8676
                                          fregnames[i]);
8677
    for (i = 0; i < 32; i++)
8678
        fpu_fpr64[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
8679
                                          offsetof(CPUState, active_fpu.fpr[i]),
8680
                                          fregnames_64[i]);
8681
    for (i = 0; i < 32; i++)
8682
        fpu_fpr32h[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8683
                                           offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8684
                                           fregnames_h[i]);
8685
    fpu_fcr0 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8686
                                   offsetof(CPUState, active_fpu.fcr0),
8687
                                   "fcr0");
8688
    fpu_fcr31 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8689
                                   offsetof(CPUState, active_fpu.fcr31),
8690
                                   "fcr31");
8691

    
8692
    /* register helpers */
8693
#undef DEF_HELPER
8694
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8695
#include "helper.h"
8696

    
8697
    inited = 1;
8698
}
8699

    
8700
#include "translate_init.c"
8701

    
8702
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8703
{
8704
    CPUMIPSState *env;
8705
    const mips_def_t *def;
8706

    
8707
    def = cpu_mips_find_by_name(cpu_model);
8708
    if (!def)
8709
        return NULL;
8710
    env = qemu_mallocz(sizeof(CPUMIPSState));
8711
    if (!env)
8712
        return NULL;
8713
    env->cpu_model = def;
8714

    
8715
    cpu_exec_init(env);
8716
    env->cpu_model_str = cpu_model;
8717
    mips_tcg_init();
8718
    cpu_reset(env);
8719
    return env;
8720
}
8721

    
8722
void cpu_reset (CPUMIPSState *env)
8723
{
8724
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8725

    
8726
    tlb_flush(env, 1);
8727

    
8728
    /* Minimal init */
8729
#if defined(CONFIG_USER_ONLY)
8730
    env->user_mode_only = 1;
8731
#endif
8732
    if (env->user_mode_only) {
8733
        env->hflags = MIPS_HFLAG_UM;
8734
    } else {
8735
        if (env->hflags & MIPS_HFLAG_BMASK) {
8736
            /* If the exception was raised from a delay slot,
8737
               come back to the jump.  */
8738
            env->CP0_ErrorEPC = env->active_tc.PC - 4;
8739
        } else {
8740
            env->CP0_ErrorEPC = env->active_tc.PC;
8741
        }
8742
        env->active_tc.PC = (int32_t)0xBFC00000;
8743
        env->CP0_Wired = 0;
8744
        /* SMP not implemented */
8745
        env->CP0_EBase = 0x80000000;
8746
        env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8747
        /* vectored interrupts not implemented, timer on int 7,
8748
           no performance counters. */
8749
        env->CP0_IntCtl = 0xe0000000;
8750
        {
8751
            int i;
8752

    
8753
            for (i = 0; i < 7; i++) {
8754
                env->CP0_WatchLo[i] = 0;
8755
                env->CP0_WatchHi[i] = 0x80000000;
8756
            }
8757
            env->CP0_WatchLo[7] = 0;
8758
            env->CP0_WatchHi[7] = 0;
8759
        }
8760
        /* Count register increments in debug mode, EJTAG version 1 */
8761
        env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8762
        env->hflags = MIPS_HFLAG_CP0;
8763
    }
8764
    env->exception_index = EXCP_NONE;
8765
    cpu_mips_register(env, env->cpu_model);
8766
}
8767

    
8768
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8769
                unsigned long searched_pc, int pc_pos, void *puc)
8770
{
8771
    env->active_tc.PC = gen_opc_pc[pc_pos];
8772
    env->hflags &= ~MIPS_HFLAG_BMASK;
8773
    env->hflags |= gen_opc_hflags[pc_pos];
8774
}