Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d12d51d5

History | View | Annotate | Download (245.5 kB)

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

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

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

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

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

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

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

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

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
428
/* global register indices */
429
static TCGv_ptr cpu_env;
430
static TCGv cpu_gpr[32], cpu_PC;
431
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
432
static TCGv cpu_dspctrl, btarget;
433
static TCGv_i32 bcond;
434
static TCGv_i32 fpu_fpr32[32], fpu_fpr32h[32];
435
static TCGv_i64 fpu_fpr64[32];
436
static TCGv_i32 fpu_fcr0, fpu_fcr31;
437

    
438
#include "gen-icount.h"
439

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

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

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

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

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

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

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

    
489
static const char *regnames_HI[] =
490
    { "HI0", "HI1", "HI2", "HI3", };
491

    
492
static const char *regnames_LO[] =
493
    { "LO0", "LO1", "LO2", "LO3", };
494

    
495
static const char *regnames_ACX[] =
496
    { "ACX0", "ACX1", "ACX2", "ACX3", };
497

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

    
504
static const char *fregnames_64[] =
505
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
506
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
507
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
508
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
509

    
510
static const char *fregnames_h[] =
511
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
512
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
513
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
514
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
515

    
516
#ifdef MIPS_DEBUG_DISAS
517
#define MIPS_DEBUG(fmt, args...)                                              \
518
do {                                                                          \
519
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
520
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
521
                ctx->pc, ctx->opcode , ##args);                               \
522
    }                                                                         \
523
} while (0)
524
#define LOG_DISAS(...)                        \
525
    do {                                      \
526
        if (loglevel & CPU_LOG_TB_IN_ASM)     \
527
            fprintf(logfile, ## __VA_ARGS__); \
528
    } while (0)
529
#else
530
#define MIPS_DEBUG(fmt, args...) do { } while(0)
531
#define LOG_DISAS(...) do { } while (0)
532
#endif
533

    
534
#define MIPS_INVAL(op)                                                        \
535
do {                                                                          \
536
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
537
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
538
} while (0)
539

    
540
/* General purpose registers moves. */
541
static inline void gen_load_gpr (TCGv t, int reg)
542
{
543
    if (reg == 0)
544
        tcg_gen_movi_tl(t, 0);
545
    else
546
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
547
}
548

    
549
static inline void gen_store_gpr (TCGv t, int reg)
550
{
551
    if (reg != 0)
552
        tcg_gen_mov_tl(cpu_gpr[reg], t);
553
}
554

    
555
/* Moves to/from ACX register.  */
556
static inline void gen_load_ACX (TCGv t, int reg)
557
{
558
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
559
}
560

    
561
static inline void gen_store_ACX (TCGv t, int reg)
562
{
563
    tcg_gen_mov_tl(cpu_ACX[reg], t);
564
}
565

    
566
/* Moves to/from shadow registers. */
567
static inline void gen_load_srsgpr (int from, int to)
568
{
569
    TCGv r_tmp1 = tcg_temp_new();
570

    
571
    if (from == 0)
572
        tcg_gen_movi_tl(r_tmp1, 0);
573
    else {
574
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
575
        TCGv_ptr addr = tcg_temp_new_ptr();
576

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

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

    
592
static inline void gen_store_srsgpr (int from, int to)
593
{
594
    if (to != 0) {
595
        TCGv r_tmp1 = tcg_temp_new();
596
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
597
        TCGv_ptr addr = tcg_temp_new_ptr();
598

    
599
        gen_load_gpr(r_tmp1, from);
600
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
601
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
602
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
603
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
604
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
605
        tcg_gen_add_ptr(addr, cpu_env, addr);
606

    
607
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
608
        tcg_temp_free_ptr(addr);
609
        tcg_temp_free_i32(r_tmp2);
610
        tcg_temp_free(r_tmp1);
611
    }
612
}
613

    
614
/* Floating point register moves. */
615
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
616
{
617
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
618
}
619

    
620
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
621
{
622
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
623
}
624

    
625
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
626
{
627
    if (ctx->hflags & MIPS_HFLAG_F64)
628
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
629
    else {
630
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
631
    }
632
}
633

    
634
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
635
{
636
    if (ctx->hflags & MIPS_HFLAG_F64)
637
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
638
    else {
639
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
640
        tcg_gen_shri_i64(t, t, 32);
641
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
642
    }
643
}
644

    
645
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
646
{
647
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
648
}
649

    
650
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
651
{
652
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
653
}
654

    
655
static inline void get_fp_cond (TCGv_i32 t)
656
{
657
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
658
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
659

    
660
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
661
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
662
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
663
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
664
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
665
    tcg_temp_free_i32(r_tmp1);
666
    tcg_temp_free_i32(r_tmp2);
667
}
668

    
669
#define FOP_CONDS(type, fmt, bits)                                            \
670
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
671
                                               TCGv_i##bits b, int cc)        \
672
{                                                                             \
673
    switch (n) {                                                              \
674
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
675
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
676
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
677
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
678
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
679
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
680
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
681
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
682
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
683
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
684
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
685
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
686
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
687
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
688
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
689
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
690
    default: abort();                                                         \
691
    }                                                                         \
692
}
693

    
694
FOP_CONDS(, d, 64)
695
FOP_CONDS(abs, d, 64)
696
FOP_CONDS(, s, 32)
697
FOP_CONDS(abs, s, 32)
698
FOP_CONDS(, ps, 64)
699
FOP_CONDS(abs, ps, 64)
700
#undef FOP_CONDS
701

    
702
/* Tests */
703
#define OP_COND(name, cond)                                   \
704
static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
705
{                                                             \
706
    int l1 = gen_new_label();                                 \
707
    int l2 = gen_new_label();                                 \
708
                                                              \
709
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
710
    tcg_gen_movi_tl(t0, 0);                                   \
711
    tcg_gen_br(l2);                                           \
712
    gen_set_label(l1);                                        \
713
    tcg_gen_movi_tl(t0, 1);                                   \
714
    gen_set_label(l2);                                        \
715
}
716
OP_COND(eq, TCG_COND_EQ);
717
OP_COND(ne, TCG_COND_NE);
718
OP_COND(ge, TCG_COND_GE);
719
OP_COND(geu, TCG_COND_GEU);
720
OP_COND(lt, TCG_COND_LT);
721
OP_COND(ltu, TCG_COND_LTU);
722
#undef OP_COND
723

    
724
#define OP_CONDI(name, cond)                                  \
725
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
726
{                                                             \
727
    int l1 = gen_new_label();                                 \
728
    int l2 = gen_new_label();                                 \
729
                                                              \
730
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
731
    tcg_gen_movi_tl(t, 0);                                    \
732
    tcg_gen_br(l2);                                           \
733
    gen_set_label(l1);                                        \
734
    tcg_gen_movi_tl(t, 1);                                    \
735
    gen_set_label(l2);                                        \
736
}
737
OP_CONDI(lti, TCG_COND_LT);
738
OP_CONDI(ltiu, TCG_COND_LTU);
739
#undef OP_CONDI
740

    
741
#define OP_CONDZ(name, cond)                                  \
742
static inline void glue(gen_op_, name) (TCGv t)               \
743
{                                                             \
744
    int l1 = gen_new_label();                                 \
745
    int l2 = gen_new_label();                                 \
746
                                                              \
747
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
748
    tcg_gen_movi_tl(t, 0);                                    \
749
    tcg_gen_br(l2);                                           \
750
    gen_set_label(l1);                                        \
751
    tcg_gen_movi_tl(t, 1);                                    \
752
    gen_set_label(l2);                                        \
753
}
754
OP_CONDZ(gez, TCG_COND_GE);
755
OP_CONDZ(gtz, TCG_COND_GT);
756
OP_CONDZ(lez, TCG_COND_LE);
757
OP_CONDZ(ltz, TCG_COND_LT);
758
#undef OP_CONDZ
759

    
760
static inline void gen_save_pc(target_ulong pc)
761
{
762
    tcg_gen_movi_tl(cpu_PC, pc);
763
}
764

    
765
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
766
{
767
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
768
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
769
        gen_save_pc(ctx->pc);
770
        ctx->saved_pc = ctx->pc;
771
    }
772
    if (ctx->hflags != ctx->saved_hflags) {
773
        TCGv_i32 r_tmp = tcg_temp_new_i32();
774

    
775
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
776
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
777
        tcg_temp_free_i32(r_tmp);
778
        ctx->saved_hflags = ctx->hflags;
779
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
780
        case MIPS_HFLAG_BR:
781
            break;
782
        case MIPS_HFLAG_BC:
783
        case MIPS_HFLAG_BL:
784
        case MIPS_HFLAG_B:
785
            tcg_gen_movi_tl(btarget, ctx->btarget);
786
            break;
787
        }
788
    }
789
}
790

    
791
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
792
{
793
    ctx->saved_hflags = ctx->hflags;
794
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
795
    case MIPS_HFLAG_BR:
796
        break;
797
    case MIPS_HFLAG_BC:
798
    case MIPS_HFLAG_BL:
799
    case MIPS_HFLAG_B:
800
        ctx->btarget = env->btarget;
801
        break;
802
    }
803
}
804

    
805
static inline void
806
generate_exception_err (DisasContext *ctx, int excp, int err)
807
{
808
    TCGv_i32 texcp = tcg_const_i32(excp);
809
    TCGv_i32 terr = tcg_const_i32(err);
810
    save_cpu_state(ctx, 1);
811
    gen_helper_raise_exception_err(texcp, terr);
812
    tcg_temp_free_i32(terr);
813
    tcg_temp_free_i32(texcp);
814
    gen_helper_interrupt_restart();
815
    tcg_gen_exit_tb(0);
816
}
817

    
818
static inline void
819
generate_exception (DisasContext *ctx, int excp)
820
{
821
    save_cpu_state(ctx, 1);
822
    gen_helper_0i(raise_exception, excp);
823
    gen_helper_interrupt_restart();
824
    tcg_gen_exit_tb(0);
825
}
826

    
827
/* Addresses computation */
828
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
829
{
830
    tcg_gen_add_tl(t0, t0, t1);
831

    
832
#if defined(TARGET_MIPS64)
833
    /* For compatibility with 32-bit code, data reference in user mode
834
       with Status_UX = 0 should be casted to 32-bit and sign extended.
835
       See the MIPS64 PRA manual, section 4.10. */
836
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
837
        !(ctx->hflags & MIPS_HFLAG_UX)) {
838
        tcg_gen_ext32s_i64(t0, t0);
839
    }
840
#endif
841
}
842

    
843
static inline void check_cp0_enabled(DisasContext *ctx)
844
{
845
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
846
        generate_exception_err(ctx, EXCP_CpU, 1);
847
}
848

    
849
static inline void check_cp1_enabled(DisasContext *ctx)
850
{
851
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
852
        generate_exception_err(ctx, EXCP_CpU, 1);
853
}
854

    
855
/* Verify that the processor is running with COP1X instructions enabled.
856
   This is associated with the nabla symbol in the MIPS32 and MIPS64
857
   opcode tables.  */
858

    
859
static inline void check_cop1x(DisasContext *ctx)
860
{
861
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
862
        generate_exception(ctx, EXCP_RI);
863
}
864

    
865
/* Verify that the processor is running with 64-bit floating-point
866
   operations enabled.  */
867

    
868
static inline void check_cp1_64bitmode(DisasContext *ctx)
869
{
870
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
871
        generate_exception(ctx, EXCP_RI);
872
}
873

    
874
/*
875
 * Verify if floating point register is valid; an operation is not defined
876
 * if bit 0 of any register specification is set and the FR bit in the
877
 * Status register equals zero, since the register numbers specify an
878
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
879
 * in the Status register equals one, both even and odd register numbers
880
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
881
 *
882
 * Multiple 64 bit wide registers can be checked by calling
883
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
884
 */
885
static inline void check_cp1_registers(DisasContext *ctx, int regs)
886
{
887
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
888
        generate_exception(ctx, EXCP_RI);
889
}
890

    
891
/* This code generates a "reserved instruction" exception if the
892
   CPU does not support the instruction set corresponding to flags. */
893
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
894
{
895
    if (unlikely(!(env->insn_flags & flags)))
896
        generate_exception(ctx, EXCP_RI);
897
}
898

    
899
/* This code generates a "reserved instruction" exception if 64-bit
900
   instructions are not enabled. */
901
static inline void check_mips_64(DisasContext *ctx)
902
{
903
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
904
        generate_exception(ctx, EXCP_RI);
905
}
906

    
907
/* load/store instructions. */
908
#define OP_LD(insn,fname)                                        \
909
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
910
{                                                                \
911
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
912
}
913
OP_LD(lb,ld8s);
914
OP_LD(lbu,ld8u);
915
OP_LD(lh,ld16s);
916
OP_LD(lhu,ld16u);
917
OP_LD(lw,ld32s);
918
#if defined(TARGET_MIPS64)
919
OP_LD(lwu,ld32u);
920
OP_LD(ld,ld64);
921
#endif
922
#undef OP_LD
923

    
924
#define OP_ST(insn,fname)                                        \
925
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
926
{                                                                \
927
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
928
}
929
OP_ST(sb,st8);
930
OP_ST(sh,st16);
931
OP_ST(sw,st32);
932
#if defined(TARGET_MIPS64)
933
OP_ST(sd,st64);
934
#endif
935
#undef OP_ST
936

    
937
#define OP_LD_ATOMIC(insn,fname)                                        \
938
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
939
{                                                                       \
940
    tcg_gen_mov_tl(t1, t0);                                             \
941
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
942
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
943
}
944
OP_LD_ATOMIC(ll,ld32s);
945
#if defined(TARGET_MIPS64)
946
OP_LD_ATOMIC(lld,ld64);
947
#endif
948
#undef OP_LD_ATOMIC
949

    
950
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
951
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
952
{                                                                       \
953
    TCGv r_tmp = tcg_temp_local_new();                       \
954
    int l1 = gen_new_label();                                           \
955
    int l2 = gen_new_label();                                           \
956
    int l3 = gen_new_label();                                           \
957
                                                                        \
958
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
959
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
960
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
961
    generate_exception(ctx, EXCP_AdES);                                 \
962
    gen_set_label(l1);                                                  \
963
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
964
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
965
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
966
    tcg_gen_movi_tl(t0, 1);                                             \
967
    tcg_gen_br(l3);                                                     \
968
    gen_set_label(l2);                                                  \
969
    tcg_gen_movi_tl(t0, 0);                                             \
970
    gen_set_label(l3);                                                  \
971
    tcg_temp_free(r_tmp);                                               \
972
}
973
OP_ST_ATOMIC(sc,st32,0x3);
974
#if defined(TARGET_MIPS64)
975
OP_ST_ATOMIC(scd,st64,0x7);
976
#endif
977
#undef OP_ST_ATOMIC
978

    
979
/* Load and store */
980
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
981
                      int base, int16_t offset)
982
{
983
    const char *opn = "ldst";
984
    TCGv t0 = tcg_temp_local_new();
985
    TCGv t1 = tcg_temp_local_new();
986

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

    
1142
/* Load and store */
1143
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1144
                          int base, int16_t offset)
1145
{
1146
    const char *opn = "flt_ldst";
1147
    TCGv t0 = tcg_temp_local_new();
1148

    
1149
    if (base == 0) {
1150
        tcg_gen_movi_tl(t0, offset);
1151
    } else if (offset == 0) {
1152
        gen_load_gpr(t0, base);
1153
    } else {
1154
        tcg_gen_movi_tl(t0, offset);
1155
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1156
    }
1157
    /* Don't do NOP if destination is zero: we must perform the actual
1158
       memory access. */
1159
    switch (opc) {
1160
    case OPC_LWC1:
1161
        {
1162
            TCGv_i32 fp0 = tcg_temp_new_i32();
1163
            TCGv t1 = tcg_temp_new();
1164

    
1165
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1166
            tcg_gen_trunc_tl_i32(fp0, t1);
1167
            gen_store_fpr32(fp0, ft);
1168
            tcg_temp_free(t1);
1169
            tcg_temp_free_i32(fp0);
1170
        }
1171
        opn = "lwc1";
1172
        break;
1173
    case OPC_SWC1:
1174
        {
1175
            TCGv_i32 fp0 = tcg_temp_new_i32();
1176
            TCGv t1 = tcg_temp_new();
1177

    
1178
            gen_load_fpr32(fp0, ft);
1179
            tcg_gen_extu_i32_tl(t1, fp0);
1180
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1181
            tcg_temp_free(t1);
1182
            tcg_temp_free_i32(fp0);
1183
        }
1184
        opn = "swc1";
1185
        break;
1186
    case OPC_LDC1:
1187
        {
1188
            TCGv_i64 fp0 = tcg_temp_new_i64();
1189

    
1190
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1191
            gen_store_fpr64(ctx, fp0, ft);
1192
            tcg_temp_free_i64(fp0);
1193
        }
1194
        opn = "ldc1";
1195
        break;
1196
    case OPC_SDC1:
1197
        {
1198
            TCGv_i64 fp0 = tcg_temp_new_i64();
1199

    
1200
            gen_load_fpr64(ctx, fp0, ft);
1201
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1202
            tcg_temp_free_i64(fp0);
1203
        }
1204
        opn = "sdc1";
1205
        break;
1206
    default:
1207
        MIPS_INVAL(opn);
1208
        generate_exception(ctx, EXCP_RI);
1209
        goto out;
1210
    }
1211
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1212
 out:
1213
    tcg_temp_free(t0);
1214
}
1215

    
1216
/* Arithmetic with immediate operand */
1217
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1218
                           int rt, int rs, int16_t imm)
1219
{
1220
    target_ulong uimm;
1221
    const char *opn = "imm arith";
1222
    TCGv t0 = tcg_temp_local_new();
1223

    
1224
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1225
        /* If no destination, treat it as a NOP.
1226
           For addi, we must generate the overflow exception when needed. */
1227
        MIPS_DEBUG("NOP");
1228
        goto out;
1229
    }
1230
    uimm = (uint16_t)imm;
1231
    switch (opc) {
1232
    case OPC_ADDI:
1233
    case OPC_ADDIU:
1234
#if defined(TARGET_MIPS64)
1235
    case OPC_DADDI:
1236
    case OPC_DADDIU:
1237
#endif
1238
    case OPC_SLTI:
1239
    case OPC_SLTIU:
1240
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1241
        /* Fall through. */
1242
    case OPC_ANDI:
1243
    case OPC_ORI:
1244
    case OPC_XORI:
1245
        gen_load_gpr(t0, rs);
1246
        break;
1247
    case OPC_LUI:
1248
        tcg_gen_movi_tl(t0, imm << 16);
1249
        break;
1250
    case OPC_SLL:
1251
    case OPC_SRA:
1252
    case OPC_SRL:
1253
#if defined(TARGET_MIPS64)
1254
    case OPC_DSLL:
1255
    case OPC_DSRA:
1256
    case OPC_DSRL:
1257
    case OPC_DSLL32:
1258
    case OPC_DSRA32:
1259
    case OPC_DSRL32:
1260
#endif
1261
        uimm &= 0x1f;
1262
        gen_load_gpr(t0, rs);
1263
        break;
1264
    }
