Statistics
| Branch: | Revision:

root / target-mips / translate.c @ bf4120ad

History | View | Annotate | Download (286.6 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
 *  Copyright (c) 2009 CodeSourcery (MIPS16 support)
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21
 */
22

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

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

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

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

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

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

    
124
/* MIPS special opcodes */
125
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
126

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

    
196
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
197

    
198
    /* Special */
199
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
200
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
201
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
202
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
203
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
204

    
205
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
206
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
207
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
208
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
209
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
210
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
211
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
212
};
213

    
214
/* Multiplication variants of the vr54xx. */
215
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
216

    
217
enum {
218
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
219
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
220
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
221
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
222
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
223
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
224
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
225
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
226
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
227
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
228
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
229
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
230
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
231
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
232
};
233

    
234
/* REGIMM (rt field) opcodes */
235
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
236

    
237
enum {
238
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
239
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
240
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
241
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
242
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
243
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
244
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
245
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
246
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
247
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
248
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
249
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
250
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
251
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
252
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
253
};
254

    
255
/* Special2 opcodes */
256
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
257

    
258
enum {
259
    /* Multiply & xxx operations */
260
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
261
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
262
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
263
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
264
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
265
    /* Misc */
266
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
267
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
268
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
269
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
270
    /* Special */
271
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
272
};
273

    
274
/* Special3 opcodes */
275
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
276

    
277
enum {
278
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
279
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
280
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
281
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
282
    OPC_INS      = 0x04 | OPC_SPECIAL3,
283
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
284
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
285
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
286
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
287
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
288
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
289
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
290
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
291
};
292

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

    
296
enum {
297
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
298
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
299
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
300
};
301

    
302
/* DBSHFL opcodes */
303
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
304

    
305
enum {
306
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
307
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
308
};
309

    
310
/* Coprocessor 0 (rs field) */
311
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
312

    
313
enum {
314
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
315
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
316
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
317
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
318
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
319
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
320
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
321
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
322
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
323
    OPC_C0       = (0x10 << 21) | OPC_CP0,
324
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
325
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
326
};
327

    
328
/* MFMC0 opcodes */
329
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
330

    
331
enum {
332
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
333
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
334
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
335
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
336
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
337
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
338
};
339

    
340
/* Coprocessor 0 (with rs == C0) */
341
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
342

    
343
enum {
344
    OPC_TLBR     = 0x01 | OPC_C0,
345
    OPC_TLBWI    = 0x02 | OPC_C0,
346
    OPC_TLBWR    = 0x06 | OPC_C0,
347
    OPC_TLBP     = 0x08 | OPC_C0,
348
    OPC_RFE      = 0x10 | OPC_C0,
349
    OPC_ERET     = 0x18 | OPC_C0,
350
    OPC_DERET    = 0x1F | OPC_C0,
351
    OPC_WAIT     = 0x20 | OPC_C0,
352
};
353

    
354
/* Coprocessor 1 (rs field) */
355
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
356

    
357
/* Values for the fmt field in FP instructions */
358
enum {
359
    /* 0 - 15 are reserved */
360
    FMT_S = 16,
361
    FMT_D = 17,
362
    FMT_E = 18,
363
    FMT_Q = 19,
364
    FMT_W = 20,
365
    FMT_L = 21,
366
    FMT_PS = 22,
367
    /* 23 - 31 are reserved */
368
};
369

    
370
enum {
371
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
372
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
373
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
374
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
375
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
376
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
377
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
378
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
379
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
380
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
381
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
382
    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,  /* 16: fmt=single fp */
383
    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,  /* 17: fmt=double fp */
384
    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,  /* 18: fmt=extended fp */
385
    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,  /* 19: fmt=quad fp */
386
    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,  /* 20: fmt=32bit fixed */
387
    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,  /* 21: fmt=64bit fixed */
388
    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1, /* 22: fmt=paired single fp */
389
};
390

    
391
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
392
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
393

    
394
enum {
395
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
396
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
397
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
398
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
399
};
400

    
401
enum {
402
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
403
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
404
};
405

    
406
enum {
407
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
408
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
409
};
410

    
411
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
412

    
413
enum {
414
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
415
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
416
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
417
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
418
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
419
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
420
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
421
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
422
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
423
};
424

    
425
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
426

    
427
enum {
428
    OPC_LWXC1   = 0x00 | OPC_CP3,
429
    OPC_LDXC1   = 0x01 | OPC_CP3,
430
    OPC_LUXC1   = 0x05 | OPC_CP3,
431
    OPC_SWXC1   = 0x08 | OPC_CP3,
432
    OPC_SDXC1   = 0x09 | OPC_CP3,
433
    OPC_SUXC1   = 0x0D | OPC_CP3,
434
    OPC_PREFX   = 0x0F | OPC_CP3,
435
    OPC_ALNV_PS = 0x1E | OPC_CP3,
436
    OPC_MADD_S  = 0x20 | OPC_CP3,
437
    OPC_MADD_D  = 0x21 | OPC_CP3,
438
    OPC_MADD_PS = 0x26 | OPC_CP3,
439
    OPC_MSUB_S  = 0x28 | OPC_CP3,
440
    OPC_MSUB_D  = 0x29 | OPC_CP3,
441
    OPC_MSUB_PS = 0x2E | OPC_CP3,
442
    OPC_NMADD_S = 0x30 | OPC_CP3,
443
    OPC_NMADD_D = 0x31 | OPC_CP3,
444
    OPC_NMADD_PS= 0x36 | OPC_CP3,
445
    OPC_NMSUB_S = 0x38 | OPC_CP3,
446
    OPC_NMSUB_D = 0x39 | OPC_CP3,
447
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
448
};
449

    
450
/* global register indices */
451
static TCGv_ptr cpu_env;
452
static TCGv cpu_gpr[32], cpu_PC;
453
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
454
static TCGv cpu_dspctrl, btarget, bcond;
455
static TCGv_i32 hflags;
456
static TCGv_i32 fpu_fcr0, fpu_fcr31;
457

    
458
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
459

    
460
#include "gen-icount.h"
461

    
462
#define gen_helper_0i(name, arg) do {                             \
463
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
464
    gen_helper_##name(helper_tmp);                                \
465
    tcg_temp_free_i32(helper_tmp);                                \
466
    } while(0)
467

    
468
#define gen_helper_1i(name, arg1, arg2) do {                      \
469
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
470
    gen_helper_##name(arg1, helper_tmp);                          \
471
    tcg_temp_free_i32(helper_tmp);                                \
472
    } while(0)
473

    
474
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
475
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
476
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
477
    tcg_temp_free_i32(helper_tmp);                                \
478
    } while(0)
479

    
480
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
481
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
482
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
483
    tcg_temp_free_i32(helper_tmp);                                \
484
    } while(0)
485

    
486
typedef struct DisasContext {
487
    struct TranslationBlock *tb;
488
    target_ulong pc, saved_pc;
489
    uint32_t opcode;
490
    int singlestep_enabled;
491
    /* Routine used to access memory */
492
    int mem_idx;
493
    uint32_t hflags, saved_hflags;
494
    int bstate;
495
    target_ulong btarget;
496
} DisasContext;
497

    
498
enum {
499
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
500
                      * exception condition */
501
    BS_STOP     = 1, /* We want to stop translation for any reason */
502
    BS_BRANCH   = 2, /* We reached a branch condition     */
503
    BS_EXCP     = 3, /* We reached an exception condition */
504
};
505

    
506
static const char *regnames[] =
507
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
508
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
509
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
510
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
511

    
512
static const char *regnames_HI[] =
513
    { "HI0", "HI1", "HI2", "HI3", };
514

    
515
static const char *regnames_LO[] =
516
    { "LO0", "LO1", "LO2", "LO3", };
517

    
518
static const char *regnames_ACX[] =
519
    { "ACX0", "ACX1", "ACX2", "ACX3", };
520

    
521
static const char *fregnames[] =
522
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
523
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
524
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
525
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
526

    
527
#ifdef MIPS_DEBUG_DISAS
528
#define MIPS_DEBUG(fmt, ...)                         \
529
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
530
                       TARGET_FMT_lx ": %08x " fmt "\n", \
531
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
532
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
533
#else
534
#define MIPS_DEBUG(fmt, ...) do { } while(0)
535
#define LOG_DISAS(...) do { } while (0)
536
#endif
537

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

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

    
553
static inline void gen_store_gpr (TCGv t, int reg)
554
{
555
    if (reg != 0)
556
        tcg_gen_mov_tl(cpu_gpr[reg], t);
557
}
558

    
559
/* Moves to/from ACX register.  */
560
static inline void gen_load_ACX (TCGv t, int reg)
561
{
562
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
563
}
564

    
565
static inline void gen_store_ACX (TCGv t, int reg)
566
{
567
    tcg_gen_mov_tl(cpu_ACX[reg], t);
568
}
569

    
570
/* Moves to/from shadow registers. */
571
static inline void gen_load_srsgpr (int from, int to)
572
{
573
    TCGv t0 = tcg_temp_new();
574

    
575
    if (from == 0)
576
        tcg_gen_movi_tl(t0, 0);
577
    else {
578
        TCGv_i32 t2 = tcg_temp_new_i32();
579
        TCGv_ptr addr = tcg_temp_new_ptr();
580

    
581
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
582
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
583
        tcg_gen_andi_i32(t2, t2, 0xf);
584
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
585
        tcg_gen_ext_i32_ptr(addr, t2);
586
        tcg_gen_add_ptr(addr, cpu_env, addr);
587

    
588
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
589
        tcg_temp_free_ptr(addr);
590
        tcg_temp_free_i32(t2);
591
    }
592
    gen_store_gpr(t0, to);
593
    tcg_temp_free(t0);
594
}
595

    
596
static inline void gen_store_srsgpr (int from, int to)
597
{
598
    if (to != 0) {
599
        TCGv t0 = tcg_temp_new();
600
        TCGv_i32 t2 = tcg_temp_new_i32();
601
        TCGv_ptr addr = tcg_temp_new_ptr();
602

    
603
        gen_load_gpr(t0, from);
604
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
605
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
606
        tcg_gen_andi_i32(t2, t2, 0xf);
607
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
608
        tcg_gen_ext_i32_ptr(addr, t2);
609
        tcg_gen_add_ptr(addr, cpu_env, addr);
610

    
611
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
612
        tcg_temp_free_ptr(addr);
613
        tcg_temp_free_i32(t2);
614
        tcg_temp_free(t0);
615
    }
616
}
617

    
618
/* Floating point register moves. */
619
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
620
{
621
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
622
}
623

    
624
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
625
{
626
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
627
}
628

    
629
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
630
{
631
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
632
}
633

    
634
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
635
{
636
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
637
}
638

    
639
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
640
{
641
    if (ctx->hflags & MIPS_HFLAG_F64) {
642
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
643
    } else {
644
        TCGv_i32 t0 = tcg_temp_new_i32();
645
        TCGv_i32 t1 = tcg_temp_new_i32();
646
        gen_load_fpr32(t0, reg & ~1);
647
        gen_load_fpr32(t1, reg | 1);
648
        tcg_gen_concat_i32_i64(t, t0, t1);
649
        tcg_temp_free_i32(t0);
650
        tcg_temp_free_i32(t1);
651
    }
652
}
653

    
654
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
655
{
656
    if (ctx->hflags & MIPS_HFLAG_F64) {
657
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
658
    } else {
659
        TCGv_i64 t0 = tcg_temp_new_i64();
660
        TCGv_i32 t1 = tcg_temp_new_i32();
661
        tcg_gen_trunc_i64_i32(t1, t);
662
        gen_store_fpr32(t1, reg & ~1);
663
        tcg_gen_shri_i64(t0, t, 32);
664
        tcg_gen_trunc_i64_i32(t1, t0);
665
        gen_store_fpr32(t1, reg | 1);
666
        tcg_temp_free_i32(t1);
667
        tcg_temp_free_i64(t0);
668
    }
669
}
670

    
671
static inline int get_fp_bit (int cc)
672
{
673
    if (cc)
674
        return 24 + cc;
675
    else
676
        return 23;
677
}
678

    
679
#define FOP_CONDS(type, fmt, bits)                                            \
680
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
681
                                               TCGv_i##bits b, int cc)        \
682
{                                                                             \
683
    switch (n) {                                                              \
684
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
685
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
686
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
687
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
688
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
689
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
690
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
691
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
692
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
693
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
694
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
695
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
696
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
697
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
698
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
699
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
700
    default: abort();                                                         \
701
    }                                                                         \
702
}
703

    
704
FOP_CONDS(, d, 64)
705
FOP_CONDS(abs, d, 64)
706
FOP_CONDS(, s, 32)
707
FOP_CONDS(abs, s, 32)
708
FOP_CONDS(, ps, 64)
709
FOP_CONDS(abs, ps, 64)
710
#undef FOP_CONDS
711

    
712
/* Tests */
713
static inline void gen_save_pc(target_ulong pc)
714
{
715
    tcg_gen_movi_tl(cpu_PC, pc);
716
}
717

    
718
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
719
{
720
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
721
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
722
        gen_save_pc(ctx->pc);
723
        ctx->saved_pc = ctx->pc;
724
    }
725
    if (ctx->hflags != ctx->saved_hflags) {
726
        tcg_gen_movi_i32(hflags, ctx->hflags);
727
        ctx->saved_hflags = ctx->hflags;
728
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
729
        case MIPS_HFLAG_BR:
730
            break;
731
        case MIPS_HFLAG_BC:
732
        case MIPS_HFLAG_BL:
733
        case MIPS_HFLAG_B:
734
            tcg_gen_movi_tl(btarget, ctx->btarget);
735
            break;
736
        }
737
    }
738
}
739

    
740
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
741
{
742
    ctx->saved_hflags = ctx->hflags;
743
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
744
    case MIPS_HFLAG_BR:
745
        break;
746
    case MIPS_HFLAG_BC:
747
    case MIPS_HFLAG_BL:
748
    case MIPS_HFLAG_B:
749
        ctx->btarget = env->btarget;
750
        break;
751
    }
752
}
753

    
754
static inline void
755
generate_exception_err (DisasContext *ctx, int excp, int err)
756
{
757
    TCGv_i32 texcp = tcg_const_i32(excp);
758
    TCGv_i32 terr = tcg_const_i32(err);
759
    save_cpu_state(ctx, 1);
760
    gen_helper_raise_exception_err(texcp, terr);
761
    tcg_temp_free_i32(terr);
762
    tcg_temp_free_i32(texcp);
763
}
764

    
765
static inline void
766
generate_exception (DisasContext *ctx, int excp)
767
{
768
    save_cpu_state(ctx, 1);
769
    gen_helper_0i(raise_exception, excp);
770
}
771

    
772
/* Addresses computation */
773
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
774
{
775
    tcg_gen_add_tl(ret, arg0, arg1);
776

    
777
#if defined(TARGET_MIPS64)
778
    /* For compatibility with 32-bit code, data reference in user mode
779
       with Status_UX = 0 should be casted to 32-bit and sign extended.
780
       See the MIPS64 PRA manual, section 4.10. */
781
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
782
        !(ctx->hflags & MIPS_HFLAG_UX)) {
783
        tcg_gen_ext32s_i64(ret, ret);
784
    }
785
#endif
786
}
787

    
788
static inline void check_cp0_enabled(DisasContext *ctx)
789
{
790
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
791
        generate_exception_err(ctx, EXCP_CpU, 0);
792
}
793

    
794
static inline void check_cp1_enabled(DisasContext *ctx)
795
{
796
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
797
        generate_exception_err(ctx, EXCP_CpU, 1);
798
}
799

    
800
/* Verify that the processor is running with COP1X instructions enabled.
801
   This is associated with the nabla symbol in the MIPS32 and MIPS64
802
   opcode tables.  */
803

    
804
static inline void check_cop1x(DisasContext *ctx)
805
{
806
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
807
        generate_exception(ctx, EXCP_RI);
808
}
809

    
810
/* Verify that the processor is running with 64-bit floating-point
811
   operations enabled.  */
812

    
813
static inline void check_cp1_64bitmode(DisasContext *ctx)
814
{
815
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
816
        generate_exception(ctx, EXCP_RI);
817
}
818

    
819
/*
820
 * Verify if floating point register is valid; an operation is not defined
821
 * if bit 0 of any register specification is set and the FR bit in the
822
 * Status register equals zero, since the register numbers specify an
823
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
824
 * in the Status register equals one, both even and odd register numbers
825
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
826
 *
827
 * Multiple 64 bit wide registers can be checked by calling
828
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
829
 */
830
static inline void check_cp1_registers(DisasContext *ctx, int regs)
831
{
832
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
833
        generate_exception(ctx, EXCP_RI);
834
}
835

    
836
/* This code generates a "reserved instruction" exception if the
837
   CPU does not support the instruction set corresponding to flags. */
838
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
839
{
840
    if (unlikely(!(env->insn_flags & flags)))
841
        generate_exception(ctx, EXCP_RI);
842
}
843

    
844
/* This code generates a "reserved instruction" exception if 64-bit
845
   instructions are not enabled. */
846
static inline void check_mips_64(DisasContext *ctx)
847
{
848
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/* load/store instructions. */
853
#define OP_LD(insn,fname)                                                 \
854
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
855
{                                                                         \
856
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
857
}
858
OP_LD(lb,ld8s);
859
OP_LD(lbu,ld8u);
860
OP_LD(lh,ld16s);
861
OP_LD(lhu,ld16u);
862
OP_LD(lw,ld32s);
863
#if defined(TARGET_MIPS64)
864
OP_LD(lwu,ld32u);
865
OP_LD(ld,ld64);
866
#endif
867
#undef OP_LD
868

    
869
#define OP_ST(insn,fname)                                                  \
870
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
871
{                                                                          \
872
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
873
}
874
OP_ST(sb,st8);
875
OP_ST(sh,st16);
876
OP_ST(sw,st32);
877
#if defined(TARGET_MIPS64)
878
OP_ST(sd,st64);
879
#endif
880
#undef OP_ST
881

    
882
#ifdef CONFIG_USER_ONLY
883
#define OP_LD_ATOMIC(insn,fname)                                           \
884
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
885
{                                                                          \
886
    TCGv t0 = tcg_temp_new();                                              \
887
    tcg_gen_mov_tl(t0, arg1);                                              \
888
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
889
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
890
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
891
    tcg_temp_free(t0);                                                     \
892
}
893
#else
894
#define OP_LD_ATOMIC(insn,fname)                                           \
895
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
896
{                                                                          \
897
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
898
}
899
#endif
900
OP_LD_ATOMIC(ll,ld32s);
901
#if defined(TARGET_MIPS64)
902
OP_LD_ATOMIC(lld,ld64);
903
#endif
904
#undef OP_LD_ATOMIC
905

    
906
#ifdef CONFIG_USER_ONLY
907
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
908
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
909
{                                                                            \
910
    TCGv t0 = tcg_temp_new();                                                \
911
    int l1 = gen_new_label();                                                \
912
    int l2 = gen_new_label();                                                \
913
                                                                             \
914
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
915
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
916
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
917
    generate_exception(ctx, EXCP_AdES);                                      \
918
    gen_set_label(l1);                                                       \
919
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
920
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
921
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
922
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
923
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
924
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
925
    gen_set_label(l2);                                                       \
926
    tcg_gen_movi_tl(t0, 0);                                                  \
927
    gen_store_gpr(t0, rt);                                                   \
928
    tcg_temp_free(t0);                                                       \
929
}
930
#else
931
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
932
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
933
{                                                                            \
934
    TCGv t0 = tcg_temp_new();                                                \
935
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
936
    gen_store_gpr(t0, rt);                                                   \
937
    tcg_temp_free(t0);                                                       \
938
}
939
#endif
940
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
941
#if defined(TARGET_MIPS64)
942
OP_ST_ATOMIC(scd,st64,ld64,0x7);
943
#endif
944
#undef OP_ST_ATOMIC
945

    
946
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
947
                                  int base, int16_t offset)
948
{
949
    if (base == 0) {
950
        tcg_gen_movi_tl(addr, offset);
951
    } else if (offset == 0) {
952
        gen_load_gpr(addr, base);
953
    } else {
954
        tcg_gen_movi_tl(addr, offset);
955
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
956
    }
957
}
958

    
959
static target_ulong pc_relative_pc (DisasContext *ctx)
960
{
961
    target_ulong pc = ctx->pc;
962

    
963
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
964
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
965

    
966
        pc -= branch_bytes;
967
    }
968

    
969
    pc &= ~(target_ulong)3;
970
    return pc;
971
}
972

    
973
/* Load and store */
974
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
975
                      int base, int16_t offset)
976
{
977
    const char *opn = "ldst";
978
    TCGv t0 = tcg_temp_new();
979
    TCGv t1 = tcg_temp_new();
980

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

    
1137
/* Store conditional */
1138
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1139
                         int base, int16_t offset)
1140
{
1141
    const char *opn = "st_cond";
1142
    TCGv t0, t1;
1143

    
1144
    t0 = tcg_temp_local_new();
1145

    
1146
    gen_base_offset_addr(ctx, t0, base, offset);
1147
    /* Don't do NOP if destination is zero: we must perform the actual
1148
       memory access. */
1149

    
1150
    t1 = tcg_temp_local_new();
1151
    gen_load_gpr(t1, rt);
1152
    switch (opc) {
1153
#if defined(TARGET_MIPS64)
1154
    case OPC_SCD:
1155
        save_cpu_state(ctx, 0);
1156
        op_ldst_scd(t1, t0, rt, ctx);
1157
        opn = "scd";
1158
        break;
1159
#endif
1160
    case OPC_SC:
1161
        save_cpu_state(ctx, 1);
1162
        op_ldst_sc(t1, t0, rt, ctx);
1163
        opn = "sc";
1164
        break;
1165
    }
1166
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1167
    tcg_temp_free(t1);
1168
    tcg_temp_free(t0);
1169
}
1170

    
1171
/* Load and store */
1172
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1173
                          int base, int16_t offset)
1174
{
1175
    const char *opn = "flt_ldst";
1176
    TCGv t0 = tcg_temp_new();
1177

    
1178
    gen_base_offset_addr(ctx, t0, base, offset);
1179
    /* Don't do NOP if destination is zero: we must perform the actual
1180
       memory access. */
1181
    switch (opc) {
1182
    case OPC_LWC1:
1183
        {
1184
            TCGv_i32 fp0 = tcg_temp_new_i32();
1185

    
1186
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1187
            tcg_gen_trunc_tl_i32(fp0, t0);
1188
            gen_store_fpr32(fp0, ft);
1189
            tcg_temp_free_i32(fp0);
1190
        }
1191
        opn = "lwc1";
1192
        break;
1193
    case OPC_SWC1:
1194
        {
1195
            TCGv_i32 fp0 = tcg_temp_new_i32();
1196
            TCGv t1 = tcg_temp_new();
1197

    
1198
            gen_load_fpr32(fp0, ft);
1199
            tcg_gen_extu_i32_tl(t1, fp0);
1200
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1201
            tcg_temp_free(t1);
1202
            tcg_temp_free_i32(fp0);
1203
        }
1204
        opn = "swc1";
1205
        break;
1206
    case OPC_LDC1:
1207
        {
1208
            TCGv_i64 fp0 = tcg_temp_new_i64();
1209

    
1210
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1211
            gen_store_fpr64(ctx, fp0, ft);
1212
            tcg_temp_free_i64(fp0);
1213
        }
1214
        opn = "ldc1";
1215
        break;
1216
    case OPC_SDC1:
1217
        {
1218
            TCGv_i64 fp0 = tcg_temp_new_i64();
1219

    
1220
            gen_load_fpr64(ctx, fp0, ft);
1221
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1222
            tcg_temp_free_i64(fp0);
1223
        }
1224
        opn = "sdc1";
1225
        break;
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        goto out;
1230
    }
1231
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1232
 out:
1233
    tcg_temp_free(t0);
1234
}
1235

    
1236
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1237
                          uint32_t op, int rt, int rs, int16_t imm)
1238
{
1239
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1240
        check_cp1_enabled(ctx);
1241
        gen_flt_ldst(ctx, op, rt, rs, imm);
1242
    } else {
1243
        generate_exception_err(ctx, EXCP_CpU, 1);
1244
    }
1245
}
1246

    
1247
/* Arithmetic with immediate operand */
1248
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1249
                           int rt, int rs, int16_t imm)
1250
{
1251
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1252
    const char *opn = "imm arith";
1253

    
1254
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1255
        /* If no destination, treat it as a NOP.
1256
           For addi, we must generate the overflow exception when needed. */
1257
        MIPS_DEBUG("NOP");
1258
        return;
1259
    }
1260
    switch (opc) {
1261
    case OPC_ADDI:
1262
        {
1263
            TCGv t0 = tcg_temp_local_new();
1264
            TCGv t1 = tcg_temp_new();
1265
            TCGv t2 = tcg_temp_new();
1266
            int l1 = gen_new_label();
1267

    
1268
            gen_load_gpr(t1, rs);
1269
            tcg_gen_addi_tl(t0, t1, uimm);
1270
            tcg_gen_ext32s_tl(t0, t0);
1271

    
1272
            tcg_gen_xori_tl(t1, t1, ~uimm);
1273
            tcg_gen_xori_tl(t2, t0, uimm);
1274
            tcg_gen_and_tl(t1, t1, t2);
1275
            tcg_temp_free(t2);
1276
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1277
            tcg_temp_free(t1);
1278
            /* operands of same sign, result different sign */
1279
            generate_exception(ctx, EXCP_OVERFLOW);
1280
            gen_set_label(l1);
1281
            tcg_gen_ext32s_tl(t0, t0);
1282
            gen_store_gpr(t0, rt);
1283
            tcg_temp_free(t0);
1284
        }
1285
        opn = "addi";
1286
        break;
1287
    case OPC_ADDIU:
1288
        if (rs != 0) {
1289
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1290
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1291
        } else {
1292
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1293
        }
1294
        opn = "addiu";
1295
        break;
1296
#if defined(TARGET_MIPS64)
1297
    case OPC_DADDI:
1298
        {
1299
            TCGv t0 = tcg_temp_local_new();
1300
            TCGv t1 = tcg_temp_new();
1301
            TCGv t2 = tcg_temp_new();
1302
            int l1 = gen_new_label();
1303

    
1304
            gen_load_gpr(t1, rs);
1305
            tcg_gen_addi_tl(t0, t1, uimm);
1306

    
1307
            tcg_gen_xori_tl(t1, t1, ~uimm);
1308
            tcg_gen_xori_tl(t2, t0, uimm);
1309
            tcg_gen_and_tl(t1, t1, t2);
1310
            tcg_temp_free(t2);
1311
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1312
            tcg_temp_free(t1);
1313
            /* operands of same sign, result different sign */
1314
            generate_exception(ctx, EXCP_OVERFLOW);
1315
            gen_set_label(l1);
1316
            gen_store_gpr(t0, rt);
1317
            tcg_temp_free(t0);
1318
        }
1319
        opn = "daddi";
1320
        break;
1321
    case OPC_DADDIU:
1322
        if (rs != 0) {
1323
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1324
        } else {
1325
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1326
        }
1327
        opn = "daddiu";
1328
        break;
1329
#endif
1330
    }
1331
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1332
}
1333

    
1334
/* Logic with immediate operand */
1335
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1336
{
1337
    target_ulong uimm;
1338
    const char *opn = "imm logic";
1339

    
1340
    if (rt == 0) {
1341
        /* If no destination, treat it as a NOP. */
1342
        MIPS_DEBUG("NOP");
1343
        return;
1344
    }
1345
    uimm = (uint16_t)imm;
1346
    switch (opc) {
1347
    case OPC_ANDI:
1348
        if (likely(rs != 0))
1349
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1350
        else
1351
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1352
        opn = "andi";
1353
        break;
1354
    case OPC_ORI:
1355
        if (rs != 0)
1356
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1357
        else
1358
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1359
        opn = "ori";
1360
        break;
1361
    case OPC_XORI:
1362
        if (likely(rs != 0))
1363
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1364
        else
1365
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1366
        opn = "xori";
1367
        break;
1368
    case OPC_LUI:
1369
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1370
        opn = "lui";
1371
        break;
1372
    }
1373
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1374
}
1375

    
1376
/* Set on less than with immediate operand */
1377
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1378
{
1379
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1380
    const char *opn = "imm arith";
1381
    TCGv t0;
1382

    
1383
    if (rt == 0) {
1384
        /* If no destination, treat it as a NOP. */
1385
        MIPS_DEBUG("NOP");
1386
        return;
1387
    }
1388
    t0 = tcg_temp_new();
1389
    gen_load_gpr(t0, rs);
1390
    switch (opc) {
1391
    case OPC_SLTI:
1392
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1393
        opn = "slti";
1394
        break;
1395
    case OPC_SLTIU:
1396
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1397
        opn = "sltiu";
1398
        break;
1399
    }
1400
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1401
    tcg_temp_free(t0);
1402
}
1403

    
1404
/* Shifts with immediate operand */
1405
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1406
                          int rt, int rs, int16_t imm)
