Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 0eaef5aa

History | View | Annotate | Download (258.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, bcond, btarget, current_fpu;
427

    
428
#include "gen-icount.h"
429

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3436
    if (use_icount)
3437
        gen_io_start();
3438

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

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

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

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

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

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

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

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

    
4620
    if (use_icount)
4621
        gen_io_start();
4622

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5897
/* Coprocessor 1 (FPU) */
5898

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6019
    tcg_gen_mov_tl(t0, t1);
6020
    tcg_temp_free(t1);
6021

    
6022
    gen_set_label(l1);
6023
    gen_store_gpr(t0, rd);
6024
    tcg_temp_free(t0);
6025
}
6026

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

    
6036
    if (cc)
6037
        ccbit = 1 << (24 + cc);
6038
    else
6039
        ccbit = 1 << 23;
6040

    
6041
    if (tf)
6042
        cond = TCG_COND_EQ;
6043
    else
6044
        cond = TCG_COND_NE;
6045

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

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

    
6068
    if (cc)
6069
        ccbit = 1 << (24 + cc);
6070
    else
6071
        ccbit = 1 << 23;
6072

    
6073
    if (tf)
6074
        cond = TCG_COND_EQ;
6075
    else
6076
        cond = TCG_COND_NE;
6077

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

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

    
6103
    if (tf)
6104
        cond = TCG_COND_EQ;
6105
    else
6106
        cond = TCG_COND_NE;
6107

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

    
6132

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7798
/* ISA extensions (ASEs) */
7799
/* MIPS16 extension to MIPS32 */
7800
/* SmartMIPS extension to MIPS32 */
7801

    
7802
#if defined(TARGET_MIPS64)
7803

    
7804
/* MDMX extension to MIPS64 */
7805

    
7806
#endif
7807

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8635

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

    
8644
#undef printfpr
8645
}
8646

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

    
8651
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8652

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

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

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

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

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

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

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

    
8709
static void mips_tcg_init(void)
8710
{
8711
    static int inited;
8712

    
8713
    /* Initialize various static tables. */
8714
    if (inited)
8715
        return;
8716

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

    
8727
    /* register helpers */
8728
#undef DEF_HELPER
8729
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8730
#include "helper.h"
8731

    
8732
    inited = 1;
8733
}
8734

    
8735
#include "translate_init.c"
8736

    
8737
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8738
{
8739
    CPUMIPSState *env;
8740
    const mips_def_t *def;
8741

    
8742
    def = cpu_mips_find_by_name(cpu_model);
8743
    if (!def)
8744
        return NULL;
8745
    env = qemu_mallocz(sizeof(CPUMIPSState));
8746
    if (!env)
8747
        return NULL;
8748
    env->cpu_model = def;
8749

    
8750
    cpu_exec_init(env);
8751
    env->cpu_model_str = cpu_model;
8752
    mips_tcg_init();
8753
    cpu_reset(env);
8754
    return env;
8755
}
8756

    
8757
void cpu_reset (CPUMIPSState *env)
8758
{
8759
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8760

    
8761
    tlb_flush(env, 1);
8762

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

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

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