1265
    switch (opc) {
1266
    case OPC_ADDI:
1267
        {
1268
            TCGv r_tmp1 = tcg_temp_new();
1269
            TCGv r_tmp2 = tcg_temp_new();
1270
            int l1 = gen_new_label();
1271

    
1272
            save_cpu_state(ctx, 1);
1273
            tcg_gen_ext32s_tl(r_tmp1, t0);
1274
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1275

    
1276
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1277
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1278
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1279
            tcg_temp_free(r_tmp2);
1280
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1281
            /* operands of same sign, result different sign */
1282
            generate_exception(ctx, EXCP_OVERFLOW);
1283
            gen_set_label(l1);
1284
            tcg_temp_free(r_tmp1);
1285

    
1286
            tcg_gen_ext32s_tl(t0, t0);
1287
        }
1288
        opn = "addi";
1289
        break;
1290
    case OPC_ADDIU:
1291
        tcg_gen_addi_tl(t0, t0, uimm);
1292
        tcg_gen_ext32s_tl(t0, t0);
1293
        opn = "addiu";
1294
        break;
1295
#if defined(TARGET_MIPS64)
1296
    case OPC_DADDI:
1297
        {
1298
            TCGv r_tmp1 = tcg_temp_new();
1299
            TCGv r_tmp2 = tcg_temp_new();
1300
            int l1 = gen_new_label();
1301

    
1302
            save_cpu_state(ctx, 1);
1303
            tcg_gen_mov_tl(r_tmp1, t0);
1304
            tcg_gen_addi_tl(t0, t0, uimm);
1305

    
1306
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1307
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1308
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1309
            tcg_temp_free(r_tmp2);
1310
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1311
            /* operands of same sign, result different sign */
1312
            generate_exception(ctx, EXCP_OVERFLOW);
1313
            gen_set_label(l1);
1314
            tcg_temp_free(r_tmp1);
1315
        }
1316
        opn = "daddi";
1317
        break;
1318
    case OPC_DADDIU:
1319
        tcg_gen_addi_tl(t0, t0, uimm);
1320
        opn = "daddiu";
1321
        break;
1322
#endif
1323
    case OPC_SLTI:
1324
        gen_op_lti(t0, uimm);
1325
        opn = "slti";
1326
        break;
1327
    case OPC_SLTIU:
1328
        gen_op_ltiu(t0, uimm);
1329
        opn = "sltiu";
1330
        break;
1331
    case OPC_ANDI:
1332
        tcg_gen_andi_tl(t0, t0, uimm);
1333
        opn = "andi";
1334
        break;
1335
    case OPC_ORI:
1336
        tcg_gen_ori_tl(t0, t0, uimm);
1337
        opn = "ori";
1338
        break;
1339
    case OPC_XORI:
1340
        tcg_gen_xori_tl(t0, t0, uimm);
1341
        opn = "xori";
1342
        break;
1343
    case OPC_LUI:
1344
        opn = "lui";
1345
        break;
1346
    case OPC_SLL:
1347
        tcg_gen_shli_tl(t0, t0, uimm);
1348
        tcg_gen_ext32s_tl(t0, t0);
1349
        opn = "sll";
1350
        break;
1351
    case OPC_SRA:
1352
        tcg_gen_ext32s_tl(t0, t0);
1353
        tcg_gen_sari_tl(t0, t0, uimm);
1354
        opn = "sra";
1355
        break;
1356
    case OPC_SRL:
1357
        switch ((ctx->opcode >> 21) & 0x1f) {
1358
        case 0:
1359
            if (uimm != 0) {
1360
                tcg_gen_ext32u_tl(t0, t0);
1361
                tcg_gen_shri_tl(t0, t0, uimm);
1362
            } else {
1363
                tcg_gen_ext32s_tl(t0, t0);
1364
            }
1365
            opn = "srl";
1366
            break;
1367
        case 1:
1368
            /* rotr is decoded as srl on non-R2 CPUs */
1369
            if (env->insn_flags & ISA_MIPS32R2) {
1370
                if (uimm != 0) {
1371
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1372

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

    
1470
/* Arithmetic */
1471
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1472
                       int rd, int rs, int rt)
1473
{
1474
    const char *opn = "arith";
1475
    TCGv t0 = tcg_temp_local_new();
1476
    TCGv t1 = tcg_temp_local_new();
1477

    
1478
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1479
       && opc != OPC_DADD && opc != OPC_DSUB) {
1480
        /* If no destination, treat it as a NOP.
1481
           For add & sub, we must generate the overflow exception when needed. */
1482
        MIPS_DEBUG("NOP");
1483
        goto out;
1484
    }
1485
    gen_load_gpr(t0, rs);
1486
    /* Specialcase the conventional move operation. */
1487
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1488
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1489
        gen_store_gpr(t0, rd);
1490
        goto out;
1491
    }
1492
    gen_load_gpr(t1, rt);
1493
    switch (opc) {
1494
    case OPC_ADD:
1495
        {
1496
            TCGv r_tmp1 = tcg_temp_new();
1497
            TCGv r_tmp2 = tcg_temp_new();
1498
            int l1 = gen_new_label();
1499

    
1500
            save_cpu_state(ctx, 1);
1501
            tcg_gen_ext32s_tl(r_tmp1, t0);
1502
            tcg_gen_ext32s_tl(r_tmp2, t1);
1503
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1504

    
1505
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1506
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1507
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1508
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1509
            tcg_temp_free(r_tmp2);
1510
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1511
            /* operands of same sign, result different sign */
1512
            generate_exception(ctx, EXCP_OVERFLOW);
1513
            gen_set_label(l1);
1514
            tcg_temp_free(r_tmp1);
1515

    
1516
            tcg_gen_ext32s_tl(t0, t0);
1517
        }
1518
        opn = "add";
1519
        break;
1520
    case OPC_ADDU:
1521
        tcg_gen_add_tl(t0, t0, t1);
1522
        tcg_gen_ext32s_tl(t0, t0);
1523
        opn = "addu";
1524
        break;
1525
    case OPC_SUB:
1526
        {
1527
            TCGv r_tmp1 = tcg_temp_new();
1528
            TCGv r_tmp2 = tcg_temp_new();
1529
            int l1 = gen_new_label();
1530

    
1531
            save_cpu_state(ctx, 1);
1532
            tcg_gen_ext32s_tl(r_tmp1, t0);
1533
            tcg_gen_ext32s_tl(r_tmp2, t1);
1534
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1535

    
1536
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1537
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1538
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1539
            tcg_temp_free(r_tmp2);
1540
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1541
            /* operands of different sign, first operand and result different sign */
1542
            generate_exception(ctx, EXCP_OVERFLOW);
1543
            gen_set_label(l1);
1544
            tcg_temp_free(r_tmp1);
1545

    
1546
            tcg_gen_ext32s_tl(t0, t0);
1547
        }
1548
        opn = "sub";
1549
        break;
1550
    case OPC_SUBU:
1551
        tcg_gen_sub_tl(t0, t0, t1);
1552
        tcg_gen_ext32s_tl(t0, t0);
1553
        opn = "subu";
1554
        break;
1555
#if defined(TARGET_MIPS64)
1556
    case OPC_DADD:
1557
        {
1558
            TCGv r_tmp1 = tcg_temp_new();
1559
            TCGv r_tmp2 = tcg_temp_new();
1560
            int l1 = gen_new_label();
1561

    
1562
            save_cpu_state(ctx, 1);
1563
            tcg_gen_mov_tl(r_tmp1, t0);
1564
            tcg_gen_add_tl(t0, t0, t1);
1565

    
1566
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1567
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1568
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1569
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1570
            tcg_temp_free(r_tmp2);
1571
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1572
            /* operands of same sign, result different sign */
1573
            generate_exception(ctx, EXCP_OVERFLOW);
1574
            gen_set_label(l1);
1575
            tcg_temp_free(r_tmp1);
1576
        }
1577
        opn = "dadd";
1578
        break;
1579
    case OPC_DADDU:
1580
        tcg_gen_add_tl(t0, t0, t1);
1581
        opn = "daddu";
1582
        break;
1583
    case OPC_DSUB:
1584
        {
1585
            TCGv r_tmp1 = tcg_temp_new();
1586
            TCGv r_tmp2 = tcg_temp_new();
1587
            int l1 = gen_new_label();
1588

    
1589
            save_cpu_state(ctx, 1);
1590
            tcg_gen_mov_tl(r_tmp1, t0);
1591
            tcg_gen_sub_tl(t0, t0, t1);
1592

    
1593
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1594
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1595
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1596
            tcg_temp_free(r_tmp2);
1597
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1598
            /* operands of different sign, first operand and result different sign */
1599
            generate_exception(ctx, EXCP_OVERFLOW);
1600
            gen_set_label(l1);
1601
            tcg_temp_free(r_tmp1);
1602
        }
1603
        opn = "dsub";
1604
        break;
1605
    case OPC_DSUBU:
1606
        tcg_gen_sub_tl(t0, t0, t1);
1607
        opn = "dsubu";
1608
        break;
1609
#endif
1610
    case OPC_SLT:
1611
        gen_op_lt(t0, t1);
1612
        opn = "slt";
1613
        break;
1614
    case OPC_SLTU:
1615
        gen_op_ltu(t0, t1);
1616
        opn = "sltu";
1617
        break;
1618
    case OPC_AND:
1619
        tcg_gen_and_tl(t0, t0, t1);
1620
        opn = "and";
1621
        break;
1622
    case OPC_NOR:
1623
        tcg_gen_or_tl(t0, t0, t1);
1624
        tcg_gen_not_tl(t0, t0);
1625
        opn = "nor";
1626
        break;
1627
    case OPC_OR:
1628
        tcg_gen_or_tl(t0, t0, t1);
1629
        opn = "or";
1630
        break;
1631
    case OPC_XOR:
1632
        tcg_gen_xor_tl(t0, t0, t1);
1633
        opn = "xor";
1634
        break;
1635
    case OPC_MUL:
1636
        tcg_gen_mul_tl(t0, t0, t1);
1637
        tcg_gen_ext32s_tl(t0, t0);
1638
        opn = "mul";
1639
        break;
1640
    case OPC_MOVN:
1641
        {
1642
            int l1 = gen_new_label();
1643

    
1644
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1645
            gen_store_gpr(t0, rd);
1646
            gen_set_label(l1);
1647
        }
1648
        opn = "movn";
1649
        goto print;
1650
    case OPC_MOVZ:
1651
        {
1652
            int l1 = gen_new_label();
1653

    
1654
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1655
            gen_store_gpr(t0, rd);
1656
            gen_set_label(l1);
1657
        }
1658
        opn = "movz";
1659
        goto print;
1660
    case OPC_SLLV:
1661
        tcg_gen_andi_tl(t0, t0, 0x1f);
1662
        tcg_gen_shl_tl(t0, t1, t0);
1663
        tcg_gen_ext32s_tl(t0, t0);
1664
        opn = "sllv";
1665
        break;
1666
    case OPC_SRAV:
1667
        tcg_gen_ext32s_tl(t1, t1);
1668
        tcg_gen_andi_tl(t0, t0, 0x1f);
1669
        tcg_gen_sar_tl(t0, t1, t0);
1670
        opn = "srav";
1671
        break;
1672
    case OPC_SRLV:
1673
        switch ((ctx->opcode >> 6) & 0x1f) {
1674
        case 0:
1675
            tcg_gen_ext32u_tl(t1, t1);
1676
            tcg_gen_andi_tl(t0, t0, 0x1f);
1677
            tcg_gen_shr_tl(t0, t1, t0);
1678
            tcg_gen_ext32s_tl(t0, t0);
1679
            opn = "srlv";
1680
            break;
1681
        case 1:
1682
            /* rotrv is decoded as srlv on non-R2 CPUs */
1683
            if (env->insn_flags & ISA_MIPS32R2) {
1684
                int l1 = gen_new_label();
1685
                int l2 = gen_new_label();
1686

    
1687
                tcg_gen_andi_tl(t0, t0, 0x1f);
1688
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1689
                {
1690
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1691
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1692

    
1693
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1694
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1695
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1696
                    tcg_temp_free_i32(r_tmp1);
1697
                    tcg_temp_free_i32(r_tmp2);
1698
                    tcg_gen_br(l2);
1699
                }
1700
                gen_set_label(l1);
1701
                tcg_gen_mov_tl(t0, t1);
1702
                gen_set_label(l2);
1703
                opn = "rotrv";
1704
            } else {
1705
                tcg_gen_ext32u_tl(t1, t1);
1706
                tcg_gen_andi_tl(t0, t0, 0x1f);
1707
                tcg_gen_shr_tl(t0, t1, t0);
1708
                tcg_gen_ext32s_tl(t0, t0);
1709
                opn = "srlv";
1710
            }
1711
            break;
1712
        default:
1713
            MIPS_INVAL("invalid srlv flag");
1714
            generate_exception(ctx, EXCP_RI);
1715
            break;
1716
        }
1717
        break;
1718
#if defined(TARGET_MIPS64)
1719
    case OPC_DSLLV:
1720
        tcg_gen_andi_tl(t0, t0, 0x3f);
1721
        tcg_gen_shl_tl(t0, t1, t0);
1722
        opn = "dsllv";
1723
        break;
1724
    case OPC_DSRAV:
1725
        tcg_gen_andi_tl(t0, t0, 0x3f);
1726
        tcg_gen_sar_tl(t0, t1, t0);
1727
        opn = "dsrav";
1728
        break;
1729
    case OPC_DSRLV:
1730
        switch ((ctx->opcode >> 6) & 0x1f) {
1731
        case 0:
1732
            tcg_gen_andi_tl(t0, t0, 0x3f);
1733
            tcg_gen_shr_tl(t0, t1, t0);
1734
            opn = "dsrlv";
1735
            break;
1736
        case 1:
1737
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1738
            if (env->insn_flags & ISA_MIPS32R2) {
1739
                int l1 = gen_new_label();
1740
                int l2 = gen_new_label();
1741

    
1742
                tcg_gen_andi_tl(t0, t0, 0x3f);
1743
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1744
                {
1745
                    tcg_gen_rotr_tl(t0, t1, t0);
1746
                    tcg_gen_br(l2);
1747
                }
1748
                gen_set_label(l1);
1749
                tcg_gen_mov_tl(t0, t1);
1750
                gen_set_label(l2);
1751
                opn = "drotrv";
1752
            } else {
1753
                tcg_gen_andi_tl(t0, t0, 0x3f);
1754
                tcg_gen_shr_tl(t0, t1, t0);
1755
                opn = "dsrlv";
1756
            }
1757
            break;
1758
        default:
1759
            MIPS_INVAL("invalid dsrlv flag");
1760
            generate_exception(ctx, EXCP_RI);
1761
            break;
1762
        }
1763
        break;
1764
#endif
1765
    default:
1766
        MIPS_INVAL(opn);
1767
        generate_exception(ctx, EXCP_RI);
1768
        goto out;
1769
    }
1770
    gen_store_gpr(t0, rd);
1771
 print:
1772
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1773
 out:
1774
    tcg_temp_free(t0);
1775
    tcg_temp_free(t1);
1776
}
1777

    
1778
/* Arithmetic on HI/LO registers */
1779
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1780
{
1781
    const char *opn = "hilo";
1782
    TCGv t0 = tcg_temp_local_new();
1783

    
1784
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1785
        /* Treat as NOP. */
1786
        MIPS_DEBUG("NOP");
1787
        goto out;
1788
    }
1789
    switch (opc) {
1790
    case OPC_MFHI:
1791
        tcg_gen_mov_tl(t0, cpu_HI[0]);
1792
        gen_store_gpr(t0, reg);
1793
        opn = "mfhi";
1794
        break;
1795
    case OPC_MFLO:
1796
        tcg_gen_mov_tl(t0, cpu_LO[0]);
1797
        gen_store_gpr(t0, reg);
1798
        opn = "mflo";
1799
        break;
1800
    case OPC_MTHI:
1801
        gen_load_gpr(t0, reg);
1802
        tcg_gen_mov_tl(cpu_HI[0], t0);
1803
        opn = "mthi";
1804
        break;
1805
    case OPC_MTLO:
1806
        gen_load_gpr(t0, reg);
1807
        tcg_gen_mov_tl(cpu_LO[0], t0);
1808
        opn = "mtlo";
1809
        break;
1810
    default:
1811
        MIPS_INVAL(opn);
1812
        generate_exception(ctx, EXCP_RI);
1813
        goto out;
1814
    }
1815
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1816
 out:
1817
    tcg_temp_free(t0);
1818
}
1819

    
1820
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1821
                        int rs, int rt)
1822
{
1823
    const char *opn = "mul/div";
1824
    TCGv t0 = tcg_temp_local_new();
1825
    TCGv t1 = tcg_temp_local_new();
1826

    
1827
    gen_load_gpr(t0, rs);
1828
    gen_load_gpr(t1, rt);
1829
    switch (opc) {
1830
    case OPC_DIV:
1831
        {
1832
            int l1 = gen_new_label();
1833

    
1834
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1835
            {
1836
                int l2 = gen_new_label();
1837
                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1838
                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1839
                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1840

    
1841
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1842
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1843
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1844
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1845
                tcg_gen_ext32s_tl(cpu_LO[0], t0);
1846
                tcg_gen_movi_tl(cpu_HI[0], 0);
1847
                tcg_gen_br(l1);
1848
                gen_set_label(l2);
1849
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1850
                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1851
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1852
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1853
                tcg_temp_free_i32(r_tmp1);
1854
                tcg_temp_free_i32(r_tmp2);
1855
                tcg_temp_free_i32(r_tmp3);
1856
            }
1857
            gen_set_label(l1);
1858
        }
1859
        opn = "div";
1860
        break;
1861
    case OPC_DIVU:
1862
        {
1863
            int l1 = gen_new_label();
1864

    
1865
            tcg_gen_ext32s_tl(t1, t1);
1866
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1867
            {
1868
                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1869
                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1870
                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1871

    
1872
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1873
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1874
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1875
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1876
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1877
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1878
                tcg_temp_free_i32(r_tmp1);
1879
                tcg_temp_free_i32(r_tmp2);
1880
                tcg_temp_free_i32(r_tmp3);
1881
            }
1882
            gen_set_label(l1);
1883
        }
1884
        opn = "divu";
1885
        break;
1886
    case OPC_MULT:
1887
        {
1888
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1889
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1890

    
1891
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1892
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1893
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1894
            tcg_temp_free_i64(r_tmp2);
1895
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1896
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1897
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1898
            tcg_temp_free_i64(r_tmp1);
1899
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1900
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1901
        }
1902
        opn = "mult";
1903
        break;
1904
    case OPC_MULTU:
1905
        {
1906
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1907
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1908

    
1909
            tcg_gen_ext32u_tl(t0, t0);
1910
            tcg_gen_ext32u_tl(t1, t1);
1911
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1912
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1913
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1914
            tcg_temp_free_i64(r_tmp2);
1915
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1916
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1917
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1918
            tcg_temp_free_i64(r_tmp1);
1919
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1920
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1921
        }
1922
        opn = "multu";
1923
        break;
1924
#if defined(TARGET_MIPS64)
1925
    case OPC_DDIV:
1926
        {
1927
            int l1 = gen_new_label();
1928

    
1929
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1930
            {
1931
                int l2 = gen_new_label();
1932

    
1933
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1934
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1935
                tcg_gen_mov_tl(cpu_LO[0], t0);
1936
                tcg_gen_movi_tl(cpu_HI[0], 0);
1937
                tcg_gen_br(l1);
1938
                gen_set_label(l2);
1939
                tcg_gen_div_i64(cpu_LO[0], t0, t1);
1940
                tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1941
            }
1942
            gen_set_label(l1);
1943
        }
1944
        opn = "ddiv";
1945
        break;
1946
    case OPC_DDIVU:
1947
        {
1948
            int l1 = gen_new_label();
1949

    
1950
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1951
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1952
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1953
            gen_set_label(l1);
1954
        }
1955
        opn = "ddivu";
1956
        break;
1957
    case OPC_DMULT:
1958
        gen_helper_dmult(t0, t1);
1959
        opn = "dmult";
1960
        break;
1961
    case OPC_DMULTU:
1962
        gen_helper_dmultu(t0, t1);
1963
        opn = "dmultu";
1964
        break;
1965
#endif
1966
    case OPC_MADD:
1967
        {
1968
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1969
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1970

    
1971
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1972
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1973
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1974
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1975
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1976
            tcg_temp_free_i64(r_tmp2);
1977
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1978
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1979
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1980
            tcg_temp_free_i64(r_tmp1);
1981
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1982
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1983
        }
1984
        opn = "madd";
1985
        break;
1986
    case OPC_MADDU:
1987
       {
1988
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1989
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1990

    
1991
            tcg_gen_ext32u_tl(t0, t0);
1992
            tcg_gen_ext32u_tl(t1, t1);
1993
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1994
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1995
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1996
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1997
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1998
            tcg_temp_free_i64(r_tmp2);
1999
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2000
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2001
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2002
            tcg_temp_free_i64(r_tmp1);
2003
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2004
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2005
        }
2006
        opn = "maddu";
2007
        break;
2008
    case OPC_MSUB:
2009
        {
2010
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2011
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2012

    
2013
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2014
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2015
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2016
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2017
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2018
            tcg_temp_free_i64(r_tmp2);
2019
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2020
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2021
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2022
            tcg_temp_free_i64(r_tmp1);
2023
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2024
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2025
        }
2026
        opn = "msub";
2027
        break;
2028
    case OPC_MSUBU:
2029
        {
2030
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2031
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2032

    
2033
            tcg_gen_ext32u_tl(t0, t0);
2034
            tcg_gen_ext32u_tl(t1, t1);
2035
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2036
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2037
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2038
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2039
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2040
            tcg_temp_free_i64(r_tmp2);
2041
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2042
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2043
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2044
            tcg_temp_free_i64(r_tmp1);
2045
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2046
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2047
        }
2048
        opn = "msubu";
2049
        break;
2050
    default:
2051
        MIPS_INVAL(opn);
2052
        generate_exception(ctx, EXCP_RI);
2053
        goto out;
2054
    }
2055
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2056
 out:
2057
    tcg_temp_free(t0);
2058
    tcg_temp_free(t1);
2059
}
2060

    
2061
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2062
                            int rd, int rs, int rt)
2063
{
2064
    const char *opn = "mul vr54xx";
2065
    TCGv t0 = tcg_temp_local_new();
2066
    TCGv t1 = tcg_temp_local_new();
2067

    
2068
    gen_load_gpr(t0, rs);
2069
    gen_load_gpr(t1, rt);
2070

    
2071
    switch (opc) {
2072
    case OPC_VR54XX_MULS:
2073
        gen_helper_muls(t0, t0, t1);
2074
        opn = "muls";
2075
        break;
2076
    case OPC_VR54XX_MULSU:
2077
        gen_helper_mulsu(t0, t0, t1);
2078
        opn = "mulsu";
2079
        break;
2080
    case OPC_VR54XX_MACC:
2081
        gen_helper_macc(t0, t0, t1);
2082
        opn = "macc";
2083
        break;
2084
    case OPC_VR54XX_MACCU:
2085
        gen_helper_maccu(t0, t0, t1);
2086
        opn = "maccu";
2087
        break;
2088
    case OPC_VR54XX_MSAC:
2089
        gen_helper_msac(t0, t0, t1);
2090
        opn = "msac";
2091
        break;
2092
    case OPC_VR54XX_MSACU:
2093
        gen_helper_msacu(t0, t0, t1);
2094
        opn = "msacu";
2095
        break;
2096
    case OPC_VR54XX_MULHI:
2097
        gen_helper_mulhi(t0, t0, t1);
2098
        opn = "mulhi";
2099
        break;
2100
    case OPC_VR54XX_MULHIU:
2101
        gen_helper_mulhiu(t0, t0, t1);
2102
        opn = "mulhiu";
2103
        break;
2104
    case OPC_VR54XX_MULSHI:
2105
        gen_helper_mulshi(t0, t0, t1);
2106
        opn = "mulshi";
2107
        break;
2108
    case OPC_VR54XX_MULSHIU:
2109
        gen_helper_mulshiu(t0, t0, t1);
2110
        opn = "mulshiu";
2111
        break;
2112
    case OPC_VR54XX_MACCHI:
2113
        gen_helper_macchi(t0, t0, t1);
2114
        opn = "macchi";
2115
        break;
2116
    case OPC_VR54XX_MACCHIU:
2117
        gen_helper_macchiu(t0, t0, t1);
2118
        opn = "macchiu";
2119
        break;
2120
    case OPC_VR54XX_MSACHI:
2121
        gen_helper_msachi(t0, t0, t1);
2122
        opn = "msachi";
2123
        break;
2124
    case OPC_VR54XX_MSACHIU:
2125
        gen_helper_msachiu(t0, t0, t1);
2126
        opn = "msachiu";
2127
        break;
2128
    default:
2129
        MIPS_INVAL("mul vr54xx");
2130
        generate_exception(ctx, EXCP_RI);
2131
        goto out;
2132
    }
2133
    gen_store_gpr(t0, rd);
2134
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2135

    
2136
 out:
2137
    tcg_temp_free(t0);
2138
    tcg_temp_free(t1);
2139
}
2140

    
2141
static void gen_cl (DisasContext *ctx, uint32_t opc,
2142
                    int rd, int rs)
2143
{
2144
    const char *opn = "CLx";
2145
    TCGv t0 = tcg_temp_local_new();
2146

    
2147
    if (rd == 0) {
2148
        /* Treat as NOP. */
2149
        MIPS_DEBUG("NOP");
2150
        goto out;
2151
    }
2152
    gen_load_gpr(t0, rs);
2153
    switch (opc) {
2154
    case OPC_CLO:
2155
        gen_helper_clo(t0, t0);
2156
        opn = "clo";
2157
        break;
2158
    case OPC_CLZ:
2159
        gen_helper_clz(t0, t0);
2160
        opn = "clz";
2161
        break;
2162
#if defined(TARGET_MIPS64)
2163
    case OPC_DCLO:
2164
        gen_helper_dclo(t0, t0);
2165
        opn = "dclo";
2166
        break;
2167
    case OPC_DCLZ:
2168
        gen_helper_dclz(t0, t0);
2169
        opn = "dclz";
2170
        break;
2171
#endif
2172
    default:
2173
        MIPS_INVAL(opn);
2174
        generate_exception(ctx, EXCP_RI);
2175
        goto out;
2176
    }
2177
    gen_store_gpr(t0, rd);
2178
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2179

    
2180
 out:
2181
    tcg_temp_free(t0);
2182
}
2183

    
2184
/* Traps */
2185
static void gen_trap (DisasContext *ctx, uint32_t opc,
2186
                      int rs, int rt, int16_t imm)