1407
{
1408
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1409
    const char *opn = "imm shift";
1410
    TCGv t0;
1411

    
1412
    if (rt == 0) {
1413
        /* If no destination, treat it as a NOP. */
1414
        MIPS_DEBUG("NOP");
1415
        return;
1416
    }
1417

    
1418
    t0 = tcg_temp_new();
1419
    gen_load_gpr(t0, rs);
1420
    switch (opc) {
1421
    case OPC_SLL:
1422
        tcg_gen_shli_tl(t0, t0, uimm);
1423
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1424
        opn = "sll";
1425
        break;
1426
    case OPC_SRA:
1427
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1428
        opn = "sra";
1429
        break;
1430
    case OPC_SRL:
1431
        if (uimm != 0) {
1432
            tcg_gen_ext32u_tl(t0, t0);
1433
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1434
        } else {
1435
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1436
        }
1437
        opn = "srl";
1438
        break;
1439
    case OPC_ROTR:
1440
        if (uimm != 0) {
1441
            TCGv_i32 t1 = tcg_temp_new_i32();
1442

    
1443
            tcg_gen_trunc_tl_i32(t1, t0);
1444
            tcg_gen_rotri_i32(t1, t1, uimm);
1445
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1446
            tcg_temp_free_i32(t1);
1447
        } else {
1448
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1449
        }
1450
        opn = "rotr";
1451
        break;
1452
#if defined(TARGET_MIPS64)
1453
    case OPC_DSLL:
1454
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1455
        opn = "dsll";
1456
        break;
1457
    case OPC_DSRA:
1458
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1459
        opn = "dsra";
1460
        break;
1461
    case OPC_DSRL:
1462
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1463
        opn = "dsrl";
1464
        break;
1465
    case OPC_DROTR:
1466
        if (uimm != 0) {
1467
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1468
        } else {
1469
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1470
        }
1471
        opn = "drotr";
1472
        break;
1473
    case OPC_DSLL32:
1474
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1475
        opn = "dsll32";
1476
        break;
1477
    case OPC_DSRA32:
1478
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1479
        opn = "dsra32";
1480
        break;
1481
    case OPC_DSRL32:
1482
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1483
        opn = "dsrl32";
1484
        break;
1485
    case OPC_DROTR32:
1486
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1487
        opn = "drotr32";
1488
        break;
1489
#endif
1490
    }
1491
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1492
    tcg_temp_free(t0);
1493
}
1494

    
1495
/* Arithmetic */
1496
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1497
                       int rd, int rs, int rt)
1498
{
1499
    const char *opn = "arith";
1500

    
1501
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1502
       && opc != OPC_DADD && opc != OPC_DSUB) {
1503
        /* If no destination, treat it as a NOP.
1504
           For add & sub, we must generate the overflow exception when needed. */
1505
        MIPS_DEBUG("NOP");
1506
        return;
1507
    }
1508

    
1509
    switch (opc) {
1510
    case OPC_ADD:
1511
        {
1512
            TCGv t0 = tcg_temp_local_new();
1513
            TCGv t1 = tcg_temp_new();
1514
            TCGv t2 = tcg_temp_new();
1515
            int l1 = gen_new_label();
1516

    
1517
            gen_load_gpr(t1, rs);
1518
            gen_load_gpr(t2, rt);
1519
            tcg_gen_add_tl(t0, t1, t2);
1520
            tcg_gen_ext32s_tl(t0, t0);
1521
            tcg_gen_xor_tl(t1, t1, t2);
1522
            tcg_gen_xor_tl(t2, t0, t2);
1523
            tcg_gen_andc_tl(t1, t2, t1);
1524
            tcg_temp_free(t2);
1525
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1526
            tcg_temp_free(t1);
1527
            /* operands of same sign, result different sign */
1528
            generate_exception(ctx, EXCP_OVERFLOW);
1529
            gen_set_label(l1);
1530
            gen_store_gpr(t0, rd);
1531
            tcg_temp_free(t0);
1532
        }
1533
        opn = "add";
1534
        break;
1535
    case OPC_ADDU:
1536
        if (rs != 0 && rt != 0) {
1537
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1538
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1539
        } else if (rs == 0 && rt != 0) {
1540
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1541
        } else if (rs != 0 && rt == 0) {
1542
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1543
        } else {
1544
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1545
        }
1546
        opn = "addu";
1547
        break;
1548
    case OPC_SUB:
1549
        {
1550
            TCGv t0 = tcg_temp_local_new();
1551
            TCGv t1 = tcg_temp_new();
1552
            TCGv t2 = tcg_temp_new();
1553
            int l1 = gen_new_label();
1554

    
1555
            gen_load_gpr(t1, rs);
1556
            gen_load_gpr(t2, rt);
1557
            tcg_gen_sub_tl(t0, t1, t2);
1558
            tcg_gen_ext32s_tl(t0, t0);
1559
            tcg_gen_xor_tl(t2, t1, t2);
1560
            tcg_gen_xor_tl(t1, t0, t1);
1561
            tcg_gen_and_tl(t1, t1, t2);
1562
            tcg_temp_free(t2);
1563
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1564
            tcg_temp_free(t1);
1565
            /* operands of different sign, first operand and result different sign */
1566
            generate_exception(ctx, EXCP_OVERFLOW);
1567
            gen_set_label(l1);
1568
            gen_store_gpr(t0, rd);
1569
            tcg_temp_free(t0);
1570
        }
1571
        opn = "sub";
1572
        break;
1573
    case OPC_SUBU:
1574
        if (rs != 0 && rt != 0) {
1575
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1576
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1577
        } else if (rs == 0 && rt != 0) {
1578
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1579
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1580
        } else if (rs != 0 && rt == 0) {
1581
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1582
        } else {
1583
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1584
        }
1585
        opn = "subu";
1586
        break;
1587
#if defined(TARGET_MIPS64)
1588
    case OPC_DADD:
1589
        {
1590
            TCGv t0 = tcg_temp_local_new();
1591
            TCGv t1 = tcg_temp_new();
1592
            TCGv t2 = tcg_temp_new();
1593
            int l1 = gen_new_label();
1594

    
1595
            gen_load_gpr(t1, rs);
1596
            gen_load_gpr(t2, rt);
1597
            tcg_gen_add_tl(t0, t1, t2);
1598
            tcg_gen_xor_tl(t1, t1, t2);
1599
            tcg_gen_xor_tl(t2, t0, t2);
1600
            tcg_gen_andc_tl(t1, t2, t1);
1601
            tcg_temp_free(t2);
1602
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1603
            tcg_temp_free(t1);
1604
            /* operands of same sign, result different sign */
1605
            generate_exception(ctx, EXCP_OVERFLOW);
1606
            gen_set_label(l1);
1607
            gen_store_gpr(t0, rd);
1608
            tcg_temp_free(t0);
1609
        }
1610
        opn = "dadd";
1611
        break;
1612
    case OPC_DADDU:
1613
        if (rs != 0 && rt != 0) {
1614
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1615
        } else if (rs == 0 && rt != 0) {
1616
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1617
        } else if (rs != 0 && rt == 0) {
1618
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1619
        } else {
1620
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1621
        }
1622
        opn = "daddu";
1623
        break;
1624
    case OPC_DSUB:
1625
        {
1626
            TCGv t0 = tcg_temp_local_new();
1627
            TCGv t1 = tcg_temp_new();
1628
            TCGv t2 = tcg_temp_new();
1629
            int l1 = gen_new_label();
1630

    
1631
            gen_load_gpr(t1, rs);
1632
            gen_load_gpr(t2, rt);
1633
            tcg_gen_sub_tl(t0, t1, t2);
1634
            tcg_gen_xor_tl(t2, t1, t2);
1635
            tcg_gen_xor_tl(t1, t0, t1);
1636
            tcg_gen_and_tl(t1, t1, t2);
1637
            tcg_temp_free(t2);
1638
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1639
            tcg_temp_free(t1);
1640
            /* operands of different sign, first operand and result different sign */
1641
            generate_exception(ctx, EXCP_OVERFLOW);
1642
            gen_set_label(l1);
1643
            gen_store_gpr(t0, rd);
1644
            tcg_temp_free(t0);
1645
        }
1646
        opn = "dsub";
1647
        break;
1648
    case OPC_DSUBU:
1649
        if (rs != 0 && rt != 0) {
1650
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1651
        } else if (rs == 0 && rt != 0) {
1652
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1653
        } else if (rs != 0 && rt == 0) {
1654
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1655
        } else {
1656
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1657
        }
1658
        opn = "dsubu";
1659
        break;
1660
#endif
1661
    case OPC_MUL:
1662
        if (likely(rs != 0 && rt != 0)) {
1663
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1664
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1665
        } else {
1666
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1667
        }
1668
        opn = "mul";
1669
        break;
1670
    }
1671
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1672
}
1673

    
1674
/* Conditional move */
1675
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1676
{
1677
    const char *opn = "cond move";
1678
    int l1;
1679

    
1680
    if (rd == 0) {
1681
        /* If no destination, treat it as a NOP.
1682
           For add & sub, we must generate the overflow exception when needed. */
1683
        MIPS_DEBUG("NOP");
1684
        return;
1685
    }
1686

    
1687
    l1 = gen_new_label();
1688
    switch (opc) {
1689
    case OPC_MOVN:
1690
        if (likely(rt != 0))
1691
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1692
        else
1693
            tcg_gen_br(l1);
1694
        opn = "movn";
1695
        break;
1696
    case OPC_MOVZ:
1697
        if (likely(rt != 0))
1698
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1699
        opn = "movz";
1700
        break;
1701
    }
1702
    if (rs != 0)
1703
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1704
    else
1705
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1706
    gen_set_label(l1);
1707

    
1708
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1709
}
1710

    
1711
/* Logic */
1712
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1713
{
1714
    const char *opn = "logic";
1715

    
1716
    if (rd == 0) {
1717
        /* If no destination, treat it as a NOP. */
1718
        MIPS_DEBUG("NOP");
1719
        return;
1720
    }
1721

    
1722
    switch (opc) {
1723
    case OPC_AND:
1724
        if (likely(rs != 0 && rt != 0)) {
1725
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1726
        } else {
1727
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1728
        }
1729
        opn = "and";
1730
        break;
1731
    case OPC_NOR:
1732
        if (rs != 0 && rt != 0) {
1733
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1734
        } else if (rs == 0 && rt != 0) {
1735
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1736
        } else if (rs != 0 && rt == 0) {
1737
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1738
        } else {
1739
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1740
        }
1741
        opn = "nor";
1742
        break;
1743
    case OPC_OR:
1744
        if (likely(rs != 0 && rt != 0)) {
1745
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1746
        } else if (rs == 0 && rt != 0) {
1747
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1748
        } else if (rs != 0 && rt == 0) {
1749
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1750
        } else {
1751
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1752
        }
1753
        opn = "or";
1754
        break;
1755
    case OPC_XOR:
1756
        if (likely(rs != 0 && rt != 0)) {
1757
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1758
        } else if (rs == 0 && rt != 0) {
1759
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1760
        } else if (rs != 0 && rt == 0) {
1761
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1762
        } else {
1763
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1764
        }
1765
        opn = "xor";
1766
        break;
1767
    }
1768
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1769
}
1770

    
1771
/* Set on lower than */
1772
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1773
{
1774
    const char *opn = "slt";
1775
    TCGv t0, t1;
1776

    
1777
    if (rd == 0) {
1778
        /* If no destination, treat it as a NOP. */
1779
        MIPS_DEBUG("NOP");
1780
        return;
1781
    }
1782

    
1783
    t0 = tcg_temp_new();
1784
    t1 = tcg_temp_new();
1785
    gen_load_gpr(t0, rs);
1786
    gen_load_gpr(t1, rt);
1787
    switch (opc) {
1788
    case OPC_SLT:
1789
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1790
        opn = "slt";
1791
        break;
1792
    case OPC_SLTU:
1793
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1794
        opn = "sltu";
1795
        break;
1796
    }
1797
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1798
    tcg_temp_free(t0);
1799
    tcg_temp_free(t1);
1800
}
1801

    
1802
/* Shifts */
1803
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1804
                       int rd, int rs, int rt)
1805
{
1806
    const char *opn = "shifts";
1807
    TCGv t0, t1;
1808

    
1809
    if (rd == 0) {
1810
        /* If no destination, treat it as a NOP.
1811
           For add & sub, we must generate the overflow exception when needed. */
1812
        MIPS_DEBUG("NOP");
1813
        return;
1814
    }
1815

    
1816
    t0 = tcg_temp_new();
1817
    t1 = tcg_temp_new();
1818
    gen_load_gpr(t0, rs);
1819
    gen_load_gpr(t1, rt);
1820
    switch (opc) {
1821
    case OPC_SLLV:
1822
        tcg_gen_andi_tl(t0, t0, 0x1f);
1823
        tcg_gen_shl_tl(t0, t1, t0);
1824
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1825
        opn = "sllv";
1826
        break;
1827
    case OPC_SRAV:
1828
        tcg_gen_andi_tl(t0, t0, 0x1f);
1829
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1830
        opn = "srav";
1831
        break;
1832
    case OPC_SRLV:
1833
        tcg_gen_ext32u_tl(t1, t1);
1834
        tcg_gen_andi_tl(t0, t0, 0x1f);
1835
        tcg_gen_shr_tl(t0, t1, t0);
1836
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1837
        opn = "srlv";
1838
        break;
1839
    case OPC_ROTRV:
1840
        {
1841
            TCGv_i32 t2 = tcg_temp_new_i32();
1842
            TCGv_i32 t3 = tcg_temp_new_i32();
1843

    
1844
            tcg_gen_trunc_tl_i32(t2, t0);
1845
            tcg_gen_trunc_tl_i32(t3, t1);
1846
            tcg_gen_andi_i32(t2, t2, 0x1f);
1847
            tcg_gen_rotr_i32(t2, t3, t2);
1848
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1849
            tcg_temp_free_i32(t2);
1850
            tcg_temp_free_i32(t3);
1851
            opn = "rotrv";
1852
        }
1853
        break;
1854
#if defined(TARGET_MIPS64)
1855
    case OPC_DSLLV:
1856
        tcg_gen_andi_tl(t0, t0, 0x3f);
1857
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1858
        opn = "dsllv";
1859
        break;
1860
    case OPC_DSRAV:
1861
        tcg_gen_andi_tl(t0, t0, 0x3f);
1862
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1863
        opn = "dsrav";
1864
        break;
1865
    case OPC_DSRLV:
1866
        tcg_gen_andi_tl(t0, t0, 0x3f);
1867
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1868
        opn = "dsrlv";
1869
        break;
1870
    case OPC_DROTRV:
1871
        tcg_gen_andi_tl(t0, t0, 0x3f);
1872
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1873
        opn = "drotrv";
1874
        break;
1875
#endif
1876
    }
1877
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1878
    tcg_temp_free(t0);
1879
    tcg_temp_free(t1);
1880
}
1881

    
1882
/* Arithmetic on HI/LO registers */
1883
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1884
{
1885
    const char *opn = "hilo";
1886

    
1887
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1888
        /* Treat as NOP. */
1889
        MIPS_DEBUG("NOP");
1890
        return;
1891
    }
1892
    switch (opc) {
1893
    case OPC_MFHI:
1894
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1895
        opn = "mfhi";
1896
        break;
1897
    case OPC_MFLO:
1898
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1899
        opn = "mflo";
1900
        break;
1901
    case OPC_MTHI:
1902
        if (reg != 0)
1903
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1904
        else
1905
            tcg_gen_movi_tl(cpu_HI[0], 0);
1906
        opn = "mthi";
1907
        break;
1908
    case OPC_MTLO:
1909
        if (reg != 0)
1910
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1911
        else
1912
            tcg_gen_movi_tl(cpu_LO[0], 0);
1913
        opn = "mtlo";
1914
        break;
1915
    }
1916
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1917
}
1918

    
1919
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1920
                        int rs, int rt)
1921
{
1922
    const char *opn = "mul/div";
1923
    TCGv t0, t1;
1924

    
1925
    switch (opc) {
1926
    case OPC_DIV:
1927
    case OPC_DIVU:
1928
#if defined(TARGET_MIPS64)
1929
    case OPC_DDIV:
1930
    case OPC_DDIVU:
1931
#endif
1932
        t0 = tcg_temp_local_new();
1933
        t1 = tcg_temp_local_new();
1934
        break;
1935
    default:
1936
        t0 = tcg_temp_new();
1937
        t1 = tcg_temp_new();
1938
        break;
1939
    }
1940

    
1941
    gen_load_gpr(t0, rs);
1942
    gen_load_gpr(t1, rt);
1943
    switch (opc) {
1944
    case OPC_DIV:
1945
        {
1946
            int l1 = gen_new_label();
1947
            int l2 = gen_new_label();
1948

    
1949
            tcg_gen_ext32s_tl(t0, t0);
1950
            tcg_gen_ext32s_tl(t1, t1);
1951
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1952
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1953
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1954

    
1955
            tcg_gen_mov_tl(cpu_LO[0], t0);
1956
            tcg_gen_movi_tl(cpu_HI[0], 0);
1957
            tcg_gen_br(l1);
1958
            gen_set_label(l2);
1959
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1960
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1961
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1962
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1963
            gen_set_label(l1);
1964
        }
1965
        opn = "div";
1966
        break;
1967
    case OPC_DIVU:
1968
        {
1969
            int l1 = gen_new_label();
1970

    
1971
            tcg_gen_ext32u_tl(t0, t0);
1972
            tcg_gen_ext32u_tl(t1, t1);
1973
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1974
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1975
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1976
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1977
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1978
            gen_set_label(l1);
1979
        }
1980
        opn = "divu";
1981
        break;
1982
    case OPC_MULT:
1983
        {
1984
            TCGv_i64 t2 = tcg_temp_new_i64();
1985
            TCGv_i64 t3 = tcg_temp_new_i64();
1986

    
1987
            tcg_gen_ext_tl_i64(t2, t0);
1988
            tcg_gen_ext_tl_i64(t3, t1);
1989
            tcg_gen_mul_i64(t2, t2, t3);
1990
            tcg_temp_free_i64(t3);
1991
            tcg_gen_trunc_i64_tl(t0, t2);
1992
            tcg_gen_shri_i64(t2, t2, 32);
1993
            tcg_gen_trunc_i64_tl(t1, t2);
1994
            tcg_temp_free_i64(t2);
1995
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1996
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1997
        }
1998
        opn = "mult";
1999
        break;
2000
    case OPC_MULTU:
2001
        {
2002
            TCGv_i64 t2 = tcg_temp_new_i64();
2003
            TCGv_i64 t3 = tcg_temp_new_i64();
2004

    
2005
            tcg_gen_ext32u_tl(t0, t0);
2006
            tcg_gen_ext32u_tl(t1, t1);
2007
            tcg_gen_extu_tl_i64(t2, t0);
2008
            tcg_gen_extu_tl_i64(t3, t1);
2009
            tcg_gen_mul_i64(t2, t2, t3);
2010
            tcg_temp_free_i64(t3);
2011
            tcg_gen_trunc_i64_tl(t0, t2);
2012
            tcg_gen_shri_i64(t2, t2, 32);
2013
            tcg_gen_trunc_i64_tl(t1, t2);
2014
            tcg_temp_free_i64(t2);
2015
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2016
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2017
        }
2018
        opn = "multu";
2019
        break;
2020
#if defined(TARGET_MIPS64)
2021
    case OPC_DDIV:
2022
        {
2023
            int l1 = gen_new_label();
2024
            int l2 = gen_new_label();
2025

    
2026
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2027
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2028
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2029
            tcg_gen_mov_tl(cpu_LO[0], t0);
2030
            tcg_gen_movi_tl(cpu_HI[0], 0);
2031
            tcg_gen_br(l1);
2032
            gen_set_label(l2);
2033
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2034
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2035
            gen_set_label(l1);
2036
        }
2037
        opn = "ddiv";
2038
        break;
2039
    case OPC_DDIVU:
2040
        {
2041
            int l1 = gen_new_label();
2042

    
2043
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2044
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2045
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2046
            gen_set_label(l1);
2047
        }
2048
        opn = "ddivu";
2049
        break;
2050
    case OPC_DMULT:
2051
        gen_helper_dmult(t0, t1);
2052
        opn = "dmult";
2053
        break;
2054
    case OPC_DMULTU:
2055
        gen_helper_dmultu(t0, t1);
2056
        opn = "dmultu";
2057
        break;
2058
#endif
2059
    case OPC_MADD:
2060
        {
2061
            TCGv_i64 t2 = tcg_temp_new_i64();
2062
            TCGv_i64 t3 = tcg_temp_new_i64();
2063

    
2064
            tcg_gen_ext_tl_i64(t2, t0);
2065
            tcg_gen_ext_tl_i64(t3, t1);
2066
            tcg_gen_mul_i64(t2, t2, t3);
2067
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2068
            tcg_gen_add_i64(t2, t2, t3);
2069
            tcg_temp_free_i64(t3);
2070
            tcg_gen_trunc_i64_tl(t0, t2);
2071
            tcg_gen_shri_i64(t2, t2, 32);
2072
            tcg_gen_trunc_i64_tl(t1, t2);
2073
            tcg_temp_free_i64(t2);
2074
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2075
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2076
        }
2077
        opn = "madd";
2078
        break;
2079
    case OPC_MADDU:
2080
       {
2081
            TCGv_i64 t2 = tcg_temp_new_i64();
2082
            TCGv_i64 t3 = tcg_temp_new_i64();
2083

    
2084
            tcg_gen_ext32u_tl(t0, t0);
2085
            tcg_gen_ext32u_tl(t1, t1);
2086
            tcg_gen_extu_tl_i64(t2, t0);
2087
            tcg_gen_extu_tl_i64(t3, t1);
2088
            tcg_gen_mul_i64(t2, t2, t3);
2089
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2090
            tcg_gen_add_i64(t2, t2, t3);
2091
            tcg_temp_free_i64(t3);
2092
            tcg_gen_trunc_i64_tl(t0, t2);
2093
            tcg_gen_shri_i64(t2, t2, 32);
2094
            tcg_gen_trunc_i64_tl(t1, t2);
2095
            tcg_temp_free_i64(t2);
2096
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2097
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2098
        }
2099
        opn = "maddu";
2100
        break;
2101
    case OPC_MSUB:
2102
        {
2103
            TCGv_i64 t2 = tcg_temp_new_i64();
2104
            TCGv_i64 t3 = tcg_temp_new_i64();
2105

    
2106
            tcg_gen_ext_tl_i64(t2, t0);
2107
            tcg_gen_ext_tl_i64(t3, t1);
2108
            tcg_gen_mul_i64(t2, t2, t3);
2109
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2110
            tcg_gen_sub_i64(t2, t3, t2);
2111
            tcg_temp_free_i64(t3);
2112
            tcg_gen_trunc_i64_tl(t0, t2);
2113
            tcg_gen_shri_i64(t2, t2, 32);
2114
            tcg_gen_trunc_i64_tl(t1, t2);
2115
            tcg_temp_free_i64(t2);
2116
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2117
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2118
        }
2119
        opn = "msub";
2120
        break;
2121
    case OPC_MSUBU:
2122
        {
2123
            TCGv_i64 t2 = tcg_temp_new_i64();
2124
            TCGv_i64 t3 = tcg_temp_new_i64();
2125

    
2126
            tcg_gen_ext32u_tl(t0, t0);
2127
            tcg_gen_ext32u_tl(t1, t1);
2128
            tcg_gen_extu_tl_i64(t2, t0);
2129
            tcg_gen_extu_tl_i64(t3, t1);
2130
            tcg_gen_mul_i64(t2, t2, t3);
2131
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2132
            tcg_gen_sub_i64(t2, t3, t2);
2133
            tcg_temp_free_i64(t3);
2134
            tcg_gen_trunc_i64_tl(t0, t2);
2135
            tcg_gen_shri_i64(t2, t2, 32);
2136
            tcg_gen_trunc_i64_tl(t1, t2);
2137
            tcg_temp_free_i64(t2);
2138
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2139
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2140
        }
2141
        opn = "msubu";
2142
        break;
2143
    default:
2144
        MIPS_INVAL(opn);
2145
        generate_exception(ctx, EXCP_RI);
2146
        goto out;
2147
    }
2148
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2149
 out:
2150
    tcg_temp_free(t0);
2151
    tcg_temp_free(t1);
2152
}
2153

    
2154
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2155
                            int rd, int rs, int rt)
2156
{
2157
    const char *opn = "mul vr54xx";
2158
    TCGv t0 = tcg_temp_new();
2159
    TCGv t1 = tcg_temp_new();
2160

    
2161
    gen_load_gpr(t0, rs);
2162
    gen_load_gpr(t1, rt);
2163

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

    
2229
 out:
2230
    tcg_temp_free(t0);
2231
    tcg_temp_free(t1);
2232
}
2233

    
2234
static void gen_cl (DisasContext *ctx, uint32_t opc,
2235
                    int rd, int rs)
2236
{
2237
    const char *opn = "CLx";
2238
    TCGv t0;
2239

    
2240
    if (rd == 0) {
2241
        /* Treat as NOP. */
2242
        MIPS_DEBUG("NOP");
2243
        return;
2244
    }
2245
    t0 = tcg_temp_new();
2246
    gen_load_gpr(t0, rs);
2247
    switch (opc) {
2248
    case OPC_CLO:
2249
        gen_helper_clo(cpu_gpr[rd], t0);
2250
        opn = "clo";
2251
        break;
2252
    case OPC_CLZ:
2253
        gen_helper_clz(cpu_gpr[rd], t0);
2254
        opn = "clz";
2255
        break;
2256
#if defined(TARGET_MIPS64)
2257
    case OPC_DCLO:
2258
        gen_helper_dclo(cpu_gpr[rd], t0);
2259
        opn = "dclo";
2260
        break;
2261
    case OPC_DCLZ:
2262
        gen_helper_dclz(cpu_gpr[rd], t0);
2263
        opn = "dclz";
2264
        break;
2265
#endif
2266
    }
2267
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2268
    tcg_temp_free(t0);
2269
}
2270

    
2271
/* Traps */
2272
static void gen_trap (DisasContext *ctx, uint32_t opc,
2273
                      int rs, int rt, int16_t imm)
2274
{
2275
    int cond;
2276
    TCGv t0 = tcg_temp_new();
2277
    TCGv t1 = tcg_temp_new();
2278

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

    
2332
        switch (opc) {
2333
        case OPC_TEQ:
2334
        case OPC_TEQI:
2335
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2336
            break;
2337
        case OPC_TGE:
2338
        case OPC_TGEI:
2339
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2340
            break;
2341
        case OPC_TGEU:
2342
        case OPC_TGEIU:
2343
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2344
            break;
2345
        case OPC_TLT:
2346
        case OPC_TLTI:
2347
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2348
            break;
2349
        case OPC_TLTU:
2350
        case OPC_TLTIU:
2351
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2352
            break;
2353
        case OPC_TNE:
2354
        case OPC_TNEI:
2355
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2356
            break;
2357
        }
2358
        generate_exception(ctx, EXCP_TRAP);
2359
        gen_set_label(l1);
2360
    }
2361
    tcg_temp_free(t0);
2362
    tcg_temp_free(t1);
2363
}
2364

    
2365
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2366
{
2367
    TranslationBlock *tb;
2368
    tb = ctx->tb;
2369
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2370
        likely(!ctx->singlestep_enabled)) {
2371
        tcg_gen_goto_tb(n);
2372
        gen_save_pc(dest);
2373
        tcg_gen_exit_tb((long)tb + n);
2374
    } else {
2375
        gen_save_pc(dest);
2376
        if (ctx->singlestep_enabled) {
2377
            save_cpu_state(ctx, 0);
2378
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2379
        }
2380
        tcg_gen_exit_tb(0);
2381
    }
2382
}
2383

    
2384
/* Branches (before delay slot) */
2385
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2386
                                int insn_bytes,
2387
                                int rs, int rt, int32_t offset)
2388
{
2389
    target_ulong btgt = -1;
2390
    int blink = 0;
2391
    int bcond_compute = 0;
2392
    TCGv t0 = tcg_temp_new();
2393
    TCGv t1 = tcg_temp_new();
2394

    
2395
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2396
#ifdef MIPS_DEBUG_DISAS
2397
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2398
#endif
2399
        generate_exception(ctx, EXCP_RI);
2400
        goto out;
2401
    }
2402

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

    
2624
    ctx->btarget = btgt;
2625
    if (blink > 0) {
2626
        int post_delay = insn_bytes;
2627
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2628

    
2629
        if (opc != OPC_JALRC)
2630
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2631

    
2632
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2633
    }
2634

    
2635
 out:
2636
    if (insn_bytes == 2)
2637
        ctx->hflags |= MIPS_HFLAG_B16;
2638
    tcg_temp_free(t0);
2639
    tcg_temp_free(t1);
2640
}
2641

    
2642
/* special3 bitfield operations */
2643
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2644
                        int rs, int lsb, int msb)