2187
{
2188
    int cond;
2189
    TCGv t0 = tcg_temp_local_new();
2190
    TCGv t1 = tcg_temp_local_new();
2191

    
2192
    cond = 0;
2193
    /* Load needed operands */
2194
    switch (opc) {
2195
    case OPC_TEQ:
2196
    case OPC_TGE:
2197
    case OPC_TGEU:
2198
    case OPC_TLT:
2199
    case OPC_TLTU:
2200
    case OPC_TNE:
2201
        /* Compare two registers */
2202
        if (rs != rt) {
2203
            gen_load_gpr(t0, rs);
2204
            gen_load_gpr(t1, rt);
2205
            cond = 1;
2206
        }
2207
        break;
2208
    case OPC_TEQI:
2209
    case OPC_TGEI:
2210
    case OPC_TGEIU:
2211
    case OPC_TLTI:
2212
    case OPC_TLTIU:
2213
    case OPC_TNEI:
2214
        /* Compare register to immediate */
2215
        if (rs != 0 || imm != 0) {
2216
            gen_load_gpr(t0, rs);
2217
            tcg_gen_movi_tl(t1, (int32_t)imm);
2218
            cond = 1;
2219
        }
2220
        break;
2221
    }
2222
    if (cond == 0) {
2223
        switch (opc) {
2224
        case OPC_TEQ:   /* rs == rs */
2225
        case OPC_TEQI:  /* r0 == 0  */
2226
        case OPC_TGE:   /* rs >= rs */
2227
        case OPC_TGEI:  /* r0 >= 0  */
2228
        case OPC_TGEU:  /* rs >= rs unsigned */
2229
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2230
            /* Always trap */
2231
            tcg_gen_movi_tl(t0, 1);
2232
            break;
2233
        case OPC_TLT:   /* rs < rs           */
2234
        case OPC_TLTI:  /* r0 < 0            */
2235
        case OPC_TLTU:  /* rs < rs unsigned  */
2236
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2237
        case OPC_TNE:   /* rs != rs          */
2238
        case OPC_TNEI:  /* r0 != 0           */
2239
            /* Never trap: treat as NOP. */
2240
            goto out;
2241
        default:
2242
            MIPS_INVAL("trap");
2243
            generate_exception(ctx, EXCP_RI);
2244
            goto out;
2245
        }
2246
    } else {
2247
        switch (opc) {
2248
        case OPC_TEQ:
2249
        case OPC_TEQI:
2250
            gen_op_eq(t0, t1);
2251
            break;
2252
        case OPC_TGE:
2253
        case OPC_TGEI:
2254
            gen_op_ge(t0, t1);
2255
            break;
2256
        case OPC_TGEU:
2257
        case OPC_TGEIU:
2258
            gen_op_geu(t0, t1);
2259
            break;
2260
        case OPC_TLT:
2261
        case OPC_TLTI:
2262
            gen_op_lt(t0, t1);
2263
            break;
2264
        case OPC_TLTU:
2265
        case OPC_TLTIU:
2266
            gen_op_ltu(t0, t1);
2267
            break;
2268
        case OPC_TNE:
2269
        case OPC_TNEI:
2270
            gen_op_ne(t0, t1);
2271
            break;
2272
        default:
2273
            MIPS_INVAL("trap");
2274
            generate_exception(ctx, EXCP_RI);
2275
            goto out;
2276
        }
2277
    }
2278
    save_cpu_state(ctx, 1);
2279
    {
2280
        int l1 = gen_new_label();
2281

    
2282
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2283
        gen_helper_0i(raise_exception, EXCP_TRAP);
2284
        gen_set_label(l1);
2285
    }
2286
    ctx->bstate = BS_STOP;
2287
 out:
2288
    tcg_temp_free(t0);
2289
    tcg_temp_free(t1);
2290
}
2291

    
2292
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2293
{
2294
    TranslationBlock *tb;
2295
    tb = ctx->tb;
2296
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2297
        tcg_gen_goto_tb(n);
2298
        gen_save_pc(dest);
2299
        tcg_gen_exit_tb((long)tb + n);
2300
    } else {
2301
        gen_save_pc(dest);
2302
        tcg_gen_exit_tb(0);
2303
    }
2304
}
2305

    
2306
/* Branches (before delay slot) */
2307
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2308
                                int rs, int rt, int32_t offset)
2309
{
2310
    target_ulong btgt = -1;
2311
    int blink = 0;
2312
    int bcond_compute = 0;
2313
    TCGv t0 = tcg_temp_local_new();
2314
    TCGv t1 = tcg_temp_local_new();
2315

    
2316
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2317
#ifdef MIPS_DEBUG_DISAS
2318
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2319
#endif
2320
        generate_exception(ctx, EXCP_RI);
2321
        goto out;
2322
    }
2323

    
2324
    /* Load needed operands */
2325
    switch (opc) {
2326
    case OPC_BEQ:
2327
    case OPC_BEQL:
2328
    case OPC_BNE:
2329
    case OPC_BNEL:
2330
        /* Compare two registers */
2331
        if (rs != rt) {
2332
            gen_load_gpr(t0, rs);
2333
            gen_load_gpr(t1, rt);
2334
            bcond_compute = 1;
2335
        }
2336
        btgt = ctx->pc + 4 + offset;
2337
        break;
2338
    case OPC_BGEZ:
2339
    case OPC_BGEZAL:
2340
    case OPC_BGEZALL:
2341
    case OPC_BGEZL:
2342
    case OPC_BGTZ:
2343
    case OPC_BGTZL:
2344
    case OPC_BLEZ:
2345
    case OPC_BLEZL:
2346
    case OPC_BLTZ:
2347
    case OPC_BLTZAL:
2348
    case OPC_BLTZALL:
2349
    case OPC_BLTZL:
2350
        /* Compare to zero */
2351
        if (rs != 0) {
2352
            gen_load_gpr(t0, rs);
2353
            bcond_compute = 1;
2354
        }
2355
        btgt = ctx->pc + 4 + offset;
2356
        break;
2357
    case OPC_J:
2358
    case OPC_JAL:
2359
        /* Jump to immediate */
2360
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2361
        break;
2362
    case OPC_JR:
2363
    case OPC_JALR:
2364
        /* Jump to register */
2365
        if (offset != 0 && offset != 16) {
2366
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2367
               others are reserved. */
2368
            MIPS_INVAL("jump hint");
2369
            generate_exception(ctx, EXCP_RI);
2370
            goto out;
2371
        }
2372
        gen_load_gpr(btarget, rs);
2373
        break;
2374
    default:
2375
        MIPS_INVAL("branch/jump");
2376
        generate_exception(ctx, EXCP_RI);
2377
        goto out;
2378
    }
2379
    if (bcond_compute == 0) {
2380
        /* No condition to be computed */
2381
        switch (opc) {
2382
        case OPC_BEQ:     /* rx == rx        */
2383
        case OPC_BEQL:    /* rx == rx likely */
2384
        case OPC_BGEZ:    /* 0 >= 0          */
2385
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2386
        case OPC_BLEZ:    /* 0 <= 0          */
2387
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2388
            /* Always take */
2389
            ctx->hflags |= MIPS_HFLAG_B;
2390
            MIPS_DEBUG("balways");
2391
            break;
2392
        case OPC_BGEZAL:  /* 0 >= 0          */
2393
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2394
            /* Always take and link */
2395
            blink = 31;
2396
            ctx->hflags |= MIPS_HFLAG_B;
2397
            MIPS_DEBUG("balways and link");
2398
            break;
2399
        case OPC_BNE:     /* rx != rx        */
2400
        case OPC_BGTZ:    /* 0 > 0           */
2401
        case OPC_BLTZ:    /* 0 < 0           */
2402
            /* Treat as NOP. */
2403
            MIPS_DEBUG("bnever (NOP)");
2404
            goto out;
2405
        case OPC_BLTZAL:  /* 0 < 0           */
2406
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2407
            gen_store_gpr(t0, 31);
2408
            MIPS_DEBUG("bnever and link");
2409
            goto out;
2410
        case OPC_BLTZALL: /* 0 < 0 likely */
2411
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2412
            gen_store_gpr(t0, 31);
2413
            /* Skip the instruction in the delay slot */
2414
            MIPS_DEBUG("bnever, link and skip");
2415
            ctx->pc += 4;
2416
            goto out;
2417
        case OPC_BNEL:    /* rx != rx likely */
2418
        case OPC_BGTZL:   /* 0 > 0 likely */
2419
        case OPC_BLTZL:   /* 0 < 0 likely */
2420
            /* Skip the instruction in the delay slot */
2421
            MIPS_DEBUG("bnever and skip");
2422
            ctx->pc += 4;
2423
            goto out;
2424
        case OPC_J:
2425
            ctx->hflags |= MIPS_HFLAG_B;
2426
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2427
            break;
2428
        case OPC_JAL:
2429
            blink = 31;
2430
            ctx->hflags |= MIPS_HFLAG_B;
2431
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2432
            break;
2433
        case OPC_JR:
2434
            ctx->hflags |= MIPS_HFLAG_BR;
2435
            MIPS_DEBUG("jr %s", regnames[rs]);
2436
            break;
2437
        case OPC_JALR:
2438
            blink = rt;
2439
            ctx->hflags |= MIPS_HFLAG_BR;
2440
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2441
            break;
2442
        default:
2443
            MIPS_INVAL("branch/jump");
2444
            generate_exception(ctx, EXCP_RI);
2445
            goto out;
2446
        }
2447
    } else {
2448
        switch (opc) {
2449
        case OPC_BEQ:
2450
            gen_op_eq(t0, t1);
2451
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2452
                       regnames[rs], regnames[rt], btgt);
2453
            goto not_likely;
2454
        case OPC_BEQL:
2455
            gen_op_eq(t0, t1);
2456
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2457
                       regnames[rs], regnames[rt], btgt);
2458
            goto likely;
2459
        case OPC_BNE:
2460
            gen_op_ne(t0, t1);
2461
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2462
                       regnames[rs], regnames[rt], btgt);
2463
            goto not_likely;
2464
        case OPC_BNEL:
2465
            gen_op_ne(t0, t1);
2466
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2467
                       regnames[rs], regnames[rt], btgt);
2468
            goto likely;
2469
        case OPC_BGEZ:
2470
            gen_op_gez(t0);
2471
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2472
            goto not_likely;
2473
        case OPC_BGEZL:
2474
            gen_op_gez(t0);
2475
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2476
            goto likely;
2477
        case OPC_BGEZAL:
2478
            gen_op_gez(t0);
2479
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2480
            blink = 31;
2481
            goto not_likely;
2482
        case OPC_BGEZALL:
2483
            gen_op_gez(t0);
2484
            blink = 31;
2485
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2486
            goto likely;
2487
        case OPC_BGTZ:
2488
            gen_op_gtz(t0);
2489
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2490
            goto not_likely;
2491
        case OPC_BGTZL:
2492
            gen_op_gtz(t0);
2493
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2494
            goto likely;
2495
        case OPC_BLEZ:
2496
            gen_op_lez(t0);
2497
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2498
            goto not_likely;
2499
        case OPC_BLEZL:
2500
            gen_op_lez(t0);
2501
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2502
            goto likely;
2503
        case OPC_BLTZ:
2504
            gen_op_ltz(t0);
2505
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2506
            goto not_likely;
2507
        case OPC_BLTZL:
2508
            gen_op_ltz(t0);
2509
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2510
            goto likely;
2511
        case OPC_BLTZAL:
2512
            gen_op_ltz(t0);
2513
            blink = 31;
2514
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2515
        not_likely:
2516
            ctx->hflags |= MIPS_HFLAG_BC;
2517
            tcg_gen_trunc_tl_i32(bcond, t0);
2518
            break;
2519
        case OPC_BLTZALL:
2520
            gen_op_ltz(t0);
2521
            blink = 31;
2522
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2523
        likely:
2524
            ctx->hflags |= MIPS_HFLAG_BL;
2525
            tcg_gen_trunc_tl_i32(bcond, t0);
2526
            break;
2527
        default:
2528
            MIPS_INVAL("conditional branch/jump");
2529
            generate_exception(ctx, EXCP_RI);
2530
            goto out;
2531
        }
2532
    }
2533
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2534
               blink, ctx->hflags, btgt);
2535

    
2536
    ctx->btarget = btgt;
2537
    if (blink > 0) {
2538
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2539
        gen_store_gpr(t0, blink);
2540
    }
2541

    
2542
 out:
2543
    tcg_temp_free(t0);
2544
    tcg_temp_free(t1);
2545
}
2546

    
2547
/* special3 bitfield operations */
2548
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2549
                        int rs, int lsb, int msb)
2550
{
2551
    TCGv t0 = tcg_temp_new();
2552
    TCGv t1 = tcg_temp_new();
2553
    target_ulong mask;
2554

    
2555
    gen_load_gpr(t1, rs);
2556
    switch (opc) {
2557
    case OPC_EXT:
2558
        if (lsb + msb > 31)
2559
            goto fail;
2560
        tcg_gen_shri_tl(t0, t1, lsb);
2561
        if (msb != 31) {
2562
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2563
        } else {
2564
            tcg_gen_ext32s_tl(t0, t0);
2565
        }
2566
        break;
2567
#if defined(TARGET_MIPS64)
2568
    case OPC_DEXTM:
2569
        tcg_gen_shri_tl(t0, t1, lsb);
2570
        if (msb != 31) {
2571
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2572
        }
2573
        break;
2574
    case OPC_DEXTU:
2575
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2576
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2577
        break;
2578
    case OPC_DEXT:
2579
        tcg_gen_shri_tl(t0, t1, lsb);
2580
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2581
        break;
2582
#endif
2583
    case OPC_INS:
2584
        if (lsb > msb)
2585
            goto fail;
2586
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2587
        gen_load_gpr(t0, rt);
2588
        tcg_gen_andi_tl(t0, t0, ~mask);
2589
        tcg_gen_shli_tl(t1, t1, lsb);
2590
        tcg_gen_andi_tl(t1, t1, mask);
2591
        tcg_gen_or_tl(t0, t0, t1);
2592
        tcg_gen_ext32s_tl(t0, t0);
2593
        break;
2594
#if defined(TARGET_MIPS64)
2595
    case OPC_DINSM:
2596
        if (lsb > msb)
2597
            goto fail;
2598
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2599
        gen_load_gpr(t0, rt);
2600
        tcg_gen_andi_tl(t0, t0, ~mask);
2601
        tcg_gen_shli_tl(t1, t1, lsb);
2602
        tcg_gen_andi_tl(t1, t1, mask);
2603
        tcg_gen_or_tl(t0, t0, t1);
2604
        break;
2605
    case OPC_DINSU:
2606
        if (lsb > msb)
2607
            goto fail;
2608
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2609
        gen_load_gpr(t0, rt);
2610
        tcg_gen_andi_tl(t0, t0, ~mask);
2611
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2612
        tcg_gen_andi_tl(t1, t1, mask);
2613
        tcg_gen_or_tl(t0, t0, t1);
2614
        break;
2615
    case OPC_DINS:
2616
        if (lsb > msb)
2617
            goto fail;
2618
        gen_load_gpr(t0, rt);
2619
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2620
        gen_load_gpr(t0, rt);
2621
        tcg_gen_andi_tl(t0, t0, ~mask);
2622
        tcg_gen_shli_tl(t1, t1, lsb);
2623
        tcg_gen_andi_tl(t1, t1, mask);
2624
        tcg_gen_or_tl(t0, t0, t1);
2625
        break;
2626
#endif
2627
    default:
2628
fail:
2629
        MIPS_INVAL("bitops");
2630
        generate_exception(ctx, EXCP_RI);
2631
        tcg_temp_free(t0);
2632
        tcg_temp_free(t1);
2633
        return;
2634
    }
2635
    gen_store_gpr(t0, rt);
2636
    tcg_temp_free(t0);
2637
    tcg_temp_free(t1);
2638
}
2639

    
2640
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2641
{
2642
    TCGv t0 = tcg_temp_new();
2643
    TCGv t1 = tcg_temp_new();
2644

    
2645
    gen_load_gpr(t1, rt);
2646
    switch (op2) {
2647
    case OPC_WSBH:
2648
        tcg_gen_shri_tl(t0, t1, 8);
2649
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
2650
        tcg_gen_shli_tl(t1, t1, 8);
2651
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
2652
        tcg_gen_or_tl(t0, t0, t1);
2653
        tcg_gen_ext32s_tl(t0, t0);
2654
        break;
2655
    case OPC_SEB:
2656
        tcg_gen_ext8s_tl(t0, t1);
2657
        break;
2658
    case OPC_SEH:
2659
        tcg_gen_ext16s_tl(t0, t1);
2660
        break;
2661
#if defined(TARGET_MIPS64)
2662
    case OPC_DSBH:
2663
        gen_load_gpr(t1, rt);
2664
        tcg_gen_shri_tl(t0, t1, 8);
2665
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
2666
        tcg_gen_shli_tl(t1, t1, 8);
2667
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
2668
        tcg_gen_or_tl(t0, t0, t1);
2669
        break;
2670
    case OPC_DSHD:
2671
        gen_load_gpr(t1, rt);
2672
        tcg_gen_shri_tl(t0, t1, 16);
2673
        tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
2674
        tcg_gen_shli_tl(t1, t1, 16);
2675
        tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
2676
        tcg_gen_or_tl(t1, t0, t1);
2677
        tcg_gen_shri_tl(t0, t1, 32);
2678
        tcg_gen_shli_tl(t1, t1, 32);
2679
        tcg_gen_or_tl(t0, t0, t1);
2680
        break;
2681
#endif
2682
    default:
2683
        MIPS_INVAL("bsfhl");
2684
        generate_exception(ctx, EXCP_RI);
2685
        tcg_temp_free(t0);
2686
        tcg_temp_free(t1);
2687
        return;
2688
    }
2689
    gen_store_gpr(t0, rd);
2690
    tcg_temp_free(t0);
2691
    tcg_temp_free(t1);
2692
}
2693

    
2694
#ifndef CONFIG_USER_ONLY
2695
/* CP0 (MMU and control) */
2696
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2697
{
2698
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2699

    
2700
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2701
    tcg_gen_ext_i32_tl(t, r_tmp);
2702
    tcg_temp_free_i32(r_tmp);
2703
}
2704

    
2705
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2706
{
2707
    tcg_gen_ld_tl(t, cpu_env, off);
2708
    tcg_gen_ext32s_tl(t, t);
2709
}
2710

    
2711
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2712
{
2713
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2714

    
2715
    tcg_gen_trunc_tl_i32(r_tmp, t);
2716
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2717
    tcg_temp_free_i32(r_tmp);
2718
}
2719

    
2720
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2721
{
2722
    tcg_gen_ext32s_tl(t, t);
2723
    tcg_gen_st_tl(t, cpu_env, off);
2724
}
2725

    
2726
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2727
{
2728
    const char *rn = "invalid";
2729

    
2730
    if (sel != 0)
2731
        check_insn(env, ctx, ISA_MIPS32);
2732

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

    
3298
die:
3299
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3300
    generate_exception(ctx, EXCP_RI);
3301
}
3302

    
3303
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3304
{
3305
    const char *rn = "invalid";
3306

    
3307
    if (sel != 0)
3308
        check_insn(env, ctx, ISA_MIPS32);
3309

    
3310
    if (use_icount)
3311
        gen_io_start();
3312

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

    
3897
die:
3898
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3899
    generate_exception(ctx, EXCP_RI);
3900
}
3901

    
3902
#if defined(TARGET_MIPS64)
3903
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3904
{
3905
    const char *rn = "invalid";
3906

    
3907
    if (sel != 0)
3908
        check_insn(env, ctx, ISA_MIPS64);
3909

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

    
4464
die:
4465
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4466
    generate_exception(ctx, EXCP_RI);
4467
}
4468

    
4469
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4470
{
4471
    const char *rn = "invalid";
4472

    
4473
    if (sel != 0)
4474
        check_insn(env, ctx, ISA_MIPS64);
4475

    
4476
    if (use_icount)
4477
        gen_io_start();
4478

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

    
5050
die:
5051
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5052
    generate_exception(ctx, EXCP_RI);
5053
}
5054
#endif /* TARGET_MIPS64 */
5055

    
5056
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5057
                     int u, int sel, int h)
5058
{
5059
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5060
    TCGv t0 = tcg_temp_local_new();
5061

    
5062
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5063
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5064
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5065
        tcg_gen_movi_tl(t0, -1);
5066
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5067
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5068
        tcg_gen_movi_tl(t0, -1);
5069
    else if (u == 0) {
5070
        switch (rt) {
5071
        case 2:
5072
            switch (sel) {
5073
            case 1:
5074
                gen_helper_mftc0_tcstatus(t0);
5075
                break;
5076
            case 2:
5077
                gen_helper_mftc0_tcbind(t0);
5078
                break;
5079
            case 3:
5080
                gen_helper_mftc0_tcrestart(t0);
5081
                break;
5082
            case 4:
5083
                gen_helper_mftc0_tchalt(t0);
5084
                break;
5085
            case 5:
5086
                gen_helper_mftc0_tccontext(t0);
5087
                break;
5088
            case 6:
5089
                gen_helper_mftc0_tcschedule(t0);
5090
                break;
5091
            case 7:
5092
                gen_helper_mftc0_tcschefback(t0);
5093
                break;
5094
            default:
5095
                gen_mfc0(env, ctx, t0, rt, sel);
5096
                break;
5097
            }
5098
            break;
5099
        case 10:
5100
            switch (sel) {
5101
            case 0:
5102
                gen_helper_mftc0_entryhi(t0);
5103
                break;
5104
            default:
5105
                gen_mfc0(env, ctx, t0, rt, sel);
5106
                break;
5107
            }
5108
        case 12:
5109
            switch (sel) {
5110
            case 0:
5111
                gen_helper_mftc0_status(t0);
5112
                break;
5113
            default:
5114
                gen_mfc0(env, ctx, t0, rt, sel);
5115
                break;
5116
            }
5117
        case 23:
5118
            switch (sel) {
5119
            case 0:
5120
                gen_helper_mftc0_debug(t0);
5121
                break;
5122
            default:
5123
                gen_mfc0(env, ctx, t0, rt, sel);
5124
                break;
5125
            }
5126
            break;
5127
        default:
5128
            gen_mfc0(env, ctx, t0, rt, sel);
5129
        }
5130
    } else switch (sel) {
5131
    /* GPR registers. */
5132
    case 0:
5133
        gen_helper_1i(mftgpr, t0, rt);
5134
        break;
5135
    /* Auxiliary CPU registers */
5136
    case 1:
5137
        switch (rt) {
5138
        case 0:
5139
            gen_helper_1i(mftlo, t0, 0);
5140
            break;
5141
        case 1:
5142
            gen_helper_1i(mfthi, t0, 0);
5143
            break;
5144
        case 2:
5145
            gen_helper_1i(mftacx, t0, 0);
5146
            break;
5147
        case 4:
5148
            gen_helper_1i(mftlo, t0, 1);
5149
            break;
5150
        case 5:
5151
            gen_helper_1i(mfthi, t0, 1);
5152
            break;
5153
        case 6:
5154
            gen_helper_1i(mftacx, t0, 1);
5155
            break;
5156
        case 8:
5157
            gen_helper_1i(mftlo, t0, 2);
5158
            break;
5159
        case 9:
5160
            gen_helper_1i(mfthi, t0, 2);
5161
            break;
5162
        case 10:
5163
            gen_helper_1i(mftacx, t0, 2);
5164
            break;
5165
        case 12:
5166
            gen_helper_1i(mftlo, t0, 3);
5167
            break;
5168
        case 13:
5169
            gen_helper_1i(mfthi, t0, 3);
5170
            break;
5171
        case 14:
5172
            gen_helper_1i(mftacx, t0, 3);
5173
            break;
5174
        case 16:
5175
            gen_helper_mftdsp(t0);
5176
            break;
5177
        default:
5178
            goto die;
5179
        }
5180
        break;
5181
    /* Floating point (COP1). */
5182
    case 2:
5183
        /* XXX: For now we support only a single FPU context. */
5184
        if (h == 0) {
5185
            TCGv_i32 fp0 = tcg_temp_new_i32();
5186

    
5187
            gen_load_fpr32(fp0, rt);
5188
            tcg_gen_ext_i32_tl(t0, fp0);
5189
            tcg_temp_free_i32(fp0);
5190
        } else {
5191
            TCGv_i32 fp0 = tcg_temp_new_i32();
5192

    
5193
            gen_load_fpr32h(fp0, rt);
5194
            tcg_gen_ext_i32_tl(t0, fp0);
5195
            tcg_temp_free_i32(fp0);
5196
        }
5197
        break;
5198
    case 3:
5199
        /* XXX: For now we support only a single FPU context. */
5200
        gen_helper_1i(cfc1, t0, rt);
5201
        break;
5202
    /* COP2: Not implemented. */
5203
    case 4:
5204
    case 5:
5205
        /* fall through */
5206
    default:
5207
        goto die;
5208
    }
5209
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5210
    gen_store_gpr(t0, rd);
5211
    tcg_temp_free(t0);
5212
    return;
5213

    
5214
die:
5215
    tcg_temp_free(t0);
5216
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5217
    generate_exception(ctx, EXCP_RI);
5218
}
5219

    
5220
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5221
                     int u, int sel, int h)
5222
{
5223
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5224
    TCGv t0 = tcg_temp_local_new();
5225

    
5226
    gen_load_gpr(t0, rt);
5227
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5228
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5229
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5230
        /* NOP */ ;
5231
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5232
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5233
        /* NOP */ ;
5234
    else if (u == 0) {
5235
        switch (rd) {
5236
        case 2:
5237
            switch (sel) {
5238
            case 1:
5239
                gen_helper_mttc0_tcstatus(t0);
5240
                break;
5241
            case 2:
5242
                gen_helper_mttc0_tcbind(t0);
5243
                break;
5244
            case 3:
5245
                gen_helper_mttc0_tcrestart(t0);
5246
                break;
5247
            case 4:
5248
                gen_helper_mttc0_tchalt(t0);
5249
                break;
5250
            case 5:
5251
                gen_helper_mttc0_tccontext(t0);
5252
                break;
5253
            case 6:
5254
                gen_helper_mttc0_tcschedule(t0);
5255
                break;
5256
            case 7:
5257
                gen_helper_mttc0_tcschefback(t0);
5258
                break;
5259
            default:
5260
                gen_mtc0(env, ctx, t0, rd, sel);
5261
                break;
5262
            }
5263
            break;
5264
        case 10:
5265
            switch (sel) {
5266
            case 0:
5267
                gen_helper_mttc0_entryhi(t0);
5268
                break;
5269
            default:
5270
                gen_mtc0(env, ctx, t0, rd, sel);
5271
                break;
5272
            }
5273
        case 12:
5274
            switch (sel) {
5275
            case 0:
5276
                gen_helper_mttc0_status(t0);
5277
                break;
5278
            default:
5279
                gen_mtc0(env, ctx, t0, rd, sel);
5280
                break;
5281
            }
5282
        case 23:
5283
            switch (sel) {
5284
            case 0:
5285
                gen_helper_mttc0_debug(t0);
5286
                break;
5287
            default:
5288
                gen_mtc0(env, ctx, t0, rd, sel);
5289
                break;
5290
            }
5291
            break;
5292
        default:
5293
            gen_mtc0(env, ctx, t0, rd, sel);
5294
        }
5295
    } else switch (sel) {
5296
    /* GPR registers. */
5297
    case 0:
5298
        gen_helper_1i(mttgpr, t0, rd);
5299
        break;
5300
    /* Auxiliary CPU registers */
5301
    case 1:
5302
        switch (rd) {
5303
        case 0:
5304
            gen_helper_1i(mttlo, t0, 0);
5305
            break;
5306
        case 1:
5307
            gen_helper_1i(mtthi, t0, 0);
5308
            break;
5309
        case 2:
5310
            gen_helper_1i(mttacx, t0, 0);
5311
            break;
5312
        case 4:
5313
            gen_helper_1i(mttlo, t0, 1);
5314
            break;
5315
        case 5:
5316
            gen_helper_1i(mtthi, t0, 1);
5317
            break;
5318
        case 6:
5319
            gen_helper_1i(mttacx, t0, 1);
5320
            break;
5321
        case 8:
5322
            gen_helper_1i(mttlo, t0, 2);
5323
            break;
5324
        case 9:
5325
            gen_helper_1i(mtthi, t0, 2);
5326
            break;
5327
        case 10:
5328
            gen_helper_1i(mttacx, t0, 2);
5329
            break;
5330
        case 12:
5331
            gen_helper_1i(mttlo, t0, 3);
5332
            break;
5333
        case 13:
5334
            gen_helper_1i(mtthi, t0, 3);
5335
            break;
5336
        case 14:
5337
            gen_helper_1i(mttacx, t0, 3);
5338
            break;
5339
        case 16:
5340
            gen_helper_mttdsp(t0);
5341
            break;
5342
        default:
5343
            goto die;
5344
        }
5345
        break;
5346
    /* Floating point (COP1). */
5347
    case 2:
5348
        /* XXX: For now we support only a single FPU context. */
5349
        if (h == 0) {
5350
            TCGv_i32 fp0 = tcg_temp_new_i32();
5351

    
5352
            tcg_gen_trunc_tl_i32(fp0, t0);
5353
            gen_store_fpr32(fp0, rd);
5354
            tcg_temp_free_i32(fp0);
5355
        } else {
5356
            TCGv_i32 fp0 = tcg_temp_new_i32();
5357

    
5358
            tcg_gen_trunc_tl_i32(fp0, t0);
5359
            gen_store_fpr32h(fp0, rd);
5360
            tcg_temp_free_i32(fp0);
5361
        }
5362
        break;
5363
    case 3:
5364
        /* XXX: For now we support only a single FPU context. */
5365
        gen_helper_1i(ctc1, t0, rd);
5366
        break;
5367
    /* COP2: Not implemented. */
5368
    case 4:
5369
    case 5:
5370
        /* fall through */
5371
    default:
5372
        goto die;
5373
    }
5374
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5375
    tcg_temp_free(t0);
5376
    return;
5377

    
5378
die:
5379
    tcg_temp_free(t0);
5380
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5381
    generate_exception(ctx, EXCP_RI);
5382
}
5383

    
5384
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5385
{
5386
    const char *opn = "ldst";
5387

    
5388
    switch (opc) {
5389
    case OPC_MFC0:
5390
        if (rt == 0) {
5391
            /* Treat as NOP. */
5392
            return;
5393
        }
5394
        {
5395
            TCGv t0 = tcg_temp_local_new();
5396

    
5397
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5398
            gen_store_gpr(t0, rt);
5399
            tcg_temp_free(t0);
5400
        }
5401
        opn = "mfc0";
5402
        break;
5403
    case OPC_MTC0:
5404
        {
5405
            TCGv t0 = tcg_temp_local_new();
5406

    
5407
            gen_load_gpr(t0, rt);
5408
            save_cpu_state(ctx, 1);
5409
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5410
            tcg_temp_free(t0);
5411
        }
5412
        opn = "mtc0";
5413
        break;
5414
#if defined(TARGET_MIPS64)
5415
    case OPC_DMFC0:
5416
        check_insn(env, ctx, ISA_MIPS3);
5417
        if (rt == 0) {
5418
            /* Treat as NOP. */
5419
            return;
5420
        }
5421
        {
5422
            TCGv t0 = tcg_temp_local_new();
5423

    
5424
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5425
            gen_store_gpr(t0, rt);
5426
            tcg_temp_free(t0);
5427
        }
5428
        opn = "dmfc0";
5429
        break;
5430
    case OPC_DMTC0:
5431
        check_insn(env, ctx, ISA_MIPS3);
5432
        {
5433
            TCGv t0 = tcg_temp_local_new();
5434

    
5435
            gen_load_gpr(t0, rt);
5436
            save_cpu_state(ctx, 1);
5437
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5438
            tcg_temp_free(t0);
5439
        }
5440
        opn = "dmtc0";
5441
        break;
5442
#endif
5443
    case OPC_MFTR:
5444
        check_insn(env, ctx, ASE_MT);
5445
        if (rd == 0) {
5446
            /* Treat as NOP. */
5447
            return;
5448
        }
5449
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5450
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5451
        opn = "mftr";
5452
        break;
5453
    case OPC_MTTR:
5454
        check_insn(env, ctx, ASE_MT);
5455
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5456
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5457
        opn = "mttr";
5458
        break;
5459
    case OPC_TLBWI:
5460
        opn = "tlbwi";
5461
        if (!env->tlb->do_tlbwi)
5462
            goto die;
5463
        gen_helper_tlbwi();
5464
        break;
5465
    case OPC_TLBWR:
5466
        opn = "tlbwr";
5467
        if (!env->tlb->do_tlbwr)
5468
            goto die;
5469
        gen_helper_tlbwr();
5470
        break;
5471
    case OPC_TLBP:
5472
        opn = "tlbp";
5473
        if (!env->tlb->do_tlbp)
5474
            goto die;
5475
        gen_helper_tlbp();
5476
        break;
5477
    case OPC_TLBR:
5478
        opn = "tlbr";
5479
        if (!env->tlb->do_tlbr)
5480
            goto die;
5481
        gen_helper_tlbr();
5482
        break;
5483
    case OPC_ERET:
5484
        opn = "eret";
5485
        check_insn(env, ctx, ISA_MIPS2);
5486
        save_cpu_state(ctx, 1);
5487
        gen_helper_eret();
5488
        ctx->bstate = BS_EXCP;
5489
        break;
5490
    case OPC_DERET:
5491
        opn = "deret";
5492
        check_insn(env, ctx, ISA_MIPS32);
5493
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5494
            MIPS_INVAL(opn);
5495
            generate_exception(ctx, EXCP_RI);
5496
        } else {
5497
            save_cpu_state(ctx, 1);
5498
            gen_helper_deret();
5499
            ctx->bstate = BS_EXCP;
5500
        }
5501
        break;
5502
    case OPC_WAIT:
5503
        opn = "wait";
5504
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5505
        /* If we get an exception, we want to restart at next instruction */
5506
        ctx->pc += 4;
5507
        save_cpu_state(ctx, 1);
5508
        ctx->pc -= 4;
5509
        gen_helper_wait();
5510
        ctx->bstate = BS_EXCP;
5511
        break;
5512
    default:
5513
 die:
5514
        MIPS_INVAL(opn);
5515
        generate_exception(ctx, EXCP_RI);
5516
        return;
5517
    }
5518
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5519
}
5520
#endif /* !CONFIG_USER_ONLY */
5521

    
5522
/* CP1 Branches (before delay slot) */
5523
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5524
                                 int32_t cc, int32_t offset)
5525
{
5526
    target_ulong btarget;
5527
    const char *opn = "cp1 cond branch";
5528
    TCGv_i32 t0 = tcg_temp_new_i32();
5529

    
5530
    if (cc != 0)
5531
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5532

    
5533
    btarget = ctx->pc + 4 + offset;
5534

    
5535
    switch (op) {
5536
    case OPC_BC1F:
5537
        {
5538
            int l1 = gen_new_label();
5539
            int l2 = gen_new_label();
5540

    
5541
            get_fp_cond(t0);
5542
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5543
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5544
            tcg_gen_movi_i32(bcond, 0);
5545
            tcg_gen_br(l2);
5546
            gen_set_label(l1);
5547
            tcg_gen_movi_i32(bcond, 1);
5548
            gen_set_label(l2);
5549
        }
5550
        opn = "bc1f";
5551
        goto not_likely;
5552
    case OPC_BC1FL:
5553
        {
5554
            int l1 = gen_new_label();
5555
            int l2 = gen_new_label();
5556

    
5557
            get_fp_cond(t0);
5558
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5559
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5560
            tcg_gen_movi_i32(bcond, 0);
5561
            tcg_gen_br(l2);
5562
            gen_set_label(l1);
5563
            tcg_gen_movi_i32(bcond, 1);
5564
            gen_set_label(l2);
5565
        }
5566
        opn = "bc1fl";
5567
        goto likely;
5568
    case OPC_BC1T:
5569
        {
5570
            int l1 = gen_new_label();
5571
            int l2 = gen_new_label();
5572

    
5573
            get_fp_cond(t0);
5574
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5575
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5576
            tcg_gen_movi_i32(bcond, 0);
5577
            tcg_gen_br(l2);
5578
            gen_set_label(l1);
5579
            tcg_gen_movi_i32(bcond, 1);
5580
            gen_set_label(l2);
5581
        }
5582
        opn = "bc1t";
5583
        goto not_likely;
5584
    case OPC_BC1TL:
5585
        {
5586
            int l1 = gen_new_label();
5587
            int l2 = gen_new_label();
5588

    
5589
            get_fp_cond(t0);
5590
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5591
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5592
            tcg_gen_movi_i32(bcond, 0);
5593
            tcg_gen_br(l2);
5594
            gen_set_label(l1);
5595
            tcg_gen_movi_i32(bcond, 1);
5596
            gen_set_label(l2);
5597
        }
5598
        opn = "bc1tl";
5599
    likely:
5600
        ctx->hflags |= MIPS_HFLAG_BL;
5601
        break;
5602
    case OPC_BC1FANY2:
5603
        {
5604
            int l1 = gen_new_label();
5605
            int l2 = gen_new_label();
5606

    
5607
            get_fp_cond(t0);
5608
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5609
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5610
            tcg_gen_movi_i32(bcond, 0);
5611
            tcg_gen_br(l2);
5612
            gen_set_label(l1);
5613
            tcg_gen_movi_i32(bcond, 1);
5614
            gen_set_label(l2);
5615
        }
5616
        opn = "bc1any2f";
5617
        goto not_likely;
5618
    case OPC_BC1TANY2:
5619
        {
5620
            int l1 = gen_new_label();
5621
            int l2 = gen_new_label();
5622

    
5623
            get_fp_cond(t0);
5624
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5625
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5626
            tcg_gen_movi_i32(bcond, 0);
5627
            tcg_gen_br(l2);
5628
            gen_set_label(l1);
5629
            tcg_gen_movi_i32(bcond, 1);
5630
            gen_set_label(l2);
5631
        }
5632
        opn = "bc1any2t";
5633
        goto not_likely;
5634
    case OPC_BC1FANY4:
5635
        {
5636
            int l1 = gen_new_label();
5637
            int l2 = gen_new_label();
5638

    
5639
            get_fp_cond(t0);
5640
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5641
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5642
            tcg_gen_movi_i32(bcond, 0);
5643
            tcg_gen_br(l2);
5644
            gen_set_label(l1);
5645
            tcg_gen_movi_i32(bcond, 1);
5646
            gen_set_label(l2);
5647
        }
5648
        opn = "bc1any4f";
5649
        goto not_likely;
5650
    case OPC_BC1TANY4:
5651
        {
5652
            int l1 = gen_new_label();
5653
            int l2 = gen_new_label();
5654

    
5655
            get_fp_cond(t0);
5656
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5657
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5658
            tcg_gen_movi_i32(bcond, 0);
5659
            tcg_gen_br(l2);
5660
            gen_set_label(l1);
5661
            tcg_gen_movi_i32(bcond, 1);
5662
            gen_set_label(l2);
5663
        }
5664
        opn = "bc1any4t";
5665
    not_likely:
5666
        ctx->hflags |= MIPS_HFLAG_BC;
5667
        break;
5668
    default:
5669
        MIPS_INVAL(opn);
5670
        generate_exception (ctx, EXCP_RI);
5671
        goto out;
5672
    }
5673
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5674
               ctx->hflags, btarget);
5675
    ctx->btarget = btarget;
5676

    
5677
 out:
5678
    tcg_temp_free_i32(t0);