2645
{
2646
    TCGv t0 = tcg_temp_new();
2647
    TCGv t1 = tcg_temp_new();
2648
    target_ulong mask;
2649

    
2650
    gen_load_gpr(t1, rs);
2651
    switch (opc) {
2652
    case OPC_EXT:
2653
        if (lsb + msb > 31)
2654
            goto fail;
2655
        tcg_gen_shri_tl(t0, t1, lsb);
2656
        if (msb != 31) {
2657
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2658
        } else {
2659
            tcg_gen_ext32s_tl(t0, t0);
2660
        }
2661
        break;
2662
#if defined(TARGET_MIPS64)
2663
    case OPC_DEXTM:
2664
        tcg_gen_shri_tl(t0, t1, lsb);
2665
        if (msb != 31) {
2666
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2667
        }
2668
        break;
2669
    case OPC_DEXTU:
2670
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2671
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2672
        break;
2673
    case OPC_DEXT:
2674
        tcg_gen_shri_tl(t0, t1, lsb);
2675
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2676
        break;
2677
#endif
2678
    case OPC_INS:
2679
        if (lsb > msb)
2680
            goto fail;
2681
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2682
        gen_load_gpr(t0, rt);
2683
        tcg_gen_andi_tl(t0, t0, ~mask);
2684
        tcg_gen_shli_tl(t1, t1, lsb);
2685
        tcg_gen_andi_tl(t1, t1, mask);
2686
        tcg_gen_or_tl(t0, t0, t1);
2687
        tcg_gen_ext32s_tl(t0, t0);
2688
        break;
2689
#if defined(TARGET_MIPS64)
2690
    case OPC_DINSM:
2691
        if (lsb > msb)
2692
            goto fail;
2693
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2694
        gen_load_gpr(t0, rt);
2695
        tcg_gen_andi_tl(t0, t0, ~mask);
2696
        tcg_gen_shli_tl(t1, t1, lsb);
2697
        tcg_gen_andi_tl(t1, t1, mask);
2698
        tcg_gen_or_tl(t0, t0, t1);
2699
        break;
2700
    case OPC_DINSU:
2701
        if (lsb > msb)
2702
            goto fail;
2703
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2704
        gen_load_gpr(t0, rt);
2705
        tcg_gen_andi_tl(t0, t0, ~mask);
2706
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2707
        tcg_gen_andi_tl(t1, t1, mask);
2708
        tcg_gen_or_tl(t0, t0, t1);
2709
        break;
2710
    case OPC_DINS:
2711
        if (lsb > msb)
2712
            goto fail;
2713
        gen_load_gpr(t0, rt);
2714
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2715
        gen_load_gpr(t0, rt);
2716
        tcg_gen_andi_tl(t0, t0, ~mask);
2717
        tcg_gen_shli_tl(t1, t1, lsb);
2718
        tcg_gen_andi_tl(t1, t1, mask);
2719
        tcg_gen_or_tl(t0, t0, t1);
2720
        break;
2721
#endif
2722
    default:
2723
fail:
2724
        MIPS_INVAL("bitops");
2725
        generate_exception(ctx, EXCP_RI);
2726
        tcg_temp_free(t0);
2727
        tcg_temp_free(t1);
2728
        return;
2729
    }
2730
    gen_store_gpr(t0, rt);
2731
    tcg_temp_free(t0);
2732
    tcg_temp_free(t1);
2733
}
2734

    
2735
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2736
{
2737
    TCGv t0;
2738

    
2739
    if (rd == 0) {
2740
        /* If no destination, treat it as a NOP. */
2741
        MIPS_DEBUG("NOP");
2742
        return;
2743
    }
2744

    
2745
    t0 = tcg_temp_new();
2746
    gen_load_gpr(t0, rt);
2747
    switch (op2) {
2748
    case OPC_WSBH:
2749
        {
2750
            TCGv t1 = tcg_temp_new();
2751

    
2752
            tcg_gen_shri_tl(t1, t0, 8);
2753
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2754
            tcg_gen_shli_tl(t0, t0, 8);
2755
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2756
            tcg_gen_or_tl(t0, t0, t1);
2757
            tcg_temp_free(t1);
2758
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2759
        }
2760
        break;
2761
    case OPC_SEB:
2762
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2763
        break;
2764
    case OPC_SEH:
2765
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2766
        break;
2767
#if defined(TARGET_MIPS64)
2768
    case OPC_DSBH:
2769
        {
2770
            TCGv t1 = tcg_temp_new();
2771

    
2772
            tcg_gen_shri_tl(t1, t0, 8);
2773
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2774
            tcg_gen_shli_tl(t0, t0, 8);
2775
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2776
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2777
            tcg_temp_free(t1);
2778
        }
2779
        break;
2780
    case OPC_DSHD:
2781
        {
2782
            TCGv t1 = tcg_temp_new();
2783

    
2784
            tcg_gen_shri_tl(t1, t0, 16);
2785
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2786
            tcg_gen_shli_tl(t0, t0, 16);
2787
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2788
            tcg_gen_or_tl(t0, t0, t1);
2789
            tcg_gen_shri_tl(t1, t0, 32);
2790
            tcg_gen_shli_tl(t0, t0, 32);
2791
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2792
            tcg_temp_free(t1);
2793
        }
2794
        break;
2795
#endif
2796
    default:
2797
        MIPS_INVAL("bsfhl");
2798
        generate_exception(ctx, EXCP_RI);
2799
        tcg_temp_free(t0);
2800
        return;
2801
    }
2802
    tcg_temp_free(t0);
2803
}
2804

    
2805
#ifndef CONFIG_USER_ONLY
2806
/* CP0 (MMU and control) */
2807
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2808
{
2809
    TCGv_i32 t0 = tcg_temp_new_i32();
2810

    
2811
    tcg_gen_ld_i32(t0, cpu_env, off);
2812
    tcg_gen_ext_i32_tl(arg, t0);
2813
    tcg_temp_free_i32(t0);
2814
}
2815

    
2816
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2817
{
2818
    tcg_gen_ld_tl(arg, cpu_env, off);
2819
    tcg_gen_ext32s_tl(arg, arg);
2820
}
2821

    
2822
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2823
{
2824
    TCGv_i32 t0 = tcg_temp_new_i32();
2825

    
2826
    tcg_gen_trunc_tl_i32(t0, arg);
2827
    tcg_gen_st_i32(t0, cpu_env, off);
2828
    tcg_temp_free_i32(t0);
2829
}
2830

    
2831
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2832
{
2833
    tcg_gen_ext32s_tl(arg, arg);
2834
    tcg_gen_st_tl(arg, cpu_env, off);
2835
}
2836

    
2837
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2838
{
2839
    const char *rn = "invalid";
2840

    
2841
    if (sel != 0)
2842
        check_insn(env, ctx, ISA_MIPS32);
2843

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

    
3409
die:
3410
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3411
    generate_exception(ctx, EXCP_RI);
3412
}
3413

    
3414
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3415
{
3416
    const char *rn = "invalid";
3417

    
3418
    if (sel != 0)
3419
        check_insn(env, ctx, ISA_MIPS32);
3420

    
3421
    if (use_icount)
3422
        gen_io_start();
3423

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

    
4004
die:
4005
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4006
    generate_exception(ctx, EXCP_RI);
4007
}
4008

    
4009
#if defined(TARGET_MIPS64)
4010
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4011
{
4012
    const char *rn = "invalid";
4013

    
4014
    if (sel != 0)
4015
        check_insn(env, ctx, ISA_MIPS64);
4016

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

    
4571
die:
4572
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4573
    generate_exception(ctx, EXCP_RI);
4574
}
4575

    
4576
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4577
{
4578
    const char *rn = "invalid";
4579

    
4580
    if (sel != 0)
4581
        check_insn(env, ctx, ISA_MIPS64);
4582

    
4583
    if (use_icount)
4584
        gen_io_start();
4585

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

    
5157
die:
5158
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5159
    generate_exception(ctx, EXCP_RI);
5160
}
5161
#endif /* TARGET_MIPS64 */
5162

    
5163
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5164
                     int u, int sel, int h)
5165
{
5166
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5167
    TCGv t0 = tcg_temp_local_new();
5168

    
5169
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5170
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5171
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5172
        tcg_gen_movi_tl(t0, -1);
5173
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5174
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5175
        tcg_gen_movi_tl(t0, -1);
5176
    else if (u == 0) {
5177
        switch (rt) {
5178
        case 2:
5179
            switch (sel) {
5180
            case 1:
5181
                gen_helper_mftc0_tcstatus(t0);
5182
                break;
5183
            case 2:
5184
                gen_helper_mftc0_tcbind(t0);
5185
                break;
5186
            case 3:
5187
                gen_helper_mftc0_tcrestart(t0);
5188
                break;
5189
            case 4:
5190
                gen_helper_mftc0_tchalt(t0);
5191
                break;
5192
            case 5:
5193
                gen_helper_mftc0_tccontext(t0);
5194
                break;
5195
            case 6:
5196
                gen_helper_mftc0_tcschedule(t0);
5197
                break;
5198
            case 7:
5199
                gen_helper_mftc0_tcschefback(t0);
5200
                break;
5201
            default:
5202
                gen_mfc0(env, ctx, t0, rt, sel);
5203
                break;
5204
            }
5205
            break;
5206
        case 10:
5207
            switch (sel) {
5208
            case 0:
5209
                gen_helper_mftc0_entryhi(t0);
5210
                break;
5211
            default:
5212
                gen_mfc0(env, ctx, t0, rt, sel);
5213
                break;
5214
            }
5215
        case 12:
5216
            switch (sel) {
5217
            case 0:
5218
                gen_helper_mftc0_status(t0);
5219
                break;
5220
            default:
5221
                gen_mfc0(env, ctx, t0, rt, sel);
5222
                break;
5223
            }
5224
        case 23:
5225
            switch (sel) {
5226
            case 0:
5227
                gen_helper_mftc0_debug(t0);
5228
                break;
5229
            default:
5230
                gen_mfc0(env, ctx, t0, rt, sel);
5231
                break;
5232
            }
5233
            break;
5234
        default:
5235
            gen_mfc0(env, ctx, t0, rt, sel);
5236
        }
5237
    } else switch (sel) {
5238
    /* GPR registers. */
5239
    case 0:
5240
        gen_helper_1i(mftgpr, t0, rt);
5241
        break;
5242
    /* Auxiliary CPU registers */
5243
    case 1:
5244
        switch (rt) {
5245
        case 0:
5246
            gen_helper_1i(mftlo, t0, 0);
5247
            break;
5248
        case 1:
5249
            gen_helper_1i(mfthi, t0, 0);
5250
            break;
5251
        case 2:
5252
            gen_helper_1i(mftacx, t0, 0);
5253
            break;
5254
        case 4:
5255
            gen_helper_1i(mftlo, t0, 1);
5256
            break;
5257
        case 5:
5258
            gen_helper_1i(mfthi, t0, 1);
5259
            break;
5260
        case 6:
5261
            gen_helper_1i(mftacx, t0, 1);
5262
            break;
5263
        case 8:
5264
            gen_helper_1i(mftlo, t0, 2);
5265
            break;
5266
        case 9:
5267
            gen_helper_1i(mfthi, t0, 2);
5268
            break;
5269
        case 10:
5270
            gen_helper_1i(mftacx, t0, 2);
5271
            break;
5272
        case 12:
5273
            gen_helper_1i(mftlo, t0, 3);
5274
            break;
5275
        case 13:
5276
            gen_helper_1i(mfthi, t0, 3);
5277
            break;
5278
        case 14:
5279
            gen_helper_1i(mftacx, t0, 3);
5280
            break;
5281
        case 16:
5282
            gen_helper_mftdsp(t0);
5283
            break;
5284
        default:
5285
            goto die;
5286
        }
5287
        break;
5288
    /* Floating point (COP1). */
5289
    case 2:
5290
        /* XXX: For now we support only a single FPU context. */
5291
        if (h == 0) {
5292
            TCGv_i32 fp0 = tcg_temp_new_i32();
5293

    
5294
            gen_load_fpr32(fp0, rt);
5295
            tcg_gen_ext_i32_tl(t0, fp0);
5296
            tcg_temp_free_i32(fp0);
5297
        } else {
5298
            TCGv_i32 fp0 = tcg_temp_new_i32();
5299

    
5300
            gen_load_fpr32h(fp0, rt);
5301
            tcg_gen_ext_i32_tl(t0, fp0);
5302
            tcg_temp_free_i32(fp0);
5303
        }
5304
        break;
5305
    case 3:
5306
        /* XXX: For now we support only a single FPU context. */
5307
        gen_helper_1i(cfc1, t0, rt);
5308
        break;
5309
    /* COP2: Not implemented. */
5310
    case 4:
5311
    case 5:
5312
        /* fall through */
5313
    default:
5314
        goto die;
5315
    }
5316
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5317
    gen_store_gpr(t0, rd);
5318
    tcg_temp_free(t0);
5319
    return;
5320

    
5321
die:
5322
    tcg_temp_free(t0);
5323
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5324
    generate_exception(ctx, EXCP_RI);
5325
}
5326

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

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

    
5459
            tcg_gen_trunc_tl_i32(fp0, t0);
5460
            gen_store_fpr32(fp0, rd);
5461
            tcg_temp_free_i32(fp0);
5462
        } else {
5463
            TCGv_i32 fp0 = tcg_temp_new_i32();
5464

    
5465
            tcg_gen_trunc_tl_i32(fp0, t0);
5466
            gen_store_fpr32h(fp0, rd);
5467
            tcg_temp_free_i32(fp0);
5468
        }
5469
        break;
5470
    case 3:
5471
        /* XXX: For now we support only a single FPU context. */
5472
        gen_helper_1i(ctc1, t0, rd);
5473
        break;
5474
    /* COP2: Not implemented. */
5475
    case 4:
5476
    case 5:
5477
        /* fall through */
5478
    default:
5479
        goto die;
5480
    }
5481
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5482
    tcg_temp_free(t0);
5483
    return;
5484

    
5485
die:
5486
    tcg_temp_free(t0);
5487
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5488
    generate_exception(ctx, EXCP_RI);
5489
}
5490

    
5491
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5492
{
5493
    const char *opn = "ldst";
5494

    
5495
    switch (opc) {
5496
    case OPC_MFC0:
5497
        if (rt == 0) {
5498
            /* Treat as NOP. */
5499
            return;
5500
        }
5501
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5502
        opn = "mfc0";
5503
        break;
5504
    case OPC_MTC0:
5505
        {
5506
            TCGv t0 = tcg_temp_new();
5507

    
5508
            gen_load_gpr(t0, rt);
5509
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5510
            tcg_temp_free(t0);
5511
        }
5512
        opn = "mtc0";
5513
        break;
5514
#if defined(TARGET_MIPS64)
5515
    case OPC_DMFC0:
5516
        check_insn(env, ctx, ISA_MIPS3);
5517
        if (rt == 0) {
5518
            /* Treat as NOP. */
5519
            return;
5520
        }
5521
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5522
        opn = "dmfc0";
5523
        break;
5524
    case OPC_DMTC0:
5525
        check_insn(env, ctx, ISA_MIPS3);
5526
        {
5527
            TCGv t0 = tcg_temp_new();
5528

    
5529
            gen_load_gpr(t0, rt);
5530
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5531
            tcg_temp_free(t0);
5532
        }
5533
        opn = "dmtc0";
5534
        break;
5535
#endif
5536
    case OPC_MFTR:
5537
        check_insn(env, ctx, ASE_MT);
5538
        if (rd == 0) {
5539
            /* Treat as NOP. */
5540
            return;
5541
        }
5542
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5543
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5544
        opn = "mftr";
5545
        break;
5546
    case OPC_MTTR:
5547
        check_insn(env, ctx, ASE_MT);
5548
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5549
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5550
        opn = "mttr";
5551
        break;
5552
    case OPC_TLBWI:
5553
        opn = "tlbwi";
5554
        if (!env->tlb->helper_tlbwi)
5555
            goto die;
5556
        gen_helper_tlbwi();
5557
        break;
5558
    case OPC_TLBWR:
5559
        opn = "tlbwr";
5560
        if (!env->tlb->helper_tlbwr)
5561
            goto die;
5562
        gen_helper_tlbwr();
5563
        break;
5564
    case OPC_TLBP:
5565
        opn = "tlbp";
5566
        if (!env->tlb->helper_tlbp)
5567
            goto die;
5568
        gen_helper_tlbp();
5569
        break;
5570
    case OPC_TLBR:
5571
        opn = "tlbr";
5572
        if (!env->tlb->helper_tlbr)
5573
            goto die;
5574
        gen_helper_tlbr();
5575
        break;
5576
    case OPC_ERET:
5577
        opn = "eret";
5578
        check_insn(env, ctx, ISA_MIPS2);
5579
        gen_helper_eret();
5580
        ctx->bstate = BS_EXCP;
5581
        break;
5582
    case OPC_DERET:
5583
        opn = "deret";
5584
        check_insn(env, ctx, ISA_MIPS32);
5585
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5586
            MIPS_INVAL(opn);
5587
            generate_exception(ctx, EXCP_RI);
5588
        } else {
5589
            gen_helper_deret();
5590
            ctx->bstate = BS_EXCP;
5591
        }
5592
        break;
5593
    case OPC_WAIT:
5594
        opn = "wait";
5595
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5596
        /* If we get an exception, we want to restart at next instruction */
5597
        ctx->pc += 4;
5598
        save_cpu_state(ctx, 1);
5599
        ctx->pc -= 4;
5600
        gen_helper_wait();
5601
        ctx->bstate = BS_EXCP;
5602
        break;
5603
    default:
5604
 die:
5605
        MIPS_INVAL(opn);
5606
        generate_exception(ctx, EXCP_RI);
5607
        return;
5608
    }
5609
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5610
}
5611
#endif /* !CONFIG_USER_ONLY */
5612

    
5613
/* CP1 Branches (before delay slot) */
5614
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5615
                                 int32_t cc, int32_t offset)
5616
{
5617
    target_ulong btarget;
5618
    const char *opn = "cp1 cond branch";
5619
    TCGv_i32 t0 = tcg_temp_new_i32();
5620

    
5621
    if (cc != 0)
5622
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5623

    
5624
    btarget = ctx->pc + 4 + offset;
5625

    
5626
    switch (op) {
5627
    case OPC_BC1F:
5628
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5629
        tcg_gen_not_i32(t0, t0);
5630
        tcg_gen_andi_i32(t0, t0, 1);
5631
        tcg_gen_extu_i32_tl(bcond, t0);
5632
        opn = "bc1f";
5633
        goto not_likely;
5634
    case OPC_BC1FL:
5635
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5636
        tcg_gen_not_i32(t0, t0);
5637
        tcg_gen_andi_i32(t0, t0, 1);
5638
        tcg_gen_extu_i32_tl(bcond, t0);
5639
        opn = "bc1fl";
5640
        goto likely;
5641
    case OPC_BC1T:
5642
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5643
        tcg_gen_andi_i32(t0, t0, 1);
5644
        tcg_gen_extu_i32_tl(bcond, t0);
5645
        opn = "bc1t";
5646
        goto not_likely;
5647
    case OPC_BC1TL:
5648
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5649
        tcg_gen_andi_i32(t0, t0, 1);
5650
        tcg_gen_extu_i32_tl(bcond, t0);
5651
        opn = "bc1tl";
5652
    likely:
5653
        ctx->hflags |= MIPS_HFLAG_BL;
5654
        break;
5655
    case OPC_BC1FANY2:
5656
        {
5657
            TCGv_i32 t1 = tcg_temp_new_i32();
5658
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5659
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5660
            tcg_gen_nor_i32(t0, t0, t1);
5661
            tcg_temp_free_i32(t1);
5662
            tcg_gen_andi_i32(t0, t0, 1);
5663
            tcg_gen_extu_i32_tl(bcond, t0);
5664
        }
5665
        opn = "bc1any2f";
5666
        goto not_likely;
5667
    case OPC_BC1TANY2:
5668
        {
5669
            TCGv_i32 t1 = tcg_temp_new_i32();
5670
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5671
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5672
            tcg_gen_or_i32(t0, t0, t1);
5673
            tcg_temp_free_i32(t1);
5674
            tcg_gen_andi_i32(t0, t0, 1);
5675
            tcg_gen_extu_i32_tl(bcond, t0);
5676
        }
5677
        opn = "bc1any2t";
5678
        goto not_likely;
5679
    case OPC_BC1FANY4:
5680
        {
5681
            TCGv_i32 t1 = tcg_temp_new_i32();
5682
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5683
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5684
            tcg_gen_or_i32(t0, t0, t1);
5685
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5686
            tcg_gen_or_i32(t0, t0, t1);
5687
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5688
            tcg_gen_nor_i32(t0, t0, t1);
5689
            tcg_temp_free_i32(t1);
5690
            tcg_gen_andi_i32(t0, t0, 1);
5691
            tcg_gen_extu_i32_tl(bcond, t0);
5692
        }
5693
        opn = "bc1any4f";
5694
        goto not_likely;
5695
    case OPC_BC1TANY4:
5696
        {
5697
            TCGv_i32 t1 = tcg_temp_new_i32();
5698
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5699
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5700
            tcg_gen_or_i32(t0, t0, t1);
5701
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5702
            tcg_gen_or_i32(t0, t0, t1);
5703
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5704
            tcg_gen_or_i32(t0, t0, t1);
5705
            tcg_temp_free_i32(t1);
5706
            tcg_gen_andi_i32(t0, t0, 1);
5707
            tcg_gen_extu_i32_tl(bcond, t0);
5708
        }
5709
        opn = "bc1any4t";
5710
    not_likely:
5711
        ctx->hflags |= MIPS_HFLAG_BC;
5712
        break;
5713
    default:
5714
        MIPS_INVAL(opn);
5715
        generate_exception (ctx, EXCP_RI);
5716
        goto out;
5717
    }
5718
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5719
               ctx->hflags, btarget);
5720
    ctx->btarget = btarget;
5721

    
5722
 out:
5723
    tcg_temp_free_i32(t0);
5724
}
5725

    
5726
/* Coprocessor 1 (FPU) */
5727

    
5728
#define FOP(func, fmt) (((fmt) << 21) | (func))
5729

    
5730
enum fopcode {
5731
    OPC_ADD_S = FOP(0, FMT_S),
5732
    OPC_SUB_S = FOP(1, FMT_S),
5733
    OPC_MUL_S = FOP(2, FMT_S),
5734
    OPC_DIV_S = FOP(3, FMT_S),
5735
    OPC_SQRT_S = FOP(4, FMT_S),
5736
    OPC_ABS_S = FOP(5, FMT_S),
5737
    OPC_MOV_S = FOP(6, FMT_S),
5738
    OPC_NEG_S = FOP(7, FMT_S),
5739
    OPC_ROUND_L_S = FOP(8, FMT_S),
5740
    OPC_TRUNC_L_S = FOP(9, FMT_S),
5741
    OPC_CEIL_L_S = FOP(10, FMT_S),
5742
    OPC_FLOOR_L_S = FOP(11, FMT_S),
5743
    OPC_ROUND_W_S = FOP(12, FMT_S),
5744
    OPC_TRUNC_W_S = FOP(13, FMT_S),
5745
    OPC_CEIL_W_S = FOP(14, FMT_S),
5746
    OPC_FLOOR_W_S = FOP(15, FMT_S),
5747
    OPC_MOVCF_S = FOP(17, FMT_S),
5748
    OPC_MOVZ_S = FOP(18, FMT_S),
5749
    OPC_MOVN_S = FOP(19, FMT_S),
5750
    OPC_RECIP_S = FOP(21, FMT_S),
5751
    OPC_RSQRT_S = FOP(22, FMT_S),
5752
    OPC_RECIP2_S = FOP(28, FMT_S),
5753
    OPC_RECIP1_S = FOP(29, FMT_S),
5754
    OPC_RSQRT1_S = FOP(30, FMT_S),
5755
    OPC_RSQRT2_S = FOP(31, FMT_S),
5756
    OPC_CVT_D_S = FOP(33, FMT_S),
5757
    OPC_CVT_W_S = FOP(36, FMT_S),
5758
    OPC_CVT_L_S = FOP(37, FMT_S),
5759
    OPC_CVT_PS_S = FOP(38, FMT_S),
5760
    OPC_CMP_F_S = FOP (48, FMT_S),
5761
    OPC_CMP_UN_S = FOP (49, FMT_S),
5762
    OPC_CMP_EQ_S = FOP (50, FMT_S),
5763
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
5764
    OPC_CMP_OLT_S = FOP (52, FMT_S),
5765
    OPC_CMP_ULT_S = FOP (53, FMT_S),
5766
    OPC_CMP_OLE_S = FOP (54, FMT_S),
5767
    OPC_CMP_ULE_S = FOP (55, FMT_S),
5768
    OPC_CMP_SF_S = FOP (56, FMT_S),
5769
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
5770
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
5771
    OPC_CMP_NGL_S = FOP (59, FMT_S),
5772
    OPC_CMP_LT_S = FOP (60, FMT_S),
5773
    OPC_CMP_NGE_S = FOP (61, FMT_S),
5774
    OPC_CMP_LE_S = FOP (62, FMT_S),
5775
    OPC_CMP_NGT_S = FOP (63, FMT_S),
5776

    
5777
    OPC_ADD_D = FOP(0, FMT_D),
5778
    OPC_SUB_D = FOP(1, FMT_D),
5779
    OPC_MUL_D = FOP(2, FMT_D),
5780
    OPC_DIV_D = FOP(3, FMT_D),
5781
    OPC_SQRT_D = FOP(4, FMT_D),
5782
    OPC_ABS_D = FOP(5, FMT_D),
5783
    OPC_MOV_D = FOP(6, FMT_D),
5784
    OPC_NEG_D = FOP(7, FMT_D),
5785
    OPC_ROUND_L_D = FOP(8, FMT_D),
5786
    OPC_TRUNC_L_D = FOP(9, FMT_D),
5787
    OPC_CEIL_L_D = FOP(10, FMT_D),
5788
    OPC_FLOOR_L_D = FOP(11, FMT_D),
5789
    OPC_ROUND_W_D = FOP(12, FMT_D),
5790
    OPC_TRUNC_W_D = FOP(13, FMT_D),
5791
    OPC_CEIL_W_D = FOP(14, FMT_D),
5792
    OPC_FLOOR_W_D = FOP(15, FMT_D),
5793
    OPC_MOVCF_D = FOP(17, FMT_D),
5794
    OPC_MOVZ_D = FOP(18, FMT_D),
5795
    OPC_MOVN_D = FOP(19, FMT_D),
5796
    OPC_RECIP_D = FOP(21, FMT_D),
5797
    OPC_RSQRT_D = FOP(22, FMT_D),
5798
    OPC_RECIP2_D = FOP(28, FMT_D),
5799
    OPC_RECIP1_D = FOP(29, FMT_D),
5800
    OPC_RSQRT1_D = FOP(30, FMT_D),
5801
    OPC_RSQRT2_D = FOP(31, FMT_D),
5802
    OPC_CVT_S_D = FOP(32, FMT_D),
5803
    OPC_CVT_W_D = FOP(36, FMT_D),
5804
    OPC_CVT_L_D = FOP(37, FMT_D),
5805
    OPC_CMP_F_D = FOP (48, FMT_D),
5806
    OPC_CMP_UN_D = FOP (49, FMT_D),
5807
    OPC_CMP_EQ_D = FOP (50, FMT_D),
5808
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
5809
    OPC_CMP_OLT_D = FOP (52, FMT_D),
5810
    OPC_CMP_ULT_D = FOP (53, FMT_D),
5811
    OPC_CMP_OLE_D = FOP (54, FMT_D),
5812
    OPC_CMP_ULE_D = FOP (55, FMT_D),
5813
    OPC_CMP_SF_D = FOP (56, FMT_D),
5814
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
5815
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
5816
    OPC_CMP_NGL_D = FOP (59, FMT_D),
5817
    OPC_CMP_LT_D = FOP (60, FMT_D),
5818
    OPC_CMP_NGE_D = FOP (61, FMT_D),
5819
    OPC_CMP_LE_D = FOP (62, FMT_D),
5820
    OPC_CMP_NGT_D = FOP (63, FMT_D),
5821

    
5822
    OPC_CVT_S_W = FOP(32, FMT_W),
5823
    OPC_CVT_D_W = FOP(33, FMT_W),
5824
    OPC_CVT_S_L = FOP(32, FMT_L),
5825
    OPC_CVT_D_L = FOP(33, FMT_L),
5826
    OPC_CVT_PS_PW = FOP(38, FMT_W),
5827

    
5828
    OPC_ADD_PS = FOP(0, FMT_PS),
5829
    OPC_SUB_PS = FOP(1, FMT_PS),
5830
    OPC_MUL_PS = FOP(2, FMT_PS),
5831
    OPC_DIV_PS = FOP(3, FMT_PS),
5832
    OPC_ABS_PS = FOP(5, FMT_PS),
5833
    OPC_MOV_PS = FOP(6, FMT_PS),
5834
    OPC_NEG_PS = FOP(7, FMT_PS),
5835
    OPC_MOVCF_PS = FOP(17, FMT_PS),
5836
    OPC_MOVZ_PS = FOP(18, FMT_PS),
5837
    OPC_MOVN_PS = FOP(19, FMT_PS),
5838
    OPC_ADDR_PS = FOP(24, FMT_PS),
5839
    OPC_MULR_PS = FOP(26, FMT_PS),
5840
    OPC_RECIP2_PS = FOP(28, FMT_PS),
5841
    OPC_RECIP1_PS = FOP(29, FMT_PS),
5842
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
5843
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
5844

    
5845
    OPC_CVT_S_PU = FOP(32, FMT_PS),
5846
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
5847
    OPC_CVT_S_PL = FOP(40, FMT_PS),
5848
    OPC_PLL_PS = FOP(44, FMT_PS),
5849
    OPC_PLU_PS = FOP(45, FMT_PS),
5850
    OPC_PUL_PS = FOP(46, FMT_PS),
5851
    OPC_PUU_PS = FOP(47, FMT_PS),
5852
    OPC_CMP_F_PS = FOP (48, FMT_PS),
5853
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
5854
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
5855
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
5856
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
5857
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
5858
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
5859
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
5860
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
5861
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
5862
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
5863
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
5864
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
5865
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
5866
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
5867
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
5868
};
5869

    
5870
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5871
{
5872
    const char *opn = "cp1 move";
5873
    TCGv t0 = tcg_temp_new();
5874

    
5875
    switch (opc) {
5876
    case OPC_MFC1:
5877
        {
5878
            TCGv_i32 fp0 = tcg_temp_new_i32();
5879

    
5880
            gen_load_fpr32(fp0, fs);
5881
            tcg_gen_ext_i32_tl(t0, fp0);
5882
            tcg_temp_free_i32(fp0);
5883
        }
5884
        gen_store_gpr(t0, rt);
5885
        opn = "mfc1";
5886
        break;
5887
    case OPC_MTC1:
5888
        gen_load_gpr(t0, rt);
5889
        {
5890
            TCGv_i32 fp0 = tcg_temp_new_i32();
5891

    
5892
            tcg_gen_trunc_tl_i32(fp0, t0);
5893
            gen_store_fpr32(fp0, fs);
5894
            tcg_temp_free_i32(fp0);
5895
        }
5896
        opn = "mtc1";
5897
        break;
5898
    case OPC_CFC1:
5899
        gen_helper_1i(cfc1, t0, fs);
5900
        gen_store_gpr(t0, rt);
5901
        opn = "cfc1";
5902
        break;
5903
    case OPC_CTC1:
5904
        gen_load_gpr(t0, rt);
5905
        gen_helper_1i(ctc1, t0, fs);
5906
        opn = "ctc1";
5907
        break;
5908
#if defined(TARGET_MIPS64)
5909
    case OPC_DMFC1:
5910
        gen_load_fpr64(ctx, t0, fs);
5911
        gen_store_gpr(t0, rt);
5912
        opn = "dmfc1";
5913
        break;
5914
    case OPC_DMTC1:
5915
        gen_load_gpr(t0, rt);
5916
        gen_store_fpr64(ctx, t0, fs);
5917
        opn = "dmtc1";
5918
        break;
5919
#endif
5920
    case OPC_MFHC1:
5921
        {
5922
            TCGv_i32 fp0 = tcg_temp_new_i32();
5923

    
5924
            gen_load_fpr32h(fp0, fs);
5925
            tcg_gen_ext_i32_tl(t0, fp0);
5926
            tcg_temp_free_i32(fp0);
5927
        }
5928
        gen_store_gpr(t0, rt);
5929
        opn = "mfhc1";
5930
        break;
5931
    case OPC_MTHC1:
5932
        gen_load_gpr(t0, rt);
5933
        {
5934
            TCGv_i32 fp0 = tcg_temp_new_i32();
5935

    
5936
            tcg_gen_trunc_tl_i32(fp0, t0);
5937
            gen_store_fpr32h(fp0, fs);
5938
            tcg_temp_free_i32(fp0);
5939
        }
5940
        opn = "mthc1";
5941
        break;
5942
    default:
5943
        MIPS_INVAL(opn);
5944
        generate_exception (ctx, EXCP_RI);
5945
        goto out;
5946
    }
5947
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5948

    
5949
 out:
5950
    tcg_temp_free(t0);
5951
}
5952

    
5953
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5954
{
5955
    int l1;
5956
    TCGCond cond;
5957
    TCGv_i32 t0;
5958

    
5959
    if (rd == 0) {
5960
        /* Treat as NOP. */
5961
        return;
5962
    }
5963

    
5964
    if (tf)
5965
        cond = TCG_COND_EQ;
5966
    else
5967
        cond = TCG_COND_NE;
5968

    
5969
    l1 = gen_new_label();
5970
    t0 = tcg_temp_new_i32();
5971
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5972
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5973
    tcg_temp_free_i32(t0);
5974
    if (rs == 0) {
5975
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5976
    } else {
5977
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5978
    }
5979
    gen_set_label(l1);
5980
}
5981

    
5982
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5983
{
5984
    int cond;
5985
    TCGv_i32 t0 = tcg_temp_new_i32();
5986
    int l1 = gen_new_label();
5987

    
5988
    if (tf)
5989
        cond = TCG_COND_EQ;
5990
    else
5991
        cond = TCG_COND_NE;
5992

    
5993
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5994
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5995
    gen_load_fpr32(t0, fs);
5996
    gen_store_fpr32(t0, fd);
5997
    gen_set_label(l1);
5998
    tcg_temp_free_i32(t0);
5999
}
6000

    
6001
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6002
{
6003
    int cond;
6004
    TCGv_i32 t0 = tcg_temp_new_i32();
6005
    TCGv_i64 fp0;
6006
    int l1 = gen_new_label();
6007

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

    
6013
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6014
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6015
    tcg_temp_free_i32(t0);
6016
    fp0 = tcg_temp_new_i64();
6017
    gen_load_fpr64(ctx, fp0, fs);
6018
    gen_store_fpr64(ctx, fp0, fd);
6019
    tcg_temp_free_i64(fp0);
6020
    gen_set_label(l1);
6021
}
6022

    
6023
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6024
{
6025
    int cond;
6026
    TCGv_i32 t0 = tcg_temp_new_i32();
6027
    int l1 = gen_new_label();
6028
    int l2 = gen_new_label();
6029

    
6030
    if (tf)
6031
        cond = TCG_COND_EQ;
6032
    else
6033
        cond = TCG_COND_NE;
6034

    
6035
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6036
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6037
    gen_load_fpr32(t0, fs);
6038
    gen_store_fpr32(t0, fd);
6039
    gen_set_label(l1);
6040

    
6041
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6042
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6043
    gen_load_fpr32h(t0, fs);
6044
    gen_store_fpr32h(t0, fd);
6045
    tcg_temp_free_i32(t0);
6046
    gen_set_label(l2);
6047
}
6048

    
6049

    
6050
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6051
                        int ft, int fs, int fd, int cc)