5679
}
5680

    
5681
/* Coprocessor 1 (FPU) */
5682

    
5683
#define FOP(func, fmt) (((fmt) << 21) | (func))
5684

    
5685
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5686
{
5687
    const char *opn = "cp1 move";
5688
    TCGv t0 = tcg_temp_local_new();
5689

    
5690
    switch (opc) {
5691
    case OPC_MFC1:
5692
        {
5693
            TCGv_i32 fp0 = tcg_temp_new_i32();
5694

    
5695
            gen_load_fpr32(fp0, fs);
5696
            tcg_gen_ext_i32_tl(t0, fp0);
5697
            tcg_temp_free_i32(fp0);
5698
        }
5699
        gen_store_gpr(t0, rt);
5700
        opn = "mfc1";
5701
        break;
5702
    case OPC_MTC1:
5703
        gen_load_gpr(t0, rt);
5704
        {
5705
            TCGv_i32 fp0 = tcg_temp_new_i32();
5706

    
5707
            tcg_gen_trunc_tl_i32(fp0, t0);
5708
            gen_store_fpr32(fp0, fs);
5709
            tcg_temp_free_i32(fp0);
5710
        }
5711
        opn = "mtc1";
5712
        break;
5713
    case OPC_CFC1:
5714
        gen_helper_1i(cfc1, t0, fs);
5715
        gen_store_gpr(t0, rt);
5716
        opn = "cfc1";
5717
        break;
5718
    case OPC_CTC1:
5719
        gen_load_gpr(t0, rt);
5720
        gen_helper_1i(ctc1, t0, fs);
5721
        opn = "ctc1";
5722
        break;
5723
    case OPC_DMFC1:
5724
        {
5725
            TCGv_i64 fp0 = tcg_temp_new_i64();
5726

    
5727
            gen_load_fpr64(ctx, fp0, fs);
5728
            tcg_gen_trunc_i64_tl(t0, fp0);
5729
            tcg_temp_free_i64(fp0);
5730
        }
5731
        gen_store_gpr(t0, rt);
5732
        opn = "dmfc1";
5733
        break;
5734
    case OPC_DMTC1:
5735
        gen_load_gpr(t0, rt);
5736
        {
5737
            TCGv_i64 fp0 = tcg_temp_new_i64();
5738

    
5739
            tcg_gen_extu_tl_i64(fp0, t0);
5740
            gen_store_fpr64(ctx, fp0, fs);
5741
            tcg_temp_free_i64(fp0);
5742
        }
5743
        opn = "dmtc1";
5744
        break;
5745
    case OPC_MFHC1:
5746
        {
5747
            TCGv_i32 fp0 = tcg_temp_new_i32();
5748

    
5749
            gen_load_fpr32h(fp0, fs);
5750
            tcg_gen_ext_i32_tl(t0, fp0);
5751
            tcg_temp_free_i32(fp0);
5752
        }
5753
        gen_store_gpr(t0, rt);
5754
        opn = "mfhc1";
5755
        break;
5756
    case OPC_MTHC1:
5757
        gen_load_gpr(t0, rt);
5758
        {
5759
            TCGv_i32 fp0 = tcg_temp_new_i32();
5760

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

    
5774
 out:
5775
    tcg_temp_free(t0);
5776
}
5777

    
5778
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5779
{
5780
    int l1 = gen_new_label();
5781
    uint32_t ccbit;
5782
    TCGCond cond;
5783
    TCGv t0 = tcg_temp_local_new();
5784
    TCGv_i32 r_tmp = tcg_temp_new_i32();
5785

    
5786
    if (cc)
5787
        ccbit = 1 << (24 + cc);
5788
    else
5789
        ccbit = 1 << 23;
5790
    if (tf)
5791
        cond = TCG_COND_EQ;
5792
    else
5793
        cond = TCG_COND_NE;
5794

    
5795
    gen_load_gpr(t0, rd);
5796
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5797
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5798
    tcg_temp_free_i32(r_tmp);
5799
    gen_load_gpr(t0, rs);
5800
    gen_set_label(l1);
5801
    gen_store_gpr(t0, rd);
5802
    tcg_temp_free(t0);
5803
}
5804

    
5805
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5806
{
5807
    uint32_t ccbit;
5808
    int cond;
5809
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5810
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5811
    int l1 = gen_new_label();
5812

    
5813
    if (cc)
5814
        ccbit = 1 << (24 + cc);
5815
    else
5816
        ccbit = 1 << 23;
5817

    
5818
    if (tf)
5819
        cond = TCG_COND_EQ;
5820
    else
5821
        cond = TCG_COND_NE;
5822

    
5823
    gen_load_fpr32(fp0, fd);
5824
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5825
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5826
    tcg_temp_free_i32(r_tmp1);
5827
    gen_load_fpr32(fp0, fs);
5828
    gen_set_label(l1);
5829
    gen_store_fpr32(fp0, fd);
5830
    tcg_temp_free_i32(fp0);
5831
}
5832

    
5833
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5834
{
5835
    uint32_t ccbit;
5836
    int cond;
5837
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5838
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5839
    int l1 = gen_new_label();
5840

    
5841
    if (cc)
5842
        ccbit = 1 << (24 + cc);
5843
    else
5844
        ccbit = 1 << 23;
5845

    
5846
    if (tf)
5847
        cond = TCG_COND_EQ;
5848
    else
5849
        cond = TCG_COND_NE;
5850

    
5851
    gen_load_fpr64(ctx, fp0, fd);
5852
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5853
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5854
    tcg_temp_free_i32(r_tmp1);
5855
    gen_load_fpr64(ctx, fp0, fs);
5856
    gen_set_label(l1);
5857
    gen_store_fpr64(ctx, fp0, fd);
5858
    tcg_temp_free_i64(fp0);
5859
}
5860

    
5861
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5862
{
5863
    uint32_t ccbit1, ccbit2;
5864
    int cond;
5865
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5866
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5867
    int l1 = gen_new_label();
5868
    int l2 = gen_new_label();
5869

    
5870
    if (cc) {
5871
        ccbit1 = 1 << (24 + cc);
5872
        ccbit2 = 1 << (25 + cc);
5873
    } else {
5874
        ccbit1 = 1 << 23;
5875
        ccbit2 = 1 << 25;
5876
    }
5877

    
5878
    if (tf)
5879
        cond = TCG_COND_EQ;
5880
    else
5881
        cond = TCG_COND_NE;
5882

    
5883
    gen_load_fpr32(fp0, fd);
5884
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5885
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5886
    gen_load_fpr32(fp0, fs);
5887
    gen_set_label(l1);
5888
    gen_store_fpr32(fp0, fd);
5889

    
5890
    gen_load_fpr32h(fp0, fd);
5891
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5892
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5893
    gen_load_fpr32h(fp0, fs);
5894
    gen_set_label(l2);
5895
    gen_store_fpr32h(fp0, fd);
5896

    
5897
    tcg_temp_free_i32(r_tmp1);
5898
    tcg_temp_free_i32(fp0);
5899
}
5900

    
5901

    
5902
static void gen_farith (DisasContext *ctx, uint32_t op1,
5903
                        int ft, int fs, int fd, int cc)
5904
{
5905
    const char *opn = "farith";
5906
    const char *condnames[] = {
5907
            "c.f",
5908
            "c.un",
5909
            "c.eq",
5910
            "c.ueq",
5911
            "c.olt",
5912
            "c.ult",
5913
            "c.ole",
5914
            "c.ule",
5915
            "c.sf",
5916
            "c.ngle",
5917
            "c.seq",
5918
            "c.ngl",
5919
            "c.lt",
5920
            "c.nge",
5921
            "c.le",
5922
            "c.ngt",
5923
    };
5924
    const char *condnames_abs[] = {
5925
            "cabs.f",
5926
            "cabs.un",
5927
            "cabs.eq",
5928
            "cabs.ueq",
5929
            "cabs.olt",
5930
            "cabs.ult",
5931
            "cabs.ole",
5932
            "cabs.ule",
5933
            "cabs.sf",
5934
            "cabs.ngle",
5935
            "cabs.seq",
5936
            "cabs.ngl",
5937
            "cabs.lt",
5938
            "cabs.nge",
5939
            "cabs.le",
5940
            "cabs.ngt",
5941
    };
5942
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5943
    uint32_t func = ctx->opcode & 0x3f;
5944

    
5945
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5946
    case FOP(0, 16):
5947
        {
5948
            TCGv_i32 fp0 = tcg_temp_new_i32();
5949
            TCGv_i32 fp1 = tcg_temp_new_i32();
5950

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

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

    
5981
            gen_load_fpr32(fp0, fs);
5982
            gen_load_fpr32(fp1, ft);
5983
            gen_helper_float_mul_s(fp0, fp0, fp1);
5984
            tcg_temp_free_i32(fp1);
5985
            gen_store_fpr32(fp0, fd);
5986
            tcg_temp_free_i32(fp0);
5987
        }
5988
        opn = "mul.s";
5989
        optype = BINOP;
5990
        break;
5991
    case FOP(3, 16):
5992
        {
5993
            TCGv_i32 fp0 = tcg_temp_new_i32();
5994
            TCGv_i32 fp1 = tcg_temp_new_i32();
5995

    
5996
            gen_load_fpr32(fp0, fs);
5997
            gen_load_fpr32(fp1, ft);
5998
            gen_helper_float_div_s(fp0, fp0, fp1);
5999
            tcg_temp_free_i32(fp1);
6000
            gen_store_fpr32(fp0, fd);
6001
            tcg_temp_free_i32(fp0);
6002
        }
6003
        opn = "div.s";
6004
        optype = BINOP;
6005
        break;
6006
    case FOP(4, 16):
6007
        {
6008
            TCGv_i32 fp0 = tcg_temp_new_i32();
6009

    
6010
            gen_load_fpr32(fp0, fs);
6011
            gen_helper_float_sqrt_s(fp0, fp0);
6012
            gen_store_fpr32(fp0, fd);
6013
            tcg_temp_free_i32(fp0);
6014
        }
6015
        opn = "sqrt.s";
6016
        break;
6017
    case FOP(5, 16):
6018
        {
6019
            TCGv_i32 fp0 = tcg_temp_new_i32();
6020

    
6021
            gen_load_fpr32(fp0, fs);
6022
            gen_helper_float_abs_s(fp0, fp0);
6023
            gen_store_fpr32(fp0, fd);
6024
            tcg_temp_free_i32(fp0);
6025
        }
6026
        opn = "abs.s";
6027
        break;
6028
    case FOP(6, 16):
6029
        {
6030
            TCGv_i32 fp0 = tcg_temp_new_i32();
6031

    
6032
            gen_load_fpr32(fp0, fs);
6033
            gen_store_fpr32(fp0, fd);
6034
            tcg_temp_free_i32(fp0);
6035
        }
6036
        opn = "mov.s";
6037
        break;
6038
    case FOP(7, 16):
6039
        {
6040
            TCGv_i32 fp0 = tcg_temp_new_i32();
6041

    
6042
            gen_load_fpr32(fp0, fs);
6043
            gen_helper_float_chs_s(fp0, fp0);
6044
            gen_store_fpr32(fp0, fd);
6045
            tcg_temp_free_i32(fp0);
6046
        }
6047
        opn = "neg.s";
6048
        break;
6049
    case FOP(8, 16):
6050
        check_cp1_64bitmode(ctx);
6051
        {
6052
            TCGv_i32 fp32 = tcg_temp_new_i32();
6053
            TCGv_i64 fp64 = tcg_temp_new_i64();
6054

    
6055
            gen_load_fpr32(fp32, fs);
6056
            gen_helper_float_roundl_s(fp64, fp32);
6057
            tcg_temp_free_i32(fp32);
6058
            gen_store_fpr64(ctx, fp64, fd);
6059
            tcg_temp_free_i64(fp64);
6060
        }
6061
        opn = "round.l.s";
6062
        break;
6063
    case FOP(9, 16):
6064
        check_cp1_64bitmode(ctx);
6065
        {
6066
            TCGv_i32 fp32 = tcg_temp_new_i32();
6067
            TCGv_i64 fp64 = tcg_temp_new_i64();
6068

    
6069
            gen_load_fpr32(fp32, fs);
6070
            gen_helper_float_truncl_s(fp64, fp32);
6071
            tcg_temp_free_i32(fp32);
6072
            gen_store_fpr64(ctx, fp64, fd);
6073
            tcg_temp_free_i64(fp64);
6074
        }
6075
        opn = "trunc.l.s";
6076
        break;
6077
    case FOP(10, 16):
6078
        check_cp1_64bitmode(ctx);
6079
        {
6080
            TCGv_i32 fp32 = tcg_temp_new_i32();
6081
            TCGv_i64 fp64 = tcg_temp_new_i64();
6082

    
6083
            gen_load_fpr32(fp32, fs);
6084
            gen_helper_float_ceill_s(fp64, fp32);
6085
            tcg_temp_free_i32(fp32);
6086
            gen_store_fpr64(ctx, fp64, fd);
6087
            tcg_temp_free_i64(fp64);
6088
        }
6089
        opn = "ceil.l.s";
6090
        break;
6091
    case FOP(11, 16):
6092
        check_cp1_64bitmode(ctx);
6093
        {
6094
            TCGv_i32 fp32 = tcg_temp_new_i32();
6095
            TCGv_i64 fp64 = tcg_temp_new_i64();
6096

    
6097
            gen_load_fpr32(fp32, fs);
6098
            gen_helper_float_floorl_s(fp64, fp32);
6099
            tcg_temp_free_i32(fp32);
6100
            gen_store_fpr64(ctx, fp64, fd);
6101
            tcg_temp_free_i64(fp64);
6102
        }
6103
        opn = "floor.l.s";
6104
        break;
6105
    case FOP(12, 16):
6106
        {
6107
            TCGv_i32 fp0 = tcg_temp_new_i32();
6108

    
6109
            gen_load_fpr32(fp0, fs);
6110
            gen_helper_float_roundw_s(fp0, fp0);
6111
            gen_store_fpr32(fp0, fd);
6112
            tcg_temp_free_i32(fp0);
6113
        }
6114
        opn = "round.w.s";
6115
        break;
6116
    case FOP(13, 16):
6117
        {
6118
            TCGv_i32 fp0 = tcg_temp_new_i32();
6119

    
6120
            gen_load_fpr32(fp0, fs);
6121
            gen_helper_float_truncw_s(fp0, fp0);
6122
            gen_store_fpr32(fp0, fd);
6123
            tcg_temp_free_i32(fp0);
6124
        }
6125
        opn = "trunc.w.s";
6126
        break;
6127
    case FOP(14, 16):
6128
        {
6129
            TCGv_i32 fp0 = tcg_temp_new_i32();
6130

    
6131
            gen_load_fpr32(fp0, fs);
6132
            gen_helper_float_ceilw_s(fp0, fp0);
6133
            gen_store_fpr32(fp0, fd);
6134
            tcg_temp_free_i32(fp0);
6135
        }
6136
        opn = "ceil.w.s";
6137
        break;
6138
    case FOP(15, 16):
6139
        {
6140
            TCGv_i32 fp0 = tcg_temp_new_i32();
6141

    
6142
            gen_load_fpr32(fp0, fs);
6143
            gen_helper_float_floorw_s(fp0, fp0);
6144
            gen_store_fpr32(fp0, fd);
6145
            tcg_temp_free_i32(fp0);
6146
        }
6147
        opn = "floor.w.s";
6148
        break;
6149
    case FOP(17, 16):
6150
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6151
        opn = "movcf.s";
6152
        break;
6153
    case FOP(18, 16):
6154
        {
6155
            int l1 = gen_new_label();
6156
            TCGv t0 = tcg_temp_new();
6157
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6158

    
6159
            gen_load_gpr(t0, ft);
6160
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6161
            gen_load_fpr32(fp0, fs);
6162
            gen_store_fpr32(fp0, fd);
6163
            tcg_temp_free_i32(fp0);
6164
            gen_set_label(l1);
6165
            tcg_temp_free(t0);
6166
        }
6167
        opn = "movz.s";
6168
        break;
6169
    case FOP(19, 16):
6170
        {
6171
            int l1 = gen_new_label();
6172
            TCGv t0 = tcg_temp_new();
6173
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6174

    
6175
            gen_load_gpr(t0, ft);
6176
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6177
            gen_load_fpr32(fp0, fs);
6178
            gen_store_fpr32(fp0, fd);
6179
            tcg_temp_free_i32(fp0);
6180
            gen_set_label(l1);
6181
            tcg_temp_free(t0);
6182
        }
6183
        opn = "movn.s";
6184
        break;
6185
    case FOP(21, 16):
6186
        check_cop1x(ctx);
6187
        {
6188
            TCGv_i32 fp0 = tcg_temp_new_i32();
6189

    
6190
            gen_load_fpr32(fp0, fs);
6191
            gen_helper_float_recip_s(fp0, fp0);
6192
            gen_store_fpr32(fp0, fd);
6193
            tcg_temp_free_i32(fp0);
6194
        }
6195
        opn = "recip.s";
6196
        break;
6197
    case FOP(22, 16):
6198
        check_cop1x(ctx);
6199
        {
6200
            TCGv_i32 fp0 = tcg_temp_new_i32();
6201

    
6202
            gen_load_fpr32(fp0, fs);
6203
            gen_helper_float_rsqrt_s(fp0, fp0);
6204
            gen_store_fpr32(fp0, fd);
6205
            tcg_temp_free_i32(fp0);
6206
        }
6207
        opn = "rsqrt.s";
6208
        break;
6209
    case FOP(28, 16):
6210
        check_cp1_64bitmode(ctx);
6211
        {
6212
            TCGv_i32 fp0 = tcg_temp_new_i32();
6213
            TCGv_i32 fp1 = tcg_temp_new_i32();
6214

    
6215
            gen_load_fpr32(fp0, fs);
6216
            gen_load_fpr32(fp1, fd);
6217
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6218
            tcg_temp_free_i32(fp1);
6219
            gen_store_fpr32(fp0, fd);
6220
            tcg_temp_free_i32(fp0);
6221
        }
6222
        opn = "recip2.s";
6223
        break;
6224
    case FOP(29, 16):
6225
        check_cp1_64bitmode(ctx);
6226
        {
6227
            TCGv_i32 fp0 = tcg_temp_new_i32();
6228

    
6229
            gen_load_fpr32(fp0, fs);
6230
            gen_helper_float_recip1_s(fp0, fp0);
6231
            gen_store_fpr32(fp0, fd);
6232
            tcg_temp_free_i32(fp0);
6233
        }
6234
        opn = "recip1.s";
6235
        break;
6236
    case FOP(30, 16):
6237
        check_cp1_64bitmode(ctx);
6238
        {
6239
            TCGv_i32 fp0 = tcg_temp_new_i32();
6240

    
6241
            gen_load_fpr32(fp0, fs);
6242
            gen_helper_float_rsqrt1_s(fp0, fp0);
6243
            gen_store_fpr32(fp0, fd);
6244
            tcg_temp_free_i32(fp0);
6245
        }
6246
        opn = "rsqrt1.s";
6247
        break;
6248
    case FOP(31, 16):
6249
        check_cp1_64bitmode(ctx);
6250
        {
6251
            TCGv_i32 fp0 = tcg_temp_new_i32();
6252
            TCGv_i32 fp1 = tcg_temp_new_i32();
6253

    
6254
            gen_load_fpr32(fp0, fs);
6255
            gen_load_fpr32(fp1, ft);
6256
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6257
            tcg_temp_free_i32(fp1);
6258
            gen_store_fpr32(fp0, fd);
6259
            tcg_temp_free_i32(fp0);
6260
        }
6261
        opn = "rsqrt2.s";
6262
        break;
6263
    case FOP(33, 16):
6264
        check_cp1_registers(ctx, fd);
6265
        {
6266
            TCGv_i32 fp32 = tcg_temp_new_i32();
6267
            TCGv_i64 fp64 = tcg_temp_new_i64();
6268

    
6269
            gen_load_fpr32(fp32, fs);
6270
            gen_helper_float_cvtd_s(fp64, fp32);
6271
            tcg_temp_free_i32(fp32);
6272
            gen_store_fpr64(ctx, fp64, fd);
6273
            tcg_temp_free_i64(fp64);
6274
        }
6275
        opn = "cvt.d.s";
6276
        break;
6277
    case FOP(36, 16):
6278
        {
6279
            TCGv_i32 fp0 = tcg_temp_new_i32();
6280

    
6281
            gen_load_fpr32(fp0, fs);
6282
            gen_helper_float_cvtw_s(fp0, fp0);
6283
            gen_store_fpr32(fp0, fd);
6284
            tcg_temp_free_i32(fp0);
6285
        }
6286
        opn = "cvt.w.s";
6287
        break;
6288
    case FOP(37, 16):
6289
        check_cp1_64bitmode(ctx);
6290
        {
6291
            TCGv_i32 fp32 = tcg_temp_new_i32();
6292
            TCGv_i64 fp64 = tcg_temp_new_i64();
6293

    
6294
            gen_load_fpr32(fp32, fs);
6295
            gen_helper_float_cvtl_s(fp64, fp32);
6296
            tcg_temp_free_i32(fp32);
6297
            gen_store_fpr64(ctx, fp64, fd);
6298
            tcg_temp_free_i64(fp64);
6299
        }
6300
        opn = "cvt.l.s";
6301
        break;
6302
    case FOP(38, 16):
6303
        check_cp1_64bitmode(ctx);
6304
        {
6305
            TCGv_i64 fp64 = tcg_temp_new_i64();
6306
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6307
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6308

    
6309
            gen_load_fpr32(fp32_0, fs);
6310
            gen_load_fpr32(fp32_1, ft);
6311
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6312
            tcg_temp_free_i32(fp32_1);
6313
            tcg_temp_free_i32(fp32_0);
6314
            gen_store_fpr64(ctx, fp64, fd);
6315
            tcg_temp_free_i64(fp64);
6316
        }
6317
        opn = "cvt.ps.s";
6318
        break;
6319
    case FOP(48, 16):
6320
    case FOP(49, 16):
6321
    case FOP(50, 16):
6322
    case FOP(51, 16):
6323
    case FOP(52, 16):
6324
    case FOP(53, 16):
6325
    case FOP(54, 16):
6326
    case FOP(55, 16):
6327
    case FOP(56, 16):
6328
    case FOP(57, 16):
6329
    case FOP(58, 16):
6330
    case FOP(59, 16):
6331
    case FOP(60, 16):
6332
    case FOP(61, 16):
6333
    case FOP(62, 16):
6334
    case FOP(63, 16):
6335
        {
6336
            TCGv_i32 fp0 = tcg_temp_new_i32();
6337
            TCGv_i32 fp1 = tcg_temp_new_i32();
6338

    
6339
            gen_load_fpr32(fp0, fs);
6340
            gen_load_fpr32(fp1, ft);
6341
            if (ctx->opcode & (1 << 6)) {
6342
                check_cop1x(ctx);
6343
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6344
                opn = condnames_abs[func-48];
6345
            } else {
6346
                gen_cmp_s(func-48, fp0, fp1, cc);
6347
                opn = condnames[func-48];
6348
            }
6349
            tcg_temp_free_i32(fp0);
6350
            tcg_temp_free_i32(fp1);
6351
        }
6352
        break;
6353
    case FOP(0, 17):
6354
        check_cp1_registers(ctx, fs | ft | fd);
6355
        {
6356
            TCGv_i64 fp0 = tcg_temp_new_i64();
6357
            TCGv_i64 fp1 = tcg_temp_new_i64();
6358

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

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

    
6391
            gen_load_fpr64(ctx, fp0, fs);
6392
            gen_load_fpr64(ctx, fp1, ft);
6393
            gen_helper_float_mul_d(fp0, fp0, fp1);
6394
            tcg_temp_free_i64(fp1);
6395
            gen_store_fpr64(ctx, fp0, fd);
6396
            tcg_temp_free_i64(fp0);
6397
        }
6398
        opn = "mul.d";
6399
        optype = BINOP;
6400
        break;
6401
    case FOP(3, 17):
6402
        check_cp1_registers(ctx, fs | ft | fd);
6403
        {
6404
            TCGv_i64 fp0 = tcg_temp_new_i64();
6405
            TCGv_i64 fp1 = tcg_temp_new_i64();
6406

    
6407
            gen_load_fpr64(ctx, fp0, fs);
6408
            gen_load_fpr64(ctx, fp1, ft);
6409
            gen_helper_float_div_d(fp0, fp0, fp1);
6410
            tcg_temp_free_i64(fp1);
6411
            gen_store_fpr64(ctx, fp0, fd);
6412
            tcg_temp_free_i64(fp0);
6413
        }
6414
        opn = "div.d";
6415
        optype = BINOP;
6416
        break;
6417
    case FOP(4, 17):
6418
        check_cp1_registers(ctx, fs | fd);
6419
        {
6420
            TCGv_i64 fp0 = tcg_temp_new_i64();
6421

    
6422
            gen_load_fpr64(ctx, fp0, fs);
6423
            gen_helper_float_sqrt_d(fp0, fp0);
6424
            gen_store_fpr64(ctx, fp0, fd);
6425
            tcg_temp_free_i64(fp0);
6426
        }
6427
        opn = "sqrt.d";
6428
        break;
6429
    case FOP(5, 17):
6430
        check_cp1_registers(ctx, fs | fd);
6431
        {
6432
            TCGv_i64 fp0 = tcg_temp_new_i64();
6433

    
6434
            gen_load_fpr64(ctx, fp0, fs);
6435
            gen_helper_float_abs_d(fp0, fp0);
6436
            gen_store_fpr64(ctx, fp0, fd);
6437
            tcg_temp_free_i64(fp0);
6438
        }
6439
        opn = "abs.d";
6440
        break;
6441
    case FOP(6, 17):
6442
        check_cp1_registers(ctx, fs | fd);
6443
        {
6444
            TCGv_i64 fp0 = tcg_temp_new_i64();
6445

    
6446
            gen_load_fpr64(ctx, fp0, fs);
6447
            gen_store_fpr64(ctx, fp0, fd);
6448
            tcg_temp_free_i64(fp0);
6449
        }
6450
        opn = "mov.d";
6451
        break;
6452
    case FOP(7, 17):
6453
        check_cp1_registers(ctx, fs | fd);
6454
        {
6455
            TCGv_i64 fp0 = tcg_temp_new_i64();
6456

    
6457
            gen_load_fpr64(ctx, fp0, fs);
6458
            gen_helper_float_chs_d(fp0, fp0);
6459
            gen_store_fpr64(ctx, fp0, fd);
6460
            tcg_temp_free_i64(fp0);
6461
        }
6462
        opn = "neg.d";
6463
        break;
6464
    case FOP(8, 17):
6465
        check_cp1_64bitmode(ctx);
6466
        {
6467
            TCGv_i64 fp0 = tcg_temp_new_i64();
6468

    
6469
            gen_load_fpr64(ctx, fp0, fs);
6470
            gen_helper_float_roundl_d(fp0, fp0);
6471
            gen_store_fpr64(ctx, fp0, fd);
6472
            tcg_temp_free_i64(fp0);
6473
        }
6474
        opn = "round.l.d";
6475
        break;
6476
    case FOP(9, 17):
6477
        check_cp1_64bitmode(ctx);
6478
        {
6479
            TCGv_i64 fp0 = tcg_temp_new_i64();
6480

    
6481
            gen_load_fpr64(ctx, fp0, fs);
6482
            gen_helper_float_truncl_d(fp0, fp0);
6483
            gen_store_fpr64(ctx, fp0, fd);
6484
            tcg_temp_free_i64(fp0);
6485
        }
6486
        opn = "trunc.l.d";
6487
        break;
6488
    case FOP(10, 17):
6489
        check_cp1_64bitmode(ctx);
6490
        {
6491
            TCGv_i64 fp0 = tcg_temp_new_i64();
6492

    
6493
            gen_load_fpr64(ctx, fp0, fs);
6494
            gen_helper_float_ceill_d(fp0, fp0);
6495
            gen_store_fpr64(ctx, fp0, fd);
6496
            tcg_temp_free_i64(fp0);
6497
        }
6498
        opn = "ceil.l.d";
6499
        break;
6500
    case FOP(11, 17):
6501
        check_cp1_64bitmode(ctx);
6502
        {
6503
            TCGv_i64 fp0 = tcg_temp_new_i64();
6504

    
6505
            gen_load_fpr64(ctx, fp0, fs);
6506
            gen_helper_float_floorl_d(fp0, fp0);
6507
            gen_store_fpr64(ctx, fp0, fd);
6508
            tcg_temp_free_i64(fp0);
6509
        }
6510
        opn = "floor.l.d";
6511
        break;
6512
    case FOP(12, 17):
6513
        check_cp1_registers(ctx, fs);
6514
        {
6515
            TCGv_i32 fp32 = tcg_temp_new_i32();
6516
            TCGv_i64 fp64 = tcg_temp_new_i64();
6517

    
6518
            gen_load_fpr64(ctx, fp64, fs);
6519
            gen_helper_float_roundw_d(fp32, fp64);
6520
            tcg_temp_free_i64(fp64);
6521
            gen_store_fpr32(fp32, fd);
6522
            tcg_temp_free_i32(fp32);
6523
        }
6524
        opn = "round.w.d";
6525
        break;
6526
    case FOP(13, 17):
6527
        check_cp1_registers(ctx, fs);
6528
        {
6529
            TCGv_i32 fp32 = tcg_temp_new_i32();
6530
            TCGv_i64 fp64 = tcg_temp_new_i64();
6531

    
6532
            gen_load_fpr64(ctx, fp64, fs);
6533
            gen_helper_float_truncw_d(fp32, fp64);
6534
            tcg_temp_free_i64(fp64);
6535
            gen_store_fpr32(fp32, fd);
6536
            tcg_temp_free_i32(fp32);
6537
        }
6538
        opn = "trunc.w.d";
6539
        break;
6540
    case FOP(14, 17):
6541
        check_cp1_registers(ctx, fs);
6542
        {
6543
            TCGv_i32 fp32 = tcg_temp_new_i32();
6544
            TCGv_i64 fp64 = tcg_temp_new_i64();
6545

    
6546
            gen_load_fpr64(ctx, fp64, fs);
6547
            gen_helper_float_ceilw_d(fp32, fp64);
6548
            tcg_temp_free_i64(fp64);
6549
            gen_store_fpr32(fp32, fd);
6550
            tcg_temp_free_i32(fp32);
6551
        }
6552
        opn = "ceil.w.d";
6553
        break;
6554
    case FOP(15, 17):
6555
        check_cp1_registers(ctx, fs);
6556
        {
6557
            TCGv_i32 fp32 = tcg_temp_new_i32();
6558
            TCGv_i64 fp64 = tcg_temp_new_i64();
6559

    
6560
            gen_load_fpr64(ctx, fp64, fs);
6561
            gen_helper_float_floorw_d(fp32, fp64);
6562
            tcg_temp_free_i64(fp64);
6563
            gen_store_fpr32(fp32, fd);
6564
            tcg_temp_free_i32(fp32);
6565
        }
6566
        opn = "floor.w.d";
6567
        break;
6568
    case FOP(17, 17):
6569
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6570
        opn = "movcf.d";
6571
        break;
6572
    case FOP(18, 17):
6573
        {
6574
            int l1 = gen_new_label();
6575
            TCGv t0 = tcg_temp_new();
6576
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6577

    
6578
            gen_load_gpr(t0, ft);
6579
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6580
            gen_load_fpr64(ctx, fp0, fs);
6581
            gen_store_fpr64(ctx, fp0, fd);
6582
            tcg_temp_free_i64(fp0);
6583
            gen_set_label(l1);
6584
            tcg_temp_free(t0);
6585
        }
6586
        opn = "movz.d";
6587
        break;
6588
    case FOP(19, 17):
6589
        {
6590
            int l1 = gen_new_label();
6591
            TCGv t0 = tcg_temp_new();
6592
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6593

    
6594
            gen_load_gpr(t0, ft);
6595
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6596
            gen_load_fpr64(ctx, fp0, fs);
6597
            gen_store_fpr64(ctx, fp0, fd);
6598
            tcg_temp_free_i64(fp0);
6599
            gen_set_label(l1);
6600
            tcg_temp_free(t0);
6601
        }
6602
        opn = "movn.d";
6603
        break;
6604
    case FOP(21, 17):
6605
        check_cp1_64bitmode(ctx);
6606
        {
6607
            TCGv_i64 fp0 = tcg_temp_new_i64();
6608

    
6609
            gen_load_fpr64(ctx, fp0, fs);
6610
            gen_helper_float_recip_d(fp0, fp0);
6611
            gen_store_fpr64(ctx, fp0, fd);
6612
            tcg_temp_free_i64(fp0);
6613
        }
6614
        opn = "recip.d";
6615
        break;
6616
    case FOP(22, 17):
6617
        check_cp1_64bitmode(ctx);
6618
        {
6619
            TCGv_i64 fp0 = tcg_temp_new_i64();
6620

    
6621
            gen_load_fpr64(ctx, fp0, fs);
6622
            gen_helper_float_rsqrt_d(fp0, fp0);
6623
            gen_store_fpr64(ctx, fp0, fd);
6624
            tcg_temp_free_i64(fp0);
6625
        }
6626
        opn = "rsqrt.d";
6627
        break;
6628
    case FOP(28, 17):
6629
        check_cp1_64bitmode(ctx);
6630
        {
6631
            TCGv_i64 fp0 = tcg_temp_new_i64();
6632
            TCGv_i64 fp1 = tcg_temp_new_i64();
6633

    
6634
            gen_load_fpr64(ctx, fp0, fs);
6635
            gen_load_fpr64(ctx, fp1, ft);
6636
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6637
            tcg_temp_free_i64(fp1);
6638
            gen_store_fpr64(ctx, fp0, fd);
6639
            tcg_temp_free_i64(fp0);
6640
        }
6641
        opn = "recip2.d";
6642
        break;
6643
    case FOP(29, 17):
6644
        check_cp1_64bitmode(ctx);
6645
        {
6646
            TCGv_i64 fp0 = tcg_temp_new_i64();
6647

    
6648
            gen_load_fpr64(ctx, fp0, fs);
6649
            gen_helper_float_recip1_d(fp0, fp0);
6650
            gen_store_fpr64(ctx, fp0, fd);
6651
            tcg_temp_free_i64(fp0);
6652
        }
6653
        opn = "recip1.d";
6654
        break;
6655
    case FOP(30, 17):
6656
        check_cp1_64bitmode(ctx);
6657
        {
6658
            TCGv_i64 fp0 = tcg_temp_new_i64();
6659

    
6660
            gen_load_fpr64(ctx, fp0, fs);
6661
            gen_helper_float_rsqrt1_d(fp0, fp0);
6662
            gen_store_fpr64(ctx, fp0, fd);
6663
            tcg_temp_free_i64(fp0);
6664
        }
6665
        opn = "rsqrt1.d";
6666
        break;
6667
    case FOP(31, 17):
6668
        check_cp1_64bitmode(ctx);
6669
        {
6670
            TCGv_i64 fp0 = tcg_temp_new_i64();
6671
            TCGv_i64 fp1 = tcg_temp_new_i64();
6672

    
6673
            gen_load_fpr64(ctx, fp0, fs);
6674
            gen_load_fpr64(ctx, fp1, ft);
6675
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6676
            tcg_temp_free_i64(fp1);
6677
            gen_store_fpr64(ctx, fp0, fd);
6678
            tcg_temp_free_i64(fp0);
6679
        }
6680
        opn = "rsqrt2.d";
6681
        break;
6682
    case FOP(48, 17):
6683
    case FOP(49, 17):
6684
    case FOP(50, 17):
6685
    case FOP(51, 17):
6686
    case FOP(52, 17):
6687
    case FOP(53, 17):
6688
    case FOP(54, 17):
6689
    case FOP(55, 17):
6690
    case FOP(56, 17):
6691
    case FOP(57, 17):
6692
    case FOP(58, 17):
6693
    case FOP(59, 17):
6694
    case FOP(60, 17):
6695
    case FOP(61, 17):
6696
    case FOP(62, 17):
6697
    case FOP(63, 17):
6698
        {
6699
            TCGv_i64 fp0 = tcg_temp_new_i64();
6700
            TCGv_i64 fp1 = tcg_temp_new_i64();
6701

    
6702
            gen_load_fpr64(ctx, fp0, fs);
6703
            gen_load_fpr64(ctx, fp1, ft);
6704
            if (ctx->opcode & (1 << 6)) {
6705
                check_cop1x(ctx);
6706
                check_cp1_registers(ctx, fs | ft);
6707
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6708
                opn = condnames_abs[func-48];
6709
            } else {
6710
                check_cp1_registers(ctx, fs | ft);
6711
                gen_cmp_d(func-48, fp0, fp1, cc);
6712
                opn = condnames[func-48];
6713
            }
6714
            tcg_temp_free_i64(fp0);
6715
            tcg_temp_free_i64(fp1);
6716
        }
6717
        break;
6718
    case FOP(32, 17):
6719
        check_cp1_registers(ctx, fs);
6720
        {
6721
            TCGv_i32 fp32 = tcg_temp_new_i32();
6722
            TCGv_i64 fp64 = tcg_temp_new_i64();
6723

    
6724
            gen_load_fpr64(ctx, fp64, fs);
6725
            gen_helper_float_cvts_d(fp32, fp64);
6726
            tcg_temp_free_i64(fp64);
6727
            gen_store_fpr32(fp32, fd);
6728
            tcg_temp_free_i32(fp32);
6729
        }
6730
        opn = "cvt.s.d";
6731
        break;
6732
    case FOP(36, 17):
6733
        check_cp1_registers(ctx, fs);
6734
        {
6735
            TCGv_i32 fp32 = tcg_temp_new_i32();
6736
            TCGv_i64 fp64 = tcg_temp_new_i64();
6737

    
6738
            gen_load_fpr64(ctx, fp64, fs);
6739
            gen_helper_float_cvtw_d(fp32, fp64);
6740
            tcg_temp_free_i64(fp64);
6741
            gen_store_fpr32(fp32, fd);
6742
            tcg_temp_free_i32(fp32);
6743
        }
6744
        opn = "cvt.w.d";
6745
        break;
6746
    case FOP(37, 17):
6747
        check_cp1_64bitmode(ctx);
6748
        {
6749
            TCGv_i64 fp0 = tcg_temp_new_i64();
6750

    
6751
            gen_load_fpr64(ctx, fp0, fs);
6752
            gen_helper_float_cvtl_d(fp0, fp0);
6753
            gen_store_fpr64(ctx, fp0, fd);
6754
            tcg_temp_free_i64(fp0);
6755
        }
6756
        opn = "cvt.l.d";
6757
        break;
6758
    case FOP(32, 20):
6759
        {
6760
            TCGv_i32 fp0 = tcg_temp_new_i32();
6761

    
6762
            gen_load_fpr32(fp0, fs);
6763
            gen_helper_float_cvts_w(fp0, fp0);
6764
            gen_store_fpr32(fp0, fd);
6765
            tcg_temp_free_i32(fp0);
6766
        }
6767
        opn = "cvt.s.w";
6768
        break;
6769
    case FOP(33, 20):
6770
        check_cp1_registers(ctx, fd);
6771
        {
6772
            TCGv_i32 fp32 = tcg_temp_new_i32();
6773
            TCGv_i64 fp64 = tcg_temp_new_i64();
6774

    
6775
            gen_load_fpr32(fp32, fs);
6776
            gen_helper_float_cvtd_w(fp64, fp32);
6777
            tcg_temp_free_i32(fp32);
6778
            gen_store_fpr64(ctx, fp64, fd);
6779
            tcg_temp_free_i64(fp64);
6780
        }
6781
        opn = "cvt.d.w";
6782
        break;
6783
    case FOP(32, 21):
6784
        check_cp1_64bitmode(ctx);
6785
        {
6786
            TCGv_i32 fp32 = tcg_temp_new_i32();
6787
            TCGv_i64 fp64 = tcg_temp_new_i64();
6788

    
6789
            gen_load_fpr64(ctx, fp64, fs);
6790
            gen_helper_float_cvts_l(fp32, fp64);
6791
            tcg_temp_free_i64(fp64);
6792
            gen_store_fpr32(fp32, fd);
6793
            tcg_temp_free_i32(fp32);
6794
        }
6795
        opn = "cvt.s.l";
6796
        break;
6797
    case FOP(33, 21):
6798
        check_cp1_64bitmode(ctx);
6799
        {
6800
            TCGv_i64 fp0 = tcg_temp_new_i64();
6801

    
6802
            gen_load_fpr64(ctx, fp0, fs);
6803
            gen_helper_float_cvtd_l(fp0, fp0);
6804
            gen_store_fpr64(ctx, fp0, fd);
6805
            tcg_temp_free_i64(fp0);
6806
        }
6807
        opn = "cvt.d.l";
6808
        break;
6809
    case FOP(38, 20):
6810
        check_cp1_64bitmode(ctx);
6811
        {
6812
            TCGv_i64 fp0 = tcg_temp_new_i64();
6813

    
6814
            gen_load_fpr64(ctx, fp0, fs);
6815
            gen_helper_float_cvtps_pw(fp0, fp0);
6816
            gen_store_fpr64(ctx, fp0, fd);
6817
            tcg_temp_free_i64(fp0);
6818
        }
6819
        opn = "cvt.ps.pw";
6820
        break;
6821
    case FOP(0, 22):
6822
        check_cp1_64bitmode(ctx);
6823
        {
6824
            TCGv_i64 fp0 = tcg_temp_new_i64();
6825
            TCGv_i64 fp1 = tcg_temp_new_i64();
6826

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

    
6842
            gen_load_fpr64(ctx, fp0, fs);
6843
            gen_load_fpr64(ctx, fp1, ft);
6844
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6845
            tcg_temp_free_i64(fp1);
6846
            gen_store_fpr64(ctx, fp0, fd);
6847
            tcg_temp_free_i64(fp0);
6848
        }
6849
        opn = "sub.ps";
6850
        break;
6851
    case FOP(2, 22):
6852
        check_cp1_64bitmode(ctx);
6853
        {
6854
            TCGv_i64 fp0 = tcg_temp_new_i64();
6855
            TCGv_i64 fp1 = tcg_temp_new_i64();
6856

    
6857
            gen_load_fpr64(ctx, fp0, fs);
6858
            gen_load_fpr64(ctx, fp1, ft);
6859
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6860
            tcg_temp_free_i64(fp1);
6861
            gen_store_fpr64(ctx, fp0, fd);
6862
            tcg_temp_free_i64(fp0);
6863
        }
6864
        opn = "mul.ps";
6865
        break;
6866
    case FOP(5, 22):
6867
        check_cp1_64bitmode(ctx);
6868
        {
6869
            TCGv_i64 fp0 = tcg_temp_new_i64();
6870

    
6871
            gen_load_fpr64(ctx, fp0, fs);
6872
            gen_helper_float_abs_ps(fp0, fp0);
6873
            gen_store_fpr64(ctx, fp0, fd);
6874
            tcg_temp_free_i64(fp0);
6875
        }
6876
        opn = "abs.ps";
6877
        break;
6878
    case FOP(6, 22):
6879
        check_cp1_64bitmode(ctx);
6880
        {
6881
            TCGv_i64 fp0 = tcg_temp_new_i64();
6882

    
6883
            gen_load_fpr64(ctx, fp0, fs);
6884
            gen_store_fpr64(ctx, fp0, fd);
6885
            tcg_temp_free_i64(fp0);
6886
        }
6887
        opn = "mov.ps";
6888
        break;
6889
    case FOP(7, 22):
6890
        check_cp1_64bitmode(ctx);
6891
        {
6892
            TCGv_i64 fp0 = tcg_temp_new_i64();
6893

    
6894
            gen_load_fpr64(ctx, fp0, fs);
6895
            gen_helper_float_chs_ps(fp0, fp0);
6896
            gen_store_fpr64(ctx, fp0, fd);
6897
            tcg_temp_free_i64(fp0);
6898
        }
6899
        opn = "neg.ps";
6900
        break;
6901
    case FOP(17, 22):
6902
        check_cp1_64bitmode(ctx);
6903
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6904
        opn = "movcf.ps";
6905
        break;
6906
    case FOP(18, 22):
6907
        check_cp1_64bitmode(ctx);
6908
        {
6909
            int l1 = gen_new_label();
6910
            TCGv t0 = tcg_temp_new();
6911
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6912
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6913

    
6914
            gen_load_gpr(t0, ft);
6915
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6916
            gen_load_fpr32(fp0, fs);
6917
            gen_load_fpr32h(fph0, fs);
6918
            gen_store_fpr32(fp0, fd);
6919
            gen_store_fpr32h(fph0, fd);
6920
            tcg_temp_free_i32(fp0);
6921
            tcg_temp_free_i32(fph0);
6922
            gen_set_label(l1);
6923
            tcg_temp_free(t0);
6924
        }
6925
        opn = "movz.ps";
6926
        break;
6927
    case FOP(19, 22):
6928
        check_cp1_64bitmode(ctx);
6929
        {
6930
            int l1 = gen_new_label();
6931
            TCGv t0 = tcg_temp_new();
6932
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6933
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6934

    
6935
            gen_load_gpr(t0, ft);
6936
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6937
            gen_load_fpr32(fp0, fs);
6938
            gen_load_fpr32h(fph0, fs);
6939
            gen_store_fpr32(fp0, fd);
6940
            gen_store_fpr32h(fph0, fd);
6941
            tcg_temp_free_i32(fp0);
6942
            tcg_temp_free_i32(fph0);
6943
            gen_set_label(l1);
6944
            tcg_temp_free(t0);
6945
        }
6946
        opn = "movn.ps";
6947
        break;
6948
    case FOP(24, 22):
6949
        check_cp1_64bitmode(ctx);
6950
        {
6951
            TCGv_i64 fp0 = tcg_temp_new_i64();
6952
            TCGv_i64 fp1 = tcg_temp_new_i64();
6953

    
6954
            gen_load_fpr64(ctx, fp0, ft);
6955
            gen_load_fpr64(ctx, fp1, fs);
6956
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6957
            tcg_temp_free_i64(fp1);
6958
            gen_store_fpr64(ctx, fp0, fd);
6959
            tcg_temp_free_i64(fp0);
6960
        }
6961
        opn = "addr.ps";
6962
        break;
6963
    case FOP(26, 22):
6964
        check_cp1_64bitmode(ctx);
6965
        {
6966
            TCGv_i64 fp0 = tcg_temp_new_i64();
6967
            TCGv_i64 fp1 = tcg_temp_new_i64();
6968

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

    
6984
            gen_load_fpr64(ctx, fp0, fs);
6985
            gen_load_fpr64(ctx, fp1, fd);
6986
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6987
            tcg_temp_free_i64(fp1);
6988
            gen_store_fpr64(ctx, fp0, fd);
6989
            tcg_temp_free_i64(fp0);
6990
        }
6991
        opn = "recip2.ps";
6992
        break;
6993
    case FOP(29, 22):
6994
        check_cp1_64bitmode(ctx);
6995
        {
6996
            TCGv_i64 fp0 = tcg_temp_new_i64();
6997

    
6998
            gen_load_fpr64(ctx, fp0, fs);
6999
            gen_helper_float_recip1_ps(fp0, fp0);
7000
            gen_store_fpr64(ctx, fp0, fd);
7001
            tcg_temp_free_i64(fp0);
7002
        }
7003
        opn = "recip1.ps";
7004
        break;
7005
    case FOP(30, 22):
7006
        check_cp1_64bitmode(ctx);
7007
        {
7008
            TCGv_i64 fp0 = tcg_temp_new_i64();
7009

    
7010
            gen_load_fpr64(ctx, fp0, fs);
7011
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7012
            gen_store_fpr64(ctx, fp0, fd);
7013
            tcg_temp_free_i64(fp0);
7014
        }
7015
        opn = "rsqrt1.ps";
7016
        break;
7017
    case FOP(31, 22):
7018
        check_cp1_64bitmode(ctx);
7019
        {
7020
            TCGv_i64 fp0 = tcg_temp_new_i64();
7021
            TCGv_i64 fp1 = tcg_temp_new_i64();
7022

    
7023
            gen_load_fpr64(ctx, fp0, fs);
7024
            gen_load_fpr64(ctx, fp1, ft);
7025
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7026
            tcg_temp_free_i64(fp1);
7027
            gen_store_fpr64(ctx, fp0, fd);
7028
            tcg_temp_free_i64(fp0);
7029
        }
7030
        opn = "rsqrt2.ps";
7031
        break;
7032
    case FOP(32, 22):
7033
        check_cp1_64bitmode(ctx);
7034
        {
7035
            TCGv_i32 fp0 = tcg_temp_new_i32();
7036

    
7037
            gen_load_fpr32h(fp0, fs);
7038
            gen_helper_float_cvts_pu(fp0, fp0);
7039
            gen_store_fpr32(fp0, fd);
7040
            tcg_temp_free_i32(fp0);
7041
        }
7042
        opn = "cvt.s.pu";
7043
        break;
7044
    case FOP(36, 22):
7045
        check_cp1_64bitmode(ctx);
7046
        {
7047
            TCGv_i64 fp0 = tcg_temp_new_i64();
7048

    
7049
            gen_load_fpr64(ctx, fp0, fs);
7050
            gen_helper_float_cvtpw_ps(fp0, fp0);
7051
            gen_store_fpr64(ctx, fp0, fd);
7052
            tcg_temp_free_i64(fp0);
7053
        }
7054
        opn = "cvt.pw.ps";
7055
        break;
7056
    case FOP(40, 22):
7057
        check_cp1_64bitmode(ctx);
7058
        {
7059
            TCGv_i32 fp0 = tcg_temp_new_i32();
7060

    
7061
            gen_load_fpr32(fp0, fs);
7062
            gen_helper_float_cvts_pl(fp0, fp0);
7063
            gen_store_fpr32(fp0, fd);
7064
            tcg_temp_free_i32(fp0);
7065
        }
7066
        opn = "cvt.s.pl";
7067
        break;
7068
    case FOP(44, 22):
7069
        check_cp1_64bitmode(ctx);
7070
        {
7071
            TCGv_i32 fp0 = tcg_temp_new_i32();
7072
            TCGv_i32 fp1 = tcg_temp_new_i32();
7073

    
7074
            gen_load_fpr32(fp0, fs);
7075
            gen_load_fpr32(fp1, ft);
7076
            gen_store_fpr32h(fp0, fd);
7077
            gen_store_fpr32(fp1, fd);
7078
            tcg_temp_free_i32(fp0);
7079
            tcg_temp_free_i32(fp1);
7080
        }
7081
        opn = "pll.ps";
7082
        break;
7083
    case FOP(45, 22):
7084
        check_cp1_64bitmode(ctx);
7085
        {
7086
            TCGv_i32 fp0 = tcg_temp_new_i32();
7087
            TCGv_i32 fp1 = tcg_temp_new_i32();
7088

    
7089
            gen_load_fpr32(fp0, fs);
7090
            gen_load_fpr32h(fp1, ft);
7091
            gen_store_fpr32(fp1, fd);
7092
            gen_store_fpr32h(fp0, fd);
7093
            tcg_temp_free_i32(fp0);
7094
            tcg_temp_free_i32(fp1);
7095
        }
7096
        opn = "plu.ps";
7097
        break;
7098
    case FOP(46, 22):
7099
        check_cp1_64bitmode(ctx);
7100
        {
7101
            TCGv_i32 fp0 = tcg_temp_new_i32();
7102
            TCGv_i32 fp1 = tcg_temp_new_i32();
7103

    
7104
            gen_load_fpr32h(fp0, fs);
7105
            gen_load_fpr32(fp1, ft);
7106
            gen_store_fpr32(fp1, fd);
7107
            gen_store_fpr32h(fp0, fd);
7108
            tcg_temp_free_i32(fp0);
7109
            tcg_temp_free_i32(fp1);
7110
        }
7111
        opn = "pul.ps";
7112
        break;
7113
    case FOP(47, 22):
7114
        check_cp1_64bitmode(ctx);
7115
        {
7116
            TCGv_i32 fp0 = tcg_temp_new_i32();
7117
            TCGv_i32 fp1 = tcg_temp_new_i32();
7118

    
7119
            gen_load_fpr32h(fp0, fs);
7120
            gen_load_fpr32h(fp1, ft);
7121
            gen_store_fpr32(fp1, fd);
7122
            gen_store_fpr32h(fp0, fd);
7123
            tcg_temp_free_i32(fp0);
7124
            tcg_temp_free_i32(fp1);
7125
        }
7126
        opn = "puu.ps";
7127
        break;
7128
    case FOP(48, 22):
7129
    case FOP(49, 22):
7130
    case FOP(50, 22):
7131
    case FOP(51, 22):
7132
    case FOP(52, 22):
7133
    case FOP(53, 22):
7134
    case FOP(54, 22):
7135
    case FOP(55, 22):
7136
    case FOP(56, 22):
7137
    case FOP(57, 22):
7138
    case FOP(58, 22):
7139
    case FOP(59, 22):
7140
    case FOP(60, 22):
7141
    case FOP(61, 22):
7142
    case FOP(62, 22):
7143
    case FOP(63, 22):
7144
        check_cp1_64bitmode(ctx);
7145
        {
7146
            TCGv_i64 fp0 = tcg_temp_new_i64();
7147
            TCGv_i64 fp1 = tcg_temp_new_i64();
7148

    
7149
            gen_load_fpr64(ctx, fp0, fs);
7150
            gen_load_fpr64(ctx, fp1, ft);
7151
            if (ctx->opcode & (1 << 6)) {
7152
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7153
                opn = condnames_abs[func-48];
7154
            } else {
7155
                gen_cmp_ps(func-48, fp0, fp1, cc);
7156
                opn = condnames[func-48];
7157
            }
7158
            tcg_temp_free_i64(fp0);
7159
            tcg_temp_free_i64(fp1);
7160
        }
7161
        break;
7162
    default:
7163
        MIPS_INVAL(opn);
7164
        generate_exception (ctx, EXCP_RI);
7165
        return;
7166
    }
7167
    switch (optype) {
7168
    case BINOP:
7169
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7170
        break;
7171
    case CMPOP:
7172
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7173
        break;
7174
    default:
7175
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7176
        break;
7177
    }
7178
}
7179

    
7180
/* Coprocessor 3 (FPU) */
7181
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7182
                           int fd, int fs, int base, int index)
7183
{
7184
    const char *opn = "extended float load/store";
7185
    int store = 0;
7186
    TCGv t0 = tcg_temp_local_new();
7187
    TCGv t1 = tcg_temp_local_new();
7188

    
7189
    if (base == 0) {
7190
        gen_load_gpr(t0, index);
7191
    } else if (index == 0) {
7192
        gen_load_gpr(t0, base);
7193
    } else {
7194
        gen_load_gpr(t0, index);
7195
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7196
    }
7197
    /* Don't do NOP if destination is zero: we must perform the actual
7198
       memory access. */
7199
    switch (opc) {
7200
    case OPC_LWXC1:
7201
        check_cop1x(ctx);
7202
        {
7203
            TCGv_i32 fp0 = tcg_temp_new_i32();
7204

    
7205
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7206
            tcg_gen_trunc_tl_i32(fp0, t1);
7207
            gen_store_fpr32(fp0, fd);
7208
            tcg_temp_free_i32(fp0);
7209
        }
7210
        opn = "lwxc1";
7211
        break;
7212
    case OPC_LDXC1:
7213
        check_cop1x(ctx);
7214
        check_cp1_registers(ctx, fd);
7215
        {
7216
            TCGv_i64 fp0 = tcg_temp_new_i64();
7217

    
7218
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7219
            gen_store_fpr64(ctx, fp0, fd);
7220
            tcg_temp_free_i64(fp0);
7221
        }
7222
        opn = "ldxc1";
7223
        break;
7224
    case OPC_LUXC1:
7225
        check_cp1_64bitmode(ctx);
7226
        tcg_gen_andi_tl(t0, t0, ~0x7);
7227
        {
7228
            TCGv_i64 fp0 = tcg_temp_new_i64();
7229

    
7230
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7231
            gen_store_fpr64(ctx, fp0, fd);
7232
            tcg_temp_free_i64(fp0);
7233
        }
7234
        opn = "luxc1";
7235
        break;
7236
    case OPC_SWXC1:
7237
        check_cop1x(ctx);
7238
        {
7239
            TCGv_i32 fp0 = tcg_temp_new_i32();
7240

    
7241
            gen_load_fpr32(fp0, fs);
7242
            tcg_gen_extu_i32_tl(t1, fp0);
7243
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7244
            tcg_temp_free_i32(fp0);
7245
        }
7246
        opn = "swxc1";
7247
        store = 1;
7248
        break;
7249
    case OPC_SDXC1:
7250
        check_cop1x(ctx);
7251
        check_cp1_registers(ctx, fs);
7252
        {
7253
            TCGv_i64 fp0 = tcg_temp_new_i64();
7254

    
7255
            gen_load_fpr64(ctx, fp0, fs);
7256
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7257
            tcg_temp_free_i64(fp0);
7258
        }
7259
        opn = "sdxc1";
7260
        store = 1;
7261
        break;
7262
    case OPC_SUXC1:
7263
        check_cp1_64bitmode(ctx);
7264
        tcg_gen_andi_tl(t0, t0, ~0x7);
7265
        {
7266
            TCGv_i64 fp0 = tcg_temp_new_i64();
7267

    
7268
            gen_load_fpr64(ctx, fp0, fs);
7269
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7270
            tcg_temp_free_i64(fp0);
7271
        }
7272
        opn = "suxc1";
7273
        store = 1;
7274
        break;
7275
    default:
7276
        MIPS_INVAL(opn);
7277
        generate_exception(ctx, EXCP_RI);
7278
        tcg_temp_free(t0);
7279
        tcg_temp_free(t1);
7280
        return;
7281
    }
7282
    tcg_temp_free(t0);
7283
    tcg_temp_free(t1);
7284
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7285
               regnames[index], regnames[base]);