6052
{
6053
    const char *opn = "farith";
6054
    const char *condnames[] = {
6055
            "c.f",
6056
            "c.un",
6057
            "c.eq",
6058
            "c.ueq",
6059
            "c.olt",
6060
            "c.ult",
6061
            "c.ole",
6062
            "c.ule",
6063
            "c.sf",
6064
            "c.ngle",
6065
            "c.seq",
6066
            "c.ngl",
6067
            "c.lt",
6068
            "c.nge",
6069
            "c.le",
6070
            "c.ngt",
6071
    };
6072
    const char *condnames_abs[] = {
6073
            "cabs.f",
6074
            "cabs.un",
6075
            "cabs.eq",
6076
            "cabs.ueq",
6077
            "cabs.olt",
6078
            "cabs.ult",
6079
            "cabs.ole",
6080
            "cabs.ule",
6081
            "cabs.sf",
6082
            "cabs.ngle",
6083
            "cabs.seq",
6084
            "cabs.ngl",
6085
            "cabs.lt",
6086
            "cabs.nge",
6087
            "cabs.le",
6088
            "cabs.ngt",
6089
    };
6090
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6091
    uint32_t func = ctx->opcode & 0x3f;
6092

    
6093
    switch (op1) {
6094
    case OPC_ADD_S:
6095
        {
6096
            TCGv_i32 fp0 = tcg_temp_new_i32();
6097
            TCGv_i32 fp1 = tcg_temp_new_i32();
6098

    
6099
            gen_load_fpr32(fp0, fs);
6100
            gen_load_fpr32(fp1, ft);
6101
            gen_helper_float_add_s(fp0, fp0, fp1);
6102
            tcg_temp_free_i32(fp1);
6103
            gen_store_fpr32(fp0, fd);
6104
            tcg_temp_free_i32(fp0);
6105
        }
6106
        opn = "add.s";
6107
        optype = BINOP;
6108
        break;
6109
    case OPC_SUB_S:
6110
        {
6111
            TCGv_i32 fp0 = tcg_temp_new_i32();
6112
            TCGv_i32 fp1 = tcg_temp_new_i32();
6113

    
6114
            gen_load_fpr32(fp0, fs);
6115
            gen_load_fpr32(fp1, ft);
6116
            gen_helper_float_sub_s(fp0, fp0, fp1);
6117
            tcg_temp_free_i32(fp1);
6118
            gen_store_fpr32(fp0, fd);
6119
            tcg_temp_free_i32(fp0);
6120
        }
6121
        opn = "sub.s";
6122
        optype = BINOP;
6123
        break;
6124
    case OPC_MUL_S:
6125
        {
6126
            TCGv_i32 fp0 = tcg_temp_new_i32();
6127
            TCGv_i32 fp1 = tcg_temp_new_i32();
6128

    
6129
            gen_load_fpr32(fp0, fs);
6130
            gen_load_fpr32(fp1, ft);
6131
            gen_helper_float_mul_s(fp0, fp0, fp1);
6132
            tcg_temp_free_i32(fp1);
6133
            gen_store_fpr32(fp0, fd);
6134
            tcg_temp_free_i32(fp0);
6135
        }
6136
        opn = "mul.s";
6137
        optype = BINOP;
6138
        break;
6139
    case OPC_DIV_S:
6140
        {
6141
            TCGv_i32 fp0 = tcg_temp_new_i32();
6142
            TCGv_i32 fp1 = tcg_temp_new_i32();
6143

    
6144
            gen_load_fpr32(fp0, fs);
6145
            gen_load_fpr32(fp1, ft);
6146
            gen_helper_float_div_s(fp0, fp0, fp1);
6147
            tcg_temp_free_i32(fp1);
6148
            gen_store_fpr32(fp0, fd);
6149
            tcg_temp_free_i32(fp0);
6150
        }
6151
        opn = "div.s";
6152
        optype = BINOP;
6153
        break;
6154
    case OPC_SQRT_S:
6155
        {
6156
            TCGv_i32 fp0 = tcg_temp_new_i32();
6157

    
6158
            gen_load_fpr32(fp0, fs);
6159
            gen_helper_float_sqrt_s(fp0, fp0);
6160
            gen_store_fpr32(fp0, fd);
6161
            tcg_temp_free_i32(fp0);
6162
        }
6163
        opn = "sqrt.s";
6164
        break;
6165
    case OPC_ABS_S:
6166
        {
6167
            TCGv_i32 fp0 = tcg_temp_new_i32();
6168

    
6169
            gen_load_fpr32(fp0, fs);
6170
            gen_helper_float_abs_s(fp0, fp0);
6171
            gen_store_fpr32(fp0, fd);
6172
            tcg_temp_free_i32(fp0);
6173
        }
6174
        opn = "abs.s";
6175
        break;
6176
    case OPC_MOV_S:
6177
        {
6178
            TCGv_i32 fp0 = tcg_temp_new_i32();
6179

    
6180
            gen_load_fpr32(fp0, fs);
6181
            gen_store_fpr32(fp0, fd);
6182
            tcg_temp_free_i32(fp0);
6183
        }
6184
        opn = "mov.s";
6185
        break;
6186
    case OPC_NEG_S:
6187
        {
6188
            TCGv_i32 fp0 = tcg_temp_new_i32();
6189

    
6190
            gen_load_fpr32(fp0, fs);
6191
            gen_helper_float_chs_s(fp0, fp0);
6192
            gen_store_fpr32(fp0, fd);
6193
            tcg_temp_free_i32(fp0);
6194
        }
6195
        opn = "neg.s";
6196
        break;
6197
    case OPC_ROUND_L_S:
6198
        check_cp1_64bitmode(ctx);
6199
        {
6200
            TCGv_i32 fp32 = tcg_temp_new_i32();
6201
            TCGv_i64 fp64 = tcg_temp_new_i64();
6202

    
6203
            gen_load_fpr32(fp32, fs);
6204
            gen_helper_float_roundl_s(fp64, fp32);
6205
            tcg_temp_free_i32(fp32);
6206
            gen_store_fpr64(ctx, fp64, fd);
6207
            tcg_temp_free_i64(fp64);
6208
        }
6209
        opn = "round.l.s";
6210
        break;
6211
    case OPC_TRUNC_L_S:
6212
        check_cp1_64bitmode(ctx);
6213
        {
6214
            TCGv_i32 fp32 = tcg_temp_new_i32();
6215
            TCGv_i64 fp64 = tcg_temp_new_i64();
6216

    
6217
            gen_load_fpr32(fp32, fs);
6218
            gen_helper_float_truncl_s(fp64, fp32);
6219
            tcg_temp_free_i32(fp32);
6220
            gen_store_fpr64(ctx, fp64, fd);
6221
            tcg_temp_free_i64(fp64);
6222
        }
6223
        opn = "trunc.l.s";
6224
        break;
6225
    case OPC_CEIL_L_S:
6226
        check_cp1_64bitmode(ctx);
6227
        {
6228
            TCGv_i32 fp32 = tcg_temp_new_i32();
6229
            TCGv_i64 fp64 = tcg_temp_new_i64();
6230

    
6231
            gen_load_fpr32(fp32, fs);
6232
            gen_helper_float_ceill_s(fp64, fp32);
6233
            tcg_temp_free_i32(fp32);
6234
            gen_store_fpr64(ctx, fp64, fd);
6235
            tcg_temp_free_i64(fp64);
6236
        }
6237
        opn = "ceil.l.s";
6238
        break;
6239
    case OPC_FLOOR_L_S:
6240
        check_cp1_64bitmode(ctx);
6241
        {
6242
            TCGv_i32 fp32 = tcg_temp_new_i32();
6243
            TCGv_i64 fp64 = tcg_temp_new_i64();
6244

    
6245
            gen_load_fpr32(fp32, fs);
6246
            gen_helper_float_floorl_s(fp64, fp32);
6247
            tcg_temp_free_i32(fp32);
6248
            gen_store_fpr64(ctx, fp64, fd);
6249
            tcg_temp_free_i64(fp64);
6250
        }
6251
        opn = "floor.l.s";
6252
        break;
6253
    case OPC_ROUND_W_S:
6254
        {
6255
            TCGv_i32 fp0 = tcg_temp_new_i32();
6256

    
6257
            gen_load_fpr32(fp0, fs);
6258
            gen_helper_float_roundw_s(fp0, fp0);
6259
            gen_store_fpr32(fp0, fd);
6260
            tcg_temp_free_i32(fp0);
6261
        }
6262
        opn = "round.w.s";
6263
        break;
6264
    case OPC_TRUNC_W_S:
6265
        {
6266
            TCGv_i32 fp0 = tcg_temp_new_i32();
6267

    
6268
            gen_load_fpr32(fp0, fs);
6269
            gen_helper_float_truncw_s(fp0, fp0);
6270
            gen_store_fpr32(fp0, fd);
6271
            tcg_temp_free_i32(fp0);
6272
        }
6273
        opn = "trunc.w.s";
6274
        break;
6275
    case OPC_CEIL_W_S:
6276
        {
6277
            TCGv_i32 fp0 = tcg_temp_new_i32();
6278

    
6279
            gen_load_fpr32(fp0, fs);
6280
            gen_helper_float_ceilw_s(fp0, fp0);
6281
            gen_store_fpr32(fp0, fd);
6282
            tcg_temp_free_i32(fp0);
6283
        }
6284
        opn = "ceil.w.s";
6285
        break;
6286
    case OPC_FLOOR_W_S:
6287
        {
6288
            TCGv_i32 fp0 = tcg_temp_new_i32();
6289

    
6290
            gen_load_fpr32(fp0, fs);
6291
            gen_helper_float_floorw_s(fp0, fp0);
6292
            gen_store_fpr32(fp0, fd);
6293
            tcg_temp_free_i32(fp0);
6294
        }
6295
        opn = "floor.w.s";
6296
        break;
6297
    case OPC_MOVCF_S:
6298
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6299
        opn = "movcf.s";
6300
        break;
6301
    case OPC_MOVZ_S:
6302
        {
6303
            int l1 = gen_new_label();
6304
            TCGv_i32 fp0;
6305

    
6306
            if (ft != 0) {
6307
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6308
            }
6309
            fp0 = tcg_temp_new_i32();
6310
            gen_load_fpr32(fp0, fs);
6311
            gen_store_fpr32(fp0, fd);
6312
            tcg_temp_free_i32(fp0);
6313
            gen_set_label(l1);
6314
        }
6315
        opn = "movz.s";
6316
        break;
6317
    case OPC_MOVN_S:
6318
        {
6319
            int l1 = gen_new_label();
6320
            TCGv_i32 fp0;
6321

    
6322
            if (ft != 0) {
6323
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6324
                fp0 = tcg_temp_new_i32();
6325
                gen_load_fpr32(fp0, fs);
6326
                gen_store_fpr32(fp0, fd);
6327
                tcg_temp_free_i32(fp0);
6328
                gen_set_label(l1);
6329
            }
6330
        }
6331
        opn = "movn.s";
6332
        break;
6333
    case OPC_RECIP_S:
6334
        check_cop1x(ctx);
6335
        {
6336
            TCGv_i32 fp0 = tcg_temp_new_i32();
6337

    
6338
            gen_load_fpr32(fp0, fs);
6339
            gen_helper_float_recip_s(fp0, fp0);
6340
            gen_store_fpr32(fp0, fd);
6341
            tcg_temp_free_i32(fp0);
6342
        }
6343
        opn = "recip.s";
6344
        break;
6345
    case OPC_RSQRT_S:
6346
        check_cop1x(ctx);
6347
        {
6348
            TCGv_i32 fp0 = tcg_temp_new_i32();
6349

    
6350
            gen_load_fpr32(fp0, fs);
6351
            gen_helper_float_rsqrt_s(fp0, fp0);
6352
            gen_store_fpr32(fp0, fd);
6353
            tcg_temp_free_i32(fp0);
6354
        }
6355
        opn = "rsqrt.s";
6356
        break;
6357
    case OPC_RECIP2_S:
6358
        check_cp1_64bitmode(ctx);
6359
        {
6360
            TCGv_i32 fp0 = tcg_temp_new_i32();
6361
            TCGv_i32 fp1 = tcg_temp_new_i32();
6362

    
6363
            gen_load_fpr32(fp0, fs);
6364
            gen_load_fpr32(fp1, fd);
6365
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6366
            tcg_temp_free_i32(fp1);
6367
            gen_store_fpr32(fp0, fd);
6368
            tcg_temp_free_i32(fp0);
6369
        }
6370
        opn = "recip2.s";
6371
        break;
6372
    case OPC_RECIP1_S:
6373
        check_cp1_64bitmode(ctx);
6374
        {
6375
            TCGv_i32 fp0 = tcg_temp_new_i32();
6376

    
6377
            gen_load_fpr32(fp0, fs);
6378
            gen_helper_float_recip1_s(fp0, fp0);
6379
            gen_store_fpr32(fp0, fd);
6380
            tcg_temp_free_i32(fp0);
6381
        }
6382
        opn = "recip1.s";
6383
        break;
6384
    case OPC_RSQRT1_S:
6385
        check_cp1_64bitmode(ctx);
6386
        {
6387
            TCGv_i32 fp0 = tcg_temp_new_i32();
6388

    
6389
            gen_load_fpr32(fp0, fs);
6390
            gen_helper_float_rsqrt1_s(fp0, fp0);
6391
            gen_store_fpr32(fp0, fd);
6392
            tcg_temp_free_i32(fp0);
6393
        }
6394
        opn = "rsqrt1.s";
6395
        break;
6396
    case OPC_RSQRT2_S:
6397
        check_cp1_64bitmode(ctx);
6398
        {
6399
            TCGv_i32 fp0 = tcg_temp_new_i32();
6400
            TCGv_i32 fp1 = tcg_temp_new_i32();
6401

    
6402
            gen_load_fpr32(fp0, fs);
6403
            gen_load_fpr32(fp1, ft);
6404
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6405
            tcg_temp_free_i32(fp1);
6406
            gen_store_fpr32(fp0, fd);
6407
            tcg_temp_free_i32(fp0);
6408
        }
6409
        opn = "rsqrt2.s";
6410
        break;
6411
    case OPC_CVT_D_S:
6412
        check_cp1_registers(ctx, fd);
6413
        {
6414
            TCGv_i32 fp32 = tcg_temp_new_i32();
6415
            TCGv_i64 fp64 = tcg_temp_new_i64();
6416

    
6417
            gen_load_fpr32(fp32, fs);
6418
            gen_helper_float_cvtd_s(fp64, fp32);
6419
            tcg_temp_free_i32(fp32);
6420
            gen_store_fpr64(ctx, fp64, fd);
6421
            tcg_temp_free_i64(fp64);
6422
        }
6423
        opn = "cvt.d.s";
6424
        break;
6425
    case OPC_CVT_W_S:
6426
        {
6427
            TCGv_i32 fp0 = tcg_temp_new_i32();
6428

    
6429
            gen_load_fpr32(fp0, fs);
6430
            gen_helper_float_cvtw_s(fp0, fp0);
6431
            gen_store_fpr32(fp0, fd);
6432
            tcg_temp_free_i32(fp0);
6433
        }
6434
        opn = "cvt.w.s";
6435
        break;
6436
    case OPC_CVT_L_S:
6437
        check_cp1_64bitmode(ctx);
6438
        {
6439
            TCGv_i32 fp32 = tcg_temp_new_i32();
6440
            TCGv_i64 fp64 = tcg_temp_new_i64();
6441

    
6442
            gen_load_fpr32(fp32, fs);
6443
            gen_helper_float_cvtl_s(fp64, fp32);
6444
            tcg_temp_free_i32(fp32);
6445
            gen_store_fpr64(ctx, fp64, fd);
6446
            tcg_temp_free_i64(fp64);
6447
        }
6448
        opn = "cvt.l.s";
6449
        break;
6450
    case OPC_CVT_PS_S:
6451
        check_cp1_64bitmode(ctx);
6452
        {
6453
            TCGv_i64 fp64 = tcg_temp_new_i64();
6454
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6455
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6456

    
6457
            gen_load_fpr32(fp32_0, fs);
6458
            gen_load_fpr32(fp32_1, ft);
6459
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6460
            tcg_temp_free_i32(fp32_1);
6461
            tcg_temp_free_i32(fp32_0);
6462
            gen_store_fpr64(ctx, fp64, fd);
6463
            tcg_temp_free_i64(fp64);
6464
        }
6465
        opn = "cvt.ps.s";
6466
        break;
6467
    case OPC_CMP_F_S:
6468
    case OPC_CMP_UN_S:
6469
    case OPC_CMP_EQ_S:
6470
    case OPC_CMP_UEQ_S:
6471
    case OPC_CMP_OLT_S:
6472
    case OPC_CMP_ULT_S:
6473
    case OPC_CMP_OLE_S:
6474
    case OPC_CMP_ULE_S:
6475
    case OPC_CMP_SF_S:
6476
    case OPC_CMP_NGLE_S:
6477
    case OPC_CMP_SEQ_S:
6478
    case OPC_CMP_NGL_S:
6479
    case OPC_CMP_LT_S:
6480
    case OPC_CMP_NGE_S:
6481
    case OPC_CMP_LE_S:
6482
    case OPC_CMP_NGT_S:
6483
        {
6484
            TCGv_i32 fp0 = tcg_temp_new_i32();
6485
            TCGv_i32 fp1 = tcg_temp_new_i32();
6486

    
6487
            gen_load_fpr32(fp0, fs);
6488
            gen_load_fpr32(fp1, ft);
6489
            if (ctx->opcode & (1 << 6)) {
6490
                check_cop1x(ctx);
6491
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6492
                opn = condnames_abs[func-48];
6493
            } else {
6494
                gen_cmp_s(func-48, fp0, fp1, cc);
6495
                opn = condnames[func-48];
6496
            }
6497
            tcg_temp_free_i32(fp0);
6498
            tcg_temp_free_i32(fp1);
6499
        }
6500
        break;
6501
    case OPC_ADD_D:
6502
        check_cp1_registers(ctx, fs | ft | fd);
6503
        {
6504
            TCGv_i64 fp0 = tcg_temp_new_i64();
6505
            TCGv_i64 fp1 = tcg_temp_new_i64();
6506

    
6507
            gen_load_fpr64(ctx, fp0, fs);
6508
            gen_load_fpr64(ctx, fp1, ft);
6509
            gen_helper_float_add_d(fp0, fp0, fp1);
6510
            tcg_temp_free_i64(fp1);
6511
            gen_store_fpr64(ctx, fp0, fd);
6512
            tcg_temp_free_i64(fp0);
6513
        }
6514
        opn = "add.d";
6515
        optype = BINOP;
6516
        break;
6517
    case OPC_SUB_D:
6518
        check_cp1_registers(ctx, fs | ft | fd);
6519
        {
6520
            TCGv_i64 fp0 = tcg_temp_new_i64();
6521
            TCGv_i64 fp1 = tcg_temp_new_i64();
6522

    
6523
            gen_load_fpr64(ctx, fp0, fs);
6524
            gen_load_fpr64(ctx, fp1, ft);
6525
            gen_helper_float_sub_d(fp0, fp0, fp1);
6526
            tcg_temp_free_i64(fp1);
6527
            gen_store_fpr64(ctx, fp0, fd);
6528
            tcg_temp_free_i64(fp0);
6529
        }
6530
        opn = "sub.d";
6531
        optype = BINOP;
6532
        break;
6533
    case OPC_MUL_D:
6534
        check_cp1_registers(ctx, fs | ft | fd);
6535
        {
6536
            TCGv_i64 fp0 = tcg_temp_new_i64();
6537
            TCGv_i64 fp1 = tcg_temp_new_i64();
6538

    
6539
            gen_load_fpr64(ctx, fp0, fs);
6540
            gen_load_fpr64(ctx, fp1, ft);
6541
            gen_helper_float_mul_d(fp0, fp0, fp1);
6542
            tcg_temp_free_i64(fp1);
6543
            gen_store_fpr64(ctx, fp0, fd);
6544
            tcg_temp_free_i64(fp0);
6545
        }
6546
        opn = "mul.d";
6547
        optype = BINOP;
6548
        break;
6549
    case OPC_DIV_D:
6550
        check_cp1_registers(ctx, fs | ft | fd);
6551
        {
6552
            TCGv_i64 fp0 = tcg_temp_new_i64();
6553
            TCGv_i64 fp1 = tcg_temp_new_i64();
6554

    
6555
            gen_load_fpr64(ctx, fp0, fs);
6556
            gen_load_fpr64(ctx, fp1, ft);
6557
            gen_helper_float_div_d(fp0, fp0, fp1);
6558
            tcg_temp_free_i64(fp1);
6559
            gen_store_fpr64(ctx, fp0, fd);
6560
            tcg_temp_free_i64(fp0);
6561
        }
6562
        opn = "div.d";
6563
        optype = BINOP;
6564
        break;
6565
    case OPC_SQRT_D:
6566
        check_cp1_registers(ctx, fs | fd);
6567
        {
6568
            TCGv_i64 fp0 = tcg_temp_new_i64();
6569

    
6570
            gen_load_fpr64(ctx, fp0, fs);
6571
            gen_helper_float_sqrt_d(fp0, fp0);
6572
            gen_store_fpr64(ctx, fp0, fd);
6573
            tcg_temp_free_i64(fp0);
6574
        }
6575
        opn = "sqrt.d";
6576
        break;
6577
    case OPC_ABS_D:
6578
        check_cp1_registers(ctx, fs | fd);
6579
        {
6580
            TCGv_i64 fp0 = tcg_temp_new_i64();
6581

    
6582
            gen_load_fpr64(ctx, fp0, fs);
6583
            gen_helper_float_abs_d(fp0, fp0);
6584
            gen_store_fpr64(ctx, fp0, fd);
6585
            tcg_temp_free_i64(fp0);
6586
        }
6587
        opn = "abs.d";
6588
        break;
6589
    case OPC_MOV_D:
6590
        check_cp1_registers(ctx, fs | fd);
6591
        {
6592
            TCGv_i64 fp0 = tcg_temp_new_i64();
6593

    
6594
            gen_load_fpr64(ctx, fp0, fs);
6595
            gen_store_fpr64(ctx, fp0, fd);
6596
            tcg_temp_free_i64(fp0);
6597
        }
6598
        opn = "mov.d";
6599
        break;
6600
    case OPC_NEG_D:
6601
        check_cp1_registers(ctx, fs | fd);
6602
        {
6603
            TCGv_i64 fp0 = tcg_temp_new_i64();
6604

    
6605
            gen_load_fpr64(ctx, fp0, fs);
6606
            gen_helper_float_chs_d(fp0, fp0);
6607
            gen_store_fpr64(ctx, fp0, fd);
6608
            tcg_temp_free_i64(fp0);
6609
        }
6610
        opn = "neg.d";
6611
        break;
6612
    case OPC_ROUND_L_D:
6613
        check_cp1_64bitmode(ctx);
6614
        {
6615
            TCGv_i64 fp0 = tcg_temp_new_i64();
6616

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

    
6629
            gen_load_fpr64(ctx, fp0, fs);
6630
            gen_helper_float_truncl_d(fp0, fp0);
6631
            gen_store_fpr64(ctx, fp0, fd);
6632
            tcg_temp_free_i64(fp0);
6633
        }
6634
        opn = "trunc.l.d";
6635
        break;
6636
    case OPC_CEIL_L_D:
6637
        check_cp1_64bitmode(ctx);
6638
        {
6639
            TCGv_i64 fp0 = tcg_temp_new_i64();
6640

    
6641
            gen_load_fpr64(ctx, fp0, fs);
6642
            gen_helper_float_ceill_d(fp0, fp0);
6643
            gen_store_fpr64(ctx, fp0, fd);
6644
            tcg_temp_free_i64(fp0);
6645
        }
6646
        opn = "ceil.l.d";
6647
        break;
6648
    case OPC_FLOOR_L_D:
6649
        check_cp1_64bitmode(ctx);
6650
        {
6651
            TCGv_i64 fp0 = tcg_temp_new_i64();
6652

    
6653
            gen_load_fpr64(ctx, fp0, fs);
6654
            gen_helper_float_floorl_d(fp0, fp0);
6655
            gen_store_fpr64(ctx, fp0, fd);
6656
            tcg_temp_free_i64(fp0);
6657
        }
6658
        opn = "floor.l.d";
6659
        break;
6660
    case OPC_ROUND_W_D:
6661
        check_cp1_registers(ctx, fs);
6662
        {
6663
            TCGv_i32 fp32 = tcg_temp_new_i32();
6664
            TCGv_i64 fp64 = tcg_temp_new_i64();
6665

    
6666
            gen_load_fpr64(ctx, fp64, fs);
6667
            gen_helper_float_roundw_d(fp32, fp64);
6668
            tcg_temp_free_i64(fp64);
6669
            gen_store_fpr32(fp32, fd);
6670
            tcg_temp_free_i32(fp32);
6671
        }
6672
        opn = "round.w.d";
6673
        break;
6674
    case OPC_TRUNC_W_D:
6675
        check_cp1_registers(ctx, fs);
6676
        {
6677
            TCGv_i32 fp32 = tcg_temp_new_i32();
6678
            TCGv_i64 fp64 = tcg_temp_new_i64();
6679

    
6680
            gen_load_fpr64(ctx, fp64, fs);
6681
            gen_helper_float_truncw_d(fp32, fp64);
6682
            tcg_temp_free_i64(fp64);
6683
            gen_store_fpr32(fp32, fd);
6684
            tcg_temp_free_i32(fp32);
6685
        }
6686
        opn = "trunc.w.d";
6687
        break;
6688
    case OPC_CEIL_W_D:
6689
        check_cp1_registers(ctx, fs);
6690
        {
6691
            TCGv_i32 fp32 = tcg_temp_new_i32();
6692
            TCGv_i64 fp64 = tcg_temp_new_i64();
6693

    
6694
            gen_load_fpr64(ctx, fp64, fs);
6695
            gen_helper_float_ceilw_d(fp32, fp64);
6696
            tcg_temp_free_i64(fp64);
6697
            gen_store_fpr32(fp32, fd);
6698
            tcg_temp_free_i32(fp32);
6699
        }
6700
        opn = "ceil.w.d";
6701
        break;
6702
    case OPC_FLOOR_W_D:
6703
        check_cp1_registers(ctx, fs);
6704
        {
6705
            TCGv_i32 fp32 = tcg_temp_new_i32();
6706
            TCGv_i64 fp64 = tcg_temp_new_i64();
6707

    
6708
            gen_load_fpr64(ctx, fp64, fs);
6709
            gen_helper_float_floorw_d(fp32, fp64);
6710
            tcg_temp_free_i64(fp64);
6711
            gen_store_fpr32(fp32, fd);
6712
            tcg_temp_free_i32(fp32);
6713
        }
6714
        opn = "floor.w.d";
6715
        break;
6716
    case OPC_MOVCF_D:
6717
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6718
        opn = "movcf.d";
6719
        break;
6720
    case OPC_MOVZ_D:
6721
        {
6722
            int l1 = gen_new_label();
6723
            TCGv_i64 fp0;
6724

    
6725
            if (ft != 0) {
6726
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6727
            }
6728
            fp0 = tcg_temp_new_i64();
6729
            gen_load_fpr64(ctx, fp0, fs);
6730
            gen_store_fpr64(ctx, fp0, fd);
6731
            tcg_temp_free_i64(fp0);
6732
            gen_set_label(l1);
6733
        }
6734
        opn = "movz.d";
6735
        break;
6736
    case OPC_MOVN_D:
6737
        {
6738
            int l1 = gen_new_label();
6739
            TCGv_i64 fp0;
6740

    
6741
            if (ft != 0) {
6742
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6743
                fp0 = tcg_temp_new_i64();
6744
                gen_load_fpr64(ctx, fp0, fs);
6745
                gen_store_fpr64(ctx, fp0, fd);
6746
                tcg_temp_free_i64(fp0);
6747
                gen_set_label(l1);
6748
            }
6749
        }
6750
        opn = "movn.d";
6751
        break;
6752
    case OPC_RECIP_D:
6753
        check_cp1_64bitmode(ctx);
6754
        {
6755
            TCGv_i64 fp0 = tcg_temp_new_i64();
6756

    
6757
            gen_load_fpr64(ctx, fp0, fs);
6758
            gen_helper_float_recip_d(fp0, fp0);
6759
            gen_store_fpr64(ctx, fp0, fd);
6760
            tcg_temp_free_i64(fp0);
6761
        }
6762
        opn = "recip.d";
6763
        break;
6764
    case OPC_RSQRT_D:
6765
        check_cp1_64bitmode(ctx);
6766
        {
6767
            TCGv_i64 fp0 = tcg_temp_new_i64();
6768

    
6769
            gen_load_fpr64(ctx, fp0, fs);
6770
            gen_helper_float_rsqrt_d(fp0, fp0);
6771
            gen_store_fpr64(ctx, fp0, fd);
6772
            tcg_temp_free_i64(fp0);
6773
        }
6774
        opn = "rsqrt.d";
6775
        break;
6776
    case OPC_RECIP2_D:
6777
        check_cp1_64bitmode(ctx);
6778
        {
6779
            TCGv_i64 fp0 = tcg_temp_new_i64();
6780
            TCGv_i64 fp1 = tcg_temp_new_i64();
6781

    
6782
            gen_load_fpr64(ctx, fp0, fs);
6783
            gen_load_fpr64(ctx, fp1, ft);
6784
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6785
            tcg_temp_free_i64(fp1);
6786
            gen_store_fpr64(ctx, fp0, fd);
6787
            tcg_temp_free_i64(fp0);
6788
        }
6789
        opn = "recip2.d";
6790
        break;
6791
    case OPC_RECIP1_D:
6792
        check_cp1_64bitmode(ctx);
6793
        {
6794
            TCGv_i64 fp0 = tcg_temp_new_i64();
6795

    
6796
            gen_load_fpr64(ctx, fp0, fs);
6797
            gen_helper_float_recip1_d(fp0, fp0);
6798
            gen_store_fpr64(ctx, fp0, fd);
6799
            tcg_temp_free_i64(fp0);
6800
        }
6801
        opn = "recip1.d";
6802
        break;
6803
    case OPC_RSQRT1_D:
6804
        check_cp1_64bitmode(ctx);
6805
        {
6806
            TCGv_i64 fp0 = tcg_temp_new_i64();
6807

    
6808
            gen_load_fpr64(ctx, fp0, fs);
6809
            gen_helper_float_rsqrt1_d(fp0, fp0);
6810
            gen_store_fpr64(ctx, fp0, fd);
6811
            tcg_temp_free_i64(fp0);
6812
        }
6813
        opn = "rsqrt1.d";
6814
        break;
6815
    case OPC_RSQRT2_D:
6816
        check_cp1_64bitmode(ctx);
6817
        {
6818
            TCGv_i64 fp0 = tcg_temp_new_i64();
6819
            TCGv_i64 fp1 = tcg_temp_new_i64();
6820

    
6821
            gen_load_fpr64(ctx, fp0, fs);
6822
            gen_load_fpr64(ctx, fp1, ft);
6823
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6824
            tcg_temp_free_i64(fp1);
6825
            gen_store_fpr64(ctx, fp0, fd);
6826
            tcg_temp_free_i64(fp0);
6827
        }
6828
        opn = "rsqrt2.d";
6829
        break;
6830
    case OPC_CMP_F_D:
6831
    case OPC_CMP_UN_D:
6832
    case OPC_CMP_EQ_D:
6833
    case OPC_CMP_UEQ_D:
6834
    case OPC_CMP_OLT_D:
6835
    case OPC_CMP_ULT_D:
6836
    case OPC_CMP_OLE_D:
6837
    case OPC_CMP_ULE_D:
6838
    case OPC_CMP_SF_D:
6839
    case OPC_CMP_NGLE_D:
6840
    case OPC_CMP_SEQ_D:
6841
    case OPC_CMP_NGL_D:
6842
    case OPC_CMP_LT_D:
6843
    case OPC_CMP_NGE_D:
6844
    case OPC_CMP_LE_D:
6845
    case OPC_CMP_NGT_D:
6846
        {
6847
            TCGv_i64 fp0 = tcg_temp_new_i64();
6848
            TCGv_i64 fp1 = tcg_temp_new_i64();
6849

    
6850
            gen_load_fpr64(ctx, fp0, fs);
6851
            gen_load_fpr64(ctx, fp1, ft);
6852
            if (ctx->opcode & (1 << 6)) {
6853
                check_cop1x(ctx);
6854
                check_cp1_registers(ctx, fs | ft);
6855
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6856
                opn = condnames_abs[func-48];
6857
            } else {
6858
                check_cp1_registers(ctx, fs | ft);
6859
                gen_cmp_d(func-48, fp0, fp1, cc);
6860
                opn = condnames[func-48];
6861
            }
6862
            tcg_temp_free_i64(fp0);
6863
            tcg_temp_free_i64(fp1);
6864
        }
6865
        break;
6866
    case OPC_CVT_S_D:
6867
        check_cp1_registers(ctx, fs);
6868
        {
6869
            TCGv_i32 fp32 = tcg_temp_new_i32();
6870
            TCGv_i64 fp64 = tcg_temp_new_i64();
6871

    
6872
            gen_load_fpr64(ctx, fp64, fs);
6873
            gen_helper_float_cvts_d(fp32, fp64);
6874
            tcg_temp_free_i64(fp64);
6875
            gen_store_fpr32(fp32, fd);
6876
            tcg_temp_free_i32(fp32);
6877
        }
6878
        opn = "cvt.s.d";
6879
        break;
6880
    case OPC_CVT_W_D:
6881
        check_cp1_registers(ctx, fs);
6882
        {
6883
            TCGv_i32 fp32 = tcg_temp_new_i32();
6884
            TCGv_i64 fp64 = tcg_temp_new_i64();
6885

    
6886
            gen_load_fpr64(ctx, fp64, fs);
6887
            gen_helper_float_cvtw_d(fp32, fp64);
6888
            tcg_temp_free_i64(fp64);
6889
            gen_store_fpr32(fp32, fd);
6890
            tcg_temp_free_i32(fp32);
6891
        }
6892
        opn = "cvt.w.d";
6893
        break;
6894
    case OPC_CVT_L_D:
6895
        check_cp1_64bitmode(ctx);
6896
        {
6897
            TCGv_i64 fp0 = tcg_temp_new_i64();
6898

    
6899
            gen_load_fpr64(ctx, fp0, fs);
6900
            gen_helper_float_cvtl_d(fp0, fp0);
6901
            gen_store_fpr64(ctx, fp0, fd);
6902
            tcg_temp_free_i64(fp0);
6903
        }
6904
        opn = "cvt.l.d";
6905
        break;
6906
    case OPC_CVT_S_W:
6907
        {
6908
            TCGv_i32 fp0 = tcg_temp_new_i32();
6909

    
6910
            gen_load_fpr32(fp0, fs);
6911
            gen_helper_float_cvts_w(fp0, fp0);
6912
            gen_store_fpr32(fp0, fd);
6913
            tcg_temp_free_i32(fp0);
6914
        }
6915
        opn = "cvt.s.w";
6916
        break;
6917
    case OPC_CVT_D_W:
6918
        check_cp1_registers(ctx, fd);
6919
        {
6920
            TCGv_i32 fp32 = tcg_temp_new_i32();
6921
            TCGv_i64 fp64 = tcg_temp_new_i64();
6922

    
6923
            gen_load_fpr32(fp32, fs);
6924
            gen_helper_float_cvtd_w(fp64, fp32);
6925
            tcg_temp_free_i32(fp32);
6926
            gen_store_fpr64(ctx, fp64, fd);
6927
            tcg_temp_free_i64(fp64);
6928
        }
6929
        opn = "cvt.d.w";
6930
        break;
6931
    case OPC_CVT_S_L:
6932
        check_cp1_64bitmode(ctx);
6933
        {
6934
            TCGv_i32 fp32 = tcg_temp_new_i32();
6935
            TCGv_i64 fp64 = tcg_temp_new_i64();
6936

    
6937
            gen_load_fpr64(ctx, fp64, fs);
6938
            gen_helper_float_cvts_l(fp32, fp64);
6939
            tcg_temp_free_i64(fp64);
6940
            gen_store_fpr32(fp32, fd);
6941
            tcg_temp_free_i32(fp32);
6942
        }
6943
        opn = "cvt.s.l";
6944
        break;
6945
    case OPC_CVT_D_L:
6946
        check_cp1_64bitmode(ctx);
6947
        {
6948
            TCGv_i64 fp0 = tcg_temp_new_i64();
6949

    
6950
            gen_load_fpr64(ctx, fp0, fs);
6951
            gen_helper_float_cvtd_l(fp0, fp0);
6952
            gen_store_fpr64(ctx, fp0, fd);
6953
            tcg_temp_free_i64(fp0);
6954
        }
6955
        opn = "cvt.d.l";
6956
        break;
6957
    case OPC_CVT_PS_PW:
6958
        check_cp1_64bitmode(ctx);
6959
        {
6960
            TCGv_i64 fp0 = tcg_temp_new_i64();
6961

    
6962
            gen_load_fpr64(ctx, fp0, fs);
6963
            gen_helper_float_cvtps_pw(fp0, fp0);
6964
            gen_store_fpr64(ctx, fp0, fd);
6965
            tcg_temp_free_i64(fp0);
6966
        }
6967
        opn = "cvt.ps.pw";
6968
        break;
6969
    case OPC_ADD_PS:
6970
        check_cp1_64bitmode(ctx);
6971
        {
6972
            TCGv_i64 fp0 = tcg_temp_new_i64();
6973
            TCGv_i64 fp1 = tcg_temp_new_i64();
6974

    
6975
            gen_load_fpr64(ctx, fp0, fs);
6976
            gen_load_fpr64(ctx, fp1, ft);
6977
            gen_helper_float_add_ps(fp0, fp0, fp1);
6978
            tcg_temp_free_i64(fp1);
6979
            gen_store_fpr64(ctx, fp0, fd);
6980
            tcg_temp_free_i64(fp0);
6981
        }
6982
        opn = "add.ps";
6983
        break;
6984
    case OPC_SUB_PS:
6985
        check_cp1_64bitmode(ctx);
6986
        {
6987
            TCGv_i64 fp0 = tcg_temp_new_i64();
6988
            TCGv_i64 fp1 = tcg_temp_new_i64();
6989

    
6990
            gen_load_fpr64(ctx, fp0, fs);
6991
            gen_load_fpr64(ctx, fp1, ft);
6992
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6993
            tcg_temp_free_i64(fp1);
6994
            gen_store_fpr64(ctx, fp0, fd);
6995
            tcg_temp_free_i64(fp0);
6996
        }
6997
        opn = "sub.ps";
6998
        break;
6999
    case OPC_MUL_PS:
7000
        check_cp1_64bitmode(ctx);
7001
        {
7002
            TCGv_i64 fp0 = tcg_temp_new_i64();
7003
            TCGv_i64 fp1 = tcg_temp_new_i64();
7004

    
7005
            gen_load_fpr64(ctx, fp0, fs);
7006
            gen_load_fpr64(ctx, fp1, ft);
7007
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7008
            tcg_temp_free_i64(fp1);
7009
            gen_store_fpr64(ctx, fp0, fd);
7010
            tcg_temp_free_i64(fp0);
7011
        }
7012
        opn = "mul.ps";
7013
        break;
7014
    case OPC_ABS_PS:
7015
        check_cp1_64bitmode(ctx);
7016
        {
7017
            TCGv_i64 fp0 = tcg_temp_new_i64();
7018

    
7019
            gen_load_fpr64(ctx, fp0, fs);
7020
            gen_helper_float_abs_ps(fp0, fp0);
7021
            gen_store_fpr64(ctx, fp0, fd);
7022
            tcg_temp_free_i64(fp0);
7023
        }
7024
        opn = "abs.ps";
7025
        break;
7026
    case OPC_MOV_PS:
7027
        check_cp1_64bitmode(ctx);
7028
        {
7029
            TCGv_i64 fp0 = tcg_temp_new_i64();
7030

    
7031
            gen_load_fpr64(ctx, fp0, fs);
7032
            gen_store_fpr64(ctx, fp0, fd);
7033
            tcg_temp_free_i64(fp0);
7034
        }
7035
        opn = "mov.ps";
7036
        break;
7037
    case OPC_NEG_PS:
7038
        check_cp1_64bitmode(ctx);
7039
        {
7040
            TCGv_i64 fp0 = tcg_temp_new_i64();
7041

    
7042
            gen_load_fpr64(ctx, fp0, fs);
7043
            gen_helper_float_chs_ps(fp0, fp0);
7044
            gen_store_fpr64(ctx, fp0, fd);
7045
            tcg_temp_free_i64(fp0);
7046
        }
7047
        opn = "neg.ps";
7048
        break;
7049
    case OPC_MOVCF_PS:
7050
        check_cp1_64bitmode(ctx);
7051
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7052
        opn = "movcf.ps";
7053
        break;
7054
    case OPC_MOVZ_PS:
7055
        check_cp1_64bitmode(ctx);
7056
        {
7057
            int l1 = gen_new_label();
7058
            TCGv_i64 fp0;
7059

    
7060
            if (ft != 0)
7061
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7062
            fp0 = tcg_temp_new_i64();
7063
            gen_load_fpr64(ctx, fp0, fs);
7064
            gen_store_fpr64(ctx, fp0, fd);
7065
            tcg_temp_free_i64(fp0);
7066
            gen_set_label(l1);
7067
        }
7068
        opn = "movz.ps";
7069
        break;
7070
    case OPC_MOVN_PS:
7071
        check_cp1_64bitmode(ctx);
7072
        {
7073
            int l1 = gen_new_label();
7074
            TCGv_i64 fp0;
7075

    
7076
            if (ft != 0) {
7077
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7078
                fp0 = tcg_temp_new_i64();
7079
                gen_load_fpr64(ctx, fp0, fs);
7080
                gen_store_fpr64(ctx, fp0, fd);
7081
                tcg_temp_free_i64(fp0);
7082
                gen_set_label(l1);
7083
            }
7084
        }
7085
        opn = "movn.ps";
7086
        break;
7087
    case OPC_ADDR_PS:
7088
        check_cp1_64bitmode(ctx);
7089
        {
7090
            TCGv_i64 fp0 = tcg_temp_new_i64();
7091
            TCGv_i64 fp1 = tcg_temp_new_i64();
7092

    
7093
            gen_load_fpr64(ctx, fp0, ft);
7094
            gen_load_fpr64(ctx, fp1, fs);
7095
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7096
            tcg_temp_free_i64(fp1);
7097
            gen_store_fpr64(ctx, fp0, fd);
7098
            tcg_temp_free_i64(fp0);
7099
        }
7100
        opn = "addr.ps";
7101
        break;
7102
    case OPC_MULR_PS:
7103
        check_cp1_64bitmode(ctx);
7104
        {
7105
            TCGv_i64 fp0 = tcg_temp_new_i64();
7106
            TCGv_i64 fp1 = tcg_temp_new_i64();
7107

    
7108
            gen_load_fpr64(ctx, fp0, ft);
7109
            gen_load_fpr64(ctx, fp1, fs);
7110
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7111
            tcg_temp_free_i64(fp1);
7112
            gen_store_fpr64(ctx, fp0, fd);
7113
            tcg_temp_free_i64(fp0);
7114
        }
7115
        opn = "mulr.ps";
7116
        break;
7117
    case OPC_RECIP2_PS:
7118
        check_cp1_64bitmode(ctx);
7119
        {
7120
            TCGv_i64 fp0 = tcg_temp_new_i64();
7121
            TCGv_i64 fp1 = tcg_temp_new_i64();
7122

    
7123
            gen_load_fpr64(ctx, fp0, fs);
7124
            gen_load_fpr64(ctx, fp1, fd);
7125
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7126
            tcg_temp_free_i64(fp1);
7127
            gen_store_fpr64(ctx, fp0, fd);
7128
            tcg_temp_free_i64(fp0);
7129
        }
7130
        opn = "recip2.ps";
7131
        break;
7132
    case OPC_RECIP1_PS:
7133
        check_cp1_64bitmode(ctx);
7134
        {
7135
            TCGv_i64 fp0 = tcg_temp_new_i64();
7136

    
7137
            gen_load_fpr64(ctx, fp0, fs);
7138
            gen_helper_float_recip1_ps(fp0, fp0);
7139
            gen_store_fpr64(ctx, fp0, fd);
7140
            tcg_temp_free_i64(fp0);
7141
        }
7142
        opn = "recip1.ps";
7143
        break;
7144
    case OPC_RSQRT1_PS:
7145
        check_cp1_64bitmode(ctx);
7146
        {
7147
            TCGv_i64 fp0 = tcg_temp_new_i64();
7148

    
7149
            gen_load_fpr64(ctx, fp0, fs);
7150
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7151
            gen_store_fpr64(ctx, fp0, fd);
7152
            tcg_temp_free_i64(fp0);
7153
        }
7154
        opn = "rsqrt1.ps";
7155
        break;
7156
    case OPC_RSQRT2_PS:
7157
        check_cp1_64bitmode(ctx);
7158
        {
7159
            TCGv_i64 fp0 = tcg_temp_new_i64();
7160
            TCGv_i64 fp1 = tcg_temp_new_i64();
7161

    
7162
            gen_load_fpr64(ctx, fp0, fs);
7163
            gen_load_fpr64(ctx, fp1, ft);
7164
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7165
            tcg_temp_free_i64(fp1);
7166
            gen_store_fpr64(ctx, fp0, fd);
7167
            tcg_temp_free_i64(fp0);
7168
        }
7169
        opn = "rsqrt2.ps";
7170
        break;
7171
    case OPC_CVT_S_PU:
7172
        check_cp1_64bitmode(ctx);
7173
        {
7174
            TCGv_i32 fp0 = tcg_temp_new_i32();
7175

    
7176
            gen_load_fpr32h(fp0, fs);
7177
            gen_helper_float_cvts_pu(fp0, fp0);
7178
            gen_store_fpr32(fp0, fd);
7179
            tcg_temp_free_i32(fp0);
7180
        }
7181
        opn = "cvt.s.pu";
7182
        break;
7183
    case OPC_CVT_PW_PS:
7184
        check_cp1_64bitmode(ctx);
7185
        {
7186
            TCGv_i64 fp0 = tcg_temp_new_i64();
7187

    
7188
            gen_load_fpr64(ctx, fp0, fs);
7189
            gen_helper_float_cvtpw_ps(fp0, fp0);
7190
            gen_store_fpr64(ctx, fp0, fd);
7191
            tcg_temp_free_i64(fp0);
7192
        }
7193
        opn = "cvt.pw.ps";
7194
        break;
7195
    case OPC_CVT_S_PL:
7196
        check_cp1_64bitmode(ctx);
7197
        {
7198
            TCGv_i32 fp0 = tcg_temp_new_i32();
7199

    
7200
            gen_load_fpr32(fp0, fs);
7201
            gen_helper_float_cvts_pl(fp0, fp0);
7202
            gen_store_fpr32(fp0, fd);
7203
            tcg_temp_free_i32(fp0);
7204
        }
7205
        opn = "cvt.s.pl";
7206
        break;
7207
    case OPC_PLL_PS:
7208
        check_cp1_64bitmode(ctx);
7209
        {
7210
            TCGv_i32 fp0 = tcg_temp_new_i32();
7211
            TCGv_i32 fp1 = tcg_temp_new_i32();
7212

    
7213
            gen_load_fpr32(fp0, fs);
7214
            gen_load_fpr32(fp1, ft);
7215
            gen_store_fpr32h(fp0, fd);
7216
            gen_store_fpr32(fp1, fd);
7217
            tcg_temp_free_i32(fp0);
7218
            tcg_temp_free_i32(fp1);
7219
        }
7220
        opn = "pll.ps";
7221
        break;
7222
    case OPC_PLU_PS:
7223
        check_cp1_64bitmode(ctx);
7224
        {
7225
            TCGv_i32 fp0 = tcg_temp_new_i32();
7226
            TCGv_i32 fp1 = tcg_temp_new_i32();
7227

    
7228
            gen_load_fpr32(fp0, fs);
7229
            gen_load_fpr32h(fp1, ft);
7230
            gen_store_fpr32(fp1, fd);
7231
            gen_store_fpr32h(fp0, fd);
7232
            tcg_temp_free_i32(fp0);
7233
            tcg_temp_free_i32(fp1);
7234
        }
7235
        opn = "plu.ps";
7236
        break;
7237
    case OPC_PUL_PS:
7238
        check_cp1_64bitmode(ctx);
7239
        {
7240
            TCGv_i32 fp0 = tcg_temp_new_i32();
7241
            TCGv_i32 fp1 = tcg_temp_new_i32();
7242

    
7243
            gen_load_fpr32h(fp0, fs);
7244
            gen_load_fpr32(fp1, ft);
7245
            gen_store_fpr32(fp1, fd);
7246
            gen_store_fpr32h(fp0, fd);
7247
            tcg_temp_free_i32(fp0);
7248
            tcg_temp_free_i32(fp1);
7249
        }
7250
        opn = "pul.ps";
7251
        break;
7252
    case OPC_PUU_PS:
7253
        check_cp1_64bitmode(ctx);
7254
        {
7255
            TCGv_i32 fp0 = tcg_temp_new_i32();
7256
            TCGv_i32 fp1 = tcg_temp_new_i32();
7257

    
7258
            gen_load_fpr32h(fp0, fs);
7259
            gen_load_fpr32h(fp1, ft);
7260
            gen_store_fpr32(fp1, fd);
7261
            gen_store_fpr32h(fp0, fd);
7262
            tcg_temp_free_i32(fp0);
7263
            tcg_temp_free_i32(fp1);
7264
        }
7265
        opn = "puu.ps";
7266
        break;
7267
    case OPC_CMP_F_PS:
7268
    case OPC_CMP_UN_PS:
7269
    case OPC_CMP_EQ_PS:
7270
    case OPC_CMP_UEQ_PS:
7271
    case OPC_CMP_OLT_PS:
7272
    case OPC_CMP_ULT_PS:
7273
    case OPC_CMP_OLE_PS:
7274
    case OPC_CMP_ULE_PS:
7275
    case OPC_CMP_SF_PS:
7276
    case OPC_CMP_NGLE_PS:
7277
    case OPC_CMP_SEQ_PS:
7278
    case OPC_CMP_NGL_PS:
7279
    case OPC_CMP_LT_PS:
7280
    case OPC_CMP_NGE_PS:
7281
    case OPC_CMP_LE_PS:
7282
    case OPC_CMP_NGT_PS:
7283
        check_cp1_64bitmode(ctx);
7284
        {
7285
            TCGv_i64 fp0 = tcg_temp_new_i64();
7286
            TCGv_i64 fp1 = tcg_temp_new_i64();
7287

    
7288
            gen_load_fpr64(ctx, fp0, fs);
7289
            gen_load_fpr64(ctx, fp1, ft);
7290
            if (ctx->opcode & (1 << 6)) {
7291
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7292
                opn = condnames_abs[func-48];
7293
            } else {
7294
                gen_cmp_ps(func-48, fp0, fp1, cc);
7295
                opn = condnames[func-48];
7296
            }
7297
            tcg_temp_free_i64(fp0);
7298
            tcg_temp_free_i64(fp1);
7299
        }
7300
        break;
7301
    default:
7302
        MIPS_INVAL(opn);
7303
        generate_exception (ctx, EXCP_RI);
7304
        return;
7305
    }
7306
    switch (optype) {
7307
    case BINOP:
7308
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7309
        break;
7310
    case CMPOP:
7311
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7312
        break;
7313
    default:
7314
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7315
        break;
7316
    }
7317
}
7318

    
7319
/* Coprocessor 3 (FPU) */
7320
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7321
                           int fd, int fs, int base, int index)