7286
}
7287

    
7288
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7289
                            int fd, int fr, int fs, int ft)
7290
{
7291
    const char *opn = "flt3_arith";
7292

    
7293
    switch (opc) {
7294
    case OPC_ALNV_PS:
7295
        check_cp1_64bitmode(ctx);
7296
        {
7297
            TCGv t0 = tcg_temp_local_new();
7298
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7299
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7300
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7301
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7302
            int l1 = gen_new_label();
7303
            int l2 = gen_new_label();
7304

    
7305
            gen_load_gpr(t0, fr);
7306
            tcg_gen_andi_tl(t0, t0, 0x7);
7307
            gen_load_fpr32(fp0, fs);
7308
            gen_load_fpr32h(fph0, fs);
7309
            gen_load_fpr32(fp1, ft);
7310
            gen_load_fpr32h(fph1, ft);
7311

    
7312
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7313
            gen_store_fpr32(fp0, fd);
7314
            gen_store_fpr32h(fph0, fd);
7315
            tcg_gen_br(l2);
7316
            gen_set_label(l1);
7317
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7318
            tcg_temp_free(t0);
7319
#ifdef TARGET_WORDS_BIGENDIAN
7320
            gen_store_fpr32(fph1, fd);
7321
            gen_store_fpr32h(fp0, fd);
7322
#else
7323
            gen_store_fpr32(fph0, fd);
7324
            gen_store_fpr32h(fp1, fd);
7325
#endif
7326
            gen_set_label(l2);
7327
            tcg_temp_free_i32(fp0);
7328
            tcg_temp_free_i32(fph0);
7329
            tcg_temp_free_i32(fp1);
7330
            tcg_temp_free_i32(fph1);
7331
        }
7332
        opn = "alnv.ps";
7333
        break;
7334
    case OPC_MADD_S:
7335
        check_cop1x(ctx);
7336
        {
7337
            TCGv_i32 fp0 = tcg_temp_new_i32();
7338
            TCGv_i32 fp1 = tcg_temp_new_i32();
7339
            TCGv_i32 fp2 = tcg_temp_new_i32();
7340

    
7341
            gen_load_fpr32(fp0, fs);
7342
            gen_load_fpr32(fp1, ft);
7343
            gen_load_fpr32(fp2, fr);
7344
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7345
            tcg_temp_free_i32(fp0);
7346
            tcg_temp_free_i32(fp1);
7347
            gen_store_fpr32(fp2, fd);
7348
            tcg_temp_free_i32(fp2);
7349
        }
7350
        opn = "madd.s";
7351
        break;
7352
    case OPC_MADD_D:
7353
        check_cop1x(ctx);
7354
        check_cp1_registers(ctx, fd | fs | ft | fr);
7355
        {
7356
            TCGv_i64 fp0 = tcg_temp_new_i64();
7357
            TCGv_i64 fp1 = tcg_temp_new_i64();
7358
            TCGv_i64 fp2 = tcg_temp_new_i64();
7359

    
7360
            gen_load_fpr64(ctx, fp0, fs);
7361
            gen_load_fpr64(ctx, fp1, ft);
7362
            gen_load_fpr64(ctx, fp2, fr);
7363
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7364
            tcg_temp_free_i64(fp0);
7365
            tcg_temp_free_i64(fp1);
7366
            gen_store_fpr64(ctx, fp2, fd);
7367
            tcg_temp_free_i64(fp2);
7368
        }
7369
        opn = "madd.d";
7370
        break;
7371
    case OPC_MADD_PS:
7372
        check_cp1_64bitmode(ctx);
7373
        {
7374
            TCGv_i64 fp0 = tcg_temp_new_i64();
7375
            TCGv_i64 fp1 = tcg_temp_new_i64();
7376
            TCGv_i64 fp2 = tcg_temp_new_i64();
7377

    
7378
            gen_load_fpr64(ctx, fp0, fs);
7379
            gen_load_fpr64(ctx, fp1, ft);
7380
            gen_load_fpr64(ctx, fp2, fr);
7381
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7382
            tcg_temp_free_i64(fp0);
7383
            tcg_temp_free_i64(fp1);
7384
            gen_store_fpr64(ctx, fp2, fd);
7385
            tcg_temp_free_i64(fp2);
7386
        }
7387
        opn = "madd.ps";
7388
        break;
7389
    case OPC_MSUB_S:
7390
        check_cop1x(ctx);
7391
        {
7392
            TCGv_i32 fp0 = tcg_temp_new_i32();
7393
            TCGv_i32 fp1 = tcg_temp_new_i32();
7394
            TCGv_i32 fp2 = tcg_temp_new_i32();
7395

    
7396
            gen_load_fpr32(fp0, fs);
7397
            gen_load_fpr32(fp1, ft);
7398
            gen_load_fpr32(fp2, fr);
7399
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7400
            tcg_temp_free_i32(fp0);
7401
            tcg_temp_free_i32(fp1);
7402
            gen_store_fpr32(fp2, fd);
7403
            tcg_temp_free_i32(fp2);
7404
        }
7405
        opn = "msub.s";
7406
        break;
7407
    case OPC_MSUB_D:
7408
        check_cop1x(ctx);
7409
        check_cp1_registers(ctx, fd | fs | ft | fr);
7410
        {
7411
            TCGv_i64 fp0 = tcg_temp_new_i64();
7412
            TCGv_i64 fp1 = tcg_temp_new_i64();
7413
            TCGv_i64 fp2 = tcg_temp_new_i64();
7414

    
7415
            gen_load_fpr64(ctx, fp0, fs);
7416
            gen_load_fpr64(ctx, fp1, ft);
7417
            gen_load_fpr64(ctx, fp2, fr);
7418
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7419
            tcg_temp_free_i64(fp0);
7420
            tcg_temp_free_i64(fp1);
7421
            gen_store_fpr64(ctx, fp2, fd);
7422
            tcg_temp_free_i64(fp2);
7423
        }
7424
        opn = "msub.d";
7425
        break;
7426
    case OPC_MSUB_PS:
7427
        check_cp1_64bitmode(ctx);
7428
        {
7429
            TCGv_i64 fp0 = tcg_temp_new_i64();
7430
            TCGv_i64 fp1 = tcg_temp_new_i64();
7431
            TCGv_i64 fp2 = tcg_temp_new_i64();
7432

    
7433
            gen_load_fpr64(ctx, fp0, fs);
7434
            gen_load_fpr64(ctx, fp1, ft);
7435
            gen_load_fpr64(ctx, fp2, fr);
7436
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7437
            tcg_temp_free_i64(fp0);
7438
            tcg_temp_free_i64(fp1);
7439
            gen_store_fpr64(ctx, fp2, fd);
7440
            tcg_temp_free_i64(fp2);
7441
        }
7442
        opn = "msub.ps";
7443
        break;
7444
    case OPC_NMADD_S:
7445
        check_cop1x(ctx);
7446
        {
7447
            TCGv_i32 fp0 = tcg_temp_new_i32();
7448
            TCGv_i32 fp1 = tcg_temp_new_i32();
7449
            TCGv_i32 fp2 = tcg_temp_new_i32();
7450

    
7451
            gen_load_fpr32(fp0, fs);
7452
            gen_load_fpr32(fp1, ft);
7453
            gen_load_fpr32(fp2, fr);
7454
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7455
            tcg_temp_free_i32(fp0);
7456
            tcg_temp_free_i32(fp1);
7457
            gen_store_fpr32(fp2, fd);
7458
            tcg_temp_free_i32(fp2);
7459
        }
7460
        opn = "nmadd.s";
7461
        break;
7462
    case OPC_NMADD_D:
7463
        check_cop1x(ctx);
7464
        check_cp1_registers(ctx, fd | fs | ft | fr);
7465
        {
7466
            TCGv_i64 fp0 = tcg_temp_new_i64();
7467
            TCGv_i64 fp1 = tcg_temp_new_i64();
7468
            TCGv_i64 fp2 = tcg_temp_new_i64();
7469

    
7470
            gen_load_fpr64(ctx, fp0, fs);
7471
            gen_load_fpr64(ctx, fp1, ft);
7472
            gen_load_fpr64(ctx, fp2, fr);
7473
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7474
            tcg_temp_free_i64(fp0);
7475
            tcg_temp_free_i64(fp1);
7476
            gen_store_fpr64(ctx, fp2, fd);
7477
            tcg_temp_free_i64(fp2);
7478
        }
7479
        opn = "nmadd.d";
7480
        break;
7481
    case OPC_NMADD_PS:
7482
        check_cp1_64bitmode(ctx);
7483
        {
7484
            TCGv_i64 fp0 = tcg_temp_new_i64();
7485
            TCGv_i64 fp1 = tcg_temp_new_i64();
7486
            TCGv_i64 fp2 = tcg_temp_new_i64();
7487

    
7488
            gen_load_fpr64(ctx, fp0, fs);
7489
            gen_load_fpr64(ctx, fp1, ft);
7490
            gen_load_fpr64(ctx, fp2, fr);
7491
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7492
            tcg_temp_free_i64(fp0);
7493
            tcg_temp_free_i64(fp1);
7494
            gen_store_fpr64(ctx, fp2, fd);
7495
            tcg_temp_free_i64(fp2);
7496
        }
7497
        opn = "nmadd.ps";
7498
        break;
7499
    case OPC_NMSUB_S:
7500
        check_cop1x(ctx);
7501
        {
7502
            TCGv_i32 fp0 = tcg_temp_new_i32();
7503
            TCGv_i32 fp1 = tcg_temp_new_i32();
7504
            TCGv_i32 fp2 = tcg_temp_new_i32();
7505

    
7506
            gen_load_fpr32(fp0, fs);
7507
            gen_load_fpr32(fp1, ft);
7508
            gen_load_fpr32(fp2, fr);
7509
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7510
            tcg_temp_free_i32(fp0);
7511
            tcg_temp_free_i32(fp1);
7512
            gen_store_fpr32(fp2, fd);
7513
            tcg_temp_free_i32(fp2);
7514
        }
7515
        opn = "nmsub.s";
7516
        break;
7517
    case OPC_NMSUB_D:
7518
        check_cop1x(ctx);
7519
        check_cp1_registers(ctx, fd | fs | ft | fr);
7520
        {
7521
            TCGv_i64 fp0 = tcg_temp_new_i64();
7522
            TCGv_i64 fp1 = tcg_temp_new_i64();
7523
            TCGv_i64 fp2 = tcg_temp_new_i64();
7524

    
7525
            gen_load_fpr64(ctx, fp0, fs);
7526
            gen_load_fpr64(ctx, fp1, ft);
7527
            gen_load_fpr64(ctx, fp2, fr);
7528
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7529
            tcg_temp_free_i64(fp0);
7530
            tcg_temp_free_i64(fp1);
7531
            gen_store_fpr64(ctx, fp2, fd);
7532
            tcg_temp_free_i64(fp2);
7533
        }
7534
        opn = "nmsub.d";
7535
        break;
7536
    case OPC_NMSUB_PS:
7537
        check_cp1_64bitmode(ctx);
7538
        {
7539
            TCGv_i64 fp0 = tcg_temp_new_i64();
7540
            TCGv_i64 fp1 = tcg_temp_new_i64();
7541
            TCGv_i64 fp2 = tcg_temp_new_i64();
7542

    
7543
            gen_load_fpr64(ctx, fp0, fs);
7544
            gen_load_fpr64(ctx, fp1, ft);
7545
            gen_load_fpr64(ctx, fp2, fr);
7546
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7547
            tcg_temp_free_i64(fp0);
7548
            tcg_temp_free_i64(fp1);
7549
            gen_store_fpr64(ctx, fp2, fd);
7550
            tcg_temp_free_i64(fp2);
7551
        }
7552
        opn = "nmsub.ps";
7553
        break;
7554
    default:
7555
        MIPS_INVAL(opn);
7556
        generate_exception (ctx, EXCP_RI);
7557
        return;
7558
    }
7559
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7560
               fregnames[fs], fregnames[ft]);
7561
}
7562

    
7563
/* ISA extensions (ASEs) */
7564
/* MIPS16 extension to MIPS32 */
7565
/* SmartMIPS extension to MIPS32 */
7566

    
7567
#if defined(TARGET_MIPS64)
7568

    
7569
/* MDMX extension to MIPS64 */
7570

    
7571
#endif
7572

    
7573
static void decode_opc (CPUState *env, DisasContext *ctx)
7574
{
7575
    int32_t offset;
7576
    int rs, rt, rd, sa;
7577
    uint32_t op, op1, op2;
7578
    int16_t imm;
7579

    
7580
    /* make sure instructions are on a word boundary */
7581
    if (ctx->pc & 0x3) {
7582
        env->CP0_BadVAddr = ctx->pc;
7583
        generate_exception(ctx, EXCP_AdEL);
7584
        return;
7585
    }
7586

    
7587
    /* Handle blikely not taken case */
7588
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7589
        int l1 = gen_new_label();
7590

    
7591
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7592
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7593
        {
7594
            TCGv_i32 r_tmp = tcg_temp_new_i32();
7595

    
7596
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7597
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7598
            tcg_temp_free_i32(r_tmp);
7599
        }
7600
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7601
        gen_set_label(l1);
7602
    }
7603
    op = MASK_OP_MAJOR(ctx->opcode);
7604
    rs = (ctx->opcode >> 21) & 0x1f;
7605
    rt = (ctx->opcode >> 16) & 0x1f;
7606
    rd = (ctx->opcode >> 11) & 0x1f;
7607
    sa = (ctx->opcode >> 6) & 0x1f;
7608
    imm = (int16_t)ctx->opcode;
7609
    switch (op) {
7610
    case OPC_SPECIAL:
7611
        op1 = MASK_SPECIAL(ctx->opcode);
7612
        switch (op1) {
7613
        case OPC_SLL:          /* Arithmetic with immediate */
7614
        case OPC_SRL ... OPC_SRA:
7615
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7616
            break;
7617
        case OPC_MOVZ ... OPC_MOVN:
7618
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7619
        case OPC_SLLV:         /* Arithmetic */
7620
        case OPC_SRLV ... OPC_SRAV:
7621
        case OPC_ADD ... OPC_NOR:
7622
        case OPC_SLT ... OPC_SLTU:
7623
            gen_arith(env, ctx, op1, rd, rs, rt);
7624
            break;
7625
        case OPC_MULT ... OPC_DIVU:
7626
            if (sa) {
7627
                check_insn(env, ctx, INSN_VR54XX);
7628
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7629
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7630
            } else
7631
                gen_muldiv(ctx, op1, rs, rt);
7632
            break;
7633
        case OPC_JR ... OPC_JALR:
7634
            gen_compute_branch(ctx, op1, rs, rd, sa);
7635
            return;
7636
        case OPC_TGE ... OPC_TEQ: /* Traps */
7637
        case OPC_TNE:
7638
            gen_trap(ctx, op1, rs, rt, -1);
7639
            break;
7640
        case OPC_MFHI:          /* Move from HI/LO */
7641
        case OPC_MFLO:
7642
            gen_HILO(ctx, op1, rd);
7643
            break;
7644
        case OPC_MTHI:
7645
        case OPC_MTLO:          /* Move to HI/LO */
7646
            gen_HILO(ctx, op1, rs);
7647
            break;
7648
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7649
#ifdef MIPS_STRICT_STANDARD
7650
            MIPS_INVAL("PMON / selsl");
7651
            generate_exception(ctx, EXCP_RI);
7652
#else
7653
            gen_helper_0i(pmon, sa);
7654
#endif
7655
            break;
7656
        case OPC_SYSCALL:
7657
            generate_exception(ctx, EXCP_SYSCALL);
7658
            break;
7659
        case OPC_BREAK:
7660
            generate_exception(ctx, EXCP_BREAK);
7661
            break;
7662
        case OPC_SPIM:
7663
#ifdef MIPS_STRICT_STANDARD
7664
            MIPS_INVAL("SPIM");
7665
            generate_exception(ctx, EXCP_RI);
7666
#else
7667
           /* Implemented as RI exception for now. */
7668
            MIPS_INVAL("spim (unofficial)");
7669
            generate_exception(ctx, EXCP_RI);
7670
#endif
7671
            break;
7672
        case OPC_SYNC:
7673
            /* Treat as NOP. */
7674
            break;
7675

    
7676
        case OPC_MOVCI:
7677
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7678
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7679
                save_cpu_state(ctx, 1);
7680
                check_cp1_enabled(ctx);
7681
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7682
                          (ctx->opcode >> 16) & 1);
7683
            } else {
7684
                generate_exception_err(ctx, EXCP_CpU, 1);
7685
            }
7686
            break;
7687

    
7688
#if defined(TARGET_MIPS64)
7689
       /* MIPS64 specific opcodes */
7690
        case OPC_DSLL:
7691
        case OPC_DSRL ... OPC_DSRA:
7692
        case OPC_DSLL32:
7693
        case OPC_DSRL32 ... OPC_DSRA32:
7694
            check_insn(env, ctx, ISA_MIPS3);
7695
            check_mips_64(ctx);
7696
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7697
            break;
7698
        case OPC_DSLLV:
7699
        case OPC_DSRLV ... OPC_DSRAV:
7700
        case OPC_DADD ... OPC_DSUBU:
7701
            check_insn(env, ctx, ISA_MIPS3);
7702
            check_mips_64(ctx);
7703
            gen_arith(env, ctx, op1, rd, rs, rt);
7704
            break;
7705
        case OPC_DMULT ... OPC_DDIVU:
7706
            check_insn(env, ctx, ISA_MIPS3);
7707
            check_mips_64(ctx);
7708
            gen_muldiv(ctx, op1, rs, rt);
7709
            break;
7710
#endif
7711
        default:            /* Invalid */
7712
            MIPS_INVAL("special");
7713
            generate_exception(ctx, EXCP_RI);
7714
            break;
7715
        }
7716
        break;
7717
    case OPC_SPECIAL2:
7718
        op1 = MASK_SPECIAL2(ctx->opcode);
7719
        switch (op1) {
7720
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7721
        case OPC_MSUB ... OPC_MSUBU:
7722
            check_insn(env, ctx, ISA_MIPS32);
7723
            gen_muldiv(ctx, op1, rs, rt);
7724
            break;
7725
        case OPC_MUL:
7726
            gen_arith(env, ctx, op1, rd, rs, rt);
7727
            break;
7728
        case OPC_CLZ ... OPC_CLO:
7729
            check_insn(env, ctx, ISA_MIPS32);
7730
            gen_cl(ctx, op1, rd, rs);
7731
            break;
7732
        case OPC_SDBBP:
7733
            /* XXX: not clear which exception should be raised
7734
             *      when in debug mode...
7735
             */
7736
            check_insn(env, ctx, ISA_MIPS32);
7737
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7738
                generate_exception(ctx, EXCP_DBp);
7739
            } else {
7740
                generate_exception(ctx, EXCP_DBp);
7741
            }
7742
            /* Treat as NOP. */
7743
            break;
7744
#if defined(TARGET_MIPS64)
7745
        case OPC_DCLZ ... OPC_DCLO:
7746
            check_insn(env, ctx, ISA_MIPS64);
7747
            check_mips_64(ctx);
7748
            gen_cl(ctx, op1, rd, rs);
7749
            break;
7750
#endif
7751
        default:            /* Invalid */
7752
            MIPS_INVAL("special2");
7753
            generate_exception(ctx, EXCP_RI);
7754
            break;
7755
        }
7756
        break;
7757
    case OPC_SPECIAL3:
7758
        op1 = MASK_SPECIAL3(ctx->opcode);
7759
        switch (op1) {
7760
        case OPC_EXT:
7761
        case OPC_INS:
7762
            check_insn(env, ctx, ISA_MIPS32R2);
7763
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7764
            break;
7765
        case OPC_BSHFL:
7766
            check_insn(env, ctx, ISA_MIPS32R2);
7767
            op2 = MASK_BSHFL(ctx->opcode);
7768
            gen_bshfl(ctx, op2, rt, rd);
7769
            break;
7770
        case OPC_RDHWR:
7771
            check_insn(env, ctx, ISA_MIPS32R2);
7772
            {
7773
                TCGv t0 = tcg_temp_local_new();
7774

    
7775
                switch (rd) {
7776
                case 0:
7777
                    save_cpu_state(ctx, 1);
7778
                    gen_helper_rdhwr_cpunum(t0);
7779
                    break;
7780
                case 1:
7781
                    save_cpu_state(ctx, 1);
7782
                    gen_helper_rdhwr_synci_step(t0);
7783
                    break;
7784
                case 2:
7785
                    save_cpu_state(ctx, 1);
7786
                    gen_helper_rdhwr_cc(t0);
7787
                    break;
7788
                case 3:
7789
                    save_cpu_state(ctx, 1);
7790
                    gen_helper_rdhwr_ccres(t0);
7791
                    break;
7792
                case 29:
7793
#if defined(CONFIG_USER_ONLY)
7794
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7795
                    break;
7796
#else
7797
                    /* XXX: Some CPUs implement this in hardware.
7798
                       Not supported yet. */
7799
#endif
7800
                default:            /* Invalid */
7801
                    MIPS_INVAL("rdhwr");
7802
                    generate_exception(ctx, EXCP_RI);
7803
                    break;
7804
                }
7805
                gen_store_gpr(t0, rt);
7806
                tcg_temp_free(t0);
7807
            }
7808
            break;
7809
        case OPC_FORK:
7810
            check_insn(env, ctx, ASE_MT);
7811
            {
7812
                TCGv t0 = tcg_temp_local_new();
7813
                TCGv t1 = tcg_temp_local_new();
7814

    
7815
                gen_load_gpr(t0, rt);
7816
                gen_load_gpr(t1, rs);
7817
                gen_helper_fork(t0, t1);
7818
                tcg_temp_free(t0);
7819
                tcg_temp_free(t1);
7820
            }
7821
            break;
7822
        case OPC_YIELD:
7823
            check_insn(env, ctx, ASE_MT);
7824
            {
7825
                TCGv t0 = tcg_temp_local_new();
7826

    
7827
                gen_load_gpr(t0, rs);
7828
                gen_helper_yield(t0, t0);
7829
                gen_store_gpr(t0, rd);
7830
                tcg_temp_free(t0);
7831
            }
7832
            break;
7833
#if defined(TARGET_MIPS64)
7834
        case OPC_DEXTM ... OPC_DEXT:
7835
        case OPC_DINSM ... OPC_DINS:
7836
            check_insn(env, ctx, ISA_MIPS64R2);
7837
            check_mips_64(ctx);
7838
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7839
            break;
7840
        case OPC_DBSHFL:
7841
            check_insn(env, ctx, ISA_MIPS64R2);
7842
            check_mips_64(ctx);
7843
            op2 = MASK_DBSHFL(ctx->opcode);
7844
            gen_bshfl(ctx, op2, rt, rd);
7845
            break;
7846
#endif
7847
        default:            /* Invalid */
7848
            MIPS_INVAL("special3");
7849
            generate_exception(ctx, EXCP_RI);
7850
            break;
7851
        }
7852
        break;
7853
    case OPC_REGIMM:
7854
        op1 = MASK_REGIMM(ctx->opcode);
7855
        switch (op1) {
7856
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7857
        case OPC_BLTZAL ... OPC_BGEZALL:
7858
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7859
            return;
7860
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7861
        case OPC_TNEI:
7862
            gen_trap(ctx, op1, rs, -1, imm);
7863
            break;
7864
        case OPC_SYNCI:
7865
            check_insn(env, ctx, ISA_MIPS32R2);
7866
            /* Treat as NOP. */
7867
            break;
7868
        default:            /* Invalid */
7869
            MIPS_INVAL("regimm");
7870
            generate_exception(ctx, EXCP_RI);
7871
            break;
7872
        }
7873
        break;
7874
    case OPC_CP0:
7875
        check_cp0_enabled(ctx);
7876
        op1 = MASK_CP0(ctx->opcode);
7877
        switch (op1) {
7878
        case OPC_MFC0:
7879
        case OPC_MTC0:
7880
        case OPC_MFTR:
7881
        case OPC_MTTR:
7882
#if defined(TARGET_MIPS64)
7883
        case OPC_DMFC0:
7884
        case OPC_DMTC0:
7885
#endif
7886
#ifndef CONFIG_USER_ONLY
7887
            gen_cp0(env, ctx, op1, rt, rd);
7888
#endif /* !CONFIG_USER_ONLY */
7889
            break;
7890
        case OPC_C0_FIRST ... OPC_C0_LAST:
7891
#ifndef CONFIG_USER_ONLY
7892
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7893
#endif /* !CONFIG_USER_ONLY */
7894
            break;
7895
        case OPC_MFMC0:
7896
#ifndef CONFIG_USER_ONLY
7897
            {
7898
                TCGv t0 = tcg_temp_local_new();
7899

    
7900
                op2 = MASK_MFMC0(ctx->opcode);
7901
                switch (op2) {
7902
                case OPC_DMT:
7903
                    check_insn(env, ctx, ASE_MT);
7904
                    gen_helper_dmt(t0, t0);
7905
                    break;
7906
                case OPC_EMT:
7907
                    check_insn(env, ctx, ASE_MT);
7908
                    gen_helper_emt(t0, t0);
7909
                    break;
7910
                case OPC_DVPE:
7911
                    check_insn(env, ctx, ASE_MT);
7912
                    gen_helper_dvpe(t0, t0);
7913
                    break;
7914
                case OPC_EVPE:
7915
                    check_insn(env, ctx, ASE_MT);
7916
                    gen_helper_evpe(t0, t0);
7917
                    break;
7918
                case OPC_DI:
7919
                    check_insn(env, ctx, ISA_MIPS32R2);
7920
                    save_cpu_state(ctx, 1);
7921
                    gen_helper_di(t0);
7922
                    /* Stop translation as we may have switched the execution mode */
7923
                    ctx->bstate = BS_STOP;
7924
                    break;
7925
                case OPC_EI:
7926
                    check_insn(env, ctx, ISA_MIPS32R2);
7927
                    save_cpu_state(ctx, 1);
7928
                    gen_helper_ei(t0);
7929
                    /* Stop translation as we may have switched the execution mode */
7930
                    ctx->bstate = BS_STOP;
7931
                    break;
7932
                default:            /* Invalid */
7933
                    MIPS_INVAL("mfmc0");
7934
                    generate_exception(ctx, EXCP_RI);
7935
                    break;
7936
                }
7937
                gen_store_gpr(t0, rt);
7938
                tcg_temp_free(t0);
7939
            }
7940
#endif /* !CONFIG_USER_ONLY */
7941
            break;
7942
        case OPC_RDPGPR:
7943
            check_insn(env, ctx, ISA_MIPS32R2);
7944
            gen_load_srsgpr(rt, rd);
7945
            break;
7946
        case OPC_WRPGPR:
7947
            check_insn(env, ctx, ISA_MIPS32R2);
7948
            gen_store_srsgpr(rt, rd);
7949
            break;
7950
        default:
7951
            MIPS_INVAL("cp0");
7952
            generate_exception(ctx, EXCP_RI);
7953
            break;
7954
        }
7955
        break;
7956
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7957
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7958
         break;
7959
    case OPC_J ... OPC_JAL: /* Jump */
7960
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7961
         gen_compute_branch(ctx, op, rs, rt, offset);
7962
         return;
7963
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7964
    case OPC_BEQL ... OPC_BGTZL:
7965
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7966
         return;
7967
    case OPC_LB ... OPC_LWR: /* Load and stores */
7968
    case OPC_SB ... OPC_SW:
7969
    case OPC_SWR:
7970
    case OPC_LL:
7971
    case OPC_SC:
7972
         gen_ldst(ctx, op, rt, rs, imm);
7973
         break;
7974
    case OPC_CACHE:
7975
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7976
        /* Treat as NOP. */
7977
        break;
7978
    case OPC_PREF:
7979
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7980
        /* Treat as NOP. */
7981
        break;
7982

    
7983
    /* Floating point (COP1). */
7984
    case OPC_LWC1:
7985
    case OPC_LDC1:
7986
    case OPC_SWC1:
7987
    case OPC_SDC1:
7988
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7989
            save_cpu_state(ctx, 1);
7990
            check_cp1_enabled(ctx);
7991
            gen_flt_ldst(ctx, op, rt, rs, imm);
7992
        } else {
7993
            generate_exception_err(ctx, EXCP_CpU, 1);
7994
        }
7995
        break;
7996

    
7997
    case OPC_CP1:
7998
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7999
            save_cpu_state(ctx, 1);
8000
            check_cp1_enabled(ctx);
8001
            op1 = MASK_CP1(ctx->opcode);
8002
            switch (op1) {
8003
            case OPC_MFHC1:
8004
            case OPC_MTHC1:
8005
                check_insn(env, ctx, ISA_MIPS32R2);
8006
            case OPC_MFC1:
8007
            case OPC_CFC1:
8008
            case OPC_MTC1:
8009
            case OPC_CTC1:
8010
                gen_cp1(ctx, op1, rt, rd);
8011
                break;
8012
#if defined(TARGET_MIPS64)
8013
            case OPC_DMFC1:
8014
            case OPC_DMTC1:
8015
                check_insn(env, ctx, ISA_MIPS3);
8016
                gen_cp1(ctx, op1, rt, rd);
8017
                break;
8018
#endif
8019
            case OPC_BC1ANY2:
8020
            case OPC_BC1ANY4:
8021
                check_cop1x(ctx);
8022
                check_insn(env, ctx, ASE_MIPS3D);
8023
                /* fall through */
8024
            case OPC_BC1:
8025
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8026
                                    (rt >> 2) & 0x7, imm << 2);
8027
                return;
8028
            case OPC_S_FMT:
8029
            case OPC_D_FMT:
8030
            case OPC_W_FMT:
8031
            case OPC_L_FMT:
8032
            case OPC_PS_FMT:
8033
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8034
                           (imm >> 8) & 0x7);
8035
                break;
8036
            default:
8037
                MIPS_INVAL("cp1");
8038
                generate_exception (ctx, EXCP_RI);
8039
                break;
8040
            }
8041
        } else {
8042
            generate_exception_err(ctx, EXCP_CpU, 1);
8043
        }
8044
        break;
8045

    
8046
    /* COP2.  */
8047
    case OPC_LWC2:
8048
    case OPC_LDC2:
8049
    case OPC_SWC2:
8050
    case OPC_SDC2:
8051
    case OPC_CP2:
8052
        /* COP2: Not implemented. */
8053
        generate_exception_err(ctx, EXCP_CpU, 2);
8054
        break;
8055

    
8056
    case OPC_CP3:
8057
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8058
            save_cpu_state(ctx, 1);
8059
            check_cp1_enabled(ctx);
8060
            op1 = MASK_CP3(ctx->opcode);
8061
            switch (op1) {
8062
            case OPC_LWXC1:
8063
            case OPC_LDXC1:
8064
            case OPC_LUXC1:
8065
            case OPC_SWXC1:
8066
            case OPC_SDXC1:
8067
            case OPC_SUXC1:
8068
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8069
                break;
8070
            case OPC_PREFX:
8071
                /* Treat as NOP. */
8072
                break;
8073
            case OPC_ALNV_PS:
8074
            case OPC_MADD_S:
8075
            case OPC_MADD_D:
8076
            case OPC_MADD_PS:
8077
            case OPC_MSUB_S:
8078
            case OPC_MSUB_D:
8079
            case OPC_MSUB_PS:
8080
            case OPC_NMADD_S:
8081
            case OPC_NMADD_D:
8082
            case OPC_NMADD_PS:
8083
            case OPC_NMSUB_S:
8084
            case OPC_NMSUB_D:
8085
            case OPC_NMSUB_PS:
8086
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8087
                break;
8088
            default:
8089
                MIPS_INVAL("cp3");
8090
                generate_exception (ctx, EXCP_RI);
8091
                break;
8092
            }
8093
        } else {
8094
            generate_exception_err(ctx, EXCP_CpU, 1);
8095
        }
8096
        break;
8097

    
8098
#if defined(TARGET_MIPS64)
8099
    /* MIPS64 opcodes */
8100
    case OPC_LWU:
8101
    case OPC_LDL ... OPC_LDR:
8102
    case OPC_SDL ... OPC_SDR:
8103
    case OPC_LLD:
8104
    case OPC_LD:
8105
    case OPC_SCD:
8106
    case OPC_SD:
8107
        check_insn(env, ctx, ISA_MIPS3);
8108
        check_mips_64(ctx);
8109
        gen_ldst(ctx, op, rt, rs, imm);
8110
        break;
8111
    case OPC_DADDI ... OPC_DADDIU:
8112
        check_insn(env, ctx, ISA_MIPS3);
8113
        check_mips_64(ctx);
8114
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8115
        break;
8116
#endif
8117
    case OPC_JALX:
8118
        check_insn(env, ctx, ASE_MIPS16);
8119
        /* MIPS16: Not implemented. */
8120
    case OPC_MDMX:
8121
        check_insn(env, ctx, ASE_MDMX);
8122
        /* MDMX: Not implemented. */
8123
    default:            /* Invalid */
8124
        MIPS_INVAL("major opcode");
8125
        generate_exception(ctx, EXCP_RI);
8126
        break;
8127
    }
8128
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8129
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8130
        /* Branches completion */
8131
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8132
        ctx->bstate = BS_BRANCH;
8133
        save_cpu_state(ctx, 0);
8134
        /* FIXME: Need to clear can_do_io.  */
8135
        switch (hflags) {
8136
        case MIPS_HFLAG_B:
8137
            /* unconditional branch */
8138
            MIPS_DEBUG("unconditional branch");
8139
            gen_goto_tb(ctx, 0, ctx->btarget);
8140
            break;
8141
        case MIPS_HFLAG_BL:
8142
            /* blikely taken case */
8143
            MIPS_DEBUG("blikely branch taken");
8144
            gen_goto_tb(ctx, 0, ctx->btarget);
8145
            break;
8146
        case MIPS_HFLAG_BC:
8147
            /* Conditional branch */
8148
            MIPS_DEBUG("conditional branch");
8149
            {
8150
                int l1 = gen_new_label();
8151

    
8152
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8153
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8154
                gen_set_label(l1);
8155
                gen_goto_tb(ctx, 0, ctx->btarget);
8156
            }
8157
            break;
8158
        case MIPS_HFLAG_BR:
8159
            /* unconditional branch to register */
8160
            MIPS_DEBUG("branch to register");
8161
            tcg_gen_mov_tl(cpu_PC, btarget);
8162
            tcg_gen_exit_tb(0);
8163
            break;
8164
        default:
8165
            MIPS_DEBUG("unknown branch");
8166
            break;
8167
        }
8168
    }
8169
}
8170

    
8171
static inline void
8172
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8173
                                int search_pc)
8174
{
8175
    DisasContext ctx;
8176
    target_ulong pc_start;
8177
    uint16_t *gen_opc_end;
8178
    CPUBreakpoint *bp;
8179
    int j, lj = -1;
8180
    int num_insns;
8181
    int max_insns;
8182

    
8183
    if (search_pc && loglevel)
8184
        fprintf (logfile, "search pc %d\n", search_pc);
8185

    
8186
    pc_start = tb->pc;
8187
    /* Leave some spare opc slots for branch handling. */
8188
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8189
    ctx.pc = pc_start;
8190
    ctx.saved_pc = -1;
8191
    ctx.tb = tb;
8192
    ctx.bstate = BS_NONE;
8193
    /* Restore delay slot state from the tb context.  */
8194
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8195
    restore_cpu_state(env, &ctx);
8196
#ifdef CONFIG_USER_ONLY
8197
        ctx.mem_idx = MIPS_HFLAG_UM;
8198
#else
8199
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8200
#endif
8201
    num_insns = 0;
8202
    max_insns = tb->cflags & CF_COUNT_MASK;
8203
    if (max_insns == 0)
8204
        max_insns = CF_COUNT_MASK;
8205
#ifdef DEBUG_DISAS
8206
    if (loglevel & CPU_LOG_TB_CPU) {
8207
        fprintf(logfile, "------------------------------------------------\n");
8208
        /* FIXME: This may print out stale hflags from env... */
8209
        cpu_dump_state(env, logfile, fprintf, 0);
8210
    }
8211
#endif
8212
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8213
    gen_icount_start();
8214
    while (ctx.bstate == BS_NONE) {
8215
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8216
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8217
                if (bp->pc == ctx.pc) {
8218
                    save_cpu_state(&ctx, 1);
8219
                    ctx.bstate = BS_BRANCH;
8220
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8221
                    /* Include the breakpoint location or the tb won't
8222
                     * be flushed when it must be.  */
8223
                    ctx.pc += 4;
8224
                    goto done_generating;
8225
                }
8226
            }
8227
        }
8228

    
8229
        if (search_pc) {
8230
            j = gen_opc_ptr - gen_opc_buf;
8231
            if (lj < j) {
8232
                lj++;
8233
                while (lj < j)
8234
                    gen_opc_instr_start[lj++] = 0;
8235
            }
8236
            gen_opc_pc[lj] = ctx.pc;
8237
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8238
            gen_opc_instr_start[lj] = 1;
8239
            gen_opc_icount[lj] = num_insns;
8240
        }
8241
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8242
            gen_io_start();
8243
        ctx.opcode = ldl_code(ctx.pc);
8244
        decode_opc(env, &ctx);
8245
        ctx.pc += 4;
8246
        num_insns++;
8247

    
8248
        if (env->singlestep_enabled)
8249
            break;
8250

    
8251
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8252
            break;
8253

    
8254
        if (gen_opc_ptr >= gen_opc_end)
8255
            break;
8256

    
8257
        if (num_insns >= max_insns)
8258
            break;
8259
#if defined (MIPS_SINGLE_STEP)
8260
        break;
8261
#endif
8262
    }
8263
    if (tb->cflags & CF_LAST_IO)
8264
        gen_io_end();
8265
    if (env->singlestep_enabled) {
8266
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8267
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8268
    } else {
8269
        switch (ctx.bstate) {
8270
        case BS_STOP:
8271
            gen_helper_interrupt_restart();
8272
            gen_goto_tb(&ctx, 0, ctx.pc);
8273
            break;
8274
        case BS_NONE:
8275
            save_cpu_state(&ctx, 0);
8276
            gen_goto_tb(&ctx, 0, ctx.pc);
8277
            break;
8278
        case BS_EXCP:
8279
            gen_helper_interrupt_restart();
8280
            tcg_gen_exit_tb(0);
8281
            break;
8282
        case BS_BRANCH:
8283
        default:
8284
            break;
8285
        }
8286
    }
8287
done_generating:
8288
    gen_icount_end(tb, num_insns);
8289
    *gen_opc_ptr = INDEX_op_end;
8290
    if (search_pc) {
8291
        j = gen_opc_ptr - gen_opc_buf;
8292
        lj++;
8293
        while (lj <= j)
8294
            gen_opc_instr_start[lj++] = 0;
8295
    } else {
8296
        tb->size = ctx.pc - pc_start;
8297
        tb->icount = num_insns;
8298
    }
8299
#ifdef DEBUG_DISAS
8300
    LOG_DISAS("\n");
8301
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8302
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8303
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8304
        fprintf(logfile, "\n");
8305
    }
8306
    if (loglevel & CPU_LOG_TB_CPU) {
8307
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8308
    }
8309
#endif
8310
}
8311

    
8312
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8313
{
8314
    gen_intermediate_code_internal(env, tb, 0);
8315
}
8316

    
8317
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8318
{
8319
    gen_intermediate_code_internal(env, tb, 1);
8320
}
8321

    
8322
static void fpu_dump_state(CPUState *env, FILE *f,
8323
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8324
                           int flags)
8325
{
8326
    int i;
8327
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8328

    
8329
#define printfpr(fp)                                                        \
8330
    do {                                                                    \
8331
        if (is_fpu64)                                                       \
8332
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8333
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8334
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8335
        else {                                                              \
8336
            fpr_t tmp;                                                      \
8337
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8338
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8339
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8340
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8341
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8342
        }                                                                   \
8343
    } while(0)
8344

    
8345

    
8346
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8347
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8348
                get_float_exception_flags(&env->active_fpu.fp_status));
8349
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8350
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8351
        printfpr(&env->active_fpu.fpr[i]);
8352
    }
8353

    
8354
#undef printfpr
8355
}
8356

    
8357
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8358
/* Debug help: The architecture requires 32bit code to maintain proper
8359
   sign-extended values on 64bit machines.  */
8360

    
8361
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8362

    
8363
static void
8364
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8365
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8366
                                int flags)
8367
{
8368
    int i;
8369

    
8370
    if (!SIGN_EXT_P(env->active_tc.PC))
8371
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8372
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8373
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8374
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8375
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8376
    if (!SIGN_EXT_P(env->btarget))
8377
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8378

    
8379
    for (i = 0; i < 32; i++) {
8380
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8381
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8382
    }
8383

    
8384
    if (!SIGN_EXT_P(env->CP0_EPC))
8385
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8386
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8387
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8388
}
8389
#endif
8390

    
8391
void cpu_dump_state (CPUState *env, FILE *f,
8392
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8393
                     int flags)
8394
{
8395
    int i;
8396

    
8397
    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",
8398
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8399
                env->hflags, env->btarget, env->bcond);
8400
    for (i = 0; i < 32; i++) {
8401
        if ((i & 3) == 0)
8402
            cpu_fprintf(f, "GPR%02d:", i);
8403
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8404
        if ((i & 3) == 3)
8405
            cpu_fprintf(f, "\n");
8406
    }
8407

    
8408
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8409
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8410
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8411
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8412
    if (env->hflags & MIPS_HFLAG_FPU)
8413
        fpu_dump_state(env, f, cpu_fprintf, flags);
8414
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8415
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8416
#endif
8417
}
8418

    
8419
static void mips_tcg_init(void)
8420
{
8421
    int i;
8422
    static int inited;
8423

    
8424
    /* Initialize various static tables. */
8425
    if (inited)
8426
        return;
8427

    
8428
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8429
    for (i = 0; i < 32; i++)
8430
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8431
                                        offsetof(CPUState, active_tc.gpr[i]),
8432
                                        regnames[i]);
8433
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8434
                                offsetof(CPUState, active_tc.PC), "PC");
8435
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8436
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8437
                                       offsetof(CPUState, active_tc.HI[i]),
8438
                                       regnames_HI[i]);
8439
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8440
                                       offsetof(CPUState, active_tc.LO[i]),
8441
                                       regnames_LO[i]);
8442
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8443
                                        offsetof(CPUState, active_tc.ACX[i]),
8444
                                        regnames_ACX[i]);
8445
    }
8446
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8447
                                     offsetof(CPUState, active_tc.DSPControl),
8448
                                     "DSPControl");
8449
    bcond = tcg_global_mem_new_i32(TCG_AREG0,
8450
                                   offsetof(CPUState, bcond), "bcond");
8451
    btarget = tcg_global_mem_new(TCG_AREG0,
8452
                                 offsetof(CPUState, btarget), "btarget");
8453
    for (i = 0; i < 32; i++)
8454
        fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8455
            offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8456
            fregnames[i]);
8457
    for (i = 0; i < 32; i++)
8458
        fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
8459
            offsetof(CPUState, active_fpu.fpr[i]),
8460
            fregnames_64[i]);
8461
    for (i = 0; i < 32; i++)
8462
        fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8463
            offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8464
            fregnames_h[i]);
8465
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8466
                                      offsetof(CPUState, active_fpu.fcr0),
8467
                                      "fcr0");
8468
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8469
                                       offsetof(CPUState, active_fpu.fcr31),
8470
                                       "fcr31");
8471

    
8472
    /* register helpers */
8473
#define GEN_HELPER 2
8474
#include "helper.h"
8475

    
8476
    inited = 1;
8477
}
8478

    
8479
#include "translate_init.c"
8480

    
8481
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8482
{
8483
    CPUMIPSState *env;
8484
    const mips_def_t *def;
8485

    
8486
    def = cpu_mips_find_by_name(cpu_model);
8487
    if (!def)
8488
        return NULL;
8489
    env = qemu_mallocz(sizeof(CPUMIPSState));
8490
    if (!env)
8491
        return NULL;
8492
    env->cpu_model = def;
8493

    
8494
    cpu_exec_init(env);
8495
    env->cpu_model_str = cpu_model;
8496
    mips_tcg_init();
8497
    cpu_reset(env);
8498
    return env;
8499
}
8500

    
8501
void cpu_reset (CPUMIPSState *env)
8502
{
8503
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8504

    
8505
    tlb_flush(env, 1);
8506

    
8507
    /* Minimal init */
8508
#if defined(CONFIG_USER_ONLY)
8509
    env->hflags = MIPS_HFLAG_UM;
8510
#else
8511
    if (env->hflags & MIPS_HFLAG_BMASK) {
8512
        /* If the exception was raised from a delay slot,
8513
           come back to the jump.  */
8514
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8515
    } else {
8516
        env->CP0_ErrorEPC = env->active_tc.PC;
8517
    }
8518
    env->active_tc.PC = (int32_t)0xBFC00000;
8519
    env->CP0_Wired = 0;
8520
    /* SMP not implemented */
8521
    env->CP0_EBase = 0x80000000;
8522
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8523
    /* vectored interrupts not implemented, timer on int 7,
8524
       no performance counters. */
8525
    env->CP0_IntCtl = 0xe0000000;
8526
    {
8527
        int i;
8528

    
8529
        for (i = 0; i < 7; i++) {
8530
            env->CP0_WatchLo[i] = 0;
8531
            env->CP0_WatchHi[i] = 0x80000000;
8532
        }
8533
        env->CP0_WatchLo[7] = 0;
8534
        env->CP0_WatchHi[7] = 0;
8535
    }
8536
    /* Count register increments in debug mode, EJTAG version 1 */
8537
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8538
    env->hflags = MIPS_HFLAG_CP0;
8539
#endif
8540
    env->exception_index = EXCP_NONE;
8541
    cpu_mips_register(env, env->cpu_model);
8542
}
8543

    
8544
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8545
                unsigned long searched_pc, int pc_pos, void *puc)
8546
{
8547
    env->active_tc.PC = gen_opc_pc[pc_pos];
8548
    env->hflags &= ~MIPS_HFLAG_BMASK;
8549
    env->hflags |= gen_opc_hflags[pc_pos];
8550
}