7322
{
7323
    const char *opn = "extended float load/store";
7324
    int store = 0;
7325
    TCGv t0 = tcg_temp_new();
7326

    
7327
    if (base == 0) {
7328
        gen_load_gpr(t0, index);
7329
    } else if (index == 0) {
7330
        gen_load_gpr(t0, base);
7331
    } else {
7332
        gen_load_gpr(t0, index);
7333
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7334
    }
7335
    /* Don't do NOP if destination is zero: we must perform the actual
7336
       memory access. */
7337
    save_cpu_state(ctx, 0);
7338
    switch (opc) {
7339
    case OPC_LWXC1:
7340
        check_cop1x(ctx);
7341
        {
7342
            TCGv_i32 fp0 = tcg_temp_new_i32();
7343

    
7344
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7345
            tcg_gen_trunc_tl_i32(fp0, t0);
7346
            gen_store_fpr32(fp0, fd);
7347
            tcg_temp_free_i32(fp0);
7348
        }
7349
        opn = "lwxc1";
7350
        break;
7351
    case OPC_LDXC1:
7352
        check_cop1x(ctx);
7353
        check_cp1_registers(ctx, fd);
7354
        {
7355
            TCGv_i64 fp0 = tcg_temp_new_i64();
7356

    
7357
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7358
            gen_store_fpr64(ctx, fp0, fd);
7359
            tcg_temp_free_i64(fp0);
7360
        }
7361
        opn = "ldxc1";
7362
        break;
7363
    case OPC_LUXC1:
7364
        check_cp1_64bitmode(ctx);
7365
        tcg_gen_andi_tl(t0, t0, ~0x7);
7366
        {
7367
            TCGv_i64 fp0 = tcg_temp_new_i64();
7368

    
7369
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7370
            gen_store_fpr64(ctx, fp0, fd);
7371
            tcg_temp_free_i64(fp0);
7372
        }
7373
        opn = "luxc1";
7374
        break;
7375
    case OPC_SWXC1:
7376
        check_cop1x(ctx);
7377
        {
7378
            TCGv_i32 fp0 = tcg_temp_new_i32();
7379
            TCGv t1 = tcg_temp_new();
7380

    
7381
            gen_load_fpr32(fp0, fs);
7382
            tcg_gen_extu_i32_tl(t1, fp0);
7383
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7384
            tcg_temp_free_i32(fp0);
7385
            tcg_temp_free(t1);
7386
        }
7387
        opn = "swxc1";
7388
        store = 1;
7389
        break;
7390
    case OPC_SDXC1:
7391
        check_cop1x(ctx);
7392
        check_cp1_registers(ctx, fs);
7393
        {
7394
            TCGv_i64 fp0 = tcg_temp_new_i64();
7395

    
7396
            gen_load_fpr64(ctx, fp0, fs);
7397
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7398
            tcg_temp_free_i64(fp0);
7399
        }
7400
        opn = "sdxc1";
7401
        store = 1;
7402
        break;
7403
    case OPC_SUXC1:
7404
        check_cp1_64bitmode(ctx);
7405
        tcg_gen_andi_tl(t0, t0, ~0x7);
7406
        {
7407
            TCGv_i64 fp0 = tcg_temp_new_i64();
7408

    
7409
            gen_load_fpr64(ctx, fp0, fs);
7410
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7411
            tcg_temp_free_i64(fp0);
7412
        }
7413
        opn = "suxc1";
7414
        store = 1;
7415
        break;
7416
    }
7417
    tcg_temp_free(t0);
7418
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7419
               regnames[index], regnames[base]);
7420
}
7421

    
7422
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7423
                            int fd, int fr, int fs, int ft)
7424
{
7425
    const char *opn = "flt3_arith";
7426

    
7427
    switch (opc) {
7428
    case OPC_ALNV_PS:
7429
        check_cp1_64bitmode(ctx);
7430
        {
7431
            TCGv t0 = tcg_temp_local_new();
7432
            TCGv_i32 fp = tcg_temp_new_i32();
7433
            TCGv_i32 fph = tcg_temp_new_i32();
7434
            int l1 = gen_new_label();
7435
            int l2 = gen_new_label();
7436

    
7437
            gen_load_gpr(t0, fr);
7438
            tcg_gen_andi_tl(t0, t0, 0x7);
7439

    
7440
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7441
            gen_load_fpr32(fp, fs);
7442
            gen_load_fpr32h(fph, fs);
7443
            gen_store_fpr32(fp, fd);
7444
            gen_store_fpr32h(fph, fd);
7445
            tcg_gen_br(l2);
7446
            gen_set_label(l1);
7447
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7448
            tcg_temp_free(t0);
7449
#ifdef TARGET_WORDS_BIGENDIAN
7450
            gen_load_fpr32(fp, fs);
7451
            gen_load_fpr32h(fph, ft);
7452
            gen_store_fpr32h(fp, fd);
7453
            gen_store_fpr32(fph, fd);
7454
#else
7455
            gen_load_fpr32h(fph, fs);
7456
            gen_load_fpr32(fp, ft);
7457
            gen_store_fpr32(fph, fd);
7458
            gen_store_fpr32h(fp, fd);
7459
#endif
7460
            gen_set_label(l2);
7461
            tcg_temp_free_i32(fp);
7462
            tcg_temp_free_i32(fph);
7463
        }
7464
        opn = "alnv.ps";
7465
        break;
7466
    case OPC_MADD_S:
7467
        check_cop1x(ctx);
7468
        {
7469
            TCGv_i32 fp0 = tcg_temp_new_i32();
7470
            TCGv_i32 fp1 = tcg_temp_new_i32();
7471
            TCGv_i32 fp2 = tcg_temp_new_i32();
7472

    
7473
            gen_load_fpr32(fp0, fs);
7474
            gen_load_fpr32(fp1, ft);
7475
            gen_load_fpr32(fp2, fr);
7476
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7477
            tcg_temp_free_i32(fp0);
7478
            tcg_temp_free_i32(fp1);
7479
            gen_store_fpr32(fp2, fd);
7480
            tcg_temp_free_i32(fp2);
7481
        }
7482
        opn = "madd.s";
7483
        break;
7484
    case OPC_MADD_D:
7485
        check_cop1x(ctx);
7486
        check_cp1_registers(ctx, fd | fs | ft | fr);
7487
        {
7488
            TCGv_i64 fp0 = tcg_temp_new_i64();
7489
            TCGv_i64 fp1 = tcg_temp_new_i64();
7490
            TCGv_i64 fp2 = tcg_temp_new_i64();
7491

    
7492
            gen_load_fpr64(ctx, fp0, fs);
7493
            gen_load_fpr64(ctx, fp1, ft);
7494
            gen_load_fpr64(ctx, fp2, fr);
7495
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7496
            tcg_temp_free_i64(fp0);
7497
            tcg_temp_free_i64(fp1);
7498
            gen_store_fpr64(ctx, fp2, fd);
7499
            tcg_temp_free_i64(fp2);
7500
        }
7501
        opn = "madd.d";
7502
        break;
7503
    case OPC_MADD_PS:
7504
        check_cp1_64bitmode(ctx);
7505
        {
7506
            TCGv_i64 fp0 = tcg_temp_new_i64();
7507
            TCGv_i64 fp1 = tcg_temp_new_i64();
7508
            TCGv_i64 fp2 = tcg_temp_new_i64();
7509

    
7510
            gen_load_fpr64(ctx, fp0, fs);
7511
            gen_load_fpr64(ctx, fp1, ft);
7512
            gen_load_fpr64(ctx, fp2, fr);
7513
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7514
            tcg_temp_free_i64(fp0);
7515
            tcg_temp_free_i64(fp1);
7516
            gen_store_fpr64(ctx, fp2, fd);
7517
            tcg_temp_free_i64(fp2);
7518
        }
7519
        opn = "madd.ps";
7520
        break;
7521
    case OPC_MSUB_S:
7522
        check_cop1x(ctx);
7523
        {
7524
            TCGv_i32 fp0 = tcg_temp_new_i32();
7525
            TCGv_i32 fp1 = tcg_temp_new_i32();
7526
            TCGv_i32 fp2 = tcg_temp_new_i32();
7527

    
7528
            gen_load_fpr32(fp0, fs);
7529
            gen_load_fpr32(fp1, ft);
7530
            gen_load_fpr32(fp2, fr);
7531
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7532
            tcg_temp_free_i32(fp0);
7533
            tcg_temp_free_i32(fp1);
7534
            gen_store_fpr32(fp2, fd);
7535
            tcg_temp_free_i32(fp2);
7536
        }
7537
        opn = "msub.s";
7538
        break;
7539
    case OPC_MSUB_D:
7540
        check_cop1x(ctx);
7541
        check_cp1_registers(ctx, fd | fs | ft | fr);
7542
        {
7543
            TCGv_i64 fp0 = tcg_temp_new_i64();
7544
            TCGv_i64 fp1 = tcg_temp_new_i64();
7545
            TCGv_i64 fp2 = tcg_temp_new_i64();
7546

    
7547
            gen_load_fpr64(ctx, fp0, fs);
7548
            gen_load_fpr64(ctx, fp1, ft);
7549
            gen_load_fpr64(ctx, fp2, fr);
7550
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7551
            tcg_temp_free_i64(fp0);
7552
            tcg_temp_free_i64(fp1);
7553
            gen_store_fpr64(ctx, fp2, fd);
7554
            tcg_temp_free_i64(fp2);
7555
        }
7556
        opn = "msub.d";
7557
        break;
7558
    case OPC_MSUB_PS:
7559
        check_cp1_64bitmode(ctx);
7560
        {
7561
            TCGv_i64 fp0 = tcg_temp_new_i64();
7562
            TCGv_i64 fp1 = tcg_temp_new_i64();
7563
            TCGv_i64 fp2 = tcg_temp_new_i64();
7564

    
7565
            gen_load_fpr64(ctx, fp0, fs);
7566
            gen_load_fpr64(ctx, fp1, ft);
7567
            gen_load_fpr64(ctx, fp2, fr);
7568
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7569
            tcg_temp_free_i64(fp0);
7570
            tcg_temp_free_i64(fp1);
7571
            gen_store_fpr64(ctx, fp2, fd);
7572
            tcg_temp_free_i64(fp2);
7573
        }
7574
        opn = "msub.ps";
7575
        break;
7576
    case OPC_NMADD_S:
7577
        check_cop1x(ctx);
7578
        {
7579
            TCGv_i32 fp0 = tcg_temp_new_i32();
7580
            TCGv_i32 fp1 = tcg_temp_new_i32();
7581
            TCGv_i32 fp2 = tcg_temp_new_i32();
7582

    
7583
            gen_load_fpr32(fp0, fs);
7584
            gen_load_fpr32(fp1, ft);
7585
            gen_load_fpr32(fp2, fr);
7586
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7587
            tcg_temp_free_i32(fp0);
7588
            tcg_temp_free_i32(fp1);
7589
            gen_store_fpr32(fp2, fd);
7590
            tcg_temp_free_i32(fp2);
7591
        }
7592
        opn = "nmadd.s";
7593
        break;
7594
    case OPC_NMADD_D:
7595
        check_cop1x(ctx);
7596
        check_cp1_registers(ctx, fd | fs | ft | fr);
7597
        {
7598
            TCGv_i64 fp0 = tcg_temp_new_i64();
7599
            TCGv_i64 fp1 = tcg_temp_new_i64();
7600
            TCGv_i64 fp2 = tcg_temp_new_i64();
7601

    
7602
            gen_load_fpr64(ctx, fp0, fs);
7603
            gen_load_fpr64(ctx, fp1, ft);
7604
            gen_load_fpr64(ctx, fp2, fr);
7605
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7606
            tcg_temp_free_i64(fp0);
7607
            tcg_temp_free_i64(fp1);
7608
            gen_store_fpr64(ctx, fp2, fd);
7609
            tcg_temp_free_i64(fp2);
7610
        }
7611
        opn = "nmadd.d";
7612
        break;
7613
    case OPC_NMADD_PS:
7614
        check_cp1_64bitmode(ctx);
7615
        {
7616
            TCGv_i64 fp0 = tcg_temp_new_i64();
7617
            TCGv_i64 fp1 = tcg_temp_new_i64();
7618
            TCGv_i64 fp2 = tcg_temp_new_i64();
7619

    
7620
            gen_load_fpr64(ctx, fp0, fs);
7621
            gen_load_fpr64(ctx, fp1, ft);
7622
            gen_load_fpr64(ctx, fp2, fr);
7623
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7624
            tcg_temp_free_i64(fp0);
7625
            tcg_temp_free_i64(fp1);
7626
            gen_store_fpr64(ctx, fp2, fd);
7627
            tcg_temp_free_i64(fp2);
7628
        }
7629
        opn = "nmadd.ps";
7630
        break;
7631
    case OPC_NMSUB_S:
7632
        check_cop1x(ctx);
7633
        {
7634
            TCGv_i32 fp0 = tcg_temp_new_i32();
7635
            TCGv_i32 fp1 = tcg_temp_new_i32();
7636
            TCGv_i32 fp2 = tcg_temp_new_i32();
7637

    
7638
            gen_load_fpr32(fp0, fs);
7639
            gen_load_fpr32(fp1, ft);
7640
            gen_load_fpr32(fp2, fr);
7641
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7642
            tcg_temp_free_i32(fp0);
7643
            tcg_temp_free_i32(fp1);
7644
            gen_store_fpr32(fp2, fd);
7645
            tcg_temp_free_i32(fp2);
7646
        }
7647
        opn = "nmsub.s";
7648
        break;
7649
    case OPC_NMSUB_D:
7650
        check_cop1x(ctx);
7651
        check_cp1_registers(ctx, fd | fs | ft | fr);
7652
        {
7653
            TCGv_i64 fp0 = tcg_temp_new_i64();
7654
            TCGv_i64 fp1 = tcg_temp_new_i64();
7655
            TCGv_i64 fp2 = tcg_temp_new_i64();
7656

    
7657
            gen_load_fpr64(ctx, fp0, fs);
7658
            gen_load_fpr64(ctx, fp1, ft);
7659
            gen_load_fpr64(ctx, fp2, fr);
7660
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7661
            tcg_temp_free_i64(fp0);
7662
            tcg_temp_free_i64(fp1);
7663
            gen_store_fpr64(ctx, fp2, fd);
7664
            tcg_temp_free_i64(fp2);
7665
        }
7666
        opn = "nmsub.d";
7667
        break;
7668
    case OPC_NMSUB_PS:
7669
        check_cp1_64bitmode(ctx);
7670
        {
7671
            TCGv_i64 fp0 = tcg_temp_new_i64();
7672
            TCGv_i64 fp1 = tcg_temp_new_i64();
7673
            TCGv_i64 fp2 = tcg_temp_new_i64();
7674

    
7675
            gen_load_fpr64(ctx, fp0, fs);
7676
            gen_load_fpr64(ctx, fp1, ft);
7677
            gen_load_fpr64(ctx, fp2, fr);
7678
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7679
            tcg_temp_free_i64(fp0);
7680
            tcg_temp_free_i64(fp1);
7681
            gen_store_fpr64(ctx, fp2, fd);
7682
            tcg_temp_free_i64(fp2);
7683
        }
7684
        opn = "nmsub.ps";
7685
        break;
7686
    default:
7687
        MIPS_INVAL(opn);
7688
        generate_exception (ctx, EXCP_RI);
7689
        return;
7690
    }
7691
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7692
               fregnames[fs], fregnames[ft]);
7693
}
7694

    
7695
static void
7696
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
7697
{
7698
    TCGv t0;
7699

    
7700
    check_insn(env, ctx, ISA_MIPS32R2);
7701
    t0 = tcg_temp_new();
7702

    
7703
    switch (rd) {
7704
    case 0:
7705
        save_cpu_state(ctx, 1);
7706
        gen_helper_rdhwr_cpunum(t0);
7707
        gen_store_gpr(t0, rt);
7708
        break;
7709
    case 1:
7710
        save_cpu_state(ctx, 1);
7711
        gen_helper_rdhwr_synci_step(t0);
7712
        gen_store_gpr(t0, rt);
7713
        break;
7714
    case 2:
7715
        save_cpu_state(ctx, 1);
7716
        gen_helper_rdhwr_cc(t0);
7717
        gen_store_gpr(t0, rt);
7718
        break;
7719
    case 3:
7720
        save_cpu_state(ctx, 1);
7721
        gen_helper_rdhwr_ccres(t0);
7722
        gen_store_gpr(t0, rt);
7723
        break;
7724
    case 29:
7725
#if defined(CONFIG_USER_ONLY)
7726
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7727
        gen_store_gpr(t0, rt);
7728
        break;
7729
#else
7730
        /* XXX: Some CPUs implement this in hardware.
7731
           Not supported yet. */
7732
#endif
7733
    default:            /* Invalid */
7734
        MIPS_INVAL("rdhwr");
7735
        generate_exception(ctx, EXCP_RI);
7736
        break;
7737
    }
7738
    tcg_temp_free(t0);
7739
}
7740

    
7741
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
7742
                               int insn_bytes)
7743
{
7744
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7745
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7746
        /* Branches completion */
7747
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7748
        ctx->bstate = BS_BRANCH;
7749
        save_cpu_state(ctx, 0);
7750
        /* FIXME: Need to clear can_do_io.  */
7751
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
7752
        case MIPS_HFLAG_B:
7753
            /* unconditional branch */
7754
            MIPS_DEBUG("unconditional branch");
7755
            if (proc_hflags & MIPS_HFLAG_BX) {
7756
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
7757
            }
7758
            gen_goto_tb(ctx, 0, ctx->btarget);
7759
            break;
7760
        case MIPS_HFLAG_BL:
7761
            /* blikely taken case */
7762
            MIPS_DEBUG("blikely branch taken");
7763
            gen_goto_tb(ctx, 0, ctx->btarget);
7764
            break;
7765
        case MIPS_HFLAG_BC:
7766
            /* Conditional branch */
7767
            MIPS_DEBUG("conditional branch");
7768
            {
7769
                int l1 = gen_new_label();
7770

    
7771
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7772
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
7773
                gen_set_label(l1);
7774
                gen_goto_tb(ctx, 0, ctx->btarget);
7775
            }
7776
            break;
7777
        case MIPS_HFLAG_BR:
7778
            /* unconditional branch to register */
7779
            MIPS_DEBUG("branch to register");
7780
            if (env->insn_flags & ASE_MIPS16) {
7781
                TCGv t0 = tcg_temp_new();
7782
                TCGv_i32 t1 = tcg_temp_new_i32();
7783

    
7784
                tcg_gen_andi_tl(t0, btarget, 0x1);
7785
                tcg_gen_trunc_tl_i32(t1, t0);
7786
                tcg_temp_free(t0);
7787
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
7788
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
7789
                tcg_gen_or_i32(hflags, hflags, t1);
7790
                tcg_temp_free_i32(t1);
7791

    
7792
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
7793
            } else {
7794
                tcg_gen_mov_tl(cpu_PC, btarget);
7795
            }
7796
            if (ctx->singlestep_enabled) {
7797
                save_cpu_state(ctx, 0);
7798
                gen_helper_0i(raise_exception, EXCP_DEBUG);
7799
            }
7800
            tcg_gen_exit_tb(0);
7801
            break;
7802
        default:
7803
            MIPS_DEBUG("unknown branch");
7804
            break;
7805
        }
7806
    }
7807
}
7808

    
7809
/* ISA extensions (ASEs) */
7810
/* MIPS16 extension to MIPS32 */
7811

    
7812
/* MIPS16 major opcodes */
7813
enum {
7814
  M16_OPC_ADDIUSP = 0x00,
7815
  M16_OPC_ADDIUPC = 0x01,
7816
  M16_OPC_B = 0x02,
7817
  M16_OPC_JAL = 0x03,
7818
  M16_OPC_BEQZ = 0x04,
7819
  M16_OPC_BNEQZ = 0x05,
7820
  M16_OPC_SHIFT = 0x06,
7821
  M16_OPC_LD = 0x07,
7822
  M16_OPC_RRIA = 0x08,
7823
  M16_OPC_ADDIU8 = 0x09,
7824
  M16_OPC_SLTI = 0x0a,
7825
  M16_OPC_SLTIU = 0x0b,
7826
  M16_OPC_I8 = 0x0c,
7827
  M16_OPC_LI = 0x0d,
7828
  M16_OPC_CMPI = 0x0e,
7829
  M16_OPC_SD = 0x0f,
7830
  M16_OPC_LB = 0x10,
7831
  M16_OPC_LH = 0x11,
7832
  M16_OPC_LWSP = 0x12,
7833
  M16_OPC_LW = 0x13,
7834
  M16_OPC_LBU = 0x14,
7835
  M16_OPC_LHU = 0x15,
7836
  M16_OPC_LWPC = 0x16,
7837
  M16_OPC_LWU = 0x17,
7838
  M16_OPC_SB = 0x18,
7839
  M16_OPC_SH = 0x19,
7840
  M16_OPC_SWSP = 0x1a,
7841
  M16_OPC_SW = 0x1b,
7842
  M16_OPC_RRR = 0x1c,
7843
  M16_OPC_RR = 0x1d,
7844
  M16_OPC_EXTEND = 0x1e,
7845
  M16_OPC_I64 = 0x1f
7846
};
7847

    
7848
/* I8 funct field */
7849
enum {
7850
  I8_BTEQZ = 0x0,
7851
  I8_BTNEZ = 0x1,
7852
  I8_SWRASP = 0x2,
7853
  I8_ADJSP = 0x3,
7854
  I8_SVRS = 0x4,
7855
  I8_MOV32R = 0x5,
7856
  I8_MOVR32 = 0x7
7857
};
7858

    
7859
/* RRR f field */
7860
enum {
7861
  RRR_DADDU = 0x0,
7862
  RRR_ADDU = 0x1,
7863
  RRR_DSUBU = 0x2,
7864
  RRR_SUBU = 0x3
7865
};
7866

    
7867
/* RR funct field */
7868
enum {
7869
  RR_JR = 0x00,
7870
  RR_SDBBP = 0x01,
7871
  RR_SLT = 0x02,
7872
  RR_SLTU = 0x03,
7873
  RR_SLLV = 0x04,
7874
  RR_BREAK = 0x05,
7875
  RR_SRLV = 0x06,
7876
  RR_SRAV = 0x07,
7877
  RR_DSRL = 0x08,
7878
  RR_CMP = 0x0a,
7879
  RR_NEG = 0x0b,
7880
  RR_AND = 0x0c,
7881
  RR_OR = 0x0d,
7882
  RR_XOR = 0x0e,
7883
  RR_NOT = 0x0f,
7884
  RR_MFHI = 0x10,
7885
  RR_CNVT = 0x11,
7886
  RR_MFLO = 0x12,
7887
  RR_DSRA = 0x13,
7888
  RR_DSLLV = 0x14,
7889
  RR_DSRLV = 0x16,
7890
  RR_DSRAV = 0x17,
7891
  RR_MULT = 0x18,
7892
  RR_MULTU = 0x19,
7893
  RR_DIV = 0x1a,
7894
  RR_DIVU = 0x1b,
7895
  RR_DMULT = 0x1c,
7896
  RR_DMULTU = 0x1d,
7897
  RR_DDIV = 0x1e,
7898
  RR_DDIVU = 0x1f
7899
};
7900

    
7901
/* I64 funct field */
7902
enum {
7903
  I64_LDSP = 0x0,
7904
  I64_SDSP = 0x1,
7905
  I64_SDRASP = 0x2,
7906
  I64_DADJSP = 0x3,
7907
  I64_LDPC = 0x4,
7908
  I64_DADDIU5 = 0x5,
7909
  I64_DADDIUPC = 0x6,
7910
  I64_DADDIUSP = 0x7
7911
};
7912

    
7913
/* RR ry field for CNVT */
7914
enum {
7915
  RR_RY_CNVT_ZEB = 0x0,
7916
  RR_RY_CNVT_ZEH = 0x1,
7917
  RR_RY_CNVT_ZEW = 0x2,
7918
  RR_RY_CNVT_SEB = 0x4,
7919
  RR_RY_CNVT_SEH = 0x5,
7920
  RR_RY_CNVT_SEW = 0x6,
7921
};
7922

    
7923
static int xlat (int r)
7924
{
7925
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
7926

    
7927
  return map[r];
7928
}
7929

    
7930
static void gen_mips16_save (DisasContext *ctx,
7931
                             int xsregs, int aregs,
7932
                             int do_ra, int do_s0, int do_s1,
7933
                             int framesize)
7934
{
7935
    TCGv t0 = tcg_temp_new();
7936
    TCGv t1 = tcg_temp_new();
7937
    int args, astatic;
7938

    
7939
    switch (aregs) {
7940
    case 0:
7941
    case 1:
7942
    case 2:
7943
    case 3:
7944
    case 11:
7945
        args = 0;
7946
        break;
7947
    case 4:
7948
    case 5:
7949
    case 6:
7950
    case 7:
7951
        args = 1;
7952
        break;
7953
    case 8:
7954
    case 9:
7955
    case 10:
7956
        args = 2;
7957
        break;
7958
    case 12:
7959
    case 13:
7960
        args = 3;
7961
        break;
7962
    case 14:
7963
        args = 4;
7964
        break;
7965
    default:
7966
        generate_exception(ctx, EXCP_RI);
7967
        return;
7968
    }
7969

    
7970
    switch (args) {
7971
    case 4:
7972
        gen_base_offset_addr(ctx, t0, 29, 12);
7973
        gen_load_gpr(t1, 7);
7974
        op_ldst_sw(t1, t0, ctx);
7975
        /* Fall through */
7976
    case 3:
7977
        gen_base_offset_addr(ctx, t0, 29, 8);
7978
        gen_load_gpr(t1, 6);
7979
        op_ldst_sw(t1, t0, ctx);
7980
        /* Fall through */
7981
    case 2:
7982
        gen_base_offset_addr(ctx, t0, 29, 4);
7983
        gen_load_gpr(t1, 5);
7984
        op_ldst_sw(t1, t0, ctx);
7985
        /* Fall through */
7986
    case 1:
7987
        gen_base_offset_addr(ctx, t0, 29, 0);
7988
        gen_load_gpr(t1, 4);
7989
        op_ldst_sw(t1, t0, ctx);
7990
    }
7991

    
7992
    gen_load_gpr(t0, 29);
7993

    
7994
#define DECR_AND_STORE(reg) do {                \
7995
        tcg_gen_subi_tl(t0, t0, 4);             \
7996
        gen_load_gpr(t1, reg);                  \
7997
        op_ldst_sw(t1, t0, ctx);                \
7998
    } while (0)
7999

    
8000
    if (do_ra) {
8001
        DECR_AND_STORE(31);
8002
    }
8003

    
8004
    switch (xsregs) {
8005
    case 7:
8006
        DECR_AND_STORE(30);
8007
        /* Fall through */
8008
    case 6:
8009
        DECR_AND_STORE(23);
8010
        /* Fall through */
8011
    case 5:
8012
        DECR_AND_STORE(22);
8013
        /* Fall through */
8014
    case 4:
8015
        DECR_AND_STORE(21);
8016
        /* Fall through */
8017
    case 3:
8018
        DECR_AND_STORE(20);
8019
        /* Fall through */
8020
    case 2:
8021
        DECR_AND_STORE(19);
8022
        /* Fall through */
8023
    case 1:
8024
        DECR_AND_STORE(18);
8025
    }
8026

    
8027
    if (do_s1) {
8028
        DECR_AND_STORE(17);
8029
    }
8030
    if (do_s0) {
8031
        DECR_AND_STORE(16);
8032
    }
8033

    
8034
    switch (aregs) {
8035
    case 0:
8036
    case 4:
8037
    case 8:
8038
    case 12:
8039
    case 14:
8040
        astatic = 0;
8041
        break;
8042
    case 1:
8043
    case 5:
8044
    case 9:
8045
    case 13:
8046
        astatic = 1;
8047
        break;
8048
    case 2:
8049
    case 6:
8050
    case 10:
8051
        astatic = 2;
8052
        break;
8053
    case 3:
8054
    case 7:
8055
        astatic = 3;
8056
        break;
8057
    case 11:
8058
        astatic = 4;
8059
        break;
8060
    default:
8061
        generate_exception(ctx, EXCP_RI);
8062
        return;
8063
    }
8064

    
8065
    if (astatic > 0) {
8066
        DECR_AND_STORE(7);
8067
        if (astatic > 1) {
8068
            DECR_AND_STORE(6);
8069
            if (astatic > 2) {
8070
                DECR_AND_STORE(5);
8071
                if (astatic > 3) {
8072
                    DECR_AND_STORE(4);
8073
                }
8074
            }
8075
        }
8076
    }
8077
#undef DECR_AND_STORE
8078

    
8079
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8080
    tcg_temp_free(t0);
8081
    tcg_temp_free(t1);
8082
}
8083

    
8084
static void gen_mips16_restore (DisasContext *ctx,
8085
                                int xsregs, int aregs,
8086
                                int do_ra, int do_s0, int do_s1,
8087
                                int framesize)
8088
{
8089
    int astatic;
8090
    TCGv t0 = tcg_temp_new();
8091
    TCGv t1 = tcg_temp_new();
8092

    
8093
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8094

    
8095
#define DECR_AND_LOAD(reg) do {                 \
8096
        tcg_gen_subi_tl(t0, t0, 4);             \
8097
        op_ldst_lw(t1, t0, ctx);                \
8098
        gen_store_gpr(t1, reg);                 \
8099
    } while (0)
8100

    
8101
    if (do_ra) {
8102
        DECR_AND_LOAD(31);
8103
    }
8104

    
8105
    switch (xsregs) {
8106
    case 7:
8107
        DECR_AND_LOAD(30);
8108
        /* Fall through */
8109
    case 6:
8110
        DECR_AND_LOAD(23);
8111
        /* Fall through */
8112
    case 5:
8113
        DECR_AND_LOAD(22);
8114
        /* Fall through */
8115
    case 4:
8116
        DECR_AND_LOAD(21);
8117
        /* Fall through */
8118
    case 3:
8119
        DECR_AND_LOAD(20);
8120
        /* Fall through */
8121
    case 2:
8122
        DECR_AND_LOAD(19);
8123
        /* Fall through */
8124
    case 1:
8125
        DECR_AND_LOAD(18);
8126
    }
8127

    
8128
    if (do_s1) {
8129
        DECR_AND_LOAD(17);
8130
    }
8131
    if (do_s0) {
8132
        DECR_AND_LOAD(16);
8133
    }
8134

    
8135
    switch (aregs) {
8136
    case 0:
8137
    case 4:
8138
    case 8:
8139
    case 12:
8140
    case 14:
8141
        astatic = 0;
8142
        break;
8143
    case 1:
8144
    case 5:
8145
    case 9:
8146
    case 13:
8147
        astatic = 1;
8148
        break;
8149
    case 2:
8150
    case 6:
8151
    case 10:
8152
        astatic = 2;
8153
        break;
8154
    case 3:
8155
    case 7:
8156
        astatic = 3;
8157
        break;
8158
    case 11:
8159
        astatic = 4;
8160
        break;
8161
    default:
8162
        generate_exception(ctx, EXCP_RI);
8163
        return;
8164
    }
8165

    
8166
    if (astatic > 0) {
8167
        DECR_AND_LOAD(7);
8168
        if (astatic > 1) {
8169
            DECR_AND_LOAD(6);
8170
            if (astatic > 2) {
8171
                DECR_AND_LOAD(5);
8172
                if (astatic > 3) {
8173
                    DECR_AND_LOAD(4);
8174
                }
8175
            }
8176
        }
8177
    }
8178
#undef DECR_AND_LOAD
8179

    
8180
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8181
    tcg_temp_free(t0);
8182
    tcg_temp_free(t1);
8183
}
8184

    
8185
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8186
                         int is_64_bit, int extended)
8187
{
8188
    TCGv t0;
8189

    
8190
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8191
        generate_exception(ctx, EXCP_RI);
8192
        return;
8193
    }
8194

    
8195
    t0 = tcg_temp_new();
8196

    
8197
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8198
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8199
    if (!is_64_bit) {
8200
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8201
    }
8202

    
8203
    tcg_temp_free(t0);
8204
}
8205

    
8206
#if defined(TARGET_MIPS64)
8207
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8208
                               int ry, int funct, int16_t offset,
8209
                               int extended)
8210
{
8211
    switch (funct) {
8212
    case I64_LDSP:
8213
        check_mips_64(ctx);
8214
        offset = extended ? offset : offset << 3;
8215
        gen_ldst(ctx, OPC_LD, ry, 29, offset);
8216
        break;
8217
    case I64_SDSP:
8218
        check_mips_64(ctx);
8219
        offset = extended ? offset : offset << 3;
8220
        gen_ldst(ctx, OPC_SD, ry, 29, offset);
8221
        break;
8222
    case I64_SDRASP:
8223
        check_mips_64(ctx);
8224
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8225
        gen_ldst(ctx, OPC_SD, 31, 29, offset);
8226
        break;
8227
    case I64_DADJSP:
8228
        check_mips_64(ctx);
8229
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8230
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8231
        break;
8232
    case I64_LDPC:
8233
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8234
            generate_exception(ctx, EXCP_RI);
8235
        } else {
8236
            offset = extended ? offset : offset << 3;
8237
            gen_ldst(ctx, OPC_LDPC, ry, 0, offset);
8238
        }
8239
        break;
8240
    case I64_DADDIU5:
8241
        check_mips_64(ctx);
8242
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8243
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8244
        break;
8245
    case I64_DADDIUPC:
8246
        check_mips_64(ctx);
8247
        offset = extended ? offset : offset << 2;
8248
        gen_addiupc(ctx, ry, offset, 1, extended);
8249
        break;
8250
    case I64_DADDIUSP:
8251
        check_mips_64(ctx);
8252
        offset = extended ? offset : offset << 2;
8253
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8254
        break;
8255
    }
8256
}
8257
#endif
8258

    
8259
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8260
                                       int *is_branch)
8261
{
8262
    int extend = lduw_code(ctx->pc + 2);
8263
    int op, rx, ry, funct, sa;
8264
    int16_t imm, offset;
8265

    
8266
    ctx->opcode = (ctx->opcode << 16) | extend;
8267
    op = (ctx->opcode >> 11) & 0x1f;
8268
    sa = (ctx->opcode >> 22) & 0x1f;
8269
    funct = (ctx->opcode >> 8) & 0x7;
8270
    rx = xlat((ctx->opcode >> 8) & 0x7);
8271
    ry = xlat((ctx->opcode >> 5) & 0x7);
8272
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8273
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8274
                              | (ctx->opcode & 0x1f));
8275

    
8276
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8277
       counterparts.  */
8278
    switch (op) {
8279
    case M16_OPC_ADDIUSP:
8280
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8281
        break;
8282
    case M16_OPC_ADDIUPC:
8283
        gen_addiupc(ctx, rx, imm, 0, 1);
8284
        break;
8285
    case M16_OPC_B:
8286
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8287
        /* No delay slot, so just process as a normal instruction */
8288
        break;
8289
    case M16_OPC_BEQZ:
8290
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8291
        /* No delay slot, so just process as a normal instruction */
8292
        break;
8293
    case M16_OPC_BNEQZ:
8294
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8295
        /* No delay slot, so just process as a normal instruction */
8296
        break;
8297
    case M16_OPC_SHIFT:
8298
        switch (ctx->opcode & 0x3) {
8299
        case 0x0:
8300
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8301
            break;
8302
        case 0x1:
8303
#if defined(TARGET_MIPS64)
8304
            check_mips_64(ctx);
8305
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8306
#else
8307
            generate_exception(ctx, EXCP_RI);
8308
#endif
8309
            break;
8310
        case 0x2:
8311
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8312
            break;
8313
        case 0x3:
8314
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8315
            break;
8316
        }
8317
        break;
8318
#if defined(TARGET_MIPS64)
8319
    case M16_OPC_LD:
8320
            check_mips_64(ctx);
8321
        gen_ldst(ctx, OPC_LD, ry, rx, offset);
8322
        break;
8323
#endif
8324
    case M16_OPC_RRIA:
8325
        imm = ctx->opcode & 0xf;
8326
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8327
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8328
        imm = (int16_t) (imm << 1) >> 1;
8329
        if ((ctx->opcode >> 4) & 0x1) {
8330
#if defined(TARGET_MIPS64)
8331
            check_mips_64(ctx);
8332
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8333
#else
8334
            generate_exception(ctx, EXCP_RI);
8335
#endif
8336
        } else {
8337
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8338
        }
8339
        break;
8340
    case M16_OPC_ADDIU8:
8341
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8342
        break;
8343
    case M16_OPC_SLTI:
8344
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8345
        break;
8346
    case M16_OPC_SLTIU:
8347
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8348
        break;
8349
    case M16_OPC_I8:
8350
        switch (funct) {
8351
        case I8_BTEQZ:
8352
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8353
            break;
8354
        case I8_BTNEZ:
8355
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8356
            break;
8357
        case I8_SWRASP:
8358
            gen_ldst(ctx, OPC_SW, 31, 29, imm);
8359
            break;
8360
        case I8_ADJSP:
8361
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8362
            break;
8363
        case I8_SVRS:
8364
            {
8365
                int xsregs = (ctx->opcode >> 24) & 0x7;
8366
                int aregs = (ctx->opcode >> 16) & 0xf;
8367
                int do_ra = (ctx->opcode >> 6) & 0x1;
8368
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8369
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8370
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8371
                                 | (ctx->opcode & 0xf)) << 3;
8372

    
8373
                if (ctx->opcode & (1 << 7)) {
8374
                    gen_mips16_save(ctx, xsregs, aregs,
8375
                                    do_ra, do_s0, do_s1,
8376
                                    framesize);
8377
                } else {
8378
                    gen_mips16_restore(ctx, xsregs, aregs,
8379
                                       do_ra, do_s0, do_s1,
8380
                                       framesize);
8381
                }
8382
            }
8383
            break;
8384
        default:
8385
            generate_exception(ctx, EXCP_RI);
8386
            break;
8387
        }
8388
        break;
8389
    case M16_OPC_LI:
8390
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8391
        break;
8392
    case M16_OPC_CMPI:
8393
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8394
        break;
8395
#if defined(TARGET_MIPS64)
8396
    case M16_OPC_SD:
8397
        gen_ldst(ctx, OPC_SD, ry, rx, offset);
8398
        break;
8399
#endif
8400
    case M16_OPC_LB:
8401
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8402
        break;
8403
    case M16_OPC_LH:
8404
        gen_ldst(ctx, OPC_LH, ry, rx, offset);
8405
        break;
8406
    case M16_OPC_LWSP:
8407
        gen_ldst(ctx, OPC_LW, rx, 29, offset);
8408
        break;
8409
    case M16_OPC_LW:
8410
        gen_ldst(ctx, OPC_LW, ry, rx, offset);
8411
        break;
8412
    case M16_OPC_LBU:
8413
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8414
        break;
8415
    case M16_OPC_LHU:
8416
        gen_ldst(ctx, OPC_LHU, ry, rx, offset);
8417
        break;
8418
    case M16_OPC_LWPC:
8419
        gen_ldst(ctx, OPC_LWPC, rx, 0, offset);
8420
        break;
8421
#if defined(TARGET_MIPS64)
8422
    case M16_OPC_LWU:
8423
        gen_ldst(ctx, OPC_LWU, ry, rx, offset);
8424
        break;
8425
#endif
8426
    case M16_OPC_SB:
8427
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8428
        break;
8429
    case M16_OPC_SH:
8430
        gen_ldst(ctx, OPC_SH, ry, rx, offset);
8431
        break;
8432
    case M16_OPC_SWSP:
8433
        gen_ldst(ctx, OPC_SW, rx, 29, offset);
8434
        break;
8435
    case M16_OPC_SW:
8436
        gen_ldst(ctx, OPC_SW, ry, rx, offset);
8437
        break;
8438
#if defined(TARGET_MIPS64)
8439
    case M16_OPC_I64:
8440
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8441
        break;
8442
#endif
8443
    default:
8444
        generate_exception(ctx, EXCP_RI);
8445
        break;
8446
    }
8447

    
8448
    return 4;
8449
}
8450

    
8451
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8452
                              int *is_branch)
8453
{
8454
    int rx, ry;
8455
    int sa;
8456
    int op, cnvt_op, op1, offset;
8457
    int funct;
8458
    int n_bytes;
8459

    
8460
    op = (ctx->opcode >> 11) & 0x1f;
8461
    sa = (ctx->opcode >> 2) & 0x7;
8462
    sa = sa == 0 ? 8 : sa;
8463
    rx = xlat((ctx->opcode >> 8) & 0x7);
8464
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8465
    ry = xlat((ctx->opcode >> 5) & 0x7);
8466
    op1 = offset = ctx->opcode & 0x1f;
8467

    
8468
    n_bytes = 2;
8469

    
8470
    switch (op) {
8471
    case M16_OPC_ADDIUSP:
8472
        {
8473
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8474

    
8475
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8476
        }
8477
        break;
8478
    case M16_OPC_ADDIUPC:
8479
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8480
        break;
8481
    case M16_OPC_B:
8482
        offset = (ctx->opcode & 0x7ff) << 1;
8483
        offset = (int16_t)(offset << 4) >> 4;
8484
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8485
        /* No delay slot, so just process as a normal instruction */
8486
        break;
8487
    case M16_OPC_JAL:
8488
        offset = lduw_code(ctx->pc + 2);
8489
        offset = (((ctx->opcode & 0x1f) << 21)
8490
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8491
                  | offset) << 2;
8492
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
8493
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8494
        n_bytes = 4;
8495
        *is_branch = 1;
8496
        break;
8497
    case M16_OPC_BEQZ:
8498
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8499
        /* No delay slot, so just process as a normal instruction */
8500
        break;
8501
    case M16_OPC_BNEQZ:
8502
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8503
        /* No delay slot, so just process as a normal instruction */
8504
        break;
8505
    case M16_OPC_SHIFT:
8506
        switch (ctx->opcode & 0x3) {
8507
        case 0x0:
8508
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8509
            break;
8510
        case 0x1:
8511
#if defined(TARGET_MIPS64)
8512
            check_mips_64(ctx);
8513
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8514
#else
8515
            generate_exception(ctx, EXCP_RI);
8516
#endif
8517
            break;
8518
        case 0x2:
8519
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8520
            break;
8521
        case 0x3:
8522
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8523
            break;
8524
        }
8525
        break;
8526
#if defined(TARGET_MIPS64)
8527
    case M16_OPC_LD:
8528
        check_mips_64(ctx);
8529
        gen_ldst(ctx, OPC_LD, ry, rx, offset << 3);
8530
        break;
8531
#endif
8532
    case M16_OPC_RRIA:
8533
        {
8534
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8535

    
8536
            if ((ctx->opcode >> 4) & 1) {
8537
#if defined(TARGET_MIPS64)
8538
                check_mips_64(ctx);
8539
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8540
#else
8541
                generate_exception(ctx, EXCP_RI);
8542
#endif
8543
            } else {
8544
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8545
            }
8546
        }
8547
        break;
8548
    case M16_OPC_ADDIU8:
8549
        {
8550
            int16_t imm = (int8_t) ctx->opcode;
8551

    
8552
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8553
        }
8554
        break;
8555
    case M16_OPC_SLTI:
8556
        {
8557
            int16_t imm = (uint8_t) ctx->opcode;
8558

    
8559
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8560
        }
8561
        break;
8562
    case M16_OPC_SLTIU:
8563
        {
8564
            int16_t imm = (uint8_t) ctx->opcode;
8565

    
8566
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8567
        }
8568
        break;
8569
    case M16_OPC_I8:
8570
        {
8571
            int reg32;
8572

    
8573
            funct = (ctx->opcode >> 8) & 0x7;
8574
            switch (funct) {
8575
            case I8_BTEQZ:
8576
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8577
                                   ((int8_t)ctx->opcode) << 1);
8578
                break;
8579
            case I8_BTNEZ:
8580
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8581
                                   ((int8_t)ctx->opcode) << 1);
8582
                break;
8583
            case I8_SWRASP:
8584
                gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8585
                break;
8586
            case I8_ADJSP:
8587
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8588
                              ((int8_t)ctx->opcode) << 3);
8589
                break;
8590
            case I8_SVRS:
8591
                {
8592
                    int do_ra = ctx->opcode & (1 << 6);
8593
                    int do_s0 = ctx->opcode & (1 << 5);
8594
                    int do_s1 = ctx->opcode & (1 << 4);
8595
                    int framesize = ctx->opcode & 0xf;
8596

    
8597
                    if (framesize == 0) {
8598
                        framesize = 128;
8599
                    } else {
8600
                        framesize = framesize << 3;
8601
                    }
8602

    
8603
                    if (ctx->opcode & (1 << 7)) {
8604
                        gen_mips16_save(ctx, 0, 0,
8605
                                        do_ra, do_s0, do_s1, framesize);
8606
                    } else {
8607
                        gen_mips16_restore(ctx, 0, 0,
8608
                                           do_ra, do_s0, do_s1, framesize);
8609
                    }
8610
                }
8611
                break;
8612
            case I8_MOV32R:
8613
                {
8614
                    int rz = xlat(ctx->opcode & 0x7);
8615

    
8616
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8617
                        ((ctx->opcode >> 5) & 0x7);
8618
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8619
                }
8620
                break;
8621
            case I8_MOVR32:
8622
                reg32 = ctx->opcode & 0x1f;
8623
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8624
                break;
8625
            default:
8626
                generate_exception(ctx, EXCP_RI);
8627
                break;
8628
            }
8629
        }
8630
        break;
8631
    case M16_OPC_LI:
8632
        {
8633
            int16_t imm = (uint8_t) ctx->opcode;
8634

    
8635
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8636
        }
8637
        break;
8638
    case M16_OPC_CMPI:
8639
        {
8640
            int16_t imm = (uint8_t) ctx->opcode;
8641

    
8642
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8643
        }
8644
        break;
8645
#if defined(TARGET_MIPS64)
8646
    case M16_OPC_SD:
8647
        check_mips_64(ctx);
8648
        gen_ldst(ctx, OPC_SD, ry, rx, offset << 3);
8649
        break;
8650
#endif
8651
    case M16_OPC_LB:
8652
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8653
        break;
8654
    case M16_OPC_LH:
8655
        gen_ldst(ctx, OPC_LH, ry, rx, offset << 1);
8656
        break;
8657
    case M16_OPC_LWSP:
8658
        gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8659
        break;
8660
    case M16_OPC_LW:
8661
        gen_ldst(ctx, OPC_LW, ry, rx, offset << 2);
8662
        break;
8663
    case M16_OPC_LBU:
8664
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8665
        break;
8666
    case M16_OPC_LHU:
8667
        gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1);
8668
        break;
8669
    case M16_OPC_LWPC:
8670
        gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8671
        break;
8672
#if defined (TARGET_MIPS64)
8673
    case M16_OPC_LWU:
8674
        check_mips_64(ctx);
8675
        gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2);
8676
        break;
8677
#endif
8678
    case M16_OPC_SB:
8679
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8680
        break;
8681
    case M16_OPC_SH:
8682
        gen_ldst(ctx, OPC_SH, ry, rx, offset << 1);
8683
        break;
8684
    case M16_OPC_SWSP:
8685
        gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8686
        break;
8687
    case M16_OPC_SW:
8688
        gen_ldst(ctx, OPC_SW, ry, rx, offset << 2);
8689
        break;
8690
    case M16_OPC_RRR:
8691
        {
8692
            int rz = xlat((ctx->opcode >> 2) & 0x7);
8693
            int mips32_op;
8694

    
8695
            switch (ctx->opcode & 0x3) {
8696
            case RRR_ADDU:
8697
                mips32_op = OPC_ADDU;
8698
                break;
8699
            case RRR_SUBU:
8700
                mips32_op = OPC_SUBU;
8701
                break;
8702
#if defined(TARGET_MIPS64)
8703
            case RRR_DADDU:
8704
                mips32_op = OPC_DADDU;
8705
                check_mips_64(ctx);
8706
                break;
8707
            case RRR_DSUBU:
8708
                mips32_op = OPC_DSUBU;
8709
                check_mips_64(ctx);
8710
                break;
8711
#endif
8712
            default:
8713
                generate_exception(ctx, EXCP_RI);
8714
                goto done;
8715
            }
8716

    
8717
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
8718
        done:
8719
            ;
8720
        }
8721
        break;
8722
    case M16_OPC_RR:
8723
        switch (op1) {
8724
        case RR_JR:
8725
            {
8726
                int nd = (ctx->opcode >> 7) & 0x1;
8727
                int link = (ctx->opcode >> 6) & 0x1;
8728
                int ra = (ctx->opcode >> 5) & 0x1;
8729

    
8730
                if (link) {
8731
                    op = nd ? OPC_JALRC : OPC_JALR;
8732
                } else {
8733
                    op = OPC_JR;
8734
                }
8735

    
8736
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
8737
                if (!nd) {
8738
                    *is_branch = 1;
8739
                }
8740
            }
8741
            break;
8742
        case RR_SDBBP:
8743
            /* XXX: not clear which exception should be raised
8744
             *      when in debug mode...
8745
             */
8746
            check_insn(env, ctx, ISA_MIPS32);
8747
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8748
                generate_exception(ctx, EXCP_DBp);
8749
            } else {
8750
                generate_exception(ctx, EXCP_DBp);
8751
            }
8752
            break;
8753
        case RR_SLT:
8754
            gen_slt(env, OPC_SLT, 24, rx, ry);
8755
            break;
8756
        case RR_SLTU:
8757
            gen_slt(env, OPC_SLTU, 24, rx, ry);
8758
            break;
8759
        case RR_BREAK:
8760
            generate_exception(ctx, EXCP_BREAK);
8761
            break;
8762
        case RR_SLLV:
8763
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
8764
            break;
8765
        case RR_SRLV:
8766
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
8767
            break;
8768
        case RR_SRAV:
8769
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
8770
            break;
8771
#if defined (TARGET_MIPS64)
8772
        case RR_DSRL:
8773
            check_mips_64(ctx);
8774
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
8775
            break;
8776
#endif
8777
        case RR_CMP:
8778
            gen_logic(env, OPC_XOR, 24, rx, ry);
8779
            break;
8780
        case RR_NEG:
8781
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
8782
            break;
8783
        case RR_AND:
8784
            gen_logic(env, OPC_AND, rx, rx, ry);
8785
            break;
8786
        case RR_OR:
8787
            gen_logic(env, OPC_OR, rx, rx, ry);
8788
            break;
8789
        case RR_XOR:
8790
            gen_logic(env, OPC_XOR, rx, rx, ry);
8791
            break;
8792
        case RR_NOT:
8793
            gen_logic(env, OPC_NOR, rx, ry, 0);
8794
            break;
8795
        case RR_MFHI:
8796
            gen_HILO(ctx, OPC_MFHI, rx);
8797
            break;
8798
        case RR_CNVT:
8799
            switch (cnvt_op) {
8800
            case RR_RY_CNVT_ZEB:
8801
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8802
                break;
8803
            case RR_RY_CNVT_ZEH:
8804
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8805
                break;
8806
            case RR_RY_CNVT_SEB:
8807
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8808
                break;
8809
            case RR_RY_CNVT_SEH:
8810
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8811
                break;
8812
#if defined (TARGET_MIPS64)
8813
            case RR_RY_CNVT_ZEW:
8814
                check_mips_64(ctx);
8815
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8816
                break;
8817
            case RR_RY_CNVT_SEW:
8818
                check_mips_64(ctx);
8819
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8820
                break;
8821
#endif
8822
            default:
8823
                generate_exception(ctx, EXCP_RI);
8824
                break;
8825
            }
8826
            break;
8827
        case RR_MFLO:
8828
            gen_HILO(ctx, OPC_MFLO, rx);
8829
            break;
8830
#if defined (TARGET_MIPS64)
8831
        case RR_DSRA:
8832
            check_mips_64(ctx);
8833
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
8834
            break;
8835
        case RR_DSLLV:
8836
            check_mips_64(ctx);
8837
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
8838
            break;
8839
        case RR_DSRLV:
8840
            check_mips_64(ctx);
8841
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
8842
            break;
8843
        case RR_DSRAV:
8844
            check_mips_64(ctx);
8845
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
8846
            break;
8847
#endif
8848
        case RR_MULT:
8849
            gen_muldiv(ctx, OPC_MULT, rx, ry);
8850
            break;
8851
        case RR_MULTU:
8852
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
8853
            break;
8854
        case RR_DIV:
8855
            gen_muldiv(ctx, OPC_DIV, rx, ry);
8856
            break;
8857
        case RR_DIVU:
8858
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
8859
            break;
8860
#if defined (TARGET_MIPS64)
8861
        case RR_DMULT:
8862
            check_mips_64(ctx);
8863
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
8864
            break;
8865
        case RR_DMULTU:
8866
            check_mips_64(ctx);
8867
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
8868
            break;
8869
        case RR_DDIV:
8870
            check_mips_64(ctx);
8871
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
8872
            break;
8873
        case RR_DDIVU:
8874
            check_mips_64(ctx);
8875
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
8876
            break;
8877
#endif
8878
        default:
8879
            generate_exception(ctx, EXCP_RI);
8880
            break;
8881
        }
8882
        break;
8883
    case M16_OPC_EXTEND:
8884
        decode_extended_mips16_opc(env, ctx, is_branch);
8885
        n_bytes = 4;
8886
        break;
8887
#if defined(TARGET_MIPS64)
8888
    case M16_OPC_I64:
8889
        funct = (ctx->opcode >> 8) & 0x7;
8890
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
8891
        break;
8892
#endif
8893
    default:
8894
        generate_exception(ctx, EXCP_RI);
8895
        break;
8896
    }
8897

    
8898
    return n_bytes;
8899
}
8900

    
8901
/* SmartMIPS extension to MIPS32 */
8902

    
8903
#if defined(TARGET_MIPS64)
8904

    
8905
/* MDMX extension to MIPS64 */
8906

    
8907
#endif
8908

    
8909
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
8910
{
8911
    int32_t offset;
8912
    int rs, rt, rd, sa;
8913
    uint32_t op, op1, op2;
8914
    int16_t imm;
8915

    
8916
    /* make sure instructions are on a word boundary */
8917
    if (ctx->pc & 0x3) {
8918
        env->CP0_BadVAddr = ctx->pc;
8919
        generate_exception(ctx, EXCP_AdEL);
8920
        return;
8921
    }
8922

    
8923
    /* Handle blikely not taken case */
8924
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
8925
        int l1 = gen_new_label();
8926

    
8927
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
8928
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8929
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
8930
        gen_goto_tb(ctx, 1, ctx->pc + 4);
8931
        gen_set_label(l1);
8932
    }
8933

    
8934
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
8935
        tcg_gen_debug_insn_start(ctx->pc);
8936

    
8937
    op = MASK_OP_MAJOR(ctx->opcode);
8938
    rs = (ctx->opcode >> 21) & 0x1f;
8939
    rt = (ctx->opcode >> 16) & 0x1f;
8940
    rd = (ctx->opcode >> 11) & 0x1f;
8941
    sa = (ctx->opcode >> 6) & 0x1f;
8942
    imm = (int16_t)ctx->opcode;
8943
    switch (op) {
8944
    case OPC_SPECIAL:
8945
        op1 = MASK_SPECIAL(ctx->opcode);
8946
        switch (op1) {
8947
        case OPC_SLL:          /* Shift with immediate */
8948
        case OPC_SRA:
8949
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
8950
            break;
8951
        case OPC_SRL:
8952
            switch ((ctx->opcode >> 21) & 0x1f) {
8953
            case 1:
8954
                /* rotr is decoded as srl on non-R2 CPUs */
8955
                if (env->insn_flags & ISA_MIPS32R2) {
8956
                    op1 = OPC_ROTR;
8957
                }
8958
                /* Fallthrough */
8959
            case 0:
8960
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8961
                break;
8962
            default:
8963
                generate_exception(ctx, EXCP_RI);
8964
                break;
8965
            }
8966
            break;
8967
        case OPC_MOVN:         /* Conditional move */
8968
        case OPC_MOVZ:
8969
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8970
            gen_cond_move(env, op1, rd, rs, rt);
8971
            break;
8972
        case OPC_ADD ... OPC_SUBU:
8973
            gen_arith(env, ctx, op1, rd, rs, rt);
8974
            break;
8975
        case OPC_SLLV:         /* Shifts */
8976
        case OPC_SRAV:
8977
            gen_shift(env, ctx, op1, rd, rs, rt);
8978
            break;
8979
        case OPC_SRLV:
8980
            switch ((ctx->opcode >> 6) & 0x1f) {
8981
            case 1:
8982
                /* rotrv is decoded as srlv on non-R2 CPUs */
8983
                if (env->insn_flags & ISA_MIPS32R2) {
8984
                    op1 = OPC_ROTRV;
8985
                }
8986
                /* Fallthrough */
8987
            case 0:
8988
                gen_shift(env, ctx, op1, rd, rs, rt);
8989
                break;
8990
            default:
8991
                generate_exception(ctx, EXCP_RI);
8992
                break;
8993
            }
8994
            break;
8995
        case OPC_SLT:          /* Set on less than */
8996
        case OPC_SLTU:
8997
            gen_slt(env, op1, rd, rs, rt);
8998
            break;
8999
        case OPC_AND:          /* Logic*/
9000
        case OPC_OR:
9001
        case OPC_NOR:
9002
        case OPC_XOR:
9003
            gen_logic(env, op1, rd, rs, rt);
9004
            break;
9005
        case OPC_MULT ... OPC_DIVU:
9006
            if (sa) {
9007
                check_insn(env, ctx, INSN_VR54XX);
9008
                op1 = MASK_MUL_VR54XX(ctx->opcode);
9009
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
9010
            } else
9011
                gen_muldiv(ctx, op1, rs, rt);
9012
            break;
9013
        case OPC_JR ... OPC_JALR:
9014
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
9015
            *is_branch = 1;
9016
            break;
9017
        case OPC_TGE ... OPC_TEQ: /* Traps */
9018
        case OPC_TNE:
9019
            gen_trap(ctx, op1, rs, rt, -1);
9020
            break;
9021
        case OPC_MFHI:          /* Move from HI/LO */
9022
        case OPC_MFLO:
9023
            gen_HILO(ctx, op1, rd);
9024
            break;
9025
        case OPC_MTHI:
9026
        case OPC_MTLO:          /* Move to HI/LO */
9027
            gen_HILO(ctx, op1, rs);
9028
            break;
9029
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
9030
#ifdef MIPS_STRICT_STANDARD
9031
            MIPS_INVAL("PMON / selsl");
9032
            generate_exception(ctx, EXCP_RI);
9033
#else
9034
            gen_helper_0i(pmon, sa);
9035
#endif
9036
            break;
9037
        case OPC_SYSCALL:
9038
            generate_exception(ctx, EXCP_SYSCALL);
9039
            ctx->bstate = BS_STOP;
9040
            break;
9041
        case OPC_BREAK:
9042
            generate_exception(ctx, EXCP_BREAK);
9043
            break;
9044
        case OPC_SPIM:
9045
#ifdef MIPS_STRICT_STANDARD
9046
            MIPS_INVAL("SPIM");
9047
            generate_exception(ctx, EXCP_RI);
9048
#else
9049
           /* Implemented as RI exception for now. */
9050
            MIPS_INVAL("spim (unofficial)");
9051
            generate_exception(ctx, EXCP_RI);
9052
#endif
9053
            break;
9054
        case OPC_SYNC:
9055
            /* Treat as NOP. */
9056
            break;
9057

    
9058
        case OPC_MOVCI:
9059
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
9060
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9061
                check_cp1_enabled(ctx);
9062
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
9063
                          (ctx->opcode >> 16) & 1);
9064
            } else {
9065
                generate_exception_err(ctx, EXCP_CpU, 1);
9066
            }
9067
            break;
9068

    
9069
#if defined(TARGET_MIPS64)
9070
       /* MIPS64 specific opcodes */
9071
        case OPC_DSLL:
9072
        case OPC_DSRA:
9073
        case OPC_DSLL32:
9074
        case OPC_DSRA32:
9075
            check_insn(env, ctx, ISA_MIPS3);
9076
            check_mips_64(ctx);
9077
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
9078
            break;
9079
        case OPC_DSRL:
9080
            switch ((ctx->opcode >> 21) & 0x1f) {
9081
            case 1:
9082
                /* drotr is decoded as dsrl on non-R2 CPUs */
9083
                if (env->insn_flags & ISA_MIPS32R2) {
9084
                    op1 = OPC_DROTR;
9085
                }
9086
                /* Fallthrough */
9087
            case 0:
9088
                check_insn(env, ctx, ISA_MIPS3);
9089
                check_mips_64(ctx);
9090
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
9091
                break;
9092
            default:
9093
                generate_exception(ctx, EXCP_RI);
9094
                break;
9095
            }
9096
            break;
9097
        case OPC_DSRL32:
9098
            switch ((ctx->opcode >> 21) & 0x1f) {
9099
            case 1:
9100
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
9101
                if (env->insn_flags & ISA_MIPS32R2) {
9102
                    op1 = OPC_DROTR32;
9103
                }
9104
                /* Fallthrough */
9105
            case 0:
9106
                check_insn(env, ctx, ISA_MIPS3);
9107
                check_mips_64(ctx);
9108
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
9109
                break;
9110
            default:
9111
                generate_exception(ctx, EXCP_RI);
9112
                break;
9113
            }
9114
            break;
9115
        case OPC_DADD ... OPC_DSUBU:
9116
            check_insn(env, ctx, ISA_MIPS3);
9117
            check_mips_64(ctx);
9118
            gen_arith(env, ctx, op1, rd, rs, rt);
9119
            break;
9120
        case OPC_DSLLV:
9121
        case OPC_DSRAV:
9122
            check_insn(env, ctx, ISA_MIPS3);
9123
            check_mips_64(ctx);
9124
            gen_shift(env, ctx, op1, rd, rs, rt);
9125
            break;
9126
        case OPC_DSRLV:
9127
            switch ((ctx->opcode >> 6) & 0x1f) {
9128
            case 1:
9129
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
9130
                if (env->insn_flags & ISA_MIPS32R2) {
9131
                    op1 = OPC_DROTRV;
9132
                }
9133
                /* Fallthrough */
9134
            case 0:
9135
                check_insn(env, ctx, ISA_MIPS3);
9136
                check_mips_64(ctx);
9137
                gen_shift(env, ctx, op1, rd, rs, rt);
9138
                break;
9139
            default:
9140
                generate_exception(ctx, EXCP_RI);
9141
                break;
9142
            }
9143
            break;
9144
        case OPC_DMULT ... OPC_DDIVU:
9145
            check_insn(env, ctx, ISA_MIPS3);
9146
            check_mips_64(ctx);
9147
            gen_muldiv(ctx, op1, rs, rt);
9148
            break;
9149
#endif
9150
        default:            /* Invalid */
9151
            MIPS_INVAL("special");
9152
            generate_exception(ctx, EXCP_RI);
9153
            break;
9154
        }
9155
        break;
9156
    case OPC_SPECIAL2:
9157
        op1 = MASK_SPECIAL2(ctx->opcode);
9158
        switch (op1) {
9159
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
9160
        case OPC_MSUB ... OPC_MSUBU:
9161
            check_insn(env, ctx, ISA_MIPS32);
9162
            gen_muldiv(ctx, op1, rs, rt);
9163
            break;
9164
        case OPC_MUL:
9165
            gen_arith(env, ctx, op1, rd, rs, rt);
9166
            break;
9167
        case OPC_CLO:
9168
        case OPC_CLZ:
9169
            check_insn(env, ctx, ISA_MIPS32);
9170
            gen_cl(ctx, op1, rd, rs);
9171
            break;
9172
        case OPC_SDBBP:
9173
            /* XXX: not clear which exception should be raised
9174
             *      when in debug mode...
9175
             */
9176
            check_insn(env, ctx, ISA_MIPS32);
9177
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9178
                generate_exception(ctx, EXCP_DBp);
9179
            } else {
9180
                generate_exception(ctx, EXCP_DBp);
9181
            }
9182
            /* Treat as NOP. */
9183
            break;
9184
#if defined(TARGET_MIPS64)
9185
        case OPC_DCLO:
9186
        case OPC_DCLZ:
9187
            check_insn(env, ctx, ISA_MIPS64);
9188
            check_mips_64(ctx);
9189
            gen_cl(ctx, op1, rd, rs);
9190
            break;
9191
#endif
9192
        default:            /* Invalid */
9193
            MIPS_INVAL("special2");
9194
            generate_exception(ctx, EXCP_RI);
9195
            break;
9196
        }
9197
        break;
9198
    case OPC_SPECIAL3:
9199
        op1 = MASK_SPECIAL3(ctx->opcode);
9200
        switch (op1) {
9201
        case OPC_EXT:
9202
        case OPC_INS:
9203
            check_insn(env, ctx, ISA_MIPS32R2);
9204
            gen_bitops(ctx, op1, rt, rs, sa, rd);
9205
            break;
9206
        case OPC_BSHFL:
9207
            check_insn(env, ctx, ISA_MIPS32R2);
9208
            op2 = MASK_BSHFL(ctx->opcode);
9209
            gen_bshfl(ctx, op2, rt, rd);
9210
            break;
9211
        case OPC_RDHWR:
9212
            gen_rdhwr(env, ctx, rt, rd);
9213
            break;
9214
        case OPC_FORK:
9215
            check_insn(env, ctx, ASE_MT);
9216
            {
9217
                TCGv t0 = tcg_temp_new();
9218
                TCGv t1 = tcg_temp_new();
9219

    
9220
                gen_load_gpr(t0, rt);
9221
                gen_load_gpr(t1, rs);
9222
                gen_helper_fork(t0, t1);
9223
                tcg_temp_free(t0);
9224
                tcg_temp_free(t1);
9225
            }
9226
            break;
9227
        case OPC_YIELD:
9228
            check_insn(env, ctx, ASE_MT);
9229
            {
9230
                TCGv t0 = tcg_temp_new();
9231

    
9232
                save_cpu_state(ctx, 1);
9233
                gen_load_gpr(t0, rs);
9234
                gen_helper_yield(t0, t0);
9235
                gen_store_gpr(t0, rd);
9236
                tcg_temp_free(t0);
9237
            }
9238
            break;
9239
#if defined(TARGET_MIPS64)
9240
        case OPC_DEXTM ... OPC_DEXT:
9241
        case OPC_DINSM ... OPC_DINS:
9242
            check_insn(env, ctx, ISA_MIPS64R2);
9243
            check_mips_64(ctx);
9244
            gen_bitops(ctx, op1, rt, rs, sa, rd);
9245
            break;
9246
        case OPC_DBSHFL:
9247
            check_insn(env, ctx, ISA_MIPS64R2);
9248
            check_mips_64(ctx);
9249
            op2 = MASK_DBSHFL(ctx->opcode);
9250
            gen_bshfl(ctx, op2, rt, rd);
9251
            break;
9252
#endif
9253
        default:            /* Invalid */
9254
            MIPS_INVAL("special3");
9255
            generate_exception(ctx, EXCP_RI);
9256
            break;
9257
        }
9258
        break;
9259
    case OPC_REGIMM:
9260
        op1 = MASK_REGIMM(ctx->opcode);
9261
        switch (op1) {
9262
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
9263
        case OPC_BLTZAL ... OPC_BGEZALL:
9264
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
9265
            *is_branch = 1;
9266
            break;
9267
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
9268
        case OPC_TNEI:
9269
            gen_trap(ctx, op1, rs, -1, imm);
9270
            break;
9271
        case OPC_SYNCI:
9272
            check_insn(env, ctx, ISA_MIPS32R2);
9273
            /* Treat as NOP. */
9274
            break;
9275
        default:            /* Invalid */
9276
            MIPS_INVAL("regimm");
9277
            generate_exception(ctx, EXCP_RI);
9278
            break;
9279
        }
9280
        break;
9281
    case OPC_CP0:
9282
        check_cp0_enabled(ctx);
9283
        op1 = MASK_CP0(ctx->opcode);
9284
        switch (op1) {
9285
        case OPC_MFC0:
9286
        case OPC_MTC0:
9287
        case OPC_MFTR:
9288
        case OPC_MTTR:
9289
#if defined(TARGET_MIPS64)
9290
        case OPC_DMFC0:
9291
        case OPC_DMTC0:
9292
#endif
9293
#ifndef CONFIG_USER_ONLY
9294
            gen_cp0(env, ctx, op1, rt, rd);
9295
#endif /* !CONFIG_USER_ONLY */
9296
            break;
9297
        case OPC_C0_FIRST ... OPC_C0_LAST:
9298
#ifndef CONFIG_USER_ONLY
9299
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
9300
#endif /* !CONFIG_USER_ONLY */
9301
            break;
9302
        case OPC_MFMC0:
9303
#ifndef CONFIG_USER_ONLY
9304
            {
9305
                TCGv t0 = tcg_temp_new();
9306

    
9307
                op2 = MASK_MFMC0(ctx->opcode);
9308
                switch (op2) {
9309
                case OPC_DMT:
9310
                    check_insn(env, ctx, ASE_MT);
9311
                    gen_helper_dmt(t0, t0);
9312
                    gen_store_gpr(t0, rt);
9313
                    break;
9314
                case OPC_EMT:
9315
                    check_insn(env, ctx, ASE_MT);
9316
                    gen_helper_emt(t0, t0);
9317
                    gen_store_gpr(t0, rt);
9318
                    break;
9319
                case OPC_DVPE:
9320
                    check_insn(env, ctx, ASE_MT);
9321
                    gen_helper_dvpe(t0, t0);
9322
                    gen_store_gpr(t0, rt);
9323
                    break;
9324
                case OPC_EVPE:
9325
                    check_insn(env, ctx, ASE_MT);
9326
                    gen_helper_evpe(t0, t0);
9327
                    gen_store_gpr(t0, rt);
9328
                    break;
9329
                case OPC_DI:
9330
                    check_insn(env, ctx, ISA_MIPS32R2);
9331
                    save_cpu_state(ctx, 1);
9332
                    gen_helper_di(t0);
9333
                    gen_store_gpr(t0, rt);
9334
                    /* Stop translation as we may have switched the execution mode */
9335
                    ctx->bstate = BS_STOP;
9336
                    break;
9337
                case OPC_EI:
9338
                    check_insn(env, ctx, ISA_MIPS32R2);
9339
                    save_cpu_state(ctx, 1);
9340
                    gen_helper_ei(t0);
9341
                    gen_store_gpr(t0, rt);
9342
                    /* Stop translation as we may have switched the execution mode */
9343
                    ctx->bstate = BS_STOP;
9344
                    break;
9345
                default:            /* Invalid */
9346
                    MIPS_INVAL("mfmc0");
9347
                    generate_exception(ctx, EXCP_RI);
9348
                    break;
9349
                }
9350
                tcg_temp_free(t0);
9351
            }
9352
#endif /* !CONFIG_USER_ONLY */
9353
            break;
9354
        case OPC_RDPGPR:
9355
            check_insn(env, ctx, ISA_MIPS32R2);
9356
            gen_load_srsgpr(rt, rd);
9357
            break;
9358
        case OPC_WRPGPR:
9359
            check_insn(env, ctx, ISA_MIPS32R2);
9360
            gen_store_srsgpr(rt, rd);
9361
            break;
9362
        default:
9363
            MIPS_INVAL("cp0");
9364
            generate_exception(ctx, EXCP_RI);
9365
            break;
9366
        }
9367
        break;
9368
    case OPC_ADDI: /* Arithmetic with immediate opcode */
9369
    case OPC_ADDIU:
9370
         gen_arith_imm(env, ctx, op, rt, rs, imm);
9371
         break;
9372
    case OPC_SLTI: /* Set on less than with immediate opcode */
9373
    case OPC_SLTIU:
9374
         gen_slt_imm(env, op, rt, rs, imm);
9375
         break;
9376
    case OPC_ANDI: /* Arithmetic with immediate opcode */
9377
    case OPC_LUI:
9378
    case OPC_ORI:
9379
    case OPC_XORI:
9380
         gen_logic_imm(env, op, rt, rs, imm);
9381
         break;
9382
    case OPC_J ... OPC_JAL: /* Jump */
9383
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9384
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
9385
         *is_branch = 1;
9386
         break;
9387
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
9388
    case OPC_BEQL ... OPC_BGTZL:
9389
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
9390
         *is_branch = 1;
9391
         break;
9392
    case OPC_LB ... OPC_LWR: /* Load and stores */
9393
    case OPC_SB ... OPC_SW:
9394
    case OPC_SWR:
9395
    case OPC_LL:
9396
         gen_ldst(ctx, op, rt, rs, imm);
9397
         break;
9398
    case OPC_SC:
9399
         gen_st_cond(ctx, op, rt, rs, imm);
9400
         break;
9401
    case OPC_CACHE:
9402
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
9403
        /* Treat as NOP. */
9404
        break;
9405
    case OPC_PREF:
9406
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
9407
        /* Treat as NOP. */
9408
        break;
9409

    
9410
    /* Floating point (COP1). */
9411
    case OPC_LWC1:
9412
    case OPC_LDC1:
9413
    case OPC_SWC1:
9414
    case OPC_SDC1:
9415
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
9416
        break;
9417

    
9418
    case OPC_CP1:
9419
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9420
            check_cp1_enabled(ctx);
9421
            op1 = MASK_CP1(ctx->opcode);
9422
            switch (op1) {
9423
            case OPC_MFHC1:
9424
            case OPC_MTHC1:
9425
                check_insn(env, ctx, ISA_MIPS32R2);
9426
            case OPC_MFC1:
9427
            case OPC_CFC1:
9428
            case OPC_MTC1:
9429
            case OPC_CTC1:
9430
                gen_cp1(ctx, op1, rt, rd);
9431
                break;
9432
#if defined(TARGET_MIPS64)
9433
            case OPC_DMFC1:
9434
            case OPC_DMTC1:
9435
                check_insn(env, ctx, ISA_MIPS3);
9436
                gen_cp1(ctx, op1, rt, rd);
9437
                break;
9438
#endif
9439
            case OPC_BC1ANY2:
9440
            case OPC_BC1ANY4:
9441
                check_cop1x(ctx);
9442
                check_insn(env, ctx, ASE_MIPS3D);
9443
                /* fall through */
9444
            case OPC_BC1:
9445
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
9446
                                    (rt >> 2) & 0x7, imm << 2);
9447
                *is_branch = 1;
9448
                break;
9449
            case OPC_S_FMT:
9450
            case OPC_D_FMT:
9451
            case OPC_W_FMT:
9452
            case OPC_L_FMT:
9453
            case OPC_PS_FMT:
9454
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
9455
                           (imm >> 8) & 0x7);
9456
                break;
9457
            default:
9458
                MIPS_INVAL("cp1");
9459
                generate_exception (ctx, EXCP_RI);
9460
                break;
9461
            }
9462
        } else {
9463
            generate_exception_err(ctx, EXCP_CpU, 1);
9464
        }
9465
        break;
9466

    
9467
    /* COP2.  */
9468
    case OPC_LWC2:
9469
    case OPC_LDC2:
9470
    case OPC_SWC2:
9471
    case OPC_SDC2:
9472
    case OPC_CP2:
9473
        /* COP2: Not implemented. */
9474
        generate_exception_err(ctx, EXCP_CpU, 2);
9475
        break;
9476

    
9477
    case OPC_CP3:
9478
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9479
            check_cp1_enabled(ctx);
9480
            op1 = MASK_CP3(ctx->opcode);
9481
            switch (op1) {
9482
            case OPC_LWXC1:
9483
            case OPC_LDXC1:
9484
            case OPC_LUXC1:
9485
            case OPC_SWXC1:
9486
            case OPC_SDXC1:
9487
            case OPC_SUXC1:
9488
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
9489
                break;
9490
            case OPC_PREFX:
9491
                /* Treat as NOP. */
9492
                break;
9493
            case OPC_ALNV_PS:
9494
            case OPC_MADD_S:
9495
            case OPC_MADD_D:
9496
            case OPC_MADD_PS:
9497
            case OPC_MSUB_S:
9498
            case OPC_MSUB_D:
9499
            case OPC_MSUB_PS:
9500
            case OPC_NMADD_S:
9501
            case OPC_NMADD_D:
9502
            case OPC_NMADD_PS:
9503
            case OPC_NMSUB_S:
9504
            case OPC_NMSUB_D:
9505
            case OPC_NMSUB_PS:
9506
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
9507
                break;
9508
            default:
9509
                MIPS_INVAL("cp3");
9510
                generate_exception (ctx, EXCP_RI);
9511
                break;
9512
            }
9513
        } else {
9514
            generate_exception_err(ctx, EXCP_CpU, 1);
9515
        }
9516
        break;
9517

    
9518
#if defined(TARGET_MIPS64)
9519
    /* MIPS64 opcodes */
9520
    case OPC_LWU:
9521
    case OPC_LDL ... OPC_LDR:
9522
    case OPC_SDL ... OPC_SDR:
9523
    case OPC_LLD:
9524
    case OPC_LD:
9525
    case OPC_SD:
9526
        check_insn(env, ctx, ISA_MIPS3);
9527
        check_mips_64(ctx);
9528
        gen_ldst(ctx, op, rt, rs, imm);
9529
        break;
9530
    case OPC_SCD:
9531
        check_insn(env, ctx, ISA_MIPS3);
9532
        check_mips_64(ctx);
9533
        gen_st_cond(ctx, op, rt, rs, imm);
9534
        break;
9535
    case OPC_DADDI:
9536
    case OPC_DADDIU:
9537
        check_insn(env, ctx, ISA_MIPS3);
9538
        check_mips_64(ctx);
9539
        gen_arith_imm(env, ctx, op, rt, rs, imm);
9540
        break;
9541
#endif
9542
    case OPC_JALX:
9543
        check_insn(env, ctx, ASE_MIPS16);
9544
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9545
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
9546
        *is_branch = 1;
9547
        break;
9548
    case OPC_MDMX:
9549
        check_insn(env, ctx, ASE_MDMX);
9550
        /* MDMX: Not implemented. */
9551
    default:            /* Invalid */
9552
        MIPS_INVAL("major opcode");
9553
        generate_exception(ctx, EXCP_RI);
9554
        break;
9555
    }
9556
}
9557

    
9558
static inline void
9559
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
9560
                                int search_pc)
9561
{
9562
    DisasContext ctx;
9563
    target_ulong pc_start;
9564
    uint16_t *gen_opc_end;
9565
    CPUBreakpoint *bp;
9566
    int j, lj = -1;
9567
    int num_insns;
9568
    int max_insns;
9569
    int insn_bytes;
9570
    int is_branch;
9571

    
9572
    if (search_pc)
9573
        qemu_log("search pc %d\n", search_pc);
9574

    
9575
    pc_start = tb->pc;
9576
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9577
    ctx.pc = pc_start;
9578
    ctx.saved_pc = -1;
9579
    ctx.singlestep_enabled = env->singlestep_enabled;
9580
    ctx.tb = tb;
9581
    ctx.bstate = BS_NONE;
9582
    /* Restore delay slot state from the tb context.  */
9583
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
9584
    restore_cpu_state(env, &ctx);
9585
#ifdef CONFIG_USER_ONLY
9586
        ctx.mem_idx = MIPS_HFLAG_UM;
9587
#else
9588
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
9589
#endif
9590
    num_insns = 0;
9591
    max_insns = tb->cflags & CF_COUNT_MASK;
9592
    if (max_insns == 0)
9593
        max_insns = CF_COUNT_MASK;
9594
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
9595
    gen_icount_start();
9596
    while (ctx.bstate == BS_NONE) {
9597
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9598
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9599
                if (bp->pc == ctx.pc) {
9600
                    save_cpu_state(&ctx, 1);
9601
                    ctx.bstate = BS_BRANCH;
9602
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
9603
                    /* Include the breakpoint location or the tb won't
9604
                     * be flushed when it must be.  */
9605
                    ctx.pc += 4;
9606
                    goto done_generating;
9607
                }
9608
            }
9609
        }
9610

    
9611
        if (search_pc) {
9612
            j = gen_opc_ptr - gen_opc_buf;
9613
            if (lj < j) {
9614
                lj++;
9615
                while (lj < j)
9616
                    gen_opc_instr_start[lj++] = 0;
9617
            }
9618
            gen_opc_pc[lj] = ctx.pc;
9619
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
9620
            gen_opc_instr_start[lj] = 1;
9621
            gen_opc_icount[lj] = num_insns;
9622
        }
9623
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9624
            gen_io_start();
9625

    
9626
        is_branch = 0;
9627
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
9628
            ctx.opcode = ldl_code(ctx.pc);
9629
            insn_bytes = 4;
9630
            decode_opc(env, &ctx, &is_branch);
9631
        } else if (env->insn_flags & ASE_MIPS16) {
9632
            ctx.opcode = lduw_code(ctx.pc);
9633
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
9634
        } else {
9635
            generate_exception(&ctx, EXCP_RI);
9636
            break;
9637
        }
9638
        if (!is_branch) {
9639
            handle_delay_slot(env, &ctx, insn_bytes);
9640
        }
9641
        ctx.pc += insn_bytes;
9642

    
9643
        num_insns++;
9644

    
9645
        /* Execute a branch and its delay slot as a single instruction.
9646
           This is what GDB expects and is consistent with what the
9647
           hardware does (e.g. if a delay slot instruction faults, the
9648
           reported PC is the PC of the branch).  */
9649
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
9650
            break;
9651

    
9652
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
9653
            break;
9654

    
9655
        if (gen_opc_ptr >= gen_opc_end)
9656
            break;
9657

    
9658
        if (num_insns >= max_insns)
9659
            break;
9660

    
9661
        if (singlestep)
9662
            break;
9663
    }
9664
    if (tb->cflags & CF_LAST_IO)
9665
        gen_io_end();
9666
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
9667
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
9668
        gen_helper_0i(raise_exception, EXCP_DEBUG);
9669
    } else {
9670
        switch (ctx.bstate) {
9671
        case BS_STOP:
9672
            gen_helper_interrupt_restart();
9673
            gen_goto_tb(&ctx, 0, ctx.pc);
9674
            break;
9675
        case BS_NONE:
9676
            save_cpu_state(&ctx, 0);
9677
            gen_goto_tb(&ctx, 0, ctx.pc);
9678
            break;
9679
        case BS_EXCP:
9680
            gen_helper_interrupt_restart();
9681
            tcg_gen_exit_tb(0);
9682
            break;
9683
        case BS_BRANCH:
9684
        default:
9685
            break;
9686
        }
9687
    }
9688
done_generating:
9689
    gen_icount_end(tb, num_insns);
9690
    *gen_opc_ptr = INDEX_op_end;
9691
    if (search_pc) {
9692
        j = gen_opc_ptr - gen_opc_buf;
9693
        lj++;
9694
        while (lj <= j)
9695
            gen_opc_instr_start[lj++] = 0;
9696
    } else {
9697
        tb->size = ctx.pc - pc_start;
9698
        tb->icount = num_insns;
9699
    }
9700
#ifdef DEBUG_DISAS
9701
    LOG_DISAS("\n");
9702
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9703
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9704
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
9705
        qemu_log("\n");
9706
    }
9707
#endif
9708
}
9709

    
9710
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9711
{
9712
    gen_intermediate_code_internal(env, tb, 0);
9713
}
9714

    
9715
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9716
{
9717
    gen_intermediate_code_internal(env, tb, 1);
9718
}
9719

    
9720
static void fpu_dump_state(CPUState *env, FILE *f,
9721
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
9722
                           int flags)
9723
{
9724
    int i;
9725
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
9726

    
9727
#define printfpr(fp)                                                    \
9728
    do {                                                                \
9729
        if (is_fpu64)                                                   \
9730
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
9731
                        " fd:%13g fs:%13g psu: %13g\n",                 \
9732
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
9733
                        (double)(fp)->fd,                               \
9734
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
9735
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
9736
        else {                                                          \
9737
            fpr_t tmp;                                                  \
9738
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
9739
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
9740
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
9741
                        " fd:%13g fs:%13g psu:%13g\n",                  \
9742
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
9743
                        (double)tmp.fd,                                 \
9744
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
9745
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
9746
        }                                                               \
9747
    } while(0)
9748

    
9749

    
9750
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
9751
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
9752
                get_float_exception_flags(&env->active_fpu.fp_status));
9753
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
9754
        fpu_fprintf(f, "%3s: ", fregnames[i]);
9755
        printfpr(&env->active_fpu.fpr[i]);
9756
    }
9757

    
9758
#undef printfpr
9759
}
9760

    
9761
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9762
/* Debug help: The architecture requires 32bit code to maintain proper
9763
   sign-extended values on 64bit machines.  */
9764

    
9765
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
9766

    
9767
static void
9768
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
9769
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9770
                                int flags)
9771
{
9772
    int i;
9773

    
9774
    if (!SIGN_EXT_P(env->active_tc.PC))
9775
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
9776
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
9777
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
9778
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
9779
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
9780
    if (!SIGN_EXT_P(env->btarget))
9781
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
9782

    
9783
    for (i = 0; i < 32; i++) {
9784
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
9785
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
9786
    }
9787

    
9788
    if (!SIGN_EXT_P(env->CP0_EPC))
9789
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
9790
    if (!SIGN_EXT_P(env->lladdr))
9791
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
9792
}
9793
#endif
9794

    
9795
void cpu_dump_state (CPUState *env, FILE *f,
9796
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9797
                     int flags)
9798
{
9799
    int i;
9800

    
9801
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
9802
                " LO=0x" TARGET_FMT_lx " ds %04x "
9803
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
9804
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
9805
                env->hflags, env->btarget, env->bcond);
9806
    for (i = 0; i < 32; i++) {
9807
        if ((i & 3) == 0)
9808
            cpu_fprintf(f, "GPR%02d:", i);
9809
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
9810
        if ((i & 3) == 3)
9811
            cpu_fprintf(f, "\n");
9812
    }
9813

    
9814
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
9815
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
9816
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
9817
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
9818
    if (env->hflags & MIPS_HFLAG_FPU)
9819
        fpu_dump_state(env, f, cpu_fprintf, flags);
9820
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9821
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
9822
#endif
9823
}
9824

    
9825
static void mips_tcg_init(void)
9826
{
9827
    int i;
9828
    static int inited;
9829

    
9830
    /* Initialize various static tables. */
9831
    if (inited)
9832
        return;
9833

    
9834
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
9835
    TCGV_UNUSED(cpu_gpr[0]);
9836
    for (i = 1; i < 32; i++)
9837
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
9838
                                        offsetof(CPUState, active_tc.gpr[i]),
9839
                                        regnames[i]);
9840
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
9841
                                offsetof(CPUState, active_tc.PC), "PC");
9842
    for (i = 0; i < MIPS_DSP_ACC; i++) {
9843
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
9844
                                       offsetof(CPUState, active_tc.HI[i]),
9845
                                       regnames_HI[i]);
9846
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
9847
                                       offsetof(CPUState, active_tc.LO[i]),
9848
                                       regnames_LO[i]);
9849
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
9850
                                        offsetof(CPUState, active_tc.ACX[i]),
9851
                                        regnames_ACX[i]);
9852
    }
9853
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
9854
                                     offsetof(CPUState, active_tc.DSPControl),
9855
                                     "DSPControl");
9856
    bcond = tcg_global_mem_new(TCG_AREG0,
9857
                               offsetof(CPUState, bcond), "bcond");
9858
    btarget = tcg_global_mem_new(TCG_AREG0,
9859
                                 offsetof(CPUState, btarget), "btarget");
9860
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
9861
                                    offsetof(CPUState, hflags), "hflags");
9862

    
9863
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
9864
                                      offsetof(CPUState, active_fpu.fcr0),
9865
                                      "fcr0");
9866
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
9867
                                       offsetof(CPUState, active_fpu.fcr31),
9868
                                       "fcr31");
9869

    
9870
    /* register helpers */
9871
#define GEN_HELPER 2
9872
#include "helper.h"
9873

    
9874
    inited = 1;
9875
}
9876

    
9877
#include "translate_init.c"
9878

    
9879
CPUMIPSState *cpu_mips_init (const char *cpu_model)
9880
{
9881
    CPUMIPSState *env;
9882
    const mips_def_t *def;
9883

    
9884
    def = cpu_mips_find_by_name(cpu_model);
9885
    if (!def)
9886
        return NULL;
9887
    env = qemu_mallocz(sizeof(CPUMIPSState));
9888
    env->cpu_model = def;
9889
    env->cpu_model_str = cpu_model;
9890

    
9891
    cpu_exec_init(env);
9892
#ifndef CONFIG_USER_ONLY
9893
    mmu_init(env, def);
9894
#endif
9895
    fpu_init(env, def);
9896
    mvp_init(env, def);
9897
    mips_tcg_init();
9898
    cpu_reset(env);
9899
    qemu_init_vcpu(env);
9900
    return env;
9901
}
9902

    
9903
void cpu_reset (CPUMIPSState *env)
9904
{
9905
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
9906
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
9907
        log_cpu_state(env, 0);
9908
    }
9909

    
9910
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
9911
    tlb_flush(env, 1);
9912

    
9913
    /* Reset registers to their default values */
9914
    env->CP0_PRid = env->cpu_model->CP0_PRid;
9915
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
9916
#ifdef TARGET_WORDS_BIGENDIAN
9917
    env->CP0_Config0 |= (1 << CP0C0_BE);
9918
#endif
9919
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
9920
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
9921
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
9922
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
9923
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
9924
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
9925
                                 << env->cpu_model->CP0_LLAddr_shift;
9926
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
9927
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
9928
    env->CCRes = env->cpu_model->CCRes;
9929
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
9930
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
9931
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
9932
    env->current_tc = 0;
9933
    env->SEGBITS = env->cpu_model->SEGBITS;
9934
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
9935
#if defined(TARGET_MIPS64)
9936
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
9937
        env->SEGMask |= 3ULL << 62;
9938
    }
9939
#endif
9940
    env->PABITS = env->cpu_model->PABITS;
9941
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
9942
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
9943
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
9944
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
9945
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
9946
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
9947
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
9948
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
9949
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
9950
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
9951
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
9952
    env->insn_flags = env->cpu_model->insn_flags;
9953

    
9954
#if defined(CONFIG_USER_ONLY)
9955
    env->hflags = MIPS_HFLAG_UM;
9956
    /* Enable access to the SYNCI_Step register.  */
9957
    env->CP0_HWREna |= (1 << 1);
9958
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9959
        env->hflags |= MIPS_HFLAG_FPU;
9960
    }
9961
#ifdef TARGET_MIPS64
9962
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
9963
        env->hflags |= MIPS_HFLAG_F64;
9964
    }
9965
#endif
9966
#else
9967
    if (env->hflags & MIPS_HFLAG_BMASK) {
9968
        /* If the exception was raised from a delay slot,
9969
           come back to the jump.  */
9970
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
9971
    } else {
9972
        env->CP0_ErrorEPC = env->active_tc.PC;
9973
    }
9974
    env->active_tc.PC = (int32_t)0xBFC00000;
9975
    env->CP0_Random = env->tlb->nb_tlb - 1;
9976
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
9977
    env->CP0_Wired = 0;
9978
    /* SMP not implemented */
9979
    env->CP0_EBase = 0x80000000;
9980
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
9981
    /* vectored interrupts not implemented, timer on int 7,
9982
       no performance counters. */
9983
    env->CP0_IntCtl = 0xe0000000;
9984
    {
9985
        int i;
9986

    
9987
        for (i = 0; i < 7; i++) {
9988
            env->CP0_WatchLo[i] = 0;
9989
            env->CP0_WatchHi[i] = 0x80000000;
9990
        }
9991
        env->CP0_WatchLo[7] = 0;
9992
        env->CP0_WatchHi[7] = 0;
9993
    }
9994
    /* Count register increments in debug mode, EJTAG version 1 */
9995
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9996
    env->hflags = MIPS_HFLAG_CP0;
9997
#endif
9998
#if defined(TARGET_MIPS64)
9999
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
10000
        env->hflags |= MIPS_HFLAG_64;
10001
    }
10002
#endif
10003
    env->exception_index = EXCP_NONE;
10004
}
10005

    
10006
void gen_pc_load(CPUState *env, TranslationBlock *tb,
10007
                unsigned long searched_pc, int pc_pos, void *puc)
10008
{
10009
    env->active_tc.PC = gen_opc_pc[pc_pos];
10010
    env->hflags &= ~MIPS_HFLAG_BMASK;
10011
    env->hflags |= gen_opc_hflags[pc_pos];
10012